zcl_se.c 65 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930
  1. /**************************************************************************************************
  2. Filename: zcl_se.c
  3. Revised: $Date: 2007-07-31 09:16:11 -0700 (Tue, 31 Jul 2007) $
  4. Revision: $Revision: 14985 $
  5. Description: Zigbee Cluster Library - SE (Smart Energy) Profile.
  6. Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved.
  7. IMPORTANT: Your use of this Software is limited to those specific rights
  8. granted under the terms of a software license agreement between the user
  9. who downloaded the software, his/her employer (which must be your employer)
  10. and Texas Instruments Incorporated (the "License"). You may not use this
  11. Software unless you agree to abide by the terms of the License. The License
  12. limits your use, and you acknowledge, that the Software may not be modified,
  13. copied or distributed unless embedded on a Texas Instruments microcontroller
  14. or used solely and exclusively in conjunction with a Texas Instruments radio
  15. frequency transceiver, which is integrated into your product. Other than for
  16. the foregoing purpose, you may not use, reproduce, copy, prepare derivative
  17. works of, modify, distribute, perform, display or sell this Software and/or
  18. its documentation for any purpose.
  19. YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
  20. PROVIDED “AS IS?WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
  21. INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
  22. NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
  23. TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
  24. NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
  25. LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
  26. INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
  27. OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
  28. OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
  29. (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
  30. Should you have any questions regarding your right to use this Software,
  31. contact Texas Instruments Incorporated at www.TI.com.
  32. **************************************************************************************************/
  33. /*********************************************************************
  34. * INCLUDES
  35. */
  36. #include "ZComDef.h"
  37. #include "OSAL.h"
  38. #include "zcl.h"
  39. #include "zcl_general.h"
  40. #include "zcl_se.h"
  41. #include "DebugTrace.h"
  42. #if defined ( INTER_PAN )
  43. #include "stub_aps.h"
  44. #endif
  45. #include "zcl_key_establish.h"
  46. /*********************************************************************
  47. * MACROS
  48. */
  49. // Clusters that are supported thru Inter-PAN communication
  50. #define INTER_PAN_CLUSTER( id ) ( (id) == ZCL_CLUSTER_ID_SE_PRICING || \
  51. (id) == ZCL_CLUSTER_ID_SE_MESSAGE )
  52. /*********************************************************************
  53. * CONSTANTS
  54. */
  55. /*********************************************************************
  56. * TYPEDEFS
  57. */
  58. typedef struct zclSECBRec
  59. {
  60. struct zclSECBRec *next;
  61. uint8 endpoint; // Used to link it into the endpoint descriptor
  62. zclSE_AppCallbacks_t *CBs; // Pointer to Callback function
  63. } zclSECBRec_t;
  64. /*********************************************************************
  65. * GLOBAL VARIABLES
  66. */
  67. /*********************************************************************
  68. * GLOBAL FUNCTIONS
  69. */
  70. /*********************************************************************
  71. * LOCAL VARIABLES
  72. */
  73. static zclSECBRec_t *zclSECBs = (zclSECBRec_t *)NULL;
  74. static uint8 zclSEPluginRegisted = FALSE;
  75. /*********************************************************************
  76. * LOCAL FUNCTIONS
  77. */
  78. static ZStatus_t zclSE_HdlIncoming( zclIncoming_t *pInMsg );
  79. static ZStatus_t zclSE_HdlInSpecificCommands( zclIncoming_t *pInMsg );
  80. #ifdef ZCL_SIMPLE_METERING
  81. static ZStatus_t zclSE_ProcessInSimpleMeteringCmds( zclIncoming_t *pInMsg, zclSE_AppCallbacks_t *pCBs );
  82. static ZStatus_t zclSE_ProcessInCmd_SimpleMeter_GetProfileCmd( zclIncoming_t *pInMsg, zclSE_AppCallbacks_t *pCBs );
  83. static ZStatus_t zclSE_ProcessInCmd_SimpleMeter_GetProfileRsp( zclIncoming_t *pInMsg, zclSE_AppCallbacks_t *pCBs );
  84. static ZStatus_t zclSE_ProcessInCmd_SimpleMeter_ReqMirrorCmd( zclIncoming_t *pInMsg, zclSE_AppCallbacks_t *pCBs );
  85. static ZStatus_t zclSE_ProcessInCmd_SimpleMeter_ReqMirrorRsp( zclIncoming_t *pInMsg, zclSE_AppCallbacks_t *pCBs );
  86. static ZStatus_t zclSE_ProcessInCmd_SimpleMeter_MirrorRemCmd( zclIncoming_t *pInMsg, zclSE_AppCallbacks_t *pCBs );
  87. static ZStatus_t zclSE_ProcessInCmd_SimpleMeter_MirrorRemRsp( zclIncoming_t *pInMsg, zclSE_AppCallbacks_t *pCBs );
  88. #endif
  89. #ifdef ZCL_PRICING
  90. static ZStatus_t zclSE_ProcessInPricingCmds( zclIncoming_t *pInMsg, zclSE_AppCallbacks_t *pCBs );
  91. static ZStatus_t zclSE_ProcessInCmd_Pricing_GetCurrentPrice( zclIncoming_t *pInMsg, zclSE_AppCallbacks_t *pCBs );
  92. static ZStatus_t zclSE_ProcessInCmd_Pricing_GetScheduledPrice( zclIncoming_t *pInMsg, zclSE_AppCallbacks_t *pCBs );
  93. static ZStatus_t zclSE_ProcessInCmd_Pricing_PublishPrice( zclIncoming_t *pInMsg, zclSE_AppCallbacks_t *pCBs );
  94. #endif
  95. #ifdef ZCL_MESSAGE
  96. static ZStatus_t zclSE_ProcessInMessageCmds( zclIncoming_t *pInMsg, zclSE_AppCallbacks_t *pCBs );
  97. static ZStatus_t zclSE_ProcessInCmd_Message_DisplayMessage( zclIncoming_t *pInMsg, zclSE_AppCallbacks_t *pCBs );
  98. static ZStatus_t zclSE_ProcessInCmd_Message_CancelMessage( zclIncoming_t *pInMsg, zclSE_AppCallbacks_t *pCBs );
  99. static ZStatus_t zclSE_ProcessInCmd_Message_GetLastMessage( zclIncoming_t *pInMsg, zclSE_AppCallbacks_t *pCBs );
  100. static ZStatus_t zclSE_ProcessInCmd_Message_MessageConfirmation( zclIncoming_t *pInMsg, zclSE_AppCallbacks_t *pCBs );
  101. #endif
  102. #ifdef ZCL_LOAD_CONTROL
  103. static ZStatus_t zclSE_ProcessInLoadControlCmds( zclIncoming_t *pInMsg, zclSE_AppCallbacks_t *pCBs );
  104. static ZStatus_t zclSE_ProcessInCmd_LoadControl_LoadControlEvent( zclIncoming_t *pInMsg, zclSE_AppCallbacks_t *pCBs );
  105. static ZStatus_t zclSE_ProcessInCmd_LoadControl_CancelLoadControlEvent( zclIncoming_t *pInMsg, zclSE_AppCallbacks_t *pCBs );
  106. static ZStatus_t zclSE_ProcessInCmd_LoadControl_CancelAllLoadControlEvents( zclIncoming_t *pInMsg, zclSE_AppCallbacks_t *pCBs );
  107. static ZStatus_t zclSE_ProcessInCmd_LoadControl_ReportEventStatus( zclIncoming_t *pInMsg, zclSE_AppCallbacks_t *pCBs );
  108. static ZStatus_t zclSE_ProcessInCmd_LoadControl_GetScheduledEvents( zclIncoming_t *pInMsg,
  109. zclSE_AppCallbacks_t *pCBs );
  110. #endif
  111. #ifdef ZCL_SIMPLE_METERING
  112. /*********************************************************************
  113. * @fn zclSE_SimpleMetering_Send_GetProfileCmd
  114. *
  115. * @brief Call to send out a Get Profile Command
  116. *
  117. * @param srcEP - Sending application's endpoint
  118. * @param dstAddr - where you want the message to go
  119. * @param channel - returned inteval (delivered @ 0; received @ 1)
  120. * @param endTime - UTC time for the starting time of requested interval
  121. * @param numOfPeriods - number of periods requested
  122. * @param disableDefaultRsp - disable default response
  123. * @param seqNum - ZCL sequence number
  124. *
  125. * @return ZStatus_t
  126. */
  127. ZStatus_t zclSE_SimpleMetering_Send_GetProfileCmd( uint8 srcEP, afAddrType_t *dstAddr,
  128. uint8 channel, uint32 endTime, uint8 numOfPeriods,
  129. uint8 disableDefaultRsp, uint8 seqNum )
  130. {
  131. uint8 buf[6];
  132. buf[0] = channel;
  133. osal_buffer_uint32( &buf[1], endTime );
  134. buf[5] = numOfPeriods;
  135. return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_SE_SIMPLE_METERING,
  136. COMMAND_SE_GET_PROFILE_CMD, TRUE,
  137. ZCL_FRAME_CLIENT_SERVER_DIR, disableDefaultRsp, 0, seqNum, 6, buf );
  138. }
  139. /*********************************************************************
  140. * @fn zclSE_SimpleMetering_Send_GetProfileRsp
  141. *
  142. * @brief Call to send out a Get Profile Response
  143. *
  144. * @param srcEP - Sending application's endpoint
  145. * @param dstAddr - where you want the message to go
  146. * @param endTime - UTC time for the starting time of requested interval
  147. * @param intervals - data buffer holding an array of interval data captured
  148. * using the period
  149. * specified by the ProfileIntervalPeriod attribute. Data is organized
  150. * in a reverse chronological order, the most recent interval is
  151. * transmitted first and the oldest interval is transmitted last.
  152. * Invalid intervals intervals should be marked as 0xFFFFFF
  153. * @param len - length of the intervals buffer
  154. * @param disableDefaultRsp - disable default response
  155. * @param seqNum - ZCL sequence number
  156. *
  157. * @return ZStatus_t
  158. */
  159. ZStatus_t zclSE_SimpleMetering_Send_GetProfileRsp( uint8 srcEP, afAddrType_t *dstAddr,
  160. uint32 endTime, uint8 rspStatus, uint8 profileIntervalPeriod,
  161. uint8 numOfPeriodDelivered, uint24 *intervals,
  162. uint8 disableDefaultRsp, uint8 seqNum )
  163. {
  164. uint8 *buf;
  165. uint8 *pBuf;
  166. uint8 i;
  167. uint8 len;
  168. ZStatus_t status;
  169. // endTime + status + profileIntervalPeriod + numOfEntry + array
  170. len = 4 + 1 + 1 + 1 + (3 * numOfPeriodDelivered);
  171. buf = osal_mem_alloc( len );
  172. if ( buf == NULL )
  173. return (ZMemError);
  174. osal_buffer_uint32( buf, endTime );
  175. buf[4] = rspStatus;
  176. buf[5] = profileIntervalPeriod;
  177. // Starting of the array of uint24
  178. buf[6] = numOfPeriodDelivered; // Number of entries in the array
  179. pBuf = &buf[7];
  180. for( i = 0; i< numOfPeriodDelivered; i++ )
  181. {
  182. pBuf = osal_buffer_uint24( pBuf, *intervals++ );
  183. }
  184. status = zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_SE_SIMPLE_METERING,
  185. COMMAND_SE_GET_PROFILE_RSP, TRUE,
  186. ZCL_FRAME_SERVER_CLIENT_DIR, disableDefaultRsp, 0, seqNum, len, buf );
  187. osal_mem_free( buf );
  188. return status;
  189. }
  190. /*********************************************************************
  191. * @fn zclSE_SimpleMetering_Send_ReqMirrorRsp
  192. *
  193. * @brief Call to send out a Request Mirror Response
  194. *
  195. * @param srcEP - Sending application's endpoint
  196. * @param dstAddr - where you want the message to go
  197. *
  198. * @return ZStatus_t
  199. */
  200. ZStatus_t zclSE_SimpleMetering_Send_ReqMirrorRsp( uint8 srcEP, afAddrType_t *dstAddr,
  201. uint16 endpointId,
  202. uint8 disableDefaultRsp, uint8 seqNum )
  203. {
  204. ZStatus_t status;
  205. uint8 buf[2];
  206. buf[0] = (uint8) endpointId ;
  207. buf[1] = (uint8)( endpointId >> 8 );
  208. status = zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_SE_SIMPLE_METERING,
  209. COMMAND_SE_REQ_MIRROR_RSP, TRUE,
  210. ZCL_FRAME_CLIENT_SERVER_DIR, disableDefaultRsp, 0, seqNum, 2, buf );
  211. return status ;
  212. }
  213. /*********************************************************************
  214. * @fn zclSE_SimpleMetering_Send_RemMirrorRsp
  215. *
  216. * @brief Call to send out a Remove Mirror Response
  217. *
  218. * @param srcEP - Sending application's endpoint
  219. * @param dstAddr - where you want the message to go
  220. *
  221. * @return ZStatus_t
  222. */
  223. ZStatus_t zclSE_SimpleMetering_Send_RemMirrorRsp( uint8 srcEP, afAddrType_t *dstAddr,
  224. uint16 endpointId,
  225. uint8 disableDefaultRsp, uint8 seqNum )
  226. {
  227. ZStatus_t status;
  228. uint8 buf[2];
  229. buf[0] = (uint8) endpointId ;
  230. buf[1] = (uint8)( endpointId >> 8 );
  231. status = zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_SE_SIMPLE_METERING,
  232. COMMAND_SE_MIRROR_REM_RSP, TRUE,
  233. ZCL_FRAME_CLIENT_SERVER_DIR, disableDefaultRsp, 0, seqNum, 2, buf );
  234. return status ;
  235. }
  236. #endif
  237. #ifdef ZCL_PRICING
  238. /*********************************************************************
  239. * Call to send out a Get Scheduled Price Command
  240. *
  241. * @param srcEP - Sending application's endpoint
  242. * @param dstAddr - where you want the message to go
  243. * @param cmd - command payload
  244. * @param disableDefaultRsp - disable default response
  245. * @param seqNum - ZCL sequence number
  246. *
  247. * @return ZStatus_t
  248. */
  249. ZStatus_t zclSE_Pricing_Send_GetScheduledPrice( uint8 srcEP, afAddrType_t *dstAddr,
  250. zclCCGetScheduledPrice_t *cmd,
  251. uint8 disableDefaultRsp, uint8 seqNum )
  252. {
  253. uint8 buf[5];
  254. ZStatus_t status;
  255. osal_buffer_uint32( buf, cmd->startTime );
  256. buf[4] = cmd->numEvents;
  257. status = zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_SE_PRICING,
  258. COMMAND_SE_GET_SCHEDULED_PRICE, TRUE,
  259. ZCL_FRAME_CLIENT_SERVER_DIR, disableDefaultRsp, 0,
  260. seqNum, 5, buf );
  261. return status;
  262. }
  263. /*********************************************************************
  264. * @fn zclSE_Pricing_Send_PublishPrice
  265. *
  266. * @brief Call to send out a Publish Price Command
  267. *
  268. * @param srcEP - Sending application's endpoint
  269. * @param dstAddr - where you want the message to go
  270. * @param disableDefaultRsp - disable default response
  271. * @param seqNum - ZCL sequence number
  272. *
  273. * @return ZStatus_t
  274. */
  275. ZStatus_t zclSE_Pricing_Send_PublishPrice( uint8 srcEP, afAddrType_t *dstAddr,
  276. zclCCPublishPrice_t *cmd,
  277. uint8 disableDefaultRsp, uint8 seqNum )
  278. {
  279. uint8 *buf;
  280. uint8 *pBuf;
  281. uint8 bufLen;
  282. ZStatus_t status;
  283. bufLen = PACKET_LEN_SE_PUBLISH_PRICE + cmd->rateLabel.strLen;
  284. buf = osal_mem_alloc( bufLen );
  285. if ( buf == NULL )
  286. return (ZMemError);
  287. pBuf = buf;
  288. pBuf = osal_buffer_uint32( pBuf, cmd->providerId );
  289. *pBuf++ = cmd->rateLabel.strLen;
  290. pBuf = osal_memcpy( pBuf, cmd->rateLabel.pStr, cmd->rateLabel.strLen );
  291. pBuf = osal_buffer_uint32( pBuf, cmd->issuerEventId );
  292. pBuf = osal_buffer_uint32( pBuf, cmd->currentTime );
  293. *pBuf++ = cmd->unitOfMeasure;
  294. *pBuf++ = LO_UINT16( cmd->currency );
  295. *pBuf++ = HI_UINT16( cmd->currency );
  296. *pBuf++ = cmd->priceTralingDigit;
  297. pBuf = osal_buffer_uint32( pBuf, cmd->startTime );
  298. *pBuf++ = LO_UINT16( cmd->durationInMinutes );
  299. *pBuf++ = HI_UINT16( cmd->durationInMinutes );
  300. pBuf = osal_buffer_uint32( pBuf, cmd->price );
  301. *pBuf++ = cmd->priceRatio;
  302. pBuf = osal_buffer_uint32( pBuf, cmd->generationPrice );
  303. *pBuf++ = cmd->generationPriceRatio;
  304. *pBuf = cmd->priceTier;
  305. status = zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_SE_PRICING,
  306. COMMAND_SE_PUBLISH_PRICE, TRUE,
  307. ZCL_FRAME_SERVER_CLIENT_DIR, disableDefaultRsp, 0,
  308. seqNum, bufLen, buf );
  309. osal_mem_free(buf);
  310. return status;
  311. }
  312. #endif
  313. #ifdef ZCL_MESSAGE
  314. /*********************************************************************
  315. * @fn zclSE_Message_Send_DisplayMessage
  316. *
  317. * @brief Call to send out a Display Message Command
  318. *
  319. * @param srcEP - Sending application's endpoint
  320. * @param dstAddr - where you want the message to go
  321. * @param cmd - command
  322. * @param disableDefaultRsp - disable default response
  323. * @param seqNum - ZCL sequence number
  324. *
  325. * @return ZStatus_t
  326. */
  327. ZStatus_t zclSE_Message_Send_DisplayMessage( uint8 srcEP, afAddrType_t *dstAddr,
  328. zclCCDisplayMessage_t *cmd,
  329. uint8 disableDefaultRsp, uint8 seqNum )
  330. {
  331. uint8 *buf;
  332. uint8 *pBuf;
  333. uint8 bufLen;
  334. ZStatus_t status;
  335. // msgId + msgCtrl + start time + duration + msgLen + msg
  336. bufLen = 4 + 1 + 4 + 2 + 1 + cmd->msgString.strLen;
  337. buf = osal_mem_alloc( bufLen );
  338. if ( buf == NULL )
  339. return (ZMemError);
  340. pBuf = buf;
  341. pBuf = osal_buffer_uint32( buf, cmd->messageId ); // Streamline the uint32 data
  342. *pBuf++ = cmd->messageCtrl.transmissionMode |
  343. (cmd->messageCtrl.importance << SE_PROFILE_MSGCTRL_IMPORTANCE)|
  344. (cmd->messageCtrl.confirmationRequired << SE_PROFILE_MSGCTRL_CONFREQUIRED);
  345. pBuf = osal_buffer_uint32( pBuf, cmd->startTime );
  346. *pBuf++ = LO_UINT16( cmd->durationInMinutes );
  347. *pBuf++ = HI_UINT16( cmd->durationInMinutes );
  348. *pBuf++ = cmd->msgString.strLen;
  349. osal_memcpy( pBuf, cmd->msgString.pStr, cmd->msgString.strLen );
  350. status = zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_SE_MESSAGE,
  351. COMMAND_SE_DISPLAY_MESSAGE, TRUE,
  352. ZCL_FRAME_SERVER_CLIENT_DIR, disableDefaultRsp, 0, seqNum, bufLen, buf );
  353. osal_mem_free(buf);
  354. return status;
  355. }
  356. /*********************************************************************
  357. * @fn zclSE_Message_Send_CancelMessage
  358. *
  359. * @brief Call to send out a Cancel Message Command
  360. *
  361. * @param srcEP - Sending application's endpoint
  362. * @param dstAddr - where you want the message to go
  363. * @param msgId - Message ID
  364. * @param msgCtrl - Message Control
  365. * @param disableDefaultRsp - disable default response
  366. * @param seqNum - ZCL sequence number
  367. *
  368. * @return ZStatus_t
  369. */
  370. ZStatus_t zclSE_Message_Send_CancelMessage( uint8 srcEP, afAddrType_t *dstAddr,
  371. uint32 msgId, uint8 msgCtrl,
  372. uint8 disableDefaultRsp, uint8 seqNum )
  373. {
  374. uint8 buf[5];
  375. osal_buffer_uint32( buf, msgId ); // Streamline the uint32 data
  376. buf[4] = msgCtrl;
  377. return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_SE_MESSAGE,
  378. COMMAND_SE_CANCEL_MESSAGE, TRUE,
  379. ZCL_FRAME_SERVER_CLIENT_DIR, disableDefaultRsp, 0, seqNum, 5, buf );
  380. }
  381. /*********************************************************************
  382. * @fn zclSE_Message_Send_MessageConfirmation
  383. *
  384. * @brief Call to send out a Message Confirmation
  385. *
  386. * @param srcEP - Sending application's endpoint
  387. * @param dstAddr - where you want the message to go
  388. * @param msgId - Message ID
  389. * @param confirmTime - Confirmation Time
  390. *
  391. * @return ZStatus_t
  392. */
  393. ZStatus_t zclSE_Message_Send_MessageConfirmation( uint8 srcEP, afAddrType_t *dstAddr,
  394. uint32 msgId, uint32 confirmTime,
  395. uint8 disableDefaultRsp, uint8 seqNum )
  396. {
  397. uint8 buf[8];
  398. osal_buffer_uint32( buf, msgId ); // Streamline the uint32 data
  399. osal_buffer_uint32( &buf[4], confirmTime ); // Streamline the uint32 data
  400. return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_SE_MESSAGE,
  401. COMMAND_SE_MESSAGE_CONFIRMATION, TRUE,
  402. ZCL_FRAME_CLIENT_SERVER_DIR, disableDefaultRsp, 0, seqNum, 8, buf );
  403. }
  404. #endif
  405. #ifdef ZCL_LOAD_CONTROL
  406. /*********************************************************************
  407. * @fn zclSE_LoadControl_Send_LoadControlEvent
  408. *
  409. * @brief Call to send out a Load Control Event
  410. *
  411. * @param srcEP - Sending application's endpoint
  412. * @param dstAddr - where you want the message to go
  413. * @param cmd - zclCCLoadControlEvent_t
  414. * @param disableDefaultRsp - disable default response
  415. * @param seqNum - ZCL sequence number
  416. *
  417. * @return ZStatus_t
  418. */
  419. ZStatus_t zclSE_LoadControl_Send_LoadControlEvent( uint8 srcEP, afAddrType_t *dstAddr,
  420. zclCCLoadControlEvent_t* cmd,
  421. uint8 disableDefaultRsp, uint8 seqNum )
  422. {
  423. uint8 *buf;
  424. uint8 *pBuf;
  425. ZStatus_t status;
  426. buf = osal_mem_alloc( PACKET_LEN_SE_LOAD_CONTROL_EVENT );
  427. if ( buf == NULL )
  428. return (ZMemError);
  429. pBuf = buf;
  430. pBuf = osal_buffer_uint32( pBuf, cmd->issuerEvent );
  431. pBuf = osal_buffer_uint24( pBuf, cmd->deviceGroupClass );
  432. pBuf = osal_buffer_uint32( pBuf, cmd->startTime );
  433. *pBuf++ = LO_UINT16( cmd->durationInMinutes );
  434. *pBuf++ = HI_UINT16( cmd->durationInMinutes );
  435. *pBuf++ = cmd->criticalityLevel;
  436. *pBuf++ = cmd->coolingTemperatureOffset;
  437. *pBuf++ = cmd->heatingTemperatureOffset;
  438. *pBuf++ = LO_UINT16( cmd->coolingTemperatureSetPoint );
  439. *pBuf++ = HI_UINT16( cmd->coolingTemperatureSetPoint );
  440. *pBuf++ = LO_UINT16( cmd->heatingTemperatureSetPoint );
  441. *pBuf++ = HI_UINT16( cmd->heatingTemperatureSetPoint );
  442. *pBuf++ = cmd->averageLoadAdjustmentPercentage;
  443. *pBuf++ = cmd->dutyCycle;
  444. *pBuf = cmd->eventControl;
  445. status = zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_SE_LOAD_CONTROL,
  446. COMMAND_SE_LOAD_CONTROL_EVENT, TRUE,
  447. ZCL_FRAME_SERVER_CLIENT_DIR, disableDefaultRsp, 0, seqNum,
  448. PACKET_LEN_SE_LOAD_CONTROL_EVENT, buf );
  449. osal_mem_free(buf);
  450. return status;
  451. }
  452. /*********************************************************************
  453. * @fn zclSE_LoadControl_Send_CancelLoadControlEvent
  454. *
  455. * @brief Call to send out a Cancel Load Control Event
  456. *
  457. * @param srcEP - Sending application's endpoint
  458. * @param dstAddr - where you want the message to go
  459. * @param disableDefaultRsp - disable default response
  460. * @param seqNum - ZCL sequence number
  461. *
  462. * @return ZStatus_t
  463. */
  464. ZStatus_t zclSE_LoadControl_Send_CancelLoadControlEvent( uint8 srcEP, afAddrType_t *dstAddr,
  465. zclCCCancelLoadControlEvent_t *cmd,
  466. uint8 disableDefaultRsp, uint8 seqNum )
  467. {
  468. uint8 buf[PACKET_LEN_SE_CANCEL_LOAD_CONTROL_EVENT];
  469. uint8 *pBuf;
  470. pBuf = buf;
  471. pBuf = osal_buffer_uint32( pBuf, cmd->issuerEventID );
  472. pBuf = osal_buffer_uint24( pBuf, cmd->deviceGroupClass );
  473. *pBuf++ = cmd->cancelControl;
  474. pBuf = osal_buffer_uint32( pBuf, cmd->effectiveTime );
  475. return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_SE_LOAD_CONTROL,
  476. COMMAND_SE_CANCEL_LOAD_CONTROL_EVENT, TRUE,
  477. ZCL_FRAME_SERVER_CLIENT_DIR, disableDefaultRsp, 0, seqNum,
  478. PACKET_LEN_SE_CANCEL_LOAD_CONTROL_EVENT, buf );
  479. }
  480. /*********************************************************************
  481. * @fn zclSE_LoadControl_Send_ReportEventStatus
  482. *
  483. * @brief Call to send out a Report Event Status
  484. *
  485. * @param srcEP - Sending application's endpoint
  486. * @param dstAddr - where you want the message to go
  487. * @param cmd - zclCCReportEventStatus_t
  488. * @param disableDefaultRsp - disable default response
  489. * @param seqNum - ZCL sequence number
  490. *
  491. * @return ZStatus_t
  492. */
  493. ZStatus_t zclSE_LoadControl_Send_ReportEventStatus( uint8 srcEP, afAddrType_t *dstAddr,
  494. zclCCReportEventStatus_t* cmd,
  495. uint8 disableDefaultRsp, uint8 seqNum )
  496. {
  497. uint8 *buf;
  498. uint8 *pBuf;
  499. ZStatus_t status;
  500. buf = osal_mem_alloc( PACKET_LEN_SE_REPORT_EVENT_STATUS );
  501. if ( buf == NULL )
  502. return (ZMemError);
  503. pBuf = buf;
  504. pBuf = osal_buffer_uint32( pBuf, cmd->issuerEventID );
  505. *pBuf++ = cmd->eventStatus;
  506. pBuf = osal_buffer_uint32( pBuf, cmd->eventStartTime );
  507. *pBuf++ = cmd->criticalityLevelApplied;
  508. *pBuf++ = LO_UINT16( cmd->coolingTemperatureSetPointApplied );
  509. *pBuf++ = HI_UINT16( cmd->coolingTemperatureSetPointApplied );
  510. *pBuf++ = LO_UINT16( cmd->heatingTemperatureSetPointApplied );
  511. *pBuf++ = HI_UINT16( cmd->heatingTemperatureSetPointApplied );
  512. *pBuf++ = cmd->averageLoadAdjustment;
  513. *pBuf++ = cmd->dutyCycleApplied;
  514. *pBuf++ = cmd->eventControl;
  515. *pBuf++ = cmd->signatureType;
  516. zclGeneral_KeyEstablishment_ECDSASign( buf, PACKET_LEN_SE_REPORT_EVENT_STATUS_ONLY, pBuf);
  517. status = zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_SE_LOAD_CONTROL,
  518. COMMAND_SE_REPORT_EVENT_STATUS, TRUE,
  519. ZCL_FRAME_CLIENT_SERVER_DIR, disableDefaultRsp, 0, seqNum,
  520. PACKET_LEN_SE_REPORT_EVENT_STATUS, buf );
  521. osal_mem_free(buf);
  522. return status;
  523. }
  524. /*********************************************************************
  525. * @fn zclSE_LoadControl_Send_GetScheduledEvent
  526. *
  527. * @brief Call to send out a Get Scheduled Event
  528. *
  529. * @param srcEP - Sending application's endpoint
  530. * @param dstAddr - where you want the message to go
  531. * @param cmd - command format
  532. * @param disableDefaultRsp - disable default response
  533. * @param seqNum - ZCL sequence number
  534. *
  535. * @return ZStatus_t
  536. */
  537. ZStatus_t zclSE_LoadControl_Send_GetScheduledEvent( uint8 srcEP, afAddrType_t *dstAddr,
  538. zclCCGetScheduledEvent_t *cmd,
  539. uint8 disableDefaultRsp, uint8 seqNum )
  540. {
  541. uint8 buf[PACKET_LEN_SE_GET_SCHEDULED_EVENT];
  542. osal_buffer_uint32( buf, cmd->startTime );
  543. buf[4] = cmd->numEvents;
  544. return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_SE_LOAD_CONTROL,
  545. COMMAND_SE_GET_SCHEDULED_EVENT, TRUE,
  546. ZCL_FRAME_CLIENT_SERVER_DIR, disableDefaultRsp, 0, seqNum,
  547. PACKET_LEN_SE_GET_SCHEDULED_EVENT, buf );
  548. }
  549. #endif
  550. /*********************************************************************
  551. * @fn zclSE_RegisterCmdCallbacks
  552. *
  553. * @brief Register an applications command callbacks
  554. *
  555. * @param endpoint - application's endpoint
  556. * @param callbacks - pointer to the callback record.
  557. *
  558. * @return ZMemError if not able to allocate
  559. */
  560. ZStatus_t zclSE_RegisterCmdCallbacks( uint8 endpoint, zclSE_AppCallbacks_t *callbacks )
  561. {
  562. zclSECBRec_t *pNewItem;
  563. zclSECBRec_t *pLoop;
  564. // Register as a ZCL Plugin
  565. if ( !zclSEPluginRegisted )
  566. {
  567. zcl_registerPlugin( ZCL_CLUSTER_ID_SE_PRICING,
  568. ZCL_CLUSTER_ID_SE_PRE_PAYMENT,
  569. zclSE_HdlIncoming );
  570. zclSEPluginRegisted = TRUE;
  571. }
  572. // Fill in the new profile list
  573. pNewItem = osal_mem_alloc( sizeof( zclSECBRec_t ) );
  574. if ( pNewItem == NULL )
  575. return (ZMemError);
  576. pNewItem->next = (zclSECBRec_t *)NULL;
  577. pNewItem->endpoint = endpoint;
  578. pNewItem->CBs = callbacks;
  579. // Find spot in list
  580. if ( zclSECBs == NULL )
  581. {
  582. zclSECBs = pNewItem;
  583. }
  584. else
  585. {
  586. // Look for end of list
  587. pLoop = zclSECBs;
  588. while ( pLoop->next != NULL )
  589. pLoop = pLoop->next;
  590. // Put new item at end of list
  591. pLoop->next = pNewItem;
  592. }
  593. return ( ZSuccess );
  594. }
  595. #if defined( ZCL_LOAD_CONTROL ) || defined( ZCL_SIMPLE_METERING ) || \
  596. defined( ZCL_PRICING ) || defined( ZCL_MESSAGE )
  597. /*********************************************************************
  598. * @fn zclSE_FindCallbacks
  599. *
  600. * @brief Find the callbacks for an endpoint
  601. *
  602. * @param endpoint
  603. *
  604. * @return pointer to the callbacks
  605. */
  606. static zclSE_AppCallbacks_t *zclSE_FindCallbacks( uint8 endpoint )
  607. {
  608. zclSECBRec_t *pCBs;
  609. pCBs = zclSECBs;
  610. while ( pCBs )
  611. {
  612. if ( pCBs->endpoint == endpoint )
  613. return ( pCBs->CBs );
  614. pCBs = pCBs->next;
  615. }
  616. return ( (zclSE_AppCallbacks_t *)NULL );
  617. }
  618. #endif
  619. /*********************************************************************
  620. * @fn zclSE_HdlIncoming
  621. *
  622. * @brief Callback from ZCL to process incoming Commands specific
  623. * to this cluster library or Profile commands for attributes
  624. * that aren't in the attribute list
  625. *
  626. * @param pInHdlrMsg - pointer to the incoming message
  627. *
  628. * @return ZStatus_t
  629. */
  630. static ZStatus_t zclSE_HdlIncoming( zclIncoming_t *pInMsg )
  631. {
  632. ZStatus_t stat = ZSuccess;
  633. #if defined ( INTER_PAN )
  634. if ( StubAPS_InterPan( pInMsg->msg->srcAddr.panId, pInMsg->msg->srcAddr.endPoint ) &&
  635. !INTER_PAN_CLUSTER(pInMsg->msg->clusterId) )
  636. {
  637. return ( stat ); // Cluster not supported thru Inter-PAN
  638. }
  639. #endif
  640. if ( zcl_ClusterCmd( pInMsg->hdr.fc.type ) )
  641. {
  642. // Is this a manufacturer specific command?
  643. if ( pInMsg->hdr.fc.manuSpecific == 0 )
  644. {
  645. stat = zclSE_HdlInSpecificCommands( pInMsg );
  646. }
  647. else
  648. {
  649. // We don't support any manufacturer specific command.
  650. stat = ZFailure;
  651. }
  652. }
  653. else
  654. {
  655. // Handle all the normal (Read, Write...) commands -- should never get here
  656. stat = ZFailure;
  657. }
  658. return ( stat );
  659. }
  660. /*********************************************************************
  661. * @fn zclSE_HdlInSpecificCommands
  662. *
  663. * @brief Function to process incoming Commands specific
  664. * to this cluster library
  665. * @param pInMsg - pointer to the incoming message
  666. *
  667. * @return ZStatus_t
  668. */
  669. static ZStatus_t zclSE_HdlInSpecificCommands( zclIncoming_t *pInMsg )
  670. {
  671. ZStatus_t stat;
  672. zclSE_AppCallbacks_t *pCBs;
  673. // make sure endpoint exists
  674. #if defined( ZCL_LOAD_CONTROL ) || defined( ZCL_SIMPLE_METERING ) || \
  675. defined( ZCL_PRICING ) || defined( ZCL_MESSAGE )
  676. pCBs = zclSE_FindCallbacks( pInMsg->msg->endPoint );
  677. if ( pCBs == NULL )
  678. return ( ZFailure );
  679. #endif
  680. switch ( pInMsg->msg->clusterId )
  681. {
  682. #ifdef ZCL_SIMPLE_METERING
  683. case ZCL_CLUSTER_ID_SE_SIMPLE_METERING:
  684. stat = zclSE_ProcessInSimpleMeteringCmds( pInMsg, pCBs );
  685. break;
  686. #endif
  687. #ifdef ZCL_PRICING
  688. case ZCL_CLUSTER_ID_SE_PRICING:
  689. stat = zclSE_ProcessInPricingCmds( pInMsg, pCBs );
  690. break;
  691. #endif
  692. #ifdef ZCL_MESSAGE
  693. case ZCL_CLUSTER_ID_SE_MESSAGE:
  694. stat = zclSE_ProcessInMessageCmds( pInMsg, pCBs );
  695. break;
  696. #endif
  697. #ifdef ZCL_LOAD_CONTROL
  698. case ZCL_CLUSTER_ID_SE_LOAD_CONTROL:
  699. stat = zclSE_ProcessInLoadControlCmds( pInMsg, pCBs );
  700. break;
  701. #endif
  702. default:
  703. stat = ZFailure;
  704. break;
  705. }
  706. return ( stat );
  707. }
  708. #ifdef ZCL_SIMPLE_METERING
  709. /*********************************************************************
  710. * @fn zclSE_ProcessInSimpleMeteringCmds
  711. *
  712. * @brief Callback from ZCL to process incoming Commands specific
  713. * to this cluster library on a command ID basis
  714. * @param pInMsg - pointer to the incoming message
  715. *
  716. * @return ZStatus_t
  717. */
  718. static ZStatus_t zclSE_ProcessInSimpleMeteringCmds( zclIncoming_t *pInMsg,
  719. zclSE_AppCallbacks_t *pCBs )
  720. {
  721. ZStatus_t stat = ZSuccess;
  722. if ( zcl_ServerCmd( pInMsg->hdr.fc.direction ) )
  723. {
  724. // Process Client commands, received by server
  725. if( pInMsg->hdr.commandID == COMMAND_SE_GET_PROFILE_CMD )
  726. {
  727. stat = zclSE_ProcessInCmd_SimpleMeter_GetProfileCmd( pInMsg, pCBs );
  728. }
  729. else if ( pInMsg->hdr.commandID == COMMAND_SE_REQ_MIRROR_RSP )
  730. {
  731. stat = zclSE_ProcessInCmd_SimpleMeter_ReqMirrorRsp( pInMsg, pCBs );
  732. }
  733. else if ( pInMsg->hdr.commandID == COMMAND_SE_MIRROR_REM_RSP )
  734. {
  735. stat = zclSE_ProcessInCmd_SimpleMeter_MirrorRemRsp( pInMsg, pCBs );
  736. }
  737. else
  738. stat = ZFailure;
  739. }
  740. else
  741. {
  742. // Process Server commands, received by client
  743. if ( pInMsg->hdr.commandID == COMMAND_SE_GET_PROFILE_RSP )
  744. {
  745. stat = zclSE_ProcessInCmd_SimpleMeter_GetProfileRsp( pInMsg, pCBs );
  746. }
  747. else if ( pInMsg->hdr.commandID == COMMAND_SE_REQ_MIRROR_CMD )
  748. {
  749. stat = zclSE_ProcessInCmd_SimpleMeter_ReqMirrorCmd( pInMsg, pCBs );
  750. }
  751. else if ( pInMsg->hdr.commandID == COMMAND_SE_MIRROR_REM_CMD )
  752. {
  753. stat = zclSE_ProcessInCmd_SimpleMeter_MirrorRemCmd( pInMsg, pCBs );
  754. }
  755. else
  756. stat = ZFailure;
  757. }
  758. return ( stat );
  759. }
  760. /*********************************************************************
  761. * @fn zclSE_ProcessInCmd_SimpleMeter_GetProfileCmd
  762. *
  763. * @brief Process in the received Get Profile Command.
  764. *
  765. * @param pInMsg - pointer to the incoming message
  766. *
  767. * @return ZStatus_t - ZFailure @ Unsupported
  768. * ZCL_STATUS_CMD_HAS_RSP @ Supported and do
  769. * not need default rsp
  770. * ZCL_STATUS_INVALID_FIELD @ Range checking
  771. * failure
  772. *
  773. */
  774. static ZStatus_t zclSE_ProcessInCmd_SimpleMeter_GetProfileCmd( zclIncoming_t *pInMsg,
  775. zclSE_AppCallbacks_t *pCBs )
  776. {
  777. if ( pCBs->pfnSimpleMeter_GetProfileCmd )
  778. {
  779. zclCCGetProfileCmd_t cmd;
  780. cmd.channel = pInMsg->pData[0];
  781. cmd.endTime = osal_build_uint32( &pInMsg->pData[1], 4 );
  782. cmd.numOfPeriods = pInMsg->pData[5];
  783. // Range checking
  784. if ( cmd.channel > MAX_INTERVAL_CHANNEL_SE_SIMPLE_METERING )
  785. {
  786. return ZCL_STATUS_INVALID_FIELD;
  787. }
  788. pCBs->pfnSimpleMeter_GetProfileCmd( &cmd, &(pInMsg->msg->srcAddr),
  789. pInMsg->hdr.transSeqNum );
  790. return ZCL_STATUS_CMD_HAS_RSP;
  791. }
  792. else
  793. {
  794. return ZFailure;
  795. }
  796. }
  797. /*********************************************************************
  798. * @fn zclSE_ProcessInCmd_SimpleMeter_GetProfileRsp
  799. *
  800. * @brief Process in the received Get Profile Response.
  801. *
  802. * @param pInMsg - pointer to the incoming message
  803. *
  804. * @return ZStatus_t - ZFailure @ Unsupported
  805. * ZSuccess @ Supported and send default rsp
  806. * ZCL_STATUS_INVALID_FIELD @ Range checking
  807. * failure
  808. * ZCL_STATUS_SOFTWARE_FAILURE @ ZStack memory allocation failure
  809. */
  810. static ZStatus_t zclSE_ProcessInCmd_SimpleMeter_GetProfileRsp( zclIncoming_t *pInMsg,
  811. zclSE_AppCallbacks_t *pCBs )
  812. {
  813. if ( pCBs->pfnSimpleMeter_GetProfileRsp )
  814. {
  815. uint24 *pBuf24;
  816. uint8 *pBuf8;
  817. uint8 i;
  818. zclCCGetProfileRsp_t cmd;
  819. cmd.endTime = osal_build_uint32( &pInMsg->pData[0], 4 );
  820. cmd.status = pInMsg->pData[4];
  821. cmd.profileIntervalPeriod = pInMsg->pData[5];
  822. cmd.numOfPeriodDelivered = pInMsg->pData[6];
  823. // Range Checking
  824. if ( cmd.profileIntervalPeriod > MAX_PROFILE_INTERVAL_PERIOD_SE_SIMPLE_METERING )
  825. {
  826. return ZCL_STATUS_INVALID_FIELD;
  827. }
  828. // Convert the byte stream to array of uint24
  829. pBuf8 = &pInMsg->pData[7]; // Pointer to the start of the array of bytes
  830. // Pointer to the start of the array of uint24
  831. pBuf24 = (uint24*)osal_mem_alloc( cmd.numOfPeriodDelivered *
  832. sizeof(uint24) );
  833. if ( pBuf24 == NULL )
  834. return ZCL_STATUS_SOFTWARE_FAILURE; // Memory allocation error
  835. cmd.intervals = pBuf24;
  836. for( i = 0; i < cmd.numOfPeriodDelivered; i++ )
  837. {
  838. *(pBuf24++) = osal_build_uint32( pBuf8, 3 );
  839. pBuf8 += 3;
  840. }
  841. pCBs->pfnSimpleMeter_GetProfileRsp( &cmd, &(pInMsg->msg->srcAddr),
  842. pInMsg->hdr.transSeqNum );
  843. osal_mem_free( cmd.intervals );
  844. return ZSuccess;
  845. }
  846. else
  847. {
  848. return ZFailure;
  849. }
  850. }
  851. /*********************************************************************
  852. * @fn zclSE_ProcessInCmd_SimpleMeter_ReqMirrorCmd
  853. *
  854. * @brief Process in the received Request Mirror Command.
  855. *
  856. * @param pInMsg - pointer to the incoming message
  857. *
  858. * @return ZStatus_t - ZFailure @ Unsupported
  859. * ZSuccess @ Supported and send default rsp
  860. */
  861. static ZStatus_t zclSE_ProcessInCmd_SimpleMeter_ReqMirrorCmd( zclIncoming_t *pInMsg,
  862. zclSE_AppCallbacks_t *pCBs )
  863. {
  864. if ( pCBs->pfnSimpleMeter_ReqMirrorCmd )
  865. {
  866. pCBs->pfnSimpleMeter_ReqMirrorCmd( &(pInMsg->msg->srcAddr),
  867. pInMsg->hdr.transSeqNum );
  868. return ZSuccess;
  869. }
  870. else
  871. return ZFailure;
  872. }
  873. /*********************************************************************
  874. * @fn zclSE_ProcessInCmd_SimpleMeter_ReqMirrorRsp
  875. *
  876. * @brief Process in the received Request Mirror Response.
  877. *
  878. * @param pInMsg - pointer to the incoming message
  879. *
  880. * @return ZStatus_t - ZFailure @ Unsupported
  881. * ZSuccess @ Supported and send default rsp
  882. */
  883. static ZStatus_t zclSE_ProcessInCmd_SimpleMeter_ReqMirrorRsp( zclIncoming_t *pInMsg,
  884. zclSE_AppCallbacks_t *pCBs )
  885. {
  886. if ( pCBs->pfnSimpleMeter_ReqMirrorRsp )
  887. {
  888. zclCCReqMirrorRsp_t cmd;
  889. cmd.endpointId = BUILD_UINT16( pInMsg->pData[0], pInMsg->pData[1] );
  890. pCBs->pfnSimpleMeter_ReqMirrorRsp( &cmd, &(pInMsg->msg->srcAddr),
  891. pInMsg->hdr.transSeqNum );
  892. return ZSuccess ;
  893. }
  894. else
  895. return ZFailure;
  896. }
  897. /*********************************************************************
  898. * @fn zclSE_ProcessInCmd_SimpleMeter_MirrorRemCmd
  899. *
  900. * @brief Process in the received Mirror Removed Command.
  901. *
  902. * @param pInMsg - pointer to the incoming message
  903. *
  904. * @return ZStatus_t - ZFailure @ Unsupported
  905. * ZSuccess @ Supported and send default rsp
  906. */
  907. static ZStatus_t zclSE_ProcessInCmd_SimpleMeter_MirrorRemCmd( zclIncoming_t *pInMsg,
  908. zclSE_AppCallbacks_t *pCBs )
  909. {
  910. if ( pCBs->pfnSimpleMeter_MirrorRemCmd )
  911. {
  912. pCBs->pfnSimpleMeter_MirrorRemCmd( &(pInMsg->msg->srcAddr),
  913. pInMsg->hdr.transSeqNum );
  914. return ZSuccess;
  915. }
  916. else
  917. return ZFailure;
  918. }
  919. /*********************************************************************
  920. * @fn zclSE_ProcessInCmd_SimpleMeter_MirrorRemRsp
  921. *
  922. * @brief Process in the received Mirror Removed Response.
  923. *
  924. * @param pInMsg - pointer to the incoming message
  925. *
  926. * @return ZStatus_t - ZFailure @ Unsupported
  927. * ZSuccess @ Supported and send default rsp
  928. */
  929. static ZStatus_t zclSE_ProcessInCmd_SimpleMeter_MirrorRemRsp( zclIncoming_t *pInMsg,
  930. zclSE_AppCallbacks_t *pCBs )
  931. {
  932. if ( pCBs->pfnSimpleMeter_MirrorRemRsp )
  933. {
  934. zclCCMirrorRemRsp_t cmd;
  935. cmd.endpointId = pInMsg->pData[0] | ( (uint16)pInMsg->pData[1] << 8 );
  936. pCBs->pfnSimpleMeter_MirrorRemRsp( &cmd, &(pInMsg->msg->srcAddr),
  937. pInMsg->hdr.transSeqNum );
  938. return ZSuccess;
  939. }
  940. else
  941. return ZFailure;
  942. }
  943. #endif
  944. #ifdef ZCL_PRICING
  945. /*********************************************************************
  946. * @fn zclSE_ProcessInPricingCmds
  947. *
  948. * @brief Callback from ZCL to process incoming Commands specific
  949. * to this cluster library on a command ID basis
  950. * @param pInMsg - pointer to the incoming message
  951. *
  952. * @return ZStatus_t
  953. */
  954. static ZStatus_t zclSE_ProcessInPricingCmds( zclIncoming_t *pInMsg,
  955. zclSE_AppCallbacks_t *pCBs )
  956. {
  957. ZStatus_t stat = ZSuccess;
  958. if ( zcl_ServerCmd( pInMsg->hdr.fc.direction ) )
  959. {
  960. // Process Client commands, received by server
  961. if( pInMsg->hdr.commandID == COMMAND_SE_GET_CURRENT_PRICE )
  962. {
  963. stat = zclSE_ProcessInCmd_Pricing_GetCurrentPrice( pInMsg, pCBs );
  964. }
  965. else if ( pInMsg->hdr.commandID == COMMAND_SE_GET_SCHEDULED_PRICE )
  966. {
  967. stat = zclSE_ProcessInCmd_Pricing_GetScheduledPrice( pInMsg, pCBs );
  968. }
  969. else
  970. stat = ZFailure;
  971. }
  972. else
  973. {
  974. // Process Server commands, received by client
  975. if ( pInMsg->hdr.commandID == COMMAND_SE_PUBLISH_PRICE )
  976. {
  977. stat = zclSE_ProcessInCmd_Pricing_PublishPrice( pInMsg, pCBs );
  978. }
  979. else
  980. stat = ZFailure;
  981. }
  982. return ( stat );
  983. }
  984. /*********************************************************************
  985. * @fn zclSE_ProcessInCmd_Pricing_GetCurrentPrice
  986. *
  987. * @brief Process in the received Get Current Price.
  988. *
  989. * @param pInMsg - pointer to the incoming message
  990. *
  991. * @return ZStatus_t - ZFailure @ Unsupported
  992. * ZCL_STATUS_CMD_HAS_RSP @ Supported and do
  993. * not need default rsp
  994. */
  995. static ZStatus_t zclSE_ProcessInCmd_Pricing_GetCurrentPrice( zclIncoming_t *pInMsg,
  996. zclSE_AppCallbacks_t *pCBs )
  997. {
  998. if ( pCBs->pfnPricing_GetCurrentPrice )
  999. {
  1000. zclCCGetCurrentPrice_t cmd;
  1001. cmd.option = pInMsg->pData[0];
  1002. pCBs->pfnPricing_GetCurrentPrice( &cmd, &(pInMsg->msg->srcAddr),
  1003. pInMsg->hdr.transSeqNum );
  1004. return ZCL_STATUS_CMD_HAS_RSP;
  1005. }
  1006. else
  1007. {
  1008. return ZFailure;
  1009. }
  1010. }
  1011. /*********************************************************************
  1012. * @fn zclSE_ProcessInCmd_Pricing_GetScheduledPrice
  1013. *
  1014. * @brief Process in the received Get Scheduled Price.
  1015. *
  1016. * @param pInMsg - pointer to the incoming message
  1017. *
  1018. * @return ZStatus_t - ZFailure @ Unsupported
  1019. * ZCL_STATUS_CMD_HAS_RSP @ Supported and do
  1020. * not need default rsp
  1021. */
  1022. static ZStatus_t zclSE_ProcessInCmd_Pricing_GetScheduledPrice( zclIncoming_t *pInMsg,
  1023. zclSE_AppCallbacks_t *pCBs )
  1024. {
  1025. if ( pCBs->pfnPricing_GetScheduledPrice )
  1026. {
  1027. zclCCGetScheduledPrice_t cmd;
  1028. cmd.startTime = osal_build_uint32( pInMsg->pData, 4 );
  1029. cmd.numEvents = pInMsg->pData[4];
  1030. pCBs->pfnPricing_GetScheduledPrice( &cmd, &(pInMsg->msg->srcAddr),
  1031. pInMsg->hdr.transSeqNum );
  1032. return ZCL_STATUS_CMD_HAS_RSP;
  1033. }
  1034. else
  1035. {
  1036. return ZFailure;
  1037. }
  1038. }
  1039. /*********************************************************************
  1040. * @fn zclSE_ProcessInCmd_Pricing_PublishPrice
  1041. *
  1042. * @brief Process in the received Publish Price.
  1043. *
  1044. * @param pInMsg - pointer to the incoming message
  1045. *
  1046. * @return ZStatus_t - ZFailure @ Unsupported
  1047. * ZSuccess @ Supported and need default rsp
  1048. * ZCL_STATUS_INVALID_FIELD @ Range checking
  1049. * failure
  1050. * ZCL_STATUS_SOFTWARE_FAILURE @ ZStack memory allocation failure
  1051. */
  1052. static ZStatus_t zclSE_ProcessInCmd_Pricing_PublishPrice( zclIncoming_t *pInMsg,
  1053. zclSE_AppCallbacks_t *pCBs )
  1054. {
  1055. if ( pCBs->pfnPricing_GetScheduledPrice )
  1056. {
  1057. zclCCPublishPrice_t cmd;
  1058. // Parse the command and do range check
  1059. if ( zclSE_ParseInCmd_PublishPrice( &cmd, &(pInMsg->pData[0]),
  1060. pInMsg->pDataLen ) == ZSuccess )
  1061. {
  1062. if ( cmd.unitOfMeasure > MAX_UNIT_OF_MEASURE_SE )
  1063. {
  1064. // Free the memory allocated in zclSE_ParseInCmd_PublishPrice()
  1065. if ( cmd.rateLabel.pStr != NULL )
  1066. {
  1067. osal_mem_free( cmd.rateLabel.pStr );
  1068. }
  1069. return ZCL_STATUS_INVALID_FIELD;
  1070. }
  1071. pCBs->pfnPricing_PublishPrice( &cmd, &(pInMsg->msg->srcAddr),
  1072. pInMsg->hdr.transSeqNum );
  1073. // Free the memory allocated in zclSE_ParseInCmd_PublishPrice()
  1074. if ( cmd.rateLabel.pStr != NULL )
  1075. {
  1076. osal_mem_free( cmd.rateLabel.pStr );
  1077. }
  1078. return ZSuccess;
  1079. }
  1080. else
  1081. {
  1082. return ZCL_STATUS_SOFTWARE_FAILURE;
  1083. }
  1084. }
  1085. else
  1086. {
  1087. return ZFailure;
  1088. }
  1089. }
  1090. #endif
  1091. #ifdef ZCL_MESSAGE
  1092. /*********************************************************************
  1093. * @fn zclSE_ProcessInMessageCmds
  1094. *
  1095. * @brief Callback from ZCL to process incoming Commands specific
  1096. * to this cluster library on a command ID basis
  1097. * @param pInMsg - pointer to the incoming message
  1098. *
  1099. * @return ZStatus_t
  1100. */
  1101. static ZStatus_t zclSE_ProcessInMessageCmds( zclIncoming_t *pInMsg,
  1102. zclSE_AppCallbacks_t *pCBs )
  1103. {
  1104. ZStatus_t stat = ZSuccess;
  1105. if ( zcl_ServerCmd( pInMsg->hdr.fc.direction ) )
  1106. {
  1107. // Process Client commands, received by server
  1108. if ( pInMsg->hdr.commandID == COMMAND_SE_GET_LAST_MESSAGE )
  1109. {
  1110. stat = zclSE_ProcessInCmd_Message_GetLastMessage( pInMsg, pCBs );
  1111. }
  1112. else if ( pInMsg->hdr.commandID == COMMAND_SE_MESSAGE_CONFIRMATION )
  1113. {
  1114. stat = zclSE_ProcessInCmd_Message_MessageConfirmation( pInMsg, pCBs );
  1115. }
  1116. else
  1117. stat = ZFailure;
  1118. }
  1119. else
  1120. {
  1121. // Process Server commands, received by client
  1122. if( pInMsg->hdr.commandID == COMMAND_SE_DISPLAY_MESSAGE )
  1123. {
  1124. stat = zclSE_ProcessInCmd_Message_DisplayMessage( pInMsg, pCBs );
  1125. }
  1126. else if ( pInMsg->hdr.commandID == COMMAND_SE_CANCEL_MESSAGE )
  1127. {
  1128. stat = zclSE_ProcessInCmd_Message_CancelMessage( pInMsg, pCBs );
  1129. }
  1130. else
  1131. stat = ZFailure;
  1132. }
  1133. return ( stat );
  1134. }
  1135. /*********************************************************************
  1136. * @fn zclSE_ProcessInCmd_Message_DisplayMessage
  1137. *
  1138. * @brief Process in the received Display Message Command.
  1139. *
  1140. * @param pInMsg - pointer to the incoming message
  1141. *
  1142. * @return ZStatus_t - ZFailure @ Unsupported
  1143. * ZSuccess @ Supported and send default rsp
  1144. * ZCL_STATUS_SOFTWARE_FAILURE @ ZStack memory allocation failure
  1145. */
  1146. static ZStatus_t zclSE_ProcessInCmd_Message_DisplayMessage( zclIncoming_t *pInMsg,
  1147. zclSE_AppCallbacks_t *pCBs )
  1148. {
  1149. if ( pCBs->pfnMessage_DisplayMessage )
  1150. {
  1151. zclCCDisplayMessage_t cmd;
  1152. if ( zclSE_ParseInCmd_DisplayMessage( &cmd, &(pInMsg->pData[0]), pInMsg->pDataLen ) == ZSuccess )
  1153. {
  1154. pCBs->pfnMessage_DisplayMessage( &cmd, &(pInMsg->msg->srcAddr),
  1155. pInMsg->hdr.transSeqNum );
  1156. // Free memory allocated in zclSE_ParseInCmd_DiplayMessage()
  1157. if ( cmd.msgString.pStr != NULL )
  1158. osal_mem_free( cmd.msgString.pStr );
  1159. return ZSuccess;
  1160. }
  1161. }
  1162. return ZFailure;
  1163. }
  1164. /*********************************************************************
  1165. * @fn zclSE_ProcessInCmd_Message_CancelMessage
  1166. *
  1167. * @brief Process in the received Cancel Message Command.
  1168. *
  1169. * @param pInMsg - pointer to the incoming message
  1170. *
  1171. * @return ZStatus_t - ZFailure @ Unsupported
  1172. * ZSuccess @ Supported and send default rsp
  1173. */
  1174. static ZStatus_t zclSE_ProcessInCmd_Message_CancelMessage( zclIncoming_t *pInMsg,
  1175. zclSE_AppCallbacks_t *pCBs )
  1176. {
  1177. if ( pCBs->pfnMessage_CancelMessage )
  1178. {
  1179. zclCCCancelMessage_t cmd;
  1180. cmd.messageId = osal_build_uint32( &(pInMsg->pData[0]), 4 );
  1181. // Message Control
  1182. cmd.messageCtrl.transmissionMode = pInMsg->pData[4] & 0x03; // bit 0&1
  1183. cmd.messageCtrl.importance = ( pInMsg->pData[4] >> SE_PROFILE_MSGCTRL_IMPORTANCE ) & 0x03; // bit 2&3
  1184. cmd.messageCtrl.confirmationRequired = ( pInMsg->pData[4] >> SE_PROFILE_MSGCTRL_CONFREQUIRED ) & 0x01; // bit 7
  1185. pCBs->pfnMessage_CancelMessage( &cmd, &(pInMsg->msg->srcAddr),
  1186. pInMsg->hdr.transSeqNum );
  1187. return ZSuccess;
  1188. }
  1189. else
  1190. {
  1191. return ZFailure;
  1192. }
  1193. }
  1194. /*********************************************************************
  1195. * @fn zclSE_ProcessInCmd_Message_GetLastMessage
  1196. *
  1197. * @brief Process in the received Get Last Message Command.
  1198. *
  1199. * @param pInMsg - pointer to the incoming message
  1200. *
  1201. * @return ZStatus_t - ZFailure @ Unsupported
  1202. * ZCL_STATUS_CMD_HAS_RSP @ Supported and do
  1203. * not need default rsp
  1204. */
  1205. static ZStatus_t zclSE_ProcessInCmd_Message_GetLastMessage( zclIncoming_t *pInMsg,
  1206. zclSE_AppCallbacks_t *pCBs )
  1207. {
  1208. if ( pCBs->pfnMessage_GetLastMessage )
  1209. {
  1210. pCBs->pfnMessage_GetLastMessage( &(pInMsg->msg->srcAddr), pInMsg->hdr.transSeqNum );
  1211. return ZCL_STATUS_CMD_HAS_RSP;
  1212. }
  1213. else
  1214. {
  1215. return ZFailure;
  1216. }
  1217. }
  1218. /*********************************************************************
  1219. * @fn zclSE_ProcessInCmd_Message_MessageConfirmation
  1220. *
  1221. * @brief Process in the received Message Confirmation.
  1222. *
  1223. * @param pInMsg - pointer to the incoming message
  1224. *
  1225. * @return ZStatus_t - ZFailure @ Unsupported
  1226. * ZSuccess @ Supported and send default rsp
  1227. */
  1228. static ZStatus_t zclSE_ProcessInCmd_Message_MessageConfirmation( zclIncoming_t *pInMsg,
  1229. zclSE_AppCallbacks_t *pCBs )
  1230. {
  1231. if ( pCBs->pfnMessage_MessageConfirmation )
  1232. {
  1233. zclCCMessageConfirmation_t cmd;
  1234. cmd.messageId = osal_build_uint32( &(pInMsg->pData[0]), 4 );
  1235. cmd.confirmTime = osal_build_uint32( &(pInMsg->pData[4]), 4 );
  1236. pCBs->pfnMessage_MessageConfirmation( &cmd, &(pInMsg->msg->srcAddr),
  1237. pInMsg->hdr.transSeqNum );
  1238. return ZSuccess;
  1239. }
  1240. else
  1241. {
  1242. return ZFailure;
  1243. }
  1244. }
  1245. #endif
  1246. #ifdef ZCL_LOAD_CONTROL
  1247. /*********************************************************************
  1248. * @fn zclSE_ProcessInLoadControlCmds
  1249. *
  1250. * @brief Callback from ZCL to process incoming Commands specific
  1251. * to this cluster library on a command ID basis
  1252. * @param pInMsg - pointer to the incoming message
  1253. *
  1254. * @return ZStatus_t
  1255. */
  1256. static ZStatus_t zclSE_ProcessInLoadControlCmds( zclIncoming_t *pInMsg,
  1257. zclSE_AppCallbacks_t *pCBs )
  1258. {
  1259. ZStatus_t stat = ZSuccess;
  1260. if ( zcl_ServerCmd( pInMsg->hdr.fc.direction ) )
  1261. {
  1262. // Process Client commands, received by server
  1263. if ( pInMsg->hdr.commandID == COMMAND_SE_REPORT_EVENT_STATUS )
  1264. {
  1265. stat = zclSE_ProcessInCmd_LoadControl_ReportEventStatus( pInMsg, pCBs );
  1266. }
  1267. else if( pInMsg->hdr.commandID == COMMAND_SE_GET_SCHEDULED_EVENT )
  1268. {
  1269. stat = zclSE_ProcessInCmd_LoadControl_GetScheduledEvents( pInMsg, pCBs );
  1270. }
  1271. else
  1272. stat = ZFailure;
  1273. }
  1274. else
  1275. {
  1276. // Process Server commands, received by client
  1277. if( pInMsg->hdr.commandID == COMMAND_SE_LOAD_CONTROL_EVENT )
  1278. {
  1279. stat = zclSE_ProcessInCmd_LoadControl_LoadControlEvent( pInMsg, pCBs );
  1280. }
  1281. else if ( pInMsg->hdr.commandID == COMMAND_SE_CANCEL_LOAD_CONTROL_EVENT )
  1282. {
  1283. stat = zclSE_ProcessInCmd_LoadControl_CancelLoadControlEvent( pInMsg, pCBs );
  1284. }
  1285. else if ( pInMsg->hdr.commandID == COMMAND_SE_CANCEL_ALL_LOAD_CONTROL_EVENT )
  1286. {
  1287. stat = zclSE_ProcessInCmd_LoadControl_CancelAllLoadControlEvents( pInMsg, pCBs );
  1288. }
  1289. else
  1290. stat = ZFailure;
  1291. }
  1292. return ( stat );
  1293. }
  1294. /*********************************************************************
  1295. * @fn zclSE_ProcessInCmd_LoadControl_LoadControlEvent
  1296. *
  1297. * @brief Process in the received Load Control Event.
  1298. *
  1299. * @param pInMsg - pointer to the incoming message
  1300. *
  1301. * @return ZStatus_t - ZFailure @ Unsupported
  1302. * ZCL_STATUS_CMD_HAS_RSP @ Supported and do
  1303. * not need default rsp
  1304. */
  1305. static ZStatus_t zclSE_ProcessInCmd_LoadControl_LoadControlEvent( zclIncoming_t *pInMsg,
  1306. zclSE_AppCallbacks_t *pCBs )
  1307. {
  1308. uint8 status = ZSuccess;
  1309. if ( pCBs->pfnLoadControl_LoadControlEvent )
  1310. {
  1311. zclCCLoadControlEvent_t cmd;
  1312. zclSE_ParseInCmd_LoadControlEvent( &cmd, &(pInMsg->pData[0]), pInMsg->pDataLen );
  1313. // Range checking
  1314. if ( cmd.durationInMinutes > MAX_DURATION_IN_MINUTES_SE_LOAD_CONTROL )
  1315. {
  1316. status = ZCL_STATUS_INVALID_FIELD;
  1317. }
  1318. if ( cmd.criticalityLevel > MAX_CRITICAL_LEVEL_SE_LOAD_CONTROL )
  1319. {
  1320. status = ZCL_STATUS_INVALID_FIELD;
  1321. }
  1322. if ( cmd. coolingTemperatureSetPoint != SE_OPTIONAL_FIELD_TEMPERATURE_SET_POINT &&
  1323. cmd. coolingTemperatureSetPoint > MAX_TEMPERATURE_SETPOINT_SE_LOAD_CONTROL )
  1324. {
  1325. status = ZCL_STATUS_INVALID_FIELD;
  1326. }
  1327. if ( cmd. heatingTemperatureSetPoint != SE_OPTIONAL_FIELD_TEMPERATURE_SET_POINT &&
  1328. cmd. heatingTemperatureSetPoint > MAX_TEMPERATURE_SETPOINT_SE_LOAD_CONTROL )
  1329. {
  1330. status = ZCL_STATUS_INVALID_FIELD;
  1331. }
  1332. if ( cmd.averageLoadAdjustmentPercentage != SE_OPTIONAL_FIELD_INT8 &&
  1333. (cmd.averageLoadAdjustmentPercentage < MIN_AVERAGE_LOAD_ADJUSTMENT_PERCENTAGE_SE ||
  1334. cmd.averageLoadAdjustmentPercentage > MAX_AVERAGE_LOAD_ADJUSTMENT_PERCENTAGE_SE ) )
  1335. {
  1336. status = ZCL_STATUS_INVALID_FIELD;
  1337. }
  1338. if ( cmd. dutyCycle != SE_OPTIONAL_FIELD_UINT8 &&
  1339. cmd. dutyCycle > MAX_DUTY_CYCLE_SE_LOAD_CONTROL )
  1340. {
  1341. status = ZCL_STATUS_INVALID_FIELD;
  1342. }
  1343. // If any of the four fields is optional, set them all to optional
  1344. if ( cmd.coolingTemperatureOffset == SE_OPTIONAL_FIELD_UINT8 ||
  1345. cmd.heatingTemperatureOffset == SE_OPTIONAL_FIELD_UINT8 ||
  1346. cmd.coolingTemperatureSetPoint == SE_OPTIONAL_FIELD_UINT16 ||
  1347. cmd.heatingTemperatureSetPoint == SE_OPTIONAL_FIELD_UINT16 )
  1348. {
  1349. cmd.coolingTemperatureOffset = SE_OPTIONAL_FIELD_UINT8;
  1350. cmd.heatingTemperatureOffset = SE_OPTIONAL_FIELD_UINT8;
  1351. cmd.coolingTemperatureSetPoint = SE_OPTIONAL_FIELD_UINT16;
  1352. cmd.heatingTemperatureSetPoint = SE_OPTIONAL_FIELD_UINT16;
  1353. }
  1354. pCBs->pfnLoadControl_LoadControlEvent( &cmd, &(pInMsg->msg->srcAddr), status, pInMsg->hdr.transSeqNum );
  1355. // The Load Control Event command has response, therefore,
  1356. // inform zclto not to send default response.
  1357. return ZCL_STATUS_CMD_HAS_RSP;
  1358. }
  1359. else
  1360. return ZFailure; // Not supported
  1361. }
  1362. /*********************************************************************
  1363. * @fn zclSE_ProcessInCmd_LoadControl_CancelLoadControlEvent
  1364. *
  1365. * @brief Process in the received Cancel Load Control Event.
  1366. *
  1367. * @param pInMsg - pointer to the incoming message
  1368. *
  1369. */
  1370. static ZStatus_t zclSE_ProcessInCmd_LoadControl_CancelLoadControlEvent( zclIncoming_t *pInMsg,
  1371. zclSE_AppCallbacks_t *pCBs )
  1372. {
  1373. if ( pCBs->pfnLoadControl_CancelLoadControlEvent )
  1374. {
  1375. zclCCCancelLoadControlEvent_t cmd;
  1376. zclSE_ParseInCmd_CancelLoadControlEvent( &cmd, &(pInMsg->pData[0]), pInMsg->pDataLen );
  1377. pCBs->pfnLoadControl_CancelLoadControlEvent( &cmd, &(pInMsg->msg->srcAddr), pInMsg->hdr.transSeqNum );
  1378. return ZSuccess;
  1379. }
  1380. else
  1381. return ZFailure;
  1382. }
  1383. /*********************************************************************
  1384. * @fn zclSE_ProcessInCmd_LoadControl_CancelAllLoadControlEvent
  1385. *
  1386. * @brief Process in the received Cancel All Load Control Event.
  1387. *
  1388. * @param pInMsg - pointer to the incoming message
  1389. *
  1390. */
  1391. static ZStatus_t zclSE_ProcessInCmd_LoadControl_CancelAllLoadControlEvents( zclIncoming_t *pInMsg,
  1392. zclSE_AppCallbacks_t *pCBs )
  1393. {
  1394. if ( pCBs->pfnLoadControl_CancelAllLoadControlEvents )
  1395. {
  1396. zclCCCancelAllLoadControlEvents_t cmd;
  1397. cmd.cancelControl = pInMsg->pData[0];
  1398. pCBs->pfnLoadControl_CancelAllLoadControlEvents( &cmd, &(pInMsg->msg->srcAddr), pInMsg->hdr.transSeqNum );
  1399. return ZSuccess;
  1400. }
  1401. else
  1402. return ZFailure;
  1403. }
  1404. /*********************************************************************
  1405. * @fn zclSE_ProcessInCmd_LoadControl_ReportEventStatus
  1406. *
  1407. * @brief Process in the received Load Control Event.
  1408. *
  1409. * @param pInMsg - pointer to the incoming message
  1410. *
  1411. */
  1412. static ZStatus_t zclSE_ProcessInCmd_LoadControl_ReportEventStatus( zclIncoming_t *pInMsg,
  1413. zclSE_AppCallbacks_t *pCBs )
  1414. {
  1415. if ( pCBs->pfnLoadControl_ReportEventStatus )
  1416. {
  1417. zclCCReportEventStatus_t cmd;
  1418. zclSE_ParseInCmd_ReportEventStatus( &cmd, &(pInMsg->pData[0]), pInMsg->pDataLen );
  1419. // Range Checking
  1420. if ( cmd.eventStatus != EVENT_STATUS_LOAD_CONTROL_EVENT_REJECTED &&
  1421. (cmd.eventStatus == 0 ||
  1422. cmd.eventStatus > EVENT_STATUS_LOAD_CONTROL_EVENT_SUPERSEDED ) )
  1423. {
  1424. return ZCL_STATUS_INVALID_FIELD;
  1425. }
  1426. if ( cmd.criticalityLevelApplied > MAX_CRITICAL_LEVEL_SE_LOAD_CONTROL )
  1427. {
  1428. return ZCL_STATUS_INVALID_FIELD;
  1429. }
  1430. if ( cmd.coolingTemperatureSetPointApplied != SE_OPTIONAL_FIELD_TEMPERATURE_SET_POINT &&
  1431. cmd.coolingTemperatureSetPointApplied > MAX_TEMPERATURE_SETPOINT_SE_LOAD_CONTROL )
  1432. {
  1433. return ZCL_STATUS_INVALID_FIELD;
  1434. }
  1435. if ( cmd.heatingTemperatureSetPointApplied != SE_OPTIONAL_FIELD_TEMPERATURE_SET_POINT &&
  1436. cmd.heatingTemperatureSetPointApplied > MAX_TEMPERATURE_SETPOINT_SE_LOAD_CONTROL )
  1437. {
  1438. return ZCL_STATUS_INVALID_FIELD;
  1439. }
  1440. if ( cmd.averageLoadAdjustment != SE_OPTIONAL_FIELD_INT8 &&
  1441. (cmd.averageLoadAdjustment < MIN_AVERAGE_LOAD_ADJUSTMENT_PERCENTAGE_SE ||
  1442. cmd.averageLoadAdjustment > MAX_AVERAGE_LOAD_ADJUSTMENT_PERCENTAGE_SE ) )
  1443. {
  1444. return ZCL_STATUS_INVALID_FIELD;
  1445. }
  1446. if ( cmd.dutyCycleApplied != SE_OPTIONAL_FIELD_UINT8 &&
  1447. cmd.dutyCycleApplied > MAX_DUTY_CYCLE_SE_LOAD_CONTROL )
  1448. {
  1449. return ZCL_STATUS_INVALID_FIELD;
  1450. }
  1451. pCBs->pfnLoadControl_ReportEventStatus( &cmd, &(pInMsg->msg->srcAddr), pInMsg->hdr.transSeqNum );
  1452. return ZSuccess;
  1453. }
  1454. else
  1455. return ZFailure;
  1456. }
  1457. /*********************************************************************
  1458. * @fn zclSE_ProcessInCmd_LoadControl_GetScheduledEvents
  1459. *
  1460. * @brief Process in the received Get Scheduled Event.
  1461. *
  1462. * @param pInMsg - pointer to the incoming message
  1463. *
  1464. */
  1465. static ZStatus_t zclSE_ProcessInCmd_LoadControl_GetScheduledEvents( zclIncoming_t *pInMsg,
  1466. zclSE_AppCallbacks_t *pCBs )
  1467. {
  1468. if ( pCBs->pfnLoadControl_GetScheduledEvents )
  1469. {
  1470. zclCCGetScheduledEvent_t cmd;
  1471. cmd.startTime = osal_build_uint32( pInMsg->pData, 4);
  1472. cmd.numEvents = pInMsg->pData[4];
  1473. pCBs->pfnLoadControl_GetScheduledEvents( &cmd, &(pInMsg->msg->srcAddr), pInMsg->hdr.transSeqNum );
  1474. return ZSuccess;
  1475. }
  1476. else
  1477. return ZFailure;
  1478. }
  1479. #endif
  1480. #ifdef ZCL_PRICING
  1481. /*********************************************************************
  1482. * @fn zclSE_ParseInCmd_PublishPrice
  1483. *
  1484. * @brief Parse received Publish Price Command.
  1485. *
  1486. * @param cmd - pointer to the output data struct
  1487. * @param buf - pointer to the input data buffer
  1488. * @param len - length of the input buffer
  1489. *
  1490. */
  1491. ZStatus_t zclSE_ParseInCmd_PublishPrice( zclCCPublishPrice_t *cmd, uint8 *buf, uint8 len )
  1492. {
  1493. (void)len; // Intentionally unreferenced parameter
  1494. // Parse the command buffer
  1495. cmd->providerId = osal_build_uint32( buf, 4 );
  1496. buf += 4;
  1497. // Notice that rate label is a variable length UTF-8 string
  1498. cmd->rateLabel.strLen = *buf++;
  1499. if ( cmd->rateLabel.strLen == SE_OPTIONAL_FIELD_UINT8 )
  1500. {
  1501. // If character count is 0xFF, set string length to 0
  1502. cmd->rateLabel.strLen = 0;
  1503. }
  1504. if ( cmd->rateLabel.strLen != 0 )
  1505. {
  1506. cmd->rateLabel.pStr = osal_mem_alloc( cmd->rateLabel.strLen );
  1507. if ( cmd->rateLabel.pStr == NULL )
  1508. {
  1509. return ZMemError;
  1510. }
  1511. osal_memcpy( cmd->rateLabel.pStr, buf, cmd->rateLabel.strLen );
  1512. buf += cmd->rateLabel.strLen;
  1513. }
  1514. else
  1515. {
  1516. cmd->rateLabel.pStr = NULL;
  1517. }
  1518. cmd->issuerEventId = osal_build_uint32( buf, 4 );
  1519. buf += 4;
  1520. cmd->currentTime = osal_build_uint32( buf, 4 );
  1521. buf += 4;
  1522. cmd->unitOfMeasure = *buf++;
  1523. cmd->currency = BUILD_UINT16( buf[0], buf[1] );
  1524. buf += 2;
  1525. cmd->priceTralingDigit = *buf++;
  1526. cmd->startTime = osal_build_uint32( buf, 4 );
  1527. buf += 4;
  1528. cmd->durationInMinutes = BUILD_UINT16( buf[0], buf[1] );
  1529. buf += 2;
  1530. cmd->price = osal_build_uint32( buf, 4 );
  1531. buf += 4;
  1532. cmd->priceRatio = *buf++;
  1533. cmd->generationPrice = osal_build_uint32( buf, 4 );
  1534. buf += 4;
  1535. cmd->generationPriceRatio = *buf++;
  1536. cmd->priceTier = *buf;
  1537. return ZSuccess;
  1538. }
  1539. #endif
  1540. #ifdef ZCL_MESSAGE
  1541. /*********************************************************************
  1542. * @fn zclSE_ParseInCmd_DisplayMessage
  1543. *
  1544. * @brief Parse received Display Message Command.
  1545. *
  1546. * @param cmd - pointer to the output data struct
  1547. * @param buf - pointer to the input data buffer
  1548. * @param len - length of the input buffer
  1549. *
  1550. * @return ZStatus_t - ZSuccess or ZFailure due to memory allocation failure
  1551. */
  1552. ZStatus_t zclSE_ParseInCmd_DisplayMessage( zclCCDisplayMessage_t *cmd, uint8 *buf, uint8 len )
  1553. {
  1554. (void)len; // Intentionally unreferenced parameter
  1555. cmd->messageId = osal_build_uint32( buf, 4 );
  1556. // Message control bitmap
  1557. cmd->messageCtrl.transmissionMode = buf[4] & 0x03; // bit 0&1
  1558. cmd->messageCtrl.importance = ( buf[4] >> SE_PROFILE_MSGCTRL_IMPORTANCE ) & 0x03; // bit 2&3
  1559. cmd->messageCtrl.confirmationRequired = (buf[4] >> SE_PROFILE_MSGCTRL_CONFREQUIRED ) & 0x01; // bit 7
  1560. cmd->startTime = osal_build_uint32( &(buf[5]), 4 );
  1561. cmd->durationInMinutes = BUILD_UINT16( buf[9], buf[10] );
  1562. cmd->msgString.strLen = buf[11];
  1563. // Copy the message string
  1564. if( cmd->msgString.strLen != 0 )
  1565. {
  1566. cmd->msgString.pStr = osal_mem_alloc( cmd->msgString.strLen );
  1567. if ( cmd->msgString.pStr == NULL )
  1568. return ZMemError;
  1569. osal_memcpy( cmd->msgString.pStr, &(buf[12]), cmd->msgString.strLen );
  1570. }
  1571. else
  1572. {
  1573. cmd->msgString.pStr = NULL;
  1574. }
  1575. return ZSuccess;
  1576. }
  1577. #endif
  1578. #ifdef ZCL_LOAD_CONTROL
  1579. /*********************************************************************
  1580. * @fn zclSE_ParseInCmd_LoadControlEvent
  1581. *
  1582. * @brief Parse received Load Control Event.
  1583. *
  1584. * @param cmd - pointer to the output data struct
  1585. * @param buf - pointer to the input data buffer
  1586. * @param len - length of the input buffer
  1587. *
  1588. */
  1589. void zclSE_ParseInCmd_LoadControlEvent( zclCCLoadControlEvent_t *cmd, uint8 *buf, uint8 len )
  1590. {
  1591. (void)len; // Intentionally unreferenced parameter
  1592. // Maybe add checking for buffer length later
  1593. // Skipped right now to leave MT input to guarantee
  1594. // proper buffer length
  1595. cmd->issuerEvent = osal_build_uint32( buf, 4 );
  1596. buf += 4;
  1597. cmd->deviceGroupClass = osal_build_uint32( buf, 3 );
  1598. buf += 3;
  1599. cmd->startTime = osal_build_uint32( buf, 4 );
  1600. buf += 4;
  1601. cmd->durationInMinutes = BUILD_UINT16( buf[0], buf[1] );
  1602. buf += 2;
  1603. cmd->criticalityLevel = *buf++;
  1604. cmd->coolingTemperatureOffset = *buf++;
  1605. cmd->heatingTemperatureOffset = *buf++;
  1606. cmd->coolingTemperatureSetPoint = BUILD_UINT16( buf[0], buf[1] );
  1607. buf += 2;
  1608. cmd->heatingTemperatureSetPoint = BUILD_UINT16( buf[0], buf[1] );
  1609. buf += 2;
  1610. cmd->averageLoadAdjustmentPercentage = *buf++;
  1611. cmd->dutyCycle = *buf++;
  1612. cmd->eventControl = *buf++;
  1613. return;
  1614. }
  1615. /*********************************************************************
  1616. * @fn zclSE_ParseInCmd_CancelLoadControlEvent
  1617. *
  1618. * @brief Parse received Cancel Load Control Event Command.
  1619. *
  1620. * @param cmd - pointer to the output data struct
  1621. * @param buf - pointer to the input data buffer
  1622. * @param len - length of the input buffer
  1623. *
  1624. */
  1625. void zclSE_ParseInCmd_CancelLoadControlEvent( zclCCCancelLoadControlEvent_t *cmd, uint8 *buf, uint8 len )
  1626. {
  1627. (void)len; // Intentionally unreferenced parameter
  1628. // Maybe add checking for buffer length later
  1629. // Skipped right now to leave MT input to guarantee
  1630. // proper buffer length
  1631. cmd->issuerEventID = osal_build_uint32( buf, 4 );
  1632. buf += 4;
  1633. cmd->deviceGroupClass = osal_build_uint32( buf, 3 );
  1634. buf += 3;
  1635. cmd->cancelControl = *buf++;
  1636. cmd->effectiveTime = osal_build_uint32( buf, 4 );
  1637. return;
  1638. }
  1639. /*********************************************************************
  1640. * @fn zclSE_ParseInCmd_ReportEventStatus
  1641. *
  1642. * @brief Parse received Report Event Status.
  1643. *
  1644. * @param cmd - pointer to the output data struct
  1645. * @param buf - pointer to the input data buffer
  1646. * @param len - length of the input buffer
  1647. *
  1648. */
  1649. void zclSE_ParseInCmd_ReportEventStatus( zclCCReportEventStatus_t *cmd, uint8 *buf, uint8 len )
  1650. {
  1651. (void)len; // Intentionally unreferenced parameter
  1652. // Maybe add checking for buffer length later
  1653. // Skipped right now to leave MT input to guarantee
  1654. // proper buffer length
  1655. cmd->issuerEventID = osal_build_uint32( buf, 4 );
  1656. buf += 4;
  1657. cmd->eventStatus = *buf++;
  1658. cmd->eventStartTime = osal_build_uint32( buf, 4 );
  1659. buf += 4;
  1660. cmd->criticalityLevelApplied = *buf++;
  1661. cmd->coolingTemperatureSetPointApplied = BUILD_UINT16( buf[0], buf[1] );
  1662. buf += 2;
  1663. cmd->heatingTemperatureSetPointApplied = BUILD_UINT16( buf[0], buf[1] );
  1664. buf += 2;
  1665. cmd->averageLoadAdjustment = *buf++;
  1666. cmd->dutyCycleApplied = *buf++;
  1667. cmd->eventControl = *buf++;
  1668. cmd->signatureType = *buf++;
  1669. osal_memcpy( cmd->signature, buf, SE_PROFILE_SIGNATURE_LENGTH );
  1670. return;
  1671. }
  1672. #endif
  1673. /********************************************************************************************
  1674. *********************************************************************************************/