loadcontrol.c 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972
  1. /**************************************************************************************************
  2. Filename: loadcontrol.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 Load Control Device functionality
  6. and 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 Load Control configuration:
  37. General Basic
  38. General Alarms
  39. General Time
  40. General Key Establishment
  41. SE Demand Response and Load Control
  42. Key control:
  43. SW1: Join Network
  44. SW2: N/A
  45. SW3: N/A
  46. SW4: N/A
  47. *********************************************************************/
  48. /*********************************************************************
  49. * INCLUDES
  50. */
  51. #include "OSAL.h"
  52. #include "OSAL_Clock.h"
  53. #include "ZDApp.h"
  54. #include "AddrMgr.h"
  55. #include "se.h"
  56. #include "loadcontrol.h"
  57. #include "zcl_general.h"
  58. #include "zcl_se.h"
  59. #include "zcl_key_establish.h"
  60. #include "onboard.h"
  61. /* HAL */
  62. #include "hal_lcd.h"
  63. #include "hal_led.h"
  64. #include "hal_key.h"
  65. /*********************************************************************
  66. * MACROS
  67. */
  68. // There is no attribute in the Mandatory Reportable Attribute list for now
  69. #define zcl_MandatoryReportableAttribute( a ) ( a == NULL )
  70. /*********************************************************************
  71. * CONSTANTS
  72. */
  73. /*********************************************************************
  74. * TYPEDEFS
  75. */
  76. /*********************************************************************
  77. * GLOBAL VARIABLES
  78. */
  79. /*********************************************************************
  80. * GLOBAL FUNCTIONS
  81. */
  82. /*********************************************************************
  83. * LOCAL VARIABLES
  84. */
  85. static uint8 loadControlTaskID; // osal task id for load control device
  86. static devStates_t loadControlNwkState; // network state variable
  87. static uint8 loadControlTransID; // transaction id
  88. static afAddrType_t ESPAddr; // ESP destination address
  89. static uint8 linkKeyStatus; // status variable from get link key function
  90. static zclCCReportEventStatus_t rsp; // structure for report event status
  91. /*********************************************************************
  92. * LOCAL FUNCTIONS
  93. */
  94. static void loadcontrol_HandleKeys( uint8 shift, uint8 keys );
  95. #if defined (ZCL_KEY_ESTABLISH)
  96. static uint8 loadcontrol_KeyEstablish_ReturnLinkKey( uint16 shortAddr );
  97. #endif // ZCL_KEY_ESTABLISH
  98. #if defined ( ZCL_ALARMS )
  99. static void loadcontrol_ProcessAlarmCmd( uint8 srcEP, afAddrType_t *dstAddr,
  100. uint16 clusterID, zclFrameHdr_t *hdr, uint8 len, uint8 *data );
  101. #endif // ZCL_ALARMS
  102. static void loadcontrol_ProcessIdentifyTimeChange( void );
  103. /*************************************************************************/
  104. /*** Application Callback Functions ***/
  105. /*************************************************************************/
  106. // Foundation Callback functions
  107. static uint8 loadcontrol_ValidateAttrDataCB( zclAttrRec_t *pAttr, zclWriteRec_t *pAttrInfo );
  108. // General Cluster Callback functions
  109. static void loadcontrol_BasicResetCB( void );
  110. static void loadcontrol_IdentifyCB( zclIdentify_t *pCmd );
  111. static void loadcontrol_IdentifyQueryRspCB( zclIdentifyQueryRsp_t *pRsp );
  112. static void loadcontrol_AlarmCB( zclAlarm_t *pAlarm );
  113. // SE Callback functions
  114. static void loadcontrol_LoadControlEventCB( zclCCLoadControlEvent_t *pCmd,
  115. afAddrType_t *srcAddr, uint8 status, uint8 seqNum);
  116. static void loadcontrol_CancelLoadControlEventCB( zclCCCancelLoadControlEvent_t *pCmd,
  117. afAddrType_t *srcAddr, uint8 seqNum );
  118. static void loadcontrol_CancelAllLoadControlEventsCB( zclCCCancelAllLoadControlEvents_t *pCmd,
  119. afAddrType_t *srcAddr, uint8 seqNum);
  120. static void loadcontrol_ReportEventStatusCB( zclCCReportEventStatus_t *pCmd,
  121. afAddrType_t *srcAddr, uint8 seqNum );
  122. static void loadcontrol_GetScheduledEventCB( zclCCGetScheduledEvent_t *pCmd,
  123. afAddrType_t *srcAddr, uint8 seqNum);
  124. /************************************************************************/
  125. /*** Functions to process ZCL Foundation ***/
  126. /*** incoming Command/Response messages ***/
  127. /************************************************************************/
  128. static void loadcontrol_ProcessZCLMsg( zclIncomingMsg_t *msg );
  129. #if defined ( ZCL_READ )
  130. static uint8 loadcontrol_ProcessInReadRspCmd( zclIncomingMsg_t *pInMsg );
  131. #endif // ZCL_READ
  132. #if defined ( ZCL_WRITE )
  133. static uint8 loadcontrol_ProcessInWriteRspCmd( zclIncomingMsg_t *pInMsg );
  134. #endif // ZCL_WRITE
  135. static uint8 loadcontrol_ProcessInDefaultRspCmd( zclIncomingMsg_t *pInMsg );
  136. #if defined ( ZCL_DISCOVER )
  137. static uint8 loadcontrol_ProcessInDiscRspCmd( zclIncomingMsg_t *pInMsg );
  138. #endif // ZCL_DISCOVER
  139. /*********************************************************************
  140. * ZCL General Clusters Callback table
  141. */
  142. static zclGeneral_AppCallbacks_t loadcontrol_GenCmdCallbacks =
  143. {
  144. loadcontrol_BasicResetCB, // Basic Cluster Reset command
  145. loadcontrol_IdentifyCB, // Identify command
  146. loadcontrol_IdentifyQueryRspCB, // Identify Query Response command
  147. NULL, // On/Off cluster commands
  148. NULL, // Level Control Move to Level command
  149. NULL, // Level Control Move command
  150. NULL, // Level Control Step command
  151. NULL, // Level Control Stop command
  152. NULL, // Group Response commands
  153. NULL, // Scene Store Request command
  154. NULL, // Scene Recall Request command
  155. NULL, // Scene Response command
  156. loadcontrol_AlarmCB, // Alarm (Response) command
  157. NULL, // RSSI Location command
  158. NULL, // RSSI Location Response command
  159. };
  160. /*********************************************************************
  161. * ZCL SE Clusters Callback table
  162. */
  163. static zclSE_AppCallbacks_t loadcontrol_SECmdCallbacks =
  164. {
  165. NULL, // Get Profile Command
  166. NULL, // Get Profile Response
  167. NULL, // Request Mirror Command
  168. NULL, // Request Mirror Response
  169. NULL, // Mirror Remove Command
  170. NULL, // Mirror Remove Response
  171. NULL, // Get Current Price
  172. NULL, // Get Scheduled Price
  173. NULL, // Publish Price
  174. NULL, // Display Message Command
  175. NULL, // Cancel Message Command
  176. NULL, // Get Last Message Command
  177. NULL, // Message Confirmation
  178. loadcontrol_LoadControlEventCB, // Load Control Event
  179. loadcontrol_CancelLoadControlEventCB, // Cancel Load Control Event
  180. loadcontrol_CancelAllLoadControlEventsCB, // Cancel All Load Control Events
  181. loadcontrol_ReportEventStatusCB, // Report Event Status
  182. loadcontrol_GetScheduledEventCB, // Get Scheduled Event
  183. };
  184. /*********************************************************************
  185. * @fn loadcontrol_Init
  186. *
  187. * @brief Initialization function for the ZCL App Application.
  188. *
  189. * @param uint8 task_id - load control task id
  190. *
  191. * @return none
  192. */
  193. void loadcontrol_Init( uint8 task_id )
  194. {
  195. loadControlTaskID = task_id;
  196. // setup destination address for ESP
  197. ESPAddr.addrMode = (afAddrMode_t)Addr16Bit;
  198. ESPAddr.endPoint = LOADCONTROL_ENDPOINT;
  199. ESPAddr.addr.shortAddr = 0;
  200. // register for SE endpoint
  201. zclSE_Init( &loadControlSimpleDesc );
  202. // Register the ZCL General Cluster Library callback functions
  203. zclGeneral_RegisterCmdCallbacks( LOADCONTROL_ENDPOINT, &loadcontrol_GenCmdCallbacks );
  204. // Register the ZCL SE Cluster Library callback functions
  205. zclSE_RegisterCmdCallbacks( LOADCONTROL_ENDPOINT, &loadcontrol_SECmdCallbacks );
  206. // Register the application's attribute list
  207. zcl_registerAttrList( LOADCONTROL_ENDPOINT, LOADCONTROL_MAX_ATTRIBUTES, loadControlAttrs );
  208. // Register the application's cluster option list
  209. zcl_registerClusterOptionList( LOADCONTROL_ENDPOINT, LOADCONTROL_MAX_OPTIONS, loadControlOptions );
  210. // Register the application's attribute data validation callback function
  211. zcl_registerValidateAttrData( loadcontrol_ValidateAttrDataCB );
  212. // Register the Application to receive the unprocessed Foundation command/response messages
  213. zcl_registerForMsg( loadControlTaskID );
  214. // Register for all key events - This app will handle all key events
  215. RegisterForKeys( loadControlTaskID );
  216. // Start the timer to sync LoadControl timer with the osal timer
  217. osal_start_timerEx( loadControlTaskID, LOADCONTROL_UPDATE_TIME_EVT, LOADCONTROL_UPDATE_TIME_PERIOD );
  218. }
  219. /*********************************************************************
  220. * @fn loadcontrol_event_loop
  221. *
  222. * @brief Event Loop Processor for loadcontrol.
  223. *
  224. * @param uint8 task id - load control task id
  225. * @param uint16 events - event bitmask
  226. *
  227. * @return none
  228. */
  229. uint16 loadcontrol_event_loop( uint8 task_id, uint16 events )
  230. {
  231. afIncomingMSGPacket_t *MSGpkt;
  232. if ( events & SYS_EVENT_MSG )
  233. {
  234. while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( loadControlTaskID )) )
  235. {
  236. switch ( MSGpkt->hdr.event )
  237. {
  238. case ZCL_INCOMING_MSG:
  239. // Incoming ZCL foundation command/response messages
  240. loadcontrol_ProcessZCLMsg( (zclIncomingMsg_t *)MSGpkt );
  241. break;
  242. case KEY_CHANGE:
  243. loadcontrol_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );
  244. break;
  245. case ZDO_STATE_CHANGE:
  246. loadControlNwkState = (devStates_t)(MSGpkt->hdr.status);
  247. if (ZG_SECURE_ENABLED)
  248. {
  249. if ( loadControlNwkState == DEV_ROUTER )
  250. {
  251. // check to see if link key had already been established
  252. linkKeyStatus = loadcontrol_KeyEstablish_ReturnLinkKey(ESPAddr.addr.shortAddr);
  253. if (linkKeyStatus != ZSuccess)
  254. {
  255. // send out key establishment request
  256. osal_set_event( loadControlTaskID, LOADCONTROL_KEY_ESTABLISHMENT_REQUEST_EVT);
  257. }
  258. }
  259. }
  260. break;
  261. default:
  262. break;
  263. }
  264. // Release the memory
  265. osal_msg_deallocate( (uint8 *)MSGpkt );
  266. }
  267. // return unprocessed events
  268. return (events ^ SYS_EVENT_MSG);
  269. }
  270. // event to intiate key establishment request
  271. if ( events & LOADCONTROL_KEY_ESTABLISHMENT_REQUEST_EVT )
  272. {
  273. zclGeneral_KeyEstablish_InitiateKeyEstablishment(loadControlTaskID, &ESPAddr, loadControlTransID);
  274. return ( events ^ LOADCONTROL_KEY_ESTABLISHMENT_REQUEST_EVT );
  275. }
  276. // handle processing of identify timeout event triggered by an identify command
  277. if ( events & LOADCONTROL_IDENTIFY_TIMEOUT_EVT )
  278. {
  279. if ( loadControlIdentifyTime > 0 )
  280. {
  281. loadControlIdentifyTime--;
  282. }
  283. loadcontrol_ProcessIdentifyTimeChange();
  284. return ( events ^ LOADCONTROL_IDENTIFY_TIMEOUT_EVT );
  285. }
  286. // event to get current time
  287. if ( events & LOADCONTROL_UPDATE_TIME_EVT )
  288. {
  289. loadControlTime = osal_getClock();
  290. osal_start_timerEx( loadControlTaskID, LOADCONTROL_UPDATE_TIME_EVT, LOADCONTROL_UPDATE_TIME_PERIOD );
  291. return ( events ^ LOADCONTROL_UPDATE_TIME_EVT );
  292. }
  293. // event to handle load control complete event
  294. if ( events & LOADCONTROL_LOAD_CTRL_EVT )
  295. {
  296. // load control evt completed
  297. // Send response back
  298. // DisableDefaultResponse is set to false - it is recommended to turn on
  299. // default response since Report Event Status Command does not have
  300. // a response.
  301. rsp.eventStatus = EVENT_STATUS_LOAD_CONTROL_EVENT_COMPLETED;
  302. zclSE_LoadControl_Send_ReportEventStatus( LOADCONTROL_ENDPOINT, &ESPAddr,
  303. &rsp, false, loadControlTransID );
  304. HalLcdWriteString("Load Evt Complete", HAL_LCD_LINE_3);
  305. HalLedSet(HAL_LED_4, HAL_LED_MODE_OFF);
  306. return ( events ^ LOADCONTROL_LOAD_CTRL_EVT );
  307. }
  308. // Discard unknown events
  309. return 0;
  310. }
  311. /*********************************************************************
  312. * @fn loadcontrol_ProcessIdentifyTimeChange
  313. *
  314. * @brief Called to blink led for specified IdentifyTime attribute value
  315. *
  316. * @param none
  317. *
  318. * @return none
  319. */
  320. static void loadcontrol_ProcessIdentifyTimeChange( void )
  321. {
  322. if ( loadControlIdentifyTime > 0 )
  323. {
  324. osal_start_timerEx( loadControlTaskID, LOADCONTROL_IDENTIFY_TIMEOUT_EVT, 1000 );
  325. HalLedBlink ( HAL_LED_4, 0xFF, HAL_LED_DEFAULT_DUTY_CYCLE, HAL_LED_DEFAULT_FLASH_TIME );
  326. }
  327. else
  328. {
  329. HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
  330. osal_stop_timerEx( loadControlTaskID, LOADCONTROL_IDENTIFY_TIMEOUT_EVT );
  331. }
  332. }
  333. #if defined (ZCL_KEY_ESTABLISH)
  334. /*********************************************************************
  335. * @fn loadcontrol_KeyEstablish_ReturnLinkKey
  336. *
  337. * @brief This function get the requested link key
  338. *
  339. * @param shortAddr - short address of the partner.
  340. *
  341. * @return none
  342. */
  343. static uint8 loadcontrol_KeyEstablish_ReturnLinkKey( uint16 shortAddr )
  344. {
  345. APSME_LinkKeyData_t* keyData;
  346. uint8 status = ZFailure;
  347. AddrMgrEntry_t entry;
  348. // Look up the long address of the device
  349. entry.user = ADDRMGR_USER_DEFAULT;
  350. entry.nwkAddr = shortAddr;
  351. if ( AddrMgrEntryLookupNwk( &entry ) )
  352. {
  353. // check for APS link key data
  354. APSME_LinkKeyDataGet( entry.extAddr, &keyData );
  355. if ( (keyData != NULL) && (keyData->key != NULL) )
  356. {
  357. status = ZSuccess;
  358. }
  359. }
  360. else
  361. {
  362. // It's an unknown device
  363. status = ZInvalidParameter;
  364. }
  365. return status;
  366. }
  367. #endif // ZCL_KEY_ESTABLISH
  368. /*********************************************************************
  369. * @fn loadcontrol_HandleKeys
  370. *
  371. * @brief Handles all key events for this device.
  372. *
  373. * @param shift - true if in shift/alt.
  374. * @param keys - bit field for key events. Valid entries:
  375. * HAL_KEY_SW_4
  376. * HAL_KEY_SW_3
  377. * HAL_KEY_SW_2
  378. * HAL_KEY_SW_1
  379. *
  380. * @return none
  381. */
  382. static void loadcontrol_HandleKeys( uint8 shift, uint8 keys )
  383. {
  384. // Shift is used to make each button/switch dual purpose.
  385. if ( shift )
  386. {
  387. if ( keys & HAL_KEY_SW_1 )
  388. {
  389. }
  390. if ( keys & HAL_KEY_SW_2 )
  391. {
  392. }
  393. if ( keys & HAL_KEY_SW_3 )
  394. {
  395. }
  396. if ( keys & HAL_KEY_SW_4 )
  397. {
  398. }
  399. }
  400. else
  401. {
  402. if ( keys & HAL_KEY_SW_1 )
  403. {
  404. ZDOInitDevice(0); // join the network
  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. }
  417. /*********************************************************************
  418. * @fn loadcontrol_ValidateAttrDataCB
  419. *
  420. * @brief Check to see if the supplied value for the attribute data
  421. * is within the specified range of the attribute.
  422. *
  423. * @param pAttr - pointer to attribute
  424. * @param pAttrInfo - pointer to attribute info
  425. *
  426. * @return TRUE if data valid. FALSE otherwise.
  427. */
  428. static uint8 loadcontrol_ValidateAttrDataCB( zclAttrRec_t *pAttr, zclWriteRec_t *pAttrInfo )
  429. {
  430. uint8 valid = TRUE;
  431. switch ( pAttrInfo->dataType )
  432. {
  433. case ZCL_DATATYPE_BOOLEAN:
  434. if ( ( *(pAttrInfo->attrData) != 0 ) && ( *(pAttrInfo->attrData) != 1 ) )
  435. valid = FALSE;
  436. break;
  437. default:
  438. break;
  439. }
  440. return ( valid );
  441. }
  442. /*********************************************************************
  443. * @fn loadcontrol_BasicResetCB
  444. *
  445. * @brief Callback from the ZCL General Cluster Library to set all
  446. * the attributes of all the clusters to their factory defaults
  447. *
  448. * @param none
  449. *
  450. * @return none
  451. */
  452. static void loadcontrol_BasicResetCB( void )
  453. {
  454. // user should handle setting attributes to factory defaults here
  455. }
  456. /*********************************************************************
  457. * @fn loadcontrol_IdentifyCB
  458. *
  459. * @brief Callback from the ZCL General Cluster Library when
  460. * it received an Identity Command for this application.
  461. *
  462. * @param pCmd - pointer to structure for identify command
  463. *
  464. * @return none
  465. */
  466. static void loadcontrol_IdentifyCB( zclIdentify_t *pCmd )
  467. {
  468. loadControlIdentifyTime = pCmd->identifyTime;
  469. loadcontrol_ProcessIdentifyTimeChange();
  470. }
  471. /*********************************************************************
  472. * @fn loadcontrol_IdentifyQueryRspCB
  473. *
  474. * @brief Callback from the ZCL General Cluster Library when
  475. * it received an Identity Query Response Command for this application.
  476. *
  477. * @param pRsp - pointer to structure for identify query response
  478. *
  479. * @return none
  480. */
  481. static void loadcontrol_IdentifyQueryRspCB( zclIdentifyQueryRsp_t *pRsp )
  482. {
  483. // add user code here
  484. }
  485. /*********************************************************************
  486. * @fn loadcontrol_AlarmCB
  487. *
  488. * @brief Callback from the ZCL General Cluster Library when
  489. * it received an Alarm request or response command for
  490. * this application.
  491. *
  492. * @param pAlarm - pointer to structure for alarm command
  493. *
  494. * @return none
  495. */
  496. static void loadcontrol_AlarmCB( zclAlarm_t *pAlarm )
  497. {
  498. // add user code here
  499. }
  500. #if defined (ZCL_LOAD_CONTROL)
  501. /*********************************************************************
  502. * @fn loadcontrol_SendReportEventStatus
  503. *
  504. * @brief Callback from the ZCL SE Profile Message Cluster Library when
  505. * it received a Load Control Event Command for
  506. * this application.
  507. *
  508. * @param afAddrType_t *srcAddr - pointer to source address
  509. * @param uint8 seqNum - sequence number for this event
  510. * @param uint32 eventID - event ID for this event
  511. * @param uint32 startTime - start time for this event
  512. * @param uint8 eventStatus - status for this event
  513. * @param uint8 criticalityLevel - criticality level for this event
  514. * @param uint8 eventControl - event control for this event
  515. *
  516. * @return none
  517. */
  518. static void loadcontrol_SendReportEventStatus( afAddrType_t *srcAddr, uint8 seqNum,
  519. uint32 eventID, uint32 startTime,
  520. uint8 eventStatus, uint8 criticalityLevel,
  521. uint8 eventControl )
  522. {
  523. // Mandatory fields - use the incoming data
  524. rsp.issuerEventID = eventID;
  525. rsp.eventStartTime = startTime;
  526. rsp.criticalityLevelApplied = criticalityLevel;
  527. rsp.eventControl = eventControl;
  528. rsp.eventStatus = eventStatus;
  529. rsp.signatureType = SE_PROFILE_SIGNATURE_TYPE_ECDSA;
  530. // loadcontrol_Signature is a static array.
  531. // value can be changed in loadcontrol_data.c
  532. osal_memcpy( rsp.signature, loadControlSignature, SE_PROFILE_SIGNATURE_LENGTH );
  533. // Optional fields - fill in with non-used value by default
  534. rsp.coolingTemperatureSetPointApplied = SE_OPTIONAL_FIELD_TEMPERATURE_SET_POINT;
  535. rsp.heatingTemperatureSetPointApplied = SE_OPTIONAL_FIELD_TEMPERATURE_SET_POINT;
  536. rsp.averageLoadAdjustment = SE_OPTIONAL_FIELD_INT8;
  537. rsp.dutyCycleApplied = SE_OPTIONAL_FIELD_UINT8;
  538. // Send response back
  539. // DisableDefaultResponse is set to false - it is recommended to turn on
  540. // default response since Report Event Status Command does not have
  541. // a response.
  542. zclSE_LoadControl_Send_ReportEventStatus( LOADCONTROL_ENDPOINT, srcAddr,
  543. &rsp, false, seqNum );
  544. }
  545. #endif // ZCL_LOAD_CONTROL
  546. /*********************************************************************
  547. * @fn loadcontrol_LoadControlEventCB
  548. *
  549. * @brief Callback from the ZCL SE Profile Load Control Cluster Library when
  550. * it received a Load Control Event Command for
  551. * this application.
  552. *
  553. * @param pCmd - pointer to load control event command
  554. * @param srcAddr - source address
  555. * @param status - event status
  556. * @param seqNum - sequence number of this command
  557. *
  558. * @return none
  559. */
  560. static void loadcontrol_LoadControlEventCB( zclCCLoadControlEvent_t *pCmd,
  561. afAddrType_t *srcAddr, uint8 status,
  562. uint8 seqNum)
  563. {
  564. #if defined ( ZCL_LOAD_CONTROL )
  565. // According to the Smart Metering Specification, upon receipt
  566. // of the Load Control Event command, the receiving device shall
  567. // send Report Event Status command back.
  568. uint8 eventStatus;
  569. if ( status == ZCL_STATUS_INVALID_FIELD )
  570. {
  571. // If the incoming message has invalid fields in it
  572. // Send response back with status: rejected
  573. eventStatus = EVENT_STATUS_LOAD_CONTROL_EVENT_REJECTED;
  574. }
  575. else
  576. { // Send response back with status: received
  577. eventStatus = EVENT_STATUS_LOAD_CONTROL_EVENT_RECEIVED;
  578. }
  579. // Send response back
  580. loadcontrol_SendReportEventStatus( srcAddr, seqNum, pCmd->issuerEvent,
  581. pCmd->startTime, eventStatus,
  582. pCmd->criticalityLevel, pCmd->eventControl);
  583. if ( status != ZCL_STATUS_INVALID_FIELD )
  584. {
  585. // Start the Load Control Event
  586. if ( pCmd->issuerEvent == LOADCONTROL_EVENT_ID )
  587. {
  588. if ( pCmd->startTime == START_TIME_NOW ) // start time = NOW
  589. {
  590. // send back status event = load control event started
  591. eventStatus = EVENT_STATUS_LOAD_CONTROL_EVENT_STARTED;
  592. loadcontrol_SendReportEventStatus( srcAddr, seqNum, pCmd->issuerEvent,
  593. pCmd->startTime, eventStatus,
  594. pCmd->criticalityLevel, pCmd->eventControl);
  595. if ( pCmd->deviceGroupClass == ONOFF_LOAD_DEVICE_CLASS ) // is this one for residential on/off load?
  596. {
  597. HalLcdWriteString("Load Evt Started", HAL_LCD_LINE_3);
  598. }
  599. else if ( pCmd->deviceGroupClass == HVAC_DEVICE_CLASS ) // is this one for HVAC compressor/furnace?
  600. {
  601. HalLcdWriteString("PCT Evt Started", HAL_LCD_LINE_3);
  602. }
  603. HalLedBlink ( HAL_LED_4, 0, 50, 500 );
  604. osal_start_timerEx( loadControlTaskID, LOADCONTROL_LOAD_CTRL_EVT,
  605. (LOADCONTROL_LOAD_CTRL_PERIOD * (pCmd->durationInMinutes)) );
  606. }
  607. }
  608. }
  609. #endif // ZCL_LOAD_CONTROL
  610. }
  611. /*********************************************************************
  612. * @fn loadcontrol_CancelLoadControlEventCB
  613. *
  614. * @brief Callback from the ZCL SE Profile Load Control Cluster Library when
  615. * it received a Cancel Load Control Event Command for
  616. * this application.
  617. *
  618. * @param pCmd - pointer to structure for Cancel Load Control Event command
  619. * @param scrAddr - source address
  620. * @param seqNum - sequence number for this command
  621. *
  622. * @return none
  623. */
  624. static void loadcontrol_CancelLoadControlEventCB( zclCCCancelLoadControlEvent_t *pCmd,
  625. afAddrType_t *srcAddr, uint8 seqNum )
  626. {
  627. #if defined ( ZCL_LOAD_CONTROL )
  628. if ( 0 ) // User shall replace the if condition with "if the event exist"
  629. {
  630. // If the event exist, stop the event, and respond with status: cancelled
  631. // Cancel the event here
  632. // Use the following sample code to send response back.
  633. /*
  634. loadcontrol_SendReportEventStatus( srcAddr, seqNum, pCmd->issuerEventID,
  635. // startTime
  636. EVENT_STATUS_LOAD_CONTROL_EVENT_CANCELLED, // eventStatus
  637. // Criticality level
  638. // eventControl };
  639. */
  640. }
  641. else
  642. {
  643. // If the event does not exist, respond with status: rejected
  644. // The rest of the mandatory fields are not available, therefore,
  645. // set to optional value
  646. loadcontrol_SendReportEventStatus( srcAddr, seqNum, pCmd->issuerEventID,
  647. SE_OPTIONAL_FIELD_UINT32, // startTime
  648. EVENT_STATUS_LOAD_CONTROL_EVENT_RECEIVED, // eventStatus
  649. SE_OPTIONAL_FIELD_UINT8, // Criticality level
  650. SE_OPTIONAL_FIELD_UINT8 ); // eventControl
  651. }
  652. #endif // ZCL_LOAD_CONTROL
  653. }
  654. /*********************************************************************
  655. * @fn loadcontrol_CancelAllLoadControlEventsCB
  656. *
  657. * @brief Callback from the ZCL SE Profile Load Control Cluster Library when
  658. * it received a Cancel All Load Control Event Command for
  659. * this application.
  660. *
  661. * @param pCmd - pointer to structure for Cancel All Load Control Event command
  662. * @param scrAddr - source address
  663. * @param seqNum - sequence number for this command
  664. *
  665. * @return none
  666. */
  667. static void loadcontrol_CancelAllLoadControlEventsCB( zclCCCancelAllLoadControlEvents_t *pCmd,
  668. afAddrType_t *srcAddr, uint8 seqNum )
  669. {
  670. // Upon receipt of Cancel All Load Control Event Command,
  671. // the receiving device shall look up the table for all events
  672. // and send a seperate response for each event
  673. }
  674. /*********************************************************************
  675. * @fn loadcontrol_ReportEventStatusCB
  676. *
  677. * @brief Callback from the ZCL SE Profile Load Control Cluster Library when
  678. * it received a Report Event Status Command for
  679. * this application.
  680. *
  681. * @param pCmd - pointer to structure for Report Event Status command
  682. * @param scrAddr - source address
  683. * @param seqNum - sequence number for this command
  684. *
  685. * @return none
  686. */
  687. static void loadcontrol_ReportEventStatusCB( zclCCReportEventStatus_t *pCmd,
  688. afAddrType_t *srcAddr, uint8 seqNum)
  689. {
  690. // add user code here
  691. }
  692. /*********************************************************************
  693. * @fn loadcontrol_GetScheduledEventCB
  694. *
  695. * @brief Callback from the ZCL SE Profile Load Control Cluster Library when
  696. * it received a Get Scheduled Event Command for
  697. * this application.
  698. *
  699. * @param pCmd - pointer to structure for Get Scheduled Event command
  700. * @param scrAddr - source address
  701. * @param seqNum - sequence number for this command
  702. *
  703. * @return none
  704. */
  705. static void loadcontrol_GetScheduledEventCB( zclCCGetScheduledEvent_t *pCmd,
  706. afAddrType_t *srcAddr, uint8 seqNum )
  707. {
  708. // add user code here
  709. }
  710. /******************************************************************************
  711. *
  712. * Functions for processing ZCL Foundation incoming Command/Response messages
  713. *
  714. *****************************************************************************/
  715. /*********************************************************************
  716. * @fn loadcontrol_ProcessZCLMsg
  717. *
  718. * @brief Process ZCL Foundation incoming message
  719. *
  720. * @param pInMsg - message to process
  721. *
  722. * @return none
  723. */
  724. static void loadcontrol_ProcessZCLMsg( zclIncomingMsg_t *pInMsg )
  725. {
  726. switch ( pInMsg->zclHdr.commandID )
  727. {
  728. #if defined ( ZCL_READ )
  729. case ZCL_CMD_READ_RSP:
  730. loadcontrol_ProcessInReadRspCmd( pInMsg );
  731. break;
  732. #endif // ZCL_READ
  733. #if defined ( ZCL_WRITE )
  734. case ZCL_CMD_WRITE_RSP:
  735. loadcontrol_ProcessInWriteRspCmd( pInMsg );
  736. break;
  737. #endif // ZCL_WRITE
  738. case ZCL_CMD_DEFAULT_RSP:
  739. loadcontrol_ProcessInDefaultRspCmd( pInMsg );
  740. break;
  741. #if defined ( ZCL_DISCOVER )
  742. case ZCL_CMD_DISCOVER_RSP:
  743. loadcontrol_ProcessInDiscRspCmd( pInMsg );
  744. break;
  745. #endif // ZCL_DISCOVER
  746. default:
  747. break;
  748. }
  749. if ( pInMsg->attrCmd != NULL )
  750. {
  751. // free the parsed command
  752. osal_mem_free( pInMsg->attrCmd );
  753. pInMsg->attrCmd = NULL;
  754. }
  755. }
  756. #if defined ( ZCL_READ )
  757. /*********************************************************************
  758. * @fn loadcontrol_ProcessInReadRspCmd
  759. *
  760. * @brief Process the "Profile" Read Response Command
  761. *
  762. * @param pInMsg - incoming message to process
  763. *
  764. * @return none
  765. */
  766. static uint8 loadcontrol_ProcessInReadRspCmd( zclIncomingMsg_t *pInMsg )
  767. {
  768. zclReadRspCmd_t *readRspCmd;
  769. uint8 i;
  770. readRspCmd = (zclReadRspCmd_t *)pInMsg->attrCmd;
  771. for (i = 0; i < readRspCmd->numAttr; i++)
  772. {
  773. // Notify the originator of the results of the original read attributes
  774. // attempt and, for each successfull request, the value of the requested
  775. // attribute
  776. }
  777. return TRUE;
  778. }
  779. #endif // ZCL_READ
  780. #if defined ( ZCL_WRITE )
  781. /*********************************************************************
  782. * @fn loadcontrol_ProcessInWriteRspCmd
  783. *
  784. * @brief Process the "Profile" Write Response Command
  785. *
  786. * @param pInMsg - incoming message to process
  787. *
  788. * @return none
  789. */
  790. static uint8 loadcontrol_ProcessInWriteRspCmd( zclIncomingMsg_t *pInMsg )
  791. {
  792. zclWriteRspCmd_t *writeRspCmd;
  793. uint8 i;
  794. writeRspCmd = (zclWriteRspCmd_t *)pInMsg->attrCmd;
  795. for (i = 0; i < writeRspCmd->numAttr; i++)
  796. {
  797. // Notify the device of the results of the its original write attributes
  798. // command.
  799. }
  800. return TRUE;
  801. }
  802. #endif // ZCL_WRITE
  803. /*********************************************************************
  804. * @fn loadcontrol_ProcessInDefaultRspCmd
  805. *
  806. * @brief Process the "Profile" Default Response Command
  807. *
  808. * @param pInMsg - incoming message to process
  809. *
  810. * @return none
  811. */
  812. static uint8 loadcontrol_ProcessInDefaultRspCmd( zclIncomingMsg_t *pInMsg )
  813. {
  814. // zclDefaultRspCmd_t *defaultRspCmd = (zclDefaultRspCmd_t *)pInMsg->attrCmd;
  815. // Device is notified of the Default Response command.
  816. return TRUE;
  817. }
  818. #if defined ( ZCL_DISCOVER )
  819. /*********************************************************************
  820. * @fn loadcontrol_ProcessInDiscRspCmd
  821. *
  822. * @brief Process the "Profile" Discover Response Command
  823. *
  824. * @param pInMsg - incoming message to process
  825. *
  826. * @return none
  827. */
  828. static uint8 loadcontrol_ProcessInDiscRspCmd( zclIncomingMsg_t *pInMsg )
  829. {
  830. zclDiscoverRspCmd_t *discoverRspCmd;
  831. uint8 i;
  832. discoverRspCmd = (zclDiscoverRspCmd_t *)pInMsg->attrCmd;
  833. for ( i = 0; i < discoverRspCmd->numAttr; i++ )
  834. {
  835. // Device is notified of the result of its attribute discovery command.
  836. }
  837. return TRUE;
  838. }
  839. #endif // ZCL_DISCOVER
  840. /****************************************************************************
  841. ****************************************************************************/