mp.weixin.qq.com /s/kxpH55eN72Lx65MIZbQwUA

开源 | 智能家居场景,基于 AriKiss 配网的微信小程序

徐宏 6-8 minutes
一次偶然的机会,群里某开发者问我为什么他的微信配网出问题了,我跟着回复了些问题,发现并不是那么简单,于是乎帮这位朋友适配了下并成功了,决定在全网首个开源可实现Airkiss配网的微信小程序。
图片
获取源码请见文章底部。
1
揭开微信配网的神秘面纱
AirKiss微信配网虽然是2016年开放的技术,但一直是智能家居配网领域值得深究的话题!因为在实际Wi-Fi产品用到太多了,今天大家依然非常关注这个问题,今天我就用安信可 ESP-C3-12F 模组调试,全面给大家解析我是如何在微信小程序上实现这个协议的。
首先我们理清几个问题,也是我移植前所思考的问题:

1. airkiss实现的原理?协议?配网过程?

2. 对于airkiss源码,有什么途径获取?可以从设备端、前端拿到协议对比吗?

3. 对于一键配网的弊端,你是如何优化的?为什么有些路由器怎么都无法配网?

4. 微信小程序这块支持本地组网?如何调用相关函数方法?

了解AirKiss协议:

AirKiss是微信硬件平台为Wi-Fi设备提供的微信配网、局域网发现和局域网通讯的技术。开发者若要实现通过微信客户端对Wi-Fi设备配网、通过微信客户端在局域网发现Wi-Fi设备,或者把微信客户端内的音乐、图片、文件等消息通过局域网发送至Wi-Fi设备,需要在硬件设备中集成相应的AirKiss静态库。

图片

AirKiss配网的步骤:

1. 安信可ESP-C3-12F模组开启station模式,并抓取空中的混杂UDP包;

2. 手机微信客户端通过AirKiss发送家里的路由器ssid和密码;

3. 安信可ESP-C3-12F模组通过抓包获取到ssid和密码,然后连接到家里的路由器;

4. 安信可ESP-C3-12F模组局域网发送UDP包给手机客户端表示配网成功;

AirKiss配网的基本原理:

1. 混杂模式

安信可ESP-C3-12F模组刚开始同样是以Station的模式运行,但是还有一个监听模式,我们也称为嗅探探针。是什么意思?它是指正常的wifi设备都有一个MAC地址,其硬件电路会自动过滤目标MAC地址跟其MAC不同的数据包。开启混杂模式就是我们平常时说的抓包,就是空中符合802.11格式的数据包都接收进来,不管MAC是否一样。很明显,手机智能配置APP并不知道该wifi设备的MAC地址,所以手机wifi发送出的数据包,通过家里的路由器转发出去时,wifi设备必须要在混杂模式下才能接收到这些数据包。

2. 信道切换

802.11有多个信道,某一个时候wifi设备和路由器都处于某一个信道。路由器一般都是默认在第六信道,所以要想家里的网信号好一点,可以尝试将路由器的信道改到一个其他道,这样就不会和邻居家的wifi信道重叠了。wifi信号混在同一个频道就会互相干扰。

同理,我们也不能假定wifi设备是处于哪个信道,但是我们可以在app中确定手机wifi的发送信道,这样要求wifi设备在一定的时刻切换信道,以便与接收到数据包。当wifi设备检测到有效的数据包,要锁定在该信道进行后续的通信。

3. 利用数据帧的长度来承载有效信息

我们先来看一看802.2 SNAP(802.11的物理层协议)的数据帧格式

图片

DA字段表示目标mac地址,SA字段表示源mac地址,Length字段表示后面数据的长度,LLC字段表示LLC头,SNAP字段包括3bytes的厂商代码和2bytes的协议类型标识,DATA字段为负载,对于加密信道来说是密文的,FCS字段表示帧检验序列。

从无线信号监听方的角度来说,不管无线信道有没有加密DA、SA、Length、LLC、SNAP、FCS字段总是暴露的,因此信号监听方便有了从这6个字段获取信息的可能。但从发送方的角度来说,由于操作系统的限制(比如Android或者IOS),DA、SA、LLC、SNAP、FCS五个字段的控制需要很高的控制权限,发送方一般是很难拿到的。因此只剩下Length这一字段,发送方可以通过改变其所需要发送数据包的长度进行很方便的控制。

所以,只要制定出一套利用长度编码的通信协议,那么就可利用802.2 SNAP 数据包中的Length字段进行信息传递。

在实际应用中,我们采用UDP广播包作为信息的载体。信息发送方向空间中发送一系列的UDP广播包,其中每一包的长度(即Length字段)都按照AirKiss通信协议进行编码,信息接收方利用混杂模式监听空间中的无线信号,并从数据链路层截取802.2 SNAP格式数据包,便可得到已编码的Length字段,随后接收方便可根据AirKiss通信协议解析出需要的信息。

图片

2
ESP-C3-12F模组AirKiss源码分析
安信可ESP-C3-12F是基于乐鑫ESP32C3芯片做的一个支持WiFi+蓝牙的模组,具体参数规格请移步到安信可官网,下面只给大家简单分析AirKiss配网源码的每个关键步骤。
开启嗅探模式,抓取空中的 802.11 包,并传给微信静态库解码。
static void wifi_promiscuous_rx(void *buf, wifi_promiscuous_pkt_type_t type){    wifi_promiscuous_pkt_t *pkt = (wifi_promiscuous_pkt_t *) buf;    uint8_t *payload;    uint16_t len;    int ret;    payload = pkt->payload;    len = pkt->rx_ctrl.sig_len;    //把空中的全部802.11包传给微信静态库来做解析    ret = airkiss_recv(ak_ctx, payload, len);    //符合AirKiss包的规则,开始锁定此信道进行解码    if (ret == AIRKISS_STATUS_CHANNEL_LOCKED) {        esp_timer_stop(channel_change_timer);        esp_timer_delete(channel_change_timer);        ESP_LOGI(TAG, "AIRKISS_STATUS_CHANNEL_LOCKED");    //解析完成,停止嗅探       } else if (ret == AIRKISS_STATUS_COMPLETE) {        esp_wifi_set_promiscuous(false);        airkiss_finish();        ESP_LOGI(TAG, "AIRKISS_STATUS_COMPLETE");    }}

成功解析出来路由器账号密码,并开始连接路由器。

    wifi_config_t wifi_config;    int err;    err = airkiss_get_result(ak_ctx, &result);    if (err == 0) {        //这里的 result 就是一个结构体,里面包含ssid、password等信息    } else {        ESP_LOGI(TAG, "airkiss_get_result() failed !");    }

通过UDP协议发一个ack给手机以通知配网成功,数据是一个长度为7的数组。

    struct sockaddr_in server_addr;    uint8_t buf[7];    socklen_t sin_size = sizeof(server_addr);
bzero(&server_addr, sizeof(struct sockaddr_in)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = INADDR_BROADCAST;    server_addr.sin_port = htons(10000);    //第1个buff是随机数,这个随机数是手机发来的 buf[0] = (uint8_t)ak_random_num;    //第2~6是设备mac地址 esp_wifi_get_mac(WIFI_IF_STA, &buf[1]); //开始发送    sendlen = sendto(send_socket, buf, 70,(struct sockaddr *) &server_addr, sin_size);

图片

3
小程序AirKiss源码分析
先写好对应的组包规则,PrefixCode以及Sequence序列包:
function magicCode(ssid, password) {  let bytes = strToUtf8Bytes(ssid);  let length = bytes.length + password.length + 1;  let magicCode = [];  magicCode[0] = 0x00 | (length >>> 4 & 0xF);  if (magicCode[0] == 0) {    magicCode[0] = 0x08;  }  magicCode[1] = 0x10 | (length & 0xF);  let crc8 = CRC8(bytes);  magicCode[2] = 0x20 | (crc8 >>> 4 & 0xF);  magicCode[3] = 0x30 | (crc8 & 0xF);  for (let i = 0; i < 20; ++i) {    for (let j = 0; j < 4; ++j) {      appendEncodedData(magicCode[j]);    }  }}
function prefixCode(password) { let length = password.length; let prefixCode = []; prefixCode[0] = 0x40 | (length >>> 4 & 0xF); prefixCode[1] = 0x50 | (length & 0xF); let crc8 = CRC8([length]); prefixCode[2] = 0x60 | (crc8 >>> 4 & 0xF); prefixCode[3] = 0x70 | (crc8 & 0xF); // console.log(prefixCode.join()); for (let j = 0; j < 4; ++j) { appendEncodedData(prefixCode[j]); }}

发包前,也务必开启UDP监听,等待设备配网成功的ack信息。

  wxUdp = wx.createUDPSocket();  //监听端口是 10000  let port = wxUdp.bind(10000);  var replyByteCounter = 0;  //监听函数  wxUdp.onMessage(function(res) {    if (res.remoteInfo.size > 0) {         //处理下数据,得到设备的IP和bssid        callback({"ip":res.remoteInfo.address,"bssid":bssid,"result""success""code":1});      }  });

开始发包,注意地址是 255.255.255.255 表示全网段:

  let sendData = new ArrayBuffer(mEncodedData[index]);  wxUdp.send({    address: "255.255.255.255",    port: 10000,    message: sendData  });
4
如何集成到我的项目去
考虑到开发者集成方便,我已封装成小程序插件并上架了,大家拿来即可上手集成到自己的项目去。

自行注册一个微信小程序,请下载最新版的微信开发者工具。

新建项目之后,打开 app.js文件添加下面代码:

  "plugins": {    "airkiss": {      "version": "1.1.0",      "provider": "wx610ea582556c983e"    }  }
然后,会有提示是否添加插件,按照下面提示添加插件使用

图片

下面举例说明了如何使用,更多使用技巧和方法参考本小程序源码,源码在文章底部。

const airkiss = requirePlugin('wx610ea582556c983e');
//获取版本console.log( airkiss.version)
//这里最好加微信小程序判断账号密码是否为空,以及其长度和是否为5G频段airkiss.startAirkiss(this.data.ssid, this.data.password, function (res) { switch (res.code) { case 0: wx.showModal({ title: '初始化失败', content: res.result, showCancel: false, confirmText: '收到', }) break; case 1: wx.showModal({ title: '配网成功', content: '设备IP:' + res.ip + '\r\n 设备Mac:' + res.bssid, showCancel: false, confirmText: '好的', }) break; case 2: wx.showModal({ title: '配网失败', content: '请检查密码是否正确', showCancel: false, confirmText: '收到', }) break;
default: break; }
})//停止配网,建议在页面 unload 等生命周期里面调用,释放线程airkiss.stopAirkiss()  
看到这里,希望你会喜欢。
后台发送“AirKiss”获取微信小程序源代码;

往期推荐

1、云厂商的「物联网平台」不香了吗?

2、2021国内四大IoT平台性能对比

3、国内MCU行业发展研究报告

4、2021年4G通信模组企业排行

5、艾瑞 2021中国 IoT物联网平台研究

6、动图|带你了解PCB板制作过程?

图片

::...
免责声明:
当前网页内容, 由 大妈 ZoomQuiet 使用工具: ScrapBook :: Firefox Extension 人工从互联网中收集并分享;
内容版权归原作者所有;
本人对内容的有效性/合法性不承担任何强制性责任.
若有不妥, 欢迎评注提醒:

或是邮件反馈可也:
askdama[AT]googlegroups.com


订阅 substack 体验古早写作:


点击注册~> 获得 100$ 体验券: DigitalOcean Referral Badge

关注公众号, 持续获得相关各种嗯哼:
zoomquiet


自怼圈/年度番新

DU22.4
关于 ~ DebugUself with DAMA ;-)
粤ICP备18025058号-1
公安备案号: 44049002000656 ...::