From 2d469cb35cbe3b6726bfae9b7f106ebcd79d235c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josef=20S=C3=B6ntgen?= Date: Thu, 12 Mar 2015 20:23:05 +0100 Subject: [PATCH] lwip: packet-stream/link-state signals in recv thread Issue #1327 --- repos/libports/include/lwip/genode.h | 7 ++ repos/libports/include/lwip/lwipopts.h | 3 +- repos/libports/src/lib/lwip/platform/nic.cc | 57 ++++++++++--- .../src/lib/lwip/platform/sys_arch.cc | 85 +++++++++++-------- 4 files changed, 102 insertions(+), 50 deletions(-) diff --git a/repos/libports/include/lwip/genode.h b/repos/libports/include/lwip/genode.h index 6af19b3dc..a85526010 100644 --- a/repos/libports/include/lwip/genode.h +++ b/repos/libports/include/lwip/genode.h @@ -47,6 +47,13 @@ int lwip_nic_init(genode_int32_t ip_addr, __SIZE_TYPE__ tx_buf_size, __SIZE_TYPE__ rx_buf_size); +/** + * Pass on link-state changes to lwIP + * + * \param state current link-state + */ +void lwip_nic_link_state_changed(int state); + #ifdef __cplusplus } #endif diff --git a/repos/libports/include/lwip/lwipopts.h b/repos/libports/include/lwip/lwipopts.h index 98e4ff154..ce7ff035d 100644 --- a/repos/libports/include/lwip/lwipopts.h +++ b/repos/libports/include/lwip/lwipopts.h @@ -42,7 +42,8 @@ #define TCP_RCV_SCALE 2 /* receive scale factor IETF RFC 1323 */ #if LWIP_DHCP -#define LWIP_NETIF_STATUS_CALLBACK 1 /* callback function used by DHCP init */ +#define LWIP_NETIF_STATUS_CALLBACK 1 /* callback function used for interface changes */ +#define LWIP_NETIF_LINK_CALLBACK 1 /* callback function used for link-state changes */ #endif /*********************************** diff --git a/repos/libports/src/lib/lwip/platform/nic.cc b/repos/libports/src/lib/lwip/platform/nic.cc index b3f449cef..be0c8c158 100644 --- a/repos/libports/src/lib/lwip/platform/nic.cc +++ b/repos/libports/src/lib/lwip/platform/nic.cc @@ -32,6 +32,13 @@ extern "C" { #include #include +extern "C" { + + static void genode_netif_input(struct netif *netif); + + void lwip_nic_link_state_changed(int state); +} + /* * Thread, that receives packets by the nic-session interface. @@ -46,6 +53,28 @@ class Nic_receiver_thread : public Genode::Thread<8192> Packet_descriptor _rx_packet; /* actual packet received */ struct netif *_netif; /* LwIP network interface structure */ + Genode::Signal_receiver _sig_rec; + + Genode::Signal_dispatcher _link_state_dispatcher; + Genode::Signal_dispatcher _rx_packet_avail_dispatcher; + Genode::Signal_dispatcher _rx_ready_to_ack_dispatcher; + + void _handle_rx_packet_avail(unsigned) + { + while (_nic->rx()->packet_avail() && _nic->rx()->ready_to_ack()) { + _rx_packet = _nic->rx()->get_packet(); + genode_netif_input(_netif); + _nic->rx()->acknowledge_packet(_rx_packet); + } + } + + void _handle_rx_read_to_ack(unsigned) { _handle_rx_packet_avail(0); } + + void _handle_link_state(unsigned) + { + lwip_nic_link_state_changed(_nic->link_state()); + } + void _tx_ack(bool block = false) { /* check for acknowledgements */ @@ -59,7 +88,16 @@ class Nic_receiver_thread : public Genode::Thread<8192> public: Nic_receiver_thread(Nic::Connection *nic, struct netif *netif) - : Genode::Thread<8192>("nic-recv"), _nic(nic), _netif(netif) {} + : + Genode::Thread<8192>("nic-recv"), _nic(nic), _netif(netif), + _link_state_dispatcher(_sig_rec, *this, &Nic_receiver_thread::_handle_link_state), + _rx_packet_avail_dispatcher(_sig_rec, *this, &Nic_receiver_thread::_handle_rx_packet_avail), + _rx_ready_to_ack_dispatcher(_sig_rec, *this, &Nic_receiver_thread::_handle_rx_read_to_ack) + { + _nic->link_state_sigh(_link_state_dispatcher); + _nic->rx_channel()->sigh_packet_avail(_rx_packet_avail_dispatcher); + _nic->rx_channel()->sigh_ready_to_ack(_rx_ready_to_ack_dispatcher); + } void entry(); Nic::Connection *nic() { return _nic; }; @@ -95,9 +133,6 @@ class Nic_receiver_thread : public Genode::Thread<8192> */ extern "C" { - static void genode_netif_input(struct netif *netif); - - /** * This function should do the actual transmission of the packet. The packet is * contained in the pbuf that is passed to the function. This pbuf @@ -192,8 +227,6 @@ extern "C" { LINK_STATS_INC(link.drop); } - /* Acknowledge the packet */ - nic->rx()->acknowledge_packet(rx_packet); return p; } @@ -295,11 +328,11 @@ void Nic_receiver_thread::entry() { while(true) { - /* - * Block until we receive a packet, - * then call input function. - */ - _rx_packet = _nic->rx()->get_packet(); - genode_netif_input(_netif); + Genode::Signal sig = _sig_rec.wait_for_signal(); + int num = sig.num(); + + Genode::Signal_dispatcher_base *dispatcher; + dispatcher = dynamic_cast(sig.context()); + dispatcher->dispatch(num); } } diff --git a/repos/libports/src/lib/lwip/platform/sys_arch.cc b/repos/libports/src/lib/lwip/platform/sys_arch.cc index c660f9ad1..897578996 100644 --- a/repos/libports/src/lib/lwip/platform/sys_arch.cc +++ b/repos/libports/src/lib/lwip/platform/sys_arch.cc @@ -64,16 +64,6 @@ static Lwip::Mutex *global_mutex() } -/** - * Returns a timed semaphore used to wait for DHCP to come up. - */ -static Genode::Timed_semaphore *dhcp_semaphore() -{ - static Genode::Timed_semaphore _sem; - return &_sem; -} - - /** * Used for startup synchronization by the tcpip thread. */ @@ -83,15 +73,6 @@ static void startup_done(void *arg) } -/** - * Callback function used when doing dhcp requests, - * to check availability of an IP address. - */ -static void dhcp_callback(struct netif *netif) -{ - dhcp_semaphore()->up(); -} - using namespace Lwip; extern "C" { @@ -115,6 +96,42 @@ extern "C" { #error "You cannot use the Genode LwIP backend with NO_SYS!" #endif //NO_SYS +#define netifapi_netif_set_link_up(n) netifapi_netif_common(n, netif_set_link_up, NULL) +#define netifapi_netif_set_link_down(n) netifapi_netif_common(n, netif_set_link_down, NULL) + + static struct netif netif; + + /* + * Callback function used when changing the interface state. + */ + static void status_callback(struct netif *netif) + { + static ip_addr_t ip_addr = { 0 }; + + if (ip_addr.addr != netif->ip_addr.addr) { + PINF("got IP address %d.%d.%d.%d", + ip4_addr1(&(netif->ip_addr)), + ip4_addr2(&(netif->ip_addr)), + ip4_addr3(&(netif->ip_addr)), + ip4_addr4(&(netif->ip_addr))); + ip_addr.addr = netif->ip_addr.addr; + } + } + + + /* + * Callback function used when doing a link-state change. + */ + static void link_callback(struct netif *netif) + { + /* + * We call the status callback at this point to print + * the IP address because we may have got a new one, + * e.h., we joined another wireless network. + */ + status_callback(netif); + } + /******************** ** Initialization ** @@ -141,7 +158,6 @@ extern "C" { Genode::size_t tx_buf_size, Genode::size_t rx_buf_size) { - static struct netif netif; struct ip_addr ip, nm, gw; static struct netif_buf_sizes nbs; nbs.tx_buf_size = tx_buf_size; @@ -174,25 +190,11 @@ extern "C" { /* If no static ip was set, we do dhcp */ if (!ip_addr) { #if LWIP_DHCP - /* Register callback function triggered, when DHCP succeeded. */ - netif.status_callback = dhcp_callback; + /* Register callback functions. */ + netif.status_callback = status_callback; + netif.link_callback = link_callback; - /* Start DHCP requests */ netifapi_dhcp_start(&netif); - - /* Block until DHCP succeeded or a timeout was triggered */ - try { - dhcp_semaphore()->down(20000); - } catch (Genode::Timeout_exception) { - PWRN("DHCP timed out!"); - netifapi_dhcp_stop(&netif); - return 1; - } - PINF("got IP address %d.%d.%d.%d", - ip4_addr1(&(netif.ip_addr)), - ip4_addr2(&(netif.ip_addr)), - ip4_addr3(&(netif.ip_addr)), - ip4_addr4(&(netif.ip_addr))); #else /* no IP address - no networking */ return 1; @@ -208,6 +210,15 @@ extern "C" { } + void lwip_nic_link_state_changed(int state) + { + if (state) + netifapi_netif_set_link_up(&netif); + else + netifapi_netif_set_link_down(&netif); + } + + /*************** ** Semaphore ** ***************/