loadcontrol.c 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168
  1. /**************************************************************************************************
  2. Filename: loadcontrol.c
  3. Revised: $Date: 2012-04-02 17:02:19 -0700 (Mon, 02 Apr 2012) $
  4. Revision: $Revision: 29996 $
  5. Description: This module implements the Load Control Device functionality
  6. and contains the init and event loop functions
  7. Copyright 2009-2012 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 "ZDObject.h"
  55. #include "AddrMgr.h"
  56. #include "se.h"
  57. #include "loadcontrol.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. #define loadControlNwkState devState
  75. /*********************************************************************
  76. * TYPEDEFS
  77. */
  78. /*********************************************************************
  79. * GLOBAL VARIABLES
  80. */
  81. /*********************************************************************
  82. * GLOBAL FUNCTIONS
  83. */
  84. /*********************************************************************
  85. * LOCAL VARIABLES
  86. */
  87. static uint8 loadControlTaskID; // osal task id for load control device
  88. static uint8 loadControlTransID; // transaction id
  89. static afAddrType_t ESPAddr; // ESP destination address
  90. #if SECURE
  91. static uint8 linkKeyStatus; // status variable from get link key function
  92. #endif
  93. static zclCCReportEventStatus_t rsp; // structure for report event status
  94. /*********************************************************************
  95. * LOCAL FUNCTIONS
  96. */
  97. static void loadcontrol_HandleKeys( uint8 shift, uint8 keys );
  98. #if SECURE
  99. static uint8 loadcontrol_KeyEstablish_ReturnLinkKey( uint16 shortAddr );
  100. #endif
  101. static void loadcontrol_ProcessIdentifyTimeChange( void );
  102. /*************************************************************************/
  103. /*** Application Callback Functions ***/
  104. /*************************************************************************/
  105. // Foundation Callback functions
  106. static uint8 loadcontrol_ValidateAttrDataCB( zclAttrRec_t *pAttr, zclWriteRec_t *pAttrInfo );
  107. // General Cluster Callback functions
  108. static void loadcontrol_BasicResetCB( void );
  109. static void loadcontrol_IdentifyCB( zclIdentify_t *pCmd );
  110. static void loadcontrol_IdentifyQueryRspCB( zclIdentifyQueryRsp_t *pRsp );
  111. static void loadcontrol_AlarmCB( zclAlarm_t *pAlarm );
  112. #ifdef SE_UK_EXT
  113. static void loadcontrol_GetEventLogCB( uint8 srcEP, afAddrType_t *srcAddr,
  114. zclGetEventLog_t *pEventLog, uint8 seqNum );
  115. static void loadcontrol_PublishEventLogCB( afAddrType_t *srcAddr,
  116. zclPublishEventLog_t *pEventLog );
  117. #endif // SE_UK_EXT
  118. // Function to process ZDO callback messages
  119. static void loadcontrol_ProcessZDOMsgs( zdoIncomingMsg_t *pMsg );
  120. // SE Callback functions
  121. static void loadcontrol_LoadControlEventCB( zclCCLoadControlEvent_t *pCmd,
  122. afAddrType_t *srcAddr, uint8 status, uint8 seqNum );
  123. static void loadcontrol_CancelLoadControlEventCB( zclCCCancelLoadControlEvent_t *pCmd,
  124. afAddrType_t *srcAddr, uint8 seqNum );
  125. static void loadcontrol_CancelAllLoadControlEventsCB( zclCCCancelAllLoadControlEvents_t *pCmd,
  126. afAddrType_t *srcAddr, uint8 seqNum );
  127. static void loadcontrol_ReportEventStatusCB( zclCCReportEventStatus_t *pCmd,
  128. afAddrType_t *srcAddr, uint8 seqNum );
  129. static void loadcontrol_GetScheduledEventCB( zclCCGetScheduledEvent_t *pCmd,
  130. afAddrType_t *srcAddr, uint8 seqNum );
  131. /************************************************************************/
  132. /*** Functions to process ZCL Foundation ***/
  133. /*** incoming Command/Response messages ***/
  134. /************************************************************************/
  135. static void loadcontrol_ProcessZCLMsg( zclIncomingMsg_t *msg );
  136. #if defined ( ZCL_READ )
  137. static uint8 loadcontrol_ProcessInReadRspCmd( zclIncomingMsg_t *pInMsg );
  138. #endif // ZCL_READ
  139. #if defined ( ZCL_WRITE )
  140. static uint8 loadcontrol_ProcessInWriteRspCmd( zclIncomingMsg_t *pInMsg );
  141. #endif // ZCL_WRITE
  142. static uint8 loadcontrol_ProcessInDefaultRspCmd( zclIncomingMsg_t *pInMsg );
  143. #if defined ( ZCL_DISCOVER )
  144. static uint8 loadcontrol_ProcessInDiscRspCmd( zclIncomingMsg_t *pInMsg );
  145. #endif // ZCL_DISCOVER
  146. /*********************************************************************
  147. * ZCL General Clusters Callback table
  148. */
  149. static zclGeneral_AppCallbacks_t loadcontrol_GenCmdCallbacks =
  150. {
  151. loadcontrol_BasicResetCB, // Basic Cluster Reset command
  152. loadcontrol_IdentifyCB, // Identify command
  153. loadcontrol_IdentifyQueryRspCB, // Identify Query Response command
  154. NULL, // On/Off cluster commands
  155. NULL, // Level Control Move to Level command
  156. NULL, // Level Control Move command
  157. NULL, // Level Control Step command
  158. NULL, // Level Control Stop command
  159. NULL, // Group Response commands
  160. NULL, // Scene Store Request command
  161. NULL, // Scene Recall Request command
  162. NULL, // Scene Response command
  163. loadcontrol_AlarmCB, // Alarm (Response) command
  164. #ifdef SE_UK_EXT
  165. loadcontrol_GetEventLogCB, // Get Event Log command
  166. loadcontrol_PublishEventLogCB, // Publish Event Log command
  167. #endif
  168. NULL, // RSSI Location command
  169. NULL // RSSI Location Response command
  170. };
  171. /*********************************************************************
  172. * ZCL SE Clusters Callback table
  173. */
  174. static zclSE_AppCallbacks_t loadcontrol_SECmdCallbacks =
  175. {
  176. NULL, // Publish Price
  177. NULL, // Publish Block Period
  178. #if defined ( SE_UK_EXT )
  179. NULL, // Publish Tariff Information
  180. NULL, // Publish Price Matrix
  181. NULL, // Publish Block Thresholds
  182. NULL, // Publish Conversion Factor
  183. NULL, // Publish Calorific Value
  184. NULL, // Publish CO2 Value
  185. NULL, // Publish CPP Event
  186. NULL, // Publish Billing Period
  187. NULL, // Publish Consolidated Bill
  188. NULL, // Publish Credit Payment Info
  189. #endif // SE_UK_EXT
  190. NULL, // Get Current Price
  191. NULL, // Get Scheduled Price
  192. NULL, // Price Acknowledgement
  193. NULL, // Get Block Period
  194. #if defined ( SE_UK_EXT )
  195. NULL, // Get Tariff Information
  196. NULL, // Get Price Matrix
  197. NULL, // Get Block Thresholds
  198. NULL, // Get Conversion Factor
  199. NULL, // Get Calorific Value
  200. NULL, // Get CO2 Value
  201. NULL, // Get Billing Period
  202. NULL, // Get Consolidated Bill
  203. NULL, // CPP Event Response
  204. #endif // SE_UK_EXT
  205. loadcontrol_LoadControlEventCB, // Load Control Event
  206. loadcontrol_CancelLoadControlEventCB, // Cancel Load Control Event
  207. loadcontrol_CancelAllLoadControlEventsCB, // Cancel All Load Control Events
  208. loadcontrol_ReportEventStatusCB, // Report Event Status
  209. loadcontrol_GetScheduledEventCB, // Get Scheduled Event
  210. NULL, // Get Profile Response
  211. NULL, // Request Mirror Command
  212. NULL, // Mirror Remove Command
  213. NULL, // Request Fast Poll Mode Response
  214. #if defined ( SE_UK_EXT )
  215. NULL, // Get Snapshot Response
  216. #endif // SE_UK_EXT
  217. NULL, // Get Profile Command
  218. NULL, // Request Mirror Response
  219. NULL, // Mirror Remove Response
  220. NULL, // Request Fast Poll Mode Command
  221. #if defined ( SE_UK_EXT )
  222. NULL, // Get Snapshot Command
  223. NULL, // Take Snapshot Command
  224. NULL, // Mirror Report Attribute Response
  225. #endif // SE_UK_EXT
  226. NULL, // Display Message Command
  227. NULL, // Cancel Message Command
  228. NULL, // Get Last Message Command
  229. NULL, // Message Confirmation
  230. NULL, // Request Tunnel Response
  231. NULL, // Transfer Data
  232. NULL, // Transfer Data Error
  233. NULL, // Ack Transfer Data
  234. NULL, // Ready Data
  235. #if defined ( SE_UK_EXT )
  236. NULL, // Supported Tunnel Protocols Response
  237. NULL, // Tunnel Closure Notification
  238. #endif // SE_UK_EXT
  239. NULL, // Request Tunnel
  240. NULL, // Close Tunnel
  241. #if defined ( SE_UK_EXT )
  242. NULL, // Get Supported Tunnel Protocols
  243. #endif // SE_UK_EXT
  244. NULL, // Supply Status Response
  245. #if defined ( SE_UK_EXT )
  246. NULL, // Get Prepay Snapshot Response
  247. NULL, // Change Payment Mode Response
  248. NULL, // Consumer Topup Response
  249. NULL, // Get Commands
  250. NULL, // Publish Topup Log
  251. NULL, // Publish Debt Log
  252. #endif // SE_UK_EXT
  253. NULL, // Select Available Emergency Credit Command
  254. NULL, // Change Supply Command
  255. #if defined ( SE_UK_EXT )
  256. NULL, // Change Debt
  257. NULL, // Emergency Credit Setup
  258. NULL, // Consumer Topup
  259. NULL, // Credit Adjustment
  260. NULL, // Change PaymentMode
  261. NULL, // Get Prepay Snapshot
  262. NULL, // Get Topup Log
  263. NULL, // Set Low Credit Warning Level
  264. NULL, // Get Debt Repayment Log
  265. NULL, // Publish Calendar
  266. NULL, // Publish Day Profile
  267. NULL, // Publish Week Profile
  268. NULL, // Publish Seasons
  269. NULL, // Publish Special Days
  270. NULL, // Get Calendar
  271. NULL, // Get Day Profiles
  272. NULL, // Get Week Profiles
  273. NULL, // Get Seasons
  274. NULL, // Get Special Days
  275. NULL, // Publish Change Tenancy
  276. NULL, // Publish Change Supplier
  277. NULL, // Change Supply
  278. NULL, // Change Password
  279. NULL, // Local Change Supply
  280. NULL, // Get Change Tenancy
  281. NULL, // Get Change Supplier
  282. NULL, // Get Change Supply
  283. NULL, // Supply Status Response
  284. NULL, // Get Password
  285. #endif // SE_UK_EXT
  286. };
  287. /*********************************************************************
  288. * @fn loadcontrol_Init
  289. *
  290. * @brief Initialization function for the ZCL App Application.
  291. *
  292. * @param uint8 task_id - load control task id
  293. *
  294. * @return none
  295. */
  296. void loadcontrol_Init( uint8 task_id )
  297. {
  298. loadControlTaskID = task_id;
  299. // setup destination address for ESP
  300. ESPAddr.addrMode = (afAddrMode_t)Addr16Bit;
  301. ESPAddr.endPoint = LOADCONTROL_ENDPOINT;
  302. ESPAddr.addr.shortAddr = 0;
  303. // register for SE endpoint
  304. zclSE_Init( &loadControlSimpleDesc );
  305. // Register the ZCL General Cluster Library callback functions
  306. zclGeneral_RegisterCmdCallbacks( LOADCONTROL_ENDPOINT, &loadcontrol_GenCmdCallbacks );
  307. // Register the ZCL SE Cluster Library callback functions
  308. zclSE_RegisterCmdCallbacks( LOADCONTROL_ENDPOINT, &loadcontrol_SECmdCallbacks );
  309. // Register the application's attribute list
  310. zcl_registerAttrList( LOADCONTROL_ENDPOINT, LOADCONTROL_MAX_ATTRIBUTES, loadControlAttrs );
  311. // Register the application's cluster option list
  312. zcl_registerClusterOptionList( LOADCONTROL_ENDPOINT, LOADCONTROL_MAX_OPTIONS, loadControlOptions );
  313. // Register the application's attribute data validation callback function
  314. zcl_registerValidateAttrData( loadcontrol_ValidateAttrDataCB );
  315. // Register the Application to receive the unprocessed Foundation command/response messages
  316. zcl_registerForMsg( loadControlTaskID );
  317. // Register for all key events - This app will handle all key events
  318. RegisterForKeys( loadControlTaskID );
  319. // Register with the ZDO to receive Match Descriptor Responses
  320. ZDO_RegisterForZDOMsg(task_id, Match_Desc_rsp);
  321. // Start the timer to sync LoadControl timer with the osal timer
  322. osal_start_timerEx( loadControlTaskID, LOADCONTROL_UPDATE_TIME_EVT, LOADCONTROL_UPDATE_TIME_PERIOD );
  323. }
  324. /*********************************************************************
  325. * @fn loadcontrol_event_loop
  326. *
  327. * @brief Event Loop Processor for loadcontrol.
  328. *
  329. * @param uint8 task id - load control task id
  330. * @param uint16 events - event bitmask
  331. *
  332. * @return none
  333. */
  334. uint16 loadcontrol_event_loop( uint8 task_id, uint16 events )
  335. {
  336. afIncomingMSGPacket_t *MSGpkt;
  337. if ( events & SYS_EVENT_MSG )
  338. {
  339. while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( loadControlTaskID )) )
  340. {
  341. switch ( MSGpkt->hdr.event )
  342. {
  343. case ZDO_CB_MSG:
  344. loadcontrol_ProcessZDOMsgs( (zdoIncomingMsg_t *)MSGpkt );
  345. break;
  346. case ZCL_INCOMING_MSG:
  347. // Incoming ZCL foundation command/response messages
  348. loadcontrol_ProcessZCLMsg( (zclIncomingMsg_t *)MSGpkt );
  349. break;
  350. case KEY_CHANGE:
  351. loadcontrol_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );
  352. break;
  353. case ZDO_STATE_CHANGE:
  354. if (DEV_ROUTER == (devStates_t)(MSGpkt->hdr.status))
  355. {
  356. #if SECURE
  357. {
  358. // check to see if link key had already been established
  359. linkKeyStatus = loadcontrol_KeyEstablish_ReturnLinkKey(ESPAddr.addr.shortAddr);
  360. if (linkKeyStatus != ZSuccess)
  361. {
  362. cId_t cbkeCluster = ZCL_CLUSTER_ID_GEN_KEY_ESTABLISHMENT;
  363. zAddrType_t dstAddr;
  364. // Send out a match for the key establishment
  365. dstAddr.addrMode = AddrBroadcast;
  366. dstAddr.addr.shortAddr = NWK_BROADCAST_SHORTADDR;
  367. ZDP_MatchDescReq( &dstAddr, NWK_BROADCAST_SHORTADDR, ZCL_SE_PROFILE_ID,
  368. 1, &cbkeCluster, 0, NULL, FALSE );
  369. }
  370. }
  371. #endif
  372. }
  373. break;
  374. #if defined( ZCL_KEY_ESTABLISH )
  375. case ZCL_KEY_ESTABLISH_IND:
  376. if ((MSGpkt->hdr.status) == TermKeyStatus_Success)
  377. {
  378. ESPAddr.endPoint = LOADCONTROL_ENDPOINT; // set destination endpoint back to application endpoint
  379. }
  380. break;
  381. #endif
  382. default:
  383. break;
  384. }
  385. // Release the memory
  386. osal_msg_deallocate( (uint8 *)MSGpkt );
  387. }
  388. // return unprocessed events
  389. return (events ^ SYS_EVENT_MSG);
  390. }
  391. // event to intiate key establishment request
  392. if ( events & LOADCONTROL_KEY_ESTABLISHMENT_REQUEST_EVT )
  393. {
  394. zclGeneral_KeyEstablish_InitiateKeyEstablishment(loadControlTaskID, &ESPAddr, loadControlTransID);
  395. return ( events ^ LOADCONTROL_KEY_ESTABLISHMENT_REQUEST_EVT );
  396. }
  397. // handle processing of identify timeout event triggered by an identify command
  398. if ( events & LOADCONTROL_IDENTIFY_TIMEOUT_EVT )
  399. {
  400. if ( loadControlIdentifyTime > 0 )
  401. {
  402. loadControlIdentifyTime--;
  403. }
  404. loadcontrol_ProcessIdentifyTimeChange();
  405. return ( events ^ LOADCONTROL_IDENTIFY_TIMEOUT_EVT );
  406. }
  407. // event to get current time
  408. if ( events & LOADCONTROL_UPDATE_TIME_EVT )
  409. {
  410. loadControlTime = osal_getClock();
  411. osal_start_timerEx( loadControlTaskID, LOADCONTROL_UPDATE_TIME_EVT, LOADCONTROL_UPDATE_TIME_PERIOD );
  412. return ( events ^ LOADCONTROL_UPDATE_TIME_EVT );
  413. }
  414. // event to handle load control complete event
  415. if ( events & LOADCONTROL_LOAD_CTRL_EVT )
  416. {
  417. // load control evt completed
  418. // Send response back
  419. // DisableDefaultResponse is set to FALSE - it is recommended to turn on
  420. // default response since Report Event Status Command does not have
  421. // a response.
  422. rsp.eventStatus = EVENT_STATUS_LOAD_CONTROL_EVENT_COMPLETED;
  423. zclSE_LoadControl_Send_ReportEventStatus( LOADCONTROL_ENDPOINT, &ESPAddr,
  424. &rsp, FALSE, loadControlTransID );
  425. HalLcdWriteString("Load Evt Complete", HAL_LCD_LINE_3);
  426. HalLedSet(HAL_LED_4, HAL_LED_MODE_OFF);
  427. return ( events ^ LOADCONTROL_LOAD_CTRL_EVT );
  428. }
  429. // Discard unknown events
  430. return 0;
  431. }
  432. /*********************************************************************
  433. * @fn loadcontrol_ProcessZDOMsgs
  434. *
  435. * @brief Called to process callbacks from the ZDO.
  436. *
  437. * @param none
  438. *
  439. * @return none
  440. */
  441. static void loadcontrol_ProcessZDOMsgs( zdoIncomingMsg_t *pMsg )
  442. {
  443. if (pMsg->clusterID == Match_Desc_rsp)
  444. {
  445. ZDO_ActiveEndpointRsp_t *pRsp = ZDO_ParseEPListRsp( pMsg );
  446. if (pRsp)
  447. {
  448. if (pRsp->cnt)
  449. {
  450. // Record the trust center
  451. ESPAddr.endPoint = pRsp->epList[0];
  452. ESPAddr.addr.shortAddr = pMsg->srcAddr.addr.shortAddr;
  453. // send out key establishment request
  454. osal_set_event( loadControlTaskID, LOADCONTROL_KEY_ESTABLISHMENT_REQUEST_EVT);
  455. }
  456. osal_mem_free(pRsp);
  457. }
  458. }
  459. }
  460. /*********************************************************************
  461. * @fn loadcontrol_ProcessIdentifyTimeChange
  462. *
  463. * @brief Called to blink led for specified IdentifyTime attribute value
  464. *
  465. * @param none
  466. *
  467. * @return none
  468. */
  469. static void loadcontrol_ProcessIdentifyTimeChange( void )
  470. {
  471. if ( loadControlIdentifyTime > 0 )
  472. {
  473. osal_start_timerEx( loadControlTaskID, LOADCONTROL_IDENTIFY_TIMEOUT_EVT, 1000 );
  474. HalLedBlink ( HAL_LED_4, 0xFF, HAL_LED_DEFAULT_DUTY_CYCLE, HAL_LED_DEFAULT_FLASH_TIME );
  475. }
  476. else
  477. {
  478. HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
  479. osal_stop_timerEx( loadControlTaskID, LOADCONTROL_IDENTIFY_TIMEOUT_EVT );
  480. }
  481. }
  482. #if SECURE
  483. /*********************************************************************
  484. * @fn loadcontrol_KeyEstablish_ReturnLinkKey
  485. *
  486. * @brief This function get the requested link key
  487. *
  488. * @param shortAddr - short address of the partner.
  489. *
  490. * @return none
  491. */
  492. static uint8 loadcontrol_KeyEstablish_ReturnLinkKey( uint16 shortAddr )
  493. {
  494. uint8 status = ZFailure;
  495. AddrMgrEntry_t entry;
  496. // Look up the long address of the device
  497. entry.user = ADDRMGR_USER_DEFAULT;
  498. entry.nwkAddr = shortAddr;
  499. if ( AddrMgrEntryLookupNwk( &entry ) )
  500. {
  501. // check if APS link key has been established
  502. if ( APSME_IsLinkKeyValid( entry.extAddr ) == TRUE )
  503. {
  504. status = ZSuccess;
  505. }
  506. }
  507. else
  508. {
  509. // It's an unknown device
  510. status = ZInvalidParameter;
  511. }
  512. return status;
  513. }
  514. #endif
  515. /*********************************************************************
  516. * @fn loadcontrol_HandleKeys
  517. *
  518. * @brief Handles all key events for this device.
  519. *
  520. * @param shift - true if in shift/alt.
  521. * @param keys - bit field for key events. Valid entries:
  522. * HAL_KEY_SW_4
  523. * HAL_KEY_SW_3
  524. * HAL_KEY_SW_2
  525. * HAL_KEY_SW_1
  526. *
  527. * @return none
  528. */
  529. static void loadcontrol_HandleKeys( uint8 shift, uint8 keys )
  530. {
  531. // Shift is used to make each button/switch dual purpose.
  532. if ( shift )
  533. {
  534. if ( keys & HAL_KEY_SW_1 )
  535. {
  536. }
  537. if ( keys & HAL_KEY_SW_2 )
  538. {
  539. }
  540. if ( keys & HAL_KEY_SW_3 )
  541. {
  542. }
  543. if ( keys & HAL_KEY_SW_4 )
  544. {
  545. }
  546. }
  547. else
  548. {
  549. if ( keys & HAL_KEY_SW_1 )
  550. {
  551. ZDOInitDevice(0); // join the network
  552. }
  553. if ( keys & HAL_KEY_SW_2 )
  554. {
  555. }
  556. if ( keys & HAL_KEY_SW_3 )
  557. {
  558. }
  559. if ( keys & HAL_KEY_SW_4 )
  560. {
  561. }
  562. }
  563. }
  564. /*********************************************************************
  565. * @fn loadcontrol_ValidateAttrDataCB
  566. *
  567. * @brief Check to see if the supplied value for the attribute data
  568. * is within the specified range of the attribute.
  569. *
  570. * @param pAttr - pointer to attribute
  571. * @param pAttrInfo - pointer to attribute info
  572. *
  573. * @return TRUE if data valid. FALSE otherwise.
  574. */
  575. static uint8 loadcontrol_ValidateAttrDataCB( zclAttrRec_t *pAttr, zclWriteRec_t *pAttrInfo )
  576. {
  577. uint8 valid = TRUE;
  578. switch ( pAttrInfo->dataType )
  579. {
  580. case ZCL_DATATYPE_BOOLEAN:
  581. if ( ( *(pAttrInfo->attrData) != 0 ) && ( *(pAttrInfo->attrData) != 1 ) )
  582. valid = FALSE;
  583. break;
  584. default:
  585. break;
  586. }
  587. return ( valid );
  588. }
  589. /*********************************************************************
  590. * @fn loadcontrol_BasicResetCB
  591. *
  592. * @brief Callback from the ZCL General Cluster Library to set all
  593. * the attributes of all the clusters to their factory defaults
  594. *
  595. * @param none
  596. *
  597. * @return none
  598. */
  599. static void loadcontrol_BasicResetCB( void )
  600. {
  601. // user should handle setting attributes to factory defaults here
  602. }
  603. /*********************************************************************
  604. * @fn loadcontrol_IdentifyCB
  605. *
  606. * @brief Callback from the ZCL General Cluster Library when
  607. * it received an Identity Command for this application.
  608. *
  609. * @param pCmd - pointer to structure for Identify command
  610. *
  611. * @return none
  612. */
  613. static void loadcontrol_IdentifyCB( zclIdentify_t *pCmd )
  614. {
  615. loadControlIdentifyTime = pCmd->identifyTime;
  616. loadcontrol_ProcessIdentifyTimeChange();
  617. }
  618. /*********************************************************************
  619. * @fn loadcontrol_IdentifyQueryRspCB
  620. *
  621. * @brief Callback from the ZCL General Cluster Library when
  622. * it received an Identity Query Response Command for this application.
  623. *
  624. * @param pRsp - pointer to structure for Identity Query Response command
  625. *
  626. * @return none
  627. */
  628. static void loadcontrol_IdentifyQueryRspCB( zclIdentifyQueryRsp_t *pRsp )
  629. {
  630. // add user code here
  631. }
  632. /*********************************************************************
  633. * @fn loadcontrol_AlarmCB
  634. *
  635. * @brief Callback from the ZCL General Cluster Library when
  636. * it received an Alarm request or response command for
  637. * this application.
  638. *
  639. * @param pAlarm - pointer to structure for Alarm command
  640. *
  641. * @return none
  642. */
  643. static void loadcontrol_AlarmCB( zclAlarm_t *pAlarm )
  644. {
  645. // add user code here
  646. }
  647. #ifdef SE_UK_EXT
  648. /*********************************************************************
  649. * @fn loadcontrol_GetEventLogCB
  650. *
  651. * @brief Callback from the ZCL General Cluster Library when
  652. * it received a Get Event Log command for this
  653. * application.
  654. *
  655. * @param srcEP - source endpoint
  656. * @param srcAddr - pointer to source address
  657. * @param pEventLog - pointer to structure for Get Event Log command
  658. * @param seqNum - sequence number of this command
  659. *
  660. * @return none
  661. */
  662. static void loadcontrol_GetEventLogCB( uint8 srcEP, afAddrType_t *srcAddr,
  663. zclGetEventLog_t *pEventLog, uint8 seqNum )
  664. {
  665. // add user code here, which could fragment the event log payload if
  666. // the entire payload doesn't fit into one Publish Event Log Command.
  667. // Note: the Command Index starts at 0 and is incremented for each
  668. // fragment belonging to the same command.
  669. // There's no event log for now! The Metering Device will support
  670. // logging for all events configured to do so.
  671. }
  672. /*********************************************************************
  673. * @fn loadcontrol_PublishEventLogCB
  674. *
  675. * @brief Callback from the ZCL General Cluster Library when
  676. * it received a Publish Event Log command for this
  677. * application.
  678. *
  679. * @param srcAddr - pointer to source address
  680. * @param pEventLog - pointer to structure for Publish Event Log command
  681. *
  682. * @return none
  683. */
  684. static void loadcontrol_PublishEventLogCB( afAddrType_t *srcAddr, zclPublishEventLog_t *pEventLog )
  685. {
  686. // add user code here
  687. }
  688. #endif // SE_UK_EXT
  689. #if defined (ZCL_LOAD_CONTROL)
  690. /*********************************************************************
  691. * @fn loadcontrol_SendReportEventStatus
  692. *
  693. * @brief Callback from the ZCL SE Profile Message Cluster Library when
  694. * it received a Load Control Event Command for
  695. * this application.
  696. *
  697. * @param afAddrType_t *srcAddr - pointer to source address
  698. * @param uint8 seqNum - sequence number for this event
  699. * @param uint32 eventID - event ID for this event
  700. * @param uint32 startTime - start time for this event
  701. * @param uint8 eventStatus - status for this event
  702. * @param uint8 criticalityLevel - criticality level for this event
  703. * @param uint8 eventControl - event control for this event
  704. *
  705. * @return none
  706. */
  707. static void loadcontrol_SendReportEventStatus( afAddrType_t *srcAddr, uint8 seqNum,
  708. uint32 eventID, uint32 startTime,
  709. uint8 eventStatus, uint8 criticalityLevel,
  710. uint8 eventControl )
  711. {
  712. // Mandatory fields - use the incoming data
  713. rsp.issuerEventID = eventID;
  714. rsp.eventStartTime = startTime;
  715. rsp.criticalityLevelApplied = criticalityLevel;
  716. rsp.eventControl = eventControl;
  717. rsp.eventStatus = eventStatus;
  718. rsp.signatureType = SE_PROFILE_SIGNATURE_TYPE_ECDSA;
  719. // loadcontrol_Signature is a static array.
  720. // value can be changed in loadcontrol_data.c
  721. osal_memcpy( rsp.signature, loadControlSignature, SE_PROFILE_SIGNATURE_LENGTH );
  722. // Optional fields - fill in with non-used value by default
  723. rsp.coolingTemperatureSetPointApplied = SE_OPTIONAL_FIELD_TEMPERATURE_SET_POINT;
  724. rsp.heatingTemperatureSetPointApplied = SE_OPTIONAL_FIELD_TEMPERATURE_SET_POINT;
  725. rsp.averageLoadAdjustment = SE_OPTIONAL_FIELD_INT8;
  726. rsp.dutyCycleApplied = SE_OPTIONAL_FIELD_UINT8;
  727. // Send response back
  728. // DisableDefaultResponse is set to FALSE - it is recommended to turn on
  729. // default response since Report Event Status Command does not have
  730. // a response.
  731. zclSE_LoadControl_Send_ReportEventStatus( LOADCONTROL_ENDPOINT, srcAddr,
  732. &rsp, FALSE, seqNum );
  733. }
  734. #endif // ZCL_LOAD_CONTROL
  735. /*********************************************************************
  736. * @fn loadcontrol_LoadControlEventCB
  737. *
  738. * @brief Callback from the ZCL SE Profile Load Control Cluster Library when
  739. * it received a Load Control Event Command for
  740. * this application.
  741. *
  742. * @param pCmd - pointer to load control event command
  743. * @param srcAddr - pointer to source address
  744. * @param status - event status
  745. * @param seqNum - sequence number of this command
  746. *
  747. * @return none
  748. */
  749. static void loadcontrol_LoadControlEventCB( zclCCLoadControlEvent_t *pCmd,
  750. afAddrType_t *srcAddr, uint8 status,
  751. uint8 seqNum)
  752. {
  753. #if defined ( ZCL_LOAD_CONTROL )
  754. // According to the Smart Metering Specification, upon receipt
  755. // of the Load Control Event command, the receiving device shall
  756. // send Report Event Status command back.
  757. uint8 eventStatus;
  758. if ( status == ZCL_STATUS_INVALID_FIELD )
  759. {
  760. // If the incoming message has invalid fields in it
  761. // Send response back with status: rejected
  762. eventStatus = EVENT_STATUS_LOAD_CONTROL_EVENT_REJECTED;
  763. }
  764. else
  765. { // Send response back with status: received
  766. eventStatus = EVENT_STATUS_LOAD_CONTROL_EVENT_RECEIVED;
  767. }
  768. // Send response back
  769. loadcontrol_SendReportEventStatus( srcAddr, seqNum, pCmd->issuerEvent,
  770. pCmd->startTime, eventStatus,
  771. pCmd->criticalityLevel, pCmd->eventControl);
  772. if ( status != ZCL_STATUS_INVALID_FIELD )
  773. {
  774. // Start the Load Control Event
  775. if ( pCmd->issuerEvent == LOADCONTROL_EVENT_ID )
  776. {
  777. if ( pCmd->startTime == START_TIME_NOW ) // start time = NOW
  778. {
  779. // send back status event = load control event started
  780. eventStatus = EVENT_STATUS_LOAD_CONTROL_EVENT_STARTED;
  781. loadcontrol_SendReportEventStatus( srcAddr, seqNum, pCmd->issuerEvent,
  782. pCmd->startTime, eventStatus,
  783. pCmd->criticalityLevel, pCmd->eventControl);
  784. if ( pCmd->deviceGroupClass == ONOFF_LOAD_DEVICE_CLASS ) // is this one for residential on/off load?
  785. {
  786. HalLcdWriteString("Load Evt Started", HAL_LCD_LINE_3);
  787. }
  788. else if ( pCmd->deviceGroupClass == HVAC_DEVICE_CLASS ) // is this one for HVAC compressor/furnace?
  789. {
  790. HalLcdWriteString("PCT Evt Started", HAL_LCD_LINE_3);
  791. }
  792. HalLedBlink ( HAL_LED_4, 0, 50, 500 );
  793. osal_start_timerEx( loadControlTaskID, LOADCONTROL_LOAD_CTRL_EVT,
  794. (LOADCONTROL_LOAD_CTRL_PERIOD * (pCmd->durationInMinutes)) );
  795. }
  796. }
  797. }
  798. #endif // ZCL_LOAD_CONTROL
  799. }
  800. /*********************************************************************
  801. * @fn loadcontrol_CancelLoadControlEventCB
  802. *
  803. * @brief Callback from the ZCL SE Profile Load Control Cluster Library when
  804. * it received a Cancel Load Control Event Command for
  805. * this application.
  806. *
  807. * @param pCmd - pointer to structure for Cancel Load Control Event command
  808. * @param scrAddr - source address
  809. * @param seqNum - sequence number for this command
  810. *
  811. * @return none
  812. */
  813. static void loadcontrol_CancelLoadControlEventCB( zclCCCancelLoadControlEvent_t *pCmd,
  814. afAddrType_t *srcAddr, uint8 seqNum )
  815. {
  816. #if defined ( ZCL_LOAD_CONTROL )
  817. if ( 0 ) // User shall replace the if condition with "if the event exist"
  818. {
  819. // If the event exist, stop the event, and respond with status: cancelled
  820. // Cancel the event here
  821. // Use the following sample code to send response back.
  822. /*
  823. loadcontrol_SendReportEventStatus( srcAddr, seqNum, pCmd->issuerEventID,
  824. // startTime
  825. EVENT_STATUS_LOAD_CONTROL_EVENT_CANCELLED, // eventStatus
  826. // Criticality level
  827. // eventControl };
  828. */
  829. }
  830. else
  831. {
  832. // If the event does not exist, respond with status: rejected
  833. // The rest of the mandatory fields are not available, therefore,
  834. // set to optional value
  835. loadcontrol_SendReportEventStatus( srcAddr, seqNum, pCmd->issuerEventID,
  836. SE_OPTIONAL_FIELD_UINT32, // startTime
  837. EVENT_STATUS_LOAD_CONTROL_EVENT_RECEIVED, // eventStatus
  838. SE_OPTIONAL_FIELD_UINT8, // Criticality level
  839. SE_OPTIONAL_FIELD_UINT8 ); // eventControl
  840. }
  841. #endif // ZCL_LOAD_CONTROL
  842. }
  843. /*********************************************************************
  844. * @fn loadcontrol_CancelAllLoadControlEventsCB
  845. *
  846. * @brief Callback from the ZCL SE Profile Load Control Cluster Library when
  847. * it received a Cancel All Load Control Event Command for
  848. * this application.
  849. *
  850. * @param pCmd - pointer to structure for Cancel All Load Control Event command
  851. * @param scrAddr - source address
  852. * @param seqNum - sequence number for this command
  853. *
  854. * @return none
  855. */
  856. static void loadcontrol_CancelAllLoadControlEventsCB( zclCCCancelAllLoadControlEvents_t *pCmd,
  857. afAddrType_t *srcAddr, uint8 seqNum )
  858. {
  859. // Upon receipt of Cancel All Load Control Event Command,
  860. // the receiving device shall look up the table for all events
  861. // and send a seperate response for each event
  862. }
  863. /*********************************************************************
  864. * @fn loadcontrol_ReportEventStatusCB
  865. *
  866. * @brief Callback from the ZCL SE Profile Load Control Cluster Library when
  867. * it received a Report Event Status Command for
  868. * this application.
  869. *
  870. * @param pCmd - pointer to structure for Report Event Status command
  871. * @param scrAddr - source address
  872. * @param seqNum - sequence number for this command
  873. *
  874. * @return none
  875. */
  876. static void loadcontrol_ReportEventStatusCB( zclCCReportEventStatus_t *pCmd,
  877. afAddrType_t *srcAddr, uint8 seqNum)
  878. {
  879. // add user code here
  880. }
  881. /*********************************************************************
  882. * @fn loadcontrol_GetScheduledEventCB
  883. *
  884. * @brief Callback from the ZCL SE Profile Load Control Cluster Library when
  885. * it received a Get Scheduled Event Command for
  886. * this application.
  887. *
  888. * @param pCmd - pointer to structure for Get Scheduled Event command
  889. * @param scrAddr - source address
  890. * @param seqNum - sequence number for this command
  891. *
  892. * @return none
  893. */
  894. static void loadcontrol_GetScheduledEventCB( zclCCGetScheduledEvent_t *pCmd,
  895. afAddrType_t *srcAddr, uint8 seqNum )
  896. {
  897. // add user code here
  898. }
  899. /******************************************************************************
  900. *
  901. * Functions for processing ZCL Foundation incoming Command/Response messages
  902. *
  903. *****************************************************************************/
  904. /*********************************************************************
  905. * @fn loadcontrol_ProcessZCLMsg
  906. *
  907. * @brief Process ZCL Foundation incoming message
  908. *
  909. * @param pInMsg - message to process
  910. *
  911. * @return none
  912. */
  913. static void loadcontrol_ProcessZCLMsg( zclIncomingMsg_t *pInMsg )
  914. {
  915. switch ( pInMsg->zclHdr.commandID )
  916. {
  917. #if defined ( ZCL_READ )
  918. case ZCL_CMD_READ_RSP:
  919. loadcontrol_ProcessInReadRspCmd( pInMsg );
  920. break;
  921. #endif // ZCL_READ
  922. #if defined ( ZCL_WRITE )
  923. case ZCL_CMD_WRITE_RSP:
  924. loadcontrol_ProcessInWriteRspCmd( pInMsg );
  925. break;
  926. #endif // ZCL_WRITE
  927. case ZCL_CMD_DEFAULT_RSP:
  928. loadcontrol_ProcessInDefaultRspCmd( pInMsg );
  929. break;
  930. #if defined ( ZCL_DISCOVER )
  931. case ZCL_CMD_DISCOVER_RSP:
  932. loadcontrol_ProcessInDiscRspCmd( pInMsg );
  933. break;
  934. #endif // ZCL_DISCOVER
  935. default:
  936. break;
  937. }
  938. if ( pInMsg->attrCmd != NULL )
  939. {
  940. // free the parsed command
  941. osal_mem_free( pInMsg->attrCmd );
  942. pInMsg->attrCmd = NULL;
  943. }
  944. }
  945. #if defined ( ZCL_READ )
  946. /*********************************************************************
  947. * @fn loadcontrol_ProcessInReadRspCmd
  948. *
  949. * @brief Process the "Profile" Read Response Command
  950. *
  951. * @param pInMsg - incoming message to process
  952. *
  953. * @return none
  954. */
  955. static uint8 loadcontrol_ProcessInReadRspCmd( zclIncomingMsg_t *pInMsg )
  956. {
  957. zclReadRspCmd_t *readRspCmd;
  958. uint8 i;
  959. readRspCmd = (zclReadRspCmd_t *)pInMsg->attrCmd;
  960. for (i = 0; i < readRspCmd->numAttr; i++)
  961. {
  962. // Notify the originator of the results of the original read attributes
  963. // attempt and, for each successfull request, the value of the requested
  964. // attribute
  965. }
  966. return TRUE;
  967. }
  968. #endif // ZCL_READ
  969. #if defined ( ZCL_WRITE )
  970. /*********************************************************************
  971. * @fn loadcontrol_ProcessInWriteRspCmd
  972. *
  973. * @brief Process the "Profile" Write Response Command
  974. *
  975. * @param pInMsg - incoming message to process
  976. *
  977. * @return none
  978. */
  979. static uint8 loadcontrol_ProcessInWriteRspCmd( zclIncomingMsg_t *pInMsg )
  980. {
  981. zclWriteRspCmd_t *writeRspCmd;
  982. uint8 i;
  983. writeRspCmd = (zclWriteRspCmd_t *)pInMsg->attrCmd;
  984. for (i = 0; i < writeRspCmd->numAttr; i++)
  985. {
  986. // Notify the device of the results of the its original write attributes
  987. // command.
  988. }
  989. return TRUE;
  990. }
  991. #endif // ZCL_WRITE
  992. /*********************************************************************
  993. * @fn loadcontrol_ProcessInDefaultRspCmd
  994. *
  995. * @brief Process the "Profile" Default Response Command
  996. *
  997. * @param pInMsg - incoming message to process
  998. *
  999. * @return none
  1000. */
  1001. static uint8 loadcontrol_ProcessInDefaultRspCmd( zclIncomingMsg_t *pInMsg )
  1002. {
  1003. // zclDefaultRspCmd_t *defaultRspCmd = (zclDefaultRspCmd_t *)pInMsg->attrCmd;
  1004. // Device is notified of the Default Response command.
  1005. return TRUE;
  1006. }
  1007. #if defined ( ZCL_DISCOVER )
  1008. /*********************************************************************
  1009. * @fn loadcontrol_ProcessInDiscRspCmd
  1010. *
  1011. * @brief Process the "Profile" Discover Response Command
  1012. *
  1013. * @param pInMsg - incoming message to process
  1014. *
  1015. * @return none
  1016. */
  1017. static uint8 loadcontrol_ProcessInDiscRspCmd( zclIncomingMsg_t *pInMsg )
  1018. {
  1019. zclDiscoverRspCmd_t *discoverRspCmd;
  1020. uint8 i;
  1021. discoverRspCmd = (zclDiscoverRspCmd_t *)pInMsg->attrCmd;
  1022. for ( i = 0; i < discoverRspCmd->numAttr; i++ )
  1023. {
  1024. // Device is notified of the result of its attribute discovery command.
  1025. }
  1026. return TRUE;
  1027. }
  1028. #endif // ZCL_DISCOVER
  1029. /****************************************************************************
  1030. ****************************************************************************/