Código abierto | escena del hogar inteligente, subprograma WeChat basado en la red de distribución AriKiss

Por casualidad, un desarrollador del grupo me preguntó por qué había un problema con su red de distribución WeChat, respondí algunas preguntas y descubrí que no era tan simple, así que ayudé a este amigo a adaptarlo y lo logró . El primer subprograma WeChat de código abierto en toda la red que puede realizar la red de distribución de Airkiss.

25e301a512c7210233c45e3cc452249a.png

Consulte la parte inferior del artículo para ver el código fuente .

1

Desentraña el misterio de la red de distribución WeChat

Aunque la red de distribución AirKiss WeChat es una tecnología inaugurada en 2016, siempre ha sido un tema que vale la pena estudiar en el campo de la red de distribución doméstica inteligente. Debido a que los productos Wi-Fi se usan demasiado en el mundo real , todos todavía están muy preocupados por este problema hoy. Hoy usaré el módulo Anxinke ESP-C3-12F para depurar y brindarles un análisis completo de cómo me di cuenta de esto. el acuerdo del subprograma WeChat.

En primer lugar, resuelvamos algunas preguntas, que también son las preguntas en las que pensé antes del trasplante:

1. ¿Cómo funciona Airkiss? ¿protocolo? ¿Proceso de distribución de red?

2. ¿Cómo puedo obtener el código fuente de airkiss? ¿Puedo obtener una comparación de protocolos desde el lado del dispositivo y desde el front-end?

3. ¿Cómo optimizaste las desventajas de la distribución con una sola clave? ¿Por qué algunos enrutadores no pueden configurar la red?

4. ¿El subprograma WeChat admite redes locales? ¿Cómo llamar a métodos de funciones relacionadas?

Comprenda el protocolo AirKiss:

AirKiss es la tecnología de red de distribución WeChat, descubrimiento de LAN y comunicación LAN proporcionada por la plataforma de hardware WeChat para dispositivos Wi-Fi. Si el desarrollador desea configurar la red del dispositivo Wi-Fi a través del cliente WeChat, descubra el dispositivo Wi-Fi en la LAN a través del cliente WeChat o envíe música, imágenes, archivos y otros mensajes en el cliente WeChat al cliente Wi-Fi. Dispositivo Fi a través de la LAN. El dispositivo necesita integrar la biblioteca estática AirKiss correspondiente en el dispositivo de hardware.

14de6619eb0555b485a0bcfcea35c5e2.png

Pasos para la red de distribución de AirKiss:

1. El módulo Anxinke ESP-C3-12F enciende el modo de estación y toma los paquetes UDP mezclados en el aire;

2. El cliente WeChat móvil envía el ssid y la contraseña del enrutador doméstico a través de AirKiss;

3. El módulo Anxinke ESP-C3-12F obtiene el ssid y la contraseña mediante captura de paquetes y luego se conecta al enrutador de casa;

4. El módulo LAN Anxinke ESP-C3-12F envía un paquete UDP al cliente móvil para indicar que la distribución de la red fue exitosa;

El principio básico de la red de distribución de AirKiss:

1. Modo promiscuo

El módulo Anxinke ESP-C3-12F también funciona en modo Estación al principio, pero también hay un modo de monitoreo, al que también llamamos sonda de rastreo. ¿Que significa? Significa que un dispositivo wifi normal tiene una dirección MAC y su circuito de hardware filtrará automáticamente los paquetes cuya dirección MAC de destino sea diferente de su MAC. Habilitar el modo promiscuo es lo que normalmente llamamos captura de paquetes, es decir, se reciben todos los paquetes de datos que cumplen con el formato 802.11 en el aire, independientemente de si la MAC es la misma. Obviamente, la aplicación de configuración inteligente del teléfono móvil no conoce la dirección MAC del dispositivo wifi, por lo que cuando los paquetes de datos enviados por el wifi del teléfono móvil se reenvían a través del enrutador doméstico, el dispositivo wifi debe estar en modo promiscuo para recibir estos paquetes de datos. .

2. Cambio de canal

802.11 tiene múltiples canales y, en un momento determinado, tanto el dispositivo wifi como el enrutador están en un canal determinado. Los enrutadores generalmente están en el sexto canal por defecto, por lo que si quieres tener una mejor señal de red en casa, puedes intentar cambiar el canal del enrutador a otro canal, para que no se superponga con el canal wifi del vecino. casa. Las señales de Wi-Fi interferirán entre sí si se mezclan en el mismo canal.

De la misma manera, no podemos asumir en qué canal está el dispositivo wifi, pero podemos determinar el canal de envío del wifi del teléfono móvil en la aplicación, lo que requiere que el dispositivo wifi cambie de canal en un momento determinado para poder recibir. paquetes de datos. Cuando el dispositivo wifi detecta un paquete de datos válido, debe bloquearse en el canal para su posterior comunicación.

3. Utilice la longitud del marco de datos para transportar información válida.

Echemos un vistazo al formato de trama de datos de 802.2 SNAP (el protocolo de capa física de 802.11)

81bdffeb2fe5c4541be24b517dc49b1e.png

El campo DA representa la dirección mac de destino, el campo SA representa la dirección mac de origen, el campo Longitud representa la longitud de los siguientes datos, el campo LLC representa el encabezado LLC, el campo SNAP incluye 3 bytes de código del fabricante y 2 bytes de identificación del tipo de protocolo, y el campo DATOS es la carga útil. Para canales cifrados Para texto cifrado, el campo FCS representa la secuencia de verificación de trama.

Desde la perspectiva del oyente de la señal inalámbrica, no importa si el canal inalámbrico está cifrado o no, los campos DA, SA, Longitud, LLC, SNAP y FCS siempre están expuestos, por lo que es conveniente para el monitoreo de la señal obtener información de estos. 6 campos. Pero desde la perspectiva del remitente, debido a las limitaciones del sistema operativo (como Android o IOS), el control de los cinco campos de DA, SA, LLC, SNAP y FCS requiere una alta autoridad de control, y generalmente es difícil de obtener para el remitente. Por lo tanto, solo queda el campo Longitud y el remitente puede controlarlo cómodamente cambiando la longitud del paquete de datos que necesita enviar.

Por lo tanto, siempre que se desarrolle un conjunto de protocolos de comunicación que utilicen codificación de longitud, el campo Longitud en el paquete de datos SNAP 802.2 se puede utilizar para la transmisión de información.

En aplicaciones prácticas, utilizamos paquetes de difusión UDP como portador de información. La dirección de envío de información envía una serie de paquetes de transmisión UDP en el espacio, y la longitud de cada paquete (es decir, el campo Longitud) se codifica de acuerdo con el protocolo de comunicación AirKiss. ​​La capa intercepta el paquete de datos en formato SNAP 802.2 y luego Se puede obtener el campo Longitud codificado y luego la información requerida se puede analizar de acuerdo con el protocolo de comunicación AirKiss para facilitar la recepción.

26de9ece85d3a4e48a7601c0d13a3a41.png

2

Análisis del código fuente de AirKiss del módulo ESP-C3-12F

Anxinke ESP-C3-12F es un módulo WiFi + Bluetooth basado en el chip Espressif ESP32C3. Para parámetros y especificaciones específicos, visite el sitio web oficial de Anxinke. El siguiente es un breve análisis de cada paso clave de la fuente de la red de distribución de AirKiss. código.

Active el modo de rastreo, capture los paquetes 802.11 en el aire y envíelos a la biblioteca estática de WeChat para decodificarlos.

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

Analice con éxito la contraseña de la cuenta del enrutador y comience a conectarse al enrutador.

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

Envíe un acuse de recibo al teléfono móvil a través del protocolo UDP para notificar el éxito de la red de distribución, y los datos son una matriz con una longitud de 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

Análisis del código fuente de AirKiss del pequeño programa

Primero escriba las reglas del paquete correspondientes, el paquete PrefixCode y 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]);
  }
}

Antes de enviar el paquete, también es necesario habilitar el monitoreo UDP y esperar el mensaje de confirmación de la configuración exitosa del dispositivo.

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

Comience a enviar paquetes, tenga en cuenta que la dirección es 255.255.255.255, lo que significa todo el segmento de red:

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

4

Cómo integrarlo en mi proyecto

Teniendo en cuenta la conveniencia de la integración para los desarrolladores, lo empaqueté en un pequeño complemento de programa y lo puse en los estantes. Todos pueden comenzar e integrarlo en sus propios proyectos.

Para registrar un miniprograma WeChat usted mismo, descargue la última versión de WeChat Developer Tools.

Después de crear un nuevo proyecto, abra  app.jsel archivo y agregue el siguiente código:

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

Luego, se le preguntará si desea agregar un complemento; siga las instrucciones a continuación para agregar un complemento para usar.

69cf7f7fc60c6090ea1122954dd66302.png

El siguiente ejemplo ilustra cómo usarlo. Para obtener más habilidades y métodos de uso, consulte el código fuente de este subprograma. El código fuente se encuentra al final del artículo.

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

Mira aquí, espero que te guste.

Envíe "AirKiss" en segundo plano para obtener el código fuente del subprograma WeChat;

Recomendación pasada

1. ¿No es popular la "plataforma de Internet de las cosas" de los proveedores de la nube?

2. Comparación del rendimiento de las cuatro principales plataformas nacionales de IoT en 2021

3. Informe de investigación sobre el desarrollo de la industria nacional de MCU

4. Ranking de empresas de módulos de comunicación 4G en 2021

5. Investigación de la plataforma IoT de China de iResearch 2021

6. GIF|¿Le lleva a comprender el proceso de fabricación de placas PCB?

94c208090299c309f073db196fe9c65e.gif

Supongo que te gusta

Origin blog.csdn.net/klandor2008/article/details/121586512#comments_26377233
Recomendado
Clasificación