mirror of
https://github.com/jialexd/sdk-ameba-v4.0c_180328.git
synced 2024-11-24 23:14:18 +00:00
227 lines
6.2 KiB
C
Executable file
227 lines
6.2 KiB
C
Executable file
_Pragma ("diag_suppress=Pe111")
|
|
|
|
#include <autoconf.h>
|
|
#include <FreeRTOS.h>
|
|
#include "task.h"
|
|
#include <platform/platform_stdlib.h>
|
|
#include <wifi/wifi_conf.h>
|
|
#include <lwip_netconf.h>
|
|
|
|
#ifndef WLAN0_NAME
|
|
#define WLAN0_NAME "wlan0"
|
|
#endif
|
|
#ifndef WLAN1_NAME
|
|
#define WLAN1_NAME "wlan1"
|
|
#endif
|
|
|
|
#ifndef ETH_ALEN
|
|
#define ETH_ALEN 6
|
|
#endif
|
|
|
|
#define SCAN_BUFLEN 500 //each scan list lenght = 14 + ssid_length(32MAX). so SCAN_BUFLEN should be NUM*(14+32) at least
|
|
#define RSSI_THRESHOLD -65
|
|
#define MAX_POLLING_COUNT 5
|
|
#define MAX_AP_NUM 3
|
|
typedef struct wifi_roaming_ap
|
|
{
|
|
u8 ssid[33];
|
|
u8 bssid[ETH_ALEN];
|
|
u8 channel;
|
|
rtw_security_t security_type;
|
|
u8 password[65];
|
|
u8 key_idx;
|
|
s32 rssi;
|
|
#if CONFIG_LWIP_LAYER
|
|
u8 ip[4];
|
|
#endif
|
|
}wifi_roaming_ap_t;
|
|
|
|
#if CONFIG_LWIP_LAYER
|
|
extern struct netif xnetif[NET_IF_NUM];
|
|
#endif
|
|
static wifi_roaming_ap_t * ap_list[MAX_AP_NUM]={0};
|
|
static u32 ap_count = 0;
|
|
|
|
u32 wifi_roaming_find_ap_from_scan_buf(char*buf, int buflen, char *target_ssid, void *user_data)
|
|
{
|
|
wifi_roaming_ap_t *pwifi = (wifi_roaming_ap_t *)user_data;
|
|
wifi_roaming_ap_t * candicate,*temp;
|
|
u32 i,j,plen = 0;
|
|
pwifi->rssi = -100;//init
|
|
|
|
while(plen < buflen)
|
|
{
|
|
u32 len, ssid_len, i, security_mode, security_type, channel;
|
|
s32 rssi;
|
|
u8 *mac, *ssid;
|
|
// len
|
|
len = (int)*(buf + plen);
|
|
// check end
|
|
if(len == 0) break;
|
|
// mac
|
|
mac =(u8*)(buf + plen + 1);
|
|
// rssi
|
|
rssi = *(s32*)(buf + plen + 1 + 6);
|
|
// security_mode offset = 11
|
|
security_mode = (u8)*(buf + plen + 1 + 6 + 4);
|
|
switch(security_mode){
|
|
case IW_ENCODE_ALG_NONE:
|
|
security_type = RTW_SECURITY_OPEN;
|
|
break;
|
|
case IW_ENCODE_ALG_WEP:
|
|
security_type = RTW_SECURITY_WEP_PSK;
|
|
break;
|
|
case IW_ENCODE_ALG_TKIP:
|
|
security_type = RTW_SECURITY_WPA_TKIP_PSK;
|
|
break;
|
|
case IW_ENCODE_ALG_CCMP:
|
|
security_type = RTW_SECURITY_WPA2_AES_PSK;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
// channel
|
|
channel = *(buf + plen + 1 + 6 + 4 + 1 + 1);
|
|
// ssid
|
|
ssid_len = len - 1 - 6 - 4 - 1 - 1 - 1;
|
|
ssid = (u8*)(buf + plen + 1 + 6 + 4 + 1 + 1 + 1);
|
|
if(pwifi->security_type == security_type ||
|
|
((pwifi->security_type & (WPA2_SECURITY|WPA_SECURITY))&&(security_type & (WPA2_SECURITY|WPA_SECURITY)))){
|
|
if(ap_count < MAX_AP_NUM){
|
|
candicate = (wifi_roaming_ap_t *)malloc(sizeof(wifi_roaming_ap_t));
|
|
if(!candicate)
|
|
{
|
|
printf("\r\n malloc buf for AP info fail!");
|
|
break;
|
|
}
|
|
memset(candicate, 0 , sizeof(wifi_roaming_ap_t));
|
|
memcpy(candicate->ssid, ssid, ssid_len);
|
|
memcpy(candicate->bssid, mac, ETH_ALEN);
|
|
candicate->channel = channel;
|
|
candicate->security_type = security_type;
|
|
memcpy(candicate->password, pwifi->password, strlen(pwifi->password));
|
|
candicate->key_idx = pwifi->key_idx;
|
|
candicate->rssi = rssi;
|
|
ap_list[ap_count++] = candicate;
|
|
}
|
|
}
|
|
plen += len;
|
|
}
|
|
|
|
for(i = 0; i < ap_count; i++)
|
|
{
|
|
for(j = 0; j < ap_count -1 -i ; j++)
|
|
if(ap_list[j]->rssi < ap_list[j+1]->rssi ){
|
|
temp = ap_list[j];
|
|
ap_list[j] = ap_list[j+1];
|
|
ap_list[j+1]= temp;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void wifi_ip_changed_hdl( u8* buf, u32 buf_len, u32 flags, void* userdata)
|
|
{
|
|
//todo for customer
|
|
printf("\r\n IP has channged!");
|
|
}
|
|
void wifi_roaming_thread(void *param)
|
|
{
|
|
rtw_wifi_setting_t setting;
|
|
wifi_roaming_ap_t roaming_ap,*candicate_ap;
|
|
u8 bssid_ap[6];
|
|
s32 ap_rssi;
|
|
u32 i = 0, polling_count =0;
|
|
u8 pscan_config = PSCAN_ENABLE;
|
|
memset(&setting, 0, sizeof(rtw_wifi_setting_t));
|
|
memset(&roaming_ap, 0, sizeof(wifi_roaming_ap_t));
|
|
roaming_ap.rssi = -100;
|
|
#if CONFIG_LWIP_LAYER
|
|
uint8_t *IP = LwIP_GetIP(&xnetif[0]);
|
|
#endif
|
|
|
|
while(1)
|
|
{
|
|
if(wifi_is_up(RTW_STA_INTERFACE)&&(RTW_SUCCESS == wifi_is_ready_to_transceive(RTW_STA_INTERFACE)))
|
|
{
|
|
wifi_get_rssi(&ap_rssi);
|
|
if( (ap_rssi < RSSI_THRESHOLD))
|
|
{
|
|
if( polling_count >= (MAX_POLLING_COUNT-1))
|
|
{
|
|
wifi_get_setting(WLAN0_NAME,&setting);
|
|
strcpy(roaming_ap.ssid, setting.ssid);
|
|
roaming_ap.security_type = setting.security_type;
|
|
strcpy(roaming_ap.password, setting.password);
|
|
roaming_ap.key_idx = setting.key_idx;
|
|
//if(RTW_ERROR == wifi_get_ap_bssid(bssid_ap))
|
|
if(RTW_ERROR == wifi_get_ap_bssid(roaming_ap.bssid))
|
|
printf("\r\n get AP BSSID FAIL!");
|
|
#if CONFIG_LWIP_LAYER
|
|
memcpy(roaming_ap.ip, IP, 4);
|
|
#endif
|
|
wifi_scan_networks_with_ssid(wifi_roaming_find_ap_from_scan_buf, (void *)&roaming_ap, SCAN_BUFLEN, roaming_ap.ssid, strlen(roaming_ap.ssid));
|
|
#if CONFIG_AUTO_RECONNECT
|
|
wifi_set_autoreconnect(0);
|
|
#endif
|
|
i = 0;
|
|
connect_ap:
|
|
if(ap_list[i] && memcmp(bssid_ap, ap_list[i]->bssid, ETH_ALEN))
|
|
{
|
|
u8 retry_time = 0;
|
|
while(1)
|
|
{
|
|
wifi_set_pscan_chan(&ap_list[i]->channel, &pscan_config,1);
|
|
if( RTW_SUCCESS == wifi_connect_bssid(ap_list[i]->bssid, ap_list[i]->ssid,ap_list[i]->security_type,
|
|
ap_list[i]->password, ETH_ALEN, strlen(ap_list[i]->ssid), strlen(ap_list[i]->password), ap_list[i]->key_idx, NULL ))
|
|
{
|
|
#if CONFIG_LWIP_LAYER
|
|
wifi_reg_event_handler(WIFI_EVENT_IP_CHANGED, wifi_ip_changed_hdl, NULL);
|
|
|
|
LwIP_DHCP(0, DHCP_START);
|
|
|
|
if(memcmp(roaming_ap.ip, IP, 4))
|
|
{
|
|
wifi_indication(WIFI_EVENT_IP_CHANGED, NULL,0, 0);
|
|
wifi_unreg_event_handler(WIFI_EVENT_IP_CHANGED, wifi_ip_changed_hdl);
|
|
}
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
retry_time ++;
|
|
if(retry_time >3){
|
|
i++;
|
|
goto connect_ap;
|
|
}
|
|
}
|
|
}
|
|
|
|
while(ap_count)
|
|
{
|
|
free (ap_list[ap_count-1]);
|
|
ap_count--;
|
|
}
|
|
|
|
memset(ap_list, 0, sizeof(ap_list));
|
|
polling_count = 0;
|
|
#if CONFIG_AUTO_RECONNECT
|
|
wifi_set_autoreconnect(1);
|
|
#endif
|
|
}
|
|
polling_count++;
|
|
}else
|
|
polling_count = 0;
|
|
}
|
|
vTaskDelay(2000);// 2s
|
|
}
|
|
vTaskDelete(NULL);
|
|
}
|
|
|
|
void example_wifi_roaming( )
|
|
{
|
|
if(xTaskCreate(wifi_roaming_thread, ((const char*)"wifi_roaming_thread"), 1024, NULL, tskIDLE_PRIORITY + 1 , NULL) != pdPASS)
|
|
printf("\n\r%s xTaskCreate(wifi_roaming_thread) failed", __FUNCTION__);
|
|
|
|
return;
|
|
}
|