ZDProfile.c 61 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941
  1. /**************************************************************************************************
  2. Filename: ZDProfile.c
  3. Revised: $Date: 2010-10-13 10:54:13 -0700 (Wed, 13 Oct 2010) $
  4. Revision: $Revision: 24112 $
  5. Description: This is the Zigbee Device Profile.
  6. Copyright 2004-2010 Texas Instruments Incorporated. All rights reserved.
  7. IMPORTANT: Your use of this Software is limited to those specific rights
  8. granted under the terms of a software license agreement between the user
  9. who downloaded the software, his/her employer (which must be your employer)
  10. and Texas Instruments Incorporated (the "License"). You may not use this
  11. Software unless you agree to abide by the terms of the License. The License
  12. limits your use, and you acknowledge, that the Software may not be modified,
  13. copied or distributed unless embedded on a Texas Instruments microcontroller
  14. or used solely and exclusively in conjunction with a Texas Instruments radio
  15. frequency transceiver, which is integrated into your product. Other than for
  16. the foregoing purpose, you may not use, reproduce, copy, prepare derivative
  17. works of, modify, distribute, perform, display or sell this Software and/or
  18. its documentation for any purpose.
  19. YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
  20. PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
  21. INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
  22. NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
  23. TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
  24. NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
  25. LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
  26. INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
  27. OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
  28. OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
  29. (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
  30. Should you have any questions regarding your right to use this Software,
  31. contact Texas Instruments Incorporated at www.TI.com.
  32. **************************************************************************************************/
  33. /*********************************************************************
  34. * INCLUDES
  35. */
  36. #include "ZComdef.h"
  37. #include "OSAL.h"
  38. #include "AF.h"
  39. #include "NLMEDE.h"
  40. #include "nwk_util.h"
  41. #include "APS.h"
  42. #include "AddrMgr.h"
  43. #include "ZDConfig.h"
  44. #include "ZDProfile.h"
  45. #include "ZDObject.h"
  46. #include "ZDNwkMgr.h"
  47. #if defined( LCD_SUPPORTED )
  48. #include "OnBoard.h"
  49. #endif
  50. #include "nwk_util.h"
  51. #if defined( MT_ZDO_FUNC )
  52. #include "MT_ZDO.h"
  53. #endif
  54. /*********************************************************************
  55. * MACROS
  56. */
  57. #define ZADDR_TO_AFADDR( pZADDR, AFADDR ) { \
  58. (AFADDR).endPoint = ZDP_AF_ENDPOINT; \
  59. (AFADDR).addrMode = (afAddrMode_t)(pZADDR)->addrMode; \
  60. (AFADDR).addr.shortAddr = (pZADDR)->addr.shortAddr; \
  61. }
  62. #define FillAndSendBuffer( TRANSSEQ, ADDR, ID, LEN, BUF ) { \
  63. afStatus_t stat; \
  64. ZDP_TmpBuf = (BUF)+1; \
  65. stat = fillAndSend( (TRANSSEQ), (ADDR), (ID), (LEN) ); \
  66. osal_mem_free( (BUF) ); \
  67. ZDP_TmpBuf = ZDP_Buf+1; \
  68. return stat; \
  69. }
  70. #define FillAndSendTxOptions( TRANSSEQ, ADDR, ID, LEN, TxO ) { \
  71. afStatus_t stat; \
  72. ZDP_TxOptions = (TxO); \
  73. stat = fillAndSend( (TRANSSEQ), (ADDR), (ID), (LEN) ); \
  74. ZDP_TxOptions = AF_TX_OPTIONS_NONE; \
  75. return stat; \
  76. }
  77. #define FillAndSendBufferTxOptions( TRANSSEQ, ADDR, ID, LEN, BUF, TxO ) { \
  78. afStatus_t stat; \
  79. ZDP_TmpBuf = (BUF)+1; \
  80. ZDP_TxOptions = (TxO); \
  81. stat = fillAndSend( (TRANSSEQ), (ADDR), (ID), (LEN) ); \
  82. osal_mem_free( (BUF) ); \
  83. ZDP_TmpBuf = ZDP_Buf+1; \
  84. ZDP_TxOptions = AF_TX_OPTIONS_NONE; \
  85. return stat; \
  86. }
  87. /*********************************************************************
  88. * CONSTANTS
  89. */
  90. #define ZDP_BUF_SZ 80
  91. CONST byte ZDP_AF_ENDPOINT = 0;
  92. /*********************************************************************
  93. * TYPEDEFS
  94. */
  95. typedef struct
  96. {
  97. void *next;
  98. uint8 taskID;
  99. uint16 clusterID;
  100. } ZDO_MsgCB_t;
  101. /*********************************************************************
  102. * GLOBAL VARIABLES
  103. */
  104. byte ZDP_TransID = 0;
  105. /*********************************************************************
  106. * EXTERNAL VARIABLES
  107. */
  108. extern endPointDesc_t ZDApp_epDesc;
  109. /*********************************************************************
  110. * EXTERNAL FUNCTIONS
  111. */
  112. /*********************************************************************
  113. * LOCAL FUNCTIONS
  114. */
  115. static afStatus_t fillAndSend( uint8 *transSeq, zAddrType_t *addr, cId_t clusterID, byte len );
  116. uint8 ZDO_SendMsgCBs( zdoIncomingMsg_t *inMsg );
  117. void zdpProcessAddrReq( zdoIncomingMsg_t *inMsg );
  118. /*********************************************************************
  119. * LOCAL VARIABLES
  120. */
  121. static uint8 ZDP_Buf[ ZDP_BUF_SZ ];
  122. static uint8 *ZDP_TmpBuf = ZDP_Buf+1;
  123. byte ZDP_TxOptions = AF_TX_OPTIONS_NONE;
  124. ZDO_MsgCB_t *zdoMsgCBs = (ZDO_MsgCB_t *)NULL;
  125. /*********************************************************************
  126. * ZDO Message Processing table
  127. */
  128. typedef void (*pfnZDPMsgProcessor)( zdoIncomingMsg_t *inMsg );
  129. typedef struct
  130. {
  131. uint16 clusterID;
  132. pfnZDPMsgProcessor pFn;
  133. } zdpMsgProcItem_t;
  134. CONST zdpMsgProcItem_t zdpMsgProcs[] =
  135. {
  136. #if ( RFD_RCVC_ALWAYS_ON==TRUE ) || ( ZG_BUILD_RTR_TYPE )
  137. // These aren't processed by sleeping end devices.
  138. { NWK_addr_req, zdpProcessAddrReq },
  139. { Device_annce, ZDO_ProcessDeviceAnnce },
  140. #endif
  141. { IEEE_addr_req, zdpProcessAddrReq },
  142. { Node_Desc_req, ZDO_ProcessNodeDescReq },
  143. { Power_Desc_req, ZDO_ProcessPowerDescReq },
  144. { Simple_Desc_req, ZDO_ProcessSimpleDescReq },
  145. { Active_EP_req, ZDO_ProcessActiveEPReq },
  146. { Match_Desc_req, ZDO_ProcessMatchDescReq },
  147. #if defined ( ZDO_MGMT_NWKDISC_RESPONSE )
  148. { Mgmt_NWK_Disc_req, ZDO_ProcessMgmtNwkDiscReq },
  149. #endif
  150. #if defined ( ZDO_MGMT_LQI_RESPONSE ) && ( ZG_BUILD_RTR_TYPE )
  151. { Mgmt_Lqi_req, ZDO_ProcessMgmtLqiReq },
  152. #endif
  153. #if defined ( ZDO_MGMT_RTG_RESPONSE ) && ( ZG_BUILD_RTR_TYPE )
  154. { Mgmt_Rtg_req, ZDO_ProcessMgmtRtgReq },
  155. #endif
  156. #if defined ( ZDO_MGMT_BIND_RESPONSE ) && defined ( REFLECTOR )
  157. { Mgmt_Bind_req, ZDO_ProcessMgmtBindReq },
  158. #endif
  159. #if defined ( ZDO_MGMT_JOINDIRECT_RESPONSE ) && ( ZG_BUILD_RTR_TYPE )
  160. { Mgmt_Direct_Join_req, ZDO_ProcessMgmtDirectJoinReq },
  161. #endif
  162. #if defined ( ZDO_MGMT_LEAVE_RESPONSE )
  163. { Mgmt_Leave_req, ZDO_ProcessMgmtLeaveReq },
  164. #endif
  165. #if defined ( ZDO_MGMT_PERMIT_JOIN_RESPONSE ) && ( ZG_BUILD_RTR_TYPE )
  166. { Mgmt_Permit_Join_req, ZDO_ProcessMgmtPermitJoinReq },
  167. #endif
  168. #if defined ( ZDO_USERDESC_RESPONSE )
  169. { User_Desc_req, ZDO_ProcessUserDescReq },
  170. #endif
  171. #if defined ( ZDO_USERDESCSET_RESPONSE )
  172. { User_Desc_set, ZDO_ProcessUserDescSet },
  173. #endif
  174. #if defined ( ZDO_SERVERDISC_RESPONSE )
  175. { Server_Discovery_req, ZDO_ProcessServerDiscReq },
  176. #endif
  177. {0xFFFF, NULL} // Last
  178. };
  179. /*********************************************************************
  180. * @fn fillAndSend
  181. *
  182. * @brief Combined to reduce space
  183. *
  184. * @param
  185. * @param
  186. *
  187. * @return afStatus_t
  188. */
  189. static afStatus_t fillAndSend( uint8 *transSeq, zAddrType_t *addr, cId_t clusterID, byte len )
  190. {
  191. afAddrType_t afAddr;
  192. osal_memset( &afAddr, 0, sizeof(afAddrType_t) );
  193. ZADDR_TO_AFADDR( addr, afAddr );
  194. *(ZDP_TmpBuf-1) = *transSeq;
  195. return AF_DataRequest( &afAddr, &ZDApp_epDesc, clusterID,
  196. (uint16)(len+1), (uint8*)(ZDP_TmpBuf-1),
  197. transSeq, ZDP_TxOptions, AF_DEFAULT_RADIUS );
  198. }
  199. /*********************************************************************
  200. * @fn ZDP_SendData
  201. *
  202. * @brief This builds and send a request message that has
  203. * NWKAddrOfInterest as its only parameter.
  204. *
  205. * @param dstAddr - destination address
  206. * @param cmd - clusterID
  207. * @param dataLen - number of bytes of data
  208. * @param data - pointer to the data
  209. * @param SecurityEnable - Security Options
  210. *
  211. * @return afStatus_t
  212. */
  213. afStatus_t ZDP_SendData( uint8 *TransSeq, zAddrType_t *dstAddr, uint16 cmd,
  214. byte len, uint8 *buf, byte SecurityEnable )
  215. {
  216. uint8 *pBuf = ZDP_TmpBuf;
  217. byte cnt = len;
  218. while ( cnt-- )
  219. {
  220. *pBuf++ = *buf++;
  221. }
  222. FillAndSendTxOptions( TransSeq, dstAddr, cmd, len, ((SecurityEnable) ? AF_EN_SECURITY : 0) );
  223. }
  224. /*********************************************************************
  225. * @fn ZDP_NWKAddrOfInterestReq
  226. *
  227. * @brief This builds and send a request message that has
  228. * NWKAddrOfInterest as its only parameter.
  229. *
  230. * @param dstAddr - destination address
  231. * @param nwkAddr - 16 bit address
  232. * @param SecurityEnable - Security Options
  233. *
  234. * @return afStatus_t
  235. */
  236. afStatus_t ZDP_NWKAddrOfInterestReq( zAddrType_t *dstAddr, uint16 nwkAddr,
  237. byte cmd, byte SecurityEnable )
  238. {
  239. (void)SecurityEnable; // Intentionally unreferenced parameter
  240. ZDP_TmpBuf[0] = LO_UINT16( nwkAddr );
  241. ZDP_TmpBuf[1] = HI_UINT16( nwkAddr );
  242. return fillAndSend( &ZDP_TransID, dstAddr, cmd, 2 );
  243. }
  244. /*********************************************************************
  245. * Address Requests
  246. */
  247. /*********************************************************************
  248. * @fn ZDP_NwkAddrReq
  249. *
  250. * @brief This builds and send a NWK_addr_req message. This
  251. * function sends a broadcast message looking for a 16
  252. * bit address with a 64 bit address as bait.
  253. *
  254. * @param IEEEAddress - looking for this device
  255. * @param SecurityEnable - Security Options
  256. *
  257. * @return afStatus_t
  258. */
  259. afStatus_t ZDP_NwkAddrReq( uint8 *IEEEAddress, byte ReqType,
  260. byte StartIndex, byte SecurityEnable )
  261. {
  262. uint8 *pBuf = ZDP_TmpBuf;
  263. byte len = Z_EXTADDR_LEN + 1 + 1; // IEEEAddress + ReqType + StartIndex.
  264. zAddrType_t dstAddr;
  265. (void)SecurityEnable; // Intentionally unreferenced parameter
  266. if ( osal_ExtAddrEqual( saveExtAddr, IEEEAddress ) == FALSE )
  267. {
  268. dstAddr.addrMode = AddrBroadcast;
  269. dstAddr.addr.shortAddr = NWK_BROADCAST_SHORTADDR_DEVRXON;
  270. }
  271. else
  272. {
  273. dstAddr.addrMode = Addr16Bit;
  274. dstAddr.addr.shortAddr = ZDAppNwkAddr.addr.shortAddr;
  275. }
  276. pBuf = osal_cpyExtAddr( pBuf, IEEEAddress );
  277. *pBuf++ = ReqType;
  278. *pBuf++ = StartIndex;
  279. return fillAndSend( &ZDP_TransID, &dstAddr, NWK_addr_req, len );
  280. }
  281. /*********************************************************************
  282. * @fn ZDP_IEEEAddrReq
  283. *
  284. * @brief This builds and send a IEEE_addr_req message. This
  285. * function sends a unicast message looking for a 64
  286. * bit IEEE address with a 16 bit address as bait.
  287. *
  288. * @param ReqType - ZDP_IEEEADDR_REQTYPE_SINGLE or
  289. * ZDP_IEEEADDR_REQTYPE_EXTENDED
  290. * @param SecurityEnable - Security Options
  291. *
  292. * @return afStatus_t
  293. */
  294. afStatus_t ZDP_IEEEAddrReq( uint16 shortAddr, byte ReqType,
  295. byte StartIndex, byte SecurityEnable )
  296. {
  297. uint8 *pBuf = ZDP_TmpBuf;
  298. byte len = 2 + 1 + 1; // shortAddr + ReqType + StartIndex.
  299. zAddrType_t dstAddr;
  300. (void)SecurityEnable; // Intentionally unreferenced parameter
  301. dstAddr.addrMode = (afAddrMode_t)Addr16Bit;
  302. dstAddr.addr.shortAddr = shortAddr;
  303. *pBuf++ = LO_UINT16( shortAddr );
  304. *pBuf++ = HI_UINT16( shortAddr );
  305. *pBuf++ = ReqType;
  306. *pBuf++ = StartIndex;
  307. return fillAndSend( &ZDP_TransID, &dstAddr, IEEE_addr_req, len );
  308. }
  309. /*********************************************************************
  310. * @fn ZDP_MatchDescReq
  311. *
  312. * @brief This builds and send a Match_Desc_req message. This
  313. * function sends a broadcast or unicast message
  314. * requesting the list of endpoint/interfaces that
  315. * match profile ID and cluster IDs.
  316. *
  317. * @param dstAddr - destination address
  318. * @param nwkAddr - network address of interest
  319. * @param ProfileID - Profile ID
  320. * @param NumInClusters - number of input clusters
  321. * @param InClusterList - input cluster ID list
  322. * @param NumOutClusters - number of output clusters
  323. * @param OutClusterList - output cluster ID list
  324. * @param SecurityEnable - Security Options
  325. *
  326. * @return afStatus_t
  327. */
  328. afStatus_t ZDP_MatchDescReq( zAddrType_t *dstAddr, uint16 nwkAddr,
  329. uint16 ProfileID,
  330. byte NumInClusters, cId_t *InClusterList,
  331. byte NumOutClusters, cId_t *OutClusterList,
  332. byte SecurityEnable )
  333. {
  334. uint8 *pBuf = ZDP_TmpBuf;
  335. // nwkAddr+ProfileID+NumInClusters+NumOutClusters.
  336. byte i, len = 2 + 2 + 1 + 1; // nwkAddr+ProfileID+NumInClusters+NumOutClusters.
  337. (void)SecurityEnable; // Intentionally unreferenced parameter
  338. len += (NumInClusters + NumOutClusters) * sizeof(uint16);
  339. if ( len >= ZDP_BUF_SZ-1 )
  340. {
  341. return afStatus_MEM_FAIL;
  342. }
  343. // The spec changed in Zigbee 2007 (2.4.3.1.7.1) to not allow sending
  344. // this command to 0xFFFF. So, here we will filter this and replace
  345. // with 0xFFFD to only send to devices with RX ON. This includes the
  346. // network address of interest.
  347. if ( ((dstAddr->addrMode == AddrBroadcast) || (dstAddr->addrMode == Addr16Bit))
  348. && (dstAddr->addr.shortAddr == NWK_BROADCAST_SHORTADDR_DEVALL) )
  349. {
  350. dstAddr->addr.shortAddr = NWK_BROADCAST_SHORTADDR_DEVRXON;
  351. }
  352. if ( nwkAddr == NWK_BROADCAST_SHORTADDR_DEVALL )
  353. {
  354. nwkAddr = NWK_BROADCAST_SHORTADDR_DEVRXON;
  355. }
  356. *pBuf++ = LO_UINT16( nwkAddr ); // NWKAddrOfInterest
  357. *pBuf++ = HI_UINT16( nwkAddr );
  358. *pBuf++ = LO_UINT16( ProfileID ); // Profile ID
  359. *pBuf++ = HI_UINT16( ProfileID );
  360. *pBuf++ = NumInClusters; // Input cluster list
  361. if ( NumInClusters )
  362. {
  363. for (i=0; i<NumInClusters; ++i) {
  364. *pBuf++ = LO_UINT16( InClusterList[i] );
  365. *pBuf++ = HI_UINT16( InClusterList[i] );
  366. }
  367. }
  368. *pBuf++ = NumOutClusters; // Output cluster list
  369. if ( NumOutClusters )
  370. {
  371. for (i=0; i<NumOutClusters; ++i) {
  372. *pBuf++ = LO_UINT16( OutClusterList[i] );
  373. *pBuf++ = HI_UINT16( OutClusterList[i] );
  374. }
  375. }
  376. return fillAndSend( &ZDP_TransID, dstAddr, Match_Desc_req, len );
  377. }
  378. /*********************************************************************
  379. * @fn ZDP_SimpleDescReq
  380. *
  381. * @brief This builds and send a NWK_Simple_Desc_req
  382. * message. This function sends unicast message to the
  383. * destination device.
  384. *
  385. * @param dstAddr - destination address
  386. * @param nwkAddr - 16 bit address
  387. * @param epIntf - endpoint/interface
  388. * @param SecurityEnable - Security Options
  389. *
  390. * @return afStatus_t
  391. */
  392. afStatus_t ZDP_SimpleDescReq( zAddrType_t *dstAddr, uint16 nwkAddr,
  393. byte endPoint, byte SecurityEnable )
  394. {
  395. (void)SecurityEnable; // Intentionally unreferenced parameter
  396. ZDP_TmpBuf[0] = LO_UINT16( nwkAddr );
  397. ZDP_TmpBuf[1] = HI_UINT16( nwkAddr );
  398. ZDP_TmpBuf[2] = endPoint;
  399. return fillAndSend( &ZDP_TransID, dstAddr, Simple_Desc_req, 3 );
  400. }
  401. /*********************************************************************
  402. * @fn ZDP_UserDescSet
  403. *
  404. * @brief This builds and send a User_Desc_set message to set
  405. * the user descriptor. This function sends unicast
  406. * message to the destination device.
  407. *
  408. * @param dstAddr - destination address
  409. * @param nwkAddr - 16 bit address
  410. * @param UserDescriptor - user descriptor
  411. * @param SecurityEnable - Security Options
  412. *
  413. * @return afStatus_t
  414. */
  415. afStatus_t ZDP_UserDescSet( zAddrType_t *dstAddr, uint16 nwkAddr,
  416. UserDescriptorFormat_t *UserDescriptor,
  417. byte SecurityEnable )
  418. {
  419. uint8 *pBuf = ZDP_TmpBuf;
  420. byte len = (UserDescriptor->len < AF_MAX_USER_DESCRIPTOR_LEN) ?
  421. UserDescriptor->len : AF_MAX_USER_DESCRIPTOR_LEN;
  422. byte addrLen = 2;
  423. (void)SecurityEnable; // Intentionally unreferenced parameter
  424. *pBuf++ = LO_UINT16( nwkAddr );
  425. *pBuf++ = HI_UINT16( nwkAddr );
  426. *pBuf++ = len;
  427. addrLen = 3;
  428. pBuf = osal_memcpy( pBuf, UserDescriptor->desc, len );
  429. osal_memset( pBuf, AF_USER_DESCRIPTOR_FILL, AF_MAX_USER_DESCRIPTOR_LEN-len );
  430. return fillAndSend( &ZDP_TransID, dstAddr, User_Desc_set, (AF_MAX_USER_DESCRIPTOR_LEN + addrLen) );
  431. }
  432. /*********************************************************************
  433. * @fn ZDP_ServerDiscReq
  434. *
  435. * @brief Build and send a Server_Discovery_req request message.
  436. *
  437. * @param serverMask - 16-bit bit-mask of server services being sought.
  438. * @param SecurityEnable - Security Options
  439. *
  440. * @return afStatus_t
  441. */
  442. afStatus_t ZDP_ServerDiscReq( uint16 serverMask, byte SecurityEnable )
  443. {
  444. uint8 *pBuf = ZDP_TmpBuf;
  445. zAddrType_t dstAddr;
  446. dstAddr.addrMode = AddrBroadcast;
  447. dstAddr.addr.shortAddr = NWK_BROADCAST_SHORTADDR_DEVRXON;
  448. *pBuf++ = LO_UINT16( serverMask );
  449. *pBuf = HI_UINT16( serverMask );
  450. FillAndSendTxOptions( &ZDP_TransID, &dstAddr, Server_Discovery_req, 2,
  451. ((SecurityEnable) ? AF_EN_SECURITY : AF_TX_OPTIONS_NONE) );
  452. }
  453. /*********************************************************************
  454. * @fn ZDP_DeviceAnnce
  455. *
  456. * @brief This builds and send a Device_Annce message. This
  457. * function sends a broadcast message.
  458. *
  459. * @param nwkAddr - 16 bit address of the device
  460. * @param IEEEAddr - 64 bit address of the device
  461. * @param capabilities - device capabilities. This field is only
  462. * sent for v1.1 networks.
  463. * @param SecurityEnable - Security Options
  464. *
  465. * @return afStatus_t
  466. */
  467. afStatus_t ZDP_DeviceAnnce( uint16 nwkAddr, uint8 *IEEEAddr,
  468. byte capabilities, byte SecurityEnable )
  469. {
  470. zAddrType_t dstAddr;
  471. uint8 len;
  472. (void)SecurityEnable; // Intentionally unreferenced parameter
  473. dstAddr.addrMode = (afAddrMode_t)AddrBroadcast;
  474. dstAddr.addr.shortAddr = NWK_BROADCAST_SHORTADDR_DEVRXON;
  475. ZDP_TmpBuf[0] = LO_UINT16( nwkAddr );
  476. ZDP_TmpBuf[1] = HI_UINT16( nwkAddr );
  477. osal_cpyExtAddr( &ZDP_TmpBuf[2], IEEEAddr );
  478. len = 2 + Z_EXTADDR_LEN;
  479. ZDP_TmpBuf[10] = capabilities;
  480. len++;
  481. return fillAndSend( &ZDP_TransID, &dstAddr, Device_annce, len );
  482. }
  483. /*********************************************************************
  484. * Address Responses
  485. */
  486. /*********************************************************************
  487. * @fn zdpProcessAddrReq
  488. *
  489. * @brief Process an incoming NWK_addr_req or IEEE_addr_req message and then
  490. * build and send a corresponding NWK_addr_rsp or IEEE_addr_rsp msg.
  491. *
  492. * @param inMsg - incoming message
  493. *
  494. * @return none
  495. */
  496. void zdpProcessAddrReq( zdoIncomingMsg_t *inMsg )
  497. {
  498. associated_devices_t *pAssoc;
  499. uint8 reqType;
  500. uint16 aoi = INVALID_NODE_ADDR;
  501. uint8 *ieee = NULL;
  502. reqType = inMsg->asdu[(inMsg->clusterID == NWK_addr_req) ? Z_EXTADDR_LEN : sizeof( uint16 ) ];
  503. if ( inMsg->clusterID == NWK_addr_req )
  504. {
  505. ieee = inMsg->asdu;
  506. if ( osal_ExtAddrEqual( saveExtAddr, ieee ) )
  507. {
  508. aoi = ZDAppNwkAddr.addr.shortAddr;
  509. }
  510. // Handle response for sleeping end devices
  511. else if ( (ZSTACK_ROUTER_BUILD)
  512. && (((pAssoc = AssocGetWithExt( ieee )) != NULL)
  513. && (pAssoc->nodeRelation == CHILD_RFD)) )
  514. {
  515. aoi = pAssoc->shortAddr;
  516. if ( reqType != ZDP_ADDR_REQTYPE_SINGLE )
  517. reqType = 0xFF; // Force Invalid
  518. }
  519. }
  520. else // if ( inMsg->clusterID == IEEE_addr_req )
  521. {
  522. aoi = BUILD_UINT16( inMsg->asdu[0], inMsg->asdu[1] );
  523. if ( aoi == ZDAppNwkAddr.addr.shortAddr )
  524. {
  525. ieee = saveExtAddr;
  526. }
  527. else if ( (ZSTACK_ROUTER_BUILD)
  528. && (((pAssoc = AssocGetWithShort( aoi )) != NULL)
  529. && (pAssoc->nodeRelation == CHILD_RFD)) )
  530. {
  531. AddrMgrEntry_t addrEntry;
  532. addrEntry.user = ADDRMGR_USER_DEFAULT;
  533. addrEntry.index = pAssoc->addrIdx;
  534. if ( AddrMgrEntryGet( &addrEntry ) )
  535. {
  536. ieee = addrEntry.extAddr;
  537. }
  538. if ( reqType != ZDP_ADDR_REQTYPE_SINGLE )
  539. reqType = 0xFF; // Force Invalid
  540. }
  541. }
  542. if ( ((aoi != INVALID_NODE_ADDR) && (ieee != NULL)) || (inMsg->wasBroadcast == FALSE) )
  543. {
  544. uint8 stat;
  545. uint8 *pBuf = ZDP_TmpBuf;
  546. // Status + IEEE-Addr + Nwk-Addr.
  547. uint8 len = 1 + Z_EXTADDR_LEN + 2;
  548. // If aoi and iee are both setup, we found results
  549. if ( (aoi != INVALID_NODE_ADDR) && (ieee != NULL) )
  550. {
  551. stat = ((reqType == ZDP_ADDR_REQTYPE_SINGLE) || (reqType == ZDP_ADDR_REQTYPE_EXTENDED))
  552. ? ZDP_SUCCESS : ZDP_INVALID_REQTYPE;
  553. }
  554. else
  555. {
  556. // not found and the req was unicast to this device
  557. stat = ZDP_DEVICE_NOT_FOUND;
  558. // Fill in the missing field with this device's address
  559. if ( inMsg->clusterID == NWK_addr_req )
  560. {
  561. aoi = ZDAppNwkAddr.addr.shortAddr;
  562. }
  563. else
  564. {
  565. ieee = saveExtAddr;
  566. }
  567. }
  568. *pBuf++ = stat;
  569. pBuf = osal_cpyExtAddr( pBuf, ieee );
  570. *pBuf++ = LO_UINT16( aoi );
  571. *pBuf++ = HI_UINT16( aoi );
  572. if ( ZSTACK_ROUTER_BUILD )
  573. {
  574. if ( (reqType == ZDP_ADDR_REQTYPE_EXTENDED) && (aoi == ZDAppNwkAddr.addr.shortAddr)
  575. && (stat == ZDP_SUCCESS) )
  576. {
  577. uint8 cnt = 0;
  578. uint16 *list = AssocMakeList( &cnt );
  579. if ( list != NULL )
  580. {
  581. byte idx = inMsg->asdu[(((inMsg->clusterID == NWK_addr_req) ? Z_EXTADDR_LEN : sizeof( uint16 )) + 1)];
  582. uint16 *pList = list + idx;
  583. // NumAssocDev field is only present on success.
  584. if ( cnt > idx )
  585. {
  586. cnt -= idx;
  587. len += (cnt * sizeof( uint16 ));
  588. }
  589. else
  590. {
  591. cnt = 0;
  592. }
  593. *pBuf++ = cnt;
  594. len++;
  595. // StartIndex field is only present if NumAssocDev field is non-zero.
  596. *pBuf++ = idx;
  597. len++;
  598. while ( cnt != 0 )
  599. {
  600. *pBuf++ = LO_UINT16( *pList );
  601. *pBuf++ = HI_UINT16( *pList );
  602. pList++;
  603. cnt--;
  604. }
  605. osal_mem_free( (uint8 *)list );
  606. }
  607. else
  608. {
  609. // NumAssocDev field is only present on success.
  610. *pBuf++ = 0;
  611. len++;
  612. }
  613. }
  614. }
  615. ZDP_TxOptions = AF_MSG_ACK_REQUEST;
  616. fillAndSend( &(inMsg->TransSeq), &(inMsg->srcAddr), (cId_t)(inMsg->clusterID | ZDO_RESPONSE_BIT), len );
  617. ZDP_TxOptions = AF_TX_OPTIONS_NONE;
  618. }
  619. }
  620. /*********************************************************************
  621. * @fn ZDP_NodeDescMsg
  622. *
  623. * @brief Builds and sends a Node Descriptor message, unicast to the
  624. * specified device.
  625. *
  626. * @param inMsg - incoming message
  627. * @param nwkAddr - 16 bit network address for device
  628. * @param pNodeDesc - pointer to the node descriptor
  629. *
  630. * @return afStatus_t
  631. */
  632. afStatus_t ZDP_NodeDescMsg( zdoIncomingMsg_t *inMsg,
  633. uint16 nwkAddr, NodeDescriptorFormat_t *pNodeDesc )
  634. {
  635. uint8 *pBuf = ZDP_TmpBuf;
  636. byte len;
  637. len = 1 + 2 + 13; // Status + nwkAddr + Node descriptor
  638. *pBuf++ = ZDP_SUCCESS;
  639. *pBuf++ = LO_UINT16( nwkAddr );
  640. *pBuf++ = HI_UINT16( nwkAddr );
  641. *pBuf++ = (byte)((pNodeDesc->ComplexDescAvail << 3) |
  642. (pNodeDesc->UserDescAvail << 4) |
  643. (pNodeDesc->LogicalType & 0x07));
  644. *pBuf++ = (byte)((pNodeDesc->FrequencyBand << 3) | (pNodeDesc->APSFlags & 0x07));
  645. *pBuf++ = pNodeDesc->CapabilityFlags;
  646. *pBuf++ = pNodeDesc->ManufacturerCode[0];
  647. *pBuf++ = pNodeDesc->ManufacturerCode[1];
  648. *pBuf++ = pNodeDesc->MaxBufferSize;
  649. *pBuf++ = pNodeDesc->MaxInTransferSize[0];
  650. *pBuf++ = pNodeDesc->MaxInTransferSize[1];
  651. *pBuf++ = LO_UINT16( pNodeDesc->ServerMask );
  652. *pBuf++ = HI_UINT16( pNodeDesc->ServerMask );
  653. *pBuf++ = pNodeDesc->MaxOutTransferSize[0];
  654. *pBuf++ = pNodeDesc->MaxOutTransferSize[1];
  655. *pBuf = pNodeDesc->DescriptorCapability;
  656. return fillAndSend( &(inMsg->TransSeq), &(inMsg->srcAddr), Node_Desc_rsp, len );
  657. }
  658. /*********************************************************************
  659. * @fn ZDP_PowerDescMsg
  660. *
  661. * @brief Builds and sends a Power Descriptor message, unicast to the
  662. * specified device.
  663. *
  664. * @param inMsg - incoming message (request)
  665. * @param nwkAddr - 16 bit network address for device
  666. * @param pPowerDesc - pointer to the node descriptor
  667. *
  668. * @return afStatus_t
  669. */
  670. afStatus_t ZDP_PowerDescMsg( zdoIncomingMsg_t *inMsg,
  671. uint16 nwkAddr, NodePowerDescriptorFormat_t *pPowerDesc )
  672. {
  673. uint8 *pBuf = ZDP_TmpBuf;
  674. byte len = 1 + 2 + 2; // Status + nwkAddr + Node Power descriptor.
  675. *pBuf++ = ZDP_SUCCESS;
  676. *pBuf++ = LO_UINT16( nwkAddr );
  677. *pBuf++ = HI_UINT16( nwkAddr );
  678. *pBuf++ = (byte)((pPowerDesc->AvailablePowerSources << 4)
  679. | (pPowerDesc->PowerMode & 0x0F));
  680. *pBuf++ = (byte)((pPowerDesc->CurrentPowerSourceLevel << 4)
  681. | (pPowerDesc->CurrentPowerSource & 0x0F));
  682. return fillAndSend( &(inMsg->TransSeq), &(inMsg->srcAddr), Power_Desc_rsp, len );
  683. }
  684. /*********************************************************************
  685. * @fn ZDP_SimpleDescMsg
  686. *
  687. * @brief Builds and sends a Simple Descriptor message, unicast to the
  688. * specified device.
  689. *
  690. * @param inMsg - incoming message (request)
  691. * @param Status - message status (ZDP_SUCCESS or other)
  692. * @param pSimpleDesc - pointer to the node descriptor
  693. *
  694. * @return afStatus_t
  695. */
  696. afStatus_t ZDP_SimpleDescMsg( zdoIncomingMsg_t *inMsg, byte Status,
  697. SimpleDescriptionFormat_t *pSimpleDesc )
  698. {
  699. uint8 *pBuf = ZDP_TmpBuf;
  700. uint8 i, len;
  701. if ( Status == ZDP_SUCCESS && pSimpleDesc )
  702. {
  703. // Status + NWKAddrOfInterest + desc length + empty simple descriptor.
  704. len = 1 + 2 + 1 + 8;
  705. len += (pSimpleDesc->AppNumInClusters + pSimpleDesc->AppNumOutClusters) * sizeof ( uint16 );
  706. }
  707. else
  708. {
  709. len = 1 + 2 + 1; // Status + desc length
  710. }
  711. if ( len >= ZDP_BUF_SZ-1 )
  712. {
  713. return afStatus_MEM_FAIL;
  714. }
  715. *pBuf++ = Status;
  716. *pBuf++ = LO_UINT16( ZDAppNwkAddr.addr.shortAddr );
  717. *pBuf++ = HI_UINT16( ZDAppNwkAddr.addr.shortAddr );
  718. if ( len > 4 )
  719. {
  720. *pBuf++ = len - 4; // Simple descriptor length
  721. *pBuf++ = pSimpleDesc->EndPoint;
  722. *pBuf++ = LO_UINT16( pSimpleDesc->AppProfId );
  723. *pBuf++ = HI_UINT16( pSimpleDesc->AppProfId );
  724. *pBuf++ = LO_UINT16( pSimpleDesc->AppDeviceId );
  725. *pBuf++ = HI_UINT16( pSimpleDesc->AppDeviceId );
  726. *pBuf++ = (byte)(pSimpleDesc->AppDevVer << 4);
  727. *pBuf++ = pSimpleDesc->AppNumInClusters;
  728. if ( pSimpleDesc->AppNumInClusters )
  729. {
  730. for (i=0; i<pSimpleDesc->AppNumInClusters; ++i)
  731. {
  732. *pBuf++ = LO_UINT16( pSimpleDesc->pAppInClusterList[i] );
  733. *pBuf++ = HI_UINT16( pSimpleDesc->pAppInClusterList[i] );
  734. }
  735. }
  736. *pBuf++ = pSimpleDesc->AppNumOutClusters;
  737. if ( pSimpleDesc->AppNumOutClusters )
  738. {
  739. for (i=0; i<pSimpleDesc->AppNumOutClusters; ++i)
  740. {
  741. *pBuf++ = LO_UINT16( pSimpleDesc->pAppOutClusterList[i] );
  742. *pBuf++ = HI_UINT16( pSimpleDesc->pAppOutClusterList[i] );
  743. }
  744. }
  745. }
  746. else
  747. {
  748. *pBuf = 0; // Description Length = 0;
  749. }
  750. return fillAndSend( &(inMsg->TransSeq), &(inMsg->srcAddr), Simple_Desc_rsp, len );
  751. }
  752. /*********************************************************************
  753. * @fn ZDP_EPRsp
  754. *
  755. * @brief This builds and send an endpoint list. Used in
  756. * Active_EP_rsp and Match_Desc_Rsp
  757. * message. This function sends unicast message to the
  758. * requesting device.
  759. *
  760. * @param MsgType - either Active_EP_rsp or Match_Desc_Rsp
  761. * @param dstAddr - destination address
  762. * @param Status - message status (ZDP_SUCCESS or other)
  763. * @param nwkAddr - Device's short address that this response describes
  764. * @param Count - number of endpoint/interfaces in list
  765. * @param pEPIntfList - Array of Endpoint/Interfaces
  766. * @param SecurityEnable - Security Options
  767. *
  768. * @return afStatus_t
  769. */
  770. afStatus_t ZDP_EPRsp( uint16 MsgType, byte TransSeq, zAddrType_t *dstAddr,
  771. byte Status, uint16 nwkAddr, byte Count,
  772. uint8 *pEPList,
  773. byte SecurityEnable )
  774. {
  775. uint8 *pBuf = ZDP_TmpBuf;
  776. byte len = 1 + 2 + 1; // Status + nwkAddr + endpoint/interface count.
  777. byte txOptions;
  778. (void)SecurityEnable; // Intentionally unreferenced parameter
  779. if ( MsgType == Match_Desc_rsp )
  780. txOptions = AF_MSG_ACK_REQUEST;
  781. else
  782. txOptions = 0;
  783. *pBuf++ = Status;
  784. *pBuf++ = LO_UINT16( nwkAddr );
  785. *pBuf++ = HI_UINT16( nwkAddr );
  786. *pBuf++ = Count; // Endpoint/Interface count
  787. if ( Count )
  788. {
  789. len += Count;
  790. osal_memcpy( pBuf, pEPList, Count );
  791. }
  792. FillAndSendTxOptions( &TransSeq, dstAddr, MsgType, len, txOptions );
  793. }
  794. /*********************************************************************
  795. * @fn ZDP_UserDescRsp
  796. *
  797. * @brief Build and send the User Decriptor Response.
  798. *
  799. *
  800. * @param dstAddr - destination address
  801. * @param nwkAddrOfInterest -
  802. * @param userDesc -
  803. * @param SecurityEnable - Security Options
  804. *
  805. * @return ZStatus_t
  806. */
  807. ZStatus_t ZDP_UserDescRsp( byte TransSeq, zAddrType_t *dstAddr,
  808. uint16 nwkAddrOfInterest, UserDescriptorFormat_t *userDesc,
  809. byte SecurityEnable )
  810. {
  811. uint8 *pBuf = ZDP_TmpBuf;
  812. byte len = 1 + 2 + 1; // Status + nwkAddr + descriptor length.
  813. (void)SecurityEnable; // Intentionally unreferenced parameter
  814. len += userDesc->len;
  815. *pBuf++ = ZSUCCESS;
  816. *pBuf++ = LO_UINT16( nwkAddrOfInterest );
  817. *pBuf++ = HI_UINT16( nwkAddrOfInterest );
  818. *pBuf++ = userDesc->len;
  819. osal_memcpy( pBuf, userDesc->desc, userDesc->len );
  820. return (ZStatus_t)fillAndSend( &TransSeq, dstAddr, User_Desc_rsp, len );
  821. }
  822. /*********************************************************************
  823. * @fn ZDP_ServerDiscRsp
  824. *
  825. * @brief Build and send the Server_Discovery_rsp response.
  826. *
  827. * @param transID - Transaction sequence number of request.
  828. * @param dstAddr - Network Destination Address.
  829. * @param status - Status of response to request.
  830. * @param aoi - Network Address of Interest of request.
  831. * @param serverMask - Bit map of service(s) being sought.
  832. * @param SecurityEnable - Security Options
  833. *
  834. * @return ZStatus_t
  835. */
  836. ZStatus_t ZDP_ServerDiscRsp( byte transID, zAddrType_t *dstAddr, byte status,
  837. uint16 aoi, uint16 serverMask, byte SecurityEnable )
  838. {
  839. const byte len = 1 + 2; // status + aoi + mask.
  840. uint8 *pBuf = ZDP_TmpBuf;
  841. ZStatus_t stat;
  842. // Intentionally unreferenced parameters
  843. (void)aoi;
  844. (void)SecurityEnable;
  845. *pBuf++ = status;
  846. *pBuf++ = LO_UINT16( serverMask );
  847. *pBuf++ = HI_UINT16( serverMask );
  848. ZDP_TxOptions = AF_MSG_ACK_REQUEST;
  849. stat = fillAndSend( &transID, dstAddr, Server_Discovery_rsp, len );
  850. ZDP_TxOptions = AF_TX_OPTIONS_NONE;
  851. return ( stat );
  852. }
  853. /*********************************************************************
  854. * @fn ZDP_GenericRsp
  855. *
  856. * @brief Sends a response message with only the parameter status
  857. * byte and the addr of interest for data.
  858. * This function sends unicast message to the
  859. * requesting device.
  860. *
  861. * @param dstAddr - destination address
  862. * @param status - generic status for response
  863. * @param aoi - address of interest
  864. * @param dstAddr - destination address
  865. * @param rspId - response cluster ID
  866. * @param SecurityEnable - Security Options
  867. *
  868. * @return afStatus_t
  869. */
  870. afStatus_t ZDP_GenericRsp( byte TransSeq, zAddrType_t *dstAddr,
  871. byte status, uint16 aoi, uint16 rspID, byte SecurityEnable )
  872. {
  873. uint8 len;
  874. (void)SecurityEnable; // Intentionally unreferenced parameter
  875. ZDP_TmpBuf[0] = status;
  876. ZDP_TmpBuf[1] = LO_UINT16( aoi );
  877. ZDP_TmpBuf[2] = HI_UINT16( aoi );
  878. // Length byte
  879. ZDP_TmpBuf[3] = 0;
  880. len = 4;
  881. return fillAndSend( &TransSeq, dstAddr, rspID, len );
  882. }
  883. /*********************************************************************
  884. * Binding
  885. */
  886. /*********************************************************************
  887. * @fn ZDP_EndDeviceBindReq
  888. *
  889. * @brief This builds and sends a End_Device_Bind_req message.
  890. * This function sends a unicast message.
  891. *
  892. * @param dstAddr - destination address
  893. * @param LocalCoordinator - short address of local coordinator
  894. * @param epIntf - Endpoint/Interface of Simple Desc
  895. * @param ProfileID - Profile ID
  896. *
  897. * The Input cluster list is the opposite of what you would think.
  898. * This is the output cluster list of this device
  899. * @param NumInClusters - number of input clusters
  900. * @param InClusterList - input cluster ID list
  901. *
  902. * The Output cluster list is the opposite of what you would think.
  903. * This is the input cluster list of this device
  904. * @param NumOutClusters - number of output clusters
  905. * @param OutClusterList - output cluster ID list
  906. *
  907. * @param SecurityEnable - Security Options
  908. *
  909. * @return afStatus_t
  910. */
  911. afStatus_t ZDP_EndDeviceBindReq( zAddrType_t *dstAddr,
  912. uint16 LocalCoordinator,
  913. byte endPoint,
  914. uint16 ProfileID,
  915. byte NumInClusters, cId_t *InClusterList,
  916. byte NumOutClusters, cId_t *OutClusterList,
  917. byte SecurityEnable )
  918. {
  919. uint8 *pBuf = ZDP_TmpBuf;
  920. uint8 i, len;
  921. uint8 *ieeeAddr;
  922. (void)SecurityEnable; // Intentionally unreferenced parameter
  923. // LocalCoordinator + SrcExtAddr + ep + ProfileID + NumInClusters + NumOutClusters.
  924. len = 2 + Z_EXTADDR_LEN + 1 + 2 + 1 + 1;
  925. len += (NumInClusters + NumOutClusters) * sizeof ( uint16 );
  926. if ( len >= ZDP_BUF_SZ-1 )
  927. {
  928. return afStatus_MEM_FAIL;
  929. }
  930. if ( LocalCoordinator != NLME_GetShortAddr() )
  931. {
  932. return afStatus_INVALID_PARAMETER;
  933. }
  934. *pBuf++ = LO_UINT16( LocalCoordinator );
  935. *pBuf++ = HI_UINT16( LocalCoordinator );
  936. ieeeAddr = NLME_GetExtAddr();
  937. pBuf = osal_cpyExtAddr( pBuf, ieeeAddr );
  938. *pBuf++ = endPoint;
  939. *pBuf++ = LO_UINT16( ProfileID ); // Profile ID
  940. *pBuf++ = HI_UINT16( ProfileID );
  941. *pBuf++ = NumInClusters; // Input cluster list
  942. for ( i = 0; i < NumInClusters; ++i )
  943. {
  944. *pBuf++ = LO_UINT16(InClusterList[i]);
  945. *pBuf++ = HI_UINT16(InClusterList[i]);
  946. }
  947. *pBuf++ = NumOutClusters; // Output cluster list
  948. for ( i = 0; i < NumOutClusters; ++i )
  949. {
  950. *pBuf++ = LO_UINT16(OutClusterList[i]);
  951. *pBuf++ = HI_UINT16(OutClusterList[i]);
  952. }
  953. return fillAndSend( &ZDP_TransID, dstAddr, End_Device_Bind_req, len );
  954. }
  955. /*********************************************************************
  956. * @fn ZDP_BindUnbindReq
  957. *
  958. * @brief This builds and send a Bind_req or Unbind_req message
  959. * Depending on the ClusterID. This function
  960. * sends a unicast message to the local coordinator.
  961. *
  962. * @param BindOrUnbind - either Bind_req or Unbind_req
  963. * @param dstAddr - destination address of the message
  964. * @param SourceAddr - source 64 bit address of the binding
  965. * @param SrcEPIntf - Source endpoint/interface
  966. * @param ClusterID - Binding cluster ID
  967. * @param DestinationAddr - destination 64 bit addr of binding
  968. * @param DstEPIntf - destination endpoint/interface
  969. * @param SecurityEnable - Security Options
  970. *
  971. * @return afStatus_t
  972. */
  973. afStatus_t ZDP_BindUnbindReq( uint16 BindOrUnbind, zAddrType_t *dstAddr,
  974. uint8 *SourceAddr, byte SrcEndPoint,
  975. cId_t ClusterID,
  976. zAddrType_t *destinationAddr, byte DstEndPoint,
  977. byte SecurityEnable )
  978. {
  979. uint8 *pBuf = ZDP_TmpBuf;
  980. byte len;
  981. (void)SecurityEnable; // Intentionally unreferenced parameter
  982. // SourceAddr + SrcEPIntf + ClusterID + addrMode.
  983. len = Z_EXTADDR_LEN + 1 + sizeof( cId_t ) + sizeof( uint8 );
  984. if ( destinationAddr->addrMode == Addr64Bit )
  985. len += Z_EXTADDR_LEN + 1; // +1 for DstEPIntf
  986. else if ( destinationAddr->addrMode == AddrGroup )
  987. len += sizeof ( uint16 );
  988. pBuf = osal_cpyExtAddr( pBuf, SourceAddr );
  989. *pBuf++ = SrcEndPoint;
  990. *pBuf++ = LO_UINT16( ClusterID );
  991. *pBuf++ = HI_UINT16( ClusterID );
  992. *pBuf++ = destinationAddr->addrMode;
  993. if ( destinationAddr->addrMode == Addr64Bit )
  994. {
  995. pBuf = osal_cpyExtAddr( pBuf, destinationAddr->addr.extAddr );
  996. *pBuf = DstEndPoint;
  997. }
  998. else if ( destinationAddr->addrMode == AddrGroup )
  999. {
  1000. *pBuf++ = LO_UINT16( destinationAddr->addr.shortAddr );
  1001. *pBuf++ = HI_UINT16( destinationAddr->addr.shortAddr );
  1002. }
  1003. FillAndSendTxOptions( &ZDP_TransID, dstAddr, BindOrUnbind, len, AF_MSG_ACK_REQUEST );
  1004. }
  1005. /*********************************************************************
  1006. * Network Management
  1007. */
  1008. /*********************************************************************
  1009. * @fn ZDP_MgmtNwkDiscReq
  1010. *
  1011. * @brief This builds and send a Mgmt_NWK_Disc_req message. This
  1012. * function sends a unicast message.
  1013. *
  1014. * @param dstAddr - destination address of the message
  1015. * @param ScanChannels - 32 bit address bit map
  1016. * @param StartIndex - Starting index within the reporting network
  1017. * list
  1018. * @param SecurityEnable - Security Options
  1019. *
  1020. * @return afStatus_t
  1021. */
  1022. afStatus_t ZDP_MgmtNwkDiscReq( zAddrType_t *dstAddr,
  1023. uint32 ScanChannels,
  1024. byte ScanDuration,
  1025. byte StartIndex,
  1026. byte SecurityEnable )
  1027. {
  1028. uint8 *pBuf = ZDP_TmpBuf;
  1029. byte len = sizeof( uint32 )+1+1; // ScanChannels + ScanDuration + StartIndex.
  1030. (void)SecurityEnable; // Intentionally unreferenced parameter
  1031. pBuf = osal_buffer_uint32( pBuf, ScanChannels );
  1032. *pBuf++ = ScanDuration;
  1033. *pBuf = StartIndex;
  1034. return fillAndSend( &ZDP_TransID, dstAddr, Mgmt_NWK_Disc_req, len );
  1035. }
  1036. /*********************************************************************
  1037. * @fn ZDP_MgmtDirectJoinReq
  1038. *
  1039. * @brief This builds and send a Mgmt_Direct_Join_req message. This
  1040. * function sends a unicast message.
  1041. *
  1042. * @param dstAddr - destination address of the message
  1043. * @param deviceAddr - 64 bit IEEE Address
  1044. * @param SecurityEnable - Security Options
  1045. *
  1046. * @return afStatus_t
  1047. */
  1048. afStatus_t ZDP_MgmtDirectJoinReq( zAddrType_t *dstAddr,
  1049. uint8 *deviceAddr,
  1050. byte capInfo,
  1051. byte SecurityEnable )
  1052. {
  1053. (void)SecurityEnable; // Intentionally unreferenced parameter
  1054. osal_cpyExtAddr( ZDP_TmpBuf, deviceAddr );
  1055. ZDP_TmpBuf[Z_EXTADDR_LEN] = capInfo;
  1056. return fillAndSend( &ZDP_TransID, dstAddr, Mgmt_Direct_Join_req, (Z_EXTADDR_LEN + 1) );
  1057. }
  1058. /*********************************************************************
  1059. * @fn ZDP_MgmtPermitJoinReq
  1060. *
  1061. * @brief This builds and send a Mgmt_Permit_Join_req message.
  1062. *
  1063. * @param dstAddr - destination address of the message
  1064. * @param duration - Permit duration
  1065. * @param TcSignificance - Trust Center Significance
  1066. *
  1067. * @return afStatus_t
  1068. */
  1069. afStatus_t ZDP_MgmtPermitJoinReq( zAddrType_t *dstAddr, byte duration,
  1070. byte TcSignificance, byte SecurityEnable )
  1071. {
  1072. (void)SecurityEnable; // Intentionally unreferenced parameter
  1073. // Build buffer
  1074. ZDP_TmpBuf[ZDP_MGMT_PERMIT_JOIN_REQ_DURATION] = duration;
  1075. ZDP_TmpBuf[ZDP_MGMT_PERMIT_JOIN_REQ_TC_SIG] = TcSignificance;
  1076. // Send the message
  1077. return fillAndSend( &ZDP_TransID, dstAddr, Mgmt_Permit_Join_req,
  1078. ZDP_MGMT_PERMIT_JOIN_REQ_SIZE );
  1079. }
  1080. /*********************************************************************
  1081. * @fn ZDP_MgmtLeaveReq
  1082. *
  1083. * @brief This builds and send a Mgmt_Leave_req message.
  1084. *
  1085. * @param dstAddr - destination address of the message
  1086. * IEEEAddr - IEEE adddress of device that is removed
  1087. * RemoveChildren - set to 1 to remove the children of the
  1088. * device as well. 0 otherwise.
  1089. * Rejoin - set to 1 if the removed device should rejoin
  1090. afterwards. 0 otherwise.
  1091. *
  1092. * @return afStatus_t
  1093. */
  1094. afStatus_t ZDP_MgmtLeaveReq( zAddrType_t *dstAddr, uint8 *IEEEAddr, uint8 RemoveChildren,
  1095. uint8 Rejoin, uint8 SecurityEnable )
  1096. {
  1097. (void)SecurityEnable; // Intentionally unreferenced parameter
  1098. osal_cpyExtAddr( ZDP_TmpBuf, IEEEAddr );
  1099. ZDP_TmpBuf[Z_EXTADDR_LEN] = 0;
  1100. if ( RemoveChildren == TRUE )
  1101. {
  1102. ZDP_TmpBuf[Z_EXTADDR_LEN] |= ZDP_MGMT_LEAVE_REQ_RC;
  1103. }
  1104. if ( Rejoin == TRUE )
  1105. {
  1106. ZDP_TmpBuf[Z_EXTADDR_LEN] |= ZDP_MGMT_LEAVE_REQ_REJOIN;
  1107. }
  1108. return fillAndSend( &ZDP_TransID, dstAddr, Mgmt_Leave_req, (Z_EXTADDR_LEN + 1) );
  1109. }
  1110. /*********************************************************************
  1111. * @fn ZDP_MgmtNwkUpdateReq
  1112. *
  1113. * @brief This builds and send a Mgmt_NWK_Update_req message. This
  1114. * function sends a unicast or broadcast message.
  1115. *
  1116. * @param dstAddr - destination address of the message
  1117. * @param ChannelMask - 32 bit address bit map
  1118. * @param ScanDuration - length of time to spend scanning each channel
  1119. * @param ScanCount - number of energy scans to be conducted
  1120. * @param NwkUpdateId - NWk Update Id value
  1121. * @param NwkManagerAddr - NWK address for device with Network Manager
  1122. * bit set in its Node Descriptor
  1123. *
  1124. * @return afStatus_t
  1125. */
  1126. afStatus_t ZDP_MgmtNwkUpdateReq( zAddrType_t *dstAddr,
  1127. uint32 ChannelMask,
  1128. uint8 ScanDuration,
  1129. uint8 ScanCount,
  1130. uint8 NwkUpdateId,
  1131. uint16 NwkManagerAddr )
  1132. {
  1133. uint8 *pBuf = ZDP_TmpBuf;
  1134. byte len = sizeof( uint32 ) + 1; // ChannelMask + ScanDuration
  1135. pBuf = osal_buffer_uint32( pBuf, ChannelMask );
  1136. *pBuf++ = ScanDuration;
  1137. if ( ScanDuration <= 0x05 )
  1138. {
  1139. // Request is to scan over channelMask
  1140. len += sizeof( uint8 );
  1141. *pBuf++ = ScanCount;
  1142. }
  1143. else if ( ( ScanDuration == 0xFE ) || ( ScanDuration == 0xFF ) )
  1144. {
  1145. // Request is to change Channel (0xFE) or apsChannelMask and NwkManagerAddr (0xFF)
  1146. len += sizeof( uint8 );
  1147. *pBuf++ = NwkUpdateId;
  1148. if ( ScanDuration == 0xFF )
  1149. {
  1150. len += sizeof( uint16 );
  1151. *pBuf++ = LO_UINT16( NwkManagerAddr );
  1152. *pBuf++ = HI_UINT16( NwkManagerAddr );
  1153. }
  1154. }
  1155. return fillAndSend( &ZDP_TransID, dstAddr, Mgmt_NWK_Update_req, len );
  1156. }
  1157. /*********************************************************************
  1158. * Network Management Responses
  1159. */
  1160. /*********************************************************************
  1161. * @fn ZDP_MgmtNwkDiscRsp
  1162. *
  1163. * @brief This builds and send a Mgmt_NWK_Disc_rsp message. This
  1164. * function sends a unicast message.
  1165. *
  1166. * @param dstAddr - destination address of the message
  1167. * @param Status - message status (ZDP_SUCCESS or other)
  1168. * @param NetworkCount - Total number of networks found
  1169. * @param StartIndex - Starting index within the reporting network
  1170. * list
  1171. * @param NetworkListCount - number of network lists included
  1172. * in this message
  1173. * @param NetworkList - List of network descriptors
  1174. * @param SecurityEnable - Security Options
  1175. *
  1176. * @return afStatus_t
  1177. */
  1178. afStatus_t ZDP_MgmtNwkDiscRsp( byte TransSeq, zAddrType_t *dstAddr,
  1179. byte Status,
  1180. byte NetworkCount,
  1181. byte StartIndex,
  1182. byte NetworkListCount,
  1183. networkDesc_t *NetworkList,
  1184. byte SecurityEnable )
  1185. {
  1186. uint8 *buf;
  1187. uint8 *pBuf;
  1188. byte len = 1+1+1+1; // Status + NetworkCount + StartIndex + NetworkCountList.
  1189. byte idx;
  1190. (void)SecurityEnable; // Intentionally unreferenced parameter
  1191. len += (NetworkListCount * ( ZDP_NETWORK_EXTENDED_DISCRIPTOR_SIZE - 2 ));
  1192. buf = osal_mem_alloc( len+1 );
  1193. if ( buf == NULL )
  1194. {
  1195. return afStatus_MEM_FAIL;
  1196. }
  1197. pBuf = buf+1;
  1198. *pBuf++ = Status;
  1199. *pBuf++ = NetworkCount;
  1200. *pBuf++ = StartIndex;
  1201. *pBuf++ = NetworkListCount;
  1202. for ( idx = 0; idx < NetworkListCount; idx++ )
  1203. {
  1204. osal_cpyExtAddr( pBuf, NetworkList->extendedPANID);
  1205. pBuf += Z_EXTADDR_LEN;
  1206. *pBuf++ = NetworkList->logicalChannel; // LogicalChannel
  1207. *pBuf = NetworkList->stackProfile; // Stack profile
  1208. *pBuf++ |= (byte)(NetworkList->version << 4); // ZigBee Version
  1209. *pBuf = BEACON_ORDER_NO_BEACONS; // Beacon Order
  1210. *pBuf++ |= (uint8)(BEACON_ORDER_NO_BEACONS << 4); // Superframe Order
  1211. if ( NetworkList->chosenRouter != INVALID_NODE_ADDR )
  1212. {
  1213. *pBuf++ = TRUE; // Permit Joining
  1214. }
  1215. else
  1216. {
  1217. *pBuf++ = FALSE;
  1218. }
  1219. NetworkList = NetworkList->nextDesc; // Move to next list entry
  1220. }
  1221. FillAndSendBuffer( &TransSeq, dstAddr, Mgmt_NWK_Disc_rsp, len, buf );
  1222. }
  1223. /*********************************************************************
  1224. * @fn ZDP_MgmtLqiRsp
  1225. *
  1226. * @brief This builds and send a Mgmt_Lqi_rsp message. This
  1227. * function sends a unicast message.
  1228. *
  1229. * @param dstAddr - destination address of the message
  1230. * @param Status - message status (ZDP_SUCCESS or other)
  1231. * @param NeighborLqiEntries - Total number of entries found
  1232. * @param StartIndex - Starting index within the reporting list
  1233. * @param NeighborLqiCount - number of lists included
  1234. * in this message
  1235. * @param NeighborLqiList - List of NeighborLqiItems. This list
  1236. * is the list to be sent, not the entire list
  1237. * @param SecurityEnable - true if secure
  1238. *
  1239. * @return ZStatus_t
  1240. */
  1241. ZStatus_t ZDP_MgmtLqiRsp( byte TransSeq, zAddrType_t *dstAddr,
  1242. byte Status,
  1243. byte NeighborLqiEntries,
  1244. byte StartIndex,
  1245. byte NeighborLqiCount,
  1246. ZDP_MgmtLqiItem_t* NeighborList,
  1247. byte SecurityEnable )
  1248. {
  1249. ZDP_MgmtLqiItem_t* list = NeighborList;
  1250. uint8 *buf, *pBuf;
  1251. byte len, x;
  1252. (void)SecurityEnable; // Intentionally unreferenced parameter
  1253. if ( ZSuccess != Status )
  1254. {
  1255. ZDP_TmpBuf[0] = Status;
  1256. return fillAndSend( &TransSeq, dstAddr, Mgmt_Lqi_rsp, 1 );
  1257. }
  1258. // (Status + NeighborLqiEntries + StartIndex + NeighborLqiCount) +
  1259. // neighbor LQI data.
  1260. len = (1 + 1 + 1 + 1) + (NeighborLqiCount * ZDP_MGMTLQI_EXTENDED_SIZE);
  1261. buf = osal_mem_alloc( len+1 );
  1262. if ( buf == NULL )
  1263. {
  1264. return afStatus_MEM_FAIL;
  1265. }
  1266. pBuf = buf+1;
  1267. *pBuf++ = Status;
  1268. *pBuf++ = NeighborLqiEntries;
  1269. *pBuf++ = StartIndex;
  1270. *pBuf++ = NeighborLqiCount;
  1271. for ( x = 0; x < NeighborLqiCount; x++ )
  1272. {
  1273. osal_cpyExtAddr( pBuf, list->extPanID); // Extended PanID
  1274. pBuf += Z_EXTADDR_LEN;
  1275. // EXTADDR
  1276. pBuf = osal_cpyExtAddr( pBuf, list->extAddr );
  1277. // NWKADDR
  1278. *pBuf++ = LO_UINT16( list->nwkAddr );
  1279. *pBuf++ = HI_UINT16( list->nwkAddr );
  1280. // DEVICETYPE
  1281. *pBuf = list->devType;
  1282. // RXONIDLE
  1283. *pBuf |= (uint8)(list->rxOnIdle << 2);
  1284. // RELATIONSHIP
  1285. *pBuf++ |= (uint8)(list->relation << 4);
  1286. // PERMITJOINING
  1287. *pBuf++ = (uint8)(list->permit);
  1288. // DEPTH
  1289. *pBuf++ = list->depth;
  1290. // LQI
  1291. *pBuf++ = list->lqi;
  1292. list++; // next list entry
  1293. }
  1294. FillAndSendBuffer( &TransSeq, dstAddr, Mgmt_Lqi_rsp, len, buf );
  1295. }
  1296. /*********************************************************************
  1297. * @fn ZDP_MgmtRtgRsp
  1298. *
  1299. * @brief This builds and send a Mgmt_Rtg_rsp message. This
  1300. * function sends a unicast message.
  1301. *
  1302. * @param dstAddr - destination address of the message
  1303. * @param Status - message status (ZDP_SUCCESS or other)
  1304. * @param RoutingTableEntries - Total number of entries
  1305. * @param StartIndex - Starting index within the reporting list
  1306. * @param RoutingTableListCount - number of entries included
  1307. * in this message
  1308. * @param RoutingTableList - List of Routing Table entries
  1309. * @param SecurityEnable - true to enable security for this message
  1310. *
  1311. * @return ZStatus_t
  1312. */
  1313. ZStatus_t ZDP_MgmtRtgRsp( byte TransSeq, zAddrType_t *dstAddr,
  1314. byte Status,
  1315. byte RoutingTableEntries,
  1316. byte StartIndex,
  1317. byte RoutingListCount,
  1318. rtgItem_t *RoutingTableList,
  1319. byte SecurityEnable )
  1320. {
  1321. uint8 *buf;
  1322. uint8 *pBuf;
  1323. // Status + RoutingTableEntries + StartIndex + RoutingListCount.
  1324. byte len = 1 + 1 + 1 + 1;
  1325. byte x;
  1326. (void)SecurityEnable; // Intentionally unreferenced parameter
  1327. // Add an array for Routing List data
  1328. len += (RoutingListCount * ZDP_ROUTINGENTRY_SIZE);
  1329. buf = osal_mem_alloc( (short)(len+1) );
  1330. if ( buf == NULL )
  1331. {
  1332. return afStatus_MEM_FAIL;
  1333. }
  1334. pBuf = buf+1;
  1335. *pBuf++ = Status;
  1336. *pBuf++ = RoutingTableEntries;
  1337. *pBuf++ = StartIndex;
  1338. *pBuf++ = RoutingListCount;
  1339. for ( x = 0; x < RoutingListCount; x++ )
  1340. {
  1341. *pBuf++ = LO_UINT16( RoutingTableList->dstAddress ); // Destination Address
  1342. *pBuf++ = HI_UINT16( RoutingTableList->dstAddress );
  1343. *pBuf++ = RoutingTableList->status;
  1344. *pBuf++ = LO_UINT16( RoutingTableList->nextHopAddress ); // Next hop
  1345. *pBuf++ = HI_UINT16( RoutingTableList->nextHopAddress );
  1346. RoutingTableList++; // Move to next list entry
  1347. }
  1348. FillAndSendBuffer( &TransSeq, dstAddr, Mgmt_Rtg_rsp, len, buf );
  1349. }
  1350. /*********************************************************************
  1351. * @fn ZDP_MgmtBindRsp
  1352. *
  1353. * @brief This builds and send a Mgmt_Bind_rsp message. This
  1354. * function sends a unicast message.
  1355. *
  1356. * @param dstAddr - destination address of the message
  1357. * @param Status - message status (ZDP_SUCCESS or other)
  1358. * @param BindingTableEntries - Total number of entries
  1359. * @param StartIndex - Starting index within the reporting list
  1360. * @param BindingTableListCount - number of entries included
  1361. * in this message
  1362. * @param BindingTableList - List of Binding Table entries
  1363. * @param SecurityEnable - Security Options
  1364. *
  1365. * @return ZStatus_t
  1366. */
  1367. ZStatus_t ZDP_MgmtBindRsp( byte TransSeq, zAddrType_t *dstAddr,
  1368. byte Status,
  1369. byte BindingTableEntries,
  1370. byte StartIndex,
  1371. byte BindingTableListCount,
  1372. apsBindingItem_t *BindingTableList,
  1373. byte SecurityEnable )
  1374. {
  1375. uint8 *buf;
  1376. uint8 *pBuf;
  1377. uint8 maxLen; // maxLen is the maximum packet length to allocate enough memory space
  1378. uint8 len; // Actual length varies due to different addrMode
  1379. uint8 x;
  1380. byte extZdpBindEntrySize = ZDP_BINDINGENTRY_SIZE + 1 + 1; // One more byte for cluserID and DstAddrMode
  1381. byte shortZdpBindEntrySize = ZDP_BINDINGENTRY_SIZE + 1 + 1 + 2 - 8 - 1; // clusterID + DstAddrMode + shortAddr - ExtAddr - DstEndpoint
  1382. (void)SecurityEnable; // Intentionally unreferenced parameter
  1383. // Status + BindingTableEntries + StartIndex + BindingTableListCount.
  1384. maxLen = 1 + 1 + 1 + 1;
  1385. maxLen += (BindingTableListCount * extZdpBindEntrySize ); //max length
  1386. buf = osal_mem_alloc( maxLen + 1 ); // +1 for transaction ID
  1387. if ( buf == NULL )
  1388. {
  1389. return afStatus_MEM_FAIL;
  1390. }
  1391. pBuf = buf+1;
  1392. *pBuf++ = Status;
  1393. *pBuf++ = BindingTableEntries;
  1394. *pBuf++ = StartIndex;
  1395. *pBuf++ = BindingTableListCount;
  1396. // Initial length = Status + BindingTableEntries + StartIndex + BindingTableListCount.
  1397. // length += ZDP_BINDINGENTRY_SIZE -- Version 1.0
  1398. // extZdpBindEntrySize -- Version 1.1 extended address mode
  1399. // shortZdpBindEntrySize -- Version 1.1 group address mode
  1400. len = 1 + 1 + 1 + 1;
  1401. for ( x = 0; x < BindingTableListCount; x++ )
  1402. {
  1403. pBuf = osal_cpyExtAddr( pBuf, BindingTableList->srcAddr );
  1404. *pBuf++ = BindingTableList->srcEP;
  1405. // Cluster ID
  1406. *pBuf++ = LO_UINT16( BindingTableList->clusterID );
  1407. *pBuf++ = HI_UINT16( BindingTableList->clusterID );
  1408. *pBuf++ = BindingTableList->dstAddr.addrMode;
  1409. if ( BindingTableList->dstAddr.addrMode == Addr64Bit )
  1410. {
  1411. len += extZdpBindEntrySize;
  1412. pBuf = osal_cpyExtAddr( pBuf, BindingTableList->dstAddr.addr.extAddr );
  1413. *pBuf++ = BindingTableList->dstEP;
  1414. }
  1415. else
  1416. {
  1417. len += shortZdpBindEntrySize;
  1418. *pBuf++ = LO_UINT16( BindingTableList->dstAddr.addr.shortAddr );
  1419. *pBuf++ = HI_UINT16( BindingTableList->dstAddr.addr.shortAddr );
  1420. }
  1421. BindingTableList++; // Move to next list entry
  1422. }
  1423. FillAndSendBuffer( &TransSeq, dstAddr, Mgmt_Bind_rsp, len, buf );
  1424. }
  1425. /*********************************************************************
  1426. * @fn ZDP_MgmtNwkUpdateNotify
  1427. *
  1428. * @brief This builds and send a Mgmt_NWK_Update_notify message. This
  1429. * function sends a unicast message.
  1430. *
  1431. * @param dstAddr - destination address of the message
  1432. * @param status - message status (ZDP_SUCCESS or other)
  1433. * @param scannedChannels - List of channels scanned by the request
  1434. * @param totalTransmissions - Total transmissions
  1435. * @param transmissionFailures - Sum of transmission failures
  1436. * @param listCount - Number of records contained in the energyValues list
  1437. * @param energyValues - List of descriptors, one for each of ListCount,
  1438. * of the enegry detect descriptors
  1439. * @param txOptions - Transmit options
  1440. * @param securityEnable - Security options
  1441. *
  1442. * @return afStatus_t
  1443. */
  1444. afStatus_t ZDP_MgmtNwkUpdateNotify( uint8 TransSeq, zAddrType_t *dstAddr,
  1445. uint8 status, uint32 scannedChannels,
  1446. uint16 totalTransmissions, uint16 transmissionFailures,
  1447. uint8 listCount, uint8 *energyValues, uint8 txOptions,
  1448. uint8 securityEnable )
  1449. {
  1450. uint8 *buf;
  1451. uint8 *pBuf;
  1452. uint8 len;
  1453. (void)securityEnable; // Intentionally unreferenced parameter
  1454. // Status + ScannedChannels + totalTransmissions + transmissionFailures + ListCount + energyValues
  1455. len = 1 + 4 + 2 + 2 + 1 + listCount;
  1456. buf = osal_mem_alloc( len+1 ); // +1 for transaction ID
  1457. if ( buf == NULL )
  1458. {
  1459. return afStatus_MEM_FAIL;
  1460. }
  1461. pBuf = buf+1;
  1462. *pBuf++ = status;
  1463. pBuf = osal_buffer_uint32( pBuf, scannedChannels );
  1464. *pBuf++ = LO_UINT16( totalTransmissions );
  1465. *pBuf++ = HI_UINT16( totalTransmissions );
  1466. *pBuf++ = LO_UINT16( transmissionFailures );
  1467. *pBuf++ = HI_UINT16( transmissionFailures );
  1468. *pBuf++ = listCount;
  1469. if ( listCount > 0 )
  1470. osal_memcpy( pBuf, energyValues, listCount );
  1471. FillAndSendBufferTxOptions( &TransSeq, dstAddr, Mgmt_NWK_Update_notify, len, buf, txOptions );
  1472. }
  1473. /*********************************************************************
  1474. * Functions to register for ZDO Over-the-air messages
  1475. */
  1476. /*********************************************************************
  1477. * @fn ZDO_RegisterForZDOMsg
  1478. *
  1479. * @brief Call this function to register of an incoming over
  1480. * the air ZDO message - probably a response message
  1481. * but requests can also be received.
  1482. * Messages are delivered to the task with ZDO_CB_MSG
  1483. * as the message ID.
  1484. *
  1485. * @param taskID - Where you would like the message delivered
  1486. * @param clusterID - What message?
  1487. *
  1488. * @return ZSuccess - successful, ZMemError if not
  1489. */
  1490. ZStatus_t ZDO_RegisterForZDOMsg( uint8 taskID, uint16 clusterID )
  1491. {
  1492. ZDO_MsgCB_t *pList;
  1493. ZDO_MsgCB_t *pLast;
  1494. ZDO_MsgCB_t *pNew;
  1495. // Look for duplicate
  1496. pList = pLast = zdoMsgCBs;
  1497. while ( pList )
  1498. {
  1499. if ( pList->taskID == taskID && pList->clusterID == clusterID )
  1500. return ( ZSuccess );
  1501. pLast = pList;
  1502. pList = (ZDO_MsgCB_t *)pList->next;
  1503. }
  1504. // Add to the list
  1505. pNew = (ZDO_MsgCB_t *)osal_mem_alloc( sizeof ( ZDO_MsgCB_t ) );
  1506. if ( pNew )
  1507. {
  1508. pNew->taskID = taskID;
  1509. pNew->clusterID = clusterID;
  1510. pNew->next = NULL;
  1511. if ( zdoMsgCBs )
  1512. {
  1513. pLast->next = pNew;
  1514. }
  1515. else
  1516. zdoMsgCBs = pNew;
  1517. return ( ZSuccess );
  1518. }
  1519. else
  1520. return ( ZMemError );
  1521. }
  1522. /*********************************************************************
  1523. * @fn ZDO_RemoveRegisteredCB
  1524. *
  1525. * @brief Call this function if you don't want to receive the
  1526. * incoming message.
  1527. *
  1528. * @param taskID - Where the messages are being delivered.
  1529. * @param clusterID - What message?
  1530. *
  1531. * @return ZSuccess - successful, ZFailure if not found
  1532. */
  1533. ZStatus_t ZDO_RemoveRegisteredCB( uint8 taskID, uint16 clusterID )
  1534. {
  1535. ZDO_MsgCB_t *pList;
  1536. ZDO_MsgCB_t *pLast = NULL;
  1537. pList = zdoMsgCBs;
  1538. while ( pList )
  1539. {
  1540. if ( pList->taskID == taskID && pList->clusterID == clusterID )
  1541. {
  1542. if ( pLast )
  1543. {
  1544. // remove this one from the linked list
  1545. pLast->next = pList->next;
  1546. }
  1547. else if ( pList->next )
  1548. {
  1549. // remove the first one from the linked list
  1550. zdoMsgCBs = pList->next;
  1551. }
  1552. else
  1553. {
  1554. // remove the only item from the list
  1555. zdoMsgCBs = (ZDO_MsgCB_t *)NULL;
  1556. }
  1557. osal_mem_free( pList );
  1558. return ( ZSuccess );
  1559. }
  1560. pLast = pList;
  1561. pList = pList->next;
  1562. }
  1563. return ( ZFailure );
  1564. }
  1565. /*********************************************************************
  1566. * @fn ZDO_SendMsgCBs
  1567. *
  1568. * @brief This function sends messages to registered tasks.
  1569. * Local to ZDO and shouldn't be called outside of ZDO.
  1570. *
  1571. * @param inMsg - incoming message
  1572. *
  1573. * @return TRUE if sent to at least 1 task, FALSE if not
  1574. */
  1575. uint8 ZDO_SendMsgCBs( zdoIncomingMsg_t *inMsg )
  1576. {
  1577. uint8 ret = FALSE;
  1578. ZDO_MsgCB_t *pList = zdoMsgCBs;
  1579. while ( pList )
  1580. {
  1581. if ( pList->clusterID == inMsg->clusterID )
  1582. {
  1583. zdoIncomingMsg_t *msgPtr;
  1584. // Send the address to the task
  1585. msgPtr = (zdoIncomingMsg_t *)osal_msg_allocate( sizeof( zdoIncomingMsg_t ) + inMsg->asduLen );
  1586. if ( msgPtr )
  1587. {
  1588. // copy struct
  1589. osal_memcpy( msgPtr, inMsg, sizeof( zdoIncomingMsg_t ));
  1590. if ( inMsg->asduLen )
  1591. {
  1592. msgPtr->asdu = (byte*)(((byte*)msgPtr) + sizeof( zdoIncomingMsg_t ));
  1593. osal_memcpy( msgPtr->asdu, inMsg->asdu, inMsg->asduLen );
  1594. }
  1595. msgPtr->hdr.event = ZDO_CB_MSG;
  1596. osal_msg_send( pList->taskID, (uint8 *)msgPtr );
  1597. ret = TRUE;
  1598. }
  1599. }
  1600. pList = (ZDO_MsgCB_t *)pList->next;
  1601. }
  1602. return ( ret );
  1603. }
  1604. /*********************************************************************
  1605. * Incoming message processor
  1606. */
  1607. /*********************************************************************
  1608. * @fn ZDP_IncomingData
  1609. *
  1610. * @brief This function indicates the transfer of a data PDU (ASDU)
  1611. * from the APS sub-layer to the ZDO.
  1612. *
  1613. * @param pData - Incoming Message
  1614. *
  1615. * @return none
  1616. */
  1617. void ZDP_IncomingData( afIncomingMSGPacket_t *pData )
  1618. {
  1619. uint8 x = 0;
  1620. uint8 handled;
  1621. zdoIncomingMsg_t inMsg;
  1622. inMsg.srcAddr.addrMode = Addr16Bit;
  1623. inMsg.srcAddr.addr.shortAddr = pData->srcAddr.addr.shortAddr;
  1624. inMsg.wasBroadcast = pData->wasBroadcast;
  1625. inMsg.clusterID = pData->clusterId;
  1626. inMsg.SecurityUse = pData->SecurityUse;
  1627. inMsg.asduLen = pData->cmd.DataLength-1;
  1628. inMsg.asdu = pData->cmd.Data+1;
  1629. inMsg.TransSeq = pData->cmd.Data[0];
  1630. inMsg.macDestAddr = pData->macDestAddr;
  1631. handled = ZDO_SendMsgCBs( &inMsg );
  1632. #if (defined MT_ZDO_CB_FUNC)
  1633. #if !defined MT_TASK
  1634. if (zgZdoDirectCB)
  1635. #endif
  1636. {
  1637. MT_ZdoDirectCB( pData, &inMsg );
  1638. }
  1639. #endif
  1640. while ( zdpMsgProcs[x].clusterID != 0xFFFF )
  1641. {
  1642. if ( zdpMsgProcs[x].clusterID == inMsg.clusterID )
  1643. {
  1644. zdpMsgProcs[x].pFn( &inMsg );
  1645. return;
  1646. }
  1647. x++;
  1648. }
  1649. // Handle unhandled messages
  1650. if ( !handled )
  1651. ZDApp_InMsgCB( &inMsg );
  1652. }
  1653. /*********************************************************************
  1654. *********************************************************************/