创建TASK,用于sniffer配网
//创建TASK,用于sniffer配网
void jd_innet_start_task(void)
{
xTaskCreate(jd_innet_start, "jd_innet_start", 1024*3, NULL, tskIDLE_PRIORITY + 2, NULL);
}
开启sniffer模式,进行一些配网模式的初始化等,执行到回调函数中接收802.11包
static void jd_innet_start (void *pvParameters)
{
unsigned char* pBuffer = NULL;
joylink_smnt_param_t param;
esp_wifi_set_promiscuous(0);
pBuffer = (unsigned char*)malloc(1024);
if (pBuffer == NULL) {
log_debug("%s,%d\r\n",__func__,__LINE__);
vTaskDelete(NULL);
}
memset(¶m,0x0,sizeof(param));
memcpy(param.secretkey,AES_KEY,sizeof(param.secretkey));
param.switch_channel_callback = esp_switch_channel_callback;
param.get_result_callback = esp_get_result_callback;
joylink_smnt_init(param);
#ifdef CONFIG_TARGET_PLATFORM_ESP8266
esp_wifi_set_promiscuous_data_len(32);
#endif
if (ESP_OK != esp_wifi_set_promiscuous_rx_cb(jd_innet_pack_callback)){
log_debug ("[%s] set_promiscuous fail\n\r",__func__);
}
if (ESP_OK != esp_wifi_set_promiscuous(1)){
log_debug ("[%s] open promiscuous fail\n\r",__func__);
}
if (jd_innet_timer_task_handle != NULL) {
jd_innet_timer_task_flag = true;
while(jd_innet_timer_task_flag) {
vTaskDelay(10);
}
}
xTaskCreate(jd_innet_timer_task, "jd_innet_timer_task", 2048, NULL, tskIDLE_PRIORITY + 5, &jd_innet_timer_task_handle);
vTaskDelete(NULL);
}
重要函数
esp_wifi_set_promiscuous(bool en);/开启/关闭混杂模式/
esp_err_tesp_wifi_set_promiscuous(bool en)
Enable the promiscuous mode.
Return
ESP_OK: succeed
ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init
Parameters
en: false - disable, true - enable
esp_wifi_set_promiscuous_data_len(32);
没有找到这个函数,猜测是设置混杂模式获取数据的长度为32.
esp_wifi_set_promiscuous_rx_cb(jd_innet_pack_callback)
esp_err_tesp_wifi_set_promiscuous_rx_cb(wifi_promiscuous_cb_tcb)
Register the RX callback function in the promiscuous mode.
Each time a packet is received, the registered callback function will be called.
Return
ESP_OK: succeed
ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init
Parameters
cb: callback
其中:
//特殊配网包格式
typedef struct{
smnt_status_t state;
uint16 syncFirst;
uint8 syncCount;
uint8 syncStepPoint;
uint8 syncFirst_downlink;
uint8 syncCount_downlink;
uint8 syncStepPoint_downlink;
uint8 directTimerSkip;
uint8 broadcastVersion;
uint8 muticastVersion;
uint8 broadIndex;
uint8 broadBuffer[5];
uint16 lastLength;
uint16 lastUploadSeq;
uint16 lastDownSeq;
uint8 syncAppMac[6];
uint8 syncBssid[6];
uint16 syncIsUplink;
uint8 chCurrentIndex;
uint8 chCurrentProbability;
uint8 isProbeReceived;
uint8 payload_multicast[128];
uint8 payload_broadcast[128];
smnt_encrypt_data_t result;
}joylinkSmnt_t;
//配网的状态
typedef enum{
SMART_CH_INIT = 0x1,
SMART_CH_LOCKING = 0x2,
SMART_CH_LOCKED = 0x4,
SMART_FINISH = 0x8
}smnt_status_t;
//加密数据
typedef struct{
unsigned char type; // 0:NotReady, 1:ControlPacketOK, 2:BroadcastOK, 3:MulticastOK
unsigned char encData[1+32+32+32]; // length + EncodeData
}smnt_encrypt_data_t;
接着执行到回调函数 包都到这里来
/*recv packet callback*/
static void jd_innet_pack_callback(void *buf, wifi_promiscuous_pkt_type_t type)
{
wifi_promiscuous_pkt_t *pack_all = NULL;
int len=0;
PHEADER_802_11 frame = NULL;
if (type != WIFI_PKT_MISC) {
pack_all = (wifi_promiscuous_pkt_t *)buf;
frame = (PHEADER_802_11)pack_all->payload;
#ifdef CONFIG_TARGET_PLATFORM_ESP8266
len = pack_all->rx_ctrl.sig_mode ? pack_all->rx_ctrl.HT_length : pack_all->rx_ctrl.legacy_length;
#else
len = pack_all->rx_ctrl.sig_len;
#endif
joylink_smnt_datahandler(frame, len);
}
}
以下是802.11的帧类型
//wifi帧格式
typedef enum {
WIFI_PKT_MGMT, /**< Management frame, indicates 'buf' argument is wifi_promiscuous_pkt_t */
WIFI_PKT_CTRL, /**< Control frame, indicates 'buf' argument is wifi_promiscuous_pkt_t */
WIFI_PKT_DATA, /**< Data frame, indiciates 'buf' argument is wifi_promiscuous_pkt_t */
WIFI_PKT_MISC, /**< Other type, such as MIMO etc. 'buf' argument is wifi_promiscuous_pkt_t but the payload is zero length. */
} wifi_promiscuous_pkt_type_t;
接下来进行解包,支持组播方式和广播方式
void joylink_smnt_datahandler(PHEADER_802_11 pHeader, int length)
{
uint8 isUplink = 1;
uint8 packetType = 0; // 1-multicast packets 2-broadcast packets 0-thers
uint8 isDifferentAddr = 0;
uint8 *pDest, *pSrc, *pBssid;
uint16 lastLength = 0;
uint16 lastSeq_uplink = 0,lastSeq_downlink = 0;
static uint8 past_channel = 0xFF;
if (pSmnt == NULL)
return;
if ((length > 100) && (pSmnt->state != SMART_CH_LOCKED))
return;
if (pHeader->FC.ToDs){
isUplink = 1;
pBssid = pHeader->Addr1;
pSrc = pHeader->Addr2;
pDest = pHeader->Addr3;
if (!((memcmp(pDest, "\xFF\xFF\xFF\xFF\xFF\xFF", 6) == 0) || (memcmp(pDest, "\x01\x00\x5E", 3) == 0))){
return;
}
lastSeq_uplink = pSmnt->lastUploadSeq;
pSmnt->lastUploadSeq = pHeader->Sequence;
}else{
pDest = pHeader->Addr1;
pBssid = pHeader->Addr2;
pSrc = pHeader->Addr3;
isUplink = 0;
//not broadcast nor multicast package ,return
if (!((memcmp(pDest, "\xFF\xFF\xFF\xFF\xFF\xFF", 6) == 0) || (memcmp(pDest, "\x01\x00\x5E", 3) == 0))){
return;
}
lastSeq_downlink = pSmnt->lastDownSeq;
pSmnt->lastDownSeq = pHeader->Sequence;
}
lastLength = pSmnt->lastLength;
pSmnt->lastLength = length;
if (memcmp(pDest, "\xFF\xFF\xFF\xFF\xFF\xFF", 6) == 0)
{
if (pSmnt->state == SMART_CH_LOCKING)
{
if(isUplink == 1)
printf("uplink:(%02x-%04d)->length:%2x, =length-synfirst:(0x%02x),synfirst:%2x\n", *((uint8*)pHeader) & 0xFF, pHeader->Sequence, length, (uint8)(length - pSmnt->syncFirst +1),pSmnt->syncFirst);
else
printf("downlink:(%02x-%04d)->length:%2x, =length-synfirst:(0x%02x),synfirst:%2x\n", *((uint8*)pHeader) & 0xFF, pHeader->Sequence, length, (uint8)(length - pSmnt->syncFirst_downlink +1),pSmnt->syncFirst_downlink);
}
packetType = 2;
}
else if (memcmp(pDest, "\x01\x00\x5E", 3) == 0)
{
if (pSmnt->state == SMART_CH_LOCKING)
printf("(%02x-%04d):%02x:%02x:%02x->%d\n", *((uint8*)pHeader) & 0xFF, pHeader->Sequence, pDest[3], pDest[4], pDest[5], (uint8)length);
packetType = 1;
}
if (memcmp(pSrc, pSmnt->syncAppMac, 6) != 0)
{
isDifferentAddr = 1;
}
if(pSmnt->state == SMART_CH_LOCKING)
{
if (packetType == 0) return;
if ((isUplink==1) && (pHeader->Sequence == lastSeq_uplink)) return;
if ((isUplink==0) && (pHeader->Sequence == lastSeq_downlink)) return;
if(!isDifferentAddr)
{
if (packetType != 0)
{
if (packetType == 1)
{
if (((pDest[3] >> 6) == ((pDest[4] ^ pDest[5]) & 0x1)) && (pDest[3] != 0) && ((pDest[3]&0x3F) <= PAYLOAD_MAX))
{
/*if receive multicast right message for two times,lock the channel*/
if(past_channel == pSmnt->chCurrentIndex + 1)
{
past_channel = 0xFF;
if (pSmnt->chCurrentProbability < 20)
pSmnt->chCurrentProbability = 10;
memcpy(pSmnt->syncBssid, pBssid, 6);
pSmnt->state = SMART_CH_LOCKED;
}
else
{
past_channel = pSmnt->chCurrentIndex + 1;
}
}
joylink_smnt_muticastadd(pDest); // Internal state machine could delay the ch switching
return;
}
if(isUplink == 1)
{
if (lastLength == length) return;
int expectLength = 1 + pSmnt->syncFirst + pSmnt->syncCount%4 - (pSmnt->syncStepPoint?4:0);
int isStep = (pSmnt->syncStepPoint == 0 && length == (expectLength - 4));
if ( ( length == expectLength ) || isStep)
{
pSmnt->syncCount++;
pSmnt->chCurrentProbability++;
if (isStep) pSmnt->syncStepPoint = pSmnt->syncCount;
if (pSmnt->syncCount >= 3) // Achive SYNC count!
//if (pSmnt->syncCount >= 4) // Achive SYNC count!
{
pSmnt->syncFirst = pSmnt->syncFirst + pSmnt->syncStepPoint - (pSmnt->syncStepPoint ? 4 : 0); // Save sync world
memcpy(pSmnt->syncBssid, pBssid, 6);
pSmnt->state = SMART_CH_LOCKED;
printf("SYNC:(%02X%02X%02X%02X%02X%02X-%02X%02X%02X%02X%02X%02X)------->:CH=%d, WD=%d\n",
pSrc[0], pSrc[1], pSrc[2], pSrc[3], pSrc[4], pSrc[5],
pBssid[0], pBssid[1], pBssid[2], pBssid[3], pBssid[4], pBssid[5],
pSmnt->chCurrentIndex+1, pSmnt->syncFirst);
pSmnt->syncIsUplink = isUplink;
if(pSmnt->chCurrentProbability < 20)
pSmnt->chCurrentProbability = 20;
printf("--->locked by uplink\n");
}
return;
}
if (pSmnt->syncCount)
{
pSmnt->syncStepPoint = 0;
pSmnt->syncCount = 0;
memcpy(pSmnt->syncAppMac, pSrc, 6);
pSmnt->syncFirst = length;
printf("SYNC LOST\n");
}
}
else
{
if (lastLength == length) return;
int expectLength = 1 + pSmnt->syncFirst_downlink+ pSmnt->syncCount_downlink%4 - (pSmnt->syncStepPoint_downlink?4:0);
int isStep = (pSmnt->syncStepPoint_downlink == 0 && length == (expectLength - 4));
if ( ( length == expectLength ) || isStep)
{
pSmnt->syncCount_downlink++;
pSmnt->chCurrentProbability++;
if (isStep) pSmnt->syncStepPoint_downlink = pSmnt->syncCount_downlink;
if (pSmnt->syncCount_downlink>= 3) // Achive SYNC count!
//if (pSmnt->syncCount_downlink>= 4) // Achive SYNC count!
{
pSmnt->syncFirst_downlink = pSmnt->syncFirst_downlink + pSmnt->syncStepPoint_downlink - (pSmnt->syncStepPoint_downlink? 4 : 0); // Save sync world
memcpy(pSmnt->syncBssid, pBssid, 6);
pSmnt->state = SMART_CH_LOCKED;
printf("SYNC:(%02X%02X%02X%02X%02X%02X-%02X%02X%02X%02X%02X%02X)------->:CH=%d, WD=%d\n",
pSrc[0], pSrc[1], pSrc[2], pSrc[3], pSrc[4], pSrc[5],
pBssid[0], pBssid[1], pBssid[2], pBssid[3], pBssid[4], pBssid[5],
pSmnt->chCurrentIndex+1, pSmnt->syncFirst_downlink);
pSmnt->syncIsUplink = isUplink;
if(pSmnt->chCurrentProbability < 20)
pSmnt->chCurrentProbability = 20;
printf("--->locked by downlink\n");
}
return;
}
pSmnt->syncStepPoint_downlink = 0;
pSmnt->syncCount_downlink = 0;
memcpy(pSmnt->syncAppMac, pSrc, 6);
pSmnt->syncFirst_downlink = length;
printf("SYNC LOST\n");
}
}
return;
}
memcpy(pSmnt->syncAppMac, pSrc, 6);
pSmnt->syncFirst = length;
pSmnt->syncFirst_downlink = length;
printf("Try to SYNC!\n");
return;
}
else if (pSmnt->state == SMART_CH_LOCKED)
{
if (isDifferentAddr) return;
if (packetType == 1){
joylink_smnt_muticastadd(pDest);
return;
}
if ( (packetType != 1)&&(memcmp(pDest, pSmnt->syncBssid, 6) != 0) ){
packetType = 2;
}
if(isUplink == 1)
{
if (length < (pSmnt->syncFirst - 1)) return;
if ( pHeader->Sequence == lastSeq_uplink) return;
}
else
{
if (length < (pSmnt->syncFirst_downlink - 1)) return;
if ( pHeader->Sequence == lastSeq_downlink) return;
}
if (packetType == 2)
{
int ascii;
if(isUplink == 1)
ascii = length - pSmnt->syncFirst + 1;
else
ascii = length - pSmnt->syncFirst_downlink + 1;
if((((ascii >> 8) & 0x01) == 1) && (((ascii >> 3)&0x1F) == 0))
{
;
}
else
{
joylink_smnt_broadcastadd(ascii);
}
if (((length + 4 - lastLength) % 4 == 1)&& (length - pSmnt->syncFirst)<4) // There are SYNC packets even ch locked.
{
if (pSmnt->chCurrentProbability < 20) pSmnt->chCurrentProbability++;
}
}
}
else if (pSmnt->state == SMART_FINISH)
{
printf("SMART_FINISH-1\n");
}
else
{
pSmnt->state = SMART_CH_LOCKING;
memcpy(pSmnt->syncAppMac, pSrc, 6);
pSmnt->syncFirst = length;
pSmnt->syncStepPoint = 0;
pSmnt->syncCount = 0;
printf("Reset All State\n");
}
return;
}
广播包标志:\xFF\xFF\xFF\xFF\xFF\xFF
组播包标志:\x01\x00\x5E
由调试结果可知,通过切换信道来锁定配网包的信道,循环接收包进行补全数据。
得到配网所需的SSID和PASSWORD
本示例说明:下面是调试LOG
downlink:(40-2111)->length:38, =length-synfirst:(0x01),synfirst:38
downlink:(40-0033)->length:38, =length-synfirst:(0x01),synfirst:38
downlink:(40-1855)->length:39, =length-synfirst:(0x02),synfirst:38
------------------->SYNC (CH:13) 0
uplink:(88-3624)->length:53, =length-synfirst:(0x1c),synfirst:38
Try to SYNC!
uplink:(88-3626)->length:54, =length-synfirst:(0x02),synfirst:53
------------------->SYNC (CH:1) 0
downlink:(80-0747)->length:60, =length-synfirst:(0x0e),synfirst:53
Try to SYNC!
uplink:(88-3628)->length:56, =length-synfirst:(0xf7),synfirst:60
Try to SYNC!
downlink:(40-3137)->length:39, =length-synfirst:(0xe4),synfirst:56
Try to SYNC!
downlink:(40-1362)->length:38, =length-synfirst:(0x00),synfirst:39
SYNC LOST
downlink:(80-0435)->length:60, =length-synfirst:(0x29),synfirst:38
Try to SYNC!
downlink:(40-0036)->length:38, =length-synfirst:(0xd9),synfirst:60
Try to SYNC!
downlink:(40-4030)->length:57, =length-synfirst:(0x20),synfirst:38
SYNC LOST
uplink:(88-3695)->length:53, =length-synfirst:(0x1c),synfirst:38
Try to SYNC!
uplink:(88-3696)->length:54, =length-synfirst:(0x02),synfirst:53
uplink:(88-3698)->length:55, =length-synfirst:(0x03),synfirst:53
uplink:(88-3699)->length:56, =length-synfirst:(0x04),synfirst:53
SYNC:(1C151F6A4281-BC5FF61B9FDD)------->:CH=1, WD=83
--->locked by uplink
------------------->SYNC (CH:1) 19
------------------->SYNC (CH:1) 18
M01(CH=1)--41:(5B,20)
------------------->SYNC (CH:1) 22
Version RX:2
M02(CH=1)--02:(9E,66)
------------------->SYNC (CH:1) 21
M03(CH=1)--43:(84,9D)
------------------->SYNC (CH:1) 20
------------------->SYNC (CH:1) 19
B(2=17)--9d,3d,48,7b
------------------->SYNC (CH:1) 22
M05(CH=1)--45:(F2,7B)
------------------->SYNC (CH:1) 21
------------------->SYNC (CH:1) 22
M06(CH=1)--06:(B8,0A)
------------------->SYNC (CH:1) 21
------------------->SYNC (CH:1) 20
------------------->SYNC (CH:1) 21
------------------->SYNC (CH:1) 20
M07(CH=1)--47:(C1,9E)
M07(CH=1)--47:(C1,9E)
------------------->SYNC (CH:1) 19
------------------->SYNC (CH:1) 18
M08(CH=1)--08:(17,BD)
------------------->SYNC (CH:1) 24
------------------->SYNC (CH:1) 23
B(2=17)--84,9d,3d,48
M10(CH=1)--4A:(4E,E3)
------------------->SYNC (CH:1) 26
------------------->SYNC (CH:1) 25
M11(CH=1)--4B:(78,9D)
------------------->SYNC (CH:1) 26
------------------->SYNC (CH:1) 25
M12(CH=1)--4C:(2C,F3)
------------------->SYNC (CH:1) 26
------------------->SYNC (CH:1) 25
------------------->SYNC (CH:1) 26
------------------->SYNC (CH:1) 25
M14(CH=1)--0E:(D3,E3)
M14(CH=1)--0E:(D3,E3)
------------------->SYNC (CH:1) 26
------------------->SYNC (CH:1) 25
M15(CH=1)--0F:(E1,55)
------------------->SYNC (CH:1) 26
------------------->SYNC (CH:1) 27
------------------->SYNC (CH:1) 26
------------------->SYNC (CH:1) 25
M17(CH=1)--51:(80,53)
------------------->SYNC (CH:1) 24
------------------->SYNC (CH:1) 25
------------------->SYNC (CH:1) 24
------------------->SYNC (CH:1) 23
------------------->SYNC (CH:1) 22
B(8=40)--e1,55,e0,d8
------------------->SYNC (CH:1) 25
B(9=4e)--80,25,25,00
------------------->SYNC (CH:1) 28
------------------->SYNC (CH:1) 27
------------------->SYNC (CH:1) 26
------------------->SYNC (CH:1) 25
------------------->SYNC (CH:1) 24
M02(CH=1)--02:(9E,66)
M02(CH=1)--02:(9E,66)
------------------->SYNC (CH:1) 23
B(4=27)--c1,9e,17,52
------------------->SYNC (CH:1) 26
------------------->SYNC (CH:1) 25
B(4=27)--b6,e3,00,9d
------------------->SYNC (CH:1) 28
M04(CH=1)--44:(3D,48)
------------------->SYNC (CH:1) 27
------------------->SYNC (CH:1) 28
M05(CH=1)--45:(F2,7B)
------------------->SYNC (CH:1) 27
M06(CH=1)--06:(B8,0A)
------------------->SYNC (CH:1) 28
------------------->SYNC (CH:1) 27
M07(CH=1)--47:(C1,9E)
------------------->SYNC (CH:1) 26
------------------->SYNC (CH:1) 25
M08(CH=1)--08:(17,BD)
------------------->SYNC (CH:1) 26
------------------->SYNC (CH:1) 25
------------------->SYNC (CH:1) 24
M09(CH=1)--09:(52,B6)
------------------->SYNC (CH:1) 23
------------------->SYNC (CH:1) 24
------------------->SYNC (CH:1) 23
------------------->SYNC (CH:1) 22
------------------->SYNC (CH:1) 21
------------------->SYNC (CH:1) 20
M11(CH=1)--4B:(78,9D)
------------------->SYNC (CH:1) 19
------------------->SYNC (CH:1) 20
------------------->SYNC (CH:1) 19
M13(CH=1)--4D:(FB,0C)
------------------->SYNC (CH:1) 25
------------------->SYNC (CH:1) 24
M14(CH=1)--0E:(D3,E3)
------------------->SYNC (CH:1) 23
M15(CH=1)--0F:(E1,55)
------------------->SYNC (CH:1) 22
------------------->SYNC (CH:1) 21
------------------->SYNC (CH:1) 20
------------------->SYNC (CH:1) 21
------------------->SYNC (CH:1) 20
------------------->SYNC (CH:1) 21
------------------->SYNC (CH:1) 22
------------------->SYNC (CH:1) 21
M01(CH=1)--41:(5B,20)
------------------->SYNC (CH:1) 22
------------------->SYNC (CH:1) 21
------------------->SYNC (CH:1) 22
------------------->SYNC (CH:1) 23
------------------->SYNC (CH:1) 22
------------------->SYNC (CH:1) 21
M06(CH=1)--06:(B8,0A)
------------------->SYNC (CH:1) 24
M07(CH=1)--47:(C1,9E)
------------------->SYNC (CH:1) 25
M08(CH=1)--08:(17,BD)
------------------->SYNC (CH:1) 26
M09(CH=1)--09:(52,B6)
------------------->SYNC (CH:1) 25
M10(CH=1)--4A:(4E,E3)
------------------->SYNC (CH:1) 26
M11(CH=1)--4B:(78,9D)
------------------->SYNC (CH:1) 27
M12(CH=1)--4C:(2C,F3)
------------------->SYNC (CH:1) 26
------------------->SYNC (CH:1) 25
------------------->SYNC (CH:1) 24
------------------->SYNC (CH:1) 25
M14(CH=1)--0E:(D3,E3)
------------------->SYNC (CH:1) 24
------------------->SYNC (CH:1) 23
------------------->SYNC (CH:1) 24
M16(CH=1)--10:(E0,D8)
Len=32:20,9e,66,84,9d,3d,48,f2,7b,b8,0a,c1,9e,17,bd,52,b6,4e,e3,78,9d,2c,f3,fb,0c,d3,e3,e1,55,e0,d8,80,
[DEBUG][/home/songjiaxiu/esp/esp-joylink/port/jdinnet/jd_innet.c][esp_get_result_callback][95]
ssid:mercury_song
[DEBUG][/home/songjiaxiu/esp/esp-joylink/port/jdinnet/jd_innet.c][esp_get_result_callback][96]
password:1234567890