> 文档中心 > W800/W801学习记录网络部分(一):WIFI的扫描和连接

W800/W801学习记录网络部分(一):WIFI的扫描和连接

文章目录

  • 前言
  • 一、WIFI扫描
  • 二、连接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.函数解析

步骤:

  1. 断开原有的连接;
  2. 设置协议参数;
  3. 登记回调函数;
  4. 调用连接函数。
//参数  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");}

串口发送如下:
在这里插入图片描述
此时在手机上可以看到连接的设备
在这里插入图片描述


三、进群讨论分享!

如果你喜欢我的文章,欢迎关注下方公众号,在公众号内回复“交流群”,进群一起讨论分享!
在这里插入图片描述

铃声多多