W800/W801学习记录网络部分(一):WIFI的扫描和连接
文章目录
- 前言
- 一、WIFI扫描
-
- 1.函数解析
- 2.演示
- 二、连接WIFI
-
- 1.函数解析
- 2.演示
- 三、进群讨论分享!
前言
本文主要在官方DEMO上分析扫描和连接WIFI的步骤和所调用的函数。
一、WIFI扫描
1.函数解析
首先我们来看一下WIFI扫描所调用的函数,如下:
int wifi_scan(void){tls_wifi_scan_result_cb_register(wifi_scan_handler);tls_wifi_scan(); return WM_SUCCESS;}
我们先来看第一个函数tls_wifi_scan_result_cb_register,在注释中可以知道函数的功能是登记回调函数。其中wifi_scan_handler是另外一个函数的入口,在调用tls_wifi_scan之前必须使用tls_wifi_scan_result_cb_register进行登记。运行完tls_wifi_scan函数后,再运行回调函数(也就是wifi_scan_handler)。
下面来看一下wifi_scan_handler函数,具体解析请看注释
static void wifi_scan_handler(void){ char *buf = NULL;//缓存指针,用于接收wifi扫描的 “全部” 结果 char *buf1 = NULL; //缓存指针,用于从buf复制wifi扫描结果的“单条”wifi信息 u32 buflen; //缓存buf的长度 int i, j; int err; //错误标志 u8 ssid[33]; //wifi名称 struct tls_scan_bss_t *wsr; //存放wifi扫描结果的个数和长度指针 struct tls_bss_info_t *bss_info; //存放“单条”wifi扫描结果的结构体指针 buflen = 2000; //申请内存 buf = tls_mem_alloc(buflen); if (!buf) { goto end; } buf1 = tls_mem_alloc(300); if(!buf1) { goto end; } memset(buf1, 0, 300); err = tls_wifi_get_scan_rslt((u8 *)buf, buflen); //获取wifi扫描结果 if (err) { goto end; } wsr = (struct tls_scan_bss_t *)buf; //复制wifi扫描结果的个数和长度,占8个字节 bss_info = (struct tls_bss_info_t *)(buf + 8); //复制扫描结果开始处指针(buf的前8字节为个数和长度,已经存放在wsr) printf("\n"); for(i = 0; i < wsr->count; i++) { j = sprintf(buf1, "bssid:%02X%02X%02X%02X%02X%02X, ", bss_info->bssid[0], bss_info->bssid[1], bss_info->bssid[2], bss_info->bssid[3], bss_info->bssid[4], bss_info->bssid[5]); //路由器MAC地址 j += sprintf(buf1 + j, "ch:%d, ", bss_info->channel); //WiFi信道 j += sprintf(buf1 + j, "rssi:%d, ", (signed char)bss_info->rssi); //接收信号强度 j += sprintf(buf1 + j, "wps:%d, ", bss_info->wps_support); //是否支持WPS j += sprintf(buf1 + j, "max_rate:%dMbps, ", bss_info->max_data_rate); //最大传输速率 j += sprintf(buf1 + j, "%s, ", scan_mode_string(bss_info->mode)); //ap类型 j += sprintf(buf1 + j, "%s, ", scan_privacy_string(bss_info->privacy)); //加密方式 memcpy(ssid, bss_info->ssid, bss_info->ssid_len); ssid[bss_info->ssid_len] = '\0'; j += sprintf(buf1 + j, "%s", ssid); //完成wifi名称的复制 printf("%s\n", buf1); //打印所有信息 bss_info ++; } //以下被注释的地方是官方的代码,可能会是bug。因为在上面代码发生错误后指针仍为NULL,//会导致申请的内存不能释放end: /*if(buf) { tls_mem_free(buf); } if(buf1) { tls_mem_free(buf1); }*/tls_mem_free(buf);tls_mem_free(buf1);}
2.演示
在user_main()中直接调用wifi_scan()。下载运行后,打开串口接收wifi扫描信息,如下:
二、连接WIFI
1.函数解析
步骤:
- 断开原有的连接;
- 设置协议参数;
- 登记回调函数;
- 调用连接函数。
//参数 ssid:wifi名称// pwd:wifi密码 int wifi_connect(char *ssid, char *pwd){ struct tls_param_ip *ip_param = NULL; //存在ip地址,掩码,DNS地址等参数 u8 wireless_protocol = 0; //协议标准 if (!ssid) { return WM_FAILED; } printf("\nssid:%s\n", ssid); printf("password=%s\n", pwd); tls_wifi_disconnect();//断开原有连接 tls_param_get(TLS_PARAM_ID_WPROTOCOL, (void *) &wireless_protocol, TRUE); //获取协议参数 if (TLS_PARAM_IEEE80211_INFRA != wireless_protocol) { tls_wifi_softap_destroy(); wireless_protocol = TLS_PARAM_IEEE80211_INFRA; tls_param_set(TLS_PARAM_ID_WPROTOCOL, (void *) &wireless_protocol, FALSE); } //设置infrastructure连接模式 tls_wifi_set_oneshot_flag(0); //关闭一键连接 ip_param = tls_mem_alloc(sizeof(struct tls_param_ip)); if (ip_param) { tls_param_get(TLS_PARAM_ID_IP, ip_param, FALSE); ip_param->dhcp_enable = TRUE; tls_param_set(TLS_PARAM_ID_IP, ip_param, FALSE); //tls_mem_free(ip_param); }tls_mem_free(ip_param); //开启DHCP(动态的获得IP地址、Gateway地址、DNS服务器地址等信息) tls_netif_add_status_event(con_net_status_changed_event);//登记回调函数(当网络状态参数,如IP地址、子网掩码改变时,调用此回调函数) tls_wifi_connect((u8 *)ssid, strlen(ssid), (u8 *)pwd, strlen(pwd)); //连接wifi printf("\nplease wait connect net......\n"); return WM_SUCCESS;}
然后再看一下网络状态改变时,调用的回调函数。
static void con_net_status_changed_event(u8 status ){ switch(status) { case NETIF_WIFI_JOIN_SUCCESS: //连接成功 printf("NETIF_WIFI_JOIN_SUCCESS\n"); break; case NETIF_WIFI_JOIN_FAILED: //连接失败 printf("NETIF_WIFI_JOIN_FAILED\n"); break; case NETIF_WIFI_DISCONNECTED: //断开wifi printf("NETIF_WIFI_DISCONNECTED\n"); break; case NETIF_IP_NET_UP: //获得ip地址 { struct tls_ethif *tmpethif = tls_netif_get_ethif(); print_ipaddr(&tmpethif->ip_addr);#if TLS_CONFIG_IPV6 print_ipaddr(&tmpethif->ip6_addr[0]); print_ipaddr(&tmpethif->ip6_addr[1]); print_ipaddr(&tmpethif->ip6_addr[2]); //打印ip地址#endif } break; default: //printf("UNKONWN STATE:%d\n", status); break; }}
2.演示
在void UserMain(void)中调用wifi_connect(char *ssid, char *pwd)函数,设置和打开手机热点。
void UserMain(void){ printf("\n user main \n"); wifi_connect("程序猿Aki", "1234567890");}
串口发送如下:
此时在手机上可以看到连接的设备
三、进群讨论分享!
如果你喜欢我的文章,欢迎关注下方公众号,在公众号内回复“交流群”,进群一起讨论分享!