ZigBee 2007中繫結的理解
ZigBee中的繫結
ZigBee中的繫結與端點EndPoint息息相關,其實EndPoint就像是TCP/IP中的埠,每個埠對應於不同的應用層。由於採用一個位元組來表示EndPoint,可以具有0~255個端點,但是0端點被預留用於ZDO與ZigBee協議棧的其它層通訊,實現各個層的初始化和配置。端點255用於向所有端點廣播。此外,端點241到254也是保留端點,具有特殊用途,通常使用者不要使用這個範圍的端點。因此使用者可使用的端點為1~240,也就是可以有240個端點,即240個應用。
所有端點都是使用APS提供的服務,透過NWK和安全服務提供層與端點相連線,提供資料傳送服務,因此能夠失配各種相容的裝置。
typedef struct
{
byte endPoint; //端點號,也就是埠號
byte *task_id; //對應埠的任務ID號
SimpleDescriptionFormat_t *simpleDesc; //裝置的簡單描述,說明本端點可以提供哪些命令
afNetworkLatencyReq_t latencyReq; //列舉型別
} endPointDesc_t;
//裝置的簡單描述結構
typedef struct
{
byte EndPoint; //端點號
uint16 AppProfId; // Profile ID,是由ZigBee聯盟分配的,用於描述裝置的應用場景,比如家庭自動化或者是無線感測器網路,它定義了裝置之間資訊交換的規範後者說規約
uint16 AppDeviceId; // 裝置ID號
byte AppDevVer:4; // 裝置版本
byte Reserved:4; //AF_V1_SUPPORT uses for AppFlags:4. Reserved
byte AppNumInClusters; //輸入命令個數
cId_t *pAppInClusterList; //輸入命令列表
byte AppNumOutClusters; //輸出命令個數
cId_t *pAppOutClusterList; //輸出命令列表
} SimpleDescriptionFormat_t;
在SimpleSensorEB中簡單描述符為
const SimpleDescriptionFormat_t zb_SimpleDesc =
{
MY_ENDPOINT_ID, // Endpoint
MY_PROFILE_ID, // Profile ID
DEV_ID_SENSOR, // Device ID
DEVICE_VERSION_SENSOR, // Device Version
0, // Reserved
NUM_IN_CMD_SENSOR, // Number of Input Commands
(cId_t *) NULL, // Input Command List
NUM_OUT_CMD_SENSOR, // Number of Output Commands
(cId_t *) zb_OutCmdList // Output Command List只有一個輸出命令ID
};
其中在SAPI_Init(byte task_id)中對endPointDesc_t結構賦值如下:
sapi_epDesc.task_id = &sapi_TaskID;//任務號
sapi_epDesc.endPoint = zb_SimpleDesc.EndPoint;//端點號
sapi_epDesc.latencyReq = noLatencyReqs;//無延遲
由於在本例子中只有一個應用,即採集溫度,因此只需要一個端點描述符。假如有多個應用則需要多個端點描述符,同時佔用三個端點號,在不同應用中傳送資料時採用不同的端點描述符。
比如在本例中傳送資料的語句為
status = AF_DataRequest(&dstAddr, &sapi_epDesc, commandId, len,
pData, &handle, txOptions, radius);
該語句利用AF層的AF_Datarequest函式來發送資料,需要傳入的引數包括目標地址,端點描述符,命令ID,長度,實際資料指標,處理方式(比如需不需要確認),傳送選項,半徑。
假如描述符匹配成功,則
case Match_Desc_rsp:
{
zAddrType_t dstAddr;
ZDO_ActiveEndpointRsp_t *pRsp = ZDO_ParseEPListRsp( inMsg );
if ( sapi_bindInProgress != 0xffff )
{
// Create a binding table entry
dstAddr.addrMode = Addr16Bit;
dstAddr.addr.shortAddr = pRsp->nwkAddr;
if ( APSME_BindRequest( sapi_epDesc.simpleDesc->EndPoint,
sapi_bindInProgress, &dstAddr, pRsp->epList[0] ) == ZSuccess )
{
osal_stop_timerEx(sapi_TaskID, ZB_BIND_TIMER);
osal_start_timerEx( ZDAppTaskID, ZDO_NWK_UPDATE_NV, 250 );
// Find IEEE addr
ZDP_IEEEAddrReq( pRsp->nwkAddr, ZDP_ADDR_REQTYPE_SINGLE, 0, 0 );
#if defined ( MT_SAPI_CB_FUNC )
zb_MTCallbackBindConfirm( sapi_bindInProgress, ZB_SUCCESS );
#endif
// Send bind confirm callback to application
#if ( SAPI_CB_FUNC )
zb_BindConfirm( sapi_bindInProgress, ZB_SUCCESS );
#endif
sapi_bindInProgress = 0xffff;
}
}
}
break;