物联网——WIFI热点配网

总述

WIFI配网种类很多,在之前的博客中有讲述过。WIFI热点配网是一种比较成熟的配网方式,且配网成功率很高。

详解

原理

WIFI分为AP和STA模式,在WIFI未连接上路由器前,STA模式基本是没啥用的,这个时候就可以利用AP模式进行配网。AP模式下WIFI设备相当于是一个路由器,手机等其它设备可以进行连接。WIFI设备里做一个简单的WebServer,只要访问IP地址时直接发送页面内容就好了,涉及的通信协议就是http了。当然这个网页也可以包含固件升级以及相关设备信息的展示。

简单页面展示

在这里插入图片描述

配网流程

1、 浏览器访问wifi设备IP,弹出页面
2、 输入热点名以及密码,等待配网成功

固件升级流程

1、选择文件
2、分包进行get/post请求
3、设备端收到数据进行写Flash
4、轮询设备端写Flash是否成功
5、第四步成功则从2循环直到更新成功

强制弹出网页

手机连接有些热点时,我们会发现会直接弹出认证界面,如果热点配网加上这个功能就比较人性化了。这个功能的原理是DNS劫持,在手机等设备连接上热点后,会尝试去请求DNS服务器获取一些网址的IP地址,此时wifi设备端就可以监听请求包,然后将自己的IP地址作为DNS解析结果返回给连接设备。
DNS采用UDP通信协议,端口号是53,数据协议如下:

在这里插入图片描述

相关代码如下:

void ap_dns_intercept()
{


    uint8_t data[128];
    int len = 0;
    struct sockaddr_in client = { 0 };
    socklen_t  client_len=sizeof(struct sockaddr_in); 
    uint32_t i = 0;
    printf("DNS server start ...\r\n");
    int sock = create_socket_udp(); //创建udp
    if (sock < 0) {
        printf("Failed to create IPv4 multicast socket\r\n");
    }
    while(1)
    {
        len=recvfrom(sock,data,100,0,(struct sockaddr *)&client,&client_len); 
        if((len < 0) || ( len > 100))
        {
            printf("recvfrom error\n");
            continue;
        }
        printf("DNS request:");
        for(i = 0x4; i< len;i++)
        {
            if((data[i] >= 'a' && data[i] <= 'z') || (data[i] >= 'A' && data[i] <= 'Z') ||(data[i] >= '0' && data[i] <= '9'))
                printf("%c",data[i]);
            else
                printf("_");
        }
        printf("\r\n");
        if( strstr((const char *)data+0xc,"taobao")||
            strstr((const char *)data+0xc,"qq")    || 
            strstr((const char *)data+0xc,"sogou") ||
            strstr((const char *)data+0xc,"amap")  ||
            strstr((const char *)data+0xc,"alipay")||
            strstr((const char *)data+0xc,"youku") ||
            strstr((const char *)data+0xc,"iqiyi") ||
            strstr((const char *)data+0xc,"baidu"))
        {
            continue;
        }
        data[2] |= 0x80; //
        data[3] |= 0x80; //与接收的高位不同之处
        data[7] =1;  //问题个数
        //与接收的域名相同可用指针代替
        //前两位表示最高两bit为11,表示指正方式(非指正方式,最高两bit为00)
        //后14为表示前面接收的域名的为止 这里从11位开始
        data[len++] =0xc0;
        data[len++] =0x0c; 
		//不变的
        data[len++] =0x00;
        data[len++] =0x01;
        data[len++] =0x00;
        data[len++] =0x01;
		//有效时间
        data[len++] =0x00;
        data[len++] =0x00;
        data[len++] =0x00;
        data[len++] =0x0A;
		//下面的数据长度
        data[len++] =0x00;
        data[len++] =0x04;
        data[len++] =192;
        data[len++] =168;
        data[len++] =88;
        data[len++] =1;
        sendto(sock,data,len,0,(struct sockaddr*)&client,client_len);
        OS_MSleep(10);
    }
    printf("DNS server stop ...\r\n");
    shutdown(sock, 0);
    close(sock);
    OS_ThreadDelete(NULL);



}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值