void LWIP::Interface::netif_status_irq(struct netif *netif) { LWIP::Interface *interface = our_if_from_netif(netif); nsapi_connection_status_t connectedStatusPrev = interface->connected; if (netif_is_up(&interface->netif) && netif_is_link_up(&interface->netif)) { bool dns_addr_has_to_be_added = false; if (!(interface->has_addr_state & HAS_ANY_ADDR) && LWIP::get_ip_addr(true, netif)) { if (interface->blocking) { osSemaphoreRelease(interface->has_any_addr); } interface->has_addr_state |= HAS_ANY_ADDR; dns_addr_has_to_be_added = true; } #if PREF_ADDR_TIMEOUT if (!(interface->has_addr_state & HAS_PREF_ADDR) && LWIP::get_ip_addr(false, netif)) { if (interface->blocking) { osSemaphoreRelease(interface->has_pref_addr); } interface->has_addr_state |= HAS_PREF_ADDR; dns_addr_has_to_be_added = true; } #endif #if BOTH_ADDR_TIMEOUT if (!(interface->has_addr_state & HAS_BOTH_ADDR) && LWIP::get_ipv4_addr(netif) && LWIP::get_ipv6_addr(netif)) { if (interface->blocking) { osSemaphoreRelease(interface->has_both_addr); } interface->has_addr_state |= HAS_BOTH_ADDR; dns_addr_has_to_be_added = true; } #endif if (dns_addr_has_to_be_added && !interface->blocking) { add_dns_addr(&interface->netif); } if (interface->has_addr_state & HAS_ANY_ADDR) { interface->connected = NSAPI_STATUS_GLOBAL_UP; } } else if (!netif_is_up(&interface->netif) && netif_is_link_up(&interface->netif)) { interface->connected = NSAPI_STATUS_DISCONNECTED; } if (interface->client_callback && (connectedStatusPrev != interface->connected) && interface->connected != NSAPI_STATUS_DISCONNECTED) { /* advertised by bring_down */ interface->client_callback(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, interface->connected); } }
static err_t low_level_output(struct netif* netif, struct pbuf* p) { err_t retVal = ERR_CONN; if (netif_is_link_up(netif)) { pbuf_ref(p); panIf.statusCallback(cbIP_NETWORK_ACTIVITY, NULL, NULL, panIf.callbackArg); cb_uint32 totSize = cbIP_getDataFrameSize((cbIP_frame*)p); UAllocTraits_t t; t.flags = 0; t.extended = 0; cb_uint8* buf = mbed_ualloc(totSize,t); MBED_ASSERT(buf != NULL); // Throw away packets if we can not allocate? cb_boolean status = cbIP_copyFromDataFrame(buf, (cbIP_frame*)p, totSize, 0); MBED_ASSERT(status); cb_int32 result = cbBTPAN_reqData(panIf.connHandle,buf,totSize); if(result == cbBTPAN_RESULT_OK) { retVal = ERR_OK; LINK_STATS_INC(link.xmit); } else { printf("low_level_output - packet dropped\n"); } mbed_ufree(buf); return retVal; } LINK_STATS_INC(link.drop); return retVal; }
/** * @brief Configurates the network interface * @param None * @retval None */ static void Netif_Config(void) { struct ip_addr ipaddr; struct ip_addr netmask; struct ip_addr gw; IP4_ADDR(&ipaddr, IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3); IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1 , NETMASK_ADDR2, NETMASK_ADDR3); IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3); /* add the network interface */ netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, ðernetif_init, ðernet_input); /* Registers the default network interface */ netif_set_default(&gnetif); if (netif_is_link_up(&gnetif)) { /* When the netif is fully configured this function must be called */ netif_set_up(&gnetif); } else { /* When the netif link is down this function must be called */ netif_set_down(&gnetif); } }
/** * @brief This function notify user about link status changement. * @param netif: the network interface * @retval None */ void ethernetif_notify_conn_changed(struct netif *netif) { struct ip_addr ipaddr; struct ip_addr netmask; struct ip_addr gw; if(netif_is_link_up(netif)) { IP4_ADDR(&ipaddr, IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3); IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1 , NETMASK_ADDR2, NETMASK_ADDR3); IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3); netif_set_addr(netif, &ipaddr , &netmask, &gw); /* When the netif is fully configured this function must be called.*/ netif_set_up(netif); BSP_LED_Off(LED2); BSP_LED_On(LED1); } else { /* When the netif link is down this function must be called.*/ netif_set_down(netif); BSP_LED_Off(LED1); BSP_LED_On(LED2); } }
/* init function */ void MX_LWIP_Init(void) { tcpip_init( NULL, NULL ); /* add the network interface */ netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, ðernetif_init, &tcpip_input); /* Registers the default network interface */ netif_set_default(&gnetif); if (netif_is_link_up(&gnetif)) { /* When the netif is fully configured this function must be called */ netif_set_up(&gnetif); } else { /* When the netif link is down this function must be called */ netif_set_down(&gnetif); } dhcp_start(&gnetif); /* USER CODE BEGIN 3 */ /* USER CODE END 3 */ }
/** * @brief This function notify user about link status changement. * @param netif: the network interface * @retval None */ void ethernetif_notify_conn_changed(struct netif *netif) { struct ip_addr ipaddr; struct ip_addr netmask; struct ip_addr gw; if(netif_is_link_up(netif)) { VNC_SERVER_LogMessage ("Cable is now connected."); /* Update DHCP state machine */ VNC_State = VNC_LINK_UP; VNC_SERVER_StatusChanged(VNC_LINK_UP); netif_set_addr(netif, &ipaddr , &netmask, &gw); /* When the netif is fully configured this function must be called.*/ netif_set_up(netif); } else { /* Update DHCP state machine */ VNC_State = VNC_LINK_DOWN; /* When the netif link is down this function must be called.*/ netif_set_down(netif); VNC_SERVER_LogMessage ("Cable is not connected."); closesocket(_Sock); } }
/** * @brief This function notify user about link status changement. * @param netif: the network interface * @retval None */ void ethernetif_notify_conn_changed(struct netif *netif) { ip_addr_t ipaddr; ip_addr_t netmask; ip_addr_t gw; if(netif_is_link_up(netif)) { #ifdef USE_DHCP /* Update DHCP state machine */ DHCP_state = DHCP_START; #else IP4_ADDR(&ipaddr, IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3); IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1 , NETMASK_ADDR2, NETMASK_ADDR3); IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3); #endif /* USE_DHCP */ netif_set_addr(netif, &ipaddr , &netmask, &gw); /* When the netif is fully configured this function must be called.*/ netif_set_up(netif); } else { #ifdef USE_DHCP /* Update DHCP state machine */ DHCP_state = DHCP_LINK_DOWN; #endif /* USE_DHCP */ /* When the netif link is down this function must be called.*/ netif_set_down(netif); } }
/** * @brief Initializes the lwIP stack * @param None * @retval None */ static void Netif_Config(void) { struct ip_addr ipaddr; struct ip_addr netmask; struct ip_addr gw; /* IP address default setting */ IP4_ADDR(&ipaddr, IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3); IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1 , NETMASK_ADDR2, NETMASK_ADDR3); IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3); /* add the network interface */ netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, ðernetif_init, ðernet_input); /* Registers the default network interface */ netif_set_default(&gnetif); if (netif_is_link_up(&gnetif)) { /* When the netif is fully configured this function must be called */ netif_set_up(&gnetif); } else { /* When the netif link is down this function must be called */ netif_set_down(&gnetif); } /* Set the link callback function, this function is called on change of link status*/ netif_set_link_callback(&gnetif, ethernetif_update_config); }
/** * @brief This function notify user about link status changement. * @param netif: the network interface * @retval None */ void ethernetif_notify_conn_changed(struct netif *netif) { struct ip_addr ipaddr; struct ip_addr netmask; struct ip_addr gw; if(netif_is_link_up(netif)) { #ifdef USE_DHCP #ifdef USE_LCD LCD_UsrLog ("The network cable is now connected \n"); #else BSP_LED_Off(LED2); BSP_LED_On(LED1); #endif /* USE_LCD */ /* Update DHCP state machine */ DHCP_state = DHCP_START; #else IP4_ADDR(&ipaddr, IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3); IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1 , NETMASK_ADDR2, NETMASK_ADDR3); IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3); #ifdef USE_LCD uint8_t iptxt[20]; sprintf((char*)iptxt, "%d.%d.%d.%d", IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3); LCD_UsrLog ("The network cable is now connected \n"); LCD_UsrLog ("Static IP address: %s\n", iptxt); #else BSP_LED_Off(LED2); BSP_LED_On(LED1); #endif /* USE_LCD */ #endif /* USE_DHCP */ netif_set_addr(netif, &ipaddr , &netmask, &gw); /* When the netif is fully configured this function must be called.*/ netif_set_up(netif); } else { #ifdef USE_DHCP /* Update DHCP state machine */ DHCP_state = DHCP_LINK_DOWN; #endif /* USE_DHCP */ /* When the netif link is down this function must be called.*/ netif_set_down(netif); #ifdef USE_LCD LCD_UsrLog ("The network cable is not connected \n"); #else BSP_LED_Off(LED1); BSP_LED_On(LED2); #endif /* USE_LCD */ } /* Clear MFX IO Expander Interrupt flag */ BSP_IO_ITClear(); }
void LWIP::Interface::netif_link_irq(struct netif *netif) { LWIP::Interface *interface = our_if_from_netif(netif); nsapi_connection_status_t connectedStatusPrev = interface->connected; if (netif_is_link_up(&interface->netif) && interface->connected == NSAPI_STATUS_CONNECTING) { nsapi_error_t dhcp_status = interface->set_dhcp(); if (interface->blocking && dhcp_status == NSAPI_ERROR_OK) { osSemaphoreRelease(interface->linked); } else if (dhcp_status != NSAPI_ERROR_OK) { netif_set_down(&interface->netif); } } else { osSemaphoreRelease(interface->unlinked); if (netif_is_up(&interface->netif)) { interface->connected = NSAPI_STATUS_CONNECTING; } netif_set_down(&interface->netif); } if (interface->client_callback && connectedStatusPrev != interface->connected && interface->connected != NSAPI_STATUS_GLOBAL_UP /* advertised by netif_status_irq */ && interface->connected != NSAPI_STATUS_DISCONNECTED) { /* advertised by bring_down */ interface->client_callback(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, interface->connected); } }
static void mbed_lwip_netif_link_irq(struct netif *lwip_netif) { if (netif_is_link_up(lwip_netif)) { sys_sem_signal(&lwip_netif_linked); } else { sys_sem_signal(&lwip_netif_unlinked); } }
/** * @brief Initializes the lwIP stack * @param None * @retval None */ static void Netif_Config(void) { struct ip_addr ipaddr; struct ip_addr netmask; struct ip_addr gw; /* IP address setting */ IP4_ADDR(&ipaddr, IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3); IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1 , NETMASK_ADDR2, NETMASK_ADDR3); IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3); /* - netif_add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask, struct ip_addr *gw, void *state, err_t (* init)(struct netif *netif), err_t (* input)(struct pbuf *p, struct netif *netif)) Adds your network interface to the netif_list. Allocate a struct netif and pass a pointer to this structure as the first argument. Give pointers to cleared ip_addr structures when using DHCP, or fill them with sane numbers otherwise. The state pointer may be NULL. The init function pointer must point to a initialization function for your ethernet netif interface. The following code illustrates it's use.*/ netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, ðernetif_init, &tcpip_input); /* Registers the default network interface. */ netif_set_default(&gnetif); if (netif_is_link_up(&gnetif)) { /* When the netif is fully configured this function must be called.*/ netif_set_up(&gnetif); } else { /* When the netif link is down this function must be called */ netif_set_down(&gnetif); } /* Set the link callback function, this function is called on change of link status*/ netif_set_link_callback(&gnetif, ethernetif_update_config); /* create a binary semaphore used for informing ethernetif of frame reception */ osSemaphoreDef(Netif_SEM); Netif_LinkSemaphore = osSemaphoreCreate(osSemaphore(Netif_SEM) , 1 ); link_arg.netif = &gnetif; link_arg.semaphore = Netif_LinkSemaphore; /* Create the Ethernet link handler thread */ #if defined(__GNUC__) osThreadDef(LinkThr, ethernetif_set_link, osPriorityNormal, 0, configMINIMAL_STACK_SIZE * 5); #else osThreadDef(LinkThr, ethernetif_set_link, osPriorityNormal, 0, configMINIMAL_STACK_SIZE * 2); #endif osThreadCreate (osThread(LinkThr), &link_arg); }
static void link_callback(struct netif *state_netif) { if (netif_is_link_up(state_netif)) { printf("link_callback==UP\n"); } else { printf("link_callback==DOWN\n"); } }
void link_callback(struct netif *netif) { if (netif_is_link_up(netif)) { printf("link_callback==UP\n"); #if USE_DHCP if (netif->dhcp != NULL) { dhcp_renew(netif); } #endif /* USE_DHCP */ } else { printf("link_callback==DOWN\n"); } }
nsapi_error_t mbed_lwip_bringdown_2(bool ppp) { // Check if we've connected if (lwip_connected == NSAPI_STATUS_DISCONNECTED) { return NSAPI_ERROR_PARAMETER; } #if LWIP_DHCP // Disconnect from the network if (lwip_dhcp) { dhcp_release(&lwip_netif); dhcp_stop(&lwip_netif); lwip_dhcp = false; lwip_dhcp_has_to_be_set = false; } #endif if (ppp) { /* this is a blocking call, returns when PPP is properly closed */ err_t err = ppp_lwip_disconnect(); if (err) { return mbed_lwip_err_remap(err); } MBED_ASSERT(!netif_is_link_up(&lwip_netif)); /*if (netif_is_link_up(&lwip_netif)) { if (sys_arch_sem_wait(&lwip_netif_unlinked, 15000) == SYS_ARCH_TIMEOUT) { return NSAPI_ERROR_DEVICE_ERROR; } }*/ } else { netif_set_down(&lwip_netif); } #if LWIP_IPV6 mbed_lwip_clear_ipv6_addresses(&lwip_netif); #endif sys_sem_free(&lwip_netif_has_any_addr); sys_sem_new(&lwip_netif_has_any_addr, 0); #if PREF_ADDR_TIMEOUT sys_sem_free(&lwip_netif_has_pref_addr); sys_sem_new(&lwip_netif_has_pref_addr, 0); #endif #if BOTH_ADDR_TIMEOUT sys_sem_free(&lwip_netif_has_both_addr); sys_sem_new(&lwip_netif_has_both_addr, 0); #endif lwip_has_addr_state = 0; lwip_connected = NSAPI_STATUS_DISCONNECTED; return 0; }
void LWIP_SOCKETS_Driver::Link_callback(struct netif *netif) { if (netif_is_link_up(netif)) { if (!PostAvailabilityOnContinuation.IsLinked()) PostAvailabilityOnContinuation.Enqueue(); } else { if (!PostAvailabilityOffContinuation.IsLinked()) PostAvailabilityOffContinuation.Enqueue(); } Events_Set(SYSTEM_EVENT_FLAG_SOCKET); Events_Set(SYSTEM_EVENT_FLAG_NETWORK); }
void LWIP_SOCKETS_Driver::TcpipInitDone(void* arg) { struct netif *pNetIf; for (int i = 0; i<g_NetworkConfig.NetworkInterfaceCount; i++) { int interfaceNumber; SOCK_NetworkConfiguration *pNetCfg = &g_NetworkConfig.NetworkInterfaces[i]; /* Bind and Open the Ethernet driver */ Network_Interface_Bind(i); interfaceNumber = Network_Interface_Open(i); if (interfaceNumber == SOCK_SOCKET_ERROR) { DEBUG_HANDLE_SOCKET_ERROR("Network init", FALSE); debug_printf("SocketError: %d\n", errno); continue; } g_LWIP_SOCKETS_Driver.m_interfaces[i].m_interfaceNumber = interfaceNumber; UpdateAdapterConfiguration(i, SOCK_NETWORKCONFIGURATION_UPDATE_DHCP | SOCK_NETWORKCONFIGURATION_UPDATE_DNS, pNetCfg); pNetIf = netif_find_interface(interfaceNumber); if (pNetIf) { netif_set_link_callback(pNetIf, Link_callback); if (netif_is_link_up(pNetIf)) Link_callback(pNetIf); netif_set_status_callback(pNetIf, Status_callback); if (netif_is_up(pNetIf)) Status_callback(pNetIf); // default debugger interface if (0 == i) { UINT8* addr = (UINT8*)&pNetIf->ip_addr.addr; lcd_printf("\f\n\n\n\n\n\n\nip address: %d.%d.%d.%d\r\n", addr[0], addr[1], addr[2], addr[3]); debug_printf("ip address from interface info: %d.%d.%d.%d\r\n", addr[0], addr[1], addr[2], addr[3]); } } } }
/* init function */ void MX_LWIP_Init(void) { IP_ADDRESS[0] = 192; IP_ADDRESS[1] = 168; IP_ADDRESS[2] = 203; IP_ADDRESS[3] = 36; NETMASK_ADDRESS[0] = 255; NETMASK_ADDRESS[1] = 255; NETMASK_ADDRESS[2] = 255; NETMASK_ADDRESS[3] = 0; GATEWAY_ADDRESS[0] = 192; GATEWAY_ADDRESS[1] = 168; GATEWAY_ADDRESS[2] = 203; GATEWAY_ADDRESS[3] = 2; tcpip_init( NULL, NULL ); IP4_ADDR(&ipaddr, IP_ADDRESS[0], IP_ADDRESS[1], IP_ADDRESS[2], IP_ADDRESS[3]); IP4_ADDR(&netmask, NETMASK_ADDRESS[0], NETMASK_ADDRESS[1] , NETMASK_ADDRESS[2], NETMASK_ADDRESS[3]); IP4_ADDR(&gw, GATEWAY_ADDRESS[0], GATEWAY_ADDRESS[1], GATEWAY_ADDRESS[2], GATEWAY_ADDRESS[3]); /* add the network interface */ netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, ðernetif_init, &tcpip_input); /* Registers the default network interface */ netif_set_default(&gnetif); if (netif_is_link_up(&gnetif)) { /* When the netif is fully configured this function must be called */ netif_set_up(&gnetif); } else { /* When the netif link is down this function must be called */ netif_set_down(&gnetif); } /* USER CODE BEGIN 3 */ /* USER CODE END 3 */ }
static void mbed_lwip_netif_link_irq(struct netif *lwip_netif) { if (netif_is_link_up(lwip_netif)) { nsapi_error_t dhcp_status = mbed_set_dhcp(lwip_netif); if (lwip_blocking && dhcp_status == NSAPI_ERROR_OK) { sys_sem_signal(&lwip_netif_linked); } else if (dhcp_status != NSAPI_ERROR_OK) { netif_set_down(lwip_netif); } } else { sys_sem_signal(&lwip_netif_unlinked); netif_set_down(lwip_netif); } }
/** * @brief This function notify user about link status changement. * @param netif: the network interface * @retval None */ void ethernetif_notify_conn_changed(struct netif *netif) { struct ip_addr ipaddr; struct ip_addr netmask; struct ip_addr gw; if(netif_is_link_up(netif)) { /* IP address setting */ IP4_ADDR(&ipaddr, ip_address[3], ip_address[2], ip_address[1], ip_address[0]); IP4_ADDR(&netmask, sn_mask[3], sn_mask[2] , sn_mask[1], sn_mask[0]); IP4_ADDR(&gw, gw_address[3], gw_address[2], gw_address[1], gw_address[0]); netif_set_addr(netif, &ipaddr , &netmask, &gw); /* When the netif is fully configured this function must be called.*/ netif_set_up(netif); _VNCServer_Notify(NOTIFY_SERVER_NETIF_UP); /* If DHCP: re-start process */ if (_DHCPClinet_TCB != 0) { /* Update DHCP state machine */ DHCP_state = DHCP_START; } } else { /* When the netif link is down this function must be called.*/ netif_set_down(netif); _VNCServer_Notify(NOTIFY_SERVER_NETIF_DOWN); /* If DHCP: stop process */ if (_DHCPClinet_TCB != 0) { /* Update DHCP state machine */ DHCP_state = DHCP_LINK_DOWN; } } /* Clear IO Expander Interrupt flag */ BSP_IO_ITClear(); }
/** * @brief This function notify user about link status changement. * @param netif: the network interface * @retval None */ void ethernetif_notify_conn_changed(struct netif *netif) { struct ip_addr ipaddr; struct ip_addr netmask; struct ip_addr gw; if(netif_is_link_up(netif)) { #ifdef USE_DHCP WriteConsole ("The network cable is now connected \n"); /* Update DHCP state machine */ DHCP_state = DHCP_START; #else IP4_ADDR(&ipaddr, IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3); IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1 , NETMASK_ADDR2, NETMASK_ADDR3); IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3); uint8_t iptxt[80]; sprintf((char*)iptxt, "%d.%d.%d.%d", IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3); WriteConsole ("The network cable is now connected \n"); sprintf((char*)iptxt, "Static IP address: %d.%d.%d.%d", IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3); WriteConsole (iptxt); #endif /* USE_DHCP */ netif_set_addr(netif, &ipaddr , &netmask, &gw); /* When the netif is fully configured this function must be called.*/ netif_set_up(netif); } else { #ifdef USE_DHCP /* Update DHCP state machine */ DHCP_state = DHCP_LINK_DOWN; #endif /* USE_DHCP */ /* When the netif link is down this function must be called.*/ netif_set_down(netif); WriteConsole ("The network cable is not connected \n"); } }
/** * @brief Initializes the lwIP stack * @param None * @retval None */ static void Netif_Config(void) { struct ip_addr ipaddr; struct ip_addr netmask; struct ip_addr gw; /* IP address setting */ IP4_ADDR(&ipaddr, IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3); IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1 , NETMASK_ADDR2, NETMASK_ADDR3); IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3); /* - netif_add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask, struct ip_addr *gw, void *state, err_t (* init)(struct netif *netif), err_t (* input)(struct pbuf *p, struct netif *netif)) Adds your network interface to the netif_list. Allocate a struct netif and pass a pointer to this structure as the first argument. Give pointers to cleared ip_addr structures when using DHCP, or fill them with sane numbers otherwise. The state pointer may be NULL. The init function pointer must point to a initialization function for your ethernet netif interface. The following code illustrates it's use.*/ netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, ðernetif_init, &tcpip_input); /* Registers the default network interface. */ netif_set_default(&gnetif); if (netif_is_link_up(&gnetif)) { /* When the netif is fully configured this function must be called.*/ netif_set_up(&gnetif); } else { /* When the netif link is down this function must be called */ netif_set_down(&gnetif); } }
/* init function */ void MX_LWIP_Init(void) { /* Initilialize the LwIP stack */ lwip_init(); ipaddr.addr = 0; netmask.addr = 0; gw.addr = 0; /* add the network interface */ #if LWIP_ARP netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, ðernetif_init, ðernet_input); /* Registers the default network interface */ netif_set_default(&gnetif); if (netif_is_link_up(&gnetif)) { /* When the netif is fully configured this function must be called */ netif_set_up(&gnetif); } else { /* When the netif link is down this function must be called */ netif_set_down(&gnetif); } #endif /* LWIP_ARP || LWIP_ETHERNET */ dhcp_start(&gnetif); /* USER CODE BEGIN 3 */ /* USER CODE END 3 */ }
/** * Finds the appropriate network interface for a given IPv6 address. It tries to select * a netif following a sequence of heuristics: * 1) if there is only 1 netif, return it * 2) if the destination is a link-local address, try to match the src address to a netif. * this is a tricky case because with multiple netifs, link-local addresses only have * meaning within a particular subnet/link. * 3) tries to match the destination subnet to a configured address * 4) tries to find a router * 5) tries to match the source address to the netif * 6) returns the default netif, if configured * * @param src the source IPv6 address, if known * @param dest the destination IPv6 address for which to find the route * @return the netif on which to send to reach dest */ struct netif * ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest) { struct netif *netif; s8_t i; #ifdef LWIP_HOOK_IP6_ROUTE netif = LWIP_HOOK_IP6_ROUTE(src, dest); if (netif != NULL) { return netif; } #endif /* If single netif configuration, fast return. */ if ((netif_list != NULL) && (netif_list->next == NULL)) { if (!netif_is_up(netif_list) || !netif_is_link_up(netif_list)) { return NULL; } return netif_list; } /* Special processing for link-local addresses. */ if (ip6_addr_islinklocal(dest)) { if (ip6_addr_isany(src)) { /* Use default netif, if Up. */ if (!netif_is_up(netif_default) || !netif_is_link_up(netif_default)) { return NULL; } return netif_default; } /* Try to find the netif for the source address, checking that link is up. */ for (netif = netif_list; netif != NULL; netif = netif->next) { if (!netif_is_up(netif) || !netif_is_link_up(netif)) { continue; } for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && ip6_addr_cmp(src, netif_ip6_addr(netif, i))) { return netif; } } } /* netif not found, use default netif, if up */ if (!netif_is_up(netif_default) || !netif_is_link_up(netif_default)) { return NULL; } return netif_default; } /* See if the destination subnet matches a configured address. */ for (netif = netif_list; netif != NULL; netif = netif->next) { if (!netif_is_up(netif) || !netif_is_link_up(netif)) { continue; } for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && ip6_addr_netcmp(dest, netif_ip6_addr(netif, i))) { return netif; } } } /* Get the netif for a suitable router. */ i = nd6_select_router(dest, NULL); if (i >= 0) { if (default_router_list[i].neighbor_entry != NULL) { if (default_router_list[i].neighbor_entry->netif != NULL) { if (netif_is_up(default_router_list[i].neighbor_entry->netif) && netif_is_link_up(default_router_list[i].neighbor_entry->netif)) { return default_router_list[i].neighbor_entry->netif; } } } } /* try with the netif that matches the source address. */ if (!ip6_addr_isany(src)) { for (netif = netif_list; netif != NULL; netif = netif->next) { if (!netif_is_up(netif) || !netif_is_link_up(netif)) { continue; } for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && ip6_addr_cmp(src, netif_ip6_addr(netif, i))) { return netif; } } } } #if LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF /* loopif is disabled, loopback traffic is passed through any netif */ if (ip6_addr_isloopback(dest)) { /* don't check for link on loopback traffic */ if (netif_is_up(netif_default)) { return netif_default; } /* default netif is not up, just use any netif for loopback traffic */ for (netif = netif_list; netif != NULL; netif = netif->next) { if (netif_is_up(netif)) { return netif; } } return NULL; } #endif /* LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF */ /* no matching netif found, use default netif, if up */ if (!netif_is_up(netif_default) || !netif_is_link_up(netif_default)) { return NULL; } return netif_default; }
static void netif_link_callback(struct netif *netif) { if (netif_is_link_up(netif)) { netif_linked.release(); } }
nsapi_error_t LWIP::Interface::bringdown() { // Check if we've connected if (connected == NSAPI_STATUS_DISCONNECTED) { return NSAPI_ERROR_NO_CONNECTION; } #if LWIP_DHCP // Disconnect from the network if (dhcp_started) { dhcp_release(&netif); dhcp_stop(&netif); dhcp_started = false; dhcp_has_to_be_set = false; } #endif if (ppp) { /* this is a blocking call, returns when PPP is properly closed */ err_t err = ppp_lwip_disconnect(hw); if (err) { return err_remap(err); } MBED_ASSERT(!netif_is_link_up(&netif)); /*if (netif_is_link_up(&netif)) { if (sys_arch_sem_wait(&unlinked, 15000) == SYS_ARCH_TIMEOUT) { return NSAPI_ERROR_DEVICE_ERROR; } }*/ } else { netif_set_down(&netif); } #if LWIP_IPV6 mbed_lwip_clear_ipv6_addresses(&netif); #endif #if LWIP_IPV4 ip_addr_set_zero(&(netif.ip_addr)); ip_addr_set_zero(&(netif.netmask)); ip_addr_set_zero(&(netif.gw)); #endif osSemaphoreDelete(has_any_addr); osSemaphoreAttr_t attr; attr.name = NULL; attr.attr_bits = 0; attr.cb_mem = &has_any_addr_sem; attr.cb_size = sizeof has_any_addr_sem; has_any_addr = osSemaphoreNew(UINT16_MAX, 0, &attr); #if PREF_ADDR_TIMEOUT osSemaphoreDelete(has_pref_addr); attr.cb_mem = &has_pref_addr_sem; attr.cb_size = sizeof has_pref_addr_sem; has_pref_addr = osSemaphoreNew(UINT16_MAX, 0, &attr); #endif #if BOTH_ADDR_TIMEOUT osSemaphoreDelete(has_both_addr); attr.cb_mem = &has_both_addr_sem; attr.cb_size = sizeof has_both_addr_sem; has_both_addr = osSemaphoreNew(UINT16_MAX, 0, &attr); #endif has_addr_state = 0; connected = NSAPI_STATUS_DISCONNECTED; if (client_callback) { client_callback(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, connected); } return 0; }
nsapi_error_t LWIP::Interface::bringup(bool dhcp, const char *ip, const char *netmask, const char *gw, const nsapi_ip_stack_t stack, bool block) { // Check if we've already connected if (connected == NSAPI_STATUS_GLOBAL_UP) { return NSAPI_ERROR_IS_CONNECTED; } else if (connected == NSAPI_STATUS_CONNECTING) { return NSAPI_ERROR_ALREADY; } connected = NSAPI_STATUS_CONNECTING; blocking = block; #if LWIP_DHCP if (stack != IPV6_STACK && dhcp) { dhcp_has_to_be_set = true; } #endif #if LWIP_IPV6 if (stack != IPV4_STACK) { if (netif.hwaddr_len == 6) { netif_create_ip6_linklocal_address(&netif, 1/*from MAC*/); } #if LWIP_IPV6_MLD /* * For hardware/netifs that implement MAC filtering. * All-nodes link-local is handled by default, so we must let the hardware know * to allow multicast packets in. * Should set mld_mac_filter previously. */ if (netif.mld_mac_filter != NULL) { ip6_addr_t ip6_allnodes_ll; ip6_addr_set_allnodes_linklocal(&ip6_allnodes_ll); netif.mld_mac_filter(&netif, &ip6_allnodes_ll, NETIF_ADD_MAC_FILTER); } #endif /* LWIP_IPV6_MLD */ #if LWIP_IPV6_AUTOCONFIG /* IPv6 address autoconfiguration not enabled by default */ netif.ip6_autoconfig_enabled = 1; #endif /* LWIP_IPV6_AUTOCONFIG */ } else { // Disable rourter solicitations netif.rs_count = 0; } #endif /* LWIP_IPV6 */ #if LWIP_IPV4 if (stack != IPV6_STACK) { if (!dhcp && !ppp) { ip4_addr_t ip_addr; ip4_addr_t netmask_addr; ip4_addr_t gw_addr; if (!inet_aton(ip, &ip_addr) || !inet_aton(netmask, &netmask_addr) || !inet_aton(gw, &gw_addr)) { return NSAPI_ERROR_PARAMETER; } netif_set_addr(&netif, &ip_addr, &netmask_addr, &gw_addr); } } #endif if (client_callback) { client_callback(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_STATUS_CONNECTING); } if (ppp) { err_t err = ppp_lwip_connect(hw); if (err) { connected = NSAPI_STATUS_DISCONNECTED; if (client_callback) { client_callback(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_STATUS_DISCONNECTED); } return err_remap(err); } } if (!netif_is_link_up(&netif)) { if (blocking) { if (osSemaphoreAcquire(linked, 15000) != osOK) { if (ppp) { (void) ppp_lwip_disconnect(hw); } return NSAPI_ERROR_NO_CONNECTION; } } } else { nsapi_error_t ret = set_dhcp(); if (ret != NSAPI_ERROR_OK) { return ret; } } if (!blocking) { // Done enough - as addresses are acquired, there will be // connected callbacks. // XXX shouldn't this be NSAPI_ERROR_IN_PROGRESS if in CONNECTING state? return NSAPI_ERROR_OK; } // If doesn't have address if (!LWIP::get_ip_addr(true, &netif)) { if (osSemaphoreAcquire(has_any_addr, DHCP_TIMEOUT * 1000) != osOK) { if (ppp) { (void) ppp_lwip_disconnect(hw); } return NSAPI_ERROR_DHCP_FAILURE; } } #if PREF_ADDR_TIMEOUT if (stack != IPV4_STACK && stack != IPV6_STACK) { // If address is not for preferred stack waits a while to see // if preferred stack address is acquired if (!LWIP::get_ip_addr(false, &netif)) { osSemaphoreAcquire(has_pref_addr, PREF_ADDR_TIMEOUT * 1000); } } #endif #if BOTH_ADDR_TIMEOUT if (stack != IPV4_STACK && stack != IPV6_STACK) { // If addresses for both stacks are not available waits a while to // see if address for both stacks are acquired if (!(LWIP::get_ipv4_addr(&netif) && LWIP::get_ipv6_addr(&netif))) { osSemaphoreAcquire(has_both_addr, BOTH_ADDR_TIMEOUT * 1000); } } #endif add_dns_addr(&netif); return NSAPI_ERROR_OK; }
/** * @brief LWIP handling thread. * * @param[in] p pointer to a @p lwipthread_opts structure or @p NULL * @return The function does not return. */ msg_t lwip_thread(void *p) { event_timer_t evt; event_listener_t el0, el1; struct ip_addr ip, gateway, netmask; static struct netif thisif; static const MACConfig mac_config = {thisif.hwaddr}; chRegSetThreadName("lwipthread"); /* Initializes the thing.*/ tcpip_init(NULL, NULL); /* TCP/IP parameters, runtime or compile time.*/ if (p) { struct lwipthread_opts *opts = p; unsigned i; for (i = 0; i < 6; i++) thisif.hwaddr[i] = opts->macaddress[i]; ip.addr = opts->address; gateway.addr = opts->gateway; netmask.addr = opts->netmask; } else { thisif.hwaddr[0] = LWIP_ETHADDR_0; thisif.hwaddr[1] = LWIP_ETHADDR_1; thisif.hwaddr[2] = LWIP_ETHADDR_2; thisif.hwaddr[3] = LWIP_ETHADDR_3; thisif.hwaddr[4] = LWIP_ETHADDR_4; thisif.hwaddr[5] = LWIP_ETHADDR_5; LWIP_IPADDR(&ip); LWIP_GATEWAY(&gateway); LWIP_NETMASK(&netmask); } macStart(ÐD1, &mac_config); netif_add(&thisif, &ip, &netmask, &gateway, NULL, ethernetif_init, tcpip_input); netif_set_default(&thisif); netif_set_up(&thisif); /* Setup event sources.*/ evtObjectInit(&evt, LWIP_LINK_POLL_INTERVAL); evtStart(&evt); chEvtRegisterMask(&evt.et_es, &el0, PERIODIC_TIMER_ID); chEvtRegisterMask(macGetReceiveEventSource(ÐD1), &el1, FRAME_RECEIVED_ID); chEvtAddEvents(PERIODIC_TIMER_ID | FRAME_RECEIVED_ID); /* Goes to the final priority after initialization.*/ chThdSetPriority(LWIP_THREAD_PRIORITY); while (TRUE) { eventmask_t mask = chEvtWaitAny(ALL_EVENTS); if (mask & PERIODIC_TIMER_ID) { bool_t current_link_status = macPollLinkStatus(ÐD1); if (current_link_status != netif_is_link_up(&thisif)) { if (current_link_status) tcpip_callback_with_block((tcpip_callback_fn) netif_set_link_up, &thisif, 0); else tcpip_callback_with_block((tcpip_callback_fn) netif_set_link_down, &thisif, 0); } } if (mask & FRAME_RECEIVED_ID) { struct pbuf *p; while ((p = low_level_input(&thisif)) != NULL) { struct eth_hdr *ethhdr = p->payload; switch (htons(ethhdr->type)) { /* IP or ARP packet? */ case ETHTYPE_IP: case ETHTYPE_ARP: #if PPPOE_SUPPORT /* PPPoE packet? */ case ETHTYPE_PPPOEDISC: case ETHTYPE_PPPOE: #endif /* PPPOE_SUPPORT */ /* full packet send to tcpip_thread to process */ if (thisif.input(p, &thisif) == ERR_OK) break; LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n")); default: pbuf_free(p); } } } } return 0; }
/** * @brief Link callback function, this function is called on change of link status. * @param The network interface * @retval None */ void ETH_link_callback(struct netif *netif) { __IO uint32_t timeout = 0; uint32_t tmpreg; uint16_t RegValue; struct ip_addr ipaddr; struct ip_addr netmask; struct ip_addr gw; #ifndef USE_DHCP uint8_t iptab[4] = {0}; uint8_t iptxt[20]; #endif /* USE_DHCP */ /* Clear LCD */ // LCD_ClearLine(Line4); // LCD_ClearLine(Line5); // LCD_ClearLine(Line6); // LCD_ClearLine(Line7); // LCD_ClearLine(Line8); // LCD_ClearLine(Line9); if(netif_is_link_up(netif)) { /* Restart the auto-negotiation */ if(ETH_InitStructure.ETH_AutoNegotiation != ETH_AutoNegotiation_Disable) { /* Reset Timeout counter */ timeout = 0; /* Enable auto-negotiation */ ETH_WritePHYRegister(DP83848_PHY_ADDRESS, PHY_BCR, PHY_AutoNegotiation); /* Wait until the auto-negotiation will be completed */ do { timeout++; } while (!(ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_BSR) & PHY_AutoNego_Complete) && (timeout < (uint32_t)PHY_READ_TO)); /* Reset Timeout counter */ timeout = 0; /* Read the result of the auto-negotiation */ RegValue = ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_SR); /* Configure the MAC with the Duplex Mode fixed by the auto-negotiation process */ if((RegValue & PHY_DUPLEX_STATUS) != (uint16_t)RESET) { /* Set Ethernet duplex mode to Full-duplex following the auto-negotiation */ ETH_InitStructure.ETH_Mode = ETH_Mode_FullDuplex; } else { /* Set Ethernet duplex mode to Half-duplex following the auto-negotiation */ ETH_InitStructure.ETH_Mode = ETH_Mode_HalfDuplex; } /* Configure the MAC with the speed fixed by the auto-negotiation process */ if(RegValue & PHY_SPEED_STATUS) { /* Set Ethernet speed to 10M following the auto-negotiation */ ETH_InitStructure.ETH_Speed = ETH_Speed_10M; } else { /* Set Ethernet speed to 100M following the auto-negotiation */ ETH_InitStructure.ETH_Speed = ETH_Speed_100M; } /*------------------------ ETHERNET MACCR Re-Configuration --------------------*/ /* Get the ETHERNET MACCR value */ tmpreg = ETH->MACCR; /* Set the FES bit according to ETH_Speed value */ /* Set the DM bit according to ETH_Mode value */ tmpreg |= (uint32_t)(ETH_InitStructure.ETH_Speed | ETH_InitStructure.ETH_Mode); /* Write to ETHERNET MACCR */ ETH->MACCR = (uint32_t)tmpreg; _eth_delay_(ETH_REG_WRITE_DELAY); tmpreg = ETH->MACCR; ETH->MACCR = tmpreg; } /* Restart MAC interface */ ETH_Start(); #ifdef USE_DHCP ipaddr.addr = 0; netmask.addr = 0; gw.addr = 0; DHCP_state = DHCP_START; #else IP4_ADDR(&ipaddr, IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3); IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1 , NETMASK_ADDR2, NETMASK_ADDR3); IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3); #endif /* USE_DHCP */ netif_set_addr(&gnetif, &ipaddr , &netmask, &gw); /* When the netif is fully configured this function must be called.*/ netif_set_up(&gnetif); #ifdef USE_LCD /* Set the LCD Text Color */ LCD_SetTextColor(Green); /* Display message on the LCD */ LCD_DisplayStringLine(Line5, (uint8_t*)" Network Cable is "); LCD_DisplayStringLine(Line6, (uint8_t*)" now connected "); /* Set the LCD Text Color */ LCD_SetTextColor(White); #ifndef USE_DHCP /* Display static IP address */ iptab[0] = IP_ADDR3; iptab[1] = IP_ADDR2; iptab[2] = IP_ADDR1; iptab[3] = IP_ADDR0; sprintf((char*)iptxt, " %d.%d.%d.%d", iptab[3], iptab[2], iptab[1], iptab[0]); LCD_DisplayStringLine(Line8, (uint8_t*)" Static IP address "); LCD_DisplayStringLine(Line9, iptxt); /* Clear LCD */ LCD_ClearLine(Line5); LCD_ClearLine(Line6); #endif /* USE_DHCP */ #endif /* USE_LCD */ EthLinkStatus = 0; } else { ETH_Stop(); #ifdef USE_DHCP DHCP_state = DHCP_LINK_DOWN; dhcp_stop(netif); #endif /* USE_DHCP */ /* When the netif link is down this function must be called.*/ netif_set_down(&gnetif); #ifdef USE_LCD /* Set the LCD Text Color */ LCD_SetTextColor(Red); /* Display message on the LCD */ LCD_DisplayStringLine(Line5, (uint8_t*)" Network Cable is "); LCD_DisplayStringLine(Line6, (uint8_t*)" unplugged "); /* Set the LCD Text Color */ LCD_SetTextColor(White); #endif /* USE_LCD */ } }
/** * @brief Initializes the lwIP stack * @param None * @retval None */ void LwIP_Init(void) { struct ip_addr ipaddr; struct ip_addr netmask; struct ip_addr gw; #if defined(USE_LCD) && !defined(USE_DHCP) uint8_t iptab[4]; uint8_t iptxt[20]; #endif /* Create tcp_ip stack thread */ tcpip_init( NULL, NULL ); /* IP address setting & display on STM32_evalboard LCD*/ #ifdef USE_DHCP ipaddr.addr = 0; netmask.addr = 0; gw.addr = 0; #else IP4_ADDR(&ipaddr, IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3); IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1, NETMASK_ADDR2, NETMASK_ADDR3); IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3); #ifdef USE_LCD iptab[0] = IP_ADDR3; iptab[1] = IP_ADDR2; iptab[2] = IP_ADDR1; iptab[3] = IP_ADDR0; sprintf((char*)iptxt, " %d.%d.%d.%d", iptab[3], iptab[2], iptab[1], iptab[0]); LCD_DisplayStringLine(Line8, (uint8_t*)" Static IP address "); LCD_DisplayStringLine(Line9, iptxt); #endif #endif /* - netif_add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask, struct ip_addr *gw, void *state, err_t (* init)(struct netif *netif), err_t (* input)(struct pbuf *p, struct netif *netif)) Adds your network interface to the netif_list. Allocate a struct netif and pass a pointer to this structure as the first argument. Give pointers to cleared ip_addr structures when using DHCP, or fill them with sane numbers otherwise. The state pointer may be NULL. The init function pointer must point to a initialization function for your ethernet netif interface. The following code illustrates it's use.*/ netif_add(&xnetif, &ipaddr, &netmask, &gw, NULL, ðernetif_init, &tcpip_input); /* Registers the default network interface */ netif_set_default(&xnetif); if (netif_is_link_up(&xnetif)) { /* When the netif is fully configured this function must be called */ netif_set_up(&xnetif); } else { /* When the netif link is down this function must be called */ netif_set_down(&xnetif); } /* Set the link callback function, this function is called on change of link status */ netif_set_link_callback(&xnetif, ethernetif_update_config); }