399 lines
11 KiB
C
Executable File
399 lines
11 KiB
C
Executable File
/*
|
|
* Copyright (C) 2017 XRADIO TECHNOLOGY CO., LTD. All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the
|
|
* distribution.
|
|
* 3. Neither the name of XRADIO TECHNOLOGY CO., LTD. nor the names of
|
|
* its contributors may be used to endorse or promote products derived
|
|
* from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include "net/wlan/wlan.h"
|
|
#include "net/wlan/wlan_defs.h"
|
|
#include "common/framework/net_ctrl.h"
|
|
#include "common/framework/platform_init.h"
|
|
#include "common/framework/sysinfo.h"
|
|
#include "common/cmd/cmd.h"
|
|
#include "lwip/inet.h"
|
|
#include "sys/fdcm.h"
|
|
#include "sys/xr_debug.h"
|
|
#include "util/time_logger.h"
|
|
|
|
extern uint64_t HAL_RTC_GetFreeRunTime(void);
|
|
extern void stdout_enable(uint8_t en);
|
|
extern void dns_setserver(u8_t numdns, ip_addr_t *dnsserver);
|
|
|
|
#define FC_DEBUG_EN 0
|
|
#if FC_DEBUG_EN
|
|
#define FC_DEBUG(fmt, arg...) printf(fmt, ##arg)
|
|
#else
|
|
#define FC_DEBUG(fmt, arg...)
|
|
#endif
|
|
|
|
static uint8_t g_ap_connected;
|
|
void net_msg_receiver(uint32_t event, uint32_t data, void *arg)
|
|
{
|
|
uint16_t type = EVENT_SUBTYPE(event);
|
|
|
|
switch (type) {
|
|
case NET_CTRL_MSG_WLAN_CONNECTED:
|
|
break;
|
|
case NET_CTRL_MSG_WLAN_DISCONNECTED:
|
|
g_ap_connected = 0;
|
|
wlan_sta_bss_flush(0);
|
|
break;
|
|
case NET_CTRL_MSG_WLAN_SCAN_SUCCESS:
|
|
case NET_CTRL_MSG_WLAN_SCAN_FAILED:
|
|
break;
|
|
case NET_CTRL_MSG_WLAN_4WAY_HANDSHAKE_FAILED:
|
|
case NET_CTRL_MSG_WLAN_CONNECT_FAILED:
|
|
case NET_CTRL_MSG_WLAN_CONNECTION_LOSS:
|
|
g_ap_connected = 0;
|
|
break;
|
|
case NET_CTRL_MSG_NETWORK_UP:
|
|
g_ap_connected = 1;
|
|
break;
|
|
case NET_CTRL_MSG_NETWORK_DOWN:
|
|
g_ap_connected = 0;
|
|
break;
|
|
default:
|
|
printf("unknown msg (%u, %u)\n", type, data);
|
|
break;
|
|
}
|
|
}
|
|
|
|
int net_msg_rcv_init(void)
|
|
{
|
|
observer_base *ob = sys_callback_observer_create(CTRL_MSG_TYPE_NETWORK,
|
|
NET_CTRL_MSG_ALL,
|
|
net_msg_receiver,
|
|
NULL);
|
|
if (ob == NULL)
|
|
return -1;
|
|
if (sys_ctrl_attach(ob) != 0)
|
|
return -1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
#define BSS_FLASH_NUM (0)
|
|
#define BSS_FLASH_ADDR ((1024 + 128) * 1024)
|
|
#define BSS_FLASH_SIZE (8*1024)
|
|
#define FLAGS_BSS_USING_WPA3 HAL_BIT(0)
|
|
typedef struct bss_info {
|
|
uint8_t ssid[32];
|
|
uint8_t psk[32];
|
|
uint32_t bss_size;
|
|
uint8_t bss[800];
|
|
uint8_t psk_ph[100];
|
|
uint32_t flags;
|
|
} bss_info_t;
|
|
|
|
bss_info_t g_bss_info;
|
|
char sta_ssid[100];
|
|
char sta_psk[100];
|
|
void connect_ap(void)
|
|
{
|
|
printf("Wait for link up...\n");
|
|
printf("use this cmd to connect your ap with your own ssid and password:\n"
|
|
"\t\"net fc config your_ssid your_password\"\n\t\"net fc enable\"\n");
|
|
while (!g_ap_connected) {
|
|
OS_MSleep(10);
|
|
}
|
|
save_time((uint32_t)HAL_RTC_GetFreeRunTime(), 2);
|
|
printf("Connect AP success!\n");
|
|
struct sysinfo *sysinfo = sysinfo_get();
|
|
if (sysinfo == NULL) {
|
|
printf("sysinfo %p\n", sysinfo);
|
|
return;
|
|
}
|
|
|
|
//Save IP info to flash
|
|
struct netif *nif = wlan_netif_get(WLAN_MODE_NONE);
|
|
sysinfo->sta_use_dhcp = 0;
|
|
memcpy(&sysinfo->netif_sta_param.ip_addr, &nif->ip_addr, sizeof(ip_addr_t));
|
|
memcpy(&sysinfo->netif_sta_param.gateway, &nif->gw, sizeof(ip_addr_t));
|
|
memcpy(&sysinfo->netif_sta_param.net_mask, &nif->netmask, sizeof(ip_addr_t));
|
|
sysinfo_save();
|
|
}
|
|
|
|
int save_bss_to_flash(bss_info_t *pbss_info)
|
|
{
|
|
int ret = 0;
|
|
uint32_t size;
|
|
wlan_sta_bss_info_t bss_get;
|
|
wlan_sta_ap_t ap_info;
|
|
fdcm_handle_t *bss_fdcm_hdl;
|
|
|
|
if (!g_ap_connected) {
|
|
printf("Please connect AP first!\n");
|
|
ret = -1;
|
|
return ret;
|
|
}
|
|
//Try to get current bss info size
|
|
ret = wlan_sta_get_bss_size(&size);
|
|
if (ret != 0) {
|
|
printf("Get current bss info size failed!\n");
|
|
return ret;
|
|
}
|
|
bss_get.size = size;
|
|
bss_get.bss = malloc(size);
|
|
|
|
//Try to get current bss info
|
|
ret = wlan_sta_get_bss(&bss_get);
|
|
if (ret != 0) {
|
|
printf("Get current bss info failed!\n");
|
|
return ret;
|
|
}
|
|
|
|
//Gererate 32 bytes HEX psk, so that we don't need to calcute next time
|
|
wlan_gen_psk_param_t param;
|
|
if (strlen(sta_psk) == 64) {
|
|
hex2bin(param.psk, sta_psk, 32);
|
|
} else if (sta_psk[0] == '\0') {
|
|
memset(param.psk, 0, sizeof(param.psk));
|
|
} else {
|
|
param.ssid_len = strlen(sta_ssid);
|
|
memcpy(param.ssid, sta_ssid, param.ssid_len);
|
|
strlcpy(param.passphrase, sta_psk, sizeof(param.passphrase));
|
|
ret = wlan_sta_gen_psk(¶m);
|
|
if (ret != 0) {
|
|
printf("fail to generate psk\n");
|
|
ret = -1;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
//Try to get connected ap info
|
|
ret = wlan_sta_ap_info(&ap_info);
|
|
if (ret != 0) {
|
|
printf("Get ap info failed!\n");
|
|
return ret;
|
|
}
|
|
FC_DEBUG("(%s)(%d)get ap_info flags: 0x%x\n", __func__, __LINE__, ap_info.status);
|
|
|
|
//Save current bss info to flash
|
|
memset(pbss_info, 0, sizeof(bss_info_t));
|
|
if (ap_info.status & WLAN_STA_AP_STATUS_USE_WPA3)
|
|
pbss_info->flags |= FLAGS_BSS_USING_WPA3;
|
|
else
|
|
pbss_info->flags &= ~FLAGS_BSS_USING_WPA3;
|
|
memcpy(pbss_info->ssid, sta_ssid, strlen(sta_ssid));
|
|
memcpy(pbss_info->psk, param.psk, 32);
|
|
|
|
memcpy(pbss_info->psk_ph, sta_psk, 100);
|
|
|
|
pbss_info->bss_size = size;
|
|
memcpy(pbss_info->bss, bss_get.bss, size);
|
|
bss_fdcm_hdl = fdcm_open(BSS_FLASH_NUM, BSS_FLASH_ADDR, BSS_FLASH_SIZE);
|
|
if (bss_fdcm_hdl == NULL) {
|
|
printf("fdcm open failed, hdl %p\n", bss_fdcm_hdl);
|
|
ret = -1;
|
|
return ret;
|
|
}
|
|
fdcm_write(bss_fdcm_hdl, pbss_info, sizeof(bss_info_t));
|
|
fdcm_close(bss_fdcm_hdl);
|
|
free(bss_get.bss);
|
|
printf("Save bss info done!\n");
|
|
return ret;
|
|
}
|
|
|
|
int clear_bss_in_flash(void)
|
|
{
|
|
int ret = 0;
|
|
fdcm_handle_t *bss_fdcm_hdl;
|
|
|
|
printf("Clear bss info in flash!\n");
|
|
memset(&g_bss_info, 0, sizeof(bss_info_t));
|
|
bss_fdcm_hdl = fdcm_open(BSS_FLASH_NUM, BSS_FLASH_ADDR, BSS_FLASH_SIZE);
|
|
if (bss_fdcm_hdl == NULL) {
|
|
printf("fdcm open failed, hdl %p\n", bss_fdcm_hdl);
|
|
ret = -1;
|
|
return ret;
|
|
}
|
|
fdcm_write(bss_fdcm_hdl, &g_bss_info, sizeof(bss_info_t));
|
|
fdcm_close(bss_fdcm_hdl);
|
|
|
|
struct sysinfo *sysinfo = sysinfo_get();
|
|
if (sysinfo == NULL) {
|
|
printf("sysinfo %p\n", sysinfo);
|
|
ret = -1;
|
|
return ret;
|
|
}
|
|
|
|
printf("Clear IP info inflash!\n");
|
|
sysinfo->sta_use_dhcp = 1;
|
|
sysinfo_save();
|
|
return ret;
|
|
}
|
|
|
|
void connect_ap_normal(void)
|
|
{
|
|
connect_ap();
|
|
|
|
//Save new bss info to flash
|
|
save_bss_to_flash(&g_bss_info);
|
|
}
|
|
|
|
|
|
void connect_ap_fast(bss_info_t *pbss_info)
|
|
{
|
|
char psk_buf[64];
|
|
char *p;
|
|
int i;
|
|
p = psk_buf;
|
|
|
|
FC_DEBUG("Set old bss info!\n");
|
|
if (pbss_info->flags & FLAGS_BSS_USING_WPA3) {
|
|
wlan_sta_config((uint8_t *)pbss_info->ssid, strlen((char *)pbss_info->ssid),
|
|
(uint8_t *)pbss_info->psk_ph, WLAN_STA_CONF_FLAG_WPA3);
|
|
} else if (pbss_info->psk_ph[0] == '\0') { /* for open AP */
|
|
wlan_sta_config((uint8_t *)pbss_info->ssid, strlen((char *)pbss_info->ssid),
|
|
pbss_info->psk_ph, 0);
|
|
} else { /* for wpa/wpa2 fast connect */
|
|
for (i = 0; i < 32; i++) {
|
|
sprintf(p, "%02x", pbss_info->psk[i]);
|
|
p += 2;
|
|
}
|
|
wlan_sta_config((uint8_t *)pbss_info->ssid, strlen((char *)pbss_info->ssid),
|
|
(uint8_t *)psk_buf, 0);
|
|
}
|
|
FC_DEBUG("Try to connect AP\n");
|
|
wlan_sta_enable();
|
|
|
|
FC_DEBUG("Wait for link up...\n");
|
|
while (!g_ap_connected) {
|
|
OS_MSleep(10);
|
|
}
|
|
save_time((uint32_t)HAL_RTC_GetFreeRunTime(), 2);
|
|
//Fast connect AP success
|
|
}
|
|
|
|
int get_bss_from_flash(bss_info_t *pbss_info)
|
|
{
|
|
int ret;
|
|
uint32_t size;
|
|
wlan_sta_bss_info_t bss_set;
|
|
fdcm_handle_t *bss_fdcm_hdl;
|
|
|
|
bss_fdcm_hdl = fdcm_open(BSS_FLASH_NUM, BSS_FLASH_ADDR, BSS_FLASH_SIZE);
|
|
if (bss_fdcm_hdl == NULL) {
|
|
printf("fdcm open failed, hdl %p\n", bss_fdcm_hdl);
|
|
ret = -1;
|
|
return ret;
|
|
}
|
|
size = fdcm_read(bss_fdcm_hdl, pbss_info, sizeof(bss_info_t));
|
|
fdcm_close(bss_fdcm_hdl);
|
|
if (size != sizeof(bss_info_t)) {
|
|
printf("fdcm read failed, size %d\n", size);
|
|
ret = -1;
|
|
return ret;
|
|
}
|
|
if (pbss_info->bss_size == 0) {
|
|
printf("empty bss info\n");
|
|
ret = -1;
|
|
return ret;
|
|
}
|
|
|
|
FC_DEBUG("SSID:%s\n", pbss_info->ssid);
|
|
FC_DEBUG("FLAGS:0x%x\n", pbss_info->flags);
|
|
FC_DEBUG("PSK_PHRASE:%s\n", pbss_info->psk_ph);
|
|
FC_DEBUG("PSK:");
|
|
for (int i = 1; i < 33; ++i)
|
|
FC_DEBUG("%02x", pbss_info->psk[i-1]);
|
|
FC_DEBUG("\n");
|
|
FC_DEBUG("BSS size:%d\n", pbss_info->bss_size);
|
|
|
|
FC_DEBUG("Set current bss info!\n");
|
|
bss_set.size = pbss_info->bss_size;
|
|
bss_set.bss = malloc(bss_set.size);
|
|
memcpy(bss_set.bss, pbss_info->bss, bss_set.size);
|
|
ret = wlan_sta_set_bss(&bss_set);
|
|
free(bss_set.bss);
|
|
return ret;
|
|
}
|
|
|
|
void fast_connect_example(void)
|
|
{
|
|
FC_DEBUG("Init wlan message receiver\n");
|
|
net_msg_rcv_init();
|
|
|
|
FC_DEBUG("Begin fast connect example\n");
|
|
FC_DEBUG("Try to get old bss info in flash...\n");
|
|
if (get_bss_from_flash(&g_bss_info)) {
|
|
#if !FC_DEBUG_EN
|
|
stdout_enable(1);
|
|
#endif
|
|
printf("Get old bss failed!\n");
|
|
printf("Begin normal connection\n");
|
|
connect_ap_normal();
|
|
printf("The first connection is complete, please reboot to run fast connection!\n");
|
|
} else {
|
|
FC_DEBUG("Get old bss info success!\n");
|
|
FC_DEBUG("Begin fast connection\n");
|
|
connect_ap_fast(&g_bss_info);
|
|
#if !FC_DEBUG_EN
|
|
stdout_enable(1);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
#if defined(CONFIG_LWIP_VER_2_0_3)
|
|
static inline void _ip_addr_set_ip4_u32(ip_addr_t *ipaddr, uint32_t value)
|
|
{
|
|
ip_addr_set_ip4_u32(ipaddr, value);
|
|
}
|
|
#endif
|
|
|
|
int main(void)
|
|
{
|
|
uint32_t time_eob, time_eop;
|
|
time_eob = (uint32_t)HAL_RTC_GetFreeRunTime();
|
|
#if !FC_DEBUG_EN
|
|
stdout_enable(0);
|
|
#endif
|
|
platform_init();
|
|
time_eop = (uint32_t)HAL_RTC_GetFreeRunTime();
|
|
save_time(time_eob, 0);
|
|
save_time(time_eop, 1);
|
|
fast_connect_example();
|
|
get_time();
|
|
|
|
ip_addr_t dnsserver;
|
|
#if defined(CONFIG_LWIP_VER_1_4_1)
|
|
ip4_addr_set_u32(&dnsserver, ipaddr_addr("180.76.76.76"));
|
|
#elif defined(CONFIG_LWIP_VER_2_0_3)
|
|
_ip_addr_set_ip4_u32(&dnsserver, ipaddr_addr("180.76.76.76"));
|
|
#else
|
|
ip_addr_set_ip4_u32_val(dnsserver, ipaddr_addr("180.76.76.76"));
|
|
#endif
|
|
dns_setserver(0, &dnsserver);
|
|
printf("Try to ping www.baidu.com\n");
|
|
cmd_ping_exec("www.baidu.com");
|
|
|
|
return 0;
|
|
}
|
|
|