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


前言

本文主要在官方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");
}

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


三、进群讨论分享!

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

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值