rangeext.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663
  1. /**************************************************************************************************
  2. Filename: rangeext.c
  3. Revised: $Date: 2007-08-02 09:20:10 -0700 (Thu,02 Aug 2007) $
  4. Revision: $Revision: 15001 $
  5. Description: This module implements the Range Extender functionality and
  6. contains the init and event loop functions
  7. Copyright 2009 Texas Instruments Incorporated. All rights reserved.
  8. IMPORTANT: Your use of this Software is limited to those specific rights
  9. granted under the terms of a software license agreement between the user
  10. who downloaded the software, his/her employer (which must be your employer)
  11. and Texas Instruments Incorporated (the "License"). You may not use this
  12. Software unless you agree to abide by the terms of the License. The License
  13. limits your use, and you acknowledge, that the Software may not be modified,
  14. copied or distributed unless embedded on a Texas Instruments microcontroller
  15. or used solely and exclusively in conjunction with a Texas Instruments radio
  16. frequency transceiver, which is integrated into your product. Other than for
  17. the foregoing purpose, you may not use, reproduce, copy, prepare derivative
  18. works of, modify, distribute, perform, display or sell this Software and/or
  19. its documentation for any purpose.
  20. YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
  21. PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
  22. INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
  23. NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
  24. TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
  25. NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
  26. LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
  27. INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
  28. OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
  29. OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
  30. (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
  31. Should you have any questions regarding your right to use this Software,
  32. contact Texas Instruments Incorporated at www.TI.com.
  33. **************************************************************************************************/
  34. /*********************************************************************
  35. This application is designed for the test purpose of the SE profile which
  36. exploits the following clusters for a Range Extender configuration:
  37. General Basic
  38. General Alarms
  39. General Time
  40. General Key Establishment
  41. Key control:
  42. SW1: Join Network
  43. SW2: Not Used
  44. SW3: Not Used
  45. SW4: Not Used
  46. *********************************************************************/
  47. /*********************************************************************
  48. * INCLUDES
  49. */
  50. #include "OSAL.h"
  51. #include "OSAL_Clock.h"
  52. #include "ZDApp.h"
  53. #include "AddrMgr.h"
  54. #include "se.h"
  55. #include "rangeext.h"
  56. #include "zcl_general.h"
  57. #include "zcl_key_establish.h"
  58. #include "onboard.h"
  59. /* HAL */
  60. #include "hal_lcd.h"
  61. #include "hal_led.h"
  62. #include "hal_key.h"
  63. /*********************************************************************
  64. * MACROS
  65. */
  66. // There is no attribute in the Mandatory Reportable Attribute list for now
  67. #define zcl_MandatoryReportableAttribute( a ) ( a == NULL )
  68. /*********************************************************************
  69. * CONSTANTS
  70. */
  71. /*********************************************************************
  72. * TYPEDEFS
  73. */
  74. /*********************************************************************
  75. * GLOBAL VARIABLES
  76. */
  77. /*********************************************************************
  78. * GLOBAL FUNCTIONS
  79. */
  80. /*********************************************************************
  81. * LOCAL VARIABLES
  82. */
  83. static uint8 rangeExtTaskID; // osal task id for range ext device
  84. static devStates_t rangeExtNwkState; // network state variable
  85. static uint8 rangeExtTransID; // transaction id
  86. static afAddrType_t ESPAddr; // ESP destination address
  87. static uint8 linkKeyStatus; // status variable from get link key function
  88. /*********************************************************************
  89. * LOCAL FUNCTIONS
  90. */
  91. static void rangeext_HandleKeys( uint8 shift, uint8 keys );
  92. #if defined ( ZCL_KEY_ESTABLISH )
  93. static uint8 rangeext_KeyEstablish_ReturnLinkKey( uint16 shortAddr );
  94. #endif // ZCL_KEY_ESTABLISH
  95. #if defined ( ZCL_ALARMS )
  96. static void rangeext_ProcessAlarmCmd( uint8 srcEP, afAddrType_t *dstAddr,
  97. uint16 clusterID, zclFrameHdr_t *hdr, uint8 len, uint8 *data );
  98. #endif // ZCL_ALARMS
  99. static void rangeext_ProcessIdentifyTimeChange( void );
  100. /*************************************************************************/
  101. /*** Application Callback Functions ***/
  102. /*************************************************************************/
  103. // Foundation Callback functions
  104. static uint8 rangeext_ValidateAttrDataCB( zclAttrRec_t *pAttr, zclWriteRec_t *pAttrInfo );
  105. // General Cluster Callback functions
  106. static void rangeext_BasicResetCB( void );
  107. static void rangeext_IdentifyCB( zclIdentify_t *pCmd );
  108. static void rangeext_IdentifyQueryRspCB( zclIdentifyQueryRsp_t *pRsp );
  109. static void rangeext_AlarmCB( zclAlarm_t *pAlarm );
  110. /************************************************************************/
  111. /*** Functions to process ZCL Foundation ***/
  112. /*** incoming Command/Response messages ***/
  113. /************************************************************************/
  114. static void rangeext_ProcessZCLMsg( zclIncomingMsg_t *msg );
  115. #if defined ( ZCL_READ )
  116. static uint8 rangeext_ProcessInReadRspCmd( zclIncomingMsg_t *pInMsg );
  117. #endif // ZCL_READ
  118. #if defined ( ZCL_WRITE )
  119. static uint8 rangeext_ProcessInWriteRspCmd( zclIncomingMsg_t *pInMsg );
  120. #endif // ZCL_WRITE
  121. static uint8 rangeext_ProcessInDefaultRspCmd( zclIncomingMsg_t *pInMsg );
  122. #if defined ( ZCL_DISCOVER )
  123. static uint8 rangeext_ProcessInDiscRspCmd( zclIncomingMsg_t *pInMsg );
  124. #endif // ZCL_DISCOVER
  125. /*********************************************************************
  126. * ZCL General Clusters Callback table
  127. */
  128. static zclGeneral_AppCallbacks_t rangeext_GenCmdCallbacks =
  129. {
  130. rangeext_BasicResetCB, // Basic Cluster Reset command
  131. rangeext_IdentifyCB, // Identify command
  132. rangeext_IdentifyQueryRspCB, // Identify Query Response command
  133. NULL, // On/Off cluster commands
  134. NULL, // Level Control Move to Level command
  135. NULL, // Level Control Move command
  136. NULL, // Level Control Step command
  137. NULL, // Level Control Stop command
  138. NULL, // Group Response commands
  139. NULL, // Scene Store Request command
  140. NULL, // Scene Recall Request command
  141. NULL, // Scene Response command
  142. rangeext_AlarmCB, // Alarm (Response) command
  143. NULL, // RSSI Location command
  144. NULL, // RSSI Location Response command
  145. };
  146. /*********************************************************************
  147. * @fn rangeext_Init
  148. *
  149. * @brief Initialization function for the ZCL App Application.
  150. *
  151. * @param uint8 task_id - range extender task id
  152. *
  153. * @return none
  154. */
  155. void rangeext_Init( uint8 task_id )
  156. {
  157. rangeExtTaskID = task_id;
  158. // setup ESP destination address
  159. ESPAddr.addrMode = (afAddrMode_t)Addr16Bit;
  160. ESPAddr.endPoint = RANGEEXT_ENDPOINT;
  161. ESPAddr.addr.shortAddr = 0;
  162. // register SE endpoint
  163. zclSE_Init( &rangeExtSimpleDesc );
  164. // Register the ZCL General Cluster Library callback functions
  165. zclGeneral_RegisterCmdCallbacks( RANGEEXT_ENDPOINT, &rangeext_GenCmdCallbacks );
  166. // Register the application's attribute list
  167. zcl_registerAttrList( RANGEEXT_ENDPOINT, RANGEEXT_MAX_ATTRIBUTES, rangeExtAttrs );
  168. // Register the application's cluster option list
  169. zcl_registerClusterOptionList( RANGEEXT_ENDPOINT, RANGEEXT_MAX_OPTIONS, rangeExtOptions );
  170. // Register the application's attribute data validation callback function
  171. zcl_registerValidateAttrData( rangeext_ValidateAttrDataCB );
  172. // Register the Application to receive the unprocessed Foundation command/response messages
  173. zcl_registerForMsg( rangeExtTaskID );
  174. // Register for all key events - This app will handle all key events
  175. RegisterForKeys( rangeExtTaskID );
  176. }
  177. /*********************************************************************
  178. * @fn rangeext_event_loop
  179. *
  180. * @brief Event Loop Processor for rangeext.
  181. *
  182. * @param uint8 task_id - the osal task id
  183. * @param uint16 events - the event bitmask
  184. *
  185. * @return none
  186. */
  187. uint16 rangeext_event_loop( uint8 task_id, uint16 events )
  188. {
  189. afIncomingMSGPacket_t *MSGpkt;
  190. if ( events & SYS_EVENT_MSG )
  191. {
  192. while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( rangeExtTaskID )) )
  193. {
  194. switch ( MSGpkt->hdr.event )
  195. {
  196. case ZCL_INCOMING_MSG:
  197. // Incoming ZCL foundation command/response messages
  198. rangeext_ProcessZCLMsg( (zclIncomingMsg_t *)MSGpkt );
  199. break;
  200. case KEY_CHANGE:
  201. rangeext_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );
  202. break;
  203. case ZDO_STATE_CHANGE:
  204. rangeExtNwkState = (devStates_t)(MSGpkt->hdr.status);
  205. if (ZG_SECURE_ENABLED)
  206. {
  207. if ( rangeExtNwkState == DEV_ROUTER )
  208. {
  209. // check to see if link key had already been established
  210. linkKeyStatus = rangeext_KeyEstablish_ReturnLinkKey(ESPAddr.addr.shortAddr);
  211. if (linkKeyStatus != ZSuccess)
  212. {
  213. // send out key establishment request
  214. osal_set_event( rangeExtTaskID, RANGEEXT_KEY_ESTABLISHMENT_REQUEST_EVT);
  215. }
  216. }
  217. }
  218. break;
  219. default:
  220. break;
  221. }
  222. // Release the memory
  223. osal_msg_deallocate( (uint8 *)MSGpkt );
  224. }
  225. // return unprocessed events
  226. return (events ^ SYS_EVENT_MSG);
  227. }
  228. // event to intiate key establishment request
  229. if ( events & RANGEEXT_KEY_ESTABLISHMENT_REQUEST_EVT )
  230. {
  231. zclGeneral_KeyEstablish_InitiateKeyEstablishment(rangeExtTaskID, &ESPAddr, rangeExtTransID);
  232. return ( events ^ RANGEEXT_KEY_ESTABLISHMENT_REQUEST_EVT );
  233. }
  234. // handle processing of identify timeout event triggered by an identify command
  235. if ( events & RANGEEXT_IDENTIFY_TIMEOUT_EVT )
  236. {
  237. if ( rangeExtIdentifyTime > 0 )
  238. {
  239. rangeExtIdentifyTime--;
  240. }
  241. rangeext_ProcessIdentifyTimeChange();
  242. return ( events ^ RANGEEXT_IDENTIFY_TIMEOUT_EVT );
  243. }
  244. // Discard unknown events
  245. return 0;
  246. }
  247. /*********************************************************************
  248. * @fn rangeext_ProcessIdentifyTimeChange
  249. *
  250. * @brief Called to blink led for specified IdentifyTime attribute value
  251. *
  252. * @param none
  253. *
  254. * @return none
  255. */
  256. static void rangeext_ProcessIdentifyTimeChange( void )
  257. {
  258. if ( rangeExtIdentifyTime > 0 )
  259. {
  260. osal_start_timerEx( rangeExtTaskID, RANGEEXT_IDENTIFY_TIMEOUT_EVT, 1000 );
  261. HalLedBlink ( HAL_LED_4, 0xFF, HAL_LED_DEFAULT_DUTY_CYCLE, HAL_LED_DEFAULT_FLASH_TIME );
  262. }
  263. else
  264. {
  265. HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
  266. osal_stop_timerEx( rangeExtTaskID, RANGEEXT_IDENTIFY_TIMEOUT_EVT );
  267. }
  268. }
  269. #if defined ( ZCL_KEY_ESTABLISH )
  270. /*********************************************************************
  271. * @fn rangeext_KeyEstablish_ReturnLinkKey
  272. *
  273. * @brief This function get the requested link key
  274. *
  275. * @param shortAddr - short address of the partner.
  276. *
  277. * @return none
  278. */
  279. static uint8 rangeext_KeyEstablish_ReturnLinkKey( uint16 shortAddr )
  280. {
  281. APSME_LinkKeyData_t* keyData;
  282. uint8 status = ZFailure;
  283. AddrMgrEntry_t entry;
  284. // Look up the long address of the device
  285. entry.user = ADDRMGR_USER_DEFAULT;
  286. entry.nwkAddr = shortAddr;
  287. if ( AddrMgrEntryLookupNwk( &entry ) )
  288. {
  289. // check for APS link key data
  290. APSME_LinkKeyDataGet( entry.extAddr, &keyData );
  291. if ( (keyData != NULL) && (keyData->key != NULL) )
  292. {
  293. status = ZSuccess;
  294. }
  295. }
  296. else
  297. {
  298. // It's an unknown device
  299. status = ZInvalidParameter;
  300. }
  301. return status;
  302. }
  303. #endif // ZCL_KEY_ESTABLISH
  304. /*********************************************************************
  305. * @fn rangeext_HandleKeys
  306. *
  307. * @brief Handles all key events for this device.
  308. *
  309. * @param shift - true if in shift/alt.
  310. * @param keys - bit field for key events. Valid entries:
  311. * HAL_KEY_SW_4
  312. * HAL_KEY_SW_3
  313. * HAL_KEY_SW_2
  314. * HAL_KEY_SW_1
  315. *
  316. * @return none
  317. */
  318. static void rangeext_HandleKeys( uint8 shift, uint8 keys )
  319. {
  320. // Shift is used to make each button/switch dual purpose.
  321. if ( shift )
  322. {
  323. if ( keys & HAL_KEY_SW_1 )
  324. {
  325. }
  326. if ( keys & HAL_KEY_SW_2 )
  327. {
  328. }
  329. if ( keys & HAL_KEY_SW_3 )
  330. {
  331. }
  332. if ( keys & HAL_KEY_SW_4 )
  333. {
  334. }
  335. }
  336. else
  337. {
  338. if ( keys & HAL_KEY_SW_1 )
  339. {
  340. ZDOInitDevice(0); // join the network
  341. }
  342. if ( keys & HAL_KEY_SW_2 )
  343. {
  344. }
  345. if ( keys & HAL_KEY_SW_3 )
  346. {
  347. }
  348. if ( keys & HAL_KEY_SW_4 )
  349. {
  350. }
  351. }
  352. }
  353. /*********************************************************************
  354. * @fn rangeext_ValidateAttrDataCB
  355. *
  356. * @brief Check to see if the supplied value for the attribute data
  357. * is within the specified range of the attribute.
  358. *
  359. * @param pAttr - pointer to attribute
  360. * @param pAttrInfo - pointer to attribute info
  361. *
  362. * @return TRUE if data valid. FALSE otherwise.
  363. */
  364. static uint8 rangeext_ValidateAttrDataCB( zclAttrRec_t *pAttr, zclWriteRec_t *pAttrInfo )
  365. {
  366. uint8 valid = TRUE;
  367. switch ( pAttrInfo->dataType )
  368. {
  369. case ZCL_DATATYPE_BOOLEAN:
  370. if ( ( *(pAttrInfo->attrData) != 0 ) && ( *(pAttrInfo->attrData) != 1 ) )
  371. valid = FALSE;
  372. break;
  373. default:
  374. break;
  375. }
  376. return ( valid );
  377. }
  378. /*********************************************************************
  379. * @fn rangeext_BasicResetCB
  380. *
  381. * @brief Callback from the ZCL General Cluster Library to set all
  382. * the attributes of all the clusters to their factory defaults
  383. *
  384. * @param none
  385. *
  386. * @return none
  387. */
  388. static void rangeext_BasicResetCB( void )
  389. {
  390. // user should handle setting attributes to factory defaults here
  391. }
  392. /*********************************************************************
  393. * @fn rangeext_IdentifyCB
  394. *
  395. * @brief Callback from the ZCL General Cluster Library when
  396. * it received an Identity Command for this application.
  397. *
  398. * @param pCmd - pointer to structure for identify command
  399. *
  400. * @return none
  401. */
  402. static void rangeext_IdentifyCB( zclIdentify_t *pCmd )
  403. {
  404. rangeExtIdentifyTime = pCmd->identifyTime;
  405. rangeext_ProcessIdentifyTimeChange();
  406. }
  407. /*********************************************************************
  408. * @fn rangeext_IdentifyQueryRspCB
  409. *
  410. * @brief Callback from the ZCL General Cluster Library when
  411. * it received an Identity Query Response Command for this application.
  412. *
  413. * @param pRsp - pointer to structure for identify query response
  414. *
  415. * @return none
  416. */
  417. static void rangeext_IdentifyQueryRspCB( zclIdentifyQueryRsp_t *pRsp )
  418. {
  419. // add user code here
  420. }
  421. /*********************************************************************
  422. * @fn rangeext_AlarmCB
  423. *
  424. * @brief Callback from the ZCL General Cluster Library when
  425. * it received an Alarm request or response command for
  426. * this application.
  427. *
  428. * @param pAlarm - pointer to structure for alarm command
  429. *
  430. * @return none
  431. */
  432. static void rangeext_AlarmCB( zclAlarm_t *pAlarm )
  433. {
  434. // add user code here
  435. }
  436. /******************************************************************************
  437. *
  438. * Functions for processing ZCL Foundation incoming Command/Response messages
  439. *
  440. *****************************************************************************/
  441. /*********************************************************************
  442. * @fn rangeext_ProcessZCLMsg
  443. *
  444. * @brief Process ZCL Foundation incoming message
  445. *
  446. * @param pInMsg - message to process
  447. *
  448. * @return none
  449. */
  450. static void rangeext_ProcessZCLMsg( zclIncomingMsg_t *pInMsg )
  451. {
  452. switch ( pInMsg->zclHdr.commandID )
  453. {
  454. #if defined ( ZCL_READ )
  455. case ZCL_CMD_READ_RSP:
  456. rangeext_ProcessInReadRspCmd( pInMsg );
  457. break;
  458. #endif // ZCL_READ
  459. #if defined ( ZCL_WRITE )
  460. case ZCL_CMD_WRITE_RSP:
  461. rangeext_ProcessInWriteRspCmd( pInMsg );
  462. break;
  463. #endif // ZCL_WRITE
  464. case ZCL_CMD_DEFAULT_RSP:
  465. rangeext_ProcessInDefaultRspCmd( pInMsg );
  466. break;
  467. #if defined ( ZCL_DISCOVER )
  468. case ZCL_CMD_DISCOVER_RSP:
  469. rangeext_ProcessInDiscRspCmd( pInMsg );
  470. break;
  471. #endif // ZCL_DISCOVER
  472. default:
  473. break;
  474. }
  475. if ( pInMsg->attrCmd != NULL )
  476. {
  477. // free the parsed command
  478. osal_mem_free( pInMsg->attrCmd );
  479. pInMsg->attrCmd = NULL;
  480. }
  481. }
  482. #if defined ( ZCL_READ )
  483. /*********************************************************************
  484. * @fn rangeext_ProcessInReadRspCmd
  485. *
  486. * @brief Process the "Profile" Read Response Command
  487. *
  488. * @param pInMsg - incoming message to process
  489. *
  490. * @return none
  491. */
  492. static uint8 rangeext_ProcessInReadRspCmd( zclIncomingMsg_t *pInMsg )
  493. {
  494. zclReadRspCmd_t *readRspCmd;
  495. uint8 i;
  496. readRspCmd = (zclReadRspCmd_t *)pInMsg->attrCmd;
  497. for (i = 0; i < readRspCmd->numAttr; i++)
  498. {
  499. // Notify the originator of the results of the original read attributes
  500. // attempt and, for each successfull request, the value of the requested
  501. // attribute
  502. }
  503. return TRUE;
  504. }
  505. #endif // ZCL_READ
  506. #if defined ( ZCL_WRITE )
  507. /*********************************************************************
  508. * @fn rangeext_ProcessInWriteRspCmd
  509. *
  510. * @brief Process the "Profile" Write Response Command
  511. *
  512. * @param pInMsg - incoming message to process
  513. *
  514. * @return none
  515. */
  516. static uint8 rangeext_ProcessInWriteRspCmd( zclIncomingMsg_t *pInMsg )
  517. {
  518. zclWriteRspCmd_t *writeRspCmd;
  519. uint8 i;
  520. writeRspCmd = (zclWriteRspCmd_t *)pInMsg->attrCmd;
  521. for (i = 0; i < writeRspCmd->numAttr; i++)
  522. {
  523. // Notify the device of the results of the its original write attributes
  524. // command.
  525. }
  526. return TRUE;
  527. }
  528. #endif // ZCL_WRITE
  529. /*********************************************************************
  530. * @fn rangeext_ProcessInDefaultRspCmd
  531. *
  532. * @brief Process the "Profile" Default Response Command
  533. *
  534. * @param pInMsg - incoming message to process
  535. *
  536. * @return none
  537. */
  538. static uint8 rangeext_ProcessInDefaultRspCmd( zclIncomingMsg_t *pInMsg )
  539. {
  540. // zclDefaultRspCmd_t *defaultRspCmd = (zclDefaultRspCmd_t *)pInMsg->attrCmd;
  541. // Device is notified of the Default Response command.
  542. return TRUE;
  543. }
  544. #if defined ( ZCL_DISCOVER )
  545. /*********************************************************************
  546. * @fn rangeext_ProcessInDiscRspCmd
  547. *
  548. * @brief Process the "Profile" Discover Response Command
  549. *
  550. * @param pInMsg - incoming message to process
  551. *
  552. * @return none
  553. */
  554. static uint8 rangeext_ProcessInDiscRspCmd( zclIncomingMsg_t *pInMsg )
  555. {
  556. zclDiscoverRspCmd_t *discoverRspCmd;
  557. uint8 i;
  558. discoverRspCmd = (zclDiscoverRspCmd_t *)pInMsg->attrCmd;
  559. for ( i = 0; i < discoverRspCmd->numAttr; i++ )
  560. {
  561. // Device is notified of the result of its attribute discovery command.
  562. }
  563. return TRUE;
  564. }
  565. #endif // ZCL_DISCOVER
  566. /****************************************************************************
  567. ****************************************************************************/