浅谈AriKiss微信配网 | 开源一个可实现AriKiss配网的微信小程序

IoT 2年前 (2021) admin
1,399 0 0
浅谈AriKiss微信配网 | 开源一个可实现AriKiss配网的微信小程序

大半年没在公众号发推文了,这几个月都是在CSDN发文章。
好学的态度,一直伴随,偶尔有消极,从未停止
一次偶然的机会,群里某开发者问我为什么他的微信配网出问题了,我跟着回复了些问题,发现并不是那么简单,于是乎帮这位朋友适配了下并成功了,决定在全网首个开源可实现airkiss配网的微信小程序。直接微信识别以上小程序码,即可使用!
这次的开源,可能会动到很多人的蛋糕,很多事情,是无法让每个人满意,甚至是大多数人,望大家点赞、转发、收藏,我将继续撰写有实用性的技术文章。
获取源码请见文章底部。
浅谈AriKiss微信配网 | 开源一个可实现AriKiss配网的微信小程序


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静态库。


浅谈AriKiss微信配网 | 开源一个可实现AriKiss配网的微信小程序


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的物理层协议)的数据帧格式

浅谈AriKiss微信配网 | 开源一个可实现AriKiss配网的微信小程序

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通信协议解析出需要的信息。


浅谈AriKiss微信配网 | 开源一个可实现AriKiss配网的微信小程序


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);


浅谈AriKiss微信配网 | 开源一个可实现AriKiss配网的微信小程序


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"    }  }

然后,会有提示是否添加插件,按照下面提示添加插件使用
浅谈AriKiss微信配网 | 开源一个可实现AriKiss配网的微信小程序


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

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 + 'rn 设备Mac:' + res.bssid, showCancel: false, confirmText: '好的', }) break; case 2: wx.showModal({ title: '配网失败', content: '请检查密码是否正确', showCancel: false, confirmText: '收到', }) break;
default: break; }
})//停止配网,建议在页面 unload 等生命周期里面调用,释放线程airkiss.stopAirkiss()  




看到这里,希望你会喜欢。

后台发送“211125”获取微信小程序airkiss配网工程代码;



-推荐阅读-

点击文字即可阅读全文


☞ 2019年年终总结:平凡的我,仍然在平淡的生活里打拼,寻找未来的曙光。

 2020年终总结:跌跌撞撞,沉下心来,不卑不燥,欲戴王冠,必承其重。

☞ 基于SpringBoot私有服务器对接阿里云物联网服务器,实现M2M数据流。

 我回来了,深度自研开源物联网架构

☞ 开源架构XClouds专题|私有云之天猫精灵等平台对接Oauth2.0协议详解!

☞ esp32蓝牙配网高度封装,集成简单、使用简单,提高开发效率!

 重磅开源,微信小程序ble蓝牙配网乐鑫esp32,开源奉献物联网;

 重开源一款串口调试助手,支持MQTT/TCP/UDP一键配置;



部分图片摘取网络  侵删


浅谈AriKiss微信配网 | 开源一个可实现AriKiss配网的微信小程序

– End

原文始发于微信公众号(徐宏blog):浅谈AriKiss微信配网 | 开源一个可实现AriKiss配网的微信小程序

版权声明:admin 发表于 2021年11月26日 下午11:59。
转载请注明:浅谈AriKiss微信配网 | 开源一个可实现AriKiss配网的微信小程序 | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...