ipd.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951
  1. /**************************************************************************************************
  2. Filename: ipd.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 IPD functionality and contains the
  6. 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 an IPD configuration:
  37. General Basic
  38. General Alarms
  39. General Time
  40. General Key Establishment
  41. SE Price
  42. SE Message
  43. Key control:
  44. SW1: Join Network
  45. SW2: N/A
  46. SW3: N/A
  47. SW4: N/A
  48. *********************************************************************/
  49. /*********************************************************************
  50. * INCLUDES
  51. */
  52. #include "OSAL.h"
  53. #include "OSAL_Clock.h"
  54. #include "ZDApp.h"
  55. #include "AddrMgr.h"
  56. #include "se.h"
  57. #include "ipd.h"
  58. #include "zcl_general.h"
  59. #include "zcl_se.h"
  60. #include "zcl_key_establish.h"
  61. #include "onboard.h"
  62. /* HAL */
  63. #include "hal_lcd.h"
  64. #include "hal_led.h"
  65. #include "hal_key.h"
  66. /*********************************************************************
  67. * MACROS
  68. */
  69. // There is no attribute in the Mandatory Reportable Attribute list for now
  70. #define zcl_MandatoryReportableAttribute( a ) ( a == NULL )
  71. /*********************************************************************
  72. * CONSTANTS
  73. */
  74. /*********************************************************************
  75. * TYPEDEFS
  76. */
  77. /*********************************************************************
  78. * GLOBAL VARIABLES
  79. */
  80. /*********************************************************************
  81. * GLOBAL FUNCTIONS
  82. */
  83. /*********************************************************************
  84. * LOCAL VARIABLES
  85. */
  86. static uint8 ipdTaskID; // osal task id for IPD
  87. static uint8 ipdTransID; // transaction id
  88. static devStates_t ipdNwkState; // network state variable
  89. static afAddrType_t ESPAddr; // ESP destination address
  90. static uint8 linkKeyStatus; // status variable returned from get link key function
  91. static uint8 option; // tx options field
  92. /*********************************************************************
  93. * LOCAL FUNCTIONS
  94. */
  95. static void ipd_HandleKeys( uint8 shift, uint8 keys );
  96. #if defined (ZCL_KEY_ESTABLISH)
  97. static uint8 ipd_KeyEstablish_ReturnLinkKey( uint16 shortAddr );
  98. #endif // ZCL_KEY_ESTABLISH
  99. #if defined ( ZCL_ALARMS )
  100. static void ipd_ProcessAlarmCmd( uint8 srcEP, afAddrType_t *dstAddr,
  101. uint16 clusterID, zclFrameHdr_t *hdr, uint8 len, uint8 *data );
  102. #endif // ZCL_ALARMS
  103. static void ipd_ProcessIdentifyTimeChange( void );
  104. /*************************************************************************/
  105. /*** Application Callback Functions ***/
  106. /*************************************************************************/
  107. // Foundation Callback functions
  108. static uint8 ipd_ValidateAttrDataCB( zclAttrRec_t *pAttr, zclWriteRec_t *pAttrInfo );
  109. // General Cluster Callback functions
  110. static void ipd_BasicResetCB( void );
  111. static void ipd_IdentifyCB( zclIdentify_t *pCmd );
  112. static void ipd_IdentifyQueryRspCB( zclIdentifyQueryRsp_t *pRsp );
  113. static void ipd_AlarmCB( zclAlarm_t *pAlarm );
  114. // SE Callback functions
  115. static void ipd_GetCurrentPriceCB( zclCCGetCurrentPrice_t *pCmd,
  116. afAddrType_t *srcAddr, uint8 seqNum );
  117. static void ipd_GetScheduledPriceCB( zclCCGetScheduledPrice_t *pCmd,
  118. afAddrType_t *srcAddr, uint8 seqNum );
  119. static void ipd_PublishPriceCB( zclCCPublishPrice_t *pCmd,
  120. afAddrType_t *srcAddr, uint8 seqNum );
  121. static void ipd_DisplayMessageCB( zclCCDisplayMessage_t *pCmd,
  122. afAddrType_t *srcAddr, uint8 seqNum );
  123. static void ipd_CancelMessageCB( zclCCCancelMessage_t *pCmd,
  124. afAddrType_t *srcAddr, uint8 seqNum );
  125. static void ipd_GetLastMessageCB( afAddrType_t *srcAddr, uint8 seqNum );
  126. static void ipd_MessageConfirmationCB( zclCCMessageConfirmation_t *pCmd,
  127. afAddrType_t *srcAddr, uint8 seqNum );
  128. /************************************************************************/
  129. /*** Functions to process ZCL Foundation ***/
  130. /*** incoming Command/Response messages ***/
  131. /************************************************************************/
  132. static void ipd_ProcessZCLMsg( zclIncomingMsg_t *msg );
  133. #if defined ( ZCL_READ )
  134. static uint8 ipd_ProcessInReadRspCmd( zclIncomingMsg_t *pInMsg );
  135. #endif // ZCL_READ
  136. #if defined ( ZCL_WRITE )
  137. static uint8 ipd_ProcessInWriteRspCmd( zclIncomingMsg_t *pInMsg );
  138. #endif // ZCL_WRITE
  139. static uint8 ipd_ProcessInDefaultRspCmd( zclIncomingMsg_t *pInMsg );
  140. #if defined ( ZCL_DISCOVER )
  141. static uint8 ipd_ProcessInDiscRspCmd( zclIncomingMsg_t *pInMsg );
  142. #endif // ZCL_DISCOVER
  143. /*********************************************************************
  144. * ZCL General Clusters Callback table
  145. */
  146. static zclGeneral_AppCallbacks_t ipd_GenCmdCallbacks =
  147. {
  148. ipd_BasicResetCB, // Basic Cluster Reset command
  149. ipd_IdentifyCB, // Identify command
  150. ipd_IdentifyQueryRspCB, // Identify Query Response command
  151. NULL, // On/Off cluster commands
  152. NULL, // Level Control Move to Level command
  153. NULL, // Level Control Move command
  154. NULL, // Level Control Step command
  155. NULL, // Level Control Stop command
  156. NULL, // Group Response commands
  157. NULL, // Scene Store Request command
  158. NULL, // Scene Recall Request command
  159. NULL, // Scene Response command
  160. ipd_AlarmCB, // Alarm (Response) command
  161. NULL, // RSSI Location command
  162. NULL, // RSSI Location Response command
  163. };
  164. /*********************************************************************
  165. * ZCL SE Clusters Callback table
  166. */
  167. static zclSE_AppCallbacks_t ipd_SECmdCallbacks =
  168. {
  169. NULL, // Get Profile Command
  170. NULL, // Get Profile Response
  171. NULL, // Request Mirror Command
  172. NULL, // Request Mirror Response
  173. NULL, // Mirror Remove Command
  174. NULL, // Mirror Remove Response
  175. ipd_GetCurrentPriceCB, // Get Current Price
  176. ipd_GetScheduledPriceCB, // Get Scheduled Price
  177. ipd_PublishPriceCB, // Publish Price
  178. ipd_DisplayMessageCB, // Display Message Command
  179. ipd_CancelMessageCB, // Cancel Message Command
  180. ipd_GetLastMessageCB, // Get Last Message Command
  181. ipd_MessageConfirmationCB, // Message Confirmation
  182. NULL, // Load Control Event
  183. NULL, // Cancel Load Control Event
  184. NULL, // Cancel All Load Control Events
  185. NULL, // Report Event Status
  186. NULL, // Get Scheduled Event
  187. };
  188. /*********************************************************************
  189. * @fn ipd_Init
  190. *
  191. * @brief Initialization function for the ZCL App Application.
  192. *
  193. * @param uint8 task_id - ipd task id
  194. *
  195. * @return none
  196. */
  197. void ipd_Init( uint8 task_id )
  198. {
  199. ipdTaskID = task_id;
  200. ipdNwkState = DEV_INIT;
  201. ipdTransID = 0;
  202. // Device hardware initialization can be added here or in main() (Zmain.c).
  203. // If the hardware is application specific - add it here.
  204. // If the hardware is other parts of the device add it in main().
  205. // setup ESP destination address
  206. ESPAddr.addrMode = (afAddrMode_t)Addr16Bit;
  207. ESPAddr.endPoint = IPD_ENDPOINT;
  208. ESPAddr.addr.shortAddr = 0;
  209. // Register for SE endpoint
  210. zclSE_Init( &ipdSimpleDesc );
  211. // Register the ZCL General Cluster Library callback functions
  212. zclGeneral_RegisterCmdCallbacks( IPD_ENDPOINT, &ipd_GenCmdCallbacks );
  213. // Register the ZCL SE Cluster Library callback functions
  214. zclSE_RegisterCmdCallbacks( IPD_ENDPOINT, &ipd_SECmdCallbacks );
  215. // Register the application's attribute list
  216. zcl_registerAttrList( IPD_ENDPOINT, IPD_MAX_ATTRIBUTES, ipdAttrs );
  217. // Register the application's cluster option list
  218. zcl_registerClusterOptionList( IPD_ENDPOINT, IPD_MAX_OPTIONS, ipdOptions );
  219. // Register the application's attribute data validation callback function
  220. zcl_registerValidateAttrData( ipd_ValidateAttrDataCB );
  221. // Register the Application to receive the unprocessed Foundation command/response messages
  222. zcl_registerForMsg( ipdTaskID );
  223. // Register for all key events - This app will handle all key events
  224. RegisterForKeys( ipdTaskID );
  225. // Start the timer to sync IPD timer with the osal timer
  226. osal_start_timerEx( ipdTaskID, IPD_UPDATE_TIME_EVT, IPD_UPDATE_TIME_PERIOD );
  227. }
  228. /*********************************************************************
  229. * @fn ipd_event_loop
  230. *
  231. * @brief Event Loop Processor for ipd.
  232. *
  233. * @param uint8 task_id - ipd task id
  234. * @param uint16 events - event bitmask
  235. *
  236. * @return none
  237. */
  238. uint16 ipd_event_loop( uint8 task_id, uint16 events )
  239. {
  240. afIncomingMSGPacket_t *MSGpkt;
  241. if ( events & SYS_EVENT_MSG )
  242. {
  243. while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( ipdTaskID )) )
  244. {
  245. switch ( MSGpkt->hdr.event )
  246. {
  247. case ZCL_INCOMING_MSG:
  248. // Incoming ZCL foundation command/response messages
  249. ipd_ProcessZCLMsg( (zclIncomingMsg_t *)MSGpkt );
  250. break;
  251. case KEY_CHANGE:
  252. ipd_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );
  253. break;
  254. case ZDO_STATE_CHANGE:
  255. ipdNwkState = (devStates_t)(MSGpkt->hdr.status);
  256. if (ZG_SECURE_ENABLED)
  257. {
  258. if ( ipdNwkState == DEV_END_DEVICE )
  259. {
  260. // check to see if link key had already been established
  261. linkKeyStatus = ipd_KeyEstablish_ReturnLinkKey(ESPAddr.addr.shortAddr);
  262. if (linkKeyStatus != ZSuccess)
  263. {
  264. // send out key establishment request
  265. osal_set_event( ipdTaskID, IPD_KEY_ESTABLISHMENT_REQUEST_EVT);
  266. }
  267. else
  268. {
  269. // link key already established, resume sending reports
  270. osal_start_timerEx( ipdTaskID, IPD_GET_PRICING_INFO_EVT, IPD_GET_PRICING_INFO_PERIOD );
  271. }
  272. }
  273. }
  274. else
  275. {
  276. osal_start_timerEx( ipdTaskID, IPD_GET_PRICING_INFO_EVT, IPD_GET_PRICING_INFO_PERIOD );
  277. }
  278. NLME_SetPollRate ( SE_DEVICE_POLL_RATE ); // per smart energy spec end device polling requirement of not to poll < 7.5 seconds
  279. break;
  280. #if defined( ZCL_KEY_ESTABLISH )
  281. case ZCL_KEY_ESTABLISH_IND:
  282. osal_start_timerEx( ipdTaskID, IPD_GET_PRICING_INFO_EVT, IPD_GET_PRICING_INFO_PERIOD );
  283. break;
  284. #endif
  285. default:
  286. break;
  287. }
  288. // Release the memory
  289. osal_msg_deallocate( (uint8 *)MSGpkt );
  290. }
  291. // return unprocessed events
  292. return (events ^ SYS_EVENT_MSG);
  293. }
  294. // event to intiate key establishment request
  295. if ( events & IPD_KEY_ESTABLISHMENT_REQUEST_EVT )
  296. {
  297. zclGeneral_KeyEstablish_InitiateKeyEstablishment(ipdTaskID, &ESPAddr, ipdTransID);
  298. return ( events ^ IPD_KEY_ESTABLISHMENT_REQUEST_EVT );
  299. }
  300. // event to get current price
  301. if ( events & IPD_GET_PRICING_INFO_EVT )
  302. {
  303. zclSE_Pricing_Send_GetCurrentPrice( IPD_ENDPOINT, &ESPAddr, option, TRUE, 0 );
  304. osal_start_timerEx( ipdTaskID, IPD_GET_PRICING_INFO_EVT, IPD_GET_PRICING_INFO_PERIOD );
  305. return ( events ^ IPD_GET_PRICING_INFO_EVT );
  306. }
  307. // handle processing of identify timeout event triggered by an identify command
  308. if ( events & IPD_IDENTIFY_TIMEOUT_EVT )
  309. {
  310. if ( ipdIdentifyTime > 0 )
  311. {
  312. ipdIdentifyTime--;
  313. }
  314. ipd_ProcessIdentifyTimeChange();
  315. return ( events ^ IPD_IDENTIFY_TIMEOUT_EVT );
  316. }
  317. // event to get current time
  318. if ( events & IPD_UPDATE_TIME_EVT )
  319. {
  320. ipdTime = osal_getClock();
  321. osal_start_timerEx( ipdTaskID, IPD_UPDATE_TIME_EVT, IPD_UPDATE_TIME_PERIOD );
  322. return ( events ^ IPD_UPDATE_TIME_EVT );
  323. }
  324. // Discard unknown events
  325. return 0;
  326. }
  327. /*********************************************************************
  328. * @fn ipd_ProcessIdentifyTimeChange
  329. *
  330. * @brief Called to blink led for specified IdentifyTime attribute value
  331. *
  332. * @param none
  333. *
  334. * @return none
  335. */
  336. static void ipd_ProcessIdentifyTimeChange( void )
  337. {
  338. if ( ipdIdentifyTime > 0 )
  339. {
  340. osal_start_timerEx( ipdTaskID, IPD_IDENTIFY_TIMEOUT_EVT, 1000 );
  341. HalLedBlink ( HAL_LED_4, 0xFF, HAL_LED_DEFAULT_DUTY_CYCLE, HAL_LED_DEFAULT_FLASH_TIME );
  342. }
  343. else
  344. {
  345. HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
  346. osal_stop_timerEx( ipdTaskID, IPD_IDENTIFY_TIMEOUT_EVT );
  347. }
  348. }
  349. #if defined (ZCL_KEY_ESTABLISH)
  350. /*********************************************************************
  351. * @fn ipd_KeyEstablish_ReturnLinkKey
  352. *
  353. * @brief This function get the requested link key
  354. *
  355. * @param shortAddr - short address of the partner.
  356. *
  357. * @return none
  358. */
  359. static uint8 ipd_KeyEstablish_ReturnLinkKey( uint16 shortAddr )
  360. {
  361. APSME_LinkKeyData_t* keyData;
  362. uint8 status = ZFailure;
  363. AddrMgrEntry_t entry;
  364. // Look up the long address of the device
  365. entry.user = ADDRMGR_USER_DEFAULT;
  366. entry.nwkAddr = shortAddr;
  367. if ( AddrMgrEntryLookupNwk( &entry ) )
  368. {
  369. // check for APS link key data
  370. APSME_LinkKeyDataGet( entry.extAddr, &keyData );
  371. if ( (keyData != NULL) && (keyData->key != NULL) )
  372. {
  373. status = ZSuccess;
  374. }
  375. }
  376. else
  377. {
  378. // It's an unknown device
  379. status = ZInvalidParameter;
  380. }
  381. return status;
  382. }
  383. #endif // ZCL_KEY_ESTABLISH
  384. /*********************************************************************
  385. * @fn ipd_HandleKeys
  386. *
  387. * @brief Handles all key events for this device.
  388. *
  389. * @param shift - true if in shift/alt.
  390. * @param keys - bit field for key events. Valid entries:
  391. * HAL_KEY_SW_4
  392. * HAL_KEY_SW_3
  393. * HAL_KEY_SW_2
  394. * HAL_KEY_SW_1
  395. *
  396. * @return none
  397. */
  398. static void ipd_HandleKeys( uint8 shift, uint8 keys )
  399. {
  400. // Shift is used to make each button/switch dual purpose.
  401. if ( shift )
  402. {
  403. if ( keys & HAL_KEY_SW_1 )
  404. {
  405. }
  406. if ( keys & HAL_KEY_SW_2 )
  407. {
  408. }
  409. if ( keys & HAL_KEY_SW_3 )
  410. {
  411. }
  412. if ( keys & HAL_KEY_SW_4 )
  413. {
  414. }
  415. }
  416. else
  417. {
  418. if ( keys & HAL_KEY_SW_1 )
  419. {
  420. ZDOInitDevice(0); // join the network
  421. }
  422. if ( keys & HAL_KEY_SW_2 )
  423. {
  424. }
  425. if ( keys & HAL_KEY_SW_3 )
  426. {
  427. }
  428. if ( keys & HAL_KEY_SW_4 )
  429. {
  430. }
  431. }
  432. }
  433. /*********************************************************************
  434. * @fn ipd_ValidateAttrDataCB
  435. *
  436. * @brief Check to see if the supplied value for the attribute data
  437. * is within the specified range of the attribute.
  438. *
  439. * @param pAttr - pointer to attribute
  440. * @param pAttrInfo - pointer to attribute info
  441. *
  442. * @return TRUE if data valid. FALSE otherwise.
  443. */
  444. static uint8 ipd_ValidateAttrDataCB( zclAttrRec_t *pAttr, zclWriteRec_t *pAttrInfo )
  445. {
  446. uint8 valid = TRUE;
  447. switch ( pAttrInfo->dataType )
  448. {
  449. case ZCL_DATATYPE_BOOLEAN:
  450. if ( ( *(pAttrInfo->attrData) != 0 ) && ( *(pAttrInfo->attrData) != 1 ) )
  451. valid = FALSE;
  452. break;
  453. default:
  454. break;
  455. }
  456. return ( valid );
  457. }
  458. /*********************************************************************
  459. * @fn ipd_BasicResetCB
  460. *
  461. * @brief Callback from the ZCL General Cluster Library to set all
  462. * the attributes of all the clusters to their factory defaults
  463. *
  464. * @param none
  465. *
  466. * @return none
  467. */
  468. static void ipd_BasicResetCB( void )
  469. {
  470. // user should handle setting attributes to factory defaults here
  471. }
  472. /*********************************************************************
  473. * @fn ipd_IdentifyCB
  474. *
  475. * @brief Callback from the ZCL General Cluster Library when
  476. * it received an Identity Command for this application.
  477. *
  478. * @param pCmd - pointer to structure for identify command
  479. *
  480. * @return none
  481. */
  482. static void ipd_IdentifyCB( zclIdentify_t *pCmd )
  483. {
  484. ipdIdentifyTime = pCmd->identifyTime;
  485. ipd_ProcessIdentifyTimeChange();
  486. }
  487. /*********************************************************************
  488. * @fn ipd_IdentifyQueryRspCB
  489. *
  490. * @brief Callback from the ZCL General Cluster Library when
  491. * it received an Identity Query Response Command for this application.
  492. *
  493. * @param pRsp - pointer to structure for identify query response
  494. *
  495. * @return none
  496. */
  497. static void ipd_IdentifyQueryRspCB( zclIdentifyQueryRsp_t *pRsp )
  498. {
  499. // add user code here
  500. }
  501. /*********************************************************************
  502. * @fn ipd_AlarmCB
  503. *
  504. * @brief Callback from the ZCL General Cluster Library when
  505. * it received an Alarm request or response command for
  506. * this application.
  507. *
  508. * @param pAlarm - pointer to structure for alarm command
  509. *
  510. * @return none
  511. */
  512. static void ipd_AlarmCB( zclAlarm_t *pAlarm )
  513. {
  514. // add user code here
  515. }
  516. /*********************************************************************
  517. * @fn ipd_GetCurrentPriceCB
  518. *
  519. * @brief Callback from the ZCL SE Profile Pricing Cluster Library when
  520. * it received a Get Current Price for
  521. * this application.
  522. *
  523. * @param pCmd - pointer to structure for Get Current Price command
  524. * @param srcAddr - source address
  525. * @param seqNum - sequence number for this command
  526. *
  527. * @return none
  528. */
  529. static void ipd_GetCurrentPriceCB( zclCCGetCurrentPrice_t *pCmd,
  530. afAddrType_t *srcAddr, uint8 seqNum )
  531. {
  532. #if defined ( ZCL_PRICING )
  533. // On receipt of Get Current Price command, the device shall send a
  534. // Publish Price command with the information for the current time.
  535. zclCCPublishPrice_t cmd;
  536. osal_memset( &cmd, 0, sizeof( zclCCPublishPrice_t ) );
  537. cmd.providerId = 0xbabeface;
  538. cmd.priceTier = 0xfe;
  539. zclSE_Pricing_Send_PublishPrice( IPD_ENDPOINT, srcAddr, &cmd, false, seqNum );
  540. #endif // ZCL_PRICING
  541. }
  542. /*********************************************************************
  543. * @fn ipd_GetScheduledPriceCB
  544. *
  545. * @brief Callback from the ZCL SE Profile Pricing Cluster Library when
  546. * it received a Get Scheduled Price for
  547. * this application.
  548. *
  549. * @param pCmd - pointer to structure for Get Scheduled Price command
  550. * @param srcAddr - source address
  551. * @param seqNum - sequence number for this command
  552. *
  553. * @return none
  554. */
  555. static void ipd_GetScheduledPriceCB( zclCCGetScheduledPrice_t *pCmd, afAddrType_t *srcAddr, uint8 seqNum )
  556. {
  557. // On receipt of Get Scheduled Price command, the device shall send a
  558. // Publish Price command for all currently scheduled price events.
  559. // The sample code as follows only sends one.
  560. #if defined ( ZCL_PRICING )
  561. zclCCPublishPrice_t cmd;
  562. osal_memset( &cmd, 0, sizeof( zclCCPublishPrice_t ) );
  563. cmd.providerId = 0xbabeface;
  564. cmd.priceTier = 0xfe;
  565. zclSE_Pricing_Send_PublishPrice( IPD_ENDPOINT, srcAddr, &cmd, false, seqNum );
  566. #endif // ZCL_PRICING
  567. }
  568. /*********************************************************************
  569. * @fn ipd_PublishPriceCB
  570. *
  571. * @brief Callback from the ZCL SE Profile Pricing Cluster Library when
  572. * it received a Publish Price for this application.
  573. *
  574. * @param pCmd - pointer to structure for Publish Price command
  575. * @param srcAddr - source address
  576. * @param seqNum - sequence number for this command
  577. *
  578. * @return none
  579. */
  580. static void ipd_PublishPriceCB( zclCCPublishPrice_t *pCmd,
  581. afAddrType_t *srcAddr, uint8 seqNum )
  582. {
  583. if ( pCmd )
  584. {
  585. // display Provider ID field
  586. HalLcdWriteString("Provider ID", HAL_LCD_LINE_1);
  587. HalLcdWriteValue( pCmd->providerId, 10, HAL_LCD_LINE_2 );
  588. }
  589. }
  590. /*********************************************************************
  591. * @fn ipd_DisplayMessageCB
  592. *
  593. * @brief Callback from the ZCL SE Profile Message Cluster Library when
  594. * it received a Display Message Command for
  595. * this application.
  596. *
  597. * @param pCmd - pointer to structure for Display Message command
  598. * @param srcAddr - source address
  599. * @param seqNum - sequence number for this command
  600. *
  601. * @return none
  602. */
  603. static void ipd_DisplayMessageCB( zclCCDisplayMessage_t *pCmd,
  604. afAddrType_t *srcAddr, uint8 seqNum )
  605. {
  606. // Upon receipt of the Display Message Command, the device shall
  607. // display the message. If the Message Confirmation bit indicates
  608. // the message originator require a confirmation of receipt from
  609. // a Utility Customer, the device should display the message or
  610. // alert the user until it is either confirmed via a button or by
  611. // selecting a confirmation option on the device. Confirmation is
  612. // typically used when the Utility is sending down information
  613. // such as a disconnection notice, or prepaid billing information.
  614. // Message duration is ignored when confirmation is requested and
  615. // the message is displayed until confirmed.
  616. #if defined ( LCD_SUPPORTED )
  617. HalLcdWriteString( (char*)pCmd->msgString.pStr, HAL_LCD_LINE_3 );
  618. #endif // LCD_SUPPORTED
  619. }
  620. /*********************************************************************
  621. * @fn ipd_CancelMessageCB
  622. *
  623. * @brief Callback from the ZCL SE Profile Message Cluster Library when
  624. * it received a Cancel Message Command for
  625. * this application.
  626. *
  627. * @param pCmd - pointer to structure for Cancel Message command
  628. * @param srcAddr - source address
  629. * @param seqNum - sequence number for this command
  630. *
  631. * @return none
  632. */
  633. static void ipd_CancelMessageCB( zclCCCancelMessage_t *pCmd,
  634. afAddrType_t *srcAddr, uint8 seqNum )
  635. {
  636. // add user code here
  637. }
  638. /*********************************************************************
  639. * @fn ipd_GetLastMessageCB
  640. *
  641. * @brief Callback from the ZCL SE Profile Message Cluster Library when
  642. * it received a Get Last Message Command for
  643. * this application.
  644. *
  645. * @param pCmd - pointer to structure for Get Last Message command
  646. * @param srcAddr - source address
  647. * @param seqNum - sequence number for this command
  648. *
  649. * @return none
  650. */
  651. static void ipd_GetLastMessageCB( afAddrType_t *srcAddr, uint8 seqNum )
  652. {
  653. // On receipt of Get Last Message command, the device shall send a
  654. // Display Message command back to the sender
  655. #if defined ( ZCL_MESSAGE )
  656. zclCCDisplayMessage_t cmd;
  657. uint8 msg[10] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29 };
  658. // Fill in the command with information for the last message
  659. cmd.messageId = 0xaabbccdd;
  660. cmd.messageCtrl.transmissionMode = 0;
  661. cmd.messageCtrl.importance = 1;
  662. cmd.messageCtrl.confirmationRequired = 1;
  663. cmd.durationInMinutes = 60;
  664. cmd.msgString.strLen = 10;
  665. cmd.msgString.pStr = msg;
  666. zclSE_Message_Send_DisplayMessage( IPD_ENDPOINT, srcAddr, &cmd,
  667. false, seqNum );
  668. #endif // ZCL_MESSAGE
  669. }
  670. /*********************************************************************
  671. * @fn ipd_MessageConfirmationCB
  672. *
  673. * @brief Callback from the ZCL SE Profile Message Cluster Library when
  674. * it received a Message Confirmation Command for
  675. * this application.
  676. *
  677. * @param pCmd - pointer to structure for Message Confirmation command
  678. * @param srcAddr - source address
  679. * @param seqNum - sequence number for this command
  680. *
  681. * @return none
  682. */
  683. static void ipd_MessageConfirmationCB( zclCCMessageConfirmation_t *pCmd,
  684. afAddrType_t *srcAddr, uint8 seqNum)
  685. {
  686. // add user code here
  687. }
  688. /******************************************************************************
  689. *
  690. * Functions for processing ZCL Foundation incoming Command/Response messages
  691. *
  692. *****************************************************************************/
  693. /*********************************************************************
  694. * @fn ipd_ProcessZCLMsg
  695. *
  696. * @brief Process ZCL Foundation incoming message
  697. *
  698. * @param pInMsg - message to process
  699. *
  700. * @return none
  701. */
  702. static void ipd_ProcessZCLMsg( zclIncomingMsg_t *pInMsg )
  703. {
  704. switch ( pInMsg->zclHdr.commandID )
  705. {
  706. #if defined ( ZCL_READ )
  707. case ZCL_CMD_READ_RSP:
  708. ipd_ProcessInReadRspCmd( pInMsg );
  709. break;
  710. #endif // ZCL_READ
  711. #if defined ( ZCL_WRITE )
  712. case ZCL_CMD_WRITE_RSP:
  713. ipd_ProcessInWriteRspCmd( pInMsg );
  714. break;
  715. #endif // ZCL_WRITE
  716. case ZCL_CMD_DEFAULT_RSP:
  717. ipd_ProcessInDefaultRspCmd( pInMsg );
  718. break;
  719. #if defined ( ZCL_DISCOVER )
  720. case ZCL_CMD_DISCOVER_RSP:
  721. ipd_ProcessInDiscRspCmd( pInMsg );
  722. break;
  723. #endif // ZCL_DISCOVER
  724. default:
  725. break;
  726. }
  727. if ( pInMsg->attrCmd != NULL )
  728. {
  729. // free the parsed command
  730. osal_mem_free( pInMsg->attrCmd );
  731. pInMsg->attrCmd = NULL;
  732. }
  733. }
  734. #if defined ( ZCL_READ )
  735. /*********************************************************************
  736. * @fn ipd_ProcessInReadRspCmd
  737. *
  738. * @brief Process the "Profile" Read Response Command
  739. *
  740. * @param pInMsg - incoming message to process
  741. *
  742. * @return none
  743. */
  744. static uint8 ipd_ProcessInReadRspCmd( zclIncomingMsg_t *pInMsg )
  745. {
  746. zclReadRspCmd_t *readRspCmd;
  747. uint8 i;
  748. readRspCmd = (zclReadRspCmd_t *)pInMsg->attrCmd;
  749. for (i = 0; i < readRspCmd->numAttr; i++)
  750. {
  751. // Notify the originator of the results of the original read attributes
  752. // attempt and, for each successfull request, the value of the requested
  753. // attribute
  754. }
  755. return TRUE;
  756. }
  757. #endif // ZCL_READ
  758. #if defined ( ZCL_WRITE )
  759. /*********************************************************************
  760. * @fn ipd_ProcessInWriteRspCmd
  761. *
  762. * @brief Process the "Profile" Write Response Command
  763. *
  764. * @param pInMsg - incoming message to process
  765. *
  766. * @return none
  767. */
  768. static uint8 ipd_ProcessInWriteRspCmd( zclIncomingMsg_t *pInMsg )
  769. {
  770. zclWriteRspCmd_t *writeRspCmd;
  771. uint8 i;
  772. writeRspCmd = (zclWriteRspCmd_t *)pInMsg->attrCmd;
  773. for (i = 0; i < writeRspCmd->numAttr; i++)
  774. {
  775. // Notify the device of the results of the its original write attributes
  776. // command.
  777. }
  778. return TRUE;
  779. }
  780. #endif // ZCL_WRITE
  781. /*********************************************************************
  782. * @fn ipd_ProcessInDefaultRspCmd
  783. *
  784. * @brief Process the "Profile" Default Response Command
  785. *
  786. * @param pInMsg - incoming message to process
  787. *
  788. * @return none
  789. */
  790. static uint8 ipd_ProcessInDefaultRspCmd( zclIncomingMsg_t *pInMsg )
  791. {
  792. // zclDefaultRspCmd_t *defaultRspCmd = (zclDefaultRspCmd_t *)pInMsg->attrCmd;
  793. // Device is notified of the Default Response command.
  794. return TRUE;
  795. }
  796. #if defined ( ZCL_DISCOVER )
  797. /*********************************************************************
  798. * @fn ipd_ProcessInDiscRspCmd
  799. *
  800. * @brief Process the "Profile" Discover Response Command
  801. *
  802. * @param pInMsg - incoming message to process
  803. *
  804. * @return none
  805. */
  806. static uint8 ipd_ProcessInDiscRspCmd( zclIncomingMsg_t *pInMsg )
  807. {
  808. zclDiscoverRspCmd_t *discoverRspCmd;
  809. uint8 i;
  810. discoverRspCmd = (zclDiscoverRspCmd_t *)pInMsg->attrCmd;
  811. for ( i = 0; i < discoverRspCmd->numAttr; i++ )
  812. {
  813. // Device is notified of the result of its attribute discovery command.
  814. }
  815. return TRUE;
  816. }
  817. #endif // ZCL_DISCOVER
  818. /****************************************************************************
  819. ****************************************************************************/