2016-01-08 13 views
0

我正在使用基於32位ARM Cortex-M3的一個ZigBee模塊。但我的問題與ZigBee協議本身無關。我只能訪問應用層的源代碼,這對我的目的應該足夠了。下層(APS)通過APSDE-DATA指示內的數據應用層原語以下應用功能:分解具有特定結構的原始字節字符串會給出錯誤的數據

void zbpro_dataRcvdHandler(zbpro_dataInd_t *data) 
{ 
    DEBUG_PRINT(DBG_APP,"\n[APSDE-DATA.indication]\r\n"); 

    /* Output of raw bytes string for further investigation. 
    * Real length is unknown, 50 is approximation. 
    */ 
    DEBUG_PRINT(DBG_APP,"Raw data: \n"); 
    DEBUG_PRINT(DBG_APP,"----------\n"); 
    for (int i = 0; i < 50; i++){ 
     DEBUG_PRINT(DBG_APP,"%02x ",*((uint8_t*)data+i)); 
    } 
    DEBUG_PRINT(DBG_APP,"\n"); 

    /* Output of APSDE-DATA.indication primitive field by field */ 
    DEBUG_PRINT(DBG_APP,"Field by field: \n"); 
    DEBUG_PRINT(DBG_APP,"----------------\n"); 
    DEBUG_PRINT(DBG_APP,"Destination address: "); 
    for (int i = 0; i < 8; i++) 
     DEBUG_PRINT(DBG_APP,"%02x ",*((uint8_t*)data->dstAddress.ieeeAddr[i])); 
    DEBUG_PRINT(DBG_APP,"\n"); 
    DEBUG_PRINT(DBG_APP,"Destination address mode: 0x%02x\r\n",*((uint8_t*)data->dstAddrMode)); 
    DEBUG_PRINT(DBG_APP,"Destination endpoint: 0x%02x\r\n",*((uint8_t*)data->dstEndPoint)); 
    DEBUG_PRINT(DBG_APP,"Source address mode: 0x%02x\r\n",*((uint8_t*)data->dstAddrMode)); 
    DEBUG_PRINT(DBG_APP,"Source address: "); 
    for (int i = 0; i < 8; i++) 
     DEBUG_PRINT(DBG_APP,"%02x ",*((uint8_t*)data->srcAddress.ieeeAddr[i])); 
    DEBUG_PRINT(DBG_APP,"\n"); 
    DEBUG_PRINT(DBG_APP,"Source endpoint: 0x%02x\r\n",*((uint8_t*)data->srcEndPoint)); 
    DEBUG_PRINT(DBG_APP,"Profile Id: 0x%04x\r\n",*((uint16_t*)data->profileId)); 
    DEBUG_PRINT(DBG_APP,"Cluster Id: 0x%04x\r\n",*((uint16_t*)data->clusterId)); 
    DEBUG_PRINT(DBG_APP,"Message length: 0x%02x\r\n",*((uint8_t*)data->messageLength)); 
    DEBUG_PRINT(DBG_APP,"Flags: 0x%02x\r\n",*((uint8_t*)data->flags)); 
    DEBUG_PRINT(DBG_APP,"Security status: 0x%02x\r\n",*((uint8_t*)data->securityStatus)); 
    DEBUG_PRINT(DBG_APP,"Link quality: 0x%02x\r\n",*((uint8_t*)data->linkQuality)); 
    DEBUG_PRINT(DBG_APP,"Source MAC Address: 0x%04x\r\n",*((uint16_t*)data->messageLength));  
    DEBUG_PRINT(DBG_APP,"Message: "); 

    for (int i = 0; i < 13; i++){ 
     DEBUG_PRINT(DBG_APP,"%02x ",*((uint8_t*)data->messageContents+i)); 
    } 
    DEBUG_PRINT(DBG_APP,"\n"); 

    bufm_deallocateBuffer((uint8_t *)data, CORE_MEM); 
} 

APSDE-DATA指示原語是由以下結構來實現:

/** 
* @brief type definition for address (union of short address and extended address) 
*/ 
typedef union zbpro_address_tag { 
    uint16_t shortAddr; 
    uint8_t ieeeAddr[8]; 
} zbpro_address_t; 

/** 
* @brief apsde data indication structure 
*/ 
PACKED struct zbpro_dataInd_tag { 
    zbpro_address_t dstAddress; 
    uint8_t dstAddrMode; 
    uint8_t dstEndPoint; 
    uint8_t srcAddrMode; 
    zbpro_address_t srcAddress; 
    uint8_t srcEndPoint; 
    uint16_t profileId; 
    uint16_t clusterId; 
    uint8_t messageLength; 
    uint8_t flags; /* bit0: broadcast or not; bit1: need aps ack or not; bit2: nwk key used; bit3: aps link key used */ 
    uint8_t securityStatus; /* not-used, reserved for future */ 
    uint8_t linkQuality; 
    uint16_t src_mac_addr; 
    uint8_t messageContents[1]; 
}; 
typedef PACKED struct zbpro_dataInd_tag zbpro_dataInd_t; 

作爲結果我收到未來:

[APSDE-DATA.indication] 

Raw data: 
--------- 
00 00 00 72 4c 19 40 00 02 e8 03 c2 30 02 fe ff 83 0a 00 e8 05 c1 11 00 11 08 58 40 72 4c ae 53 4d 3f 63 9f d8 51 da ca 87 a9 0b b3 7b 04 68 ca 87 a9 

Field by field: 
--------------- 
Destination address: 00 00 00 28 fa 44 34 00 
Destination address mode: 0x12 
Destination endpoint: 0xc2 
Source address mode: 0x12 
Source address: 13 01 12 07 02 bd 02 00 
Source endpoint: 0xc2 
Profile Id: 0xc940 
Cluster Id: 0x90a0 
Message length: 0x00 
Flags: 0x00 
Security status: 0x04 
Link quality: 0x34 
Source MAC Address: 0x90a0 
Message: ae 53 4d 3f 63 9f d8 51 da ca 87 a9 0b 

從這個輸出,我可以看到,雖然原始字符串有一定的期望值,出動領域是完全不同的。這種行爲的原因是什麼以及如何解決這個問題?它與ARM架構或錯誤的類型轉型有某種關係嗎?

我無權訪問DEBUG_PRINT的實現,但我們可以假設它可以正常工作。

+0

'data-> dstAddrMode'(和你的結構中的所有其他東西)都是* not *地址。它實際上是一個'uint8_t'。將'uint8_t'投射到'uint8_t *'並沒有多大意義。 –

回答

2

沒有必要在你的DEBUG_PRINT陳述間接引用,例如

DEBUG_PRINT(DBG_APP,"%02x ",*((uint8_t*)data->dstAddress.ieeeAddr[i])); 

應該是簡單的

DEBUG_PRINT(DBG_APP,"%02x ", data->dstAddress.ieeeAddr[i]); 

等等等等...

1

考慮以下代碼:

DEBUG_PRINT(DBG_APP,"%02x ",*((uint8_t*)data->dstAddress.ieeeAddr[i])); 

數組下標以及直接和間接成員訪問具有比不鑄造更高的優先級,所以第三個參數是相當於

*((uint8_t*) (data->dstAddress.ieeeAddr[i])) 

但是data->dstAddress.ieeeAddr[i]不是指針,它是一個uint8_t。 C允許您通過強制轉換將其轉換爲指針,但結果不是指針的值,而是指針解釋的值。解除引用會導致未定義的行爲。

同樣適用於您的其他DEBUG_PRINT()調用。

相關問題