大家好,我是杂烩君。
上一篇笔记我们分享了嵌入式Linux单板连接飞燕物联网平台,这篇我们分享一下配网。
在这之前,建议阅读往期相关笔记:
-
smartconfig一件配网:嵌入式大杂烩周记第 5 期 : SmartLink
-
嵌入式Linux设备开启无线AP/无线接入点:废旧板子再利用:搭建无线调试环境!
下面我们来简单分享基于阿里生活物联网平台的AP配网实例。
一、安装公版手机APP
我们使用公版的手机APP进行配网,再云平台上简单配置之后,可以扫码安装:
二、配置AP模式的环境
无论使用什么云平台,平台给我们提供的设备SDK中,都不会是完整的AP配网功能,比如板子如何进入AP模式,这个SDK是不管的,需要我们去适配。
嵌入式Linux设备,要开启无线接入点需要准备如下四个文件:
-
hostapd:一个用户态用于AP和认证服务器的守护进程。
-
hostapd.conf:hostapd配置文件,包含无线AP的名称、密码等信息。
-
udhcpd:dhcp拨号的服务器端。
-
udhcpd.conf:udhcpd配置文件,配置网关地址及IP地址的范围。
具体的方法可以查看往期笔记:废旧板子再利用:搭建无线调试环境!
二、适配AP配网接口
配网功能阿里有给我们留出接口,我们需要适配这些配网接口。比如我这里使用设备AP配网,需要适配的接口如:
-
打开AP
int HAL_Awss_Open_Ap(const char *ssid, const char *passwd, int beacon_interval, int hide)
{
const char *ap_ssid = ssid; /* "linkkit-ap"; */
char shell_cmd[SHELL_CMD_MAX_LEN] = {0};
char ip_buf[64] = {0};
if (1 == g_ap_conf_net_flag)
{
g_ap_conf_net_flag = 0;
printf("HAL_Awss_Open_Ap\n");
printf("ap_ssid = %s\n", ap_ssid);
printf("ap_ssid + 4 = %s\n", ap_ssid + 4);
// 开启热点
system(SHELL_CMD_KILL_NET_PROCESS); // 杀掉网卡操作相关的进程
system(SHELL_CMD_NETCARD_DOWN); // 禁用网卡
system(SHELL_CMD_NETCARD_UP); // 启用网卡
system(SHELL_CMD_SET_NETCARD_IP); // 设置网卡IP(作为无线AP的网关IP)
system(SHELL_CMD_START_UDHCPD); // 启动UDHCPD服务
system(SHELL_CMD_RM_HOSTAPD_CONF_FILE);
system(SHELL_CMD_RESET_HOSTAPD_CONF_FILE);
snprintf(shell_cmd, sizeof(shell_cmd), SHELL_CMD_MODIFY_AP_SSID, ap_ssid + 4);
system(shell_cmd); // 修改AP名称
system(SHELL_CMD_START_HOSTAPD); // 启动HOSTAPD服务
if (strlen(ap_ssid) < sizeof(g_opened_ap)) {
memcpy(g_opened_ap, ap_ssid, strlen(ap_ssid));
}
}
else
{
printf("HAL_Awss_Open_Ap, g_ap_conf_net_flag = FALSE\n");
}
return 0;
}
-
关闭AP
int HAL_Awss_Close_Ap()
{
/* use nmcli commands to close the previous open Ap */
printf("HAL_Awss_Close_Ap\n");
system(SHELL_CMD_KILL_NET_PROCESS);
system(SHELL_CMD_WLAN0_DOWN);
return 0;
}
-
连接AP
int HAL_Awss_Connect_Ap(
_IN_ uint32_t connection_timeout_ms,
_IN_ char ssid[HAL_MAX_SSID_LEN],
_IN_ char passwd[HAL_MAX_PASSWD_LEN],
_IN_OPT_ enum AWSS_AUTH_TYPE auth,
_IN_OPT_ enum AWSS_ENC_TYPE encry,
_IN_OPT_ uint8_t bssid[ETH_ALEN],
_IN_OPT_ uint8_t channel)
{
char ip_buf[64] = {0};
char shell_cmd[SHELL_CMD_MAX_LEN] = {0};
printf("HAL_Awss_Connect_Ap\n");
printf("ssid = %s, passwd = %s\n", ssid, passwd);
// 重置WiFi配置文件
system(SHELL_CMD_RM_WIFI_CONF_FILE);
system(SHELL_CMD_RESET_WIFI_CONF_FILE);
// 修改WiFi名称及密码
sprintf(shell_cmd, SHELL_CMD_MODIFY_WIFI_SSID, ssid);
printf("set ssid: %s\n", shell_cmd);
system(shell_cmd);
memset(shell_cmd, 0, sizeof(shell_cmd));
sprintf(shell_cmd, SHELL_CMD_MODIFY_WIFI_PSW, passwd);
printf("set passwd: %s\n", shell_cmd);
system(shell_cmd);
system(SHELL_CMD_WLAN0_UP);
system(SHELL_CMD_RUN_WPA_SUPPLICANT);
system(SHELL_CMD_RUN_UDHCPC);
if (get_local_ip(g_ifname, (char*)ip_buf) > 0)
{
printf("robot ip = %s\n", ip_buf);
return 0;
}
return -1;
}
进入设备AP配网模式的接口:
//User can call this function to start device AP of AWSS
void living_platform_do_awss_dev_ap(void)
{
printf("living_platform_do_awss_dev_ap\n");
void* stop_smartconfig_awss_thread = NULL;
void* dev_ap_open_thread = NULL;
hal_os_thread_param_t hal_os_thread_param;
memset(&hal_os_thread_param, 0, sizeof(hal_os_thread_param_t));
hal_os_thread_param.stack_size = 4096;
hal_os_thread_param.name = "smartconfig_awss_stop";
HAL_ThreadCreate(&stop_smartconfig_awss_thread, stop_smartconfig_awss, NULL, &hal_os_thread_param, NULL);
memset(&hal_os_thread_param, 0, sizeof(hal_os_thread_param_t));
hal_os_thread_param.stack_size = 4096;
hal_os_thread_param.name = "dev_ap_open";
HAL_ThreadCreate(&dev_ap_open_thread, awss_open_dev_ap, NULL, &hal_os_thread_param, NULL);
}
为了方便测试,使用命令行输入的字符触发配网模式:
void check_input_cmd(void)
{
if (kbhit())
{
int ch = 0;
ch = getchar();
switch (ch)
{
case '1':
printf("==========111111 living_platform_do_awss_dev_ap\r\n");
living_platform_do_awss_dev_ap();
break;
default:
break;
}
}
}
篇幅有限,其它代码不再贴出,测试例子完整工程可在文末获取。
下面开始运行测试。
步骤:设备进入配网模式、手机APP给设备配网并绑定设备。
使用公版手机APP扫描配网二维码进行配网:
输入设备即将链接的WiFi信息:进入配网模式(我们命令行输入命令模拟硬件进入配网):
连接设备热点:
设备连接路由器、绑定过程:
设备添加成功: