精华内容
下载资源
问答
  • wifi 一键配网资料

    2019-01-16 15:30:44
    一键配网用的apk ,oneshot 用于WIFI UDP 广播 初始化
  •  http://blog.csdn.net/flyingcys/article/details/49283273智能家居/家电现阶段还处于普及阶段,由于家庭wifi网络的普及,目前普遍采用wifi与路由器完成连接,与手机/云端进行数据交互.智能硬件,如智能插座,智能空调,...
    
    

    智能家居/家电现阶段还处于普及阶段,由于家庭wifi网络的普及,目前普遍采用wifi与路由器完成连接,与手机/云端进行数据交互.

    智能硬件,如智能插座,智能空调,智能空气净化器由于不具备人机交互界面,不能像电脑一样的搜索/选择指定路由器,输入连接密码的界面,所以必须先解决正确连接路由问题;

    目前流行的wifi配置模式一般有以下2:

    1:智能硬件处于AP模式,手机用于station模式,手机连接智能插座的AP后组成局域网,手机发送需要连接路由的SSID及密码至智能插座,智能硬件主动去连接指定路由后,完成连接

    2:一键配置(smartconfig)模式:智能硬件处于混杂模式下,监听网络中的所有报文;手机APPSSID和密码编码到UDP报文中,通过广播包或组播报发送,智能硬件接收到UDP报文后解码,得到正确的SSID和密码,然后主动连接指定SSID的路由,完成连接

    以上两种方式都可以达到让智能硬件连接至指定路由的效果,但是AP模式需要手动切换手机wifi连接的网络,先连接智能硬件的AP网络,配置完成后再恢复连接正常wifi网络.有一定的复杂性;

    但是smartconfig由于路由器品牌及手机品牌众多,存在一定的兼容性问题,所以目前一般厂家仍保留AP模式,作为smartconfig失败后的备用配网方案;

    下面重点讲解一下一键配置模式原理及应用;当前主流IOTwifi方案有:

     

    厂商

    芯片方案

    技术名称

    发包方式

    1

    TI 

    CC3200

    SmartConfig

    往某一固定IPudp

    2

    高通

    QCA4004/QCA4002

    SmartConnection

     

    3

    联发科MTK

    MTK7681

    SmartConnection

    组播地址编码

    4

    MARVELL

    MC200+8801/MW300

    EasyConnect

    组播地址编码

    5

    Reltek

    AMEBA

    SimpleConfig

    组播地址编码

    6

    乐鑫

    Esp8266

    SmartConfig

    组播,通过长度编码

    7

    新案线

    NL6621

    SmartConfig

    组播地址编码

    8

    微信

     

    AirKiss

    全网广播,通过长度编码

     

    这个功能最早是TI提出并应用于CC3200;不过从原理上讲,只要芯片驱动支持开启混杂模式(WiFi Promiscuous),就可以支持一键配网功能,只是各个厂家叫法及实现编码方式不同而已;

    手机编码发送采用有UDP组播或广播,不同的发送方式和编码,对应的解码过程也不一样.,当前测试发现,微信是通过UDP广播包实现的;TI是通过往一固定IP地址发送udp;其他芯片厂家提供的一般为UDP组播方式;

    由于无线数据传播必定是广播的,所以必然可以被监听到;如果AP没有加密的话,UDP直接可以把相关的信息发送出来.但是路由器AP一般都是加密的,而且加密方式不固定.wifi模块在无法直接解析出数据包

    我们通过分析802.11MAC帧格式,可以知道,链路层载荷数据(即网络层的头部及网络层数)在数据帧中是清晰可见的,只要接到到802.11帧就可以立刻提取出载荷数据.

    常见两种数据帧格式:

    Station to AP

     

    AP to Station

     

     

    DA:目标MAC地址

    SA:MAC地址

    LENGTH:表示后面数据的长度

    LLC:表示LLC

    SNAP:表示3byte的厂商代码和2byte的协议类型表示

    DATA:载荷数据

    FCS:帧检验序列


    发送端:可以采用2种不同的编码发送方式UDP广播和组播;

    :UDP广播:小规模测试后,发现当前只有微信的AirKiss采用了全网广播模式,为啥微信会采用广播模式,原因未知;TI采用的是固定IP地址的UDP数据包,原理和微信基本一致;

    802.11帧格式分析中获知,无线信号监听方的角度来说,不管无线信道有没有加密,DASALENGTH LLCSNAPFCS字段总是暴露的,因此信号监听方可以从这6个字段获取有效信息.从发送方讲,由于操作系统的限制,如果采用广播只剩下LENGTH发送方可通过改变其所需要发送数据包的长度进行控制.所以只要指定出一套利用长度编码的通讯协议,就可利用数据包的Lenght字段进行数据传递;

     

    :UDP组播:

    组播地址是保留的D类地址从224.0.0.0-239.255.255.255

    IP地址与MAC地址映射关系为:MAC地址的前25位设定为01.00.5e,MAC地址的后23位对应IP地址的位;

    故发送端可以将数据编码在组播ip的后23bit,通过组播包发送,接收端进行解码即可;

     

    接收端进入一键配置功能后,wifi智能硬件从信道1开始监听路由上的数据,如当前监听信道有符合规则的数据包,就停止信道切换,停留在当前信道接收完全部数据.否则就依次切换至信道2.3.4....直到信道14后又从信道1开始继续监听依次循环;

    当然,wifi智能硬件可以在开启混杂模式之前,先行扫描当前环境下存在的AP获取所有当前AP的信道,然后只对当前扫描到的信道进行依次监听,如当前环境下只存在2个路由,分别在1.6信道,只需轮流扫描channel1channel6,这样可以提高配置效率

    展开全文
  • 一、背景 物联网时代技术开始规模化服务于民众,方便快捷显得尤为重要,WIFI 直连便是一个典型案例。 目前主流的 WIFI 配置模式有以下 2 种: 1、智能硬件处于 AP 模式(类似路由器,组成局域网...2、一键配网(sm...

    一、背景

    物联网时代技术开始规模化服务于民众,方便快捷显得尤为重要,WIFI 直连便是一个典型案例。

    目前主流的 WIFI 配置模式有以下 2 种:

    1、智能硬件处于 AP 模式(类似路由器,组成局域网),手机用于 STA 模式

    手机连接到处于 AP 模式的智能硬件后组成局域网,手机发送需要连接路由的 SSID 及密码至智能硬件,智能硬件主动去连接指定路由后,完成配网

    2、一键配网(smartConfig)模式

    智能硬件处于混杂模式下,监听网络中的所有报文;手机 APP 将 SSID 和密码编码到 UDP 报文中,通过广播包或组播报发送,智能硬件接收到 UDP 报文后解码,得到正确的 SSID 和密码,然后主动连接指定 SSID 的路由完成连接。

    AP 模式:

    AP 是 (Wireless) Access Point 的缩写,即 (无线) 访问接入点。简单来讲就像是无线路由器一样,设备打开后进入 AP 模式,在手机的网络列表里面,可以搜索到类似 TPLINK_XXX 的名字(SSID)。

    连接步骤:

    1、智能硬件设备初始化并进入 AP 模式
    2、手机扫描 WIFI 列表:扫描到智能硬件设备后(SSID)连接该智能硬件设备,通过 UDP 发送 经过 AES 加密过的 ssid/password/token
    3、智能硬件设备通过 UDP 包获取配置信息,切换网络模式连接 WIFI 后配网完成

    smartConfig 模式:

    这种快速连接方式,相对于 AP 模式连接简化操作,更加贴近于市场

    1、手机连上 WiFi,打开智能硬件指定 APP 软件,进入配置界面,输入手机所在 WiFi 密码,请求配网 TOKEN
    2、智能硬件开启混杂模式监听所有网络数据包
    3、手机通过广播、组播循环发送 ssid/password/token
    4、硬件设备通过 UDP 包(长度)获取配置信息捕捉到 ssid/password/token,连接路由器(广播根据 UDP 包长度,组播根据 IP 地址信息)


    从原理上讲只要芯片驱动支持开启混杂模式(WiFi Promiscuous),就可以支持一键配网功能

    手机编码发送采用有 UDP 组播或广播,不同的发送方式和编码,对应的解码过程也不一样

    1、广播:

    发送方可通过改变其所需要发送数据包的长度进行控制,因此只要指定出一套利用长度编码的通讯协议,就可利用数据包的 Length 字段进行数据传递

    2、 组播:

    组播地址是保留的 D 类地址从224.0.0.0-239.255.255.255

    IP 地址与 MAC 地址映射关系为:将 MAC 地址的前 25 位设定为 01.00.5e,而 MAC 地址的后 23 位对应 IP 地址位

    故发送端可以将数据编码在组播 IP 的后 23bit 中,通过组播包发送接收端进行解码即可

    二、smartConfig 原理浅析

    在没有和其他设备(支持 smartConfig 技术)建立任何性质的通讯链路的情况下, 配置该设备接入 WIFI 网络 

    普通权限的应用程序是没有能力完全控制和定义传输层及下层所有协议数据的, 唯一可以完全控制的就是应用层数据

    本质上就是将 UDP 包头的数据长度作为 smartConfig 的数据,APP 端和设备端共用一套编码表即可解析数据 

    TCP/IP 协议栈中的网络层和传输层的数据结构 

    常用的网络层协议是 IPv4, IPv4 的头部绝大多数情况下都是定长的20字节

    传输层协议是 UDP, 因为 UDP 协议头部为定长的 8 字节

    明文长度 = 20 + 8 + dataLen

    密文长度 = 20 + 8 + dataLen + 算法常量

    例子:

    如果需要发出一个密文长度为 500 字节的 802.11 帧,只需要在 UDP 中填充任意(500 – 20 – 8 – 算法常亮)个字节数据即可

    因此,只需要利用可控的密文长度(dataLen)定义一张编码表即可将数据告诉任何知道这张编码表的设备(IoT硬件设备)

    自定义一张编码表,流程如下:

    dataLen --> 映射
    1234    --> 起始符; 连续的3个起始符, 用于表示数据传输开始 
    1324    --> 结束符; 连续的3个结束符, 用于表示数据传输结束 
    110     --> 间隔符; 连续的2个间隔符, 用于表示数据符之间的间隔 
    1000    --> 数据符; 表示 ASCII 0x00 
    1001    --> 数据符; 表示 ASCII 0x01 
    … 
    1127    --> 数据符; 表示 ASCII 0x7F

    假设我们要把字符串"Jay"告诉摄像头, 整个流程大致如下: (假设算法常亮为 16)

    APP 端:
     
    打开手机 APP, 在输入框中填入要发送的字符串”Jay”, 点击发送:

    1.1、APP 连续发送 3 个 UDP 广播包, 填充数据为 1190 个字节 0x00 数据 ( 1234 – 16 – 20 – 8 = 1190 ), 表示传输开始 
    1.2、APP 发送     1 个 UDP 广播包, 填充数据为 1030 个字节 0x00 数据 ( 1074 – 16 -20 – 8 = 1030  ), 传输字符 J 
    1.3、APP 连续发送 2 个 UDP 广播包, 填充数据为 66   个字节 0x00 数据 ( 110 – 16 – 20 – 8 = 66    ), 表示数据间隔 
    1.4、APP 发送     1 个 UDP 广播包, 填充数据为 1053 个字节 0x00 数据 ( 1097 – 16 -20 – 8 = 1053  ), 传输字符 1097 对应 a 
    1.5、APP 连续发送 2 个 UDP 广播包, 填充数据为 66   个字节 0x00 数据 ( 110 – 16 – 20 – 8 = 66    ), 表示数据间隔 
    1.6、APP 发送     1 个 UDP 广播包, 填充数据为 1077 个字节 0x00 数据 ( 1121 – 16 -20 – 8 = 1077  ), 传输字符 1121 对应 y 
    1.7、APP 连续发送 3 个 UDP 广播包, 填充数据为 1280 个字节 0x00 数据 ( 1324- 16 – 20 – 8 = 1280  ), 表示传输结束

    从步骤 1.1 开始循环多次, 直到超时或 IoT 设备成功接入 WIFI

    IoT 设备端:

    设备上电进入混杂模式,开始监听信号覆盖范围内的所有 WIFI 数据帧

    捕获数据帧, 如果连续收到 3 个密文,其数据长度 dataLen 为 1234 字节, 且来自于同一个发射源 channel-A 的数据帧, 则进入下一步, 否则该步骤

    捕获发射源 channel-A 的数据帧, 持续捕获密文数据长度为 110 或 1000-1127 之间的数据帧, 直到捕获到连续 3 个密文数据长度为 1324 的数据帧

    将上述数据帧按照编码表进行映射, 由于手机 APP 并非是独占网络, 所以捕获到的数据可能有噪音, 比如解码出来的结果可能是(/表示分隔符): mnJ/o@a/ymmm

    如果没有噪音, 记为候选数据RC, 重复捕获X, 进行二次验证, 通过则表示接收完成, 没通过也重复捕获 channel-A,

    将这次所得结果同上一次做交集, 循环如此直到得出唯一结果, 即 RC, 之后再重复 5

    由于捕获的数据帧头部信息中已经包含了 WIFI 的 BSSID 信息, 使用 "Jay" 作为密码去尝试连接相应的 WIFI

    三、ESP32 配网实例:

    手机 APP:

    ESP-TOUCH

    烧写设备端:

    #include "WiFi.h"
    
    void setup() {
      Serial.begin(115200);
    
      //Init WiFi as Station, start SmartConfig
      WiFi.mode(WIFI_AP_STA);
      WiFi.beginSmartConfig();
    
      //Wait for SmartConfig packet from mobile
      Serial.println("Waiting for SmartConfig.");
      while (!WiFi.smartConfigDone()) {
        delay(500);
        Serial.print(".");
      }
    
      Serial.println("");
      Serial.println("SmartConfig received.");
    
      //Wait for WiFi to connect to AP
      Serial.println("Waiting for WiFi");
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
      }
    
      Serial.println("WiFi Connected.");
    
      Serial.print("IP Address: ");
      Serial.println(WiFi.localIP());
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
    
    }

    四、知识扩展

    在当前网络通信中有三种通信模式:

    单播、广播、组播(又叫多播),其中多播出现的时间最晚,但同时具备单播和广播的优点,最具有发展前景.

    通信方式分类:

        1.单播:单台主机与单台主机之间的通信;

        2.广播:单台主机与网络中所有主机的通信;

        3.组播:单台主机与选定的一组主机的通信;

    单播:

         单播是网络通信中最常见的,网络节点之间的通信 就好像是人们之间的对话一样,如果一个人对另外一个人说话,那么用网络技术的术语来描述就是“单播”,此时信息的接收和传递只在两个节点之间进行。

         1. 单播的优点:

             (1)服务器以及响应客户端的请求;

             (2)服务器能针对每个客户端的不同请求发送不同的响应,容易显示个性化服务;

         2. 单播的缺点:

             服务器针对每个客户机发送数据流,服务器流量=客户机数量×客户机流量;在客户数量大、每个客户机流量大的流媒体应用中服务器不堪重负;

         3. 应用场景:

            单播在网络中得到了广泛的应用,网络上绝大部分的数据都是以单播的形式传输的,例如:收发电子邮件、游览网页时,必须与邮件服务器、服务器建立连接,此时使用的就是单播通信方式;

    UDP 单播:
    
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    import java.net.InetSocketAddress;
    import java.net.SocketAddress;
     
    // 客户端
    public class ClientTest
    {
        private static final int MAXRECEIVED = 255;
     
        public static void main(String[] args) throws IOException
        {
            byte[] msg = new String("connect test successfully!!!").getBytes();
     
            DatagramSocket client = new DatagramSocket();
     
            InetAddress inetAddr = InetAddress.getLocalHost();
            SocketAddress socketAddr = new InetSocketAddress(inetAddr, 8888);
     
            DatagramPacket sendPacket = new DatagramPacket(msg, msg.length,
                    socketAddr);
     
            client.send(sendPacket);
     
            client.close();
        }
    }
     
     
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.util.Arrays;
     
    //服务端
    public class ServerTest
    {
        private static final int MAXREV = 255;
     
        public static void main(String[] args) throws IOException
        {
            DatagramSocket server = new DatagramSocket(8888);
            DatagramPacket recvPacket = new DatagramPacket(new byte[MAXREV], MAXREV);
     
            while (true)
            {
                server.receive(recvPacket);
     
                byte[] receiveMsg = Arrays.copyOfRange(recvPacket.getData(),
                        recvPacket.getOffset(),
                        recvPacket.getOffset() + recvPacket.getLength());
     
                System.out.println("Handing at client "
                        + recvPacket.getAddress().getHostName() + " ip "
                        + recvPacket.getAddress().getHostAddress());
     
                System.out.println("Server Receive Data:" + new String(receiveMsg));
     
                server.send(recvPacket);
     
            }
     
        }
    }
    

    广播:

        广播可以比作为一个人通过广播喇叭对在场的全体说话,换句话说: 广播是一台主机对某一个网络上的所有主机发送数据报包。

        这个网络可能是网络,也可能时子网,还有可能是所有子网。

        广播有两类:本地广播和定向广播:

                定向广播:将数据报包发送到本网络之外的特定网络的所有主机,互联网上的大部分路由器都不转发定向广播消息;

                本地广播:将数据报包发送到本地网络的所有主机,IPv4的本地广播地址为“255.255.255.255”,路由器不会转发此广播;

        1.广播的优点:

           (1)通信的效率高,信息一下子就可以传递到某一个网络上的所有主机。

           (2)由于服务器不用向每个客户端单独发送数据,所以服务器流量比较负载低;

        2.广播的缺点:

           (1)非常占用网络的带宽;

           (2)缺乏针对性,也不管主机是否真的需要接收该数据, 就强制的接收数据;

        3.应用场景:

           有线电视就是典型的广播型网络

    UDP 广播:
    
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
     
    //客户端
    public class BroadcastSender
    {
        public static void main(String[] args) throws IOException
        {
            byte[] msg = new String("connection successfully!!!").getBytes();
            /*
             * 在Java UDP中单播与广播的代码是相同的,要实现具有广播功能的程序只需要使用广播地址即可, 例如:这里使用了本地的广播地址
             */
            InetAddress inetAddr = InetAddress.getByName("255.255.255.255");
            DatagramSocket client = new DatagramSocket();
     
            DatagramPacket sendPack = new DatagramPacket(msg, msg.length, inetAddr,
                    8888);
     
            client.send(sendPack);
            System.out.println("Client send msg complete");
            client.close();
        }
    }
     
     
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.util.Arrays;
     
    //服务端
    public class BroadcastReceive
    {
        public static void main(String[] args) throws IOException
        {
     
            DatagramPacket receive = new DatagramPacket(new byte[1024], 1024);
            DatagramSocket server = new DatagramSocket(8888);
     
            System.out.println("---------------------------------");
            System.out.println("Server current start......");
            System.out.println("---------------------------------");
     
            while (true)
            {
                server.receive(receive);
     
                byte[] recvByte = Arrays.copyOfRange(receive.getData(), 0,
                        receive.getLength());
     
                System.out.println("Server receive msg:" + new String(recvByte));
            }
     
        }
    }

    组播:

         组播可以比作为你对着大街喊:女士免费领优惠券,那么女士就会过来,男士就不会过来(组播:其中所有的女士就是一个组)

         换句话说: 
         
         组播是一台主机向指定的一组主机发送数据报包,因为如果采用单播方式,逐个节点传输,有多少个目标节点就会有多少次传送过程,这种方式显然效率极低,是不可取的;
         
         如果采用不区分目标、全部发送的广播方式,虽然一次可以传送完数据,但是显然达不到区分特定数据接收对象的目的,又会占用网络带宽。
         
         采用组播方式,既可以实现一次传送所有目标节点的数据,也可以达到只对特定对象传送数据的目的;

         IP 网络的组播一般通过组播 IP 地址来实现,组播 IP 地址就是 D 类 IP 地址,即 224.0.0.0 至 239.255.255.255 之间的IP地址。

         1.组播的优点:

            (1)具备广播所具备的所有优点;

            (2)与单播相比,提供了发送数据报包的效率,与广播相比,减少了网络流量;

         2.组播的缺点:

            与单播协议相比没有纠错机制,发生丢包错包后难以弥补,但可以通过一定的容错机制和QOS加以弥补;

    UDP 组播:
    
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.InetAddress;
    import java.net.MulticastSocket;
     
    //客户端
    public class MulticastSender
    {
        public static void main(String[] args) throws IOException
        {
            int port = 8888;
            byte[] msg = "Connection successfully!!!".getBytes();
     
            InetAddress inetRemoteAddr = InetAddress.getByName("224.0.0.5");
     
            /*
             * Java UDP组播应用程序主要通过MulticastSocket实例进行通信,它是DatagramSocket的是一个子类,
             * 其中包含了一些额外的可以控制多播的属性.
             * 
             * 注意:
             * 
             * 多播数据报包实际上可以通过DatagramSocket发送,只需要简单地指定一个多播地址。
             * 我们这里使用MulticastSocket,是因为它具有DatagramSocket没有的能力
             */
            MulticastSocket client = new MulticastSocket();
     
            DatagramPacket sendPack = new DatagramPacket(msg, msg.length,
                    inetRemoteAddr, port);
     
            client.send(sendPack);
     
            System.out.println("Client send msg complete");
     
            client.close();
     
        }
    }
     
     
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.InetAddress;
    import java.net.MulticastSocket;
    import java.util.Arrays;
     
    //服务端
    public class MulticastReceive
    {
        public static void main(String[] args) throws IOException
        {
            InetAddress inetRemoteAddr = InetAddress.getByName("224.0.0.5");
     
            DatagramPacket recvPack = new DatagramPacket(new byte[1024], 1024);
     
            MulticastSocket server = new MulticastSocket(8888);
     
            /*
             * 如果是发送数据报包,可以不加入多播组; 如果是接收数据报包,必须加入多播组; 这里是接收数据报包,所以必须加入多播组;
             */
            server.joinGroup(inetRemoteAddr);
     
            System.out.println("---------------------------------");
            System.out.println("Server current start......");
            System.out.println("---------------------------------");
     
            while (true)
            {
                server.receive(recvPack);
     
                byte[] recvByte = Arrays.copyOfRange(recvPack.getData(), 0,
                        recvPack.getLength());
     
                System.out.println("Server receive msg:" + new String(recvByte));
            }
     
        }
    }

    refer:

    https://wenku.baidu.com/view/ab6bc08a9b6648d7c0c746ac.html
    https://blog.csdn.net/sadshen/article/details/47049129

    https://my.oschina.net/u/2396236/blog/1788674
    https://blog.csdn.net/li_yangyang_li/article/details/50989220
    https://blog.csdn.net/flyingcys/article/details/49283273

    https://blog.csdn.net/dabing69221/article/details/17286441#t1

    展开全文
  • 主要介绍了微信小程序实现的一键连接wifi功能,结合实例形式分析了微信小程序操作WiFi连接的模块初始化、配置、连接等相关操作技巧,需要的朋友可以参考下
  • esp8266可用的一键配网(smart)demo,该模式ESP8266无需开启AP,快捷配网,亲测好用。适用于iOS。
  • 1、微信公众号中的基本配置里面完成IP白名单配置,很重要,影响access_token image.png 2、将下面文件下载放到目录中,只需要修改airkiss.php中的"yourAppID","yourAppSecret",其他不变 ...{"acces...

    1、微信公众号中的基本配置里面完成IP白名单配置,很重要,影响access_token

     

    image.png

    2、将下面文件下载放到目录中,只需要修改airkiss.php中的"yourAppID","yourAppSecret",其他不变

     

    image

    3、代码详情
    1、access_token.php

     

    <?php exit();?>
    {"access_token":"","expire_time":0}
    

    2、airkiss.php

     

    <?php
    require_once "jssdk.php";
    $jssdk = new JSSDK("yourAppID", "yourAppSecret");//这里改成自己的
    $signPackage = $jssdk->GetSignPackage();
    ?>
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title></title>
    </head>
    <body>
    
    </body>
    <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
    <script>
        wx.config({
        beta:true,//开启内测接口调用,注入wx.invoke方法
        debug:false,//关闭调试模式
        appId: '<?php echo $signPackage["appId"];?>',//AppID
        timestamp: <?php echo $signPackage["timestamp"];?>,//时间戳
        nonceStr: '<?php echo $signPackage["nonceStr"];?>',//随机串
        signature: '<?php echo $signPackage["signature"];?>',//签名
        jsApiList: [
          // 所有要调用的 API 都要加到这个列表中
          'configWXDeviceWiFi'
        ]
      });
      wx.ready(function () {
        // 在这里调用 API
       wx.checkJsApi({
                jsApiList: ['configWXDeviceWiFi'],
                success: function(res) {
                    wx.invoke('configWXDeviceWiFi', {}, function(res){
                        var err_msg = res.err_msg;
                        if(err_msg == 'configWXDeviceWiFi:ok') {
                            //配置成功
                            alert("WIFI配置成功");
                            window.location.href = 'https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=MzU5NzUzNDMwMw==&scene=124#wechat_redirect'
                        } else {
                            //配置失败
                            alert(err_msg);
                        }
                    });
                }
            });
      });
      wx.error(function(res){
          alert("配置出错");
      });
    </script>
    </html>
    

    3、jsapi_ticket.php

     

    <?php exit();?>
    {"jsapi_ticket":"","expire_time":0}
    

    4、jssdk.php

     

    <?php
    class JSSDK {
      private $appId;
      private $appSecret;
    
      public function __construct($appId, $appSecret) {
        $this->appId = $appId;
        $this->appSecret = $appSecret;
      }
    
      public function getSignPackage() {
        $jsapiTicket = $this->getJsApiTicket();
    
        // 注意 URL 一定要动态获取,不能 hardcode.
        $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
        $url = "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
    
        $timestamp = time();
        $nonceStr = $this->createNonceStr();
    
        // 这里参数的顺序要按照 key 值 ASCII 码升序排序
        $string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr&timestamp=$timestamp&url=$url";
    
        $signature = sha1($string);
        //var_dump($signature);exit;
    
        $signPackage = array(
          "appId"     => $this->appId,
          "nonceStr"  => $nonceStr,
          "timestamp" => $timestamp,
          "url"       => $url,
          "signature" => $signature,
          "rawString" => $string
        );
        return $signPackage; 
      }
    
      private function createNonceStr($length = 16) {
        $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++) {
          $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        return $str;
      }
    
      private function getJsApiTicket() {
        // jsapi_ticket 应该全局存储与更新,以下代码以写入到文件中做示例
        $data = json_decode($this->get_php_file("jsapi_ticket.php"));
        if ($data->expire_time < time()) {
          $accessToken = $this->getAccessToken();
          
          $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=$accessToken";
          $res = json_decode($this->httpGet($url));
          $ticket = $res->ticket;
          if ($ticket) {
            $data->expire_time = time() + 7000;
            $data->jsapi_ticket = $ticket;
            $this->set_php_file("jsapi_ticket.php", json_encode($data));
          }
        } else {
          $ticket = $data->jsapi_ticket;
        }
    
        return $ticket;
      }
    
      private function getAccessToken() {
        // access_token 应该全局存储与更新,以下代码以写入到文件中做示例
        $data = json_decode($this->get_php_file("access_token.php"));
        if ($data->expire_time < time()) {
            
          $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$this->appId&secret=$this->appSecret";
          //var_dump($url);exit;
          $res = json_decode($this->httpGet($url));
          //var_dump($res->expires_in);exit;
          $access_token = $res->access_token;
          //var_dump($access_token);exit;
          if ($access_token) {
            $data->expire_time = time() + 7000;
            $data->access_token = $access_token;
            $this->set_php_file("access_token.php", json_encode($data));
          }
        } else {
          $access_token = $data->access_token;
        }
        return $access_token;
      }
    
      private function httpGet($url) {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_TIMEOUT, 500);
        // 为保证第三方服务器与微信服务器之间数据传输的安全性,所有微信接口采用https方式调用,必须使用下面2行代码打开ssl安全校验。
        // 如果在部署过程中代码在此处验证失败,请到 http://curl.haxx.se/ca/cacert.pem 下载新的证书判别文件。
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
        curl_setopt($curl, CURLOPT_URL, $url);
    
        $res = curl_exec($curl);
        curl_close($curl);
    
        return $res;
      }
    
      private function get_php_file($filename) {
        return trim(substr(file_get_contents($filename), 15));
      }
      private function set_php_file($filename, $content) {
        $fp = fopen($filename, "w");
        fwrite($fp, "<?php exit();?>" . $content);
        fclose($fp);
      }
    }
    

    注意:MP_verify*.txt这个文件先不要,可以先跳过

    5、找到设备功能进行开启

    image

    6、访问自己配置的目录http://aa.test.com/wx/airkiss.php便可以跳出

    image

    注意:如果此时跳出,则结束,如果还不行,可能需要JS接口安全域名配置
    注意1:进入微信公众平台后台,在公众号设置->功能设置界面下配置好JS接口安全域名,如下图

     

    image.png

     

    此时会涉及上面下载的MP_verify*.txt文件,放到相应目录就可以,可以设置二级域名下的路径,如:aa.test.com/wx

    注意2:如果需要服务器进行推送,需要创建一个index.php

     

    <?php
    
    define("TOKEN","echolucky");
    
    function checkSignature()
    
    {
    
        //从GET参数中读取三个字段的值
    
        $signature = $_GET["signature"];
    
        $timestamp = $_GET["timestamp"];
    
        $nonce = $_GET["nonce"];
    
        //读取预定义的TOKEN
    
        $token = TOKEN;
    
        //对数组进行排序
    
        $tmpArr = array($token, $timestamp, $nonce);
    
        sort($tmpArr, SORT_STRING);
    
        //对三个字段进行sha1运算
    
        $tmpStr = implode( $tmpArr );
    
        $tmpStr = sha1( $tmpStr );
    
        //判断我方计算的结果是否和微信端计算的结果相符
    
        //这样利用只有微信端和我方了解的token作对比,验证访问是否来自微信官方.
    
        if( $tmpStr == $signature ){
    
            return true;
    
        }else{
    
            return false;
    
        }
    
    }
    
    if(checkSignature()){
    
        echo $_GET["echostr"];
    
    }
    
    else{
    
        echo 'error';
    
    }



    作者:IT和金融
    链接:https://www.jianshu.com/p/28e148c47fe5
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    展开全文
  • esp8266可用的一键配网(smart)demo,无需esp8266开启AP,可快速配网,亲测可用。安卓源码。
  • Airkiss一键配网小工具

    2018-05-28 10:53:30
    1、基于Airkiss原理,在Android上开发的一键配网小工具,可以为支持Airkiss的智能wifi设备进行一键配网。 2、使用简单,只需把你的智能设备进入一键配网模式,然后打开APK输入wifi对应的密码即可。 3、本工具用于...
  • EZ配网也叫wifi快连,目前市面上EZ配网的功能需要设备支持monitor模式(也称为混杂模式),即设备应当具有监听当前环境中空气包的能力。并且设备可以对相关的报文进行筛选,并解析出设备中特定信息用于完成配网。 目前...

    一键配网说明

    一键配网基本流程

    说明

    wifi快连也叫一键配网,也叫EZ配网。目前市面上一键配网的功能需要设备支持monitor模式(也称为混杂模式),即设备应当具有监听当前环境中空气包的能力。并且设备可以对相关的报文进行筛选,并解析出设备中特定信息用于完成配网。

    由于一键配网操作简单,不需要像AP(热点)配网那样需要用户频繁的操作。用户只需要点击APP上的配网按键,就有相关配网程序来完成设备的配网,对用户来说比较友好。所以目前市面上大多数做物联网解决方案的厂商,都会在自己的产品里支持这一配网功能。

    目前EZ配网一般流程为:APP(一般为用户手机端)端发送带有AP ssid和AP passwd以及token的广播包或组播包。同时设备端开启监听模式,监听这个过程中的所有报文,通过约定加密方式解密出AP的ssid 、passwd、token等。然后设备切换到station模式开始配网。

    配网流程

    整个配网过程,如下图所示:

    在这里插入图片描述

    EZ配网原理

    EZ配网通过组播或者广播报文来携带ssid/passwd/token等信息,然后设备端通过约定的加密方式来对相关信息进行解密,从而达到配网的目的。采用这两种通信方式的目的是使环境当中尽可能多的设备能接受到APP发出的信息,因为我们当前并不知道设备相关信息,所以无法直接发送特定的信息给到设备。

    组播

    组播很多时候也叫多播。组播传送地址作为目的物理地址的帧可以被组内的其它主机同时接收,而组外主机却接收不到。但是,如果将网卡设置为组播传送模式,它可以接收所有的组播传送帧,而不论它是不是组内成员。

    监听端(即设备端),会使wifi网卡在1-13信道循环监听组播wifi数据帧,以约定的组播MAC地址为同步头,当监听到同步头之后,进入接收模式并锁定信道。并且只接收来自该MAC地址的组播wifi数据帧,在接收完包头信息及数据之后进行解析,再使用之前约定的密钥解密,得到ssid/passphrase/token,同时设备切换为station模式,开始配网。
    在这里插入图片描述

    wifi组播配网正是利用了之前所说的组地址与组播MAC地址之间的映射及wifi数据帧头中的MAC地址信息来传输配网信息。IP地址与MAC地址映射关系为:将MAC地址的前25位设定为01:00:5e,而MAC地址的后23位对应IP地址的位;故发送端可以将数据编码在组播ip的后23bit中,通过组播包发送,接收端按照约定进行解码即可。

    广播

    广播即向环境中所有设备广播报文,它的目的MAC地址是 FF:FF:FF:FF:FF:FF的帧为广播帧。
    在这里插入图片描述

    显然,广播与组播有所不同,它的目的MAC地址是固定的。那么我们通过什么方式来编码相关信息呢?数据长度。广播帧会通过发送数据长度不同的广播帧来编码数据,并且不断的循环发送。

    同样的,设备会在所支持的信道(通常是1-13信道间不断的轮询),直到捕获到符合配网规则的数据报文后停止信道轮询,尝试在此信道上接收完成所有报文,若当前信道接收失败或超时则重新开始信道轮询。

    EZ配网优缺点及优化建议

    优点

    1. 用户的操作相对更少,更加方便。
    2. 配网时间相对其他方式会更短,体验相对会更好。
    3. 配网的数据会被加密,安全性更高。

    缺点

    1. APP端需要向设备发送ssid/passwd/token,这三个信息若有任意一个有错误,都会导致配网失败。
    2. 若手机连接的是5G频段的路由器则会导致设备无法接受到手机端组播/广播的信息而导致配网失败,因为设备一般默认只支持2.4G频段。
    3. 对手机和路由器的兼容性有较高的要求,如有些路由器会默认关闭广播/组播报文的转发,使得设备接收不到路由器转发的报文,从而导致配网失败。
    4. 因为设备端是通过连续多包数据来解析ssid/passwd/token等信息,所以若通信质量不佳,其中只要有一包数据丢失,就会导致解析数据失败,开始下一轮循环。
    5. 因为EZ配网同时存在以上这些缺点,所以EZ配网很多时候配网成功率相对不会很高,所以需要制定相应的第二方案当EZ配网失败时可以转换为相应的成功率更高的配网方式。

    优化建议

    1. 减少token长度。通过上面的分析,可以发现EZ配网的数据传输效率并不高,需要通过连续多包数据才能解析出对应的加密信息。ssid和passwd是由用户设定的,我们无法改变,所以通过减少token长度可以减少配网时间以及增加配网成功率。
    2. 采用组播+广播的方式传输信息。采用这种方式会同时通过组播和广播的方式编码配网信息,设备端只需要看哪种方式先被解析出配网信息。这样也会增加配网成功率以及节省配网时间。
      会同时通过组播和广播的方式编码配网信息,设备端只需要看哪种方式先被解析出配网信息。这样也会增加配网成功率以及节省配网时间。
    3. 优化设备的收包能力,避免因为设备端丢包或者将某些包过滤掉而导致配网失败。
    展开全文
  • 乐鑫esp8266/esp32一键配网smartconfig配网中文版V0.3.6.2,新增保存上次输入密码,简洁明了,配网速度比上几个版本快几倍。博客:https://blog.csdn.net/xh870189248/article/details/78677952
  • 原理,将手机端已连接的WIFI,输入密码后,广播,等待物联网模块接收后自动配网连接网络。 使用方法:下载,解压,安装。如有疑问请联系作者或留言。 TIP:工具,是物联网开发可能用到的网络配置工具。安卓手机。
  • 顾名思义,通过蓝牙给WIFI配网,过程相对较为简单,首先设备上具有WIFI和蓝牙两种功能。然后通过手机的小程序或者APP连接产品蓝牙,连接之后发送WIFI连接所需要的SSID和PASSID。产品接收到蓝牙信息后,产品WIFI通过...
  • 智能家居/家电现阶段还处于普及阶段,由于家庭wifi网络的普及,目前普遍采用wifi与路由器完成连接,与手机/云端进行数据交互. 智能硬件,如智能插座,智能空调,智能空气净化器由于不具备人机交互界面,不能像电脑一样的...
  • 同时也提供一种让智能设备连接到恶意WiFi的方式:设备一键配置功能时疯狂广播恶意WiFi的信息。 转自:http://blog.csdn.net/lbaihao/article/details/74231693 原文如下: 智能家居/家电现阶段还处于普及阶段,...
  • 乐鑫Esp32的smartConfig和微信airKiss,一键配网轻松快捷连接路由器。CSDN博客 https://blog.csdn.net/xh870189248/article/details/80430077
  • ESP8266_21基于ESP8266的一键配网

    千次阅读 2019-11-07 18:39:16
     ESPTOUCH是乐鑫提供的一键配网的APP,这里代表的是smartconfig模式,文章结尾会提供APP下载链接。  后面两行代码,一行用来设置ESP8266的工作模式,另一行启动配网,并设置相关的回调函数。    控制...
  • 听到 SmartConfig这个单词,字义上就是智能配置,但是我们电子发烧友都是称之为一键配网, 听到Airkiss这个单词就有点意思了。飞吻,象征着速度飞一般的快。 本博文的配网截图: 8266...
  • 原理,将手机端已连接的WIFI,输入密码后,广播,等待物联网模块接收后自动配网连接网络。 下载地址,吾爱和x5zj.com 已发。或在下载页下载,连接看回复地址,资源审核中,先...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,972
精华内容 788
热门标签
关键字:

wifi一键配网