#include "include.h" #include #include #include #include "netif/etharp.h" #include "lwip/netif.h" #include #include #include #include #include "lwip/prot/dhcp.h" #include #include "ethernetif.h" #include "sa_station.h" #include "drv_model_pub.h" #include "mem_pub.h" #include "common.h" #include "rw_pub.h" #include "power_save_pub.h" #include "lwip_netif_address.h" #include "rtos_pub.h" #include #include #include #include #include #include "drv_wlan.h" #include #if CFG_ROLE_LAUNCH #include "role_launch.h" #endif #define NET_DEBUG 0 #if NET_DEBUG #define NET_DBG(...) rt_kprintf("[NET]"),rt_kprintf(__VA_ARGS__) #else #define NET_DBG(...) #endif struct ipv4_config sta_ip_settings; struct ipv4_config uap_ip_settings; static int up_iface; uint32_t sta_ip_start_flag = 0; uint32_t uap_ip_start_flag = 0; #ifdef CONFIG_IPV6 #define IPV6_ADDR_STATE_TENTATIVE "Tentative" #define IPV6_ADDR_STATE_PREFERRED "Preferred" #define IPV6_ADDR_STATE_INVALID "Invalid" #define IPV6_ADDR_STATE_VALID "Valid" #define IPV6_ADDR_STATE_DEPRECATED "Deprecated" #define IPV6_ADDR_TYPE_LINKLOCAL "Link-Local" #define IPV6_ADDR_TYPE_GLOBAL "Global" #define IPV6_ADDR_TYPE_UNIQUELOCAL "Unique-Local" #define IPV6_ADDR_TYPE_SITELOCAL "Site-Local" #define IPV6_ADDR_UNKNOWN "Unknown" #endif #define net_e warning_prf #define net_d warning_prf typedef void (*net_sta_ipup_cb_fn)(void *data); struct interface { struct netif *netif; ip_addr_t ipaddr; ip_addr_t nmask; ip_addr_t gw; }; FUNCPTR sta_connected_func; static struct interface g_mlan; static struct interface g_uap; net_sta_ipup_cb_fn sta_ipup_cb = NULL; void *net_get_sta_handle(void); void *net_get_uap_handle(void); err_t lwip_netif_init(struct netif *netif); err_t lwip_netif_uap_init(struct netif *netif); void handle_data_packet(const u8_t interface, const u8_t *rcvdata, const u16_t datalen); int net_get_if_ip_addr(uint32_t *ip, void *intrfc_handle); int net_get_if_ip_mask(uint32_t *nm, void *intrfc_handle); int net_configure_address(struct ipv4_config *addr, void *intrfc_handle); extern int dhcp_server_start(void *intrfc_handle); extern void dhcp_server_stop(void); extern void dhcpd_start(char *netif_name); // extern const ip_addr_t* dns_getserver(u8_t numdns); // extern void dns_setserver(u8_t numdns, ip_addr_t *dnsserver); void net_configure_dns(struct wlan_ip_config *ip); #ifdef CONFIG_IPV6 char *ipv6_addr_state_to_desc(unsigned char addr_state) { if (ip6_addr_istentative(addr_state)) return IPV6_ADDR_STATE_TENTATIVE; else if (ip6_addr_ispreferred(addr_state)) return IPV6_ADDR_STATE_PREFERRED; else if (ip6_addr_isinvalid(addr_state)) return IPV6_ADDR_STATE_INVALID; else if (ip6_addr_isvalid(addr_state)) return IPV6_ADDR_STATE_VALID; else if (ip6_addr_isdeprecated(addr_state)) return IPV6_ADDR_STATE_DEPRECATED; else return IPV6_ADDR_UNKNOWN; } char *ipv6_addr_type_to_desc(struct ipv6_config *ipv6_conf) { if (ip6_addr_islinklocal((ip6_addr_t *)ipv6_conf->address)) return IPV6_ADDR_TYPE_LINKLOCAL; else if (ip6_addr_isglobal((ip6_addr_t *)ipv6_conf->address)) return IPV6_ADDR_TYPE_GLOBAL; else if (ip6_addr_isuniquelocal((ip6_addr_t *)ipv6_conf->address)) return IPV6_ADDR_TYPE_UNIQUELOCAL; else if (ip6_addr_issitelocal((ip6_addr_t *)ipv6_conf->address)) return IPV6_ADDR_TYPE_SITELOCAL; else return IPV6_ADDR_UNKNOWN; } #endif /* CONFIG_IPV6 */ int net_dhcp_hostname_set(char *hostname) { NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); netif_set_hostname(g_mlan.netif, hostname); return 0; } void net_ipv4stack_init() { static bool tcpip_init_done = 0; if (tcpip_init_done) return; NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); net_d("Initializing TCP/IP stack\r\n"); tcpip_init(NULL, NULL); tcpip_init_done = true; } #ifdef CONFIG_IPV6 void net_ipv6stack_init(struct netif *netif) { uint8_t mac[6]; NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); netif->flags |= NETIF_IPV6_FLAG_UP; /* Set Multicast filter for IPV6 link local address * It contains first three bytes: 0x33 0x33 0xff (fixed) * and last three bytes as last three bytes of device mac */ mac[0] = 0x33; mac[1] = 0x33; mac[2] = 0xff; mac[3] = netif->hwaddr[3]; mac[4] = netif->hwaddr[4]; mac[5] = netif->hwaddr[5]; wifi_add_mcast_filter(mac); netif_create_ip6_linklocal_address(netif, 1); netif->ip6_autoconfig_enabled = 1; /* IPv6 routers use multicast IPv6 ff02::1 and MAC address 33:33:00:00:00:01 for router advertisements */ mac[0] = 0x33; mac[1] = 0x33; mac[2] = 0x00; mac[3] = 0x00; mac[4] = 0x00; mac[5] = 0x01; wifi_add_mcast_filter(mac); } static void wm_netif_ipv6_status_callback(struct netif *n) { NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); /* TODO: Implement appropriate functionality here*/ net_d("Received callback on IPv6 address state change"); wlan_wlcmgr_send_msg(WIFI_EVENT_NET_IPV6_CONFIG, WIFI_EVENT_REASON_SUCCESS, NULL); } #endif /* CONFIG_IPV6 */ void net_set_sta_ipup_callback(void *fn) { NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); sta_ipup_cb = (net_sta_ipup_cb_fn)fn; } void user_connected_callback(FUNCPTR fn) { sta_connected_func = fn; } static void wm_netif_status_static_callback(struct netif *n) { if (n->flags & NETIF_FLAG_UP) { // static IP success; os_printf("using static ip...\n"); mhdr_set_station_status(RW_EVT_STA_GOT_IP);/* dhcp success*/ if(sta_ipup_cb != NULL) sta_ipup_cb(NULL); } else { // static IP fail; } } extern int start_connect_tick; int ip_up_tick; extern int _wifi_connect_done(void *ctx); static void wm_netif_status_callback(struct netif *n) { struct dhcp *dhcp; u32 val; FUNC_1PARAM_PTR fn; NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); if (n->flags & NETIF_FLAG_UP) { dhcp = netif_dhcp_data(n); if (dhcp != NULL) { if (dhcp->state == DHCP_STATE_BOUND) { char str[IP4ADDR_STRLEN_MAX]; memset(str, 0, IP4ADDR_STRLEN_MAX); rt_enter_critical(); memcpy(str, ipaddr_ntoa(&n->ip_addr), IP4ADDR_STRLEN_MAX); rt_exit_critical(); os_printf("IP UP: %s \r\n", ipaddr_ntoa(&n->ip_addr)); netif_set_default(n); // rtthread TODO #if CFG_ROLE_LAUNCH rl_pre_sta_set_status(RL_STATUS_STA_LAUNCHED); #endif fn = bk_wlan_get_status_cb(); if(fn) { val = RW_EVT_STA_GOT_IP; (*fn)(&val); } mhdr_set_station_status(RW_EVT_STA_GOT_IP); ip_up_tick = rt_tick_get(); rt_kprintf("[ip_up]:start tick = %d, ip_up tick = %d, total = %d \n", start_connect_tick, ip_up_tick, ip_up_tick - start_connect_tick); _wifi_connect_done(NULL); if (sta_ipup_cb != NULL) sta_ipup_cb(NULL); if (sta_connected_func != NULL) (*sta_connected_func)(); #if CFG_USE_STA_PS auto_check_dtim_rf_ps_mode(); #endif } else { // dhcp fail } } else { // static IP success; } } else { // dhcp fail; } } static int check_iface_mask(void *handle, uint32_t ipaddr) { NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); uint32_t interface_ip, interface_mask; net_get_if_ip_addr(&interface_ip, handle); net_get_if_ip_mask(&interface_mask, handle); if (interface_ip > 0) if ((interface_ip & interface_mask) == (ipaddr & interface_mask)) return 0; return -1; } void *net_ip_to_interface(uint32_t ipaddr) { int ret; struct interface *handle; NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); /* Check mlan handle */ handle = (struct interface *)net_get_sta_handle(); ret = check_iface_mask(handle->netif, ipaddr); if (ret == 0) return handle; /* Check uap handle */ handle = net_get_uap_handle(); ret = check_iface_mask(handle, ipaddr); if (ret == 0) return handle; /* If more interfaces are added then above check needs to done for * those newly added interfaces */ return NULL; } void *net_sock_to_interface(int sock) { struct sockaddr_in peer; unsigned long peerlen = sizeof(struct sockaddr_in); void *req_iface = NULL; NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); lwip_getpeername(sock, (struct sockaddr *)&peer, &peerlen); req_iface = net_ip_to_interface(peer.sin_addr.s_addr); return req_iface; } void *net_get_sta_handle(void) { NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); return &g_mlan; } void *net_get_uap_handle(void) { NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); return &g_uap; } void *net_get_netif_handle(uint8_t iface) { NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); return NULL; } void net_interface_up(void *intrfc_handle) { NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); struct interface *if_handle = (struct interface *)intrfc_handle; netifapi_netif_set_up(if_handle->netif); } void net_interface_down(void *intrfc_handle) { NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); struct interface *if_handle = (struct interface *)intrfc_handle; netifapi_netif_set_down(if_handle->netif); } #ifdef CONFIG_IPV6 void net_interface_deregister_ipv6_callback(void *intrfc_handle) { NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); struct interface *if_handle = (struct interface *)intrfc_handle; if (intrfc_handle == &g_mlan) netif_set_ipv6_status_callback(if_handle->netif, NULL); } #endif void net_interface_dhcp_stop(void *intrfc_handle) { NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); struct interface *if_handle = (struct interface *)intrfc_handle; netifapi_dhcp_stop(if_handle->netif); netif_set_status_callback(if_handle->netif, NULL); } void sta_ip_down(void) { NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); if (sta_ip_start_flag) { os_printf("sta_ip_down\r\n"); sta_ip_start_flag = 0; netifapi_netif_set_down(g_mlan.netif); netif_set_status_callback(g_mlan.netif, NULL); netifapi_dhcp_stop(g_mlan.netif); } } void sta_ip_start(void) { NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); if (!sta_ip_start_flag) { os_printf("sta_ip_start\r\n"); sta_ip_start_flag = 1; net_configure_address(&sta_ip_settings, net_get_sta_handle()); } else { if(mhdr_get_station_status() == RW_EVT_STA_CONNECTED) { mhdr_set_station_status(RW_EVT_STA_GOT_IP); } } } void sta_set_vif_netif(void) { NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); rwm_mgmt_set_vif_netif(g_mlan.netif); } void ap_set_vif_netif(void) { NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); rwm_mgmt_set_vif_netif(g_uap.netif); } void sta_set_default_netif(void) { NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); struct interface *if_handle = (struct interface *)net_get_sta_handle(); netifapi_netif_set_default(if_handle->netif); } void ap_set_default_netif(void) { NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); // as the default netif is sta's netif, so ap need to send // boardcast or not sub net packets, need set ap netif before // send those packets, after finish sending, reset default netif // to sat's netif. struct interface *if_handle = (struct interface *)net_get_uap_handle(); netifapi_netif_set_default(if_handle->netif); } void reset_default_netif(void) { NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); netifapi_netif_set_default(NULL); } uint32_t sta_ip_is_start(void) { NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); return sta_ip_start_flag; } void uap_ip_down(void) { NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); if (uap_ip_start_flag) { os_printf("uap_ip_down\r\n"); uap_ip_start_flag = 0; netifapi_netif_set_down(g_uap.netif); netif_set_status_callback(g_uap.netif, NULL); rt_kprintf("please use rtthread dncp stop server\n"); // dhcp_server_stop(); } } void uap_ip_start(void) { NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); if (!uap_ip_start_flag) { os_printf("uap_ip_start\r\n"); uap_ip_start_flag = 1; net_configure_address(&uap_ip_settings, net_get_uap_handle()); } } uint32_t uap_ip_is_start(void) { NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); return uap_ip_start_flag; } #define DEF_UAP_IP 0xc0a80a01UL /* 192.168.10.1 */ void ip_address_set(int iface, int dhcp, char *ip, char *mask, char *gw, char *dns) { NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); uint32_t tmp; struct ipv4_config addr; memset(&addr, 0, sizeof(struct ipv4_config)); if (dhcp == 1) { addr.addr_type = ADDR_TYPE_DHCP; } else { addr.addr_type = ADDR_TYPE_STATIC; tmp = inet_addr((char *)ip); addr.address = (tmp); tmp = inet_addr((char *)mask); if (tmp == 0xFFFFFFFF) tmp = 0x00FFFFFF;// if not set valid netmask, set as 255.255.255.0 addr.netmask = (tmp); tmp = inet_addr((char *)gw); addr.gw = (tmp); tmp = inet_addr((char *)dns); addr.dns1 = (tmp); } if (iface == 1) // Station memcpy(&sta_ip_settings, &addr, sizeof(addr)); else memcpy(&uap_ip_settings, &addr, sizeof(addr)); } int net_configure_address(struct ipv4_config *addr, void *intrfc_handle) { if (!intrfc_handle) return -1; NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); struct interface *if_handle = (struct interface *)intrfc_handle; net_d("\r\nconfiguring interface %s (with %s)", (if_handle == &g_mlan) ? "mlan" : "uap", (addr->addr_type == ADDR_TYPE_DHCP) ? "DHCP client" : "Static IP"); os_printf("\n"); netifapi_netif_set_down(if_handle->netif); /* De-register previously registered DHCP Callback for correct * address configuration. */ netif_set_status_callback(if_handle->netif, NULL); #ifdef CONFIG_IPV6 if (if_handle == &g_mlan) { netif_set_ipv6_status_callback(&if_handle->netif, wm_netif_ipv6_status_callback); /* Explicitly call this function so that the linklocal address * gets updated even if the interface does not get any IPv6 * address in its lifetime */ wm_netif_ipv6_status_callback(&if_handle->netif); } #endif switch (addr->addr_type) { case ADDR_TYPE_STATIC: if_handle->ipaddr.addr = addr->address; if_handle->nmask.addr = addr->netmask; if_handle->gw.addr = addr->gw; netifapi_netif_set_addr(if_handle->netif, &if_handle->ipaddr, &if_handle->nmask, &if_handle->gw); netif_set_status_callback(if_handle->netif, wm_netif_status_static_callback); netifapi_netif_set_up(if_handle->netif); if (!strncmp(if_handle->netif->name, WIFI_DEVICE_STA_NAME, sizeof(if_handle->netif->name))) { net_configure_dns((struct wlan_ip_config *)addr); } break; case ADDR_TYPE_DHCP: NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); /* Reset the address since we might be transitioning from static to DHCP */ memset(&if_handle->ipaddr, 0, sizeof(ip_addr_t)); memset(&if_handle->nmask, 0, sizeof(ip_addr_t)); memset(&if_handle->gw, 0, sizeof(ip_addr_t)); netifapi_netif_set_addr(if_handle->netif, &if_handle->ipaddr, &if_handle->nmask, &if_handle->gw); netif_set_status_callback(if_handle->netif, wm_netif_status_callback); netifapi_netif_set_up(if_handle->netif); netifapi_dhcp_start(if_handle->netif); net_configure_dns((struct wlan_ip_config*)addr); break; default: break; } /* Finally this should send the following event. */ if (if_handle == &g_mlan) { // static IP up; /* XXX For DHCP, the above event will only indicate that the * DHCP address obtaining process has started. Once the DHCP * address has been obtained, another event, * WD_EVENT_NET_DHCP_CONFIG, should be sent to the wlcmgr. */ up_iface = 1; // we always set sta netif as the default. sta_set_default_netif(); } else { // softap IP up, start dhcp server; rt_kprintf("please use rtthread dncp start server\n"); dhcpd_start(WIFI_DEVICE_AP_NAME); // dhcp_server_start(net_get_uap_handle()); up_iface = 0; // as the default netif is sta's netif, so ap need to send // boardcast or not sub net packets, need set ap netif before // send those packets, after finish sending, reset default netif // to sta's netif. os_printf("def netif is no ap's netif, sending boardcast or no-subnet ip packets may failed\r\n"); } return 0; } int net_get_if_addr(struct wlan_ip_config *addr, void *intrfc_handle) { const ip_addr_t *tmp; struct interface *if_handle = (struct interface *)intrfc_handle; NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); addr->ipv4.address = if_handle->netif->ip_addr.addr; addr->ipv4.netmask = if_handle->netif->netmask.addr; addr->ipv4.gw = if_handle->netif->gw.addr; tmp = dns_getserver(0); addr->ipv4.dns1 = tmp->addr; tmp = dns_getserver(1); addr->ipv4.dns2 = tmp->addr; return 0; } int net_get_if_macaddr(void *macaddr, void *intrfc_handle) { struct interface *if_handle = (struct interface *)intrfc_handle; NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); os_memcpy(macaddr, &if_handle->netif->hwaddr[0], if_handle->netif->hwaddr_len); return 0; } #ifdef CONFIG_IPV6 int net_get_if_ipv6_addr(struct wlan_ip_config *addr, void *intrfc_handle) { struct interface *if_handle = (struct interface *)intrfc_handle; int i; NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); for (i = 0; i < MAX_IPV6_ADDRESSES; i++) { memcpy(addr->ipv6[i].address, if_handle->netif.ip6_addr[i].addr, 16); addr->ipv6[i].addr_state = if_handle->netif.ip6_addr_state[i]; } /* TODO carry out more processing based on IPv6 fields in netif */ return 0; } int net_get_if_ipv6_pref_addr(struct wlan_ip_config *addr, void *intrfc_handle) { int i, ret = 0; struct interface *if_handle = (struct interface *)intrfc_handle; NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); for (i = 0; i < MAX_IPV6_ADDRESSES; i++) { if (if_handle->netif.ip6_addr_state[i] == IP6_ADDR_PREFERRED) { memcpy(addr->ipv6[ret++].address, if_handle->netif.ip6_addr[i].addr, 16); } } return ret; } #endif /* CONFIG_IPV6 */ int net_get_if_ip_addr(uint32_t *ip, void *intrfc_handle) { struct interface *if_handle = (struct interface *)intrfc_handle; NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); *ip = if_handle->netif->ip_addr.addr; return 0; } int net_get_if_ip_mask(uint32_t *nm, void *intrfc_handle) { struct interface *if_handle = (struct interface *)intrfc_handle; NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); *nm = if_handle->netif->netmask.addr; return 0; } int net_get_if_gw_addr(uint32_t *ip, void *intrfc_handle) { struct interface *if_handle = (struct interface *)intrfc_handle; *ip = if_handle->netif->gw.addr; NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); return 0; } void net_configure_dns(struct wlan_ip_config *ip) { ip_addr_t tmp; NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); if (ip->ipv4.addr_type == ADDR_TYPE_STATIC) { if (ip->ipv4.dns1 == 0) ip->ipv4.dns1 = ip->ipv4.gw; if (ip->ipv4.dns2 == 0) ip->ipv4.dns2 = ip->ipv4.dns1; tmp.addr = ip->ipv4.dns1; dns_setserver(0, &tmp); tmp.addr = ip->ipv4.dns2; dns_setserver(1, &tmp); } /* DNS MAX Retries should be configured in lwip/dns.c to 3/4 */ /* DNS Cache size of about 4 is sufficient */ } extern struct rt_wlan_device _g_wlan_device; void net_wlan_initial(void) { NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); net_ipv4stack_init(); #ifdef CONFIG_IPV6 net_ipv6stack_init(&g_mlan.netif); #endif /* CONFIG_IPV6 */ } void net_wlan_add_netif(void *mac) { VIF_INF_PTR vif_entry = NULL; struct interface *wlan_if = NULL; u8 vif_idx; u8 *b = (u8 *)mac; NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); if (!b || (!(b[0] | b[1] | b[2] | b[3] | b[4] | b[5]))) return; vif_idx = rwm_mgmt_vif_mac2idx(mac); if (vif_idx == 0xff) { os_printf("net_wlan_add_netif not vif idx found\r\n"); return ; } vif_entry = rwm_mgmt_vif_idx2ptr(vif_idx); if (!vif_entry) { os_printf("net_wlan_add_netif not vif found, %d\r\n", vif_idx); return ; } if (vif_entry->type == VIF_AP) { g_uap.netif = wlan_get_uap_netif(); wlan_if = &g_uap; } else if (vif_entry->type == VIF_STA) { g_mlan.netif = wlan_get_sta_netif(); wlan_if = &g_mlan; } else { os_printf("net_wlan_add_netif with other role\r\n"); return ; } wlan_if->ipaddr.addr = INADDR_ANY; wlan_if->netif->state = (void *)vif_entry; vif_entry->priv = wlan_if->netif; os_memcpy(wlan_if->netif->hwaddr, mac, ETHARP_HWADDR_LEN); /* set link_up for this netif */ netif_set_link_up(wlan_if->netif); } void net_wlan_remove_netif(void *mac) { u8 vif_idx; VIF_INF_PTR vif_entry = NULL; struct netif *netif = NULL; u8 *b = (u8 *)mac; NET_DBG("L%d, %s \r\n", __LINE__, __FUNCTION__); if (!b || (!(b[0] | b[1] | b[2] | b[3] | b[4] | b[5]))) return; vif_idx = rwm_mgmt_vif_mac2idx(mac); if (vif_idx == 0xff) { os_printf("net_wlan_add_netif not vif idx found\r\n"); return ; } vif_entry = rwm_mgmt_vif_idx2ptr(vif_idx); if (!vif_entry) { os_printf("net_wlan_add_netif not vif found, %d\r\n", vif_idx); return ; } netif = (struct netif *)vif_entry->priv; if (!netif) { os_printf("net_wlan_remove_netif netif is null\r\n"); return; } netif_set_link_down(netif); memset(&netif->ip_addr, 0, sizeof(ip_addr_t)); memset(&netif->netmask, 0, sizeof(ip_addr_t)); memset(&netif->gw, 0, sizeof(ip_addr_t)); if (!strncmp(netif->name, WIFI_DEVICE_STA_NAME, sizeof(netif->name))) { dns_setserver(0, NULL); } os_printf("netif_set_link_down !, vif_idx:%d\r\n", vif_idx); }