esp-joylink解析(smartconfig过程)

创建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(&param,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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值