1. 程式人生 > >ZigBee 2007中繫結的理解

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;