@@ -36,7 +36,7 @@ use sh::hio::{self, HStdout};
36
36
use smoltcp:: {
37
37
socket:: {
38
38
Socket , SocketSet , TcpSocket , TcpSocketBuffer , UdpPacketMetadata , UdpSocket ,
39
- UdpSocketBuffer ,
39
+ UdpSocketBuffer , IcmpSocket , IcmpEndpoint ,
40
40
} ,
41
41
time:: Instant ,
42
42
wire:: { EthernetAddress , IpAddress , IpEndpoint , Ipv4Address } ,
@@ -63,7 +63,6 @@ static ALLOCATOR: CortexMHeap = CortexMHeap::empty();
63
63
64
64
const HEAP_SIZE : usize = 50 * 1024 ; // in bytes
65
65
const ETH_ADDR : EthernetAddress = EthernetAddress ( [ 0x00 , 0x08 , 0xdc , 0xab , 0xcd , 0xef ] ) ;
66
- const IP_ADDR : Ipv4Address = Ipv4Address ( [ 141 , 52 , 46 , 198 ] ) ;
67
66
68
67
#[ entry]
69
68
fn main ( ) -> ! {
@@ -293,7 +292,7 @@ fn run() -> ! {
293
292
294
293
// FIXME: Causes link error: no memory region specified for section '.ARM.extab'
295
294
// see https://github.com/rust-embedded/cortex-m-rt/issues/157
296
- // executor.spawn_local(_ethernet_task .run()).unwrap();
295
+ executor. spawn_local ( ethernet_task . run ( ) ) . unwrap ( ) ;
297
296
298
297
// FIXME: Does not work currently due to borrowing errors
299
298
// executor.spawn_local(sd_card_task(sd, idle_stream.clone())).unwrap();
@@ -493,6 +492,10 @@ where
493
492
}
494
493
495
494
async fn run ( mut self ) {
495
+ use smoltcp:: wire:: { EthernetAddress , Ipv4Address , IpCidr } ;
496
+ use smoltcp:: socket:: { SocketSet , RawSocketBuffer , RawPacketMetadata , IcmpSocketBuffer , IcmpPacketMetadata } ;
497
+ use smoltcp:: dhcp:: Dhcpv4Client ;
498
+
496
499
let mut ethernet_interface = ethernet:: EthernetDevice :: new (
497
500
Default :: default ( ) ,
498
501
Default :: default ( ) ,
@@ -502,54 +505,93 @@ where
502
505
& mut self . ethernet_dma ,
503
506
ETH_ADDR ,
504
507
)
505
- . map ( |device| device. into_interface ( IP_ADDR ) ) ;
506
- if let Err ( e) = ethernet_interface {
507
- println ! ( "ethernet init failed: {:?}" , e) ;
508
+ . map ( |device| device. into_interface ( ) ) ;
509
+ let mut iface = match ethernet_interface {
510
+ Ok ( iface) => iface,
511
+ Err ( e) => {
512
+ println ! ( "ethernet init failed: {:?}" , e) ;
513
+ return ;
514
+ }
508
515
} ;
509
516
510
517
let idle_stream = self . idle_stream ;
511
518
pin_mut ! ( idle_stream) ;
512
519
513
520
let mut sockets = SocketSet :: new ( Vec :: new ( ) ) ;
514
521
515
- if ethernet_interface. is_ok ( ) {
516
- let endpoint = IpEndpoint :: new ( IpAddress :: Ipv4 ( IP_ADDR ) , 15 ) ;
517
- let udp_rx_buffer =
518
- UdpSocketBuffer :: new ( vec ! [ UdpPacketMetadata :: EMPTY ; 3 ] , vec ! [ 0u8 ; 256 ] ) ;
519
- let udp_tx_buffer =
520
- UdpSocketBuffer :: new ( vec ! [ UdpPacketMetadata :: EMPTY ; 1 ] , vec ! [ 0u8 ; 128 ] ) ;
521
- let mut example_udp_socket = UdpSocket :: new ( udp_rx_buffer, udp_tx_buffer) ;
522
- example_udp_socket. bind ( endpoint) . unwrap ( ) ;
523
- sockets. add ( example_udp_socket) ;
524
-
525
- let tcp_rx_buffer = TcpSocketBuffer :: new ( vec ! [ 0 ; ethernet:: MTU ] ) ;
526
- let tcp_tx_buffer = TcpSocketBuffer :: new ( vec ! [ 0 ; ethernet:: MTU ] ) ;
527
- let mut example_tcp_socket = TcpSocket :: new ( tcp_rx_buffer, tcp_tx_buffer) ;
528
- example_tcp_socket. listen ( endpoint) . unwrap ( ) ;
529
- sockets. add ( example_tcp_socket) ;
530
- }
522
+ let dhcp_rx_buffer = RawSocketBuffer :: new (
523
+ [ RawPacketMetadata :: EMPTY ; 2 ] ,
524
+ vec ! [ 0 ; 1500 ]
525
+ ) ;
526
+ let dhcp_tx_buffer = RawSocketBuffer :: new (
527
+ [ RawPacketMetadata :: EMPTY ; 1 ] ,
528
+ vec ! [ 0 ; 3000 ]
529
+ ) ;
530
+ let mut dhcp = Dhcpv4Client :: new ( & mut sockets, dhcp_rx_buffer, dhcp_tx_buffer, Instant :: from_millis ( system_clock:: ms ( ) as i64 ) ) ;
531
+ let mut prev_ip_addr = iface. ipv4_addr ( ) . unwrap ( ) ;
531
532
532
533
// handle new ethernet packets
533
- if let Ok ( ref mut eth ) = ethernet_interface {
534
- loop {
535
- match eth . poll (
536
- & mut sockets ,
537
- Instant :: from_millis ( system_clock :: ms ( ) as i64 ) ,
538
- ) {
539
- Err ( :: smoltcp :: Error :: Exhausted ) => {
540
- await ! ( idle_stream . next ( ) ) . expect ( "idle stream closed" ) ;
541
- }
542
- Err ( :: smoltcp :: Error :: Unrecognized ) => { }
543
- Err ( e ) => println ! ( "Network error: {:?}" , e ) ,
544
- Ok ( socket_changed ) => {
545
- if socket_changed {
546
- for mut socket in sockets . iter_mut ( ) {
547
- Self :: poll_socket ( & mut socket) . expect ( "socket poll failed" ) ;
548
- }
534
+ loop {
535
+ await ! ( idle_stream . next ( ) ) ;
536
+ let timestamp = Instant :: from_millis ( system_clock :: ms ( ) as i64 ) ;
537
+ match iface . poll (
538
+ & mut sockets ,
539
+ timestamp ,
540
+ ) {
541
+ Err ( :: smoltcp :: Error :: Exhausted ) => {
542
+ continue ;
543
+ }
544
+ Err ( :: smoltcp :: Error :: Unrecognized ) => { print ! ( "U" ) }
545
+ Err ( e ) => println ! ( "Network error: {:?}" , e ) ,
546
+ Ok ( socket_changed) => {
547
+ if socket_changed {
548
+ for mut socket in sockets . iter_mut ( ) {
549
+ Self :: poll_socket ( & mut socket ) . expect ( "socket poll failed" ) ;
549
550
}
550
551
}
551
552
}
552
553
}
554
+
555
+ dhcp. poll ( & mut iface, & mut sockets, timestamp)
556
+ . unwrap_or_else ( |e| println ! ( "DHCP: {:?}" , e) ) ;
557
+ let ip_addr = iface. ipv4_addr ( ) . unwrap ( ) ;
558
+ if ip_addr != prev_ip_addr {
559
+ println ! ( "Assigned a new IPv4 address: {}" , ip_addr) ;
560
+ iface. routes_mut ( )
561
+ . update ( |routes_map| {
562
+ routes_map. get ( & IpCidr :: new ( Ipv4Address :: UNSPECIFIED . into ( ) , 0 ) )
563
+ . map ( |default_route| {
564
+ println ! ( "Default gateway: {}" , default_route. via_router) ;
565
+ } ) ;
566
+ } ) ;
567
+ for dns_server in dhcp. dns_servers ( ) {
568
+ println ! ( "DNS servers: {}" , dns_server) ;
569
+ }
570
+
571
+ // TODO delete old sockets
572
+
573
+ // add new sockets
574
+ let endpoint = IpEndpoint :: new ( ip_addr. into ( ) , 15 ) ;
575
+
576
+ let udp_rx_buffer =
577
+ UdpSocketBuffer :: new ( vec ! [ UdpPacketMetadata :: EMPTY ; 3 ] , vec ! [ 0u8 ; 256 ] ) ;
578
+ let udp_tx_buffer =
579
+ UdpSocketBuffer :: new ( vec ! [ UdpPacketMetadata :: EMPTY ; 1 ] , vec ! [ 0u8 ; 128 ] ) ;
580
+ let mut example_udp_socket = UdpSocket :: new ( udp_rx_buffer, udp_tx_buffer) ;
581
+ example_udp_socket. bind ( endpoint) . unwrap ( ) ;
582
+ sockets. add ( example_udp_socket) ;
583
+
584
+ let tcp_rx_buffer = TcpSocketBuffer :: new ( vec ! [ 0 ; ethernet:: MTU ] ) ;
585
+ let tcp_tx_buffer = TcpSocketBuffer :: new ( vec ! [ 0 ; ethernet:: MTU ] ) ;
586
+ let mut example_tcp_socket = TcpSocket :: new ( tcp_rx_buffer, tcp_tx_buffer) ;
587
+ example_tcp_socket. listen ( endpoint) . unwrap ( ) ;
588
+ sockets. add ( example_tcp_socket) ;
589
+
590
+ prev_ip_addr = ip_addr;
591
+ }
592
+ let mut timeout = dhcp. next_poll ( timestamp) ;
593
+ iface. poll_delay ( & sockets, timestamp) . map ( |sockets_timeout| timeout = sockets_timeout) ;
594
+ // TODO await next interrupt
553
595
}
554
596
}
555
597
@@ -570,7 +612,7 @@ where
570
612
}
571
613
socket. send_slice ( & reply. 0 , reply. 1 ) ?;
572
614
} ,
573
- _ => { }
615
+ _ => unreachable ! ( )
574
616
} ,
575
617
& mut Socket :: Tcp ( ref mut socket) => match socket. local_endpoint ( ) . port {
576
618
15 => {
@@ -592,7 +634,7 @@ where
592
634
assert_eq ! ( socket. send_slice( & reply) ?, reply. len( ) ) ;
593
635
}
594
636
}
595
- _ => { }
637
+ _ => unreachable ! ( )
596
638
} ,
597
639
_ => { }
598
640
}
0 commit comments