loopback.rs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. #![cfg_attr(not(feature = "std"), no_std)]
  2. #![allow(unused_mut)]
  3. #[macro_use]
  4. extern crate log;
  5. #[cfg(feature = "std")]
  6. extern crate env_logger;
  7. #[cfg(feature = "std")]
  8. extern crate getopts;
  9. extern crate smoltcp;
  10. #[cfg(feature = "std")]
  11. mod utils;
  12. use smoltcp::Error;
  13. use smoltcp::phy::Loopback;
  14. #[cfg(feature = "std")]
  15. use smoltcp::phy::Tracer;
  16. use smoltcp::wire::{EthernetAddress, IpAddress};
  17. #[cfg(feature = "std")]
  18. use smoltcp::wire::EthernetFrame;
  19. use smoltcp::iface::{ArpCache, SliceArpCache, EthernetInterface};
  20. use smoltcp::socket::{AsSocket, SocketSet};
  21. use smoltcp::socket::{TcpSocket, TcpSocketBuffer};
  22. fn main() {
  23. #[cfg(feature = "std")]
  24. utils::setup_logging();
  25. let mut device = Loopback::new();
  26. #[cfg(feature = "std")]
  27. let mut device = Tracer::<_, EthernetFrame<&'static [u8]>>::new(device, utils::trace_writer);
  28. let mut arp_cache_entries: [_; 8] = Default::default();
  29. let mut arp_cache = SliceArpCache::new(&mut arp_cache_entries[..]);
  30. let hardware_addr = EthernetAddress::default();
  31. let mut protocol_addrs = [IpAddress::v4(127, 0, 0, 1)];
  32. let mut iface = EthernetInterface::new(
  33. &mut device, &mut arp_cache as &mut ArpCache,
  34. hardware_addr, &mut protocol_addrs[..]);
  35. let server_socket = {
  36. // It is not strictly necessary to use a `static mut` and unsafe code here, but
  37. // on embedded systems that smoltcp targets it is far better to allocate the data
  38. // statically to verify that it fits into RAM rather than get undefined behavior
  39. // when stack overflows.
  40. static mut TCP_SERVER_RX_DATA: [u8; 1024] = [0; 1024];
  41. static mut TCP_SERVER_TX_DATA: [u8; 1024] = [0; 1024];
  42. let tcp_rx_buffer = TcpSocketBuffer::new(unsafe { &mut TCP_SERVER_RX_DATA[..] });
  43. let tcp_tx_buffer = TcpSocketBuffer::new(unsafe { &mut TCP_SERVER_TX_DATA[..] });
  44. TcpSocket::new(tcp_rx_buffer, tcp_tx_buffer)
  45. };
  46. let client_socket = {
  47. static mut TCP_CLIENT_RX_DATA: [u8; 1024] = [0; 1024];
  48. static mut TCP_CLIENT_TX_DATA: [u8; 1024] = [0; 1024];
  49. let tcp_rx_buffer = TcpSocketBuffer::new(unsafe { &mut TCP_CLIENT_RX_DATA[..] });
  50. let tcp_tx_buffer = TcpSocketBuffer::new(unsafe { &mut TCP_CLIENT_TX_DATA[..] });
  51. TcpSocket::new(tcp_rx_buffer, tcp_tx_buffer)
  52. };
  53. let mut socket_set_entries: [_; 2] = Default::default();
  54. let mut socket_set = SocketSet::new(&mut socket_set_entries[..]);
  55. let server_handle = socket_set.add(server_socket);
  56. let client_handle = socket_set.add(client_socket);
  57. let mut did_listen = false;
  58. let mut did_connect = false;
  59. let mut done = false;
  60. let mut timestamp_ms = 0;
  61. while !done && timestamp_ms < 500 {
  62. {
  63. let socket: &mut TcpSocket = socket_set.get_mut(server_handle).as_socket();
  64. if !socket.is_active() && !socket.is_listening() {
  65. if !did_listen {
  66. socket.listen(1234).unwrap();
  67. did_listen = true;
  68. }
  69. }
  70. if socket.can_recv() {
  71. debug!("got {:?}", socket.recv(32).unwrap());
  72. socket.close();
  73. done = true;
  74. }
  75. }
  76. {
  77. let socket: &mut TcpSocket = socket_set.get_mut(client_handle).as_socket();
  78. if !socket.is_open() {
  79. if !did_connect {
  80. socket.connect((IpAddress::v4(127, 0, 0, 1), 1234),
  81. (IpAddress::v4(127, 0, 0, 1), 65000)).unwrap();
  82. did_connect = true;
  83. }
  84. }
  85. if socket.can_send() {
  86. socket.send_slice(b"0123456789abcdef").unwrap();
  87. socket.close();
  88. }
  89. }
  90. match iface.poll(&mut socket_set, timestamp_ms) {
  91. Ok(()) | Err(Error::Exhausted) => (),
  92. Err(e) => debug!("poll error: {}", e)
  93. }
  94. const DELAY: u64 = 20;
  95. debug!("{}ms pass", DELAY);
  96. timestamp_ms += DELAY;
  97. }
  98. if !done {
  99. error!("this is taking too long, bailing out");
  100. }
  101. }