850 lines
23 KiB
C
850 lines
23 KiB
C
#include "include.h"
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include <lwip/inet.h>
|
|
|
|
#include "netif/etharp.h"
|
|
#include "lwip/netif.h"
|
|
#include <lwip/netifapi.h>
|
|
#include <lwip/tcpip.h>
|
|
#include <lwip/dns.h>
|
|
#include <lwip/dhcp.h>
|
|
#include "lwip/prot/dhcp.h"
|
|
|
|
#include <lwip/sockets.h>
|
|
#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 <rtthread.h>
|
|
#include <rtdevice.h>
|
|
#include <rthw.h>
|
|
#include <wlan_dev.h>
|
|
#include <wlan_mgnt.h>
|
|
#include "drv_wlan.h"
|
|
#include <sys/socket.h>
|
|
|
|
#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);
|
|
}
|