esp.c 63 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832
  1. /**************************************************************************************************
  2. Filename: esp.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 ESP 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 ESP configuration:
  37. General Basic
  38. General Alarms
  39. General Time
  40. General Key Establishment
  41. SE Price
  42. SE Demand Response and Load Control
  43. SE Simple Metering
  44. SE Message
  45. Key control:
  46. SW1: Send out Cooling Load Control Event to PCT
  47. SW2: Send out Load Control Event to Load Control Device
  48. SW3: Send out Message to In Premise Display
  49. SW4: Send out Service Discovery messages to get 16-bit network
  50. address of PCT and Load Control Device
  51. *********************************************************************/
  52. /*********************************************************************
  53. * INCLUDES
  54. */
  55. #include "OSAL.h"
  56. #include "OSAL_Clock.h"
  57. #include "MT.h"
  58. #include "MT_APP.h"
  59. #include "ZDObject.h"
  60. #include "AddrMgr.h"
  61. #include "se.h"
  62. #include "esp.h"
  63. #include "zcl_general.h"
  64. #include "zcl_se.h"
  65. #include "zcl_key_establish.h"
  66. #include "onboard.h"
  67. /* HAL */
  68. #include "hal_lcd.h"
  69. #include "hal_led.h"
  70. #include "hal_key.h"
  71. /*********************************************************************
  72. * MACROS
  73. */
  74. // There is no attribute in the Mandatory Reportable Attribute list for now
  75. #define zcl_MandatoryReportableAttribute( a ) ( a == NULL )
  76. /*********************************************************************
  77. * CONSTANTS
  78. */
  79. #define ESP_MIN_REPORTING_INTERVAL 5
  80. /*********************************************************************
  81. * TYPEDEFS
  82. */
  83. /*********************************************************************
  84. * GLOBAL VARIABLES
  85. */
  86. /*********************************************************************
  87. * GLOBAL FUNCTIONS
  88. */
  89. /*********************************************************************
  90. * LOCAL VARIABLES
  91. */
  92. static uint8 espTaskID; // esp osal task id
  93. static afAddrType_t ipdAddr; // destination address of in premise display
  94. static afAddrType_t pctAddr; // destination address of PCT
  95. static afAddrType_t loadControlAddr; // destination address of load control device
  96. static zAddrType_t simpleDescReqAddr[2]; // destination addresses for simple desc request
  97. static uint8 matchRspCount = 0; // number of received match responses
  98. static zAddrType_t dstMatchAddr; // generic destination address used for match descriptor request
  99. static zclCCLoadControlEvent_t loadControlCmd; // command structure for load control command
  100. // cluster list used for match desc req
  101. static const cId_t matchClusterList[1] =
  102. {
  103. ZCL_CLUSTER_ID_SE_LOAD_CONTROL
  104. };
  105. /*********************************************************************
  106. * LOCAL FUNCTIONS
  107. */
  108. static void esp_HandleKeys( uint8 shift, uint8 keys );
  109. static void esp_ProcessAppMsg( uint8 *msg );
  110. #if defined (ZCL_KEY_ESTABLISH)
  111. static uint8 esp_KeyEstablish_ReturnLinkKey( uint16 shortAddr );
  112. #endif // ZCL_KEY_ESTABLISH
  113. #if defined (ZCL_ALARMS)
  114. static void esp_ProcessAlarmCmd( uint8 srcEP, afAddrType_t *dstAddr,
  115. uint16 clusterID, zclFrameHdr_t *hdr, uint8 len, uint8 *data );
  116. #endif // ZCL_ALARMS
  117. static void esp_ProcessIdentifyTimeChange( void );
  118. /*************************************************************************/
  119. /*** Application Callback Functions ***/
  120. /*************************************************************************/
  121. // Foundation Callback functions
  122. static uint8 esp_ValidateAttrDataCB( zclAttrRec_t *pAttr, zclWriteRec_t *pAttrInfo );
  123. // General Cluster Callback functions
  124. static void esp_BasicResetCB( void );
  125. static void esp_IdentifyCB( zclIdentify_t *pCmd );
  126. static void esp_IdentifyQueryRspCB( zclIdentifyQueryRsp_t *pRsp );
  127. static void esp_AlarmCB( zclAlarm_t *pAlarm );
  128. // SE Callback functions
  129. static void esp_GetProfileCmdCB( zclCCGetProfileCmd_t *pCmd,
  130. afAddrType_t *srcAddr, uint8 seqNum );
  131. static void esp_GetProfileRspCB( zclCCGetProfileRsp_t *pCmd,
  132. afAddrType_t *srcAddr, uint8 seqNum );
  133. static void esp_ReqMirrorCmdCB( afAddrType_t *srcAddr, uint8 seqNum );
  134. static void esp_ReqMirrorRspCB( zclCCReqMirrorRsp_t *pCmd,
  135. afAddrType_t *srcAddr, uint8 seqNum );
  136. static void esp_MirrorRemCmdCB( afAddrType_t *srcAddr, uint8 seqNum );
  137. static void esp_MirrorRemRspCB( zclCCMirrorRemRsp_t *pCmd,
  138. afAddrType_t *srcAddr, uint8 seqNum );
  139. static void esp_GetCurrentPriceCB( zclCCGetCurrentPrice_t *pCmd,
  140. afAddrType_t *srcAddr, uint8 seqNum );
  141. static void esp_GetScheduledPriceCB( zclCCGetScheduledPrice_t *pCmd,
  142. afAddrType_t *srcAddr, uint8 seqNum );
  143. static void esp_PublishPriceCB( zclCCPublishPrice_t *pCmd,
  144. afAddrType_t *srcAddr, uint8 seqNum );
  145. static void esp_DisplayMessageCB( zclCCDisplayMessage_t *pCmd,
  146. afAddrType_t *srcAddr, uint8 seqNum );
  147. static void esp_CancelMessageCB( zclCCCancelMessage_t *pCmd,
  148. afAddrType_t *srcAddr, uint8 seqNum );
  149. static void esp_GetLastMessageCB( afAddrType_t *srcAddr, uint8 seqNum );
  150. static void esp_MessageConfirmationCB( zclCCMessageConfirmation_t *pCmd,
  151. afAddrType_t *srcAddr, uint8 seqNum );
  152. static void esp_LoadControlEventCB( zclCCLoadControlEvent_t *pCmd,
  153. afAddrType_t *srcAddr, uint8 status, uint8 seqNum);
  154. static void esp_CancelLoadControlEventCB( zclCCCancelLoadControlEvent_t *pCmd,
  155. afAddrType_t *srcAddr, uint8 seqNum );
  156. static void esp_CancelAllLoadControlEventsCB( zclCCCancelAllLoadControlEvents_t *pCmd,
  157. afAddrType_t *srcAddr, uint8 seqNum);
  158. static void esp_ReportEventStatusCB( zclCCReportEventStatus_t *pCmd,
  159. afAddrType_t *srcAddr, uint8 seqNum );
  160. static void esp_GetScheduledEventCB( zclCCGetScheduledEvent_t *pCmd,
  161. afAddrType_t *srcAddr, uint8 seqNum);
  162. /************************************************************************/
  163. /*** Functions to process ZCL Foundation ***/
  164. /*** incoming Command/Response messages ***/
  165. /************************************************************************/
  166. static void esp_ProcessZCLMsg( zclIncomingMsg_t *msg );
  167. #if defined ( ZCL_READ )
  168. static uint8 esp_ProcessInReadRspCmd( zclIncomingMsg_t *pInMsg );
  169. #endif // ZCL_READ
  170. #if defined ( ZCL_WRITE )
  171. static uint8 esp_ProcessInWriteRspCmd( zclIncomingMsg_t *pInMsg );
  172. #endif // ZCL_WRITE
  173. #if defined ( ZCL_REPORT )
  174. static uint8 esp_ProcessInConfigReportCmd( zclIncomingMsg_t *pInMsg );
  175. static uint8 esp_ProcessInConfigReportRspCmd( zclIncomingMsg_t *pInMsg );
  176. static uint8 esp_ProcessInReadReportCfgCmd( zclIncomingMsg_t *pInMsg );
  177. static uint8 esp_ProcessInReadReportCfgRspCmd( zclIncomingMsg_t *pInMsg );
  178. static uint8 esp_ProcessInReportCmd( zclIncomingMsg_t *pInMsg );
  179. #endif // ZCL_REPORT
  180. static uint8 esp_ProcessInDefaultRspCmd( zclIncomingMsg_t *pInMsg );
  181. #if defined ( ZCL_DISCOVER )
  182. static uint8 esp_ProcessInDiscRspCmd( zclIncomingMsg_t *pInMsg );
  183. #endif // ZCL_DISCOVER
  184. // Functions to handle ZDO messages
  185. static void esp_ProcessZDOMsg( zdoIncomingMsg_t *inMsg );
  186. /*********************************************************************
  187. * ZCL General Clusters Callback table
  188. */
  189. static zclGeneral_AppCallbacks_t esp_GenCmdCallbacks =
  190. {
  191. esp_BasicResetCB, // Basic Cluster Reset command
  192. esp_IdentifyCB, // Identify command
  193. esp_IdentifyQueryRspCB, // Identify Query Response command
  194. NULL, // On/Off cluster commands
  195. NULL, // Level Control Move to Level command
  196. NULL, // Level Control Move command
  197. NULL, // Level Control Step command
  198. NULL, // Level Control Stop command
  199. NULL, // Group Response commands
  200. NULL, // Scene Store Request command
  201. NULL, // Scene Recall Request command
  202. NULL, // Scene Response command
  203. esp_AlarmCB, // Alarm (Response) command
  204. NULL, // RSSI Location command
  205. NULL, // RSSI Location Response command
  206. };
  207. /*********************************************************************
  208. * ZCL SE Clusters Callback table
  209. */
  210. static zclSE_AppCallbacks_t esp_SECmdCallbacks =
  211. {
  212. esp_GetProfileCmdCB, // Get Profile Command
  213. esp_GetProfileRspCB, // Get Profile Response
  214. esp_ReqMirrorCmdCB, // Request Mirror Command
  215. esp_ReqMirrorRspCB, // Request Mirror Response
  216. esp_MirrorRemCmdCB, // Mirror Remove Command
  217. esp_MirrorRemRspCB, // Mirror Remove Response
  218. esp_GetCurrentPriceCB, // Get Current Price
  219. esp_GetScheduledPriceCB, // Get Scheduled Price
  220. esp_PublishPriceCB, // Publish Price
  221. esp_DisplayMessageCB, // Display Message Command
  222. esp_CancelMessageCB, // Cancel Message Command
  223. esp_GetLastMessageCB, // Get Last Message Command
  224. esp_MessageConfirmationCB, // Message Confirmation
  225. esp_LoadControlEventCB, // Load Control Event
  226. esp_CancelLoadControlEventCB, // Cancel Load Control Event
  227. esp_CancelAllLoadControlEventsCB, // Cancel All Load Control Events
  228. esp_ReportEventStatusCB, // Report Event Status
  229. esp_GetScheduledEventCB, // Get Scheduled Event
  230. };
  231. /*********************************************************************
  232. * @fn esp_Init
  233. *
  234. * @brief Initialization function for the ZCL App Application.
  235. *
  236. * @param uint8 task_id - esp task id
  237. *
  238. * @return none
  239. */
  240. void esp_Init( uint8 task_id )
  241. {
  242. espTaskID = task_id;
  243. // Register for an SE endpoint
  244. zclSE_Init( &espSimpleDesc );
  245. // Register the ZCL General Cluster Library callback functions
  246. zclGeneral_RegisterCmdCallbacks( ESP_ENDPOINT, &esp_GenCmdCallbacks );
  247. // Register the ZCL SE Cluster Library callback functions
  248. zclSE_RegisterCmdCallbacks( ESP_ENDPOINT, &esp_SECmdCallbacks );
  249. // Register the application's attribute list
  250. zcl_registerAttrList( ESP_ENDPOINT, ESP_MAX_ATTRIBUTES, espAttrs );
  251. // Register the application's cluster option list
  252. zcl_registerClusterOptionList( ESP_ENDPOINT, ESP_MAX_OPTIONS, espOptions );
  253. // Register the application's attribute data validation callback function
  254. zcl_registerValidateAttrData( esp_ValidateAttrDataCB );
  255. // Register the Application to receive the unprocessed Foundation command/response messages
  256. zcl_registerForMsg( espTaskID );
  257. // register for match descriptor and simple descriptor responses
  258. ZDO_RegisterForZDOMsg( espTaskID, Match_Desc_rsp );
  259. ZDO_RegisterForZDOMsg( espTaskID, Simple_Desc_rsp );
  260. // Register for all key events - This app will handle all key events
  261. RegisterForKeys( espTaskID );
  262. // Start the timer to sync esp timer with the osal timer
  263. osal_start_timerEx( espTaskID, ESP_UPDATE_TIME_EVT, ESP_UPDATE_TIME_PERIOD );
  264. // setup address mode and destination endpoint fields for PCT
  265. pctAddr.addrMode = (afAddrMode_t)Addr16Bit;
  266. pctAddr.endPoint = ESP_ENDPOINT;
  267. // setup address mode and destination endpoint fields for load control device
  268. loadControlAddr.addrMode = (afAddrMode_t)Addr16Bit;
  269. loadControlAddr.endPoint = ESP_ENDPOINT;
  270. //setup load control command structure
  271. loadControlCmd.issuerEvent = 0x12345678; // arbitrary id
  272. loadControlCmd.deviceGroupClass = 0x000000; // addresses all groups
  273. loadControlCmd.startTime = 0x00000000; // start time = NOW
  274. loadControlCmd.durationInMinutes = 0x0001; // duration of one minute
  275. loadControlCmd.criticalityLevel = 0x01; // green level
  276. loadControlCmd.coolingTemperatureSetPoint = 0x076C; // 19 degrees C, 66.2 degress fahrenheit
  277. loadControlCmd.eventControl = 0x00; // no randomized start or end applied
  278. }
  279. /*********************************************************************
  280. * @fn esp_event_loop
  281. *
  282. * @brief Event Loop Processor for esp.
  283. *
  284. * @param uint8 task_id - esp task id
  285. * @param uint16 events - event bitmask
  286. *
  287. * @return none
  288. */
  289. uint16 esp_event_loop( uint8 task_id, uint16 events )
  290. {
  291. afIncomingMSGPacket_t *MSGpkt;
  292. if ( events & SYS_EVENT_MSG )
  293. {
  294. while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( espTaskID )) )
  295. {
  296. switch ( MSGpkt->hdr.event )
  297. {
  298. case MT_SYS_APP_MSG:
  299. // Message received from MT (serial port)
  300. esp_ProcessAppMsg( ((mtSysAppMsg_t *)MSGpkt)->appData );
  301. break;
  302. case ZCL_INCOMING_MSG:
  303. // Incoming ZCL foundation command/response messages
  304. esp_ProcessZCLMsg( (zclIncomingMsg_t *)MSGpkt );
  305. break;
  306. case KEY_CHANGE:
  307. esp_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );
  308. break;
  309. case ZDO_CB_MSG:
  310. // ZDO sends the message that we registered for
  311. esp_ProcessZDOMsg( (zdoIncomingMsg_t *)MSGpkt );
  312. break;
  313. default:
  314. break;
  315. }
  316. // Release the memory
  317. osal_msg_deallocate( (uint8 *)MSGpkt );
  318. }
  319. // return unprocessed events
  320. return (events ^ SYS_EVENT_MSG);
  321. }
  322. // handle processing of identify timeout event triggered by an identify command
  323. if ( events & ESP_IDENTIFY_TIMEOUT_EVT )
  324. {
  325. if ( espIdentifyTime > 0 )
  326. {
  327. espIdentifyTime--;
  328. }
  329. esp_ProcessIdentifyTimeChange();
  330. return ( events ^ ESP_IDENTIFY_TIMEOUT_EVT );
  331. }
  332. // event to get current time
  333. if ( events & ESP_UPDATE_TIME_EVT )
  334. {
  335. espTime = osal_getClock();
  336. osal_start_timerEx( espTaskID, ESP_UPDATE_TIME_EVT, ESP_UPDATE_TIME_PERIOD );
  337. return ( events ^ ESP_UPDATE_TIME_EVT );
  338. }
  339. // event to get simple descriptor of the first match response
  340. if ( events & SIMPLE_DESC_QUERY_EVT_1 )
  341. {
  342. ZDP_SimpleDescReq( &simpleDescReqAddr[0], simpleDescReqAddr[0].addr.shortAddr,
  343. ESP_ENDPOINT, 0);
  344. return ( events ^ SIMPLE_DESC_QUERY_EVT_1 );
  345. }
  346. // event to get simple descriptor of the second match response
  347. if ( events & SIMPLE_DESC_QUERY_EVT_2 )
  348. {
  349. ZDP_SimpleDescReq( &simpleDescReqAddr[1], simpleDescReqAddr[1].addr.shortAddr,
  350. ESP_ENDPOINT, 0);
  351. return ( events ^ SIMPLE_DESC_QUERY_EVT_2 );
  352. }
  353. // Discard unknown events
  354. return 0;
  355. }
  356. /*********************************************************************
  357. * @fn esp_ProcessAppMsg
  358. *
  359. * @brief Process MT SYS APP MSG to retrieve link key
  360. *
  361. * @param msg - pointer to message
  362. * 0 - lo byte destination address
  363. * 1 - hi byte destination address
  364. *
  365. * @return none
  366. */
  367. static void esp_ProcessAppMsg( uint8 *msg )
  368. {
  369. afAddrType_t dstAddr;
  370. dstAddr.addr.shortAddr = BUILD_UINT16( msg[0], msg[1] );
  371. esp_KeyEstablish_ReturnLinkKey( dstAddr.addr.shortAddr );
  372. }
  373. /*********************************************************************
  374. * @fn esp_ProcessIdentifyTimeChange
  375. *
  376. * @brief Called to blink led for specified IdentifyTime attribute value
  377. *
  378. * @param none
  379. *
  380. * @return none
  381. */
  382. static void esp_ProcessIdentifyTimeChange( void )
  383. {
  384. if ( espIdentifyTime > 0 )
  385. {
  386. osal_start_timerEx( espTaskID, ESP_IDENTIFY_TIMEOUT_EVT, 1000 );
  387. HalLedBlink ( HAL_LED_4, 0xFF, HAL_LED_DEFAULT_DUTY_CYCLE, HAL_LED_DEFAULT_FLASH_TIME );
  388. }
  389. else
  390. {
  391. HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
  392. osal_stop_timerEx( espTaskID, ESP_IDENTIFY_TIMEOUT_EVT );
  393. }
  394. }
  395. #if defined (ZCL_KEY_ESTABLISH)
  396. /*********************************************************************
  397. * @fn esp_KeyEstablish_ReturnLinkKey
  398. *
  399. * @brief This function get the requested link key
  400. *
  401. * @param shortAddr - short address of the partner.
  402. *
  403. * @return none
  404. */
  405. static uint8 esp_KeyEstablish_ReturnLinkKey( uint16 shortAddr )
  406. {
  407. APSME_LinkKeyData_t* keyData;
  408. uint8 status = ZFailure;
  409. uint8 buf[1+SEC_KEY_LEN];
  410. uint8 len = 1;
  411. AddrMgrEntry_t entry;
  412. // Look up the long address of the device
  413. entry.user = ADDRMGR_USER_DEFAULT;
  414. entry.nwkAddr = shortAddr;
  415. if ( AddrMgrEntryLookupNwk( &entry ) )
  416. {
  417. // check for APS link key data
  418. APSME_LinkKeyDataGet( entry.extAddr, &keyData );
  419. if ( (keyData != NULL) && (keyData->key != NULL) )
  420. {
  421. status = ZSuccess;
  422. len += SEC_KEY_LEN; // status + key
  423. }
  424. }
  425. else
  426. {
  427. // It's an unknown device
  428. status = ZInvalidParameter;
  429. }
  430. buf[0] = status;
  431. if( status == ZSuccess )
  432. {
  433. osal_memcpy( &(buf[1]), keyData->key, SEC_KEY_LEN );
  434. }
  435. MT_BuildAndSendZToolResponse( ((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_DBG), MT_DEBUG_MSG,
  436. len, buf );
  437. return status;
  438. }
  439. #endif // ZCL_KEY_ESTABLISH
  440. /*********************************************************************
  441. * @fn esp_HandleKeys
  442. *
  443. * @brief Handles all key events for this device.
  444. *
  445. * @param shift - true if in shift/alt.
  446. * @param keys - bit field for key events. Valid entries:
  447. * HAL_KEY_SW_4
  448. * HAL_KEY_SW_3
  449. * HAL_KEY_SW_2
  450. * HAL_KEY_SW_1
  451. *
  452. * @return none
  453. */
  454. static void esp_HandleKeys( uint8 shift, uint8 keys )
  455. {
  456. // Shift is used to make each button/switch dual purpose.
  457. if ( shift )
  458. {
  459. if ( keys & HAL_KEY_SW_1 )
  460. {
  461. }
  462. if ( keys & HAL_KEY_SW_2 )
  463. {
  464. }
  465. if ( keys & HAL_KEY_SW_3 )
  466. {
  467. }
  468. if ( keys & HAL_KEY_SW_4 )
  469. {
  470. }
  471. }
  472. else
  473. {
  474. if ( keys & HAL_KEY_SW_1 )
  475. {
  476. // send out cooling event to PCT
  477. loadControlCmd.deviceGroupClass = HVAC_DEVICE_CLASS; // HVAC compressor or furnace - bit 0 is set
  478. zclSE_LoadControl_Send_LoadControlEvent( ESP_ENDPOINT, &pctAddr, &loadControlCmd, TRUE, 0 );
  479. }
  480. if ( keys & HAL_KEY_SW_2 )
  481. {
  482. // send out load control event to load control device
  483. loadControlCmd.deviceGroupClass = ONOFF_LOAD_DEVICE_CLASS; // simple misc residential on/off loads - bit 7 is set
  484. zclSE_LoadControl_Send_LoadControlEvent( ESP_ENDPOINT, &loadControlAddr, &loadControlCmd, TRUE, 0 );
  485. }
  486. if ( keys & HAL_KEY_SW_3 )
  487. {
  488. zclCCDisplayMessage_t displayCmd; // command structure for message being sent to in premise display
  489. uint8 msgString[]="Rcvd MESSAGE Cmd"; // message being displayed on in premise display
  490. // send out display message to in premise display
  491. displayCmd.msgString.strLen = sizeof(msgString);
  492. displayCmd.msgString.pStr = msgString;
  493. zclSE_Message_Send_DisplayMessage( ESP_ENDPOINT, &ipdAddr, &displayCmd, TRUE, 0 );
  494. }
  495. if ( keys & HAL_KEY_SW_4 )
  496. {
  497. // perform service discovery for PCT, and load control device
  498. HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
  499. // Initiate a Match Description Request (Service Discovery)
  500. dstMatchAddr.addrMode = AddrBroadcast;
  501. dstMatchAddr.addr.shortAddr = NWK_BROADCAST_SHORTADDR;
  502. ZDP_MatchDescReq( &dstMatchAddr, NWK_BROADCAST_SHORTADDR,
  503. ZCL_SE_PROFILE_ID,
  504. 1, (cId_t *)matchClusterList,
  505. 1, (cId_t *)matchClusterList,
  506. FALSE );
  507. }
  508. }
  509. }
  510. /*********************************************************************
  511. * @fn esp_ValidateAttrDataCB
  512. *
  513. * @brief Check to see if the supplied value for the attribute data
  514. * is within the specified range of the attribute.
  515. *
  516. *
  517. * @param pAttr - pointer to attribute
  518. * @param pAttrInfo - pointer to attribute info
  519. *
  520. * @return TRUE if data valid. FALSE otherwise.
  521. */
  522. static uint8 esp_ValidateAttrDataCB( zclAttrRec_t *pAttr, zclWriteRec_t *pAttrInfo )
  523. {
  524. uint8 valid = TRUE;
  525. switch ( pAttrInfo->dataType )
  526. {
  527. case ZCL_DATATYPE_BOOLEAN:
  528. if ( ( *(pAttrInfo->attrData) != 0 ) && ( *(pAttrInfo->attrData) != 1 ) )
  529. {
  530. valid = FALSE;
  531. }
  532. break;
  533. default:
  534. break;
  535. }
  536. return ( valid );
  537. }
  538. /*********************************************************************
  539. * @fn esp_BasicResetCB
  540. *
  541. * @brief Callback from the ZCL General Cluster Library to set all
  542. * the attributes of all the clusters to their factory defaults
  543. *
  544. * @param none
  545. *
  546. * @return none
  547. */
  548. static void esp_BasicResetCB( void )
  549. {
  550. // user should handle setting attributes to factory defaults here
  551. }
  552. /*********************************************************************
  553. * @fn esp_IdentifyCB
  554. *
  555. * @brief Callback from the ZCL General Cluster Library when
  556. * it received an Identify Command for this application.
  557. *
  558. * @param pCmd - pointer to structure for identify command
  559. *
  560. * @return none
  561. */
  562. static void esp_IdentifyCB( zclIdentify_t *pCmd )
  563. {
  564. espIdentifyTime = pCmd->identifyTime;
  565. esp_ProcessIdentifyTimeChange();
  566. }
  567. /*********************************************************************
  568. * @fn esp_IdentifyQueryRspCB
  569. *
  570. * @brief Callback from the ZCL General Cluster Library when
  571. * it received an Identity Query Response Command for this application.
  572. *
  573. * @param pRsp - pointer to structure for identify query response
  574. *
  575. * @return none
  576. */
  577. static void esp_IdentifyQueryRspCB( zclIdentifyQueryRsp_t *pRsp )
  578. {
  579. // add user code here
  580. }
  581. /*********************************************************************
  582. * @fn esp_AlarmCB
  583. *
  584. * @brief Callback from the ZCL General Cluster Library when
  585. * it received an Alam request or response command for
  586. * this application.
  587. *
  588. * @param pAlarm - pointer to structure for alarm command
  589. *
  590. * @return none
  591. */
  592. static void esp_AlarmCB( zclAlarm_t *pAlarm )
  593. {
  594. // add user code here
  595. }
  596. /*********************************************************************
  597. * @fn esp_GetProfileCmdCB
  598. *
  599. * @brief Callback from the ZCL SE Profile Simple Metering Cluster Library when
  600. * it received a Get Profile Command for
  601. * this application.
  602. *
  603. * @param pCmd - pointer to get profile command structure
  604. * @param srcAddr - pointer to source address
  605. * @param seqNum - sequence number of this command
  606. *
  607. * @return none
  608. */
  609. static void esp_GetProfileCmdCB( zclCCGetProfileCmd_t *pCmd, afAddrType_t *srcAddr, uint8 seqNum )
  610. {
  611. #if defined ( ZCL_SIMPLE_METERING )
  612. // Upon receipt of the Get Profile Command, the metering device shall send
  613. // Get Profile Response back.
  614. // Variables in the following are initialized to arbitrary value for test purpose
  615. // In real application, user shall look up the interval data captured during
  616. // the period specified in the pCmd->endTime and return corresponding data.
  617. uint32 endTime;
  618. uint8 status = zclSE_SimpleMeter_GetProfileRsp_Status_Success;
  619. uint8 profileIntervalPeriod = PROFILE_INTERVAL_PERIOD_60MIN;
  620. uint8 numberOfPeriodDelivered = 5;
  621. uint24 intervals[] = {0xa00001, 0xa00002, 0xa00003, 0xa00004, 0xa00005};
  622. // endTime: 32 bit value (in UTC) representing the end time of the most
  623. // chronologically recent interval being requested.
  624. // Example: Data collected from 2:00 PM to 3:00 PM would be specified as a
  625. // 3:00 PM interval (end time).
  626. // The Intervals block returned shall be the most recent block with
  627. // its EndTime equal or older to the one in the request (pCmd->endTime).
  628. // Requested End Time with value 0xFFFFFFFF indicats the most recent
  629. // Intervals block is requested.
  630. // Sample Code - assuming the end time of the requested block is the same as
  631. // it in the request.
  632. endTime = pCmd->endTime;
  633. // Send Get Profile Response Command back
  634. zclSE_SimpleMetering_Send_GetProfileRsp( ESP_ENDPOINT, srcAddr, endTime,
  635. status,
  636. profileIntervalPeriod,
  637. numberOfPeriodDelivered, intervals,
  638. false, seqNum );
  639. #endif // ZCL_SIMPLE_METERING
  640. }
  641. /*********************************************************************
  642. * @fn esp_GetProfileRspCB
  643. *
  644. * @brief Callback from the ZCL SE Profile Simple Metering Cluster Library when
  645. * it received a Get Profile Response for
  646. * this application.
  647. *
  648. * @param pCmd - pointer to get profile response structure
  649. * @param srcAddr - pointer to source address
  650. * @param seqNum - sequence number of this command
  651. *
  652. * @return none
  653. */
  654. static void esp_GetProfileRspCB( zclCCGetProfileRsp_t *pCmd, afAddrType_t *srcAddr, uint8 seqNum )
  655. {
  656. // add user code here
  657. }
  658. /*********************************************************************
  659. * @fn esp_ReqMirrorCmdCB
  660. *
  661. * @brief Callback from the ZCL SE Profile Simple Metering Cluster Library when
  662. * it received a Request Mirror Command for
  663. * this application.
  664. *
  665. * @param srcAddr - pointer to source address
  666. * @param seqNum - sequence number of this command
  667. *
  668. * @return none
  669. */
  670. static void esp_ReqMirrorCmdCB( afAddrType_t *srcAddr, uint8 seqNum )
  671. {
  672. // add user code here
  673. }
  674. /*********************************************************************
  675. * @fn esp_ReqMirrorRspCB
  676. *
  677. * @brief Callback from the ZCL SE Profile Simple Metering Cluster Library when
  678. * it received a Request Mirror Response for
  679. * this application.
  680. *
  681. * @param pRsp - pointer to request mirror response structure
  682. * @param srcAddr - pointer to source address
  683. * @param seqNum - sequence number of this command
  684. *
  685. * @return none
  686. */
  687. static void esp_ReqMirrorRspCB( zclCCReqMirrorRsp_t *pRsp, afAddrType_t *srcAddr, uint8 seqNum )
  688. {
  689. // add user code here
  690. }
  691. /*********************************************************************
  692. * @fn esp_MirrorRemCmdCB
  693. *
  694. * @brief Callback from the ZCL SE Profile Simple Metering Cluster Library when
  695. * it received a Mirror Remove Command for
  696. * this application.
  697. *
  698. * @param srcAddr - pointer to source address
  699. * @param seqNum - sequence number of this command
  700. *
  701. * @return none
  702. */
  703. static void esp_MirrorRemCmdCB( afAddrType_t *srcAddr, uint8 seqNum )
  704. {
  705. // add user code here
  706. }
  707. /*********************************************************************
  708. * @fn esp_MirrorRemRspCB
  709. *
  710. * @brief Callback from the ZCL SE Profile Simple Metering Cluster Library when
  711. * it received a Mirror Remove Response for
  712. * this application.
  713. *
  714. * @param pCmd - pointer to mirror remove response structure
  715. * @param srcAddr - pointer to source address
  716. * @param seqNum - sequence number of this command
  717. *
  718. * @return none
  719. */
  720. static void esp_MirrorRemRspCB( zclCCMirrorRemRsp_t *pCmd, afAddrType_t *srcAddr, uint8 seqNum )
  721. {
  722. // add user code here
  723. }
  724. /*********************************************************************
  725. * @fn esp_GetCurrentPriceCB
  726. *
  727. * @brief Callback from the ZCL SE Profile Pricing Cluster Library when
  728. * it received a Get Current Price for
  729. * this application.
  730. *
  731. * @param pCmd - pointer to structure for Get Current Price command
  732. * @param srcAddr - source address
  733. * @param seqNum - sequence number for this command
  734. *
  735. * @return none
  736. */
  737. static void esp_GetCurrentPriceCB( zclCCGetCurrentPrice_t *pCmd,
  738. afAddrType_t *srcAddr, uint8 seqNum )
  739. {
  740. #if defined ( ZCL_PRICING )
  741. // On receipt of Get Current Price command, the device shall send a
  742. // Publish Price command with the information for the current time.
  743. zclCCPublishPrice_t cmd;
  744. osal_memset( &cmd, 0, sizeof( zclCCPublishPrice_t ) );
  745. cmd.providerId = 0xbabeface;
  746. cmd.priceTier = 0xfe;
  747. // copy source address of display device that requested current pricing info so
  748. // that esp can send messages to it using destination address of IPDAddr
  749. osal_memcpy( &ipdAddr, srcAddr, sizeof ( afAddrType_t ) );
  750. zclSE_Pricing_Send_PublishPrice( ESP_ENDPOINT, srcAddr, &cmd, false, seqNum );
  751. #endif // ZCL_PRICING
  752. }
  753. /*********************************************************************
  754. * @fn esp_GetScheduledPriceCB
  755. *
  756. * @brief Callback from the ZCL SE Profile Pricing Cluster Library when
  757. * it received a Get Scheduled Price for
  758. * this application.
  759. *
  760. * @param pCmd - pointer to structure for Get Scheduled Price command
  761. * @param srcAddr - source address
  762. * @param seqNum - sequence number for this command
  763. *
  764. * @return none
  765. */
  766. static void esp_GetScheduledPriceCB( zclCCGetScheduledPrice_t *pCmd, afAddrType_t *srcAddr, uint8 seqNum )
  767. {
  768. // On receipt of Get Scheduled Price command, the device shall send a
  769. // Publish Price command for all currently scheduled price events.
  770. // The sample code as follows only sends one.
  771. #if defined ( ZCL_PRICING )
  772. zclCCPublishPrice_t cmd;
  773. osal_memset( &cmd, 0, sizeof( zclCCPublishPrice_t ) );
  774. cmd.providerId = 0xbabeface;
  775. cmd.priceTier = 0xfe;
  776. zclSE_Pricing_Send_PublishPrice( ESP_ENDPOINT, srcAddr, &cmd, false, seqNum );
  777. #endif // ZCL_PRICING
  778. }
  779. /*********************************************************************
  780. * @fn esp_PublishPriceCB
  781. *
  782. * @brief Callback from the ZCL SE Profile Pricing Cluster Library when
  783. * it received a Publish Price for this application.
  784. *
  785. * @param pCmd - pointer to structure for Publish Price command
  786. * @param srcAddr - source address
  787. * @param seqNum - sequence number for this command
  788. *
  789. * @return none
  790. */
  791. static void esp_PublishPriceCB( zclCCPublishPrice_t *pCmd,
  792. afAddrType_t *srcAddr, uint8 seqNum )
  793. {
  794. // add user code here
  795. }
  796. /*********************************************************************
  797. * @fn esp_DisplayMessageCB
  798. *
  799. * @brief Callback from the ZCL SE Profile Message Cluster Library when
  800. * it received a Display Message Command for
  801. * this application.
  802. *
  803. * @param pCmd - pointer to structure for Display Message command
  804. * @param srcAddr - source address
  805. * @param seqNum - sequence number for this command
  806. *
  807. * @return none
  808. */
  809. static void esp_DisplayMessageCB( zclCCDisplayMessage_t *pCmd,
  810. afAddrType_t *srcAddr, uint8 seqNum )
  811. {
  812. // Upon receipt of the Display Message Command, the device shall
  813. // display the message. If the Message Confirmation bit indicates
  814. // the message originator require a confirmation of receipt from
  815. // a Utility Customer, the device should display the message or
  816. // alert the user until it is either confirmed via a button or by
  817. // selecting a confirmation option on the device. Confirmation is
  818. // typically used when the Utility is sending down information
  819. // such as a disconnection notice, or prepaid billing information.
  820. // Message duration is ignored when confirmation is requested and
  821. // the message is displayed until confirmed.
  822. #if defined ( LCD_SUPPORTED )
  823. HalLcdWriteString( (char*)pCmd->msgString.pStr, HAL_LCD_LINE_1 );
  824. #endif // LCD_SUPPORTED
  825. }
  826. /*********************************************************************
  827. * @fn esp_CancelMessageCB
  828. *
  829. * @brief Callback from the ZCL SE Profile Message Cluster Library when
  830. * it received a Cancel Message Command for
  831. * this application.
  832. *
  833. * @param pCmd - pointer to structure for Cancel Message command
  834. * @param srcAddr - source address
  835. * @param seqNum - sequence number for this command
  836. *
  837. * @return none
  838. */
  839. static void esp_CancelMessageCB( zclCCCancelMessage_t *pCmd,
  840. afAddrType_t *srcAddr, uint8 seqNum )
  841. {
  842. // add user code here
  843. }
  844. /*********************************************************************
  845. * @fn esp_GetLastMessageCB
  846. *
  847. * @brief Callback from the ZCL SE Profile Message Cluster Library when
  848. * it received a Get Last Message Command for
  849. * this application.
  850. *
  851. * @param pCmd - pointer to structure for Get Last Message command
  852. * @param srcAddr - source address
  853. * @param seqNum - sequence number for this command
  854. *
  855. * @return none
  856. */
  857. static void esp_GetLastMessageCB( afAddrType_t *srcAddr, uint8 seqNum )
  858. {
  859. // On receipt of Get Last Message command, the device shall send a
  860. // Display Message command back to the sender
  861. #if defined ( ZCL_MESSAGE )
  862. zclCCDisplayMessage_t cmd;
  863. uint8 msg[10] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29 };
  864. // Fill in the command with information for the last message
  865. cmd.messageId = 0xaabbccdd;
  866. cmd.messageCtrl.transmissionMode = 0;
  867. cmd.messageCtrl.importance = 1;
  868. cmd.messageCtrl.confirmationRequired = 1;
  869. cmd.durationInMinutes = 60;
  870. cmd.msgString.strLen = 10;
  871. cmd.msgString.pStr = msg;
  872. zclSE_Message_Send_DisplayMessage( ESP_ENDPOINT, srcAddr, &cmd,
  873. false, seqNum );
  874. #endif // ZCL_MESSAGe
  875. }
  876. /*********************************************************************
  877. * @fn esp_MessageConfirmationCB
  878. *
  879. * @brief Callback from the ZCL SE Profile Message Cluster Library when
  880. * it received a Message Confirmation Command for
  881. * this application.
  882. *
  883. * @param pCmd - pointer to structure for Message Confirmation command
  884. * @param srcAddr - source address
  885. * @param seqNum - sequence number for this command
  886. *
  887. * @return none
  888. */
  889. static void esp_MessageConfirmationCB( zclCCMessageConfirmation_t *pCmd,
  890. afAddrType_t *srcAddr, uint8 seqNum)
  891. {
  892. // add user code here
  893. }
  894. #if defined (ZCL_LOAD_CONTROL)
  895. /*********************************************************************
  896. * @fn esp_SendReportEventStatus
  897. *
  898. * @brief Callback from the ZCL SE Profile Message Cluster Library when
  899. * it received a Load Control Event Command for
  900. * this application.
  901. *
  902. * @param afAddrType_t *srcAddr - pointer to source address
  903. * @param uint8 seqNum - sequence number for this event
  904. * @param uint32 eventID - event ID for this event
  905. * @param uint32 startTime - start time for this event
  906. * @param uint8 eventStatus - status for this event
  907. * @param uint8 criticalityLevel - criticality level for this event
  908. * @param uint8 eventControl - event control for this event
  909. *
  910. * @return none
  911. */
  912. static void esp_SendReportEventStatus( afAddrType_t *srcAddr, uint8 seqNum,
  913. uint32 eventID, uint32 startTime,
  914. uint8 eventStatus, uint8 criticalityLevel,
  915. uint8 eventControl )
  916. {
  917. zclCCReportEventStatus_t *pRsp;
  918. pRsp = (zclCCReportEventStatus_t *)osal_mem_alloc( sizeof( zclCCReportEventStatus_t ) );
  919. if ( pRsp != NULL)
  920. {
  921. // Mandatory fields - use the incoming data
  922. pRsp->issuerEventID = eventID;
  923. pRsp->eventStartTime = startTime;
  924. pRsp->criticalityLevelApplied = criticalityLevel;
  925. pRsp->eventControl = eventControl;
  926. pRsp->eventStatus = eventStatus;
  927. pRsp->signatureType = SE_PROFILE_SIGNATURE_TYPE_ECDSA;
  928. // esp_Signature is a static array.
  929. // value can be changed in esp_data.c
  930. osal_memcpy( pRsp->signature, espSignature, 16 );
  931. // Optional fields - fill in with non-used value by default
  932. pRsp->coolingTemperatureSetPointApplied = SE_OPTIONAL_FIELD_TEMPERATURE_SET_POINT;
  933. pRsp->heatingTemperatureSetPointApplied = SE_OPTIONAL_FIELD_TEMPERATURE_SET_POINT;
  934. pRsp->averageLoadAdjustment = SE_OPTIONAL_FIELD_INT8;
  935. pRsp->dutyCycleApplied = SE_OPTIONAL_FIELD_UINT8;
  936. // Send response back
  937. // DisableDefaultResponse is set to false - it is recommended to turn on
  938. // default response since Report Event Status Command does not have
  939. // a response.
  940. zclSE_LoadControl_Send_ReportEventStatus( ESP_ENDPOINT, srcAddr,
  941. pRsp, false, seqNum );
  942. osal_mem_free( pRsp );
  943. }
  944. }
  945. #endif // ZCL_LOAD_CONTROL
  946. /*********************************************************************
  947. * @fn esp_LoadControlEventCB
  948. *
  949. * @brief Callback from the ZCL SE Profile Load Control Cluster Library when
  950. * it received a Load Control Event Command for
  951. * this application.
  952. *
  953. * @param pCmd - pointer to load control event command
  954. * @param srcAddr - source address
  955. * @param status - event status
  956. * @param seqNum - sequence number of this command
  957. *
  958. * @return none
  959. */
  960. static void esp_LoadControlEventCB( zclCCLoadControlEvent_t *pCmd,
  961. afAddrType_t *srcAddr, uint8 status,
  962. uint8 seqNum)
  963. {
  964. #if defined ( ZCL_LOAD_CONTROL )
  965. // According to the Smart Metering Specification, upon receipt
  966. // of the Load Control Event command, the receiving device shall
  967. // send Report Event Status command back.
  968. uint8 eventStatus;
  969. if ( status == ZCL_STATUS_INVALID_FIELD )
  970. {
  971. // If the incoming message has invalid fields in it
  972. // Send response back with status: rejected
  973. eventStatus = EVENT_STATUS_LOAD_CONTROL_EVENT_REJECTED;
  974. }
  975. else
  976. { // Send response back with status: received
  977. eventStatus = EVENT_STATUS_LOAD_CONTROL_EVENT_RECEIVED;
  978. }
  979. // Send response back
  980. esp_SendReportEventStatus( srcAddr, seqNum, pCmd->issuerEvent,
  981. pCmd->startTime, eventStatus,
  982. pCmd->criticalityLevel, pCmd->eventControl);
  983. if ( status != ZCL_STATUS_INVALID_FIELD )
  984. {
  985. // add user load control event handler here
  986. }
  987. #endif // ZCL_LOAD_CONTROL
  988. }
  989. /*********************************************************************
  990. * @fn esp_CancelLoadControlEventCB
  991. *
  992. * @brief Callback from the ZCL SE Profile Load Control Cluster Library when
  993. * it received a Cancel Load Control Event Command for
  994. * this application.
  995. *
  996. * @param pCmd - pointer to structure for Cancel Load Control Event command
  997. * @param scrAddr - source address
  998. * @param seqNum - sequence number for this command
  999. *
  1000. * @return none
  1001. */
  1002. static void esp_CancelLoadControlEventCB( zclCCCancelLoadControlEvent_t *pCmd,
  1003. afAddrType_t *srcAddr, uint8 seqNum )
  1004. {
  1005. #if defined ( ZCL_LOAD_CONTROL )
  1006. if ( 0 ) // User shall replace the if condition with "if the event exist"
  1007. {
  1008. // If the event exist, stop the event, and respond with status: cancelled
  1009. // Cancel the event here
  1010. // Use the following sample code to send response back.
  1011. /*
  1012. esp_SendReportEventStatus( srcAddr, seqNum, pCmd->issuerEventID,
  1013. // startTime
  1014. EVENT_STATUS_LOAD_CONTROL_EVENT_CANCELLED, // eventStatus
  1015. // Criticality level
  1016. // eventControl };
  1017. */
  1018. }
  1019. else
  1020. {
  1021. // If the event does not exist, respond with status: rejected
  1022. // The rest of the mandatory fields are not available, therefore,
  1023. // set to optional value
  1024. esp_SendReportEventStatus( srcAddr, seqNum, pCmd->issuerEventID,
  1025. SE_OPTIONAL_FIELD_UINT32, // startTime
  1026. EVENT_STATUS_LOAD_CONTROL_EVENT_RECEIVED, // eventStatus
  1027. SE_OPTIONAL_FIELD_UINT8, // Criticality level
  1028. SE_OPTIONAL_FIELD_UINT8 ); // eventControl
  1029. }
  1030. #endif // ZCL_LOAD_CONTROL
  1031. }
  1032. /*********************************************************************
  1033. * @fn esp_CancelAllLoadControlEventsCB
  1034. *
  1035. * @brief Callback from the ZCL SE Profile Load Control Cluster Library when
  1036. * it received a Cancel All Load Control Event Command for
  1037. * this application.
  1038. *
  1039. * @param pCmd - pointer to structure for Cancel All Load Control Event command
  1040. * @param scrAddr - source address
  1041. * @param seqNum - sequence number for this command
  1042. *
  1043. * @return none
  1044. */
  1045. static void esp_CancelAllLoadControlEventsCB( zclCCCancelAllLoadControlEvents_t *pCmd,
  1046. afAddrType_t *srcAddr, uint8 seqNum )
  1047. {
  1048. // Upon receipt of Cancel All Load Control Event Command,
  1049. // the receiving device shall look up the table for all events
  1050. // and send a seperate response for each event
  1051. }
  1052. /*********************************************************************
  1053. * @fn esp_ReportEventStatusCB
  1054. *
  1055. * @brief Callback from the ZCL SE Profile Load Control Cluster Library when
  1056. * it received a Report Event Status Command for
  1057. * this application.
  1058. *
  1059. * @param pCmd - pointer to structure for Report Event Status command
  1060. * @param scrAddr - source address
  1061. * @param seqNum - sequence number for this command
  1062. *
  1063. * @return none
  1064. */
  1065. static void esp_ReportEventStatusCB( zclCCReportEventStatus_t *pCmd,
  1066. afAddrType_t *srcAddr, uint8 seqNum)
  1067. {
  1068. // add user code here
  1069. }
  1070. /*********************************************************************
  1071. * @fn esp_GetScheduledEventCB
  1072. *
  1073. * @brief Callback from the ZCL SE Profile Load Control Cluster Library when
  1074. * it received a Get Scheduled Event Command for
  1075. * this application.
  1076. *
  1077. * @param pCmd - pointer to structure for Get Scheduled Event command
  1078. * @param scrAddr - source address
  1079. * @param seqNum - sequence number for this command
  1080. *
  1081. * @return none
  1082. */
  1083. static void esp_GetScheduledEventCB( zclCCGetScheduledEvent_t *pCmd,
  1084. afAddrType_t *srcAddr, uint8 seqNum )
  1085. {
  1086. // add user code here
  1087. }
  1088. /******************************************************************************
  1089. *
  1090. * Functions for processing ZDO incoming messages
  1091. *
  1092. *****************************************************************************/
  1093. /*********************************************************************
  1094. * @fn esp_ProcessZDOMsg
  1095. *
  1096. * @brief Process the incoming ZDO messages.
  1097. *
  1098. * @param inMsg - message to process
  1099. *
  1100. * @return none
  1101. */
  1102. static void esp_ProcessZDOMsg( zdoIncomingMsg_t *inMsg )
  1103. {
  1104. switch ( inMsg->clusterID )
  1105. {
  1106. case Match_Desc_rsp:
  1107. {
  1108. ZDO_ActiveEndpointRsp_t *pRsp = ZDO_ParseEPListRsp( inMsg );
  1109. if ( pRsp )
  1110. {
  1111. matchRspCount++; // found a match, increment the rsp count
  1112. if ( pRsp->status == ZSuccess && pRsp->cnt )
  1113. {
  1114. if ( matchRspCount == 1 )
  1115. {
  1116. simpleDescReqAddr[0].addrMode = (afAddrMode_t)Addr16Bit;
  1117. simpleDescReqAddr[0].addr.shortAddr = pRsp->nwkAddr;
  1118. // Light LED
  1119. HalLedSet( HAL_LED_4, HAL_LED_MODE_ON );
  1120. // set simple descriptor query event
  1121. osal_set_event( espTaskID, SIMPLE_DESC_QUERY_EVT_1 );
  1122. }
  1123. else if ( matchRspCount == 2 )
  1124. {
  1125. matchRspCount = 0; // reset rsp counter
  1126. simpleDescReqAddr[1].addrMode = (afAddrMode_t)Addr16Bit;
  1127. simpleDescReqAddr[1].addr.shortAddr = pRsp->nwkAddr;
  1128. // Light LED
  1129. HalLedSet( HAL_LED_4, HAL_LED_MODE_ON );
  1130. // set simple descriptor query event
  1131. osal_set_event( espTaskID, SIMPLE_DESC_QUERY_EVT_2 );
  1132. }
  1133. }
  1134. osal_mem_free( pRsp );
  1135. }
  1136. }
  1137. break;
  1138. case Simple_Desc_rsp:
  1139. {
  1140. ZDO_SimpleDescRsp_t *pSimpleDescRsp; // pointer to received simple desc response
  1141. pSimpleDescRsp = (ZDO_SimpleDescRsp_t *)osal_mem_alloc( sizeof( ZDO_SimpleDescRsp_t ) );
  1142. if(pSimpleDescRsp)
  1143. {
  1144. ZDO_ParseSimpleDescRsp( inMsg, pSimpleDescRsp );
  1145. if( pSimpleDescRsp->simpleDesc.AppDeviceId == ZCL_SE_DEVICEID_PCT ) // this is a PCT
  1146. {
  1147. pctAddr.addr.shortAddr = pSimpleDescRsp->nwkAddr;
  1148. }
  1149. else if ( pSimpleDescRsp->simpleDesc.AppDeviceId == ZCL_SE_DEVICEID_LOAD_CTRL_EXTENSION ) // this is a load control device
  1150. {
  1151. loadControlAddr.addr.shortAddr = pSimpleDescRsp->nwkAddr;
  1152. }
  1153. osal_mem_free( pSimpleDescRsp );
  1154. }
  1155. }
  1156. break;
  1157. }
  1158. }
  1159. /******************************************************************************
  1160. *
  1161. * Functions for processing ZCL Foundation incoming Command/Response messages
  1162. *
  1163. *****************************************************************************/
  1164. /*********************************************************************
  1165. * @fn esp_ProcessZCLMsg
  1166. *
  1167. * @brief Process ZCL Foundation incoming message
  1168. *
  1169. * @param pInMsg - message to process
  1170. *
  1171. * @return none
  1172. */
  1173. static void esp_ProcessZCLMsg( zclIncomingMsg_t *pInMsg )
  1174. {
  1175. switch ( pInMsg->zclHdr.commandID )
  1176. {
  1177. #if defined ( ZCL_READ )
  1178. case ZCL_CMD_READ_RSP:
  1179. esp_ProcessInReadRspCmd( pInMsg );
  1180. break;
  1181. #endif // ZCL_READ
  1182. #if defined ( ZCL_WRITE )
  1183. case ZCL_CMD_WRITE_RSP:
  1184. esp_ProcessInWriteRspCmd( pInMsg );
  1185. break;
  1186. #endif // ZCL_WRITE
  1187. #if defined ( ZCL_REPORT )
  1188. case ZCL_CMD_CONFIG_REPORT:
  1189. esp_ProcessInConfigReportCmd( pInMsg );
  1190. break;
  1191. case ZCL_CMD_CONFIG_REPORT_RSP:
  1192. esp_ProcessInConfigReportRspCmd( pInMsg );
  1193. break;
  1194. case ZCL_CMD_READ_REPORT_CFG:
  1195. esp_ProcessInReadReportCfgCmd( pInMsg );
  1196. break;
  1197. case ZCL_CMD_READ_REPORT_CFG_RSP:
  1198. esp_ProcessInReadReportCfgRspCmd( pInMsg );
  1199. break;
  1200. case ZCL_CMD_REPORT:
  1201. esp_ProcessInReportCmd( pInMsg );
  1202. break;
  1203. #endif // ZCL_REPORT
  1204. case ZCL_CMD_DEFAULT_RSP:
  1205. esp_ProcessInDefaultRspCmd( pInMsg );
  1206. break;
  1207. #if defined ( ZCL_DISCOVER )
  1208. case ZCL_CMD_DISCOVER_RSP:
  1209. esp_ProcessInDiscRspCmd( pInMsg );
  1210. break;
  1211. #endif // ZCL_DISCOVER
  1212. default:
  1213. break;
  1214. }
  1215. if ( pInMsg->attrCmd != NULL )
  1216. {
  1217. // free the parsed command
  1218. osal_mem_free( pInMsg->attrCmd );
  1219. pInMsg->attrCmd = NULL;
  1220. }
  1221. }
  1222. #if defined ( ZCL_READ )
  1223. /*********************************************************************
  1224. * @fn esp_ProcessInReadRspCmd
  1225. *
  1226. * @brief Process the "Profile" Read Response Command
  1227. *
  1228. * @param pInMsg - incoming message to process
  1229. *
  1230. * @return none
  1231. */
  1232. static uint8 esp_ProcessInReadRspCmd( zclIncomingMsg_t *pInMsg )
  1233. {
  1234. zclReadRspCmd_t *readRspCmd;
  1235. uint8 i;
  1236. readRspCmd = (zclReadRspCmd_t *)pInMsg->attrCmd;
  1237. for (i = 0; i < readRspCmd->numAttr; i++)
  1238. {
  1239. // Notify the originator of the results of the original read attributes
  1240. // attempt and, for each successfull request, the value of the requested
  1241. // attribute
  1242. }
  1243. return TRUE;
  1244. }
  1245. #endif // ZCL_READ
  1246. #if defined ( ZCL_WRITE )
  1247. /*********************************************************************
  1248. * @fn esp_ProcessInWriteRspCmd
  1249. *
  1250. * @brief Process the "Profile" Write Response Command
  1251. *
  1252. * @param pInMsg - incoming message to process
  1253. *
  1254. * @return none
  1255. */
  1256. static uint8 esp_ProcessInWriteRspCmd( zclIncomingMsg_t *pInMsg )
  1257. {
  1258. zclWriteRspCmd_t *writeRspCmd;
  1259. uint8 i;
  1260. writeRspCmd = (zclWriteRspCmd_t *)pInMsg->attrCmd;
  1261. for (i = 0; i < writeRspCmd->numAttr; i++)
  1262. {
  1263. // Notify the device of the results of the its original write attributes
  1264. // command.
  1265. }
  1266. return TRUE;
  1267. }
  1268. #endif // ZCL_WRITE
  1269. #if defined ( ZCL_REPORT )
  1270. /*********************************************************************
  1271. * @fn esp_ProcessInConfigReportCmd
  1272. *
  1273. * @brief Process the "Profile" Configure Reporting Command
  1274. *
  1275. * @param pInMsg - incoming message to process
  1276. *
  1277. * @return TRUE if attribute was found in the Attribute list,
  1278. * FALSE if not
  1279. */
  1280. static uint8 esp_ProcessInConfigReportCmd( zclIncomingMsg_t *pInMsg )
  1281. {
  1282. zclCfgReportCmd_t *cfgReportCmd;
  1283. zclCfgReportRec_t *reportRec;
  1284. zclCfgReportRspCmd_t *cfgReportRspCmd;
  1285. zclAttrRec_t attrRec;
  1286. uint8 status;
  1287. uint8 i, j = 0;
  1288. cfgReportCmd = (zclCfgReportCmd_t *)pInMsg->attrCmd;
  1289. // Allocate space for the response command
  1290. cfgReportRspCmd = (zclCfgReportRspCmd_t *)osal_mem_alloc( sizeof ( zclCfgReportRspCmd_t ) +
  1291. sizeof ( zclCfgReportStatus_t) * cfgReportCmd->numAttr );
  1292. if ( cfgReportRspCmd == NULL )
  1293. return FALSE; // EMBEDDED RETURN
  1294. // Process each Attribute Reporting Configuration record
  1295. for ( i = 0; i < cfgReportCmd->numAttr; i++ )
  1296. {
  1297. reportRec = &(cfgReportCmd->attrList[i]);
  1298. status = ZCL_STATUS_SUCCESS;
  1299. if ( zclFindAttrRec( ESP_ENDPOINT, pInMsg->clusterId, reportRec->attrID, &attrRec ) )
  1300. {
  1301. if ( reportRec->direction == ZCL_SEND_ATTR_REPORTS )
  1302. {
  1303. if ( reportRec->dataType == attrRec.attr.dataType )
  1304. {
  1305. // This the attribute that is to be reported
  1306. if ( zcl_MandatoryReportableAttribute( &attrRec ) == TRUE )
  1307. {
  1308. if ( reportRec->minReportInt < ESP_MIN_REPORTING_INTERVAL ||
  1309. ( reportRec->maxReportInt != 0 &&
  1310. reportRec->maxReportInt < reportRec->minReportInt ) )
  1311. {
  1312. // Invalid fields
  1313. status = ZCL_STATUS_INVALID_VALUE;
  1314. }
  1315. else
  1316. {
  1317. // Set the Min and Max Reporting Intervals and Reportable Change
  1318. //status = zclSetAttrReportInterval( pAttr, cfgReportCmd );
  1319. status = ZCL_STATUS_UNREPORTABLE_ATTRIBUTE; // for now
  1320. }
  1321. }
  1322. else
  1323. {
  1324. // Attribute cannot be reported
  1325. status = ZCL_STATUS_UNREPORTABLE_ATTRIBUTE;
  1326. }
  1327. }
  1328. else
  1329. {
  1330. // Attribute data type is incorrect
  1331. status = ZCL_STATUS_INVALID_DATA_TYPE;
  1332. }
  1333. }
  1334. else
  1335. {
  1336. // We shall expect reports of values of this attribute
  1337. if ( zcl_MandatoryReportableAttribute( &attrRec ) == TRUE )
  1338. {
  1339. // Set the Timeout Period
  1340. //status = zclSetAttrTimeoutPeriod( pAttr, cfgReportCmd );
  1341. status = ZCL_STATUS_UNSUPPORTED_ATTRIBUTE; // for now
  1342. }
  1343. else
  1344. {
  1345. // Reports of attribute cannot be received
  1346. status = ZCL_STATUS_UNSUPPORTED_ATTRIBUTE;
  1347. }
  1348. }
  1349. }
  1350. else
  1351. {
  1352. // Attribute is not supported
  1353. status = ZCL_STATUS_UNSUPPORTED_ATTRIBUTE;
  1354. }
  1355. // If not successful then record the status
  1356. if ( status != ZCL_STATUS_SUCCESS )
  1357. {
  1358. cfgReportRspCmd->attrList[j].status = status;
  1359. cfgReportRspCmd->attrList[j++].attrID = reportRec->attrID;
  1360. }
  1361. } // for loop
  1362. if ( j == 0 )
  1363. {
  1364. // Since all attributes were configured successfully, include a single
  1365. // attribute status record in the response command with the status field
  1366. // set to SUCCESS and the attribute ID field omitted.
  1367. cfgReportRspCmd->attrList[0].status = ZCL_STATUS_SUCCESS;
  1368. cfgReportRspCmd->numAttr = 1;
  1369. }
  1370. else
  1371. {
  1372. cfgReportRspCmd->numAttr = j;
  1373. }
  1374. // Send the response back
  1375. zcl_SendConfigReportRspCmd( ESP_ENDPOINT, &(pInMsg->srcAddr),
  1376. pInMsg->clusterId, cfgReportRspCmd, ZCL_FRAME_SERVER_CLIENT_DIR,
  1377. true, pInMsg->zclHdr.transSeqNum );
  1378. osal_mem_free( cfgReportRspCmd );
  1379. return TRUE ;
  1380. }
  1381. /*********************************************************************
  1382. * @fn esp_ProcessInConfigReportRspCmd
  1383. *
  1384. * @brief Process the "Profile" Configure Reporting Response Command
  1385. *
  1386. * @param pInMsg - incoming message to process
  1387. *
  1388. * @return none
  1389. */
  1390. static uint8 esp_ProcessInConfigReportRspCmd( zclIncomingMsg_t *pInMsg )
  1391. {
  1392. zclCfgReportRspCmd_t *cfgReportRspCmd;
  1393. zclAttrRec_t attrRec;
  1394. uint8 i;
  1395. cfgReportRspCmd = (zclCfgReportRspCmd_t *)pInMsg->attrCmd;
  1396. for (i = 0; i < cfgReportRspCmd->numAttr; i++)
  1397. {
  1398. if ( zclFindAttrRec( ESP_ENDPOINT, pInMsg->clusterId,
  1399. cfgReportRspCmd->attrList[i].attrID, &attrRec ) )
  1400. {
  1401. // Notify the device of success (or otherwise) of the its original configure
  1402. // reporting command, for each attribute.
  1403. }
  1404. }
  1405. return TRUE;
  1406. }
  1407. /*********************************************************************
  1408. * @fn esp_ProcessInReadReportCfgCmd
  1409. *
  1410. * @brief Process the "Profile" Read Reporting Configuration Command
  1411. *
  1412. * @param pInMsg - incoming message to process
  1413. *
  1414. * @return none
  1415. */
  1416. static uint8 esp_ProcessInReadReportCfgCmd( zclIncomingMsg_t *pInMsg )
  1417. {
  1418. zclReadReportCfgCmd_t *readReportCfgCmd;
  1419. zclReadReportCfgRspCmd_t *readReportCfgRspCmd;
  1420. zclReportCfgRspRec_t *reportRspRec;
  1421. zclAttrRec_t attrRec;
  1422. uint8 reportChangeLen;
  1423. uint8 *dataPtr;
  1424. uint8 hdrLen;
  1425. uint8 dataLen = 0;
  1426. uint8 status;
  1427. uint8 i;
  1428. readReportCfgCmd = (zclReadReportCfgCmd_t *)pInMsg->attrCmd;
  1429. // Find out the response length (Reportable Change field is of variable length)
  1430. for ( i = 0; i < readReportCfgCmd->numAttr; i++ )
  1431. {
  1432. // For supported attributes with 'analog' data type, find out the length of
  1433. // the Reportable Change field
  1434. if ( zclFindAttrRec( ESP_ENDPOINT, pInMsg->clusterId,
  1435. readReportCfgCmd->attrList[i].attrID, &attrRec ) )
  1436. {
  1437. if ( zclAnalogDataType( attrRec.attr.dataType ) )
  1438. {
  1439. reportChangeLen = zclGetDataTypeLength( attrRec.attr.dataType );
  1440. // add padding if neede
  1441. if ( PADDING_NEEDED( reportChangeLen ) )
  1442. reportChangeLen++;
  1443. dataLen += reportChangeLen;
  1444. }
  1445. }
  1446. }
  1447. hdrLen = sizeof( zclReadReportCfgRspCmd_t ) + ( readReportCfgCmd->numAttr * sizeof( zclReportCfgRspRec_t ) );
  1448. // Allocate space for the response command
  1449. readReportCfgRspCmd = (zclReadReportCfgRspCmd_t *)osal_mem_alloc( hdrLen + dataLen );
  1450. if ( readReportCfgRspCmd == NULL )
  1451. return FALSE; // EMBEDDED RETURN
  1452. dataPtr = (uint8 *)( (uint8 *)readReportCfgRspCmd + hdrLen );
  1453. readReportCfgRspCmd->numAttr = readReportCfgCmd->numAttr;
  1454. for (i = 0; i < readReportCfgCmd->numAttr; i++)
  1455. {
  1456. reportRspRec = &(readReportCfgRspCmd->attrList[i]);
  1457. if ( zclFindAttrRec( ESP_ENDPOINT, pInMsg->clusterId,
  1458. readReportCfgCmd->attrList[i].attrID, &attrRec ) )
  1459. {
  1460. if ( zcl_MandatoryReportableAttribute( &attrRec ) == TRUE )
  1461. {
  1462. // Get the Reporting Configuration
  1463. // status = zclReadReportCfg( readReportCfgCmd->attrID[i], reportRspRec );
  1464. status = ZCL_STATUS_UNREPORTABLE_ATTRIBUTE; // for now
  1465. if ( status == ZCL_STATUS_SUCCESS && zclAnalogDataType( attrRec.attr.dataType ) )
  1466. {
  1467. reportChangeLen = zclGetDataTypeLength( attrRec.attr.dataType );
  1468. //osal_memcpy( dataPtr, pBuf, reportChangeLen );
  1469. reportRspRec->reportableChange = dataPtr;
  1470. // add padding if needed
  1471. if ( PADDING_NEEDED( reportChangeLen ) )
  1472. reportChangeLen++;
  1473. dataPtr += reportChangeLen;
  1474. }
  1475. }
  1476. else
  1477. {
  1478. // Attribute not in the Mandatory Reportable Attribute list
  1479. status = ZCL_STATUS_UNREPORTABLE_ATTRIBUTE;
  1480. }
  1481. }
  1482. else
  1483. {
  1484. // Attribute not found
  1485. status = ZCL_STATUS_UNSUPPORTED_ATTRIBUTE;
  1486. }
  1487. reportRspRec->status = status;
  1488. reportRspRec->attrID = readReportCfgCmd->attrList[i].attrID;
  1489. }
  1490. // Send the response back
  1491. zcl_SendReadReportCfgRspCmd( ESP_ENDPOINT, &(pInMsg->srcAddr),
  1492. pInMsg->clusterId, readReportCfgRspCmd, ZCL_FRAME_SERVER_CLIENT_DIR,
  1493. true, pInMsg->zclHdr.transSeqNum );
  1494. osal_mem_free( readReportCfgRspCmd );
  1495. return TRUE;
  1496. }
  1497. /*********************************************************************
  1498. * @fn esp_ProcessInReadReportCfgRspCmd
  1499. *
  1500. * @brief Process the "Profile" Read Reporting Configuration Response Command
  1501. *
  1502. * @param pInMsg - incoming message to process
  1503. *
  1504. * @return none
  1505. */
  1506. static uint8 esp_ProcessInReadReportCfgRspCmd( zclIncomingMsg_t *pInMsg )
  1507. {
  1508. zclReadReportCfgRspCmd_t *readReportCfgRspCmd;
  1509. zclReportCfgRspRec_t *reportRspRec;
  1510. uint8 i;
  1511. readReportCfgRspCmd = (zclReadReportCfgRspCmd_t *)pInMsg->attrCmd;
  1512. for ( i = 0; i < readReportCfgRspCmd->numAttr; i++ )
  1513. {
  1514. reportRspRec = &(readReportCfgRspCmd->attrList[i]);
  1515. // Notify the device of the results of the its original read reporting
  1516. // configuration command.
  1517. if ( reportRspRec->status == ZCL_STATUS_SUCCESS )
  1518. {
  1519. if ( reportRspRec->direction == ZCL_SEND_ATTR_REPORTS )
  1520. {
  1521. // add user code here
  1522. }
  1523. else
  1524. {
  1525. // expecting attribute reports
  1526. }
  1527. }
  1528. }
  1529. return TRUE;
  1530. }
  1531. /*********************************************************************
  1532. * @fn esp_ProcessInReportCmd
  1533. *
  1534. * @brief Process the "Profile" Report Command
  1535. *
  1536. * @param pInMsg - incoming message to process
  1537. *
  1538. * @return none
  1539. */
  1540. static uint8 esp_ProcessInReportCmd( zclIncomingMsg_t *pInMsg )
  1541. {
  1542. zclReportCmd_t *reportCmd;
  1543. zclReport_t *reportRec;
  1544. uint8 i;
  1545. uint8 *meterData;
  1546. char lcdBuf[13];
  1547. reportCmd = (zclReportCmd_t *)pInMsg->attrCmd;
  1548. for (i = 0; i < reportCmd->numAttr; i++)
  1549. {
  1550. // Device is notified of the latest values of the attribute of another device.
  1551. reportRec = &(reportCmd->attrList[i]);
  1552. if ( reportRec->attrID == ATTRID_SE_CURRENT_SUMMATION_DELIVERED )
  1553. {
  1554. // process simple metering current summation delivered attribute
  1555. meterData = reportRec->attrData;
  1556. // process to convert hex to ascii
  1557. for(i=0; i<6; i++)
  1558. {
  1559. if(meterData[5-i] == 0)
  1560. {
  1561. lcdBuf[i*2] = '0';
  1562. lcdBuf[i*2+1] = '0';
  1563. }
  1564. else if(meterData[5-i] <= 0x0A)
  1565. {
  1566. lcdBuf[i*2] = '0';
  1567. _ltoa(meterData[5-i],(uint8*)&lcdBuf[i*2+1],16);
  1568. }
  1569. else
  1570. {
  1571. _ltoa(meterData[5-i],(uint8*)&lcdBuf[i*2],16);
  1572. }
  1573. }
  1574. // print out value of current summation delivered in hex
  1575. HalLcdWriteString("Zigbee Coord esp", HAL_LCD_LINE_1);
  1576. HalLcdWriteString("Curr Summ Dlvd", HAL_LCD_LINE_2);
  1577. HalLcdWriteString(lcdBuf, HAL_LCD_LINE_3);
  1578. }
  1579. }
  1580. return TRUE;
  1581. }
  1582. #endif // ZCL_REPORT
  1583. /*********************************************************************
  1584. * @fn esp_ProcessInDefaultRspCmd
  1585. *
  1586. * @brief Process the "Profile" Default Response Command
  1587. *
  1588. * @param pInMsg - incoming message to process
  1589. *
  1590. * @return none
  1591. */
  1592. static uint8 esp_ProcessInDefaultRspCmd( zclIncomingMsg_t *pInMsg )
  1593. {
  1594. // zclDefaultRspCmd_t *defaultRspCmd = (zclDefaultRspCmd_t *)pInMsg->attrCmd;
  1595. // Device is notified of the Default Response command.
  1596. return TRUE;
  1597. }
  1598. #if defined ( ZCL_DISCOVER )
  1599. /*********************************************************************
  1600. * @fn esp_ProcessInDiscRspCmd
  1601. *
  1602. * @brief Process the "Profile" Discover Response Command
  1603. *
  1604. * @param pInMsg - incoming message to process
  1605. *
  1606. * @return none
  1607. */
  1608. static uint8 esp_ProcessInDiscRspCmd( zclIncomingMsg_t *pInMsg )
  1609. {
  1610. zclDiscoverRspCmd_t *discoverRspCmd;
  1611. uint8 i;
  1612. discoverRspCmd = (zclDiscoverRspCmd_t *)pInMsg->attrCmd;
  1613. for ( i = 0; i < discoverRspCmd->numAttr; i++ )
  1614. {
  1615. // Device is notified of the result of its attribute discovery command.
  1616. }
  1617. return TRUE;
  1618. }
  1619. #endif // ZCL_DISCOVER
  1620. /****************************************************************************
  1621. ****************************************************************************/