跳到主要内容

潘多拉 RT-Thread WiFi 管理

实验概述

本实验使用 RT-Thread Wlan Manager 对 WiFi 网络管理,展示 WiFi 热点扫描、Join 网络、WiFi 自动连接以及 WiFi Event 处理等功能。

硬件连接

潘多拉 IoT Board 板载的一个 WiFi 模块,它是正基公司的 AP6181 WiFi 模组,集成了 IEEE 802.11 b/g/n MAC 、基带、射频以及功率放大器、电源管理装置、SDIO 2.0 接口,原理图如下。

示例代码

程序主要流程:首先调用 Scan 接口扫描周围环境中的 AP(Access Point ,即无线访问热点),并打印扫描结果;然后连接一个测试用的 AP(名字 test_ssid,密码 12345678),并等待联网成功,打印网络信息;接着在等待 5 秒之后,断开和 AP 的连接;最后,调用接口初始化自动连接的相关配置,开启自动连接功能。在开启自动连接之后,Wlan Manager 会根据存储介质中的历史记录进行 AP 连接。

参考《潘多拉 IoT Board 开发环境》创建工程,在 applications/main.c 中输入如下代码。

注意:将 WLAN_SSIDWLAN_PASSWORD 修改为你的 WiFi 接入点名称和密码。

applications/main.c
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#include <msh.h>

#include "drv_wlan.h"
#include "wifi_config.h"

#include <stdio.h>
#include <stdlib.h>

#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>

#define WLAN_SSID "test_ssid"
#define WLAN_PASSWORD "12345678"
#define NET_READY_TIME_OUT (rt_tick_from_millisecond(15 * 1000))

static void print_scan_result(struct rt_wlan_scan_result *scan_result);
static void print_wlan_information(struct rt_wlan_info *info);

static struct rt_semaphore net_ready;

void wlan_ready_handler(int event, struct rt_wlan_buff *buff, void *parameter)
{
rt_sem_release(&net_ready);
}

/* 断开连接回调函数 */
void wlan_station_disconnect_handler(int event, struct rt_wlan_buff *buff, void *parameter)
{
LOG_I("disconnect from the network!");
}

int main(void)
{
int result = RT_EOK;
struct rt_wlan_info info;
struct rt_wlan_scan_result *scan_result;

/* 等待 500 ms 以便 wifi 完成初始化 */
rt_hw_wlan_wait_init_done(500);

/* 扫描热点 */
LOG_D("start to scan ap ...");
/* 执行同步扫描 */
scan_result = rt_wlan_scan_sync();
if (scan_result)
{
LOG_D("the scan is complete, results is as follows: ");
/* 打印扫描结果 */
print_scan_result(scan_result);
/* 清除扫描结果 */
rt_wlan_scan_result_clean();
}
else
{
LOG_E("not found ap information ");
return -1;
}

/* 热点连接 */
LOG_D("start to connect ap ...");
rt_sem_init(&net_ready, "net_ready", 0, RT_IPC_FLAG_FIFO);

/* 注册 wlan ready 回调函数 */
rt_wlan_register_event_handler(RT_WLAN_EVT_READY, wlan_ready_handler, RT_NULL);
/* 注册 wlan 断开回调函数 */
rt_wlan_register_event_handler(RT_WLAN_EVT_STA_DISCONNECTED, wlan_station_disconnect_handler, RT_NULL);
result = rt_wlan_connect(WLAN_SSID, WLAN_PASSWORD);
if (result == RT_EOK)
{
rt_memset(&info, 0, sizeof(struct rt_wlan_info));
/* 获取当前连接热点信息 */
rt_wlan_get_info(&info);
LOG_D("station information:");
print_wlan_information(&info);
/* 等待成功获取 IP */
result = rt_sem_take(&net_ready, NET_READY_TIME_OUT);
if (result == RT_EOK)
{
LOG_D("networking ready!");
msh_exec("ifconfig", rt_strlen("ifconfig"));
}
else
{
LOG_D("wait ip got timeout!");
}
/* 回收资源 */
rt_wlan_unregister_event_handler(RT_WLAN_EVT_READY);
rt_sem_detach(&net_ready);
}
else
{
LOG_E("The AP(%s) is connect failed!", WLAN_SSID);
}

rt_thread_mdelay(5000);

LOG_D("ready to disconect from ap ...");
rt_wlan_disconnect();

/* 自动连接 */
LOG_D("start to autoconnect ...");
/* 初始化自动连接配置 */
wlan_autoconnect_init();
/* 使能 wlan 自动连接 */
rt_wlan_config_autoreconnect(RT_TRUE);

return 0;
}

static void print_scan_result(struct rt_wlan_scan_result *scan_result)
{
char *security;
int index, num;

num = scan_result->num;
/* 有规则的排列扫描到的热点 */
rt_kprintf(" SSID MAC security rssi chn Mbps\n");
rt_kprintf("------------------------------- ----------------- -------------- ---- --- ----\n");
for (index = 0; index < num; index++)
{
rt_kprintf("%-32.32s", &scan_result->info[index].ssid.val[0]);
rt_kprintf("%02x:%02x:%02x:%02x:%02x:%02x ",
scan_result->info[index].bssid[0],
scan_result->info[index].bssid[1],
scan_result->info[index].bssid[2],
scan_result->info[index].bssid[3],
scan_result->info[index].bssid[4],
scan_result->info[index].bssid[5]);
switch (scan_result->info[index].security)
{
case SECURITY_OPEN:
security = "OPEN";
break;
case SECURITY_WEP_PSK:
security = "WEP_PSK";
break;
case SECURITY_WEP_SHARED:
security = "WEP_SHARED";
break;
case SECURITY_WPA_TKIP_PSK:
security = "WPA_TKIP_PSK";
break;
case SECURITY_WPA_AES_PSK:
security = "WPA_AES_PSK";
break;
case SECURITY_WPA2_AES_PSK:
security = "WPA2_AES_PSK";
break;
case SECURITY_WPA2_TKIP_PSK:
security = "WPA2_TKIP_PSK";
break;
case SECURITY_WPA2_MIXED_PSK:
security = "WPA2_MIXED_PSK";
break;
case SECURITY_WPS_OPEN:
security = "WPS_OPEN";
break;
case SECURITY_WPS_SECURE:
security = "WPS_SECURE";
break;
default:
security = "UNKNOWN";
break;
}
rt_kprintf("%-14.14s ", security);
rt_kprintf("%-4d ", scan_result->info[index].rssi);
rt_kprintf("%3d ", scan_result->info[index].channel);
rt_kprintf("%4d\n", scan_result->info[index].datarate / 1000000);
}
rt_kprintf("\n");
}

static void print_wlan_information(struct rt_wlan_info *info)
{
LOG_D("SSID : %-.32s", &info->ssid.val[0]);
LOG_D("MAC Addr: %02x:%02x:%02x:%02x:%02x:%02x", info->bssid[0],
info->bssid[1],
info->bssid[2],
info->bssid[3],
info->bssid[4],
info->bssid[5]);
LOG_D("Channel: %d", info->channel);
LOG_D("DataRate: %dMbps", info->datarate / 1000000);
LOG_D("RSSI: %d", info->rssi);
}

完整代码:16_iot_wifi_manager

编译运行

开启 WiFi 选项

下载软件包