simplemeter.c 70 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957
  1. /**************************************************************************************************
  2. Filename: simplemeter.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 Simple Meter functionality and
  6. 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 Simple Metering configuration:
  37. General Basic
  38. General Alarms
  39. General Time
  40. General Key Establishment
  41. SE Simple Metering
  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 "OSAL_Nv.h"
  54. #include "ZDApp.h"
  55. #include "ZDObject.h"
  56. #include "AddrMgr.h"
  57. #include "se.h"
  58. #include "simplemeter.h"
  59. #include "zcl_general.h"
  60. #include "zcl_se.h"
  61. #include "zcl_key_establish.h"
  62. #include "onboard.h"
  63. /* HAL */
  64. #include "hal_lcd.h"
  65. #include "hal_led.h"
  66. #include "hal_key.h"
  67. /*********************************************************************
  68. * MACROS
  69. */
  70. // There is no attribute in the Mandatory Reportable Attribute list for now
  71. #define zcl_MandatoryReportableAttribute( a ) ( a == NULL )
  72. /*********************************************************************
  73. * CONSTANTS
  74. */
  75. #define SIMPLEMETER_MIN_REPORTING_INTERVAL 5
  76. /*********************************************************************
  77. * TYPEDEFS
  78. */
  79. /*********************************************************************
  80. * GLOBAL VARIABLES
  81. */
  82. /*********************************************************************
  83. * GLOBAL FUNCTIONS
  84. */
  85. /*********************************************************************
  86. * LOCAL VARIABLES
  87. */
  88. static uint8 simpleMeterTaskID; // osal task id of simple meter
  89. static uint8 simpleMeterTransID; // transaction id
  90. static afAddrType_t ESPAddr; // esp destination address
  91. static zclReportCmd_t *pSeReportCmd; // report command structure for SE Cluster
  92. static zclReportCmd_t *pBasicReportCmd; // report command structure for Basic Cluster
  93. static uint8 numSeAttr = 5; // number of SE Cluster attributes in report
  94. static uint8 numBasicAttr = 2; // number of Basic Cluster attributes in report
  95. // Report attributes defined in simplemeter_data.c
  96. extern uint8 simpleMeterCurrentSummationDelivered[];
  97. extern const uint8 simpleMeterZCLVersion;
  98. extern const uint8 simpleMeterPowerSource;
  99. extern uint8 simpleMeterStatus;
  100. extern uint8 simpleMeterUnitOfMeasure;
  101. extern uint8 simpleMeterSummationFormating;
  102. extern uint8 simpleMeterDeviceType;
  103. #if SECURE
  104. static uint8 linkKeyStatus; // status return from get link key routine
  105. #endif
  106. #if defined ( SE_UK_EXT ) && defined ( SE_MIRROR )
  107. static afAddrType_t mirrorAddr;
  108. #endif // SE_UK_EXT && SE_MIRROR
  109. /*********************************************************************
  110. * LOCAL FUNCTIONS
  111. */
  112. static void simplemeter_HandleKeys( uint8 shift, uint8 keys );
  113. #if SECURE
  114. static uint8 simplemeter_KeyEstablish_ReturnLinkKey( uint16 shortAddr );
  115. #endif
  116. static void simplemeter_ProcessIdentifyTimeChange( void );
  117. /*************************************************************************/
  118. /*** Application Callback Functions ***/
  119. /*************************************************************************/
  120. // Foundation Callback functions
  121. static uint8 simplemeter_ValidateAttrDataCB( zclAttrRec_t *pAttr, zclWriteRec_t *pAttrInfo );
  122. // General Cluster Callback functions
  123. static void simplemeter_BasicResetCB( void );
  124. static void simplemeter_IdentifyCB( zclIdentify_t *pCmd );
  125. static void simplemeter_IdentifyQueryRspCB( zclIdentifyQueryRsp_t *pRsp );
  126. static void simplemeter_AlarmCB( zclAlarm_t *pAlarm );
  127. #ifdef SE_UK_EXT
  128. static void simplemeter_GetEventLogCB( uint8 srcEP, afAddrType_t *srcAddr,
  129. zclGetEventLog_t *pEventLog, uint8 seqNum );
  130. static void simplemeter_PublishEventLogCB( afAddrType_t *srcAddr,
  131. zclPublishEventLog_t *pEventLog );
  132. #endif // SE_UK_EXT
  133. // Function to process ZDO callback messages
  134. static void simplemeter_ProcessZDOMsgs( zdoIncomingMsg_t *pMsg );
  135. // SE Callback functions
  136. static void simplemeter_GetProfileCmdCB( zclCCGetProfileCmd_t *pCmd,
  137. afAddrType_t *srcAddr, uint8 seqNum );
  138. static void simplemeter_GetProfileRspCB( zclCCGetProfileRsp_t *pCmd,
  139. afAddrType_t *srcAddr, uint8 seqNum );
  140. static void simplemeter_ReqMirrorRspCB( zclCCReqMirrorRsp_t *pCmd,
  141. afAddrType_t *srcAddr, uint8 seqNum );
  142. static void simplemeter_MirrorRemRspCB( zclCCMirrorRemRsp_t *pCmd,
  143. afAddrType_t *srcAddr, uint8 seqNum );
  144. #if defined ( SE_UK_EXT )
  145. static void simplemeter_GetSnapshotCmdCB( zclCCReqGetSnapshotCmd_t *pCmd,
  146. afAddrType_t *srcAddr, uint8 seqNum );
  147. static void simplemeter_TakeSnapshotCmdCB( afAddrType_t *srcAddr, uint8 seqNum );
  148. static void simplemeter_MirrorReportAttrRspCB( zclCCReqMirrorReportAttrRsp_t *pCmd,
  149. afAddrType_t *srcAddr, uint8 seqNum );
  150. static void simplemeter_PublishTariffInformationCB( zclCCPublishTariffInformation_t *pCmd,
  151. afAddrType_t *srcAddr, uint8 seqNum );
  152. static void simplemeter_PublishPriceMatrixCB( zclCCPublishPriceMatrix_t *pCmd,
  153. afAddrType_t *srcAddr, uint8 seqNum );
  154. static void simplemeter_PublishBlockThresholdsCB( zclCCPublishBlockThresholds_t *pCmd,
  155. afAddrType_t *srcAddr, uint8 seqNum );
  156. static void simplemeter_PublishConversionFactorCB( zclCCPublishConversionFactor_t *pCmd,
  157. afAddrType_t *srcAddr, uint8 seqNum );
  158. static void simplemeter_PublishCalorificValueCB( zclCCPublishCalorificValue_t *pCmd,
  159. afAddrType_t *srcAddr, uint8 seqNum );
  160. static void simplemeter_PublishCO2ValueCB( zclCCPublishCO2Value_t *pCmd,
  161. afAddrType_t *srcAddr, uint8 seqNum );
  162. static void simplemeter_PublishCPPEventCB( zclCCPublishCPPEvent_t *pCmd,
  163. afAddrType_t *srcAddr, uint8 seqNum );
  164. static void simplemeter_PublishBillingPeriodCB( zclCCPublishBillingPeriod_t *pCmd,
  165. afAddrType_t *srcAddr, uint8 seqNum );
  166. static void simplemeter_PublishConsolidatedBillCB( zclCCPublishConsolidatedBill_t *pCmd,
  167. afAddrType_t *srcAddr, uint8 seqNum );
  168. static void simplemeter_PublishCreditPaymentInfoCB( zclCCPublishCreditPaymentInfo_t *pCmd,
  169. afAddrType_t *srcAddr, uint8 seqNum );
  170. static void simplemeter_ChangeDebtCB( zclCCChangeDebt_t *pCmd,
  171. afAddrType_t *srcAddr, uint8 seqNum );
  172. static void simplemeter_EmergencyCreditSetupCB( zclCCEmergencyCreditSetup_t *pCmd,
  173. afAddrType_t *srcAddr, uint8 seqNum );
  174. static void simplemeter_ConsumerTopupCB( zclCCConsumerTopup_t *pCmd,
  175. afAddrType_t *srcAddr, uint8 seqNum );
  176. static void simplemeter_CreditAdjustmentCB( zclCCCreditAdjustment_t *pCmd,
  177. afAddrType_t *srcAddr, uint8 seqNum );
  178. static void simplemeter_ChangePaymentModeCB( zclCCChangePaymentMode_t *pCmd,
  179. afAddrType_t *srcAddr, uint8 seqNum );
  180. static void simplemeter_GetPrepaySnapshotCB( zclCCGetPrepaySnapshot_t *pCmd,
  181. afAddrType_t *srcAddr, uint8 seqNum );
  182. static void simplemeter_GetTopupLogCB( uint8 numEvents,
  183. afAddrType_t *srcAddr, uint8 seqNum );
  184. static void simplemeter_SetLowCreditWarningLevelCB( uint8 numEvents,
  185. afAddrType_t *srcAddr, uint8 seqNum );
  186. static void simplemeter_GetDebtRepaymentLogCB( zclCCGetDebtRepaymentLog_t *pCmd,
  187. afAddrType_t *srcAddr, uint8 seqNum );
  188. #endif // SE_UK_EXT
  189. /************************************************************************/
  190. /*** Functions to process ZCL Foundation ***/
  191. /*** incoming Command/Response messages ***/
  192. /************************************************************************/
  193. static void simplemeter_ProcessZCLMsg( zclIncomingMsg_t *msg );
  194. #if defined ( ZCL_READ )
  195. static uint8 simplemeter_ProcessInReadRspCmd( zclIncomingMsg_t *pInMsg );
  196. #endif // ZCL_READ
  197. #if defined ( ZCL_WRITE )
  198. static uint8 simplemeter_ProcessInWriteRspCmd( zclIncomingMsg_t *pInMsg );
  199. #endif // ZCL_WRITE
  200. #if defined ( ZCL_REPORT )
  201. static uint8 simplemeter_ProcessInConfigReportCmd( zclIncomingMsg_t *pInMsg );
  202. static uint8 simplemeter_ProcessInConfigReportRspCmd( zclIncomingMsg_t *pInMsg );
  203. static uint8 simplemeter_ProcessInReadReportCfgCmd( zclIncomingMsg_t *pInMsg );
  204. static uint8 simplemeter_ProcessInReadReportCfgRspCmd( zclIncomingMsg_t *pInMsg );
  205. static uint8 simplemeter_ProcessInReportCmd( zclIncomingMsg_t *pInMsg );
  206. #endif // ZCL_REPORT
  207. static uint8 simplemeter_ProcessInDefaultRspCmd( zclIncomingMsg_t *pInMsg );
  208. #if defined ( ZCL_DISCOVER )
  209. static uint8 simplemeter_ProcessInDiscRspCmd( zclIncomingMsg_t *pInMsg );
  210. #endif // ZCL_DISCOVER
  211. /*********************************************************************
  212. * ZCL General Clusters Callback table
  213. */
  214. static zclGeneral_AppCallbacks_t simplemeter_GenCmdCallbacks =
  215. {
  216. simplemeter_BasicResetCB, // Basic Cluster Reset command
  217. simplemeter_IdentifyCB, // Identify command
  218. simplemeter_IdentifyQueryRspCB, // Identify Query Response command
  219. NULL, // On/Off cluster commands
  220. NULL, // Level Control Move to Level command
  221. NULL, // Level Control Move command
  222. NULL, // Level Control Step command
  223. NULL, // Level Control Stop command
  224. NULL, // Group Response commands
  225. NULL, // Scene Store Request command
  226. NULL, // Scene Recall Request command
  227. NULL, // Scene Response command
  228. simplemeter_AlarmCB, // Alarm (Response) command
  229. #ifdef SE_UK_EXT
  230. simplemeter_GetEventLogCB, // Get Event Log command
  231. simplemeter_PublishEventLogCB, // Publish Event Log command
  232. #endif
  233. NULL, // RSSI Location command
  234. NULL // RSSI Location Response command
  235. };
  236. /*********************************************************************
  237. * ZCL SE Clusters Callback table
  238. */
  239. static zclSE_AppCallbacks_t simplemeter_SECmdCallbacks =
  240. {
  241. NULL, // Publish Price
  242. NULL, // Publish Block Period
  243. #if defined ( SE_UK_EXT )
  244. simplemeter_PublishTariffInformationCB, // Publish Tariff Information
  245. simplemeter_PublishPriceMatrixCB, // Publish Price Matrix
  246. simplemeter_PublishBlockThresholdsCB, // Publish Block Thresholds
  247. simplemeter_PublishConversionFactorCB, // Publish Conversion Factor
  248. simplemeter_PublishCalorificValueCB, // Publish Calorific Value
  249. simplemeter_PublishCO2ValueCB, // Publish CO2 Value
  250. simplemeter_PublishCPPEventCB, // Publish CPP Event
  251. simplemeter_PublishBillingPeriodCB, // Publish Billing Period
  252. simplemeter_PublishConsolidatedBillCB, // Publish Consolidated Bill
  253. simplemeter_PublishCreditPaymentInfoCB, // Publish Credit Payment Info
  254. #endif // SE_UK_EXT
  255. NULL, // Get Current Price
  256. NULL, // Get Scheduled Price
  257. NULL, // Price Acknowledgement
  258. NULL, // Get Block Period
  259. #if defined ( SE_UK_EXT )
  260. NULL, // Get Tariff Information
  261. NULL, // Get Price Matrix
  262. NULL, // Get Block Thresholds
  263. NULL, // Get Conversion Factor
  264. NULL, // Get Calorific Value
  265. NULL, // Get CO2 Value
  266. NULL, // Get Billing Period
  267. NULL, // Get Consolidated Bill
  268. NULL, // CPP Event Response
  269. #endif // SE_UK_EXT
  270. NULL, // Load Control Event
  271. NULL, // Cancel Load Control Event
  272. NULL, // Cancel All Load Control Events
  273. NULL, // Report Event Status
  274. NULL, // Get Scheduled Event
  275. simplemeter_GetProfileRspCB, // Get Profile Response
  276. NULL, // Request Mirror Command
  277. NULL, // Mirror Remove Command
  278. NULL, // Request Fast Poll Mode Response
  279. #if defined ( SE_UK_EXT )
  280. NULL, // Get Snapshot Response
  281. #endif // SE_UK_EXT
  282. simplemeter_GetProfileCmdCB, // Get Profile Command
  283. simplemeter_ReqMirrorRspCB, // Request Mirror Response
  284. simplemeter_MirrorRemRspCB, // Mirror Remove Response
  285. NULL, // Request Fast Poll Mode Command
  286. #if defined ( SE_UK_EXT )
  287. simplemeter_GetSnapshotCmdCB, // Get Snapshot Command
  288. simplemeter_TakeSnapshotCmdCB, // Take Snapshot Command
  289. simplemeter_MirrorReportAttrRspCB, // Mirror Report Attribute Response
  290. #endif // SE_UK_EXT
  291. NULL, // Display Message Command
  292. NULL, // Cancel Message Command
  293. NULL, // Get Last Message Command
  294. NULL, // Message Confirmation
  295. NULL, // Request Tunnel Response
  296. NULL, // Transfer Data
  297. NULL, // Transfer Data Error
  298. NULL, // Ack Transfer Data
  299. NULL, // Ready Data
  300. #if defined ( SE_UK_EXT )
  301. NULL, // Supported Tunnel Protocols Response
  302. NULL, // Tunnel Closure Notification
  303. #endif // SE_UK_EXT
  304. NULL, // Request Tunnel
  305. NULL, // Close Tunnel
  306. #if defined ( SE_UK_EXT )
  307. NULL, // Get Supported Tunnel Protocols
  308. #endif // SE_UK_EXT
  309. NULL, // Supply Status Response
  310. #if defined ( SE_UK_EXT )
  311. NULL, // Get Prepay Snapshot Response
  312. NULL, // Change Payment Mode Response
  313. NULL, // Consumer Topup Response
  314. NULL, // Get Commands
  315. NULL, // Publish Topup Log
  316. NULL, // Publish Debt Log
  317. #endif // SE_UK_EXT
  318. NULL, // Select Available Emergency Credit Command
  319. NULL, // Change Supply Command
  320. #if defined ( SE_UK_EXT )
  321. simplemeter_ChangeDebtCB, // Change Debt
  322. simplemeter_EmergencyCreditSetupCB, // Emergency Credit Setup
  323. simplemeter_ConsumerTopupCB, // Consumer Topup
  324. simplemeter_CreditAdjustmentCB, // Credit Adjustment
  325. simplemeter_ChangePaymentModeCB, // Change PaymentMode
  326. simplemeter_GetPrepaySnapshotCB, // Get Prepay Snapshot
  327. simplemeter_GetTopupLogCB, // Get Topup Log
  328. simplemeter_SetLowCreditWarningLevelCB, // Set Low Credit Warning Level
  329. simplemeter_GetDebtRepaymentLogCB, // Get Debt Repayment Log
  330. NULL, // Publish Calendar
  331. NULL, // Publish Day Profile
  332. NULL, // Publish Week Profile
  333. NULL, // Publish Seasons
  334. NULL, // Publish Special Days
  335. NULL, // Get Calendar
  336. NULL, // Get Day Profiles
  337. NULL, // Get Week Profiles
  338. NULL, // Get Seasons
  339. NULL, // Get Special Days
  340. NULL, // Publish Change Tenancy
  341. NULL, // Publish Change Supplier
  342. NULL, // Change Supply
  343. NULL, // Change Password
  344. NULL, // Local Change Supply
  345. NULL, // Get Change Tenancy
  346. NULL, // Get Change Supplier
  347. NULL, // Get Change Supply
  348. NULL, // Supply Status Response
  349. NULL, // Get Password
  350. #endif // SE_UK_EXT
  351. };
  352. /*********************************************************************
  353. * @fn simplemeter_Init
  354. *
  355. * @brief Initialization function for the ZCL App Application.
  356. *
  357. * @param uint8 task_id - simple meter task id
  358. *
  359. * @return none
  360. */
  361. void simplemeter_Init( uint8 task_id )
  362. {
  363. simpleMeterTaskID = task_id;
  364. simpleMeterTransID = 0;
  365. // Device hardware initialization can be added here or in main() (Zmain.c).
  366. // If the hardware is application specific - add it here.
  367. // If the hardware is other parts of the device add it in main().
  368. // ESP destination address init
  369. ESPAddr.addrMode = (afAddrMode_t)Addr16Bit;
  370. ESPAddr.endPoint = SIMPLEMETER_ENDPOINT;
  371. ESPAddr.addr.shortAddr = 0;
  372. // register for SE endpoint
  373. zclSE_Init( &simpleMeterSimpleDesc );
  374. // Register the ZCL General Cluster Library callback functions
  375. zclGeneral_RegisterCmdCallbacks( SIMPLEMETER_ENDPOINT, &simplemeter_GenCmdCallbacks );
  376. // Register the ZCL SE Cluster Library callback functions
  377. zclSE_RegisterCmdCallbacks( SIMPLEMETER_ENDPOINT, &simplemeter_SECmdCallbacks );
  378. // Register the application's attribute list
  379. zcl_registerAttrList( SIMPLEMETER_ENDPOINT, SIMPLEMETER_MAX_ATTRIBUTES, simpleMeterAttrs );
  380. // Register the application's cluster option list
  381. zcl_registerClusterOptionList( SIMPLEMETER_ENDPOINT, SIMPLEMETER_MAX_OPTIONS, simpleMeterOptions );
  382. // Register the application's attribute data validation callback function
  383. zcl_registerValidateAttrData( simplemeter_ValidateAttrDataCB );
  384. // Register the Application to receive the unprocessed Foundation command/response messages
  385. zcl_registerForMsg( simpleMeterTaskID );
  386. // Register for all key events - This app will handle all key events
  387. RegisterForKeys( simpleMeterTaskID );
  388. // Register with the ZDO to receive Match Descriptor Responses
  389. ZDO_RegisterForZDOMsg(task_id, Match_Desc_rsp);
  390. // Start the timer to sync SimpleMeter timer with the osal timer
  391. osal_start_timerEx( simpleMeterTaskID, SIMPLEMETER_UPDATE_TIME_EVT, SIMPLEMETER_UPDATE_TIME_PERIOD );
  392. // setup attribute IDs of interest for Simple Meter
  393. pBasicReportCmd = (zclReportCmd_t *)osal_mem_alloc( sizeof( zclReportCmd_t ) + ( numBasicAttr * sizeof( zclReport_t ) ) );
  394. if ( pBasicReportCmd != NULL )
  395. {
  396. pBasicReportCmd->numAttr = numBasicAttr;
  397. pBasicReportCmd->attrList[0].attrID = ATTRID_BASIC_ZCL_VERSION;
  398. pBasicReportCmd->attrList[0].dataType = ZCL_DATATYPE_UINT8;
  399. pBasicReportCmd->attrList[0].attrData = (uint8*) &simpleMeterZCLVersion;
  400. pBasicReportCmd->attrList[1].attrID = ATTRID_BASIC_POWER_SOURCE;
  401. pBasicReportCmd->attrList[1].dataType = ZCL_DATATYPE_ENUM8;
  402. pBasicReportCmd->attrList[1].attrData = (uint8*) &simpleMeterPowerSource;
  403. }
  404. pSeReportCmd = (zclReportCmd_t *)osal_mem_alloc( sizeof( zclReportCmd_t ) + ( numSeAttr * sizeof( zclReport_t ) ) );
  405. if ( pSeReportCmd != NULL )
  406. {
  407. pSeReportCmd->numAttr = numSeAttr;
  408. // Set up the first attribute
  409. pSeReportCmd->attrList[0].attrID = ATTRID_SE_CURRENT_SUMMATION_DELIVERED;
  410. pSeReportCmd->attrList[0].dataType = ZCL_DATATYPE_UINT48;
  411. pSeReportCmd->attrList[0].attrData = simpleMeterCurrentSummationDelivered;
  412. pSeReportCmd->attrList[1].attrID = ATTRID_SE_STATUS;
  413. pSeReportCmd->attrList[1].dataType = ZCL_DATATYPE_BITMAP8;
  414. pSeReportCmd->attrList[1].attrData = &simpleMeterStatus;
  415. pSeReportCmd->attrList[2].attrID = ATTRID_SE_UNIT_OF_MEASURE;
  416. pSeReportCmd->attrList[2].dataType = ZCL_DATATYPE_ENUM8;
  417. pSeReportCmd->attrList[2].attrData = &simpleMeterUnitOfMeasure;
  418. pSeReportCmd->attrList[3].attrID = ATTRID_SE_SUMMATION_FORMATTING;
  419. pSeReportCmd->attrList[3].dataType = ZCL_DATATYPE_BITMAP8;
  420. pSeReportCmd->attrList[3].attrData = &simpleMeterSummationFormating;
  421. pSeReportCmd->attrList[4].attrID = ATTRID_SE_METERING_DEVICE_TYPE;
  422. pSeReportCmd->attrList[4].dataType = ZCL_DATATYPE_BITMAP8;
  423. pSeReportCmd->attrList[4].attrData = &simpleMeterDeviceType;
  424. // Set up additional attributes
  425. }
  426. }
  427. /*********************************************************************
  428. * @fn simplemeter_event_loop
  429. *
  430. * @brief Event Loop Processor for the simple meter.
  431. *
  432. * @param uint8 task_id - the osal task id
  433. * @param uint16 events - the event bitmask
  434. *
  435. * @return none
  436. */
  437. uint16 simplemeter_event_loop( uint8 task_id, uint16 events )
  438. {
  439. afIncomingMSGPacket_t *MSGpkt;
  440. if ( events & SYS_EVENT_MSG )
  441. {
  442. while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( simpleMeterTaskID )) )
  443. {
  444. switch ( MSGpkt->hdr.event )
  445. {
  446. case ZDO_CB_MSG:
  447. simplemeter_ProcessZDOMsgs( (zdoIncomingMsg_t *)MSGpkt );
  448. break;
  449. case ZCL_INCOMING_MSG:
  450. // Incoming ZCL foundation command/response messages
  451. simplemeter_ProcessZCLMsg( (zclIncomingMsg_t *)MSGpkt );
  452. break;
  453. case KEY_CHANGE:
  454. simplemeter_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );
  455. break;
  456. case ZDO_STATE_CHANGE:
  457. if ((DEV_END_DEVICE == (devStates_t)(MSGpkt->hdr.status)) ||
  458. (DEV_ROUTER == (devStates_t)(MSGpkt->hdr.status)))
  459. {
  460. #if SECURE
  461. {
  462. // check to see if link key had already been established
  463. linkKeyStatus = simplemeter_KeyEstablish_ReturnLinkKey(ESPAddr.addr.shortAddr);
  464. if (linkKeyStatus != ZSuccess)
  465. {
  466. cId_t cbkeCluster = ZCL_CLUSTER_ID_GEN_KEY_ESTABLISHMENT;
  467. zAddrType_t dstAddr;
  468. // Send out a match for the key establishment
  469. dstAddr.addrMode = AddrBroadcast;
  470. dstAddr.addr.shortAddr = NWK_BROADCAST_SHORTADDR;
  471. ZDP_MatchDescReq( &dstAddr, NWK_BROADCAST_SHORTADDR, ZCL_SE_PROFILE_ID,
  472. 1, &cbkeCluster, 0, NULL, FALSE );
  473. }
  474. else
  475. {
  476. // link key already established, resume sending reports
  477. osal_set_event( simpleMeterTaskID, SIMPLEMETER_CONNECTED_EVT );
  478. }
  479. }
  480. #else
  481. {
  482. osal_set_event( simpleMeterTaskID, SIMPLEMETER_CONNECTED_EVT );
  483. }
  484. #endif
  485. // per smart energy spec end device polling requirement of not to poll < 7.5 seconds
  486. NLME_SetPollRate ( SE_DEVICE_POLL_RATE );
  487. }
  488. break;
  489. #if defined( ZCL_KEY_ESTABLISH )
  490. case ZCL_KEY_ESTABLISH_IND:
  491. if ((MSGpkt->hdr.status) == TermKeyStatus_Success)
  492. {
  493. ESPAddr.endPoint = SIMPLEMETER_ENDPOINT; // set destination endpoint back to application endpoint
  494. osal_set_event( simpleMeterTaskID, SIMPLEMETER_CONNECTED_EVT );
  495. }
  496. break;
  497. #endif
  498. default:
  499. break;
  500. }
  501. // Release the memory
  502. osal_msg_deallocate( (uint8 *)MSGpkt );
  503. }
  504. // return unprocessed events
  505. return (events ^ SYS_EVENT_MSG);
  506. }
  507. // event to intiate key establishment request
  508. if ( events & SIMPLEMETER_KEY_ESTABLISHMENT_REQUEST_EVT )
  509. {
  510. zclGeneral_KeyEstablish_InitiateKeyEstablishment(simpleMeterTaskID, &ESPAddr, simpleMeterTransID);
  511. return ( events ^ SIMPLEMETER_KEY_ESTABLISHMENT_REQUEST_EVT );
  512. }
  513. // Event indicating the meter has connected, and the security process has completed
  514. if ( events & SIMPLEMETER_CONNECTED_EVT )
  515. {
  516. #if defined ( SE_UK_EXT ) && defined ( SE_MIRROR )
  517. // Request a mirror on the ESP
  518. zclSE_SimpleMetering_Send_ReqMirrorCmd(SIMPLEMETER_ENDPOINT, &ESPAddr, TRUE, 0);
  519. #endif // SE_UK_EXT && SE_MIRROR
  520. // Start Reporting attributes
  521. osal_start_timerEx( simpleMeterTaskID, SIMPLEMETER_REPORT_ATTRIBUTE_EVT, SIMPLEMETER_REPORT_PERIOD );
  522. return ( events ^ SIMPLEMETER_CONNECTED_EVT );
  523. }
  524. // event to send report attribute
  525. if ( events & SIMPLEMETER_REPORT_ATTRIBUTE_EVT )
  526. {
  527. if ( pSeReportCmd != NULL )
  528. {
  529. zcl_SendReportCmd( SIMPLEMETER_ENDPOINT, &ESPAddr,
  530. ZCL_CLUSTER_ID_SE_SIMPLE_METERING, pSeReportCmd,
  531. ZCL_FRAME_SERVER_CLIENT_DIR, 1, 0 );
  532. osal_start_timerEx( simpleMeterTaskID, SIMPLEMETER_REPORT_ATTRIBUTE_EVT, SIMPLEMETER_REPORT_PERIOD );
  533. }
  534. return ( events ^ SIMPLEMETER_REPORT_ATTRIBUTE_EVT );
  535. }
  536. // handle processing of identify timeout event triggered by an identify command
  537. if ( events & SIMPLEMETER_IDENTIFY_TIMEOUT_EVT )
  538. {
  539. if ( simpleMeterIdentifyTime > 0 )
  540. {
  541. simpleMeterIdentifyTime--;
  542. }
  543. simplemeter_ProcessIdentifyTimeChange();
  544. return ( events ^ SIMPLEMETER_IDENTIFY_TIMEOUT_EVT );
  545. }
  546. // event to get current time
  547. if ( events & SIMPLEMETER_UPDATE_TIME_EVT )
  548. {
  549. simpleMeterTime = osal_getClock();
  550. osal_start_timerEx( simpleMeterTaskID, SIMPLEMETER_UPDATE_TIME_EVT, SIMPLEMETER_UPDATE_TIME_PERIOD );
  551. return ( events ^ SIMPLEMETER_UPDATE_TIME_EVT );
  552. }
  553. // Discard unknown events
  554. return 0;
  555. }
  556. /*********************************************************************
  557. * @fn simplemeter_ProcessZDOMsgs
  558. *
  559. * @brief Called to process callbacks from the ZDO.
  560. *
  561. * @param none
  562. *
  563. * @return none
  564. */
  565. static void simplemeter_ProcessZDOMsgs( zdoIncomingMsg_t *pMsg )
  566. {
  567. if (pMsg->clusterID == Match_Desc_rsp)
  568. {
  569. ZDO_ActiveEndpointRsp_t *pRsp = ZDO_ParseEPListRsp( pMsg );
  570. if (pRsp)
  571. {
  572. if (pRsp->cnt)
  573. {
  574. // Record the trust center
  575. ESPAddr.endPoint = pRsp->epList[0];
  576. ESPAddr.addr.shortAddr = pMsg->srcAddr.addr.shortAddr;
  577. // send out key establishment request
  578. osal_set_event( simpleMeterTaskID, SIMPLEMETER_KEY_ESTABLISHMENT_REQUEST_EVT);
  579. }
  580. osal_mem_free(pRsp);
  581. }
  582. }
  583. }
  584. /*********************************************************************
  585. * @fn simplemeter_ProcessIdentifyTimeChange
  586. *
  587. * @brief Called to blink led for specified IdentifyTime attribute value
  588. *
  589. * @param none
  590. *
  591. * @return none
  592. */
  593. static void simplemeter_ProcessIdentifyTimeChange( void )
  594. {
  595. if ( simpleMeterIdentifyTime > 0 )
  596. {
  597. osal_start_timerEx( simpleMeterTaskID, SIMPLEMETER_IDENTIFY_TIMEOUT_EVT, 1000 );
  598. HalLedBlink ( HAL_LED_4, 0xFF, HAL_LED_DEFAULT_DUTY_CYCLE, HAL_LED_DEFAULT_FLASH_TIME );
  599. }
  600. else
  601. {
  602. HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
  603. osal_stop_timerEx( simpleMeterTaskID, SIMPLEMETER_IDENTIFY_TIMEOUT_EVT );
  604. }
  605. }
  606. #if SECURE
  607. /*********************************************************************
  608. * @fn simplemeter_KeyEstablish_ReturnLinkKey
  609. *
  610. * @brief This function get the requested link key
  611. *
  612. * @param shortAddr - short address of the partner.
  613. *
  614. * @return none
  615. */
  616. static uint8 simplemeter_KeyEstablish_ReturnLinkKey( uint16 shortAddr )
  617. {
  618. uint8 status = ZFailure;
  619. AddrMgrEntry_t entry;
  620. // Look up the long address of the device
  621. entry.user = ADDRMGR_USER_DEFAULT;
  622. entry.nwkAddr = shortAddr;
  623. if ( AddrMgrEntryLookupNwk( &entry ) )
  624. {
  625. // check if APS link key has been established
  626. if ( APSME_IsLinkKeyValid( entry.extAddr ) == TRUE )
  627. {
  628. status = ZSuccess;
  629. }
  630. }
  631. else
  632. {
  633. // It's an unknown device
  634. status = ZInvalidParameter;
  635. }
  636. return status;
  637. }
  638. #endif
  639. /*********************************************************************
  640. * @fn simplemeter_HandleKeys
  641. *
  642. * @brief Handles all key events for this device.
  643. *
  644. * @param shift - true if in shift/alt.
  645. * @param keys - bit field for key events. Valid entries:
  646. * HAL_KEY_SW_4
  647. * HAL_KEY_SW_3
  648. * HAL_KEY_SW_2
  649. * HAL_KEY_SW_1
  650. *
  651. * @return none
  652. */
  653. static void simplemeter_HandleKeys( uint8 shift, uint8 keys )
  654. {
  655. // Shift is used to make each button/switch dual purpose.
  656. if ( shift )
  657. {
  658. if ( keys & HAL_KEY_SW_1 )
  659. {
  660. }
  661. if ( keys & HAL_KEY_SW_2 )
  662. {
  663. }
  664. if ( keys & HAL_KEY_SW_3 )
  665. {
  666. }
  667. if ( keys & HAL_KEY_SW_4 )
  668. {
  669. }
  670. }
  671. else
  672. {
  673. if ( keys & HAL_KEY_SW_1 )
  674. {
  675. ZDOInitDevice(0); // Join the network.
  676. }
  677. if ( keys & HAL_KEY_SW_2 )
  678. {
  679. // Remove mirror
  680. zclSE_SimpleMetering_Send_RemMirrorCmd(SIMPLEMETER_ENDPOINT, &ESPAddr, TRUE, 0);
  681. }
  682. if ( keys & HAL_KEY_SW_3 )
  683. {
  684. }
  685. if ( keys & HAL_KEY_SW_4 )
  686. {
  687. }
  688. }
  689. }
  690. /*********************************************************************
  691. * @fn simplemeter_ValidateAttrDataCB
  692. *
  693. * @brief Check to see if the supplied value for the attribute data
  694. * is within the specified range of the attribute.
  695. *
  696. * @param pAttr - pointer to attribute
  697. * @param pAttrInfo - pointer to attribute info
  698. *
  699. * @return TRUE if data valid. FALSE otherwise.
  700. */
  701. static uint8 simplemeter_ValidateAttrDataCB( zclAttrRec_t *pAttr, zclWriteRec_t *pAttrInfo )
  702. {
  703. uint8 valid = TRUE;
  704. switch ( pAttrInfo->dataType )
  705. {
  706. case ZCL_DATATYPE_BOOLEAN:
  707. if ( ( *(pAttrInfo->attrData) != 0 ) && ( *(pAttrInfo->attrData) != 1 ) )
  708. valid = FALSE;
  709. break;
  710. default:
  711. break;
  712. }
  713. return ( valid );
  714. }
  715. /*********************************************************************
  716. * @fn simplemeter_BasicResetCB
  717. *
  718. * @brief Callback from the ZCL General Cluster Library to set all
  719. * the attributes of all the clusters to their factory defaults
  720. *
  721. * @param none
  722. *
  723. * @return none
  724. */
  725. static void simplemeter_BasicResetCB( void )
  726. {
  727. // user should handle setting attributes to factory defaults here
  728. }
  729. /*********************************************************************
  730. * @fn simplemeter_IdentifyCB
  731. *
  732. * @brief Callback from the ZCL General Cluster Library when
  733. * it received an Identity Command for this application.
  734. *
  735. * @param pCmd - pointer to structure for Identify command
  736. *
  737. * @return none
  738. */
  739. static void simplemeter_IdentifyCB( zclIdentify_t *pCmd )
  740. {
  741. simpleMeterIdentifyTime = pCmd->identifyTime;
  742. simplemeter_ProcessIdentifyTimeChange();
  743. }
  744. /*********************************************************************
  745. * @fn simplemeter_IdentifyQueryRspCB
  746. *
  747. * @brief Callback from the ZCL General Cluster Library when
  748. * it received an Identity Query Response Command for this application.
  749. *
  750. * @param pRsp - pointer to structure for Identity Query Response command
  751. *
  752. * @return none
  753. */
  754. static void simplemeter_IdentifyQueryRspCB( zclIdentifyQueryRsp_t *pRsp )
  755. {
  756. // add user code here
  757. }
  758. /*********************************************************************
  759. * @fn simplemeter_AlarmCB
  760. *
  761. * @brief Callback from the ZCL General Cluster Library when
  762. * it received an Alarm request or response command for
  763. * this application.
  764. *
  765. * @param pAlarm - pointer to structure for Alarm command
  766. *
  767. * @return none
  768. */
  769. static void simplemeter_AlarmCB( zclAlarm_t *pAlarm )
  770. {
  771. // add user code here
  772. }
  773. #ifdef SE_UK_EXT
  774. /*********************************************************************
  775. * @fn simplemeter_GetEventLogCB
  776. *
  777. * @brief Callback from the ZCL General Cluster Library when
  778. * it received a Get Event Log command for this
  779. * application.
  780. *
  781. * @param srcEP - source endpoint
  782. * @param srcAddr - pointer to source address
  783. * @param pEventLog - pointer to structure for Get Event Log command
  784. * @param seqNum - sequence number of this command
  785. *
  786. * @return none
  787. */
  788. static void simplemeter_GetEventLogCB( uint8 srcEP, afAddrType_t *srcAddr,
  789. zclGetEventLog_t *pEventLog, uint8 seqNum )
  790. {
  791. // add user code here, which could fragment the event log payload if
  792. // the entire payload doesn't fit into one Publish Event Log Command.
  793. // Note: the Command Index starts at 0 and is incremented for each
  794. // fragment belonging to the same command.
  795. // There's no event log for now! The Metering Device will support
  796. // logging for all events configured to do so.
  797. }
  798. /*********************************************************************
  799. * @fn simplemeter_PublishEventLogCB
  800. *
  801. * @brief Callback from the ZCL General Cluster Library when
  802. * it received a Publish Event Log command for this
  803. * application.
  804. *
  805. * @param srcAddr - pointer to source address
  806. * @param pEventLog - pointer to structure for Publish Event Log command
  807. *
  808. * @return none
  809. */
  810. static void simplemeter_PublishEventLogCB( afAddrType_t *srcAddr, zclPublishEventLog_t *pEventLog )
  811. {
  812. // add user code here
  813. }
  814. #endif // SE_UK_EXT
  815. /*********************************************************************
  816. * @fn simplemeter_GetProfileCmdCB
  817. *
  818. * @brief Callback from the ZCL SE Profile Simple Metering Cluster Library when
  819. * it received a Get Profile Command for
  820. * this application.
  821. *
  822. * @param pCmd - pointer to structure for Get Profile command
  823. * @param srcAddr - pointer to source address
  824. * @param seqNum - sequence number of this command
  825. *
  826. * @return none
  827. */
  828. static void simplemeter_GetProfileCmdCB( zclCCGetProfileCmd_t *pCmd,
  829. afAddrType_t *srcAddr, uint8 seqNum )
  830. {
  831. #if defined ( ZCL_SIMPLE_METERING )
  832. // Upon receipt of the Get Profile Command, the metering device shall send
  833. // Get Profile Response back.
  834. // Variables in the following are initialized to arbitrary value for test purpose
  835. // In real application, user shall look up the interval data captured during
  836. // the period specified in the pCmd->endTime and return corresponding data.
  837. uint32 endTime;
  838. uint8 status = zclSE_SimpleMeter_GetProfileRsp_Status_Success;
  839. uint8 profileIntervalPeriod = PROFILE_INTERVAL_PERIOD_60MIN;
  840. uint8 numberOfPeriodDelivered = 5;
  841. uint24 intervals[] = {0xa00001, 0xa00002, 0xa00003, 0xa00004, 0xa00005};
  842. // endTime: 32 bit value (in UTC) representing the end time of the most
  843. // chronologically recent interval being requested.
  844. // Example: Data collected from 2:00 PM to 3:00 PM would be specified as a
  845. // 3:00 PM interval (end time).
  846. // The Intervals block returned shall be the most recent block with
  847. // its EndTime equal or older to the one in the request (pCmd->endTime).
  848. // Requested End Time with value 0xFFFFFFFF indicats the most recent
  849. // Intervals block is requested.
  850. // Sample Code - assuming the end time of the requested block is the same as
  851. // it in the request.
  852. endTime = pCmd->endTime;
  853. // Send Get Profile Response Command back
  854. zclSE_SimpleMetering_Send_GetProfileRsp( SIMPLEMETER_ENDPOINT, srcAddr, endTime,
  855. status,
  856. profileIntervalPeriod,
  857. numberOfPeriodDelivered, intervals,
  858. FALSE, seqNum );
  859. #endif // ZCL_SIMPLE_METERING
  860. }
  861. /*********************************************************************
  862. * @fn simplemeter_GetProfileRspCB
  863. *
  864. * @brief Callback from the ZCL SE Profile Simple Metering Cluster Library when
  865. * it received a Get Profile Response for
  866. * this application.
  867. *
  868. * @param pCmd - pointer to structure for Get Profile Response command
  869. * @param srcAddr - pointer to source address
  870. * @param seqNum - sequence number of this command
  871. *
  872. * @return none
  873. */
  874. static void simplemeter_GetProfileRspCB( zclCCGetProfileRsp_t *pCmd,
  875. afAddrType_t *srcAddr, uint8 seqNum )
  876. {
  877. // add user code here
  878. }
  879. /*********************************************************************
  880. * @fn simplemeter_ReqMirrorRspCB
  881. *
  882. * @brief Callback from the ZCL SE Profile Simple Metering Cluster Library when
  883. * it received a Request Mirror Response for
  884. * this application.
  885. *
  886. * @param pCmd - pointer to structure for Request Mirror Response command
  887. * @param srcAddr - pointer to source address
  888. * @param seqNum - sequence number of this command
  889. *
  890. * @return none
  891. */
  892. static void simplemeter_ReqMirrorRspCB( zclCCReqMirrorRsp_t *pCmd,
  893. afAddrType_t *srcAddr, uint8 seqNum )
  894. {
  895. #if defined ( ZCL_SIMPLE_METERING )
  896. #if defined ( SE_UK_EXT ) && defined ( SE_MIRROR )
  897. if ( pCmd != NULL )
  898. {
  899. if (pCmd->endpointId == 0xFFFF)
  900. {
  901. // The create mirror failed, try another ESP
  902. // Add user code
  903. }
  904. else
  905. {
  906. // Record the mirror address and endpoint
  907. osal_memcpy(&mirrorAddr, srcAddr, sizeof(afAddrType_t));
  908. mirrorAddr.endPoint = pCmd->endpointId;
  909. // Send a report attribute to the mirror endpoint
  910. if (pSeReportCmd)
  911. {
  912. zcl_SendReportCmd( SIMPLEMETER_ENDPOINT, &mirrorAddr,
  913. ZCL_CLUSTER_ID_SE_SIMPLE_METERING, pSeReportCmd,
  914. ZCL_FRAME_SERVER_CLIENT_DIR, 1, 0 );
  915. }
  916. if (pBasicReportCmd)
  917. {
  918. zcl_SendReportCmd( SIMPLEMETER_ENDPOINT, &mirrorAddr,
  919. ZCL_CLUSTER_ID_GEN_BASIC, pBasicReportCmd,
  920. ZCL_FRAME_SERVER_CLIENT_DIR, 1, 0 );
  921. }
  922. }
  923. }
  924. #endif // SE_UK_EXT && SE_MIRROR
  925. #endif // ZCL_SIMPLE_METERING
  926. }
  927. /*********************************************************************
  928. * @fn simplemeter_MirrorRemRspCB
  929. *
  930. * @brief Callback from the ZCL SE Profile Simple Metering Cluster Library when
  931. * it received a Mirror Remove Response for
  932. * this application.
  933. *
  934. * @param pCmd - pointer to structure for Mirror Remove Response command
  935. * @param srcAddr - pointer to source address
  936. * @param seqNum - sequence number of this command
  937. *
  938. * @return none
  939. */
  940. static void simplemeter_MirrorRemRspCB( zclCCMirrorRemRsp_t *pCmd,
  941. afAddrType_t *srcAddr, uint8 seqNum )
  942. {
  943. #if defined ( ZCL_SIMPLE_METERING )
  944. osal_stop_timerEx( simpleMeterTaskID, SIMPLEMETER_REPORT_ATTRIBUTE_EVT );
  945. #endif // ZCL_SIMPLE_METERING
  946. }
  947. #if defined ( SE_UK_EXT )
  948. /*********************************************************************
  949. * @fn simplemeter_GetSnapshotCmdCB
  950. *
  951. * @brief Callback from the ZCL SE Profile Simple Metering Cluster Library when
  952. * it received a Get Snapshot Command for
  953. * this application.
  954. *
  955. * @param pCmd - pointer to structure for Get Snapshot command
  956. * @param srcAddr - pointer to source address
  957. * @param seqNum - sequence number of this command
  958. *
  959. * @return none
  960. */
  961. static void simplemeter_GetSnapshotCmdCB( zclCCReqGetSnapshotCmd_t *pCmd,
  962. afAddrType_t *srcAddr, uint8 seqNum )
  963. {
  964. // add user code here
  965. }
  966. /*********************************************************************
  967. * @fn simplemeter_TakeSnapshotCmdCB
  968. *
  969. * @brief Callback from the ZCL SE Profile Simple Metering Cluster Library when
  970. * it received a Take Snapshot Command for
  971. * this application.
  972. *
  973. * @param srcAddr - pointer to source address
  974. * @param seqNum - sequence number of this command
  975. *
  976. * @return none
  977. */
  978. static void simplemeter_TakeSnapshotCmdCB( afAddrType_t *srcAddr, uint8 seqNum )
  979. {
  980. // add user code to store the snapshot
  981. }
  982. /*********************************************************************
  983. * @fn simplemeter_MirrorReportAttrRspCB
  984. *
  985. * @brief Callback from the ZCL SE Profile Simple Metering Cluster Library when
  986. * it received a Mirror Report Attribute Response for
  987. * this application.
  988. *
  989. * @param pCmd - pointer to structure for Mirror Report Attribute Response command
  990. * @param srcAddr - pointer to source address
  991. * @param seqNum - sequence number of this command
  992. *
  993. * @return none
  994. */
  995. static void simplemeter_MirrorReportAttrRspCB( zclCCReqMirrorReportAttrRsp_t *pCmd,
  996. afAddrType_t *srcAddr, uint8 seqNum )
  997. {
  998. // add user code here
  999. }
  1000. /*********************************************************************
  1001. * @fn simplemeter_PublishTariffInformationCB
  1002. *
  1003. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1004. * it received a Publish Tariff Information for this application.
  1005. *
  1006. * @param pCmd - pointer to structure for Publish Tariff Information command
  1007. * @param srcAddr - pointer to source address
  1008. * @param seqNum - sequence number of this command
  1009. *
  1010. * @return none
  1011. */
  1012. static void simplemeter_PublishTariffInformationCB( zclCCPublishTariffInformation_t *pCmd,
  1013. afAddrType_t *srcAddr, uint8 seqNum )
  1014. {
  1015. // add user code here
  1016. }
  1017. /*********************************************************************
  1018. * @fn simplemeter_PublishPriceMatrixCB
  1019. *
  1020. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1021. * it received a Publish Price Matrix for this application.
  1022. *
  1023. * @param pCmd - pointer to structure for Publish Price Matrix command
  1024. * @param srcAddr - pointer to source address
  1025. * @param seqNum - sequence number of this command
  1026. *
  1027. * @return none
  1028. */
  1029. static void simplemeter_PublishPriceMatrixCB( zclCCPublishPriceMatrix_t *pCmd,
  1030. afAddrType_t *srcAddr, uint8 seqNum )
  1031. {
  1032. // add user code here
  1033. }
  1034. /*********************************************************************
  1035. * @fn simplemeter_PublishBlockThresholdsCB
  1036. *
  1037. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1038. * it received a Publish Block Thresholds for this application.
  1039. *
  1040. * @param pCmd - pointer to structure for Publish Block Thresholds command
  1041. * @param srcAddr - pointer to source address
  1042. * @param seqNum - sequence number of this command
  1043. *
  1044. * @return none
  1045. */
  1046. static void simplemeter_PublishBlockThresholdsCB( zclCCPublishBlockThresholds_t *pCmd,
  1047. afAddrType_t *srcAddr, uint8 seqNum )
  1048. {
  1049. // add user code here
  1050. }
  1051. /*********************************************************************
  1052. * @fn simplemeter_PublishConversionFactorCB
  1053. *
  1054. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1055. * it received a Publish Conversion Factor for this application.
  1056. *
  1057. * @param pCmd - pointer to structure for Publish Conversion Factor command
  1058. * @param srcAddr - pointer to source address
  1059. * @param seqNum - sequence number of this command
  1060. *
  1061. * @return none
  1062. */
  1063. static void simplemeter_PublishConversionFactorCB( zclCCPublishConversionFactor_t *pCmd,
  1064. afAddrType_t *srcAddr, uint8 seqNum )
  1065. {
  1066. // add user code here
  1067. }
  1068. /*********************************************************************
  1069. * @fn simplemeter_PublishCalorificValueCB
  1070. *
  1071. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1072. * it received a Publish Calorific Value for this application.
  1073. *
  1074. * @param pCmd - pointer to structure for Publish Calorific Value command
  1075. * @param srcAddr - pointer to source address
  1076. * @param seqNum - sequence number of this command
  1077. *
  1078. * @return none
  1079. */
  1080. static void simplemeter_PublishCalorificValueCB( zclCCPublishCalorificValue_t *pCmd,
  1081. afAddrType_t *srcAddr, uint8 seqNum )
  1082. {
  1083. // add user code here
  1084. }
  1085. /*********************************************************************
  1086. * @fn simplemeter_PublishCO2ValueCB
  1087. *
  1088. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1089. * it received a Publish CO2 Value for this application.
  1090. *
  1091. * @param pCmd - pointer to structure for Publish CO2 Value command
  1092. * @param srcAddr - pointer to source address
  1093. * @param seqNum - sequence number of this command
  1094. *
  1095. * @return none
  1096. */
  1097. static void simplemeter_PublishCO2ValueCB( zclCCPublishCO2Value_t *pCmd,
  1098. afAddrType_t *srcAddr, uint8 seqNum )
  1099. {
  1100. // add user code here
  1101. }
  1102. /*********************************************************************
  1103. * @fn simplemeter_PublishCPPEventCB
  1104. *
  1105. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1106. * it received a Publish CPP Event for this application.
  1107. *
  1108. * @param pCmd - pointer to structure for Publish CPP Event command
  1109. * @param srcAddr - pointer to source address
  1110. * @param seqNum - sequence number of this command
  1111. *
  1112. * @return none
  1113. */
  1114. static void simplemeter_PublishCPPEventCB( zclCCPublishCPPEvent_t *pCmd,
  1115. afAddrType_t *srcAddr, uint8 seqNum )
  1116. {
  1117. // add user code here
  1118. }
  1119. /*********************************************************************
  1120. * @fn simplemeter_PublishBillingPeriodCB
  1121. *
  1122. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1123. * it received a Publish Billing Period for this application.
  1124. *
  1125. * @param pCmd - pointer to structure for Publish Billing Period command
  1126. * @param srcAddr - pointer to source address
  1127. * @param seqNum - sequence number of this command
  1128. *
  1129. * @return none
  1130. */
  1131. static void simplemeter_PublishBillingPeriodCB( zclCCPublishBillingPeriod_t *pCmd,
  1132. afAddrType_t *srcAddr, uint8 seqNum )
  1133. {
  1134. // add user code here
  1135. }
  1136. /*********************************************************************
  1137. * @fn simplemeter_PublishConsolidatedBillCB
  1138. *
  1139. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1140. * it received a Publish Consolidated Bill for this application.
  1141. *
  1142. * @param pCmd - pointer to structure for Publish Consolidated Bill command
  1143. * @param srcAddr - pointer to source address
  1144. * @param seqNum - sequence number of this command
  1145. *
  1146. * @return none
  1147. */
  1148. static void simplemeter_PublishConsolidatedBillCB( zclCCPublishConsolidatedBill_t *pCmd,
  1149. afAddrType_t *srcAddr, uint8 seqNum )
  1150. {
  1151. // add user code here
  1152. }
  1153. /*********************************************************************
  1154. * @fn simplemeter_PublishCreditPaymentInfoCB
  1155. *
  1156. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1157. * it received a Publish Credit Payment Info for this application.
  1158. *
  1159. * @param pCmd - pointer to structure for Publish Credit Payment Info command
  1160. * @param srcAddr - pointer to source address
  1161. * @param seqNum - sequence number of this command
  1162. *
  1163. * @return none
  1164. */
  1165. static void simplemeter_PublishCreditPaymentInfoCB( zclCCPublishCreditPaymentInfo_t *pCmd,
  1166. afAddrType_t *srcAddr, uint8 seqNum )
  1167. {
  1168. // add user code here
  1169. }
  1170. /*********************************************************************
  1171. * @fn simplemeter_ChangeDebtCB
  1172. *
  1173. * @brief Callback from the ZCL SE Profile Prepayment Cluster Library when
  1174. * it received a Change Debt for this application.
  1175. *
  1176. * @param pCmd - pointer to structure for Change Debt command
  1177. * @param srcAddr - pointer to source address
  1178. * @param seqNum - sequence number of this command
  1179. *
  1180. * @return none
  1181. */
  1182. static void simplemeter_ChangeDebtCB( zclCCChangeDebt_t *pCmd,
  1183. afAddrType_t *srcAddr, uint8 seqNum )
  1184. {
  1185. // add user code here
  1186. }
  1187. /*********************************************************************
  1188. * @fn simplemeter_EmergencyCreditSetupCB
  1189. *
  1190. * @brief Callback from the ZCL SE Profile Prepayment Cluster Library when
  1191. * it received a Emergency Credit Setup for this application.
  1192. *
  1193. * @param pCmd - pointer to structure for Emergency Credit Setup command
  1194. * @param srcAddr - pointer to source address
  1195. * @param seqNum - sequence number of this command
  1196. *
  1197. * @return none
  1198. */
  1199. static void simplemeter_EmergencyCreditSetupCB( zclCCEmergencyCreditSetup_t *pCmd,
  1200. afAddrType_t *srcAddr, uint8 seqNum )
  1201. {
  1202. // add user code here
  1203. }
  1204. /*********************************************************************
  1205. * @fn simplemeter_ConsumerTopupCB
  1206. *
  1207. * @brief Callback from the ZCL SE Profile Prepayment Cluster Library when
  1208. * it received a Consumer Topup for this application.
  1209. *
  1210. * @param pCmd - pointer to structure for Consumer Topup command
  1211. * @param srcAddr - pointer to source address
  1212. * @param seqNum - sequence number of this command
  1213. *
  1214. * @return none
  1215. */
  1216. static void simplemeter_ConsumerTopupCB( zclCCConsumerTopup_t *pCmd,
  1217. afAddrType_t *srcAddr, uint8 seqNum )
  1218. {
  1219. // add user code here
  1220. }
  1221. /*********************************************************************
  1222. * @fn simplemeter_CreditAdjustmentCB
  1223. *
  1224. * @brief Callback from the ZCL SE Profile Prepayment Cluster Library when
  1225. * it received a Credit Adjustment for this application.
  1226. *
  1227. * @param pCmd - pointer to structure for Credit Adjustment command
  1228. * @param srcAddr - pointer to source address
  1229. * @param seqNum - sequence number of this command
  1230. *
  1231. * @return none
  1232. */
  1233. static void simplemeter_CreditAdjustmentCB( zclCCCreditAdjustment_t *pCmd,
  1234. afAddrType_t *srcAddr, uint8 seqNum )
  1235. {
  1236. // add user code here
  1237. }
  1238. /*********************************************************************
  1239. * @fn simplemeter_ChangePaymentModeCB
  1240. *
  1241. * @brief Callback from the ZCL SE Profile Prepayment Cluster Library when
  1242. * it received a Change Payment Mode for this application.
  1243. *
  1244. * @param pCmd - pointer to structure for Change Payment Mode command
  1245. * @param srcAddr - pointer to source address
  1246. * @param seqNum - sequence number of this command
  1247. *
  1248. * @return none
  1249. */
  1250. static void simplemeter_ChangePaymentModeCB( zclCCChangePaymentMode_t *pCmd,
  1251. afAddrType_t *srcAddr, uint8 seqNum )
  1252. {
  1253. // add user code here
  1254. }
  1255. /*********************************************************************
  1256. * @fn simplemeter_GetPrepaySnapshotCB
  1257. *
  1258. * @brief Callback from the ZCL SE Profile Prepayment Cluster Library when
  1259. * it received a Get Prepay Snapshot for this application.
  1260. *
  1261. * @param pCmd - pointer to structure for Get Prepay Snapshot command
  1262. * @param srcAddr - pointer to source address
  1263. * @param seqNum - sequence number of this command
  1264. *
  1265. * @return none
  1266. */
  1267. static void simplemeter_GetPrepaySnapshotCB( zclCCGetPrepaySnapshot_t *pCmd,
  1268. afAddrType_t *srcAddr, uint8 seqNum )
  1269. {
  1270. // add user code here
  1271. }
  1272. /*********************************************************************
  1273. * @fn simplemeter_GetTopupLogCB
  1274. *
  1275. * @brief Callback from the ZCL SE Profile Prepayment Cluster Library when
  1276. * it received a Get Topup Log for this application.
  1277. *
  1278. * @param numEvents - number of events
  1279. * @param srcAddr - pointer to source address
  1280. * @param seqNum - sequence number of this command
  1281. *
  1282. * @return none
  1283. */
  1284. static void simplemeter_GetTopupLogCB( uint8 numEvents,
  1285. afAddrType_t *srcAddr, uint8 seqNum )
  1286. {
  1287. // add user code here
  1288. }
  1289. /*********************************************************************
  1290. * @fn simplemeter_SetLowCreditWarningLevelCB
  1291. *
  1292. * @brief Callback from the ZCL SE Profile Prepayment Cluster Library when
  1293. * it received a Set Low Credit Warning Level for this application.
  1294. *
  1295. * @param numEvents - number of events
  1296. * @param srcAddr - pointer to source address
  1297. * @param seqNum - sequence number of this command
  1298. *
  1299. * @return none
  1300. */
  1301. static void simplemeter_SetLowCreditWarningLevelCB( uint8 numEvents,
  1302. afAddrType_t *srcAddr, uint8 seqNum )
  1303. {
  1304. // add user code here
  1305. }
  1306. /*********************************************************************
  1307. * @fn simplemeter_GetDebtRepaymentLogCB
  1308. *
  1309. * @brief Callback from the ZCL SE Profile Prepayment Cluster Library when
  1310. * it received a Get Debt Repayment Log for this application.
  1311. *
  1312. * @param pCmd - pointer to structure for Get Debt Repayment Log command
  1313. * @param srcAddr - pointer to source address
  1314. * @param seqNum - sequence number of this command
  1315. *
  1316. * @return none
  1317. */
  1318. static void simplemeter_GetDebtRepaymentLogCB( zclCCGetDebtRepaymentLog_t *pCmd,
  1319. afAddrType_t *srcAddr, uint8 seqNum )
  1320. {
  1321. // add user code here
  1322. }
  1323. #endif // SE_UK_EXT
  1324. /******************************************************************************
  1325. *
  1326. * Functions for processing ZCL Foundation incoming Command/Response messages
  1327. *
  1328. *****************************************************************************/
  1329. /*********************************************************************
  1330. * @fn simplemeter_ProcessZCLMsg
  1331. *
  1332. * @brief Process ZCL Foundation incoming message
  1333. *
  1334. * @param pInMsg - message to process
  1335. *
  1336. * @return none
  1337. */
  1338. static void simplemeter_ProcessZCLMsg( zclIncomingMsg_t *pInMsg )
  1339. {
  1340. switch ( pInMsg->zclHdr.commandID )
  1341. {
  1342. #if defined ( ZCL_READ )
  1343. case ZCL_CMD_READ_RSP:
  1344. simplemeter_ProcessInReadRspCmd( pInMsg );
  1345. break;
  1346. #endif // ZCL_READ
  1347. #if defined ( ZCL_WRITE )
  1348. case ZCL_CMD_WRITE_RSP:
  1349. simplemeter_ProcessInWriteRspCmd( pInMsg );
  1350. break;
  1351. #endif // ZCL_READ
  1352. #if defined ( ZCL_REPORT )
  1353. case ZCL_CMD_CONFIG_REPORT:
  1354. simplemeter_ProcessInConfigReportCmd( pInMsg );
  1355. break;
  1356. case ZCL_CMD_CONFIG_REPORT_RSP:
  1357. simplemeter_ProcessInConfigReportRspCmd( pInMsg );
  1358. break;
  1359. case ZCL_CMD_READ_REPORT_CFG:
  1360. simplemeter_ProcessInReadReportCfgCmd( pInMsg );
  1361. break;
  1362. case ZCL_CMD_READ_REPORT_CFG_RSP:
  1363. simplemeter_ProcessInReadReportCfgRspCmd( pInMsg );
  1364. break;
  1365. case ZCL_CMD_REPORT:
  1366. simplemeter_ProcessInReportCmd( pInMsg );
  1367. break;
  1368. #endif // ZCL_REPORT
  1369. case ZCL_CMD_DEFAULT_RSP:
  1370. simplemeter_ProcessInDefaultRspCmd( pInMsg );
  1371. break;
  1372. #if defined ( ZCL_DISCOVER )
  1373. case ZCL_CMD_DISCOVER_RSP:
  1374. simplemeter_ProcessInDiscRspCmd( pInMsg );
  1375. break;
  1376. #endif // ZCL_DISCOVER
  1377. default:
  1378. break;
  1379. }
  1380. if ( pInMsg->attrCmd != NULL )
  1381. {
  1382. // free the parsed command
  1383. osal_mem_free( pInMsg->attrCmd );
  1384. pInMsg->attrCmd = NULL;
  1385. }
  1386. }
  1387. #if defined ( ZCL_READ )
  1388. /*********************************************************************
  1389. * @fn simplemeter_ProcessInReadRspCmd
  1390. *
  1391. * @brief Process the "Profile" Read Response Command
  1392. *
  1393. * @param pInMsg - incoming message to process
  1394. *
  1395. * @return none
  1396. */
  1397. static uint8 simplemeter_ProcessInReadRspCmd( zclIncomingMsg_t *pInMsg )
  1398. {
  1399. zclReadRspCmd_t *readRspCmd;
  1400. uint8 i;
  1401. readRspCmd = (zclReadRspCmd_t *)pInMsg->attrCmd;
  1402. for (i = 0; i < readRspCmd->numAttr; i++)
  1403. {
  1404. // Notify the originator of the results of the original read attributes
  1405. // attempt and, for each successfull request, the value of the requested
  1406. // attribute
  1407. }
  1408. return TRUE;
  1409. }
  1410. #endif // ZCL_READ
  1411. #if defined ( ZCL_WRITE )
  1412. /*********************************************************************
  1413. * @fn simplemeter_ProcessInWriteRspCmd
  1414. *
  1415. * @brief Process the "Profile" Write Response Command
  1416. *
  1417. * @param pInMsg - incoming message to process
  1418. *
  1419. * @return none
  1420. */
  1421. static uint8 simplemeter_ProcessInWriteRspCmd( zclIncomingMsg_t *pInMsg )
  1422. {
  1423. zclWriteRspCmd_t *writeRspCmd;
  1424. uint8 i;
  1425. writeRspCmd = (zclWriteRspCmd_t *)pInMsg->attrCmd;
  1426. for (i = 0; i < writeRspCmd->numAttr; i++)
  1427. {
  1428. // Notify the device of the results of the its original write attributes
  1429. // command.
  1430. }
  1431. return TRUE;
  1432. }
  1433. #endif // ZCL_WRITE
  1434. #if defined ( ZCL_REPORT )
  1435. /*********************************************************************
  1436. * @fn simplemeter_ProcessInConfigReportCmd
  1437. *
  1438. * @brief Process the "Profile" Configure Reporting Command
  1439. *
  1440. * @param pInMsg - incoming message to process
  1441. *
  1442. * @return TRUE if attribute was found in the Attribute list,
  1443. * FALSE if not
  1444. */
  1445. static uint8 simplemeter_ProcessInConfigReportCmd( zclIncomingMsg_t *pInMsg )
  1446. {
  1447. zclCfgReportCmd_t *cfgReportCmd;
  1448. zclCfgReportRec_t *reportRec;
  1449. zclCfgReportRspCmd_t *cfgReportRspCmd;
  1450. zclAttrRec_t attrRec;
  1451. uint8 status;
  1452. uint8 i, j = 0;
  1453. cfgReportCmd = (zclCfgReportCmd_t *)pInMsg->attrCmd;
  1454. // Allocate space for the response command
  1455. cfgReportRspCmd = (zclCfgReportRspCmd_t *)osal_mem_alloc( sizeof ( zclCfgReportRspCmd_t ) + \
  1456. sizeof ( zclCfgReportStatus_t) * cfgReportCmd->numAttr );
  1457. if ( cfgReportRspCmd == NULL )
  1458. return FALSE; // EMBEDDED RETURN
  1459. // Process each Attribute Reporting Configuration record
  1460. for ( i = 0; i < cfgReportCmd->numAttr; i++ )
  1461. {
  1462. reportRec = &(cfgReportCmd->attrList[i]);
  1463. status = ZCL_STATUS_SUCCESS;
  1464. if ( zclFindAttrRec( SIMPLEMETER_ENDPOINT, pInMsg->clusterId, reportRec->attrID, &attrRec ) )
  1465. {
  1466. if ( reportRec->direction == ZCL_SEND_ATTR_REPORTS )
  1467. {
  1468. if ( reportRec->dataType == attrRec.attr.dataType )
  1469. {
  1470. // This the attribute that is to be reported
  1471. if ( zcl_MandatoryReportableAttribute( &attrRec ) == TRUE )
  1472. {
  1473. if ( reportRec->minReportInt < SIMPLEMETER_MIN_REPORTING_INTERVAL ||
  1474. ( reportRec->maxReportInt != 0 &&
  1475. reportRec->maxReportInt < reportRec->minReportInt ) )
  1476. {
  1477. // Invalid fields
  1478. status = ZCL_STATUS_INVALID_VALUE;
  1479. }
  1480. else
  1481. {
  1482. // Set the Min and Max Reporting Intervals and Reportable Change
  1483. //status = zclSetAttrReportInterval( pAttr, cfgReportCmd );
  1484. status = ZCL_STATUS_UNREPORTABLE_ATTRIBUTE; // for now
  1485. }
  1486. }
  1487. else
  1488. {
  1489. // Attribute cannot be reported
  1490. status = ZCL_STATUS_UNREPORTABLE_ATTRIBUTE;
  1491. }
  1492. }
  1493. else
  1494. {
  1495. // Attribute data type is incorrect
  1496. status = ZCL_STATUS_INVALID_DATA_TYPE;
  1497. }
  1498. }
  1499. else
  1500. {
  1501. // We shall expect reports of values of this attribute
  1502. if ( zcl_MandatoryReportableAttribute( &attrRec ) == TRUE )
  1503. {
  1504. // Set the Timeout Period
  1505. //status = zclSetAttrTimeoutPeriod( pAttr, cfgReportCmd );
  1506. status = ZCL_STATUS_UNSUPPORTED_ATTRIBUTE; // for now
  1507. }
  1508. else
  1509. {
  1510. // Reports of attribute cannot be received
  1511. status = ZCL_STATUS_UNSUPPORTED_ATTRIBUTE;
  1512. }
  1513. }
  1514. }
  1515. else
  1516. {
  1517. // Attribute is not supported
  1518. status = ZCL_STATUS_UNSUPPORTED_ATTRIBUTE;
  1519. }
  1520. // If not successful then record the status
  1521. if ( status != ZCL_STATUS_SUCCESS )
  1522. {
  1523. cfgReportRspCmd->attrList[j].status = status;
  1524. cfgReportRspCmd->attrList[j++].attrID = reportRec->attrID;
  1525. }
  1526. } // for loop
  1527. if ( j == 0 )
  1528. {
  1529. // Since all attributes were configured successfully, include a single
  1530. // attribute status record in the response command with the status field
  1531. // set to SUCCESS and the attribute ID field omitted.
  1532. cfgReportRspCmd->attrList[0].status = ZCL_STATUS_SUCCESS;
  1533. cfgReportRspCmd->numAttr = 1;
  1534. }
  1535. else
  1536. {
  1537. cfgReportRspCmd->numAttr = j;
  1538. }
  1539. // Send the response back
  1540. zcl_SendConfigReportRspCmd( SIMPLEMETER_ENDPOINT, &(pInMsg->srcAddr),
  1541. pInMsg->clusterId, cfgReportRspCmd, ZCL_FRAME_SERVER_CLIENT_DIR,
  1542. TRUE, pInMsg->zclHdr.transSeqNum );
  1543. osal_mem_free( cfgReportRspCmd );
  1544. return TRUE ;
  1545. }
  1546. /*********************************************************************
  1547. * @fn simplemeter_ProcessInConfigReportRspCmd
  1548. *
  1549. * @brief Process the "Profile" Configure Reporting Response Command
  1550. *
  1551. * @param pInMsg - incoming message to process
  1552. *
  1553. * @return none
  1554. */
  1555. static uint8 simplemeter_ProcessInConfigReportRspCmd( zclIncomingMsg_t *pInMsg )
  1556. {
  1557. zclCfgReportRspCmd_t *cfgReportRspCmd;
  1558. zclAttrRec_t attrRec;
  1559. uint8 i;
  1560. cfgReportRspCmd = (zclCfgReportRspCmd_t *)pInMsg->attrCmd;
  1561. for (i = 0; i < cfgReportRspCmd->numAttr; i++)
  1562. {
  1563. if ( zclFindAttrRec( SIMPLEMETER_ENDPOINT, pInMsg->clusterId,
  1564. cfgReportRspCmd->attrList[i].attrID, &attrRec ) )
  1565. {
  1566. // Notify the device of success (or otherwise) of the its original configure
  1567. // reporting command, for each attribute.
  1568. }
  1569. }
  1570. return TRUE;
  1571. }
  1572. /*********************************************************************
  1573. * @fn simplemeter_ProcessInReadReportCfgCmd
  1574. *
  1575. * @brief Process the "Profile" Read Reporting Configuration Command
  1576. *
  1577. * @param pInMsg - incoming message to process
  1578. *
  1579. * @return none
  1580. */
  1581. static uint8 simplemeter_ProcessInReadReportCfgCmd( zclIncomingMsg_t *pInMsg )
  1582. {
  1583. zclReadReportCfgCmd_t *readReportCfgCmd;
  1584. zclReadReportCfgRspCmd_t *readReportCfgRspCmd;
  1585. zclReportCfgRspRec_t *reportRspRec;
  1586. zclAttrRec_t attrRec;
  1587. uint8 reportChangeLen;
  1588. uint8 *dataPtr;
  1589. uint8 hdrLen;
  1590. uint8 dataLen = 0;
  1591. uint8 status;
  1592. uint8 i;
  1593. readReportCfgCmd = (zclReadReportCfgCmd_t *)pInMsg->attrCmd;
  1594. // Find out the response length (Reportable Change field is of variable length)
  1595. for ( i = 0; i < readReportCfgCmd->numAttr; i++ )
  1596. {
  1597. // For supported attributes with 'analog' data type, find out the length of
  1598. // the Reportable Change field
  1599. if ( zclFindAttrRec( SIMPLEMETER_ENDPOINT, pInMsg->clusterId,
  1600. readReportCfgCmd->attrList[i].attrID, &attrRec ) )
  1601. {
  1602. if ( zclAnalogDataType( attrRec.attr.dataType ) )
  1603. {
  1604. reportChangeLen = zclGetDataTypeLength( attrRec.attr.dataType );
  1605. // add padding if neede
  1606. if ( PADDING_NEEDED( reportChangeLen ) )
  1607. reportChangeLen++;
  1608. dataLen += reportChangeLen;
  1609. }
  1610. }
  1611. }
  1612. hdrLen = sizeof( zclReadReportCfgRspCmd_t ) + ( readReportCfgCmd->numAttr * sizeof( zclReportCfgRspRec_t ) );
  1613. // Allocate space for the response command
  1614. readReportCfgRspCmd = (zclReadReportCfgRspCmd_t *)osal_mem_alloc( hdrLen + dataLen );
  1615. if ( readReportCfgRspCmd == NULL )
  1616. return FALSE; // EMBEDDED RETURN
  1617. dataPtr = (uint8 *)( (uint8 *)readReportCfgRspCmd + hdrLen );
  1618. readReportCfgRspCmd->numAttr = readReportCfgCmd->numAttr;
  1619. for (i = 0; i < readReportCfgCmd->numAttr; i++)
  1620. {
  1621. reportRspRec = &(readReportCfgRspCmd->attrList[i]);
  1622. if ( zclFindAttrRec( SIMPLEMETER_ENDPOINT, pInMsg->clusterId,
  1623. readReportCfgCmd->attrList[i].attrID, &attrRec ) )
  1624. {
  1625. if ( zcl_MandatoryReportableAttribute( &attrRec ) == TRUE )
  1626. {
  1627. // Get the Reporting Configuration
  1628. // status = zclReadReportCfg( readReportCfgCmd->attrID[i], reportRspRec );
  1629. status = ZCL_STATUS_UNREPORTABLE_ATTRIBUTE; // for now
  1630. if ( status == ZCL_STATUS_SUCCESS && zclAnalogDataType( attrRec.attr.dataType ) )
  1631. {
  1632. reportChangeLen = zclGetDataTypeLength( attrRec.attr.dataType );
  1633. //osal_memcpy( dataPtr, pBuf, reportChangeLen );
  1634. reportRspRec->reportableChange = dataPtr;
  1635. // add padding if needed
  1636. if ( PADDING_NEEDED( reportChangeLen ) )
  1637. reportChangeLen++;
  1638. dataPtr += reportChangeLen;
  1639. }
  1640. }
  1641. else
  1642. {
  1643. // Attribute not in the Mandatory Reportable Attribute list
  1644. status = ZCL_STATUS_UNREPORTABLE_ATTRIBUTE;
  1645. }
  1646. }
  1647. else
  1648. {
  1649. // Attribute not found
  1650. status = ZCL_STATUS_UNSUPPORTED_ATTRIBUTE;
  1651. }
  1652. reportRspRec->status = status;
  1653. reportRspRec->attrID = readReportCfgCmd->attrList[i].attrID;
  1654. }
  1655. // Send the response back
  1656. zcl_SendReadReportCfgRspCmd( SIMPLEMETER_ENDPOINT, &(pInMsg->srcAddr),
  1657. pInMsg->clusterId, readReportCfgRspCmd, ZCL_FRAME_SERVER_CLIENT_DIR,
  1658. TRUE, pInMsg->zclHdr.transSeqNum );
  1659. osal_mem_free( readReportCfgRspCmd );
  1660. return TRUE;
  1661. }
  1662. /*********************************************************************
  1663. * @fn simplemeter_ProcessInReadReportCfgRspCmd
  1664. *
  1665. * @brief Process the "Profile" Read Reporting Configuration Response Command
  1666. *
  1667. * @param pInMsg - incoming message to process
  1668. *
  1669. * @return none
  1670. */
  1671. static uint8 simplemeter_ProcessInReadReportCfgRspCmd( zclIncomingMsg_t *pInMsg )
  1672. {
  1673. zclReadReportCfgRspCmd_t *readReportCfgRspCmd;
  1674. zclReportCfgRspRec_t *reportRspRec;
  1675. uint8 i;
  1676. readReportCfgRspCmd = (zclReadReportCfgRspCmd_t *)pInMsg->attrCmd;
  1677. for ( i = 0; i < readReportCfgRspCmd->numAttr; i++ )
  1678. {
  1679. reportRspRec = &(readReportCfgRspCmd->attrList[i]);
  1680. // Notify the device of the results of the its original read reporting
  1681. // configuration command.
  1682. if ( reportRspRec->status == ZCL_STATUS_SUCCESS )
  1683. {
  1684. if ( reportRspRec->direction == ZCL_SEND_ATTR_REPORTS )
  1685. {
  1686. // add user code here
  1687. }
  1688. else
  1689. {
  1690. // expecting attribute reports
  1691. }
  1692. }
  1693. }
  1694. return TRUE;
  1695. }
  1696. /*********************************************************************
  1697. * @fn simplemeter_ProcessInReportCmd
  1698. *
  1699. * @brief Process the "Profile" Report Command
  1700. *
  1701. * @param pInMsg - incoming message to process
  1702. *
  1703. * @return none
  1704. */
  1705. static uint8 simplemeter_ProcessInReportCmd( zclIncomingMsg_t *pInMsg )
  1706. {
  1707. zclReportCmd_t *reportCmd;
  1708. uint8 i;
  1709. reportCmd = (zclReportCmd_t *)pInMsg->attrCmd;
  1710. for (i = 0; i < reportCmd->numAttr; i++)
  1711. {
  1712. // add user code here
  1713. }
  1714. return TRUE;
  1715. }
  1716. #endif // ZCL_REPORT
  1717. /*********************************************************************
  1718. * @fn simplemeter_ProcessInDefaultRspCmd
  1719. *
  1720. * @brief Process the "Profile" Default Response Command
  1721. *
  1722. * @param pInMsg - incoming message to process
  1723. *
  1724. * @return none
  1725. */
  1726. static uint8 simplemeter_ProcessInDefaultRspCmd( zclIncomingMsg_t *pInMsg )
  1727. {
  1728. // zclDefaultRspCmd_t *defaultRspCmd = (zclDefaultRspCmd_t *)pInMsg->attrCmd;
  1729. // Device is notified of the Default Response command.
  1730. return TRUE;
  1731. }
  1732. #if defined ( ZCL_DISCOVER )
  1733. /*********************************************************************
  1734. * @fn simplemeter_ProcessInDiscRspCmd
  1735. *
  1736. * @brief Process the "Profile" Discover Response Command
  1737. *
  1738. * @param pInMsg - incoming message to process
  1739. *
  1740. * @return none
  1741. */
  1742. static uint8 simplemeter_ProcessInDiscRspCmd( zclIncomingMsg_t *pInMsg )
  1743. {
  1744. zclDiscoverRspCmd_t *discoverRspCmd;
  1745. uint8 i;
  1746. discoverRspCmd = (zclDiscoverRspCmd_t *)pInMsg->attrCmd;
  1747. for ( i = 0; i < discoverRspCmd->numAttr; i++ )
  1748. {
  1749. // Device is notified of the result of its attribute discovery command.
  1750. }
  1751. return TRUE;
  1752. }
  1753. #endif // ZCL_DISCOVER
  1754. /****************************************************************************
  1755. ****************************************************************************/