Open source | smart home scene, WeChat applet based on AriKiss distribution network

By chance, a developer in the group asked me why there was a problem with his WeChat distribution network. I responded to some questions and found that it was not that simple, so I helped this friend adapt it and it succeeded. I decided to The first open source WeChat applet in the whole network that can realize Airkiss distribution network.

25e301a512c7210233c45e3cc452249a.png

See the bottom of the article for the source code .

1

Unravel the mystery of WeChat distribution network

Although AirKiss WeChat distribution network is a technology opened in 2016, it has always been a topic worth studying in the field of smart home distribution network! Because Wi-Fi products are used too much in the actual world , everyone is still very concerned about this issue today. Today I will use the Anxinke ESP-C3-12F module to debug and give you a comprehensive analysis of how I realized this on the WeChat applet. agreement.

First of all, let's sort out a few questions, which are also the questions I thought about before transplanting:

1. How does airkiss work? protocol? Network distribution process?

2. How can I get the source code of airkiss? Can I get protocol comparison from the device side and the front end?

3. How did you optimize the disadvantages of one-key distribution? Why can't some routers configure the network?

4. Does the WeChat applet support local networking? How to call related function methods?

Understand the AirKiss protocol:

AirKiss is the technology of WeChat distribution network, LAN discovery and LAN communication provided by WeChat hardware platform for Wi-Fi devices. If the developer wants to configure the Wi-Fi device network through the WeChat client, discover the Wi-Fi device on the LAN through the WeChat client, or send the music, pictures, files and other messages in the WeChat client to the Wi-Fi device through the LAN The device needs to integrate the corresponding AirKiss static library in the hardware device.

14de6619eb0555b485a0bcfcea35c5e2.png

Steps for AirKiss distribution network:

1. Anxinke ESP-C3-12F module turns on the station mode, and grabs the mixed UDP packets in the air;

2. The mobile WeChat client sends the home router ssid and password through AirKiss;

3. The Anxinke ESP-C3-12F module obtains the ssid and password through packet capture, and then connects to the router at home;

4. Anxinke ESP-C3-12F module LAN sends a UDP packet to the mobile client to indicate that the network distribution is successful;

The basic principle of AirKiss distribution network:

1. Promiscuous mode

Anxinke ESP-C3-12F module also operates in Station mode at the beginning, but there is also a monitoring mode, which we also call a sniffing probe. What means? It means that a normal wifi device has a MAC address, and its hardware circuit will automatically filter packets whose target MAC address is different from its MAC. Enabling promiscuous mode is what we usually call packet capture, that is, all data packets conforming to the 802.11 format in the air are received, regardless of whether the MAC is the same. Obviously, the mobile phone smart configuration APP does not know the MAC address of the wifi device, so when the data packets sent by the mobile phone wifi are forwarded through the home router, the wifi device must be in promiscuous mode to receive these data packets.

2. Channel switching

802.11 has multiple channels, and at a certain time, both the wifi device and the router are on a certain channel. The router is generally on the sixth channel by default, so if you want to have a better network signal at home, you can try to change the channel of the router to another channel, so that it will not overlap with the wifi channel of the neighbor’s house. Wi-Fi signals will interfere with each other if they are mixed on the same channel.

In the same way, we can't assume which channel the wifi device is in, but we can determine the sending channel of the mobile phone's wifi in the app, which requires the wifi device to switch channels at a certain time in order to receive data packets. When the wifi device detects a valid data packet, it should be locked on the channel for subsequent communication.

3. Use the length of the data frame to carry valid information

Let's take a look at the data frame format of 802.2 SNAP (the physical layer protocol of 802.11)

81bdffeb2fe5c4541be24b517dc49b1e.png

The DA field represents the target mac address, the SA field represents the source mac address, the Length field represents the length of the following data, the LLC field represents the LLC header, the SNAP field includes 3 bytes of manufacturer code and 2 bytes of protocol type identification, and the DATA field is the payload. For encrypted channels For ciphertext, the FCS field represents the frame check sequence.

From the perspective of the wireless signal listener, no matter whether the wireless channel is encrypted or not, the DA, SA, Length, LLC, SNAP, and FCS fields are always exposed, so it is convenient for signal monitoring to obtain information from these 6 fields. But from the perspective of the sender, due to the limitations of the operating system (such as Android or IOS), the control of the five fields of DA, SA, LLC, SNAP, and FCS requires high control authority, and it is generally difficult for the sender to obtain of. Therefore, only the Length field is left, and the sender can control it conveniently by changing the length of the data packet it needs to send.

Therefore, as long as a set of communication protocols using length encoding is developed, the Length field in the 802.2 SNAP data packet can be used for information transmission.

In practical applications, we use UDP broadcast packets as the carrier of information. The information sending direction sends a series of UDP broadcast packets in the space, and the length of each packet (that is, the Length field) is encoded according to the AirKiss communication protocol. The layer intercepts the 802.2 SNAP format data packet, and then the encoded Length field can be obtained, and then the required information can be parsed out according to the AirKiss communication protocol for convenience of reception.

26de9ece85d3a4e48a7601c0d13a3a41.png

2

ESP-C3-12F module AirKiss source code analysis

Anxinke ESP-C3-12F is a WiFi+Bluetooth module based on the Espressif ESP32C3 chip. For specific parameters and specifications, please go to the official website of Anxinke. The following is a brief analysis of each key step of the AirKiss distribution network source code.

Turn on the sniffing mode, capture the 802.11 packets in the air, and send them to the WeChat static library for decoding.

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

Successfully parse out the router account password, and start to connect to the router.

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 !");
    }

Send an ack to the mobile phone through the UDP protocol to notify the success of the distribution network, and the data is an array with a length of 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, 7, 0,(struct sockaddr *) &server_addr, sin_size);

3e9c2c4bbeb88897c44017e404e93a13.png

3

Small program AirKiss source code analysis

First write the corresponding package rules, PrefixCode and Sequence package:

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

Before sending the package, it is also necessary to enable UDP monitoring and wait for the ack message of the successful configuration of the device.

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

Start sending packets, note that the address is 255.255.255.255, which means the entire network segment:

let sendData = new ArrayBuffer(mEncodedData[index]);
  wxUdp.send({
    address: "255.255.255.255",
    port: 10000,
    message: sendData
  });

4

How to integrate it into my project

Considering the convenience of integration for developers, I have packaged it into a small program plug-in and put it on the shelves. Everyone can get started and integrate it into their own projects.

To register a WeChat Mini Program by yourself, please download the latest version of WeChat Developer Tools.

After creating a new project, open  app.jsthe file and add the following code:

"plugins": {
    "airkiss": {
      "version": "1.1.0",
      "provider": "wx610ea582556c983e"
    }
  }

Then, there will be a prompt whether to add a plug-in, follow the prompts below to add a plug-in to use.

69cf7f7fc60c6090ea1122954dd66302.png

The following example illustrates how to use it. For more usage skills and methods, refer to the source code of this applet. The source code is at the bottom of the article.

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

See here, hope you will like it.

Send "AirKiss" in the background to obtain the source code of the WeChat applet;

Past recommendation

1. Is the "Internet of Things Platform" of cloud vendors not popular?

2. Performance comparison of the four major domestic IoT platforms in 2021

3. Domestic MCU Industry Development Research Report

4. Ranking of 4G Communication Module Enterprises in 2021

5. iResearch 2021 China IoT Platform Research

6. GIF|Take you to understand the PCB board manufacturing process?

94c208090299c309f073db196fe9c65e.gif

Guess you like

Origin blog.csdn.net/klandor2008/article/details/121586512#comments_26377233