esp.c 121 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482
  1. /**************************************************************************************************
  2. Filename: esp.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 ESP functionality and contains the
  6. 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 an ESP configuration:
  37. General Basic
  38. General Alarms
  39. General Time
  40. General Key Establishment
  41. SE Price
  42. SE Demand Response and Load Control
  43. SE Simple Metering
  44. SE Message
  45. Key control:
  46. SW1: Send out Cooling Load Control Event to PCT
  47. SW2: Send out Load Control Event to Load Control Device
  48. SW3: Send out Message to In Premise Display
  49. SW4: Not used
  50. *********************************************************************/
  51. /*********************************************************************
  52. * INCLUDES
  53. */
  54. #include "OSAL.h"
  55. #include "OSAL_Clock.h"
  56. #include "OSAL_Nv.h"
  57. #include "MT.h"
  58. #include "MT_APP.h"
  59. #include "ZDObject.h"
  60. #include "AddrMgr.h"
  61. #include "se.h"
  62. #include "esp.h"
  63. #include "zcl_general.h"
  64. #include "zcl_se.h"
  65. #include "zcl_key_establish.h"
  66. #if defined( INTER_PAN )
  67. #include "stub_aps.h"
  68. #endif
  69. #include "onboard.h"
  70. /* HAL */
  71. #include "hal_lcd.h"
  72. #include "hal_led.h"
  73. #include "hal_key.h"
  74. /*********************************************************************
  75. * MACROS
  76. */
  77. // There is no attribute in the Mandatory Reportable Attribute list for now
  78. #define zcl_MandatoryReportableAttribute( a ) ( a == NULL )
  79. /*********************************************************************
  80. * CONSTANTS
  81. */
  82. #define ESP_MIN_REPORTING_INTERVAL 5
  83. #if defined ( SE_UK_EXT ) && defined ( SE_MIRROR )
  84. // There can be up to ESP_MAX_MIRRORS mirror endpoints starting at the ESP_MIRROR_EP_BASE and
  85. // going up to ( ESP_MIRROR_EP_BASE + ESP_MAX_MIRRORS )
  86. #define ESP_MIRROR_EP_BASE 24
  87. // The max number of mirrors the ESP can have.
  88. // Note: This value is limited by the number of bits in the mirrorMask mask
  89. #define ESP_MAX_MIRRORS 16
  90. #define ESP_MIRROR_FULL_MASK 0xFFFF
  91. #define ESP_MIRROR_NOTIFY_ATTR_COUNT 6
  92. #define ESP_MIRROR_USER_ATTRIBUTES_POSITION ESP_MIRROR_NOTIFY_ATTR_COUNT
  93. #define ESP_MIRROR_MAX_USER_ATTRIBUTES 8
  94. #define ESP_MIRROR_MAX_ATTRIBUTES (ESP_MIRROR_NOTIFY_ATTR_COUNT + ESP_MIRROR_MAX_USER_ATTRIBUTES)
  95. #define ESP_MIRROR_INVALID_ENDPOINT 0xFF
  96. #endif // SE_UK_EXT && SE_MIRROR
  97. /*********************************************************************
  98. * TYPEDEFS
  99. */
  100. /*********************************************************************
  101. * GLOBAL VARIABLES
  102. */
  103. /*********************************************************************
  104. * GLOBAL FUNCTIONS
  105. */
  106. /*********************************************************************
  107. * LOCAL VARIABLES
  108. */
  109. static uint8 espTaskID; // esp osal task id
  110. static afAddrType_t ipdAddr; // destination address of in premise display
  111. static afAddrType_t pctAddr; // destination address of PCT
  112. static afAddrType_t loadControlAddr; // destination address of load control device
  113. static zAddrType_t simpleDescReqAddr; // destination addresses for simple desc request
  114. static zclCCLoadControlEvent_t loadControlCmd; // command structure for load control command
  115. static uint16 espFastPollModeDuration; // number of fast poll events
  116. #if defined ( INTER_PAN )
  117. // define endpoint structure to register with STUB APS for INTER-PAN support
  118. static endPointDesc_t espEp =
  119. {
  120. ESP_ENDPOINT,
  121. &espTaskID,
  122. (SimpleDescriptionFormat_t *)&espSimpleDesc,
  123. (afNetworkLatencyReq_t)0
  124. };
  125. #endif
  126. #if defined ( SE_UK_EXT ) && defined ( SE_MIRROR )
  127. typedef struct
  128. {
  129. uint16 srcAddr;
  130. uint8 srcEndpoint;
  131. zclAttrRec_t *pAttr;
  132. uint8 notificationControl;
  133. zclCCReqMirrorReportAttrRsp_t notificationSet;
  134. } espMirrorInfo_t;
  135. typedef struct
  136. {
  137. uint16 mirrorMask;
  138. espMirrorInfo_t mirrorInfo[ESP_MAX_MIRRORS];
  139. } espMirrorControl_t;
  140. #define MIRROR_DEVICE_VERSION 0
  141. #define MIRROR_FLAGS 0
  142. #define MIRROR_MAX_INCLUSTERS 2
  143. CONST cId_t mirrorInClusterList[MIRROR_MAX_INCLUSTERS] =
  144. {
  145. ZCL_CLUSTER_ID_GEN_BASIC,
  146. ZCL_CLUSTER_ID_SE_SIMPLE_METERING
  147. };
  148. #define MIRROR_MAX_OUTCLUSTERS 2
  149. CONST cId_t mirrorOutClusterList[MIRROR_MAX_OUTCLUSTERS] =
  150. {
  151. ZCL_CLUSTER_ID_GEN_BASIC,
  152. ZCL_CLUSTER_ID_SE_SIMPLE_METERING
  153. };
  154. #endif // SE_UK_EXT && SE_MIRROR
  155. /*********************************************************************
  156. * LOCAL FUNCTIONS
  157. */
  158. static void esp_HandleKeys( uint8 shift, uint8 keys );
  159. static void esp_ProcessAppMsg( uint8 *msg );
  160. static void esp_ProcessIdentifyTimeChange( void );
  161. /*************************************************************************/
  162. /*** Application Callback Functions ***/
  163. /*************************************************************************/
  164. // Foundation Callback functions
  165. static uint8 esp_ValidateAttrDataCB( zclAttrRec_t *pAttr, zclWriteRec_t *pAttrInfo );
  166. // General Cluster Callback functions
  167. static void esp_BasicResetCB( void );
  168. static void esp_IdentifyCB( zclIdentify_t *pCmd );
  169. static void esp_IdentifyQueryRspCB( zclIdentifyQueryRsp_t *pRsp );
  170. static void esp_AlarmCB( zclAlarm_t *pAlarm );
  171. #ifdef SE_UK_EXT
  172. static void esp_GetEventLogCB( uint8 srcEP, afAddrType_t *srcAddr,
  173. zclGetEventLog_t *pEventLog, uint8 seqNum );
  174. static void esp_PublishEventLogCB( afAddrType_t *srcAddr, zclPublishEventLog_t *pEventLog );
  175. #endif // SE_UK_EXT
  176. // SE Callback functions
  177. static void esp_GetProfileCmdCB( zclCCGetProfileCmd_t *pCmd,
  178. afAddrType_t *srcAddr, uint8 seqNum );
  179. static void esp_GetProfileRspCB( zclCCGetProfileRsp_t *pCmd,
  180. afAddrType_t *srcAddr, uint8 seqNum );
  181. static void esp_ReqMirrorCmdCB( afAddrType_t *srcAddr, uint8 seqNum );
  182. static void esp_ReqMirrorRspCB( zclCCReqMirrorRsp_t *pCmd,
  183. afAddrType_t *srcAddr, uint8 seqNum );
  184. static void esp_MirrorRemCmdCB( afAddrType_t *srcAddr, uint8 seqNum );
  185. static void esp_MirrorRemRspCB( zclCCMirrorRemRsp_t *pCmd,
  186. afAddrType_t *srcAddr, uint8 seqNum );
  187. static void esp_ReqFastPollModeCmdCB( zclCCReqFastPollModeCmd_t *pCmd,
  188. afAddrType_t *srcAddr, uint8 seqNum );
  189. static void esp_ReqFastPollModeRspCB( zclCCReqFastPollModeRsp_t *pRsp,
  190. afAddrType_t *srcAddr, uint8 seqNum );
  191. static void esp_GetCurrentPriceCB( zclCCGetCurrentPrice_t *pCmd,
  192. afAddrType_t *srcAddr, uint8 seqNum );
  193. static void esp_GetScheduledPriceCB( zclCCGetScheduledPrice_t *pCmd,
  194. afAddrType_t *srcAddr, uint8 seqNum );
  195. static void esp_PriceAcknowledgementCB( zclCCPriceAcknowledgement_t *pCmd,
  196. afAddrType_t *srcAddr, uint8 seqNum );
  197. static void esp_GetBlockPeriodCB( zclCCGetBlockPeriod_t *pCmd,
  198. afAddrType_t *srcAddr, uint8 seqNum );
  199. static void esp_PublishPriceCB( zclCCPublishPrice_t *pCmd,
  200. afAddrType_t *srcAddr, uint8 seqNum );
  201. static void esp_PublishBlockPeriodCB( zclCCPublishBlockPeriod_t *pCmd,
  202. afAddrType_t *srcAddr, uint8 seqNum );
  203. static void esp_DisplayMessageCB( zclCCDisplayMessage_t *pCmd,
  204. afAddrType_t *srcAddr, uint8 seqNum );
  205. static void esp_CancelMessageCB( zclCCCancelMessage_t *pCmd,
  206. afAddrType_t *srcAddr, uint8 seqNum );
  207. static void esp_GetLastMessageCB( afAddrType_t *srcAddr, uint8 seqNum );
  208. static void esp_MessageConfirmationCB( zclCCMessageConfirmation_t *pCmd,
  209. afAddrType_t *srcAddr, uint8 seqNum );
  210. static void esp_LoadControlEventCB( zclCCLoadControlEvent_t *pCmd,
  211. afAddrType_t *srcAddr, uint8 status, uint8 seqNum);
  212. static void esp_CancelLoadControlEventCB( zclCCCancelLoadControlEvent_t *pCmd,
  213. afAddrType_t *srcAddr, uint8 seqNum );
  214. static void esp_CancelAllLoadControlEventsCB( zclCCCancelAllLoadControlEvents_t *pCmd,
  215. afAddrType_t *srcAddr, uint8 seqNum );
  216. static void esp_ReportEventStatusCB( zclCCReportEventStatus_t *pCmd,
  217. afAddrType_t *srcAddr, uint8 seqNum );
  218. static void esp_GetScheduledEventCB( zclCCGetScheduledEvent_t *pCmd,
  219. afAddrType_t *srcAddr, uint8 seqNum );
  220. static void esp_SelAvailEmergencyCreditCmdCB( zclCCSelAvailEmergencyCredit_t *pCmd,
  221. afAddrType_t *srcAddr, uint8 seqNum );
  222. static void esp_ChangeSupplyCmdCB( zclCCChangeSupply_t *pCmd,
  223. afAddrType_t *srcAddr, uint8 seqNum );
  224. static void esp_SupplyStatusRspCB( zclCCSupplyStatusResponse_t *pCmd,
  225. afAddrType_t *srcAddr, uint8 seqNum );
  226. #if defined ( SE_UK_EXT )
  227. static void esp_GetSnapshotRspCB( zclCCReqGetSnapshotRsp_t *pCmd,
  228. afAddrType_t *srcAddr, uint8 seqNum );
  229. static void esp_PublishTariffInformationCB( zclCCPublishTariffInformation_t *pCmd,
  230. afAddrType_t *srcAddr, uint8 seqNum );
  231. static void esp_PublishPriceMatrixCB( zclCCPublishPriceMatrix_t *pCmd,
  232. afAddrType_t *srcAddr, uint8 seqNum );
  233. static void esp_PublishBlockThresholdsCB( zclCCPublishBlockThresholds_t *pCmd,
  234. afAddrType_t *srcAddr, uint8 seqNum );
  235. static void esp_PublishConversionFactorCB( zclCCPublishConversionFactor_t *pCmd,
  236. afAddrType_t *srcAddr, uint8 seqNum );
  237. static void esp_PublishCalorificValueCB( zclCCPublishCalorificValue_t *pCmd,
  238. afAddrType_t *srcAddr, uint8 seqNum );
  239. static void esp_PublishCO2ValueCB( zclCCPublishCO2Value_t *pCmd,
  240. afAddrType_t *srcAddr, uint8 seqNum );
  241. static void esp_PublishCPPEventCB( zclCCPublishCPPEvent_t *pCmd,
  242. afAddrType_t *srcAddr, uint8 seqNum );
  243. static void esp_PublishBillingPeriodCB( zclCCPublishBillingPeriod_t *pCmd,
  244. afAddrType_t *srcAddr, uint8 seqNum );
  245. static void esp_PublishConsolidatedBillCB( zclCCPublishConsolidatedBill_t *pCmd,
  246. afAddrType_t *srcAddr, uint8 seqNum );
  247. static void esp_PublishCreditPaymentInfoCB( zclCCPublishCreditPaymentInfo_t *pCmd,
  248. afAddrType_t *srcAddr, uint8 seqNum );
  249. static void esp_GetTariffInformationCB( zclCCGetTariffInformation_t *pCmd,
  250. afAddrType_t *srcAddr, uint8 seqNum );
  251. static void esp_GetPriceMatrixCB( uint32 issuerTariffId,
  252. afAddrType_t *srcAddr, uint8 seqNum );
  253. static void esp_GetBlockThresholdsCB( uint32 issuerTariffId,
  254. afAddrType_t *srcAddr, uint8 seqNum );
  255. static void esp_GetConversionFactorCB( zclCCGetConversionFactor_t *pCmd,
  256. afAddrType_t *srcAddr, uint8 seqNum );
  257. static void esp_GetCalorificValueCB( zclCCGetCalorificValue_t *pCmd,
  258. afAddrType_t *srcAddr, uint8 seqNum );
  259. static void esp_GetCO2ValueCB( zclCCGetCO2Value_t *pCmd,
  260. afAddrType_t *srcAddr, uint8 seqNum );
  261. static void esp_GetBillingPeriodCB( zclCCGetBillingPeriod_t *pCmd,
  262. afAddrType_t *srcAddr, uint8 seqNum );
  263. static void esp_GetConsolidatedBillCB( zclCCGetConsolidatedBill_t *pCmd,
  264. afAddrType_t *srcAddr, uint8 seqNum );
  265. static void esp_CPPEventResponseCB( zclCCCPPEventResponse_t *pCmd,
  266. afAddrType_t *srcAddr, uint8 seqNum );
  267. static void esp_ChangeDebtCB( zclCCChangeDebt_t *pCmd,
  268. afAddrType_t *srcAddr, uint8 seqNum );
  269. static void esp_EmergencyCreditSetupCB( zclCCEmergencyCreditSetup_t *pCmd,
  270. afAddrType_t *srcAddr, uint8 seqNum );
  271. static void esp_ConsumerTopupCB( zclCCConsumerTopup_t *pCmd,
  272. afAddrType_t *srcAddr, uint8 seqNum );
  273. static void esp_CreditAdjustmentCB( zclCCCreditAdjustment_t *pCmd,
  274. afAddrType_t *srcAddr, uint8 seqNum );
  275. static void esp_ChangePaymentModeCB( zclCCChangePaymentMode_t *pCmd,
  276. afAddrType_t *srcAddr, uint8 seqNum );
  277. static void esp_GetPrepaySnapshotCB( zclCCGetPrepaySnapshot_t *pCmd,
  278. afAddrType_t *srcAddr, uint8 seqNum );
  279. static void esp_GetTopupLogCB( uint8 numEvents,
  280. afAddrType_t *srcAddr, uint8 seqNum );
  281. static void esp_SetLowCreditWarningLevelCB( uint8 numEvents,
  282. afAddrType_t *srcAddr, uint8 seqNum );
  283. static void esp_GetDebtRepaymentLogCB( zclCCGetDebtRepaymentLog_t *pCmd,
  284. afAddrType_t *srcAddr, uint8 seqNum );
  285. static void esp_GetPrepaySnapshotResponseCB( zclCCGetPrepaySnapshotResponse_t *pCmd,
  286. afAddrType_t *srcAddr, uint8 seqNum );
  287. static void esp_ChangePaymentModeResponseCB( zclCCChangePaymentModeResponse_t *pCmd,
  288. afAddrType_t *srcAddr, uint8 seqNum );
  289. static void esp_ConsumerTopupResponseCB( zclCCConsumerTopupResponse_t *pCmd,
  290. afAddrType_t *srcAddr, uint8 seqNum );
  291. static void esp_GetCommandsCB( uint8 prepayNotificationFlags,
  292. afAddrType_t *srcAddr, uint8 seqNum );
  293. static void esp_PublishTopupLogCB( zclCCPublishTopupLog_t *pCmd,
  294. afAddrType_t *srcAddr, uint8 seqNum );
  295. static void esp_PublishDebtLogCB( zclCCPublishDebtLog_t *pCmd,
  296. afAddrType_t *srcAddr, uint8 seqNum );
  297. #endif // SE_UK_EXT
  298. /************************************************************************/
  299. /*** Functions to process ZCL Foundation ***/
  300. /*** incoming Command/Response messages ***/
  301. /************************************************************************/
  302. static void esp_ProcessZCLMsg( zclIncomingMsg_t *msg );
  303. #if defined ( ZCL_READ )
  304. static uint8 esp_ProcessInReadRspCmd( zclIncomingMsg_t *pInMsg );
  305. #endif // ZCL_READ
  306. #if defined ( ZCL_WRITE )
  307. static uint8 esp_ProcessInWriteRspCmd( zclIncomingMsg_t *pInMsg );
  308. #endif // ZCL_WRITE
  309. #if defined ( ZCL_REPORT )
  310. static uint8 esp_ProcessInConfigReportCmd( zclIncomingMsg_t *pInMsg );
  311. static uint8 esp_ProcessInConfigReportRspCmd( zclIncomingMsg_t *pInMsg );
  312. static uint8 esp_ProcessInReadReportCfgCmd( zclIncomingMsg_t *pInMsg );
  313. static uint8 esp_ProcessInReadReportCfgRspCmd( zclIncomingMsg_t *pInMsg );
  314. static uint8 esp_ProcessInReportCmd( zclIncomingMsg_t *pInMsg );
  315. #endif // ZCL_REPORT
  316. static uint8 esp_ProcessInDefaultRspCmd( zclIncomingMsg_t *pInMsg );
  317. #if defined ( ZCL_DISCOVER )
  318. static uint8 esp_ProcessInDiscRspCmd( zclIncomingMsg_t *pInMsg );
  319. #endif // ZCL_DISCOVER
  320. // Functions to handle ZDO messages
  321. static void esp_ProcessZDOMsg( zdoIncomingMsg_t *inMsg );
  322. #if defined ( SE_UK_EXT ) && defined ( SE_MIRROR )
  323. static void esp_MirrorInit( void );
  324. static uint8 esp_GetMirrorEndpoint( afAddrType_t *srcAddr );
  325. static uint8 esp_AllocMirror( afAddrType_t *srcAddr );
  326. static void esp_FreeMirror( uint8 endPoint );
  327. static uint8 esp_IsMirrorEndpoint( uint8 endpoint );
  328. static void esp_MirrorProcessZCLMsg( zclIncomingMsg_t *pInMsg );
  329. static espMirrorInfo_t *esp_GetMirrorInfo( uint8 endpoint );
  330. static uint8 esp_MirrorUpdateAttribute( uint8 endpoint, uint16 cluster,
  331. zclReport_t *pReport );
  332. static void esp_MirrorInitAttributeSet( uint8 endpoint );
  333. static espMirrorControl_t esp_MirrorControl;
  334. #endif // SE_UK_EXT && SE_MIRROR
  335. /*********************************************************************
  336. * ZCL General Clusters Callback table
  337. */
  338. static zclGeneral_AppCallbacks_t esp_GenCmdCallbacks =
  339. {
  340. esp_BasicResetCB, // Basic Cluster Reset command
  341. esp_IdentifyCB, // Identify command
  342. esp_IdentifyQueryRspCB, // Identify Query Response command
  343. NULL, // On/Off cluster commands
  344. NULL, // Level Control Move to Level command
  345. NULL, // Level Control Move command
  346. NULL, // Level Control Step command
  347. NULL, // Level Control Stop command
  348. NULL, // Group Response commands
  349. NULL, // Scene Store Request command
  350. NULL, // Scene Recall Request command
  351. NULL, // Scene Response command
  352. esp_AlarmCB, // Alarm (Response) command
  353. #ifdef SE_UK_EXT
  354. esp_GetEventLogCB, // Get Event Log command
  355. esp_PublishEventLogCB, // Publish Event Log command
  356. #endif
  357. NULL, // RSSI Location command
  358. NULL // RSSI Location Response command
  359. };
  360. /*********************************************************************
  361. * ZCL SE Clusters Callback table
  362. */
  363. static zclSE_AppCallbacks_t esp_SECmdCallbacks =
  364. {
  365. esp_PublishPriceCB, // Publish Price
  366. esp_PublishBlockPeriodCB, // Publish Block Period
  367. #if defined ( SE_UK_EXT )
  368. esp_PublishTariffInformationCB, // Publish Tariff Information
  369. esp_PublishPriceMatrixCB, // Publish Price Matrix
  370. esp_PublishBlockThresholdsCB, // Publish Block Thresholds
  371. esp_PublishConversionFactorCB, // Publish Conversion Factor
  372. esp_PublishCalorificValueCB, // Publish Calorific Value
  373. esp_PublishCO2ValueCB, // Publish CO2 Value
  374. esp_PublishCPPEventCB, // Publish CPP Event
  375. esp_PublishBillingPeriodCB, // Publish Billing Period
  376. esp_PublishConsolidatedBillCB, // Publish Consolidated Bill
  377. esp_PublishCreditPaymentInfoCB, // Publish Credit Payment Info
  378. #endif // SE_UK_EXT
  379. esp_GetCurrentPriceCB, // Get Current Price
  380. esp_GetScheduledPriceCB, // Get Scheduled Price
  381. esp_PriceAcknowledgementCB, // Price Acknowledgement
  382. esp_GetBlockPeriodCB, // Get Block Period
  383. #if defined ( SE_UK_EXT )
  384. esp_GetTariffInformationCB, // Get Tariff Information
  385. esp_GetPriceMatrixCB, // Get Price Matrix
  386. esp_GetBlockThresholdsCB, // Get Block Thresholds
  387. esp_GetConversionFactorCB, // Get Conversion Factor
  388. esp_GetCalorificValueCB, // Get Calorific Value
  389. esp_GetCO2ValueCB, // Get CO2 Value
  390. esp_GetBillingPeriodCB, // Get Billing Period
  391. esp_GetConsolidatedBillCB, // Get Consolidated Bill
  392. esp_CPPEventResponseCB, // CPP Event Response
  393. #endif // SE_UK_EXT
  394. esp_LoadControlEventCB, // Load Control Event
  395. esp_CancelLoadControlEventCB, // Cancel Load Control Event
  396. esp_CancelAllLoadControlEventsCB, // Cancel All Load Control Events
  397. esp_ReportEventStatusCB, // Report Event Status
  398. esp_GetScheduledEventCB, // Get Scheduled Event
  399. esp_GetProfileRspCB, // Get Profile Response
  400. esp_ReqMirrorCmdCB, // Request Mirror Command
  401. esp_MirrorRemCmdCB, // Mirror Remove Command
  402. esp_ReqFastPollModeRspCB, // Request Fast Poll Mode Response
  403. #if defined ( SE_UK_EXT )
  404. esp_GetSnapshotRspCB, // Get Snapshot Response
  405. #endif // SE_UK_EXT
  406. esp_GetProfileCmdCB, // Get Profile Command
  407. esp_ReqMirrorRspCB, // Request Mirror Response
  408. esp_MirrorRemRspCB, // Mirror Remove Response
  409. esp_ReqFastPollModeCmdCB, // Request Fast Poll Mode Command
  410. #if defined ( SE_UK_EXT )
  411. NULL, // Get Snapshot Command
  412. NULL, // Take Snapshot Command
  413. NULL, // Mirror Report Attribute Response
  414. #endif // SE_UK_EXT
  415. esp_DisplayMessageCB, // Display Message Command
  416. esp_CancelMessageCB, // Cancel Message Command
  417. esp_GetLastMessageCB, // Get Last Message Command
  418. esp_MessageConfirmationCB, // Message Confirmation
  419. NULL, // Request Tunnel Response
  420. NULL, // Transfer Data
  421. NULL, // Transfer Data Error
  422. NULL, // Ack Transfer Data
  423. NULL, // Ready Data
  424. #if defined ( SE_UK_EXT )
  425. NULL, // Supported Tunnel Protocols Response
  426. NULL, // Tunnel Closure Notification
  427. #endif // SE_UK_EXT
  428. NULL, // Request Tunnel
  429. NULL, // Close Tunnel
  430. #if defined ( SE_UK_EXT )
  431. NULL, // Get Supported Tunnel Protocols
  432. #endif // SE_UK_EXT
  433. esp_SupplyStatusRspCB, // Supply Status Response
  434. #if defined ( SE_UK_EXT )
  435. esp_GetPrepaySnapshotResponseCB, // Get Prepay Snapshot Response
  436. esp_ChangePaymentModeResponseCB, // Change Payment Mode Response
  437. esp_ConsumerTopupResponseCB, // Consumer Topup Response
  438. esp_GetCommandsCB, // Get Commands
  439. esp_PublishTopupLogCB, // Publish Topup Log
  440. esp_PublishDebtLogCB, // Publish Debt Log
  441. #endif // SE_UK_EXT
  442. esp_SelAvailEmergencyCreditCmdCB, // Select Available Emergency Credit Command
  443. esp_ChangeSupplyCmdCB, // Change Supply Command
  444. #if defined ( SE_UK_EXT )
  445. esp_ChangeDebtCB, // Change Debt
  446. esp_EmergencyCreditSetupCB, // Emergency Credit Setup
  447. esp_ConsumerTopupCB, // Consumer Topup
  448. esp_CreditAdjustmentCB, // Credit Adjustment
  449. esp_ChangePaymentModeCB, // Change PaymentMode
  450. esp_GetPrepaySnapshotCB, // Get Prepay Snapshot
  451. esp_GetTopupLogCB, // Get Topup Log
  452. esp_SetLowCreditWarningLevelCB, // Set Low Credit Warning Level
  453. esp_GetDebtRepaymentLogCB, // Get Debt Repayment Log
  454. NULL, // Publish Calendar
  455. NULL, // Publish Day Profile
  456. NULL, // Publish Week Profile
  457. NULL, // Publish Seasons
  458. NULL, // Publish Special Days
  459. NULL, // Get Calendar
  460. NULL, // Get Day Profiles
  461. NULL, // Get Week Profiles
  462. NULL, // Get Seasons
  463. NULL, // Get Special Days
  464. NULL, // Publish Change Tenancy
  465. NULL, // Publish Change Supplier
  466. NULL, // Change Supply
  467. NULL, // Change Password
  468. NULL, // Local Change Supply
  469. NULL, // Get Change Tenancy
  470. NULL, // Get Change Supplier
  471. NULL, // Get Change Supply
  472. NULL, // Supply Status Response
  473. NULL, // Get Password
  474. #endif // SE_UK_EXT
  475. };
  476. /*********************************************************************
  477. * @fn esp_Init
  478. *
  479. * @brief Initialization function for the ZCL App Application.
  480. *
  481. * @param uint8 task_id - esp task id
  482. *
  483. * @return none
  484. */
  485. void esp_Init( uint8 task_id )
  486. {
  487. espTaskID = task_id;
  488. // Register for an SE endpoint
  489. zclSE_Init( &espSimpleDesc );
  490. // Register the ZCL General Cluster Library callback functions
  491. zclGeneral_RegisterCmdCallbacks( ESP_ENDPOINT, &esp_GenCmdCallbacks );
  492. // Register the ZCL SE Cluster Library callback functions
  493. zclSE_RegisterCmdCallbacks( ESP_ENDPOINT, &esp_SECmdCallbacks );
  494. // Register the application's attribute list
  495. zcl_registerAttrList( ESP_ENDPOINT, ESP_MAX_ATTRIBUTES, espAttrs );
  496. // Register the application's cluster option list
  497. zcl_registerClusterOptionList( ESP_ENDPOINT, ESP_MAX_OPTIONS, espOptions );
  498. // Register the application's attribute data validation callback function
  499. zcl_registerValidateAttrData( esp_ValidateAttrDataCB );
  500. // Register the Application to receive the unprocessed Foundation command/response messages
  501. zcl_registerForMsg( espTaskID );
  502. // register for end device annce and simple descriptor responses
  503. ZDO_RegisterForZDOMsg( espTaskID, Device_annce );
  504. ZDO_RegisterForZDOMsg( espTaskID, Simple_Desc_rsp );
  505. // Register for all key events - This app will handle all key events
  506. RegisterForKeys( espTaskID );
  507. #if defined ( INTER_PAN )
  508. // Register with Stub APS
  509. StubAPS_RegisterApp( &espEp );
  510. #endif
  511. // Start the timer to sync esp timer with the osal timer
  512. osal_start_timerEx( espTaskID, ESP_UPDATE_TIME_EVT, ESP_UPDATE_TIME_PERIOD );
  513. // setup address mode and destination endpoint fields for PCT
  514. pctAddr.addrMode = (afAddrMode_t)Addr16Bit;
  515. pctAddr.endPoint = ESP_ENDPOINT;
  516. // setup address mode and destination endpoint fields for load control device
  517. loadControlAddr.addrMode = (afAddrMode_t)Addr16Bit;
  518. loadControlAddr.endPoint = ESP_ENDPOINT;
  519. //setup load control command structure
  520. loadControlCmd.issuerEvent = 0x12345678; // arbitrary id
  521. loadControlCmd.deviceGroupClass = 0x000000; // addresses all groups
  522. loadControlCmd.startTime = 0x00000000; // start time = NOW
  523. loadControlCmd.durationInMinutes = 0x0001; // duration of one minute
  524. loadControlCmd.criticalityLevel = 0x01; // green level
  525. loadControlCmd.coolingTemperatureSetPoint = 0x076C; // 19 degrees C, 66.2 degress fahrenheit
  526. loadControlCmd.eventControl = 0x00; // no randomized start or end applied
  527. // Initialize variable used to control number of fast poll events
  528. espFastPollModeDuration = 0;
  529. // detect and remove stored deprecated end device children after power up
  530. uint8 cleanupChildTable = TRUE;
  531. zgSetItem( ZCD_NV_ROUTER_OFF_ASSOC_CLEANUP, sizeof(cleanupChildTable), &cleanupChildTable );
  532. #if defined ( SE_UK_EXT ) && defined ( SE_MIRROR )
  533. esp_MirrorInit();
  534. #endif // SE_UK_EXT && SE_MIRROR
  535. }
  536. /*********************************************************************
  537. * @fn esp_event_loop
  538. *
  539. * @brief Event Loop Processor for esp.
  540. *
  541. * @param uint8 task_id - esp task id
  542. * @param uint16 events - event bitmask
  543. *
  544. * @return none
  545. */
  546. uint16 esp_event_loop( uint8 task_id, uint16 events )
  547. {
  548. afIncomingMSGPacket_t *MSGpkt;
  549. if ( events & SYS_EVENT_MSG )
  550. {
  551. while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( espTaskID )) )
  552. {
  553. switch ( MSGpkt->hdr.event )
  554. {
  555. case MT_SYS_APP_MSG:
  556. // Message received from MT (serial port)
  557. esp_ProcessAppMsg( ((mtSysAppMsg_t *)MSGpkt)->appData );
  558. break;
  559. case ZCL_INCOMING_MSG:
  560. // Incoming ZCL foundation command/response messages
  561. esp_ProcessZCLMsg( (zclIncomingMsg_t *)MSGpkt );
  562. break;
  563. case KEY_CHANGE:
  564. esp_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );
  565. break;
  566. case ZDO_CB_MSG:
  567. // ZDO sends the message that we registered for
  568. esp_ProcessZDOMsg( (zdoIncomingMsg_t *)MSGpkt );
  569. break;
  570. default:
  571. break;
  572. }
  573. // Release the memory
  574. osal_msg_deallocate( (uint8 *)MSGpkt );
  575. }
  576. // return unprocessed events
  577. return (events ^ SYS_EVENT_MSG);
  578. }
  579. // handle processing of identify timeout event triggered by an identify command
  580. if ( events & ESP_IDENTIFY_TIMEOUT_EVT )
  581. {
  582. if ( espIdentifyTime > 0 )
  583. {
  584. espIdentifyTime--;
  585. }
  586. esp_ProcessIdentifyTimeChange();
  587. return ( events ^ ESP_IDENTIFY_TIMEOUT_EVT );
  588. }
  589. // event to get current time
  590. if ( events & ESP_UPDATE_TIME_EVT )
  591. {
  592. espTime = osal_getClock();
  593. osal_start_timerEx( espTaskID, ESP_UPDATE_TIME_EVT, ESP_UPDATE_TIME_PERIOD );
  594. return ( events ^ ESP_UPDATE_TIME_EVT );
  595. }
  596. // event to get simple descriptor of the newly joined device
  597. if ( events & SIMPLE_DESC_QUERY_EVT )
  598. {
  599. ZDP_SimpleDescReq( &simpleDescReqAddr, simpleDescReqAddr.addr.shortAddr,
  600. ESP_ENDPOINT, 0);
  601. return ( events ^ SIMPLE_DESC_QUERY_EVT );
  602. }
  603. // handle processing of timeout event triggered by request fast polling command
  604. if ( events & ESP_FAST_POLL_MODE_EVT )
  605. {
  606. if (espFastPollModeDuration)
  607. {
  608. espFastPollModeDuration--;
  609. // Start the timer for the fast poll period
  610. osal_start_timerEx( espTaskID, ESP_FAST_POLL_MODE_EVT, ESP_FAST_POLL_TIMER_PERIOD );
  611. }
  612. return ( events ^ ESP_FAST_POLL_MODE_EVT );
  613. }
  614. // Discard unknown events
  615. return 0;
  616. }
  617. /*********************************************************************
  618. * @fn esp_ProcessAppMsg
  619. *
  620. * @brief Process MT SYS APP MSG
  621. *
  622. * @param msg - pointer to message
  623. *
  624. * @return none
  625. */
  626. static void esp_ProcessAppMsg( uint8 *msg )
  627. {
  628. // user should include code to handle MT SYS APP MSG here
  629. }
  630. /*********************************************************************
  631. * @fn esp_ProcessIdentifyTimeChange
  632. *
  633. * @brief Called to blink led for specified IdentifyTime attribute value
  634. *
  635. * @param none
  636. *
  637. * @return none
  638. */
  639. static void esp_ProcessIdentifyTimeChange( void )
  640. {
  641. if ( espIdentifyTime > 0 )
  642. {
  643. osal_start_timerEx( espTaskID, ESP_IDENTIFY_TIMEOUT_EVT, 1000 );
  644. HalLedBlink ( HAL_LED_4, 0xFF, HAL_LED_DEFAULT_DUTY_CYCLE, HAL_LED_DEFAULT_FLASH_TIME );
  645. }
  646. else
  647. {
  648. HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
  649. osal_stop_timerEx( espTaskID, ESP_IDENTIFY_TIMEOUT_EVT );
  650. }
  651. }
  652. /*********************************************************************
  653. * @fn esp_HandleKeys
  654. *
  655. * @brief Handles all key events for this device.
  656. *
  657. * @param shift - true if in shift/alt.
  658. * @param keys - bit field for key events. Valid entries:
  659. * HAL_KEY_SW_4
  660. * HAL_KEY_SW_3
  661. * HAL_KEY_SW_2
  662. * HAL_KEY_SW_1
  663. *
  664. * @return none
  665. */
  666. static void esp_HandleKeys( uint8 shift, uint8 keys )
  667. {
  668. // Shift is used to make each button/switch dual purpose.
  669. if ( shift )
  670. {
  671. if ( keys & HAL_KEY_SW_1 )
  672. {
  673. }
  674. if ( keys & HAL_KEY_SW_2 )
  675. {
  676. }
  677. if ( keys & HAL_KEY_SW_3 )
  678. {
  679. }
  680. if ( keys & HAL_KEY_SW_4 )
  681. {
  682. }
  683. }
  684. else
  685. {
  686. if ( keys & HAL_KEY_SW_1 )
  687. {
  688. // send out cooling event to PCT
  689. loadControlCmd.deviceGroupClass = HVAC_DEVICE_CLASS; // HVAC compressor or furnace - bit 0 is set
  690. zclSE_LoadControl_Send_LoadControlEvent( ESP_ENDPOINT, &pctAddr, &loadControlCmd, TRUE, 0 );
  691. }
  692. if ( keys & HAL_KEY_SW_2 )
  693. {
  694. // send out load control event to load control device
  695. loadControlCmd.deviceGroupClass = ONOFF_LOAD_DEVICE_CLASS; // simple misc residential on/off loads - bit 7 is set
  696. zclSE_LoadControl_Send_LoadControlEvent( ESP_ENDPOINT, &loadControlAddr, &loadControlCmd, TRUE, 0 );
  697. }
  698. if ( keys & HAL_KEY_SW_3 )
  699. {
  700. zclCCDisplayMessage_t displayCmd; // command structure for message being sent to in premise display
  701. // Define to zero to send the TI IPD message, non-zero to send a string of abc's.
  702. #if !defined IPD_MSG_SZ
  703. #define IPD_MSG_SZ 0
  704. #endif
  705. #if (IPD_MSG_SZ == 0)
  706. uint8 msgBuf[]="TI IPD Test Msg!";
  707. const uint8 msgLen = sizeof(msgBuf);
  708. #else
  709. uint8 *msgBuf = osal_mem_alloc(IPD_MSG_SZ);
  710. const uint8 msgLen = IPD_MSG_SZ;
  711. uint8 idx;
  712. if (!msgBuf) return;
  713. for (idx = 0; idx < msgLen; idx ++)
  714. {
  715. msgBuf[idx] = 'a' + idx % 26;
  716. }
  717. #endif
  718. displayCmd.msgString.strLen = msgLen;
  719. displayCmd.msgString.pStr = msgBuf;
  720. zclSE_Message_Send_DisplayMessage( ESP_ENDPOINT, &ipdAddr, &displayCmd, TRUE, 0 );
  721. #if (IPD_MSG_SZ != 0)
  722. osal_mem_free(msgBuf);
  723. #endif
  724. }
  725. if ( keys & HAL_KEY_SW_4 )
  726. {
  727. }
  728. }
  729. }
  730. /*********************************************************************
  731. * @fn esp_ValidateAttrDataCB
  732. *
  733. * @brief Check to see if the supplied value for the attribute data
  734. * is within the specified range of the attribute.
  735. *
  736. *
  737. * @param pAttr - pointer to attribute
  738. * @param pAttrInfo - pointer to attribute info
  739. *
  740. * @return TRUE if data valid. FALSE otherwise.
  741. */
  742. static uint8 esp_ValidateAttrDataCB( zclAttrRec_t *pAttr, zclWriteRec_t *pAttrInfo )
  743. {
  744. uint8 valid = TRUE;
  745. switch ( pAttrInfo->dataType )
  746. {
  747. case ZCL_DATATYPE_BOOLEAN:
  748. if ( ( *(pAttrInfo->attrData) != 0 ) && ( *(pAttrInfo->attrData) != 1 ) )
  749. {
  750. valid = FALSE;
  751. }
  752. break;
  753. default:
  754. break;
  755. }
  756. return ( valid );
  757. }
  758. /*********************************************************************
  759. * @fn esp_BasicResetCB
  760. *
  761. * @brief Callback from the ZCL General Cluster Library to set all
  762. * the attributes of all the clusters to their factory defaults
  763. *
  764. * @param none
  765. *
  766. * @return none
  767. */
  768. static void esp_BasicResetCB( void )
  769. {
  770. // user should handle setting attributes to factory defaults here
  771. }
  772. /*********************************************************************
  773. * @fn esp_IdentifyCB
  774. *
  775. * @brief Callback from the ZCL General Cluster Library when
  776. * it received an Identify Command for this application.
  777. *
  778. * @param pCmd - pointer to structure for Identify command
  779. *
  780. * @return none
  781. */
  782. static void esp_IdentifyCB( zclIdentify_t *pCmd )
  783. {
  784. espIdentifyTime = pCmd->identifyTime;
  785. esp_ProcessIdentifyTimeChange();
  786. }
  787. /*********************************************************************
  788. * @fn esp_IdentifyQueryRspCB
  789. *
  790. * @brief Callback from the ZCL General Cluster Library when
  791. * it received an Identity Query Response Command for this application.
  792. *
  793. * @param pRsp - pointer to structure for Identity Query Response command
  794. *
  795. * @return none
  796. */
  797. static void esp_IdentifyQueryRspCB( zclIdentifyQueryRsp_t *pRsp )
  798. {
  799. // add user code here
  800. }
  801. /*********************************************************************
  802. * @fn esp_AlarmCB
  803. *
  804. * @brief Callback from the ZCL General Cluster Library when
  805. * it received an Alam request or response command for
  806. * this application.
  807. *
  808. * @param pAlarm - pointer to structure for Alarm command
  809. *
  810. * @return none
  811. */
  812. static void esp_AlarmCB( zclAlarm_t *pAlarm )
  813. {
  814. // add user code here
  815. }
  816. #ifdef SE_UK_EXT
  817. /*********************************************************************
  818. * @fn esp_GetEventLogCB
  819. *
  820. * @brief Callback from the ZCL General Cluster Library when
  821. * it received a Get Event Log command for this
  822. * application.
  823. *
  824. * @param srcEP - source endpoint
  825. * @param srcAddr - pointer to source address
  826. * @param pEventLog - pointer to structure for Get Event Log command
  827. * @param seqNum - sequence number of this command
  828. *
  829. * @return none
  830. */
  831. static void esp_GetEventLogCB( uint8 srcEP, afAddrType_t *srcAddr,
  832. zclGetEventLog_t *pEventLog, uint8 seqNum )
  833. {
  834. // add user code here, which could fragment the event log payload if
  835. // the entire payload doesn't fit into one Publish Event Log Command.
  836. // Note: the Command Index starts at 0 and is incremented for each
  837. // fragment belonging to the same command.
  838. // There's no event log for now! The Metering Device will support
  839. // logging for all events configured to do so.
  840. }
  841. /*********************************************************************
  842. * @fn esp_PublishEventLogCB
  843. *
  844. * @brief Callback from the ZCL General Cluster Library when
  845. * it received a Publish Event Log command for this
  846. * application.
  847. *
  848. * @param srcAddr - pointer to source address
  849. * @param pEventLog - pointer to structure for Publish Event Log command
  850. *
  851. * @return none
  852. */
  853. static void esp_PublishEventLogCB( afAddrType_t *srcAddr, zclPublishEventLog_t *pEventLog )
  854. {
  855. // add user code here
  856. }
  857. #endif // SE_UK_EXT
  858. /*********************************************************************
  859. * @fn esp_GetProfileCmdCB
  860. *
  861. * @brief Callback from the ZCL SE Profile Simple Metering Cluster Library when
  862. * it received a Get Profile Command for
  863. * this application.
  864. *
  865. * @param pCmd - pointer to structure for Get Profile command
  866. * @param srcAddr - pointer to source address
  867. * @param seqNum - sequence number of this command
  868. *
  869. * @return none
  870. */
  871. static void esp_GetProfileCmdCB( zclCCGetProfileCmd_t *pCmd,
  872. afAddrType_t *srcAddr, uint8 seqNum )
  873. {
  874. #if defined ( ZCL_SIMPLE_METERING )
  875. // Upon receipt of the Get Profile Command, the metering device shall send
  876. // Get Profile Response back.
  877. // Variables in the following are initialized to arbitrary value for test purpose
  878. // In real application, user shall look up the interval data captured during
  879. // the period specified in the pCmd->endTime and return corresponding data.
  880. uint32 endTime;
  881. uint8 status = zclSE_SimpleMeter_GetProfileRsp_Status_Success;
  882. uint8 profileIntervalPeriod = PROFILE_INTERVAL_PERIOD_60MIN;
  883. uint8 numberOfPeriodDelivered = 5;
  884. uint24 intervals[] = {0xa00001, 0xa00002, 0xa00003, 0xa00004, 0xa00005};
  885. // endTime: 32 bit value (in UTC) representing the end time of the most
  886. // chronologically recent interval being requested.
  887. // Example: Data collected from 2:00 PM to 3:00 PM would be specified as a
  888. // 3:00 PM interval (end time).
  889. // The Intervals block returned shall be the most recent block with
  890. // its EndTime equal or older to the one in the request (pCmd->endTime).
  891. // Requested End Time with value 0xFFFFFFFF indicats the most recent
  892. // Intervals block is requested.
  893. // Sample Code - assuming the end time of the requested block is the same as
  894. // it in the request.
  895. endTime = pCmd->endTime;
  896. // Send Get Profile Response Command back
  897. zclSE_SimpleMetering_Send_GetProfileRsp( ESP_ENDPOINT, srcAddr, endTime,
  898. status,
  899. profileIntervalPeriod,
  900. numberOfPeriodDelivered, intervals,
  901. FALSE, seqNum );
  902. #endif // ZCL_SIMPLE_METERING
  903. }
  904. /*********************************************************************
  905. * @fn esp_GetProfileRspCB
  906. *
  907. * @brief Callback from the ZCL SE Profile Simple Metering Cluster Library when
  908. * it received a Get Profile Response for
  909. * this application.
  910. *
  911. * @param pCmd - pointer to structure for Get Profile Response command
  912. * @param srcAddr - pointer to source address
  913. * @param seqNum - sequence number of this command
  914. *
  915. * @return none
  916. */
  917. static void esp_GetProfileRspCB( zclCCGetProfileRsp_t *pCmd,
  918. afAddrType_t *srcAddr, uint8 seqNum )
  919. {
  920. // add user code here
  921. }
  922. /*********************************************************************
  923. * @fn esp_ReqMirrorCmdCB
  924. *
  925. * @brief Callback from the ZCL SE Profile Simple Metering Cluster Library when
  926. * it received a Request Mirror Command for
  927. * this application.
  928. *
  929. * @param srcAddr - pointer to source address
  930. * @param seqNum - sequence number of this command
  931. *
  932. * @return none
  933. */
  934. static void esp_ReqMirrorCmdCB( afAddrType_t *srcAddr, uint8 seqNum )
  935. {
  936. #if defined ( ZCL_SIMPLE_METERING )
  937. #if defined ( SE_UK_EXT ) && defined ( SE_MIRROR )
  938. uint8 endpoint;
  939. // See if a mirror exists for the given source address and endpoint
  940. endpoint = esp_GetMirrorEndpoint( srcAddr );
  941. if ( endpoint == ESP_MIRROR_INVALID_ENDPOINT )
  942. {
  943. // No endpoint exists. Try allocating one.
  944. endpoint = esp_AllocMirror(srcAddr);
  945. if (endpoint != ESP_MIRROR_INVALID_ENDPOINT)
  946. {
  947. // Setup endpoint
  948. espMirrorInfo_t *pInfo = esp_GetMirrorInfo(endpoint);
  949. if ( pInfo != NULL )
  950. {
  951. // Create a simple descriptor for the mirror
  952. SimpleDescriptionFormat_t *pMirrorSimpleDesc = osal_mem_alloc( sizeof( SimpleDescriptionFormat_t ) );
  953. if ( pMirrorSimpleDesc != NULL )
  954. {
  955. zclAttrRec_t *pAttr = pInfo->pAttr;
  956. pMirrorSimpleDesc->EndPoint = endpoint;
  957. pMirrorSimpleDesc->AppProfId = ZCL_SE_PROFILE_ID;
  958. pMirrorSimpleDesc->AppDeviceId = ZCL_SE_DEVICEID_METER;
  959. pMirrorSimpleDesc->AppDevVer = MIRROR_DEVICE_VERSION;
  960. pMirrorSimpleDesc->Reserved = MIRROR_FLAGS;
  961. pMirrorSimpleDesc->AppNumInClusters = MIRROR_MAX_INCLUSTERS;
  962. pMirrorSimpleDesc->pAppInClusterList = (cId_t *) mirrorInClusterList;
  963. pMirrorSimpleDesc->AppNumOutClusters = MIRROR_MAX_OUTCLUSTERS;
  964. pMirrorSimpleDesc->pAppOutClusterList = (cId_t *) mirrorOutClusterList;
  965. zclSE_Init( pMirrorSimpleDesc );
  966. // Register the attribute list
  967. zcl_registerAttrList( endpoint, ESP_MIRROR_MAX_ATTRIBUTES, (CONST zclAttrRec_t *) pAttr );
  968. }
  969. else
  970. {
  971. esp_FreeMirror( endpoint );
  972. endpoint = ESP_MIRROR_INVALID_ENDPOINT;
  973. }
  974. }
  975. }
  976. }
  977. if ( endpoint != ESP_MIRROR_INVALID_ENDPOINT )
  978. {
  979. // Send response to the peer with the mirror endpoint ID
  980. zclSE_SimpleMetering_Send_ReqMirrorRsp( ESP_ENDPOINT, srcAddr, endpoint, TRUE, seqNum );
  981. }
  982. else
  983. {
  984. // Send response indicating we cannot create the mirror
  985. zclSE_SimpleMetering_Send_ReqMirrorRsp(ESP_ENDPOINT, srcAddr, 0xFFFF, TRUE, seqNum);
  986. }
  987. #endif // SE_UK_EXT && SE_MIRROR
  988. #endif // ZCL_SIMPLE_METERING
  989. }
  990. /*********************************************************************
  991. * @fn esp_ReqMirrorRspCB
  992. *
  993. * @brief Callback from the ZCL SE Profile Simple Metering Cluster Library when
  994. * it received a Request Mirror Response for
  995. * this application.
  996. *
  997. * @param pCmd - pointer to structure for Request Mirror Response command
  998. * @param srcAddr - pointer to source address
  999. * @param seqNum - sequence number of this command
  1000. *
  1001. * @return none
  1002. */
  1003. static void esp_ReqMirrorRspCB( zclCCReqMirrorRsp_t *pCmd,
  1004. afAddrType_t *srcAddr, uint8 seqNum )
  1005. {
  1006. // add user code here
  1007. }
  1008. /*********************************************************************
  1009. * @fn esp_MirrorRemCmdCB
  1010. *
  1011. * @brief Callback from the ZCL SE Profile Simple Metering Cluster Library when
  1012. * it received a Mirror Remove Command for
  1013. * this application.
  1014. *
  1015. * @param srcAddr - pointer to source address
  1016. * @param seqNum - sequence number of this command
  1017. *
  1018. * @return none
  1019. */
  1020. static void esp_MirrorRemCmdCB( afAddrType_t *srcAddr, uint8 seqNum )
  1021. {
  1022. #if defined ( ZCL_SIMPLE_METERING )
  1023. #if defined ( SE_UK_EXT ) && defined ( SE_MIRROR )
  1024. // Check if this is a valid endpoint for a mirror
  1025. uint8 endpoint = esp_GetMirrorEndpoint( srcAddr );
  1026. if ( endpoint != ESP_MIRROR_INVALID_ENDPOINT )
  1027. {
  1028. // Set the PhysicalEnvironment attribute indicating a mirror slot is available
  1029. espPhysicalEnvironment |= PHY_MIRROR_CAPACITY_ENV;
  1030. endPointDesc_t *epDesc = afFindEndPointDesc( endpoint );
  1031. // Free memory allocated for SimpleDescriptor in esp_ReqMirrorCmdCB()
  1032. if ( epDesc->simpleDesc != NULL )
  1033. {
  1034. osal_mem_free( epDesc->simpleDesc );
  1035. }
  1036. // Delete endpoint completely
  1037. afDelete( endpoint );
  1038. // Free the mirror in the mirror control block
  1039. esp_FreeMirror( endpoint );
  1040. // Send response to peer
  1041. zclSE_SimpleMetering_Send_RemMirrorRsp( ESP_ENDPOINT, srcAddr, endpoint, TRUE, seqNum );
  1042. }
  1043. else
  1044. {
  1045. // The specification does not state how to deal with the case where no mirror exists,
  1046. // For now, send 0xFFFF in the endpoint.
  1047. zclSE_SimpleMetering_Send_RemMirrorRsp( ESP_ENDPOINT, srcAddr, 0xFFFF, TRUE, seqNum );
  1048. }
  1049. #endif // SE_UK_EXT && SE_MIRROR
  1050. #endif // ZCL_SIMPLE_METERING
  1051. }
  1052. /*********************************************************************
  1053. * @fn esp_MirrorRemRspCB
  1054. *
  1055. * @brief Callback from the ZCL SE Profile Simple Metering Cluster Library when
  1056. * it received a Mirror Remove Response for
  1057. * this application.
  1058. *
  1059. * @param pCmd - pointer to structure for Mirror Remove Response command
  1060. * @param srcAddr - pointer to source address
  1061. * @param seqNum - sequence number of this command
  1062. *
  1063. * @return none
  1064. */
  1065. static void esp_MirrorRemRspCB( zclCCMirrorRemRsp_t *pCmd,
  1066. afAddrType_t *srcAddr, uint8 seqNum )
  1067. {
  1068. // add user code here
  1069. }
  1070. /*********************************************************************
  1071. * @fn esp_ReqFastPollModeCmdCB
  1072. *
  1073. * @brief Callback from the ZCL SE Profile Simple Metering Cluster Library when
  1074. * it received a Request Fast Poll Mode Command for
  1075. * this application.
  1076. *
  1077. * @param pCmd - pointer to structure for Request Fast Poll Mode command
  1078. * @param srcAddr - pointer to source address
  1079. * @param seqNum - sequence number of this command
  1080. *
  1081. * @return none
  1082. */
  1083. static void esp_ReqFastPollModeCmdCB( zclCCReqFastPollModeCmd_t *pCmd, afAddrType_t *srcAddr, uint8 seqNum )
  1084. {
  1085. #if defined ( ZCL_SIMPLE_METERING )
  1086. if ( pCmd != NULL )
  1087. {
  1088. zclCCReqFastPollModeRsp_t fastPollRsp;
  1089. UTCTime utcSecs;
  1090. if (pCmd->fastPollUpdatePeriod < espFastPollUpdatePeriod)
  1091. {
  1092. // handles client requests for a fast poll rate that is less than the
  1093. // value of the its FastPollUpdateRate attribute
  1094. fastPollRsp.appliedUpdatePeriod = espFastPollUpdatePeriod;
  1095. }
  1096. else
  1097. {
  1098. fastPollRsp.appliedUpdatePeriod = pCmd->fastPollUpdatePeriod;
  1099. }
  1100. if ((espFastPollModeDuration == 0) && (pCmd->duration > 0))
  1101. {
  1102. if (pCmd->duration > MAX_DURATION_IN_MINUTES_FAST_POLL_MODE)
  1103. {
  1104. // handles client requests for duration that is greater than the
  1105. // maximum allowable 15 minutes.
  1106. espFastPollModeDuration = MAX_DURATION_IN_MINUTES_FAST_POLL_MODE;
  1107. }
  1108. else
  1109. {
  1110. espFastPollModeDuration = pCmd->duration;
  1111. }
  1112. // This controls the counter for ZCLTESTAPP_FAST_POLL_MODE_EVT based on a 1 second timer
  1113. espFastPollModeDuration *= 60; // Duration in seconds
  1114. // Start the timer for the fast poll period
  1115. osal_start_timerEx( espTaskID, ESP_FAST_POLL_MODE_EVT, ESP_FAST_POLL_TIMER_PERIOD );
  1116. }
  1117. // get UTC time and update with requested duration in seconds
  1118. utcSecs = osal_getClock();
  1119. fastPollRsp.fastPollModeEndTime = utcSecs + espFastPollModeDuration;
  1120. zclSE_SimpleMetering_Send_ReqFastPollModeRsp( ESP_ENDPOINT, srcAddr,
  1121. &fastPollRsp,
  1122. TRUE, seqNum );
  1123. #if defined ( LCD_SUPPORTED )
  1124. HalLcdWriteString("Fast Polling", HAL_LCD_LINE_1);
  1125. HalLcdWriteStringValue("Cur 0x", utcSecs, 16, HAL_LCD_LINE_2 );
  1126. HalLcdWriteStringValue("End 0x", fastPollRsp.fastPollModeEndTime, 16, HAL_LCD_LINE_3 );
  1127. #endif
  1128. }
  1129. #endif // ZCL_SIMPLE_METERING
  1130. }
  1131. /*********************************************************************
  1132. * @fn esp_ReqFastPollModeRspCB
  1133. *
  1134. * @brief Callback from the ZCL SE Profile Simple Metering Cluster Library when
  1135. * it received a Request Fast Poll Mode Response for
  1136. * this application.
  1137. *
  1138. * @param pRsp - pointer to structure for Request Fast Poll Mode Response command
  1139. * @param srcAddr - pointer to source address
  1140. * @param seqNum - sequence number of this command
  1141. *
  1142. * @return none
  1143. */
  1144. static void esp_ReqFastPollModeRspCB( zclCCReqFastPollModeRsp_t *pRsp,
  1145. afAddrType_t *srcAddr, uint8 seqNum )
  1146. {
  1147. // add user code here
  1148. }
  1149. /*********************************************************************
  1150. * @fn esp_GetCurrentPriceCB
  1151. *
  1152. * @brief Callback from the ZCL SE Profile Pricing Cluster Library when
  1153. * it received a Get Current Price for
  1154. * this application.
  1155. *
  1156. * @param pCmd - pointer to structure for Get Current Price command
  1157. * @param srcAddr - pointer to source address
  1158. * @param seqNum - sequence number for this command
  1159. *
  1160. * @return none
  1161. */
  1162. static void esp_GetCurrentPriceCB( zclCCGetCurrentPrice_t *pCmd,
  1163. afAddrType_t *srcAddr, uint8 seqNum )
  1164. {
  1165. #if defined ( ZCL_PRICING )
  1166. // On receipt of Get Current Price command, the device shall send a
  1167. // Publish Price command with the information for the current time.
  1168. zclCCPublishPrice_t cmd;
  1169. uint8 rateLabelLen = 4; // adjust this value if different label is set, test label "BASE"
  1170. osal_memset( &cmd, 0, sizeof( zclCCPublishPrice_t ) );
  1171. // Set Pricing information
  1172. cmd.providerId = 0xbabeface;
  1173. cmd.rateLabel.pStr = (uint8 *)osal_mem_alloc(rateLabelLen);
  1174. if (cmd.rateLabel.pStr != NULL)
  1175. {
  1176. cmd.rateLabel.strLen = rateLabelLen;
  1177. osal_memcpy(cmd.rateLabel.pStr, "BASE", rateLabelLen);
  1178. }
  1179. cmd.issuerEventId = 0x00000000;
  1180. cmd.currentTime = osal_getClock();
  1181. cmd.unitOfMeasure = 0x00;
  1182. cmd.currency = 0x0348;
  1183. cmd.priceTrailingDigit = 0x11;
  1184. cmd.numberOfPriceTiers = 0x21;
  1185. cmd.startTime = 0x00000000;
  1186. cmd.durationInMinutes = 0x003C;
  1187. cmd.price = 0x00000018;
  1188. cmd.priceRatio = SE_OPTIONAL_FIELD_UINT8;
  1189. cmd.generationPrice = SE_OPTIONAL_FIELD_UINT32;
  1190. cmd.generationPriceRatio = SE_OPTIONAL_FIELD_UINT8;
  1191. cmd.alternateCostDelivered = SE_OPTIONAL_FIELD_UINT32;
  1192. cmd.alternateCostUnit = SE_OPTIONAL_FIELD_UINT8;
  1193. cmd.alternateCostTrailingDigit = SE_OPTIONAL_FIELD_UINT8;
  1194. cmd.numberOfBlockThresholds = SE_OPTIONAL_FIELD_UINT8;
  1195. cmd.priceControl = SE_PROFILE_PRICEACK_REQUIRED_MASK;
  1196. // copy source address of display device that requested current pricing info so
  1197. // that esp can send messages to it using destination address of IPDAddr
  1198. osal_memcpy( &ipdAddr, srcAddr, sizeof ( afAddrType_t ) );
  1199. zclSE_Pricing_Send_PublishPrice( ESP_ENDPOINT, srcAddr, &cmd, FALSE, seqNum );
  1200. if (cmd.rateLabel.pStr != NULL)
  1201. {
  1202. osal_mem_free(cmd.rateLabel.pStr);
  1203. }
  1204. #endif // ZCL_PRICING
  1205. }
  1206. /*********************************************************************
  1207. * @fn esp_GetScheduledPriceCB
  1208. *
  1209. * @brief Callback from the ZCL SE Profile Pricing Cluster Library when
  1210. * it received a Get Scheduled Price for
  1211. * this application.
  1212. *
  1213. * @param pCmd - pointer to structure for Get Scheduled Price command
  1214. * @param srcAddr - pointer to source address
  1215. * @param seqNum - sequence number for this command
  1216. *
  1217. * @return none
  1218. */
  1219. static void esp_GetScheduledPriceCB( zclCCGetScheduledPrice_t *pCmd,
  1220. afAddrType_t *srcAddr, uint8 seqNum )
  1221. {
  1222. // On receipt of Get Scheduled Price command, the device shall send a
  1223. // Publish Price command for all currently scheduled price events.
  1224. // The sample code as follows only sends one.
  1225. #if defined ( ZCL_PRICING )
  1226. zclCCPublishPrice_t cmd;
  1227. osal_memset( &cmd, 0, sizeof( zclCCPublishPrice_t ) );
  1228. cmd.providerId = 0xbabeface;
  1229. cmd.numberOfPriceTiers = 0xfe;
  1230. zclSE_Pricing_Send_PublishPrice( ESP_ENDPOINT, srcAddr, &cmd, FALSE, seqNum );
  1231. #endif // ZCL_PRICING
  1232. }
  1233. /*********************************************************************
  1234. * @fn esp_PriceAcknowledgementCB
  1235. *
  1236. * @brief Callback from the ZCL SE Profile Pricing Cluster Library when
  1237. * it received a Price Acknowledgement for this application.
  1238. *
  1239. * @param pCmd - pointer to structure for Price Acknowledgement command
  1240. * @param srcAddr - pointer to source address
  1241. * @param seqNum - sequence number for this command
  1242. *
  1243. * @return none
  1244. */
  1245. static void esp_PriceAcknowledgementCB( zclCCPriceAcknowledgement_t *pCmd,
  1246. afAddrType_t *srcAddr, uint8 seqNum )
  1247. {
  1248. // add user code here
  1249. }
  1250. /*********************************************************************
  1251. * @fn esp_GetBlockPeriodCB
  1252. *
  1253. * @brief Callback from the ZCL SE Profile Pricing Cluster Library when
  1254. * it received a Get Block Period for this application.
  1255. *
  1256. * @param pCmd - pointer to structure for Get Block Period command
  1257. * @param srcAddr - pointer to source address
  1258. * @param seqNum - sequence number for this command
  1259. *
  1260. * @return none
  1261. */
  1262. static void esp_GetBlockPeriodCB( zclCCGetBlockPeriod_t *pCmd,
  1263. afAddrType_t *srcAddr, uint8 seqNum )
  1264. {
  1265. // add user code here
  1266. }
  1267. /*********************************************************************
  1268. * @fn esp_PublishPriceCB
  1269. *
  1270. * @brief Callback from the ZCL SE Profile Pricing Cluster Library when
  1271. * it received a Publish Price for this application.
  1272. *
  1273. * @param pCmd - pointer to structure for Publish Price command
  1274. * @param srcAddr - pointer to source address
  1275. * @param seqNum - sequence number for this command
  1276. *
  1277. * @return none
  1278. */
  1279. static void esp_PublishPriceCB( zclCCPublishPrice_t *pCmd,
  1280. afAddrType_t *srcAddr, uint8 seqNum )
  1281. {
  1282. // add user code here
  1283. }
  1284. /*********************************************************************
  1285. * @fn esp_PublishBlockPeriodCB
  1286. *
  1287. * @brief Callback from the ZCL SE Profile Pricing Cluster Library when
  1288. * it received a Publish Block Period for this application.
  1289. *
  1290. * @param pCmd - pointer to structure for Get Block Period command
  1291. * @param srcAddr - pointer to source address
  1292. * @param seqNum - sequence number for this command
  1293. *
  1294. * @return none
  1295. */
  1296. static void esp_PublishBlockPeriodCB( zclCCPublishBlockPeriod_t *pCmd,
  1297. afAddrType_t *srcAddr, uint8 seqNum )
  1298. {
  1299. // add user code here
  1300. }
  1301. /*********************************************************************
  1302. * @fn esp_DisplayMessageCB
  1303. *
  1304. * @brief Callback from the ZCL SE Profile Message Cluster Library when
  1305. * it received a Display Message Command for
  1306. * this application.
  1307. *
  1308. * @param pCmd - pointer to structure for Display Message command
  1309. * @param srcAddr - pointer to source address
  1310. * @param seqNum - sequence number for this command
  1311. *
  1312. * @return none
  1313. */
  1314. static void esp_DisplayMessageCB( zclCCDisplayMessage_t *pCmd,
  1315. afAddrType_t *srcAddr, uint8 seqNum )
  1316. {
  1317. // Upon receipt of the Display Message Command, the device shall
  1318. // display the message. If the Message Confirmation bit indicates
  1319. // the message originator require a confirmation of receipt from
  1320. // a Utility Customer, the device should display the message or
  1321. // alert the user until it is either confirmed via a button or by
  1322. // selecting a confirmation option on the device. Confirmation is
  1323. // typically used when the Utility is sending down information
  1324. // such as a disconnection notice, or prepaid billing information.
  1325. // Message duration is ignored when confirmation is requested and
  1326. // the message is displayed until confirmed.
  1327. #if defined ( LCD_SUPPORTED )
  1328. HalLcdWriteString( (char*)pCmd->msgString.pStr, HAL_LCD_LINE_1 );
  1329. #endif // LCD_SUPPORTED
  1330. }
  1331. /*********************************************************************
  1332. * @fn esp_CancelMessageCB
  1333. *
  1334. * @brief Callback from the ZCL SE Profile Message Cluster Library when
  1335. * it received a Cancel Message Command for
  1336. * this application.
  1337. *
  1338. * @param pCmd - pointer to structure for Cancel Message command
  1339. * @param srcAddr - pointer to source address
  1340. * @param seqNum - sequence number for this command
  1341. *
  1342. * @return none
  1343. */
  1344. static void esp_CancelMessageCB( zclCCCancelMessage_t *pCmd,
  1345. afAddrType_t *srcAddr, uint8 seqNum )
  1346. {
  1347. // add user code here
  1348. }
  1349. /*********************************************************************
  1350. * @fn esp_GetLastMessageCB
  1351. *
  1352. * @brief Callback from the ZCL SE Profile Message Cluster Library when
  1353. * it received a Get Last Message Command for
  1354. * this application.
  1355. *
  1356. * @param pCmd - pointer to structure for Get Last Message command
  1357. * @param srcAddr - pointer to source address
  1358. * @param seqNum - sequence number for this command
  1359. *
  1360. * @return none
  1361. */
  1362. static void esp_GetLastMessageCB( afAddrType_t *srcAddr, uint8 seqNum )
  1363. {
  1364. // On receipt of Get Last Message command, the device shall send a
  1365. // Display Message command back to the sender
  1366. #if defined ( ZCL_MESSAGE )
  1367. zclCCDisplayMessage_t cmd;
  1368. uint8 msg[10] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29 };
  1369. // Fill in the command with information for the last message
  1370. cmd.messageId = 0xaabbccdd;
  1371. cmd.messageCtrl.transmissionMode = 0;
  1372. cmd.messageCtrl.importance = 1;
  1373. cmd.messageCtrl.confirmationRequired = 1;
  1374. cmd.durationInMinutes = 60;
  1375. cmd.msgString.strLen = 10;
  1376. cmd.msgString.pStr = msg;
  1377. zclSE_Message_Send_DisplayMessage( ESP_ENDPOINT, srcAddr, &cmd,
  1378. FALSE, seqNum );
  1379. #endif // ZCL_MESSAGe
  1380. }
  1381. /*********************************************************************
  1382. * @fn esp_MessageConfirmationCB
  1383. *
  1384. * @brief Callback from the ZCL SE Profile Message Cluster Library when
  1385. * it received a Message Confirmation Command for
  1386. * this application.
  1387. *
  1388. * @param pCmd - pointer to structure for Message Confirmation command
  1389. * @param srcAddr - pointer to source address
  1390. * @param seqNum - sequence number for this command
  1391. *
  1392. * @return none
  1393. */
  1394. static void esp_MessageConfirmationCB( zclCCMessageConfirmation_t *pCmd,
  1395. afAddrType_t *srcAddr, uint8 seqNum)
  1396. {
  1397. // add user code here
  1398. }
  1399. #if defined (ZCL_LOAD_CONTROL)
  1400. /*********************************************************************
  1401. * @fn esp_SendReportEventStatus
  1402. *
  1403. * @brief Callback from the ZCL SE Profile Message Cluster Library when
  1404. * it received a Load Control Event Command for
  1405. * this application.
  1406. *
  1407. * @param afAddrType_t *srcAddr - pointer to source address
  1408. * @param uint8 seqNum - sequence number for this event
  1409. * @param uint32 eventID - event ID for this event
  1410. * @param uint32 startTime - start time for this event
  1411. * @param uint8 eventStatus - status for this event
  1412. * @param uint8 criticalityLevel - criticality level for this event
  1413. * @param uint8 eventControl - event control for this event
  1414. *
  1415. * @return none
  1416. */
  1417. static void esp_SendReportEventStatus( afAddrType_t *srcAddr, uint8 seqNum,
  1418. uint32 eventID, uint32 startTime,
  1419. uint8 eventStatus, uint8 criticalityLevel,
  1420. uint8 eventControl )
  1421. {
  1422. zclCCReportEventStatus_t *pRsp;
  1423. pRsp = (zclCCReportEventStatus_t *)osal_mem_alloc( sizeof( zclCCReportEventStatus_t ) );
  1424. if ( pRsp != NULL)
  1425. {
  1426. // Mandatory fields - use the incoming data
  1427. pRsp->issuerEventID = eventID;
  1428. pRsp->eventStartTime = startTime;
  1429. pRsp->criticalityLevelApplied = criticalityLevel;
  1430. pRsp->eventControl = eventControl;
  1431. pRsp->eventStatus = eventStatus;
  1432. pRsp->signatureType = SE_PROFILE_SIGNATURE_TYPE_ECDSA;
  1433. // esp_Signature is a static array.
  1434. // value can be changed in esp_data.c
  1435. osal_memcpy( pRsp->signature, espSignature, 16 );
  1436. // Optional fields - fill in with non-used value by default
  1437. pRsp->coolingTemperatureSetPointApplied = SE_OPTIONAL_FIELD_TEMPERATURE_SET_POINT;
  1438. pRsp->heatingTemperatureSetPointApplied = SE_OPTIONAL_FIELD_TEMPERATURE_SET_POINT;
  1439. pRsp->averageLoadAdjustment = SE_OPTIONAL_FIELD_INT8;
  1440. pRsp->dutyCycleApplied = SE_OPTIONAL_FIELD_UINT8;
  1441. // Send response back
  1442. // DisableDefaultResponse is set to FALSE - it is recommended to turn on
  1443. // default response since Report Event Status Command does not have
  1444. // a response.
  1445. zclSE_LoadControl_Send_ReportEventStatus( ESP_ENDPOINT, srcAddr,
  1446. pRsp, FALSE, seqNum );
  1447. osal_mem_free( pRsp );
  1448. }
  1449. }
  1450. #endif // ZCL_LOAD_CONTROL
  1451. /*********************************************************************
  1452. * @fn esp_LoadControlEventCB
  1453. *
  1454. * @brief Callback from the ZCL SE Profile Load Control Cluster Library when
  1455. * it received a Load Control Event Command for
  1456. * this application.
  1457. *
  1458. * @param pCmd - pointer to load control event command
  1459. * @param srcAddr - pointer to source address
  1460. * @param status - event status
  1461. * @param seqNum - sequence number of this command
  1462. *
  1463. * @return none
  1464. */
  1465. static void esp_LoadControlEventCB( zclCCLoadControlEvent_t *pCmd,
  1466. afAddrType_t *srcAddr, uint8 status,
  1467. uint8 seqNum)
  1468. {
  1469. #if defined ( ZCL_LOAD_CONTROL )
  1470. // According to the Smart Metering Specification, upon receipt
  1471. // of the Load Control Event command, the receiving device shall
  1472. // send Report Event Status command back.
  1473. uint8 eventStatus;
  1474. if ( status == ZCL_STATUS_INVALID_FIELD )
  1475. {
  1476. // If the incoming message has invalid fields in it
  1477. // Send response back with status: rejected
  1478. eventStatus = EVENT_STATUS_LOAD_CONTROL_EVENT_REJECTED;
  1479. }
  1480. else
  1481. { // Send response back with status: received
  1482. eventStatus = EVENT_STATUS_LOAD_CONTROL_EVENT_RECEIVED;
  1483. }
  1484. // Send response back
  1485. esp_SendReportEventStatus( srcAddr, seqNum, pCmd->issuerEvent,
  1486. pCmd->startTime, eventStatus,
  1487. pCmd->criticalityLevel, pCmd->eventControl);
  1488. if ( status != ZCL_STATUS_INVALID_FIELD )
  1489. {
  1490. // add user load control event handler here
  1491. }
  1492. #endif // ZCL_LOAD_CONTROL
  1493. }
  1494. /*********************************************************************
  1495. * @fn esp_CancelLoadControlEventCB
  1496. *
  1497. * @brief Callback from the ZCL SE Profile Load Control Cluster Library when
  1498. * it received a Cancel Load Control Event Command for
  1499. * this application.
  1500. *
  1501. * @param pCmd - pointer to structure for Cancel Load Control Event command
  1502. * @param scrAddr - source address
  1503. * @param seqNum - sequence number for this command
  1504. *
  1505. * @return none
  1506. */
  1507. static void esp_CancelLoadControlEventCB( zclCCCancelLoadControlEvent_t *pCmd,
  1508. afAddrType_t *srcAddr, uint8 seqNum )
  1509. {
  1510. #if defined ( ZCL_LOAD_CONTROL )
  1511. if ( 0 ) // User shall replace the if condition with "if the event exist"
  1512. {
  1513. // If the event exist, stop the event, and respond with status: cancelled
  1514. // Cancel the event here
  1515. // Use the following sample code to send response back.
  1516. /*
  1517. esp_SendReportEventStatus( srcAddr, seqNum, pCmd->issuerEventID,
  1518. // startTime
  1519. EVENT_STATUS_LOAD_CONTROL_EVENT_CANCELLED, // eventStatus
  1520. // Criticality level
  1521. // eventControl };
  1522. */
  1523. }
  1524. else
  1525. {
  1526. // If the event does not exist, respond with status: rejected
  1527. // The rest of the mandatory fields are not available, therefore,
  1528. // set to optional value
  1529. esp_SendReportEventStatus( srcAddr, seqNum, pCmd->issuerEventID,
  1530. SE_OPTIONAL_FIELD_UINT32, // startTime
  1531. EVENT_STATUS_LOAD_CONTROL_EVENT_RECEIVED, // eventStatus
  1532. SE_OPTIONAL_FIELD_UINT8, // Criticality level
  1533. SE_OPTIONAL_FIELD_UINT8 ); // eventControl
  1534. }
  1535. #endif // ZCL_LOAD_CONTROL
  1536. }
  1537. /*********************************************************************
  1538. * @fn esp_CancelAllLoadControlEventsCB
  1539. *
  1540. * @brief Callback from the ZCL SE Profile Load Control Cluster Library when
  1541. * it received a Cancel All Load Control Event Command for
  1542. * this application.
  1543. *
  1544. * @param pCmd - pointer to structure for Cancel All Load Control Event command
  1545. * @param scrAddr - source address
  1546. * @param seqNum - sequence number for this command
  1547. *
  1548. * @return none
  1549. */
  1550. static void esp_CancelAllLoadControlEventsCB( zclCCCancelAllLoadControlEvents_t *pCmd,
  1551. afAddrType_t *srcAddr, uint8 seqNum )
  1552. {
  1553. // Upon receipt of Cancel All Load Control Event Command,
  1554. // the receiving device shall look up the table for all events
  1555. // and send a seperate response for each event
  1556. }
  1557. /*********************************************************************
  1558. * @fn esp_ReportEventStatusCB
  1559. *
  1560. * @brief Callback from the ZCL SE Profile Load Control Cluster Library when
  1561. * it received a Report Event Status Command for
  1562. * this application.
  1563. *
  1564. * @param pCmd - pointer to structure for Report Event Status command
  1565. * @param scrAddr - source address
  1566. * @param seqNum - sequence number for this command
  1567. *
  1568. * @return none
  1569. */
  1570. static void esp_ReportEventStatusCB( zclCCReportEventStatus_t *pCmd,
  1571. afAddrType_t *srcAddr, uint8 seqNum)
  1572. {
  1573. // add user code here
  1574. }
  1575. /*********************************************************************
  1576. * @fn esp_GetScheduledEventCB
  1577. *
  1578. * @brief Callback from the ZCL SE Profile Load Control Cluster Library when
  1579. * it received a Get Scheduled Event Command for
  1580. * this application.
  1581. *
  1582. * @param pCmd - pointer to structure for Get Scheduled Event command
  1583. * @param scrAddr - source address
  1584. * @param seqNum - sequence number for this command
  1585. *
  1586. * @return none
  1587. */
  1588. static void esp_GetScheduledEventCB( zclCCGetScheduledEvent_t *pCmd,
  1589. afAddrType_t *srcAddr, uint8 seqNum )
  1590. {
  1591. // add user code here
  1592. }
  1593. /*********************************************************************
  1594. * @fn esp_SelAvailEmergencyCreditCmdCB
  1595. *
  1596. * @brief Callback from the ZCL SE Prepayment Cluster Library when it recieved
  1597. * Select Available Emergency Credit command in the application
  1598. *
  1599. * @param pCmd - pointer to structure for Select Available Emergency Credit command
  1600. * @param srcAddr - pointer to source address
  1601. * @param seqNum - Sequence no of the message
  1602. *
  1603. * @return none
  1604. */
  1605. static void esp_SelAvailEmergencyCreditCmdCB( zclCCSelAvailEmergencyCredit_t *pCmd,
  1606. afAddrType_t *srcAddr, uint8 seqNum )
  1607. {
  1608. #if defined ( ZCL_PREPAYMENT )
  1609. #if defined ( LCD_SUPPORTED )
  1610. HalLcdWriteString("Emergency Credit", HAL_LCD_LINE_1);
  1611. if ((pCmd->siteId.strLen > 0) &&
  1612. (pCmd->siteId.strLen <= HAL_LCD_MAX_CHARS) &&
  1613. (pCmd->siteId.pStr != NULL))
  1614. {
  1615. HalLcdWriteString((char*)pCmd->siteId.pStr, HAL_LCD_LINE_2);
  1616. }
  1617. if ((pCmd->meterSerialNumber.strLen > 0) &&
  1618. (pCmd->meterSerialNumber.strLen <= HAL_LCD_MAX_CHARS) &&
  1619. (pCmd->meterSerialNumber.pStr != NULL))
  1620. {
  1621. HalLcdWriteString((char*)pCmd->meterSerialNumber.pStr, HAL_LCD_LINE_3);
  1622. }
  1623. #endif
  1624. #endif // ZCL_PREPAYMENT
  1625. }
  1626. /*********************************************************************
  1627. * @fn esp_ChangeSupplyCmdCB
  1628. *
  1629. * @brief Callback from the ZCL SE Prepayment Cluster Library when it recieved
  1630. * Change Supply command in the application
  1631. *
  1632. * @param pCmd - pointer to structure for Change Supply command
  1633. * @param srcAddr - pointer to source address
  1634. * @param seqNum - Sequence no of the message
  1635. *
  1636. * @return none
  1637. */
  1638. static void esp_ChangeSupplyCmdCB( zclCCChangeSupply_t *pCmd,
  1639. afAddrType_t *srcAddr, uint8 seqNum )
  1640. {
  1641. #if defined ( ZCL_PREPAYMENT )
  1642. #if !defined ( SE_UK_EXT )
  1643. zclCCSupplyStatusResponse_t SupplyStatus_cmd;
  1644. osal_memset( &SupplyStatus_cmd, 0, sizeof( zclCCSupplyStatusResponse_t ) );
  1645. SupplyStatus_cmd.providerId = pCmd->providerId;
  1646. SupplyStatus_cmd.implementationDateTime = osal_getClock();
  1647. SupplyStatus_cmd.supplyStatus = pCmd->proposedSupplyStatus;
  1648. zclSE_Prepayment_Send_SupplyStatusResponse( ESP_ENDPOINT, srcAddr, &SupplyStatus_cmd,
  1649. FALSE, seqNum );
  1650. #endif // SE_UK_EXT
  1651. #endif // ZCL_PREPAYMENT
  1652. }
  1653. /*********************************************************************
  1654. * @fn esp_SupplyStatusRspCB
  1655. *
  1656. * @brief Callback from the ZCL SE Prepayment Cluster Library when it recieved
  1657. * Supply Status Response command in the application
  1658. *
  1659. * @param pCmd - pointer to structure for Supply Status Response command
  1660. * @param srcAddr - pointer to source address
  1661. * @param seqNum - Sequence no of the message
  1662. *
  1663. * @return none
  1664. */
  1665. static void esp_SupplyStatusRspCB( zclCCSupplyStatusResponse_t *pCmd,
  1666. afAddrType_t *srcAddr, uint8 seqNum )
  1667. {
  1668. // add user code here
  1669. }
  1670. #if defined ( SE_UK_EXT )
  1671. /*********************************************************************
  1672. * @fn esp_GetSnapshotRspCB
  1673. *
  1674. * @brief Callback from the ZCL SE Profile Simple Metering Cluster Library when
  1675. * it received a Get Snapshot Response for
  1676. * this application.
  1677. *
  1678. * @param pCmd - pointer to structure for Get Snapshot Response command
  1679. * @param srcAddr - pointer to source address
  1680. * @param seqNum - sequence number of this command
  1681. *
  1682. * @return none
  1683. */
  1684. static void esp_GetSnapshotRspCB( zclCCReqGetSnapshotRsp_t *pCmd,
  1685. afAddrType_t *srcAddr, uint8 seqNum )
  1686. {
  1687. // add user code here
  1688. }
  1689. /*********************************************************************
  1690. * @fn esp_PublishTariffInformationCB
  1691. *
  1692. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1693. * it received a Publish Tariff Information for this application.
  1694. *
  1695. * @param pCmd - pointer to structure for Publish Tariff Information command
  1696. * @param srcAddr - pointer to source address
  1697. * @param seqNum - sequence number of this command
  1698. *
  1699. * @return none
  1700. */
  1701. static void esp_PublishTariffInformationCB( zclCCPublishTariffInformation_t *pCmd,
  1702. afAddrType_t *srcAddr, uint8 seqNum )
  1703. {
  1704. // add user code here
  1705. }
  1706. /*********************************************************************
  1707. * @fn esp_PublishPriceMatrixCB
  1708. *
  1709. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1710. * it received a Publish Price Matrix for this application.
  1711. *
  1712. * @param pCmd - pointer to structure for Publish Price Matrix command
  1713. * @param srcAddr - pointer to source address
  1714. * @param seqNum - sequence number of this command
  1715. *
  1716. * @return none
  1717. */
  1718. static void esp_PublishPriceMatrixCB( zclCCPublishPriceMatrix_t *pCmd,
  1719. afAddrType_t *srcAddr, uint8 seqNum )
  1720. {
  1721. // add user code here
  1722. }
  1723. /*********************************************************************
  1724. * @fn esp_PublishBlockThresholdsCB
  1725. *
  1726. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1727. * it received a Publish Block Thresholds for this application.
  1728. *
  1729. * @param pCmd - pointer to structure for Publish Block Thresholds command
  1730. * @param srcAddr - pointer to source address
  1731. * @param seqNum - sequence number of this command
  1732. *
  1733. * @return none
  1734. */
  1735. static void esp_PublishBlockThresholdsCB( zclCCPublishBlockThresholds_t *pCmd,
  1736. afAddrType_t *srcAddr, uint8 seqNum )
  1737. {
  1738. // add user code here
  1739. }
  1740. /*********************************************************************
  1741. * @fn esp_PublishConversionFactorCB
  1742. *
  1743. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1744. * it received a Publish Conversion Factor for this application.
  1745. *
  1746. * @param pCmd - pointer to structure for Publish Conversion Factor command
  1747. * @param srcAddr - pointer to source address
  1748. * @param seqNum - sequence number of this command
  1749. *
  1750. * @return none
  1751. */
  1752. static void esp_PublishConversionFactorCB( zclCCPublishConversionFactor_t *pCmd,
  1753. afAddrType_t *srcAddr, uint8 seqNum )
  1754. {
  1755. // add user code here
  1756. }
  1757. /*********************************************************************
  1758. * @fn esp_PublishCalorificValueCB
  1759. *
  1760. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1761. * it received a Publish Calorific Value for this application.
  1762. *
  1763. * @param pCmd - pointer to structure for Publish Calorific Value command
  1764. * @param srcAddr - pointer to source address
  1765. * @param seqNum - sequence number of this command
  1766. *
  1767. * @return none
  1768. */
  1769. static void esp_PublishCalorificValueCB( zclCCPublishCalorificValue_t *pCmd,
  1770. afAddrType_t *srcAddr, uint8 seqNum )
  1771. {
  1772. // add user code here
  1773. }
  1774. /*********************************************************************
  1775. * @fn esp_PublishCO2ValueCB
  1776. *
  1777. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1778. * it received a Publish CO2 Value for this application.
  1779. *
  1780. * @param pCmd - pointer to structure for Publish CO2 Value command
  1781. * @param srcAddr - pointer to source address
  1782. * @param seqNum - sequence number of this command
  1783. *
  1784. * @return none
  1785. */
  1786. static void esp_PublishCO2ValueCB( zclCCPublishCO2Value_t *pCmd,
  1787. afAddrType_t *srcAddr, uint8 seqNum )
  1788. {
  1789. // add user code here
  1790. }
  1791. /*********************************************************************
  1792. * @fn esp_PublishCPPEventCB
  1793. *
  1794. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1795. * it received a Publish CPP Event for this application.
  1796. *
  1797. * @param pCmd - pointer to structure for Publish CPP Event command
  1798. * @param srcAddr - pointer to source address
  1799. * @param seqNum - sequence number of this command
  1800. *
  1801. * @return none
  1802. */
  1803. static void esp_PublishCPPEventCB( zclCCPublishCPPEvent_t *pCmd,
  1804. afAddrType_t *srcAddr, uint8 seqNum )
  1805. {
  1806. // add user code here
  1807. }
  1808. /*********************************************************************
  1809. * @fn esp_PublishBillingPeriodCB
  1810. *
  1811. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1812. * it received a Publish Billing Period for this application.
  1813. *
  1814. * @param pCmd - pointer to structure for Publish Billing Period command
  1815. * @param srcAddr - pointer to source address
  1816. * @param seqNum - sequence number of this command
  1817. *
  1818. * @return none
  1819. */
  1820. static void esp_PublishBillingPeriodCB( zclCCPublishBillingPeriod_t *pCmd,
  1821. afAddrType_t *srcAddr, uint8 seqNum )
  1822. {
  1823. // add user code here
  1824. }
  1825. /*********************************************************************
  1826. * @fn esp_PublishConsolidatedBillCB
  1827. *
  1828. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1829. * it received a Publish Consolidated Bill for this application.
  1830. *
  1831. * @param pCmd - pointer to structure for Publish Consolidated Bill command
  1832. * @param srcAddr - pointer to source address
  1833. * @param seqNum - sequence number of this command
  1834. *
  1835. * @return none
  1836. */
  1837. static void esp_PublishConsolidatedBillCB( zclCCPublishConsolidatedBill_t *pCmd,
  1838. afAddrType_t *srcAddr, uint8 seqNum )
  1839. {
  1840. // add user code here
  1841. }
  1842. /*********************************************************************
  1843. * @fn esp_PublishCreditPaymentInfoCB
  1844. *
  1845. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1846. * it received a Publish Credit Payment Info for this application.
  1847. *
  1848. * @param pCmd - pointer to structure for Publish Credit Payment Info command
  1849. * @param srcAddr - pointer to source address
  1850. * @param seqNum - sequence number of this command
  1851. *
  1852. * @return none
  1853. */
  1854. static void esp_PublishCreditPaymentInfoCB( zclCCPublishCreditPaymentInfo_t *pCmd,
  1855. afAddrType_t *srcAddr, uint8 seqNum )
  1856. {
  1857. // add user code here
  1858. }
  1859. /*********************************************************************
  1860. * @fn esp_GetTariffInformationCB
  1861. *
  1862. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1863. * it received a Get Tariff Information for this application.
  1864. *
  1865. * @param pCmd - pointer to structure for Get Tariff Information command
  1866. * @param srcAddr - pointer to source address
  1867. * @param seqNum - sequence number of this command
  1868. *
  1869. * @return none
  1870. */
  1871. static void esp_GetTariffInformationCB( zclCCGetTariffInformation_t *pCmd,
  1872. afAddrType_t *srcAddr, uint8 seqNum )
  1873. {
  1874. // add user code here
  1875. }
  1876. /*********************************************************************
  1877. * @fn esp_GetPriceMatrixCB
  1878. *
  1879. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1880. * it received a Get Price Matrix for this application.
  1881. *
  1882. * @param issuerTariffId - issuer tariff Id
  1883. * @param srcAddr - pointer to source address
  1884. * @param seqNum - sequence number of this command
  1885. *
  1886. * @return none
  1887. */
  1888. static void esp_GetPriceMatrixCB( uint32 issuerTariffId,
  1889. afAddrType_t *srcAddr, uint8 seqNum )
  1890. {
  1891. // add user code here
  1892. }
  1893. /*********************************************************************
  1894. * @fn esp_GetBlockThresholdsCB
  1895. *
  1896. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1897. * it received a Get Block Thresholds for this application.
  1898. *
  1899. * @param issuerTariffId - issuer tariff Id
  1900. * @param srcAddr - pointer to source address
  1901. * @param seqNum - sequence number of this command
  1902. *
  1903. * @return none
  1904. */
  1905. static void esp_GetBlockThresholdsCB( uint32 issuerTariffId,
  1906. afAddrType_t *srcAddr, uint8 seqNum )
  1907. {
  1908. // add user code here
  1909. }
  1910. /*********************************************************************
  1911. * @fn esp_GetConversionFactorCB
  1912. *
  1913. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1914. * it received a Get Conversion Factor for this application.
  1915. *
  1916. * @param pCmd - pointer to structure for Get Conversion Factor command
  1917. * @param srcAddr - pointer to source address
  1918. * @param seqNum - sequence number of this command
  1919. *
  1920. * @return none
  1921. */
  1922. static void esp_GetConversionFactorCB( zclCCGetConversionFactor_t *pCmd,
  1923. afAddrType_t *srcAddr, uint8 seqNum )
  1924. {
  1925. // add user code here
  1926. }
  1927. /*********************************************************************
  1928. * @fn esp_GetCalorificValueCB
  1929. *
  1930. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1931. * it received a Get Calorific Value for this application.
  1932. *
  1933. * @param pCmd - pointer to structure for Get Calorific Value command
  1934. * @param srcAddr - pointer to source address
  1935. * @param seqNum - sequence number of this command
  1936. *
  1937. * @return none
  1938. */
  1939. static void esp_GetCalorificValueCB( zclCCGetCalorificValue_t *pCmd,
  1940. afAddrType_t *srcAddr, uint8 seqNum )
  1941. {
  1942. // add user code here
  1943. }
  1944. /*********************************************************************
  1945. * @fn esp_GetCO2ValueCB
  1946. *
  1947. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1948. * it received a Get CO2 Value for this application.
  1949. *
  1950. * @param pCmd - pointer to structure for Get CO2 Value command
  1951. * @param srcAddr - pointer to source address
  1952. * @param seqNum - sequence number of this command
  1953. *
  1954. * @return none
  1955. */
  1956. static void esp_GetCO2ValueCB( zclCCGetCO2Value_t *pCmd,
  1957. afAddrType_t *srcAddr, uint8 seqNum )
  1958. {
  1959. // add user code here
  1960. }
  1961. /*********************************************************************
  1962. * @fn esp_GetBillingPeriodCB
  1963. *
  1964. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1965. * it received a Get Billing Period for this application.
  1966. *
  1967. * @param pCmd - pointer to structure for Get Billing Period command
  1968. * @param srcAddr - pointer to source address
  1969. * @param seqNum - sequence number of this command
  1970. *
  1971. * @return none
  1972. */
  1973. static void esp_GetBillingPeriodCB( zclCCGetBillingPeriod_t *pCmd,
  1974. afAddrType_t *srcAddr, uint8 seqNum )
  1975. {
  1976. // add user code here
  1977. }
  1978. /*********************************************************************
  1979. * @fn esp_GetConsolidatedBillCB
  1980. *
  1981. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1982. * it received a Get Consolidated Bill for this application.
  1983. *
  1984. * @param pCmd - pointer to structure for Get Consolidated Bill command
  1985. * @param srcAddr - pointer to source address
  1986. * @param seqNum - sequence number of this command
  1987. *
  1988. * @return none
  1989. */
  1990. static void esp_GetConsolidatedBillCB( zclCCGetConsolidatedBill_t *pCmd,
  1991. afAddrType_t *srcAddr, uint8 seqNum )
  1992. {
  1993. // add user code here
  1994. }
  1995. /*********************************************************************
  1996. * @fn esp_CPPEventResponseCB
  1997. *
  1998. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1999. * it received a CPP Event Response for this application.
  2000. *
  2001. * @param pCmd - pointer to structure for CPP Event Response command
  2002. * @param srcAddr - pointer to source address
  2003. * @param seqNum - sequence number of this command
  2004. *
  2005. * @return none
  2006. */
  2007. static void esp_CPPEventResponseCB( zclCCCPPEventResponse_t *pCmd,
  2008. afAddrType_t *srcAddr, uint8 seqNum )
  2009. {
  2010. // add user code here
  2011. }
  2012. /*********************************************************************
  2013. * @fn esp_ChangeDebtCB
  2014. *
  2015. * @brief Callback from the ZCL SE Profile Prepayment Cluster Library when
  2016. * it received a Change Debt for this application.
  2017. *
  2018. * @param pCmd - pointer to structure for Change Debt command
  2019. * @param srcAddr - pointer to source address
  2020. * @param seqNum - sequence number of this command
  2021. *
  2022. * @return none
  2023. */
  2024. static void esp_ChangeDebtCB( zclCCChangeDebt_t *pCmd,
  2025. afAddrType_t *srcAddr, uint8 seqNum )
  2026. {
  2027. // add user code here
  2028. }
  2029. /*********************************************************************
  2030. * @fn esp_EmergencyCreditSetupCB
  2031. *
  2032. * @brief Callback from the ZCL SE Profile Prepayment Cluster Library when
  2033. * it received a Emergency Credit Setup for this application.
  2034. *
  2035. * @param pCmd - pointer to structure for Emergency Credit Setup command
  2036. * @param srcAddr - pointer to source address
  2037. * @param seqNum - sequence number of this command
  2038. *
  2039. * @return none
  2040. */
  2041. static void esp_EmergencyCreditSetupCB( zclCCEmergencyCreditSetup_t *pCmd,
  2042. afAddrType_t *srcAddr, uint8 seqNum )
  2043. {
  2044. // add user code here
  2045. }
  2046. /*********************************************************************
  2047. * @fn esp_ConsumerTopupCB
  2048. *
  2049. * @brief Callback from the ZCL SE Profile Prepayment Cluster Library when
  2050. * it received a Consumer Topup for this application.
  2051. *
  2052. * @param pCmd - pointer to structure for Consumer Topup command
  2053. * @param srcAddr - pointer to source address
  2054. * @param seqNum - sequence number of this command
  2055. *
  2056. * @return none
  2057. */
  2058. static void esp_ConsumerTopupCB( zclCCConsumerTopup_t *pCmd,
  2059. afAddrType_t *srcAddr, uint8 seqNum )
  2060. {
  2061. // add user code here
  2062. }
  2063. /*********************************************************************
  2064. * @fn esp_CreditAdjustmentCB
  2065. *
  2066. * @brief Callback from the ZCL SE Profile Prepayment Cluster Library when
  2067. * it received a Credit Adjustment for this application.
  2068. *
  2069. * @param pCmd - pointer to structure for Credit Adjustment command
  2070. * @param srcAddr - pointer to source address
  2071. * @param seqNum - sequence number of this command
  2072. *
  2073. * @return none
  2074. */
  2075. static void esp_CreditAdjustmentCB( zclCCCreditAdjustment_t *pCmd,
  2076. afAddrType_t *srcAddr, uint8 seqNum )
  2077. {
  2078. // add user code here
  2079. }
  2080. /*********************************************************************
  2081. * @fn esp_ChangePaymentModeCB
  2082. *
  2083. * @brief Callback from the ZCL SE Profile Prepayment Cluster Library when
  2084. * it received a Change Payment Mode for this application.
  2085. *
  2086. * @param pCmd - pointer to structure for Change Payment Mode command
  2087. * @param srcAddr - pointer to source address
  2088. * @param seqNum - sequence number of this command
  2089. *
  2090. * @return none
  2091. */
  2092. static void esp_ChangePaymentModeCB( zclCCChangePaymentMode_t *pCmd,
  2093. afAddrType_t *srcAddr, uint8 seqNum )
  2094. {
  2095. // add user code here
  2096. }
  2097. /*********************************************************************
  2098. * @fn esp_GetPrepaySnapshotCB
  2099. *
  2100. * @brief Callback from the ZCL SE Profile Prepayment Cluster Library when
  2101. * it received a Get Prepay Snapshot for this application.
  2102. *
  2103. * @param pCmd - pointer to structure for Get Prepay Snapshot command
  2104. * @param srcAddr - pointer to source address
  2105. * @param seqNum - sequence number of this command
  2106. *
  2107. * @return none
  2108. */
  2109. static void esp_GetPrepaySnapshotCB( zclCCGetPrepaySnapshot_t *pCmd,
  2110. afAddrType_t *srcAddr, uint8 seqNum )
  2111. {
  2112. // add user code here
  2113. }
  2114. /*********************************************************************
  2115. * @fn esp_GetTopupLogCB
  2116. *
  2117. * @brief Callback from the ZCL SE Profile Prepayment Cluster Library when
  2118. * it received a Get Topup Log for this application.
  2119. *
  2120. * @param numEvents - number of events
  2121. * @param srcAddr - pointer to source address
  2122. * @param seqNum - sequence number of this command
  2123. *
  2124. * @return none
  2125. */
  2126. static void esp_GetTopupLogCB( uint8 numEvents,
  2127. afAddrType_t *srcAddr, uint8 seqNum )
  2128. {
  2129. // add user code here
  2130. }
  2131. /*********************************************************************
  2132. * @fn esp_SetLowCreditWarningLevelCB
  2133. *
  2134. * @brief Callback from the ZCL SE Profile Prepayment Cluster Library when
  2135. * it received a Set Low Credit Warning Level for this application.
  2136. *
  2137. * @param numEvents - number of events
  2138. * @param srcAddr - pointer to source address
  2139. * @param seqNum - sequence number of this command
  2140. *
  2141. * @return none
  2142. */
  2143. static void esp_SetLowCreditWarningLevelCB( uint8 numEvents,
  2144. afAddrType_t *srcAddr, uint8 seqNum )
  2145. {
  2146. // add user code here
  2147. }
  2148. /*********************************************************************
  2149. * @fn esp_GetDebtRepaymentLogCB
  2150. *
  2151. * @brief Callback from the ZCL SE Profile Prepayment Cluster Library when
  2152. * it received a Get Debt Repayment Log for this application.
  2153. *
  2154. * @param pCmd - pointer to structure for Get Debt Repayment Log command
  2155. * @param srcAddr - pointer to source address
  2156. * @param seqNum - sequence number of this command
  2157. *
  2158. * @return none
  2159. */
  2160. static void esp_GetDebtRepaymentLogCB( zclCCGetDebtRepaymentLog_t *pCmd,
  2161. afAddrType_t *srcAddr, uint8 seqNum )
  2162. {
  2163. // add user code here
  2164. }
  2165. /*********************************************************************
  2166. * @fn esp_GetPrepaySnapshotResponseCB
  2167. *
  2168. * @brief Callback from the ZCL SE Profile Prepayment Cluster Library when
  2169. * it received a Get Prepay Snapshot Response for this application.
  2170. *
  2171. * @param pCmd - pointer to structure for Get Prepay Snapshot Response command
  2172. * @param srcAddr - pointer to source address
  2173. * @param seqNum - sequence number of this command
  2174. *
  2175. * @return none
  2176. */
  2177. static void esp_GetPrepaySnapshotResponseCB( zclCCGetPrepaySnapshotResponse_t *pCmd,
  2178. afAddrType_t *srcAddr, uint8 seqNum )
  2179. {
  2180. // add user code here
  2181. }
  2182. /*********************************************************************
  2183. * @fn esp_ChangePaymentModeResponseCB
  2184. *
  2185. * @brief Callback from the ZCL SE Profile Prepayment Cluster Library when
  2186. * it received a Change Payment Mode Response for this application.
  2187. *
  2188. * @param pCmd - pointer to structure for Change Payment Mode Response command
  2189. * @param srcAddr - pointer to source address
  2190. * @param seqNum - sequence number of this command
  2191. *
  2192. * @return none
  2193. */
  2194. static void esp_ChangePaymentModeResponseCB( zclCCChangePaymentModeResponse_t *pCmd,
  2195. afAddrType_t *srcAddr, uint8 seqNum )
  2196. {
  2197. // add user code here
  2198. }
  2199. /*********************************************************************
  2200. * @fn esp_ConsumerTopupResponseCB
  2201. *
  2202. * @brief Callback from the ZCL SE Profile Prepayment Cluster Library when
  2203. * it received a Consumer Topup Response for this application.
  2204. *
  2205. * @param pCmd - pointer to structure for Consumer Topup Response command
  2206. * @param srcAddr - pointer to source address
  2207. * @param seqNum - sequence number of this command
  2208. *
  2209. * @return none
  2210. */
  2211. static void esp_ConsumerTopupResponseCB( zclCCConsumerTopupResponse_t *pCmd,
  2212. afAddrType_t *srcAddr, uint8 seqNum )
  2213. {
  2214. // add user code here
  2215. }
  2216. /*********************************************************************
  2217. * @fn esp_GetCommandsCB
  2218. *
  2219. * @brief Callback from the ZCL SE Profile Prepayment Cluster Library when
  2220. * it received a Get Commands for this application.
  2221. *
  2222. * @param prepayNotificationFlags - prepayment notification flags
  2223. * @param srcAddr - pointer to source address
  2224. * @param seqNum - sequence number of this command
  2225. *
  2226. * @return none
  2227. */
  2228. static void esp_GetCommandsCB( uint8 prepayNotificationFlags,
  2229. afAddrType_t *srcAddr, uint8 seqNum )
  2230. {
  2231. // add user code here
  2232. }
  2233. /*********************************************************************
  2234. * @fn esp_PublishTopupLogCB
  2235. *
  2236. * @brief Callback from the ZCL SE Profile Prepayment Cluster Library when
  2237. * it received a Publish Topup Log for this application.
  2238. *
  2239. * @param pCmd - pointer to structure for Publish Topup Log command
  2240. * @param srcAddr - pointer to source address
  2241. * @param seqNum - sequence number of this command
  2242. *
  2243. * @return none
  2244. */
  2245. static void esp_PublishTopupLogCB( zclCCPublishTopupLog_t *pCmd,
  2246. afAddrType_t *srcAddr, uint8 seqNum )
  2247. {
  2248. // add user code here
  2249. }
  2250. /*********************************************************************
  2251. * @fn esp_PublishDebtLogCB
  2252. *
  2253. * @brief Callback from the ZCL SE Profile Prepayment Cluster Library when
  2254. * it received a Publish Debt Log for this application.
  2255. *
  2256. * @param pCmd - pointer to structure for Publish Debt Log command
  2257. * @param srcAddr - pointer to source address
  2258. * @param seqNum - sequence number of this command
  2259. *
  2260. * @return none
  2261. */
  2262. static void esp_PublishDebtLogCB( zclCCPublishDebtLog_t *pCmd,
  2263. afAddrType_t *srcAddr, uint8 seqNum )
  2264. {
  2265. // add user code here
  2266. }
  2267. #endif // SE_UK_EXT
  2268. /******************************************************************************
  2269. *
  2270. * Functions for processing ZDO incoming messages
  2271. *
  2272. *****************************************************************************/
  2273. /*********************************************************************
  2274. * @fn esp_ProcessZDOMsg
  2275. *
  2276. * @brief Process the incoming ZDO messages.
  2277. *
  2278. * @param inMsg - message to process
  2279. *
  2280. * @return none
  2281. */
  2282. static void esp_ProcessZDOMsg( zdoIncomingMsg_t *inMsg )
  2283. {
  2284. ZDO_DeviceAnnce_t devAnnce;
  2285. switch ( inMsg->clusterID )
  2286. {
  2287. case Device_annce:
  2288. {
  2289. ZDO_ParseDeviceAnnce( inMsg, &devAnnce );
  2290. simpleDescReqAddr.addrMode = (afAddrMode_t)Addr16Bit;
  2291. simpleDescReqAddr.addr.shortAddr = devAnnce.nwkAddr;
  2292. // set simple descriptor query event
  2293. osal_set_event( espTaskID, SIMPLE_DESC_QUERY_EVT );
  2294. }
  2295. break;
  2296. case Simple_Desc_rsp:
  2297. {
  2298. ZDO_SimpleDescRsp_t *pSimpleDescRsp; // pointer to received simple desc response
  2299. pSimpleDescRsp = (ZDO_SimpleDescRsp_t *)osal_mem_alloc( sizeof( ZDO_SimpleDescRsp_t ) );
  2300. if(pSimpleDescRsp)
  2301. {
  2302. pSimpleDescRsp->simpleDesc.pAppInClusterList = NULL;
  2303. pSimpleDescRsp->simpleDesc.pAppOutClusterList = NULL;
  2304. ZDO_ParseSimpleDescRsp( inMsg, pSimpleDescRsp );
  2305. if( pSimpleDescRsp->simpleDesc.AppDeviceId == ZCL_SE_DEVICEID_PCT ) // this is a PCT
  2306. {
  2307. pctAddr.addr.shortAddr = pSimpleDescRsp->nwkAddr;
  2308. }
  2309. else if ( pSimpleDescRsp->simpleDesc.AppDeviceId == ZCL_SE_DEVICEID_LOAD_CTRL_EXTENSION ) // this is a load control device
  2310. {
  2311. loadControlAddr.addr.shortAddr = pSimpleDescRsp->nwkAddr;
  2312. }
  2313. // free memory for InClusterList
  2314. if (pSimpleDescRsp->simpleDesc.pAppInClusterList)
  2315. {
  2316. osal_mem_free(pSimpleDescRsp->simpleDesc.pAppInClusterList);
  2317. }
  2318. // free memory for OutClusterList
  2319. if (pSimpleDescRsp->simpleDesc.pAppOutClusterList)
  2320. {
  2321. osal_mem_free(pSimpleDescRsp->simpleDesc.pAppOutClusterList);
  2322. }
  2323. osal_mem_free( pSimpleDescRsp );
  2324. }
  2325. }
  2326. break;
  2327. }
  2328. }
  2329. /******************************************************************************
  2330. *
  2331. * Functions for processing ZCL Foundation incoming Command/Response messages
  2332. *
  2333. *****************************************************************************/
  2334. /*********************************************************************
  2335. * @fn esp_ProcessZCLMsg
  2336. *
  2337. * @brief Process ZCL Foundation incoming message
  2338. *
  2339. * @param pInMsg - message to process
  2340. *
  2341. * @return none
  2342. */
  2343. static void esp_ProcessZCLMsg( zclIncomingMsg_t *pInMsg )
  2344. {
  2345. #if defined ( SE_UK_EXT ) && defined ( SE_MIRROR )
  2346. if ( esp_IsMirrorEndpoint( pInMsg->endPoint ) )
  2347. {
  2348. esp_MirrorProcessZCLMsg( pInMsg );
  2349. }
  2350. else
  2351. #endif // SE_UK_EXT && SE_MIRROR
  2352. {
  2353. switch ( pInMsg->zclHdr.commandID )
  2354. {
  2355. #if defined ( ZCL_READ )
  2356. case ZCL_CMD_READ_RSP:
  2357. esp_ProcessInReadRspCmd( pInMsg );
  2358. break;
  2359. #endif // ZCL_READ
  2360. #if defined ( ZCL_WRITE )
  2361. case ZCL_CMD_WRITE_RSP:
  2362. esp_ProcessInWriteRspCmd( pInMsg );
  2363. break;
  2364. #endif // ZCL_WRITE
  2365. #if defined ( ZCL_REPORT )
  2366. case ZCL_CMD_CONFIG_REPORT:
  2367. esp_ProcessInConfigReportCmd( pInMsg );
  2368. break;
  2369. case ZCL_CMD_CONFIG_REPORT_RSP:
  2370. esp_ProcessInConfigReportRspCmd( pInMsg );
  2371. break;
  2372. case ZCL_CMD_READ_REPORT_CFG:
  2373. esp_ProcessInReadReportCfgCmd( pInMsg );
  2374. break;
  2375. case ZCL_CMD_READ_REPORT_CFG_RSP:
  2376. esp_ProcessInReadReportCfgRspCmd( pInMsg );
  2377. break;
  2378. case ZCL_CMD_REPORT:
  2379. esp_ProcessInReportCmd( pInMsg );
  2380. break;
  2381. #endif // ZCL_REPORT
  2382. case ZCL_CMD_DEFAULT_RSP:
  2383. esp_ProcessInDefaultRspCmd( pInMsg );
  2384. break;
  2385. #if defined ( ZCL_DISCOVER )
  2386. case ZCL_CMD_DISCOVER_RSP:
  2387. esp_ProcessInDiscRspCmd( pInMsg );
  2388. break;
  2389. #endif // ZCL_DISCOVER
  2390. default:
  2391. break;
  2392. }
  2393. }
  2394. if ( pInMsg->attrCmd != NULL )
  2395. {
  2396. // free the parsed command
  2397. osal_mem_free( pInMsg->attrCmd );
  2398. pInMsg->attrCmd = NULL;
  2399. }
  2400. }
  2401. #if defined ( ZCL_READ )
  2402. /*********************************************************************
  2403. * @fn esp_ProcessInReadRspCmd
  2404. *
  2405. * @brief Process the "Profile" Read Response Command
  2406. *
  2407. * @param pInMsg - incoming message to process
  2408. *
  2409. * @return none
  2410. */
  2411. static uint8 esp_ProcessInReadRspCmd( zclIncomingMsg_t *pInMsg )
  2412. {
  2413. zclReadRspCmd_t *readRspCmd;
  2414. uint8 i;
  2415. readRspCmd = (zclReadRspCmd_t *)pInMsg->attrCmd;
  2416. for (i = 0; i < readRspCmd->numAttr; i++)
  2417. {
  2418. // Notify the originator of the results of the original read attributes
  2419. // attempt and, for each successfull request, the value of the requested
  2420. // attribute
  2421. }
  2422. return TRUE;
  2423. }
  2424. #endif // ZCL_READ
  2425. #if defined ( ZCL_WRITE )
  2426. /*********************************************************************
  2427. * @fn esp_ProcessInWriteRspCmd
  2428. *
  2429. * @brief Process the "Profile" Write Response Command
  2430. *
  2431. * @param pInMsg - incoming message to process
  2432. *
  2433. * @return none
  2434. */
  2435. static uint8 esp_ProcessInWriteRspCmd( zclIncomingMsg_t *pInMsg )
  2436. {
  2437. zclWriteRspCmd_t *writeRspCmd;
  2438. uint8 i;
  2439. writeRspCmd = (zclWriteRspCmd_t *)pInMsg->attrCmd;
  2440. for (i = 0; i < writeRspCmd->numAttr; i++)
  2441. {
  2442. // Notify the device of the results of the its original write attributes
  2443. // command.
  2444. }
  2445. return TRUE;
  2446. }
  2447. #endif // ZCL_WRITE
  2448. #if defined ( ZCL_REPORT )
  2449. /*********************************************************************
  2450. * @fn esp_ProcessInConfigReportCmd
  2451. *
  2452. * @brief Process the "Profile" Configure Reporting Command
  2453. *
  2454. * @param pInMsg - incoming message to process
  2455. *
  2456. * @return TRUE if attribute was found in the Attribute list,
  2457. * FALSE if not
  2458. */
  2459. static uint8 esp_ProcessInConfigReportCmd( zclIncomingMsg_t *pInMsg )
  2460. {
  2461. zclCfgReportCmd_t *cfgReportCmd;
  2462. zclCfgReportRec_t *reportRec;
  2463. zclCfgReportRspCmd_t *cfgReportRspCmd;
  2464. zclAttrRec_t attrRec;
  2465. uint8 status;
  2466. uint8 i, j = 0;
  2467. cfgReportCmd = (zclCfgReportCmd_t *)pInMsg->attrCmd;
  2468. // Allocate space for the response command
  2469. cfgReportRspCmd = (zclCfgReportRspCmd_t *)osal_mem_alloc( sizeof ( zclCfgReportRspCmd_t ) +
  2470. sizeof ( zclCfgReportStatus_t) * cfgReportCmd->numAttr );
  2471. if ( cfgReportRspCmd == NULL )
  2472. {
  2473. return FALSE; // EMBEDDED RETURN
  2474. }
  2475. // Process each Attribute Reporting Configuration record
  2476. for ( i = 0; i < cfgReportCmd->numAttr; i++ )
  2477. {
  2478. reportRec = &(cfgReportCmd->attrList[i]);
  2479. status = ZCL_STATUS_SUCCESS;
  2480. if ( zclFindAttrRec( ESP_ENDPOINT, pInMsg->clusterId, reportRec->attrID, &attrRec ) )
  2481. {
  2482. if ( reportRec->direction == ZCL_SEND_ATTR_REPORTS )
  2483. {
  2484. if ( reportRec->dataType == attrRec.attr.dataType )
  2485. {
  2486. // This the attribute that is to be reported
  2487. if ( zcl_MandatoryReportableAttribute( &attrRec ) == TRUE )
  2488. {
  2489. if ( reportRec->minReportInt < ESP_MIN_REPORTING_INTERVAL ||
  2490. ( reportRec->maxReportInt != 0 &&
  2491. reportRec->maxReportInt < reportRec->minReportInt ) )
  2492. {
  2493. // Invalid fields
  2494. status = ZCL_STATUS_INVALID_VALUE;
  2495. }
  2496. else
  2497. {
  2498. // Set the Min and Max Reporting Intervals and Reportable Change
  2499. //status = zclSetAttrReportInterval( pAttr, cfgReportCmd );
  2500. status = ZCL_STATUS_UNREPORTABLE_ATTRIBUTE; // for now
  2501. }
  2502. }
  2503. else
  2504. {
  2505. // Attribute cannot be reported
  2506. status = ZCL_STATUS_UNREPORTABLE_ATTRIBUTE;
  2507. }
  2508. }
  2509. else
  2510. {
  2511. // Attribute data type is incorrect
  2512. status = ZCL_STATUS_INVALID_DATA_TYPE;
  2513. }
  2514. }
  2515. else
  2516. {
  2517. // We shall expect reports of values of this attribute
  2518. if ( zcl_MandatoryReportableAttribute( &attrRec ) == TRUE )
  2519. {
  2520. // Set the Timeout Period
  2521. //status = zclSetAttrTimeoutPeriod( pAttr, cfgReportCmd );
  2522. status = ZCL_STATUS_UNSUPPORTED_ATTRIBUTE; // for now
  2523. }
  2524. else
  2525. {
  2526. // Reports of attribute cannot be received
  2527. status = ZCL_STATUS_UNSUPPORTED_ATTRIBUTE;
  2528. }
  2529. }
  2530. }
  2531. else
  2532. {
  2533. // Attribute is not supported
  2534. status = ZCL_STATUS_UNSUPPORTED_ATTRIBUTE;
  2535. }
  2536. // If not successful then record the status
  2537. if ( status != ZCL_STATUS_SUCCESS )
  2538. {
  2539. cfgReportRspCmd->attrList[j].status = status;
  2540. cfgReportRspCmd->attrList[j++].attrID = reportRec->attrID;
  2541. }
  2542. } // for loop
  2543. if ( j == 0 )
  2544. {
  2545. // Since all attributes were configured successfully, include a single
  2546. // attribute status record in the response command with the status field
  2547. // set to SUCCESS and the attribute ID field omitted.
  2548. cfgReportRspCmd->attrList[0].status = ZCL_STATUS_SUCCESS;
  2549. cfgReportRspCmd->numAttr = 1;
  2550. }
  2551. else
  2552. {
  2553. cfgReportRspCmd->numAttr = j;
  2554. }
  2555. // Send the response back
  2556. zcl_SendConfigReportRspCmd( ESP_ENDPOINT, &(pInMsg->srcAddr),
  2557. pInMsg->clusterId, cfgReportRspCmd, ZCL_FRAME_SERVER_CLIENT_DIR,
  2558. TRUE, pInMsg->zclHdr.transSeqNum );
  2559. osal_mem_free( cfgReportRspCmd );
  2560. return TRUE ;
  2561. }
  2562. /*********************************************************************
  2563. * @fn esp_ProcessInConfigReportRspCmd
  2564. *
  2565. * @brief Process the "Profile" Configure Reporting Response Command
  2566. *
  2567. * @param pInMsg - incoming message to process
  2568. *
  2569. * @return none
  2570. */
  2571. static uint8 esp_ProcessInConfigReportRspCmd( zclIncomingMsg_t *pInMsg )
  2572. {
  2573. zclCfgReportRspCmd_t *cfgReportRspCmd;
  2574. zclAttrRec_t attrRec;
  2575. uint8 i;
  2576. cfgReportRspCmd = (zclCfgReportRspCmd_t *)pInMsg->attrCmd;
  2577. for (i = 0; i < cfgReportRspCmd->numAttr; i++)
  2578. {
  2579. if ( zclFindAttrRec( ESP_ENDPOINT, pInMsg->clusterId,
  2580. cfgReportRspCmd->attrList[i].attrID, &attrRec ) )
  2581. {
  2582. // Notify the device of success (or otherwise) of the its original configure
  2583. // reporting command, for each attribute.
  2584. }
  2585. }
  2586. return TRUE;
  2587. }
  2588. /*********************************************************************
  2589. * @fn esp_ProcessInReadReportCfgCmd
  2590. *
  2591. * @brief Process the "Profile" Read Reporting Configuration Command
  2592. *
  2593. * @param pInMsg - incoming message to process
  2594. *
  2595. * @return none
  2596. */
  2597. static uint8 esp_ProcessInReadReportCfgCmd( zclIncomingMsg_t *pInMsg )
  2598. {
  2599. zclReadReportCfgCmd_t *readReportCfgCmd;
  2600. zclReadReportCfgRspCmd_t *readReportCfgRspCmd;
  2601. zclReportCfgRspRec_t *reportRspRec;
  2602. zclAttrRec_t attrRec;
  2603. uint8 reportChangeLen;
  2604. uint8 *dataPtr;
  2605. uint8 hdrLen;
  2606. uint8 dataLen = 0;
  2607. uint8 status;
  2608. uint8 i;
  2609. readReportCfgCmd = (zclReadReportCfgCmd_t *)pInMsg->attrCmd;
  2610. // Find out the response length (Reportable Change field is of variable length)
  2611. for ( i = 0; i < readReportCfgCmd->numAttr; i++ )
  2612. {
  2613. // For supported attributes with 'analog' data type, find out the length of
  2614. // the Reportable Change field
  2615. if ( zclFindAttrRec( ESP_ENDPOINT, pInMsg->clusterId,
  2616. readReportCfgCmd->attrList[i].attrID, &attrRec ) )
  2617. {
  2618. if ( zclAnalogDataType( attrRec.attr.dataType ) )
  2619. {
  2620. reportChangeLen = zclGetDataTypeLength( attrRec.attr.dataType );
  2621. // add padding if neede
  2622. if ( PADDING_NEEDED( reportChangeLen ) )
  2623. {
  2624. reportChangeLen++;
  2625. }
  2626. dataLen += reportChangeLen;
  2627. }
  2628. }
  2629. }
  2630. hdrLen = sizeof( zclReadReportCfgRspCmd_t ) + ( readReportCfgCmd->numAttr * sizeof( zclReportCfgRspRec_t ) );
  2631. // Allocate space for the response command
  2632. readReportCfgRspCmd = (zclReadReportCfgRspCmd_t *)osal_mem_alloc( hdrLen + dataLen );
  2633. if ( readReportCfgRspCmd == NULL )
  2634. {
  2635. return FALSE; // EMBEDDED RETURN
  2636. }
  2637. dataPtr = (uint8 *)( (uint8 *)readReportCfgRspCmd + hdrLen );
  2638. readReportCfgRspCmd->numAttr = readReportCfgCmd->numAttr;
  2639. for (i = 0; i < readReportCfgCmd->numAttr; i++)
  2640. {
  2641. reportRspRec = &(readReportCfgRspCmd->attrList[i]);
  2642. if ( zclFindAttrRec( ESP_ENDPOINT, pInMsg->clusterId,
  2643. readReportCfgCmd->attrList[i].attrID, &attrRec ) )
  2644. {
  2645. if ( zcl_MandatoryReportableAttribute( &attrRec ) == TRUE )
  2646. {
  2647. // Get the Reporting Configuration
  2648. // status = zclReadReportCfg( readReportCfgCmd->attrID[i], reportRspRec );
  2649. status = ZCL_STATUS_UNREPORTABLE_ATTRIBUTE; // for now
  2650. if ( status == ZCL_STATUS_SUCCESS && zclAnalogDataType( attrRec.attr.dataType ) )
  2651. {
  2652. reportChangeLen = zclGetDataTypeLength( attrRec.attr.dataType );
  2653. //osal_memcpy( dataPtr, pBuf, reportChangeLen );
  2654. reportRspRec->reportableChange = dataPtr;
  2655. // add padding if needed
  2656. if ( PADDING_NEEDED( reportChangeLen ) )
  2657. {
  2658. reportChangeLen++;
  2659. }
  2660. dataPtr += reportChangeLen;
  2661. }
  2662. }
  2663. else
  2664. {
  2665. // Attribute not in the Mandatory Reportable Attribute list
  2666. status = ZCL_STATUS_UNREPORTABLE_ATTRIBUTE;
  2667. }
  2668. }
  2669. else
  2670. {
  2671. // Attribute not found
  2672. status = ZCL_STATUS_UNSUPPORTED_ATTRIBUTE;
  2673. }
  2674. reportRspRec->status = status;
  2675. reportRspRec->attrID = readReportCfgCmd->attrList[i].attrID;
  2676. }
  2677. // Send the response back
  2678. zcl_SendReadReportCfgRspCmd( ESP_ENDPOINT, &(pInMsg->srcAddr),
  2679. pInMsg->clusterId, readReportCfgRspCmd, ZCL_FRAME_SERVER_CLIENT_DIR,
  2680. TRUE, pInMsg->zclHdr.transSeqNum );
  2681. osal_mem_free( readReportCfgRspCmd );
  2682. return TRUE;
  2683. }
  2684. /*********************************************************************
  2685. * @fn esp_ProcessInReadReportCfgRspCmd
  2686. *
  2687. * @brief Process the "Profile" Read Reporting Configuration Response Command
  2688. *
  2689. * @param pInMsg - incoming message to process
  2690. *
  2691. * @return none
  2692. */
  2693. static uint8 esp_ProcessInReadReportCfgRspCmd( zclIncomingMsg_t *pInMsg )
  2694. {
  2695. zclReadReportCfgRspCmd_t *readReportCfgRspCmd;
  2696. zclReportCfgRspRec_t *reportRspRec;
  2697. uint8 i;
  2698. readReportCfgRspCmd = (zclReadReportCfgRspCmd_t *)pInMsg->attrCmd;
  2699. for ( i = 0; i < readReportCfgRspCmd->numAttr; i++ )
  2700. {
  2701. reportRspRec = &(readReportCfgRspCmd->attrList[i]);
  2702. // Notify the device of the results of the its original read reporting
  2703. // configuration command.
  2704. if ( reportRspRec->status == ZCL_STATUS_SUCCESS )
  2705. {
  2706. if ( reportRspRec->direction == ZCL_SEND_ATTR_REPORTS )
  2707. {
  2708. // add user code here
  2709. }
  2710. else
  2711. {
  2712. // expecting attribute reports
  2713. }
  2714. }
  2715. }
  2716. return TRUE;
  2717. }
  2718. /*********************************************************************
  2719. * @fn esp_ProcessInReportCmd
  2720. *
  2721. * @brief Process the "Profile" Report Command
  2722. *
  2723. * @param pInMsg - incoming message to process
  2724. *
  2725. * @return none
  2726. */
  2727. static uint8 esp_ProcessInReportCmd( zclIncomingMsg_t *pInMsg )
  2728. {
  2729. zclReportCmd_t *reportCmd;
  2730. zclReport_t *reportRec;
  2731. uint8 i;
  2732. uint8 *meterData;
  2733. char lcdBuf[13];
  2734. reportCmd = (zclReportCmd_t *)pInMsg->attrCmd;
  2735. for (i = 0; i < reportCmd->numAttr; i++)
  2736. {
  2737. // Device is notified of the latest values of the attribute of another device.
  2738. reportRec = &(reportCmd->attrList[i]);
  2739. if ( reportRec->attrID == ATTRID_SE_CURRENT_SUMMATION_DELIVERED )
  2740. {
  2741. // process simple metering current summation delivered attribute
  2742. meterData = reportRec->attrData;
  2743. // process to convert hex to ascii
  2744. for(i=0; i<6; i++)
  2745. {
  2746. if(meterData[5-i] == 0)
  2747. {
  2748. lcdBuf[i*2] = '0';
  2749. lcdBuf[i*2+1] = '0';
  2750. }
  2751. else if(meterData[5-i] <= 0x0A)
  2752. {
  2753. lcdBuf[i*2] = '0';
  2754. _ltoa(meterData[5-i],(uint8*)&lcdBuf[i*2+1],16);
  2755. }
  2756. else
  2757. {
  2758. _ltoa(meterData[5-i],(uint8*)&lcdBuf[i*2],16);
  2759. }
  2760. }
  2761. // print out value of current summation delivered in hex
  2762. HalLcdWriteString("Zigbee Coord esp", HAL_LCD_LINE_1);
  2763. HalLcdWriteString("Curr Summ Dlvd", HAL_LCD_LINE_2);
  2764. HalLcdWriteString(lcdBuf, HAL_LCD_LINE_3);
  2765. }
  2766. }
  2767. return TRUE;
  2768. }
  2769. #endif // ZCL_REPORT
  2770. /*********************************************************************
  2771. * @fn esp_ProcessInDefaultRspCmd
  2772. *
  2773. * @brief Process the "Profile" Default Response Command
  2774. *
  2775. * @param pInMsg - incoming message to process
  2776. *
  2777. * @return none
  2778. */
  2779. static uint8 esp_ProcessInDefaultRspCmd( zclIncomingMsg_t *pInMsg )
  2780. {
  2781. // zclDefaultRspCmd_t *defaultRspCmd = (zclDefaultRspCmd_t *)pInMsg->attrCmd;
  2782. // Device is notified of the Default Response command.
  2783. return TRUE;
  2784. }
  2785. #if defined ( ZCL_DISCOVER )
  2786. /*********************************************************************
  2787. * @fn esp_ProcessInDiscRspCmd
  2788. *
  2789. * @brief Process the "Profile" Discover Response Command
  2790. *
  2791. * @param pInMsg - incoming message to process
  2792. *
  2793. * @return none
  2794. */
  2795. static uint8 esp_ProcessInDiscRspCmd( zclIncomingMsg_t *pInMsg )
  2796. {
  2797. zclDiscoverRspCmd_t *discoverRspCmd;
  2798. uint8 i;
  2799. discoverRspCmd = (zclDiscoverRspCmd_t *)pInMsg->attrCmd;
  2800. for ( i = 0; i < discoverRspCmd->numAttr; i++ )
  2801. {
  2802. // Device is notified of the result of its attribute discovery command.
  2803. }
  2804. return TRUE;
  2805. }
  2806. #endif // ZCL_DISCOVER
  2807. #if defined ( SE_UK_EXT ) && defined ( SE_MIRROR )
  2808. /*********************************************************************
  2809. * @fn esp_MirrorInit
  2810. *
  2811. * @brief Initialize the ESP Mirror Subsystem.
  2812. *
  2813. * @param none
  2814. *
  2815. * @return none
  2816. */
  2817. static void esp_MirrorInit( void )
  2818. {
  2819. osal_memset( &esp_MirrorControl, 0, sizeof( esp_MirrorControl ) );
  2820. // set the attribute
  2821. espPhysicalEnvironment |= PHY_MIRROR_CAPACITY_ENV;
  2822. }
  2823. /*********************************************************************
  2824. * @fn esp_GetMirrorEndpoint
  2825. *
  2826. * @brief Get the endpoint of a mirror using the Source Address and
  2827. * source endpoint.
  2828. *
  2829. * @param srcAddr - source address to lookup
  2830. *
  2831. * @return Endpoint of the mirror or
  2832. * ESP_MIRROR_INVALID_ENDPOINT if there is no space
  2833. */
  2834. static uint8 esp_GetMirrorEndpoint( afAddrType_t *srcAddr )
  2835. {
  2836. uint8 i;
  2837. for ( i = 0; i < ESP_MAX_MIRRORS; i++ )
  2838. {
  2839. if ( ( esp_MirrorControl.mirrorMask & (1 << i) ) &&
  2840. ( esp_MirrorControl.mirrorInfo[i].srcAddr == srcAddr->addr.shortAddr ) &&
  2841. ( esp_MirrorControl.mirrorInfo[i].srcEndpoint == srcAddr->endPoint ) )
  2842. {
  2843. return ( i + ESP_MIRROR_EP_BASE );
  2844. }
  2845. }
  2846. return ESP_MIRROR_INVALID_ENDPOINT;
  2847. }
  2848. /*********************************************************************
  2849. * @fn esp_GetMirrorInfo
  2850. *
  2851. * @brief Get the control information for a mirror endpoint.
  2852. *
  2853. * @param endpoint - to lookup
  2854. *
  2855. * @return Pointer to Mirror Information or
  2856. * NULL if no Mirror found for the Endpoint
  2857. */
  2858. static espMirrorInfo_t *esp_GetMirrorInfo( uint8 endpoint )
  2859. {
  2860. if ( esp_IsMirrorEndpoint( endpoint ) )
  2861. {
  2862. // Get the index to the mirror
  2863. uint8 index = endpoint - ESP_MIRROR_EP_BASE;
  2864. // Return a pointer to the attributes
  2865. return &esp_MirrorControl.mirrorInfo[index];
  2866. }
  2867. return NULL;
  2868. }
  2869. /*********************************************************************
  2870. * @fn esp_MirrorInitAttributeSet
  2871. *
  2872. * @brief Adds notification attributes to the mirror endpoint
  2873. *
  2874. * @param endpoint - Endpoint of the mirror
  2875. *
  2876. * @return none
  2877. */
  2878. static void esp_MirrorInitAttributeSet( uint8 endpoint )
  2879. {
  2880. espMirrorInfo_t *pInfo = esp_GetMirrorInfo( endpoint );
  2881. if ( pInfo != NULL )
  2882. {
  2883. zclAttrRec_t *pAttributes = pInfo->pAttr;
  2884. if ( pAttributes != NULL )
  2885. {
  2886. // Note: Attributes 0 through ESP_MIRROR_USER_ATTRIBUTES_POSITION-1 are used for
  2887. // the mirror notify attribute set. The rest of the attributes are reserved for
  2888. // the meter. The meter creates attributes with a report attribute command.
  2889. pAttributes[0].clusterID = ZCL_CLUSTER_ID_SE_SIMPLE_METERING;
  2890. pAttributes[0].attr.attrId = ATTRID_SE_NOTIFICATION_CONTROL_FLAGS;
  2891. pAttributes[0].attr.dataType = ZCL_DATATYPE_BITMAP8;
  2892. pAttributes[0].attr.accessControl = ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE;
  2893. pAttributes[0].attr.dataPtr = &pInfo->notificationControl;
  2894. pAttributes[1].clusterID = ZCL_CLUSTER_ID_SE_SIMPLE_METERING;
  2895. pAttributes[1].attr.attrId = ATTRID_SE_NOTIFICATION_FLAGS;
  2896. pAttributes[1].attr.dataType = ZCL_DATATYPE_BITMAP8;
  2897. pAttributes[1].attr.accessControl = ACCESS_CONTROL_READ;
  2898. pAttributes[1].attr.dataPtr = &pInfo->notificationSet.NotificationFlags;
  2899. pAttributes[2].clusterID = ZCL_CLUSTER_ID_SE_SIMPLE_METERING;
  2900. pAttributes[2].attr.attrId = ATTRID_SE_PRICE_NOTIFICATION_FLAGS;
  2901. pAttributes[2].attr.dataType = ZCL_DATATYPE_BITMAP16;
  2902. pAttributes[2].attr.accessControl = ACCESS_CONTROL_READ;
  2903. pAttributes[2].attr.dataPtr = &pInfo->notificationSet.PriceNotificationFlags;
  2904. pAttributes[3].clusterID = ZCL_CLUSTER_ID_SE_SIMPLE_METERING;
  2905. pAttributes[3].attr.attrId = ATTRID_SE_CALENDAR_NOTIFICATION_FLAGS;
  2906. pAttributes[3].attr.dataType = ZCL_DATATYPE_BITMAP8;
  2907. pAttributes[3].attr.accessControl = ACCESS_CONTROL_READ;
  2908. pAttributes[3].attr.dataPtr = &pInfo->notificationSet.CalendarNotificationFlags;
  2909. pAttributes[4].clusterID = ZCL_CLUSTER_ID_SE_SIMPLE_METERING;
  2910. pAttributes[4].attr.attrId = ATTRID_SE_PRE_PAY_NOTIFICATION_FLAGS;
  2911. pAttributes[4].attr.dataType = ZCL_DATATYPE_BITMAP16;
  2912. pAttributes[4].attr.accessControl = ACCESS_CONTROL_READ;
  2913. pAttributes[4].attr.dataPtr = &pInfo->notificationSet.PrePayNotificationFlags;
  2914. pAttributes[5].clusterID = ZCL_CLUSTER_ID_SE_SIMPLE_METERING;
  2915. pAttributes[5].attr.attrId = ATTRID_SE_DEVICE_MANAGEMENT_FLAGS;
  2916. pAttributes[5].attr.dataType = ZCL_DATATYPE_BITMAP8;
  2917. pAttributes[5].attr.accessControl = ACCESS_CONTROL_READ;
  2918. pAttributes[5].attr.dataPtr = &pInfo->notificationSet.DeviceMgmtNotificationFlags;
  2919. }
  2920. }
  2921. }
  2922. /*********************************************************************
  2923. * @fn esp_AllocMirror
  2924. *
  2925. * @brief Allocate a mirror endpoint in the mirror control structure.
  2926. *
  2927. * @param srcAddr - of the device requesting a Mirror
  2928. *
  2929. * @return Endpoint of the mirror or
  2930. * ESP_MIRROR_INVALID_ENDPOINT if there is no space
  2931. */
  2932. static uint8 esp_AllocMirror( afAddrType_t *srcAddr )
  2933. {
  2934. uint8 i;
  2935. zclAttrRec_t *pAttr;
  2936. uint8 endpoint;
  2937. // Verify space is available for another mirror endpoint
  2938. if ( esp_MirrorControl.mirrorMask != ESP_MIRROR_FULL_MASK )
  2939. {
  2940. // Allocate memory for the attribute table
  2941. pAttr = osal_mem_alloc( sizeof( zclAttrRec_t ) * ESP_MIRROR_MAX_ATTRIBUTES );
  2942. if ( pAttr != NULL )
  2943. {
  2944. // Initialize the attribute
  2945. osal_memset( pAttr, 0, sizeof( zclAttrRec_t ) * ESP_MIRROR_MAX_ATTRIBUTES );
  2946. // Set the attribute clusters to 0xFFFF indicating they are not in use
  2947. for ( i = 0; i < ESP_MIRROR_MAX_ATTRIBUTES; i++ )
  2948. {
  2949. pAttr[i].clusterID = 0xFFFF;
  2950. }
  2951. // Find the next free endpoint slot
  2952. for ( i = 0; i < ESP_MAX_MIRRORS; i++ )
  2953. {
  2954. if ( esp_MirrorControl.mirrorMask & (1 << i) )
  2955. {
  2956. continue;
  2957. }
  2958. endpoint = i + ESP_MIRROR_EP_BASE;
  2959. // Zero out the info memory
  2960. osal_memset( &esp_MirrorControl.mirrorInfo[i], 0, sizeof( espMirrorInfo_t ) );
  2961. // Setup mirror information
  2962. esp_MirrorControl.mirrorMask |= 1 << i;
  2963. esp_MirrorControl.mirrorInfo[i].srcAddr = srcAddr->addr.shortAddr;
  2964. esp_MirrorControl.mirrorInfo[i].srcEndpoint = srcAddr->endPoint;
  2965. esp_MirrorControl.mirrorInfo[i].pAttr = pAttr;
  2966. // Create attributes for the notification set
  2967. esp_MirrorInitAttributeSet( endpoint );
  2968. // If all endpoints are in use, set the PhysicalEnvironment attribute
  2969. // indicating all mirror slot are used
  2970. if ( esp_MirrorControl.mirrorMask == ESP_MIRROR_FULL_MASK )
  2971. {
  2972. espPhysicalEnvironment &= ~PHY_MIRROR_CAPACITY_ENV;
  2973. }
  2974. return endpoint;
  2975. }
  2976. // Free the attribute memory if we could not allocate the endpoint
  2977. osal_mem_free( pAttr );
  2978. }
  2979. }
  2980. return ESP_MIRROR_INVALID_ENDPOINT;
  2981. }
  2982. /*********************************************************************
  2983. * @fn esp_FreeMirror
  2984. *
  2985. * @brief Free a mirror endpoint in the mirror control structure.
  2986. *
  2987. * @param endPoint - Endpoint of the mirror to free
  2988. *
  2989. * @return none
  2990. */
  2991. void esp_FreeMirror( uint8 endPoint )
  2992. {
  2993. if ( esp_IsMirrorEndpoint( endPoint ) )
  2994. {
  2995. // Get the index to the mirror
  2996. uint8 index = endPoint - ESP_MIRROR_EP_BASE;
  2997. uint8 i;
  2998. // Clear the endpoint bit in the mask of allocated mirrors
  2999. esp_MirrorControl.mirrorMask &= ~(1 << index);
  3000. if ( esp_MirrorControl.mirrorInfo[index].pAttr )
  3001. {
  3002. // Free the user attribute data
  3003. for ( i = ESP_MIRROR_USER_ATTRIBUTES_POSITION; i < ESP_MIRROR_MAX_ATTRIBUTES; i++ )
  3004. {
  3005. if ( esp_MirrorControl.mirrorInfo[index].pAttr[i].attr.dataPtr )
  3006. {
  3007. osal_mem_free( esp_MirrorControl.mirrorInfo[index].pAttr[i].attr.dataPtr );
  3008. esp_MirrorControl.mirrorInfo[index].pAttr[i].attr.dataPtr = NULL;
  3009. }
  3010. }
  3011. // Free the attribute table
  3012. osal_mem_free( esp_MirrorControl.mirrorInfo[index].pAttr );
  3013. esp_MirrorControl.mirrorInfo[index].pAttr = NULL;
  3014. }
  3015. }
  3016. }
  3017. /*********************************************************************
  3018. * @fn esp_IsMirrorEndpoint
  3019. *
  3020. * @brief Check if the endpoint is in the mirror block of endpoints.
  3021. *
  3022. * @param endpoint - Endpoint of the mirror to free
  3023. *
  3024. * @return TRUE - if Endpoint is in the Mirror Block
  3025. * FALSE - Otherwise
  3026. */
  3027. static uint8 esp_IsMirrorEndpoint( uint8 endpoint )
  3028. {
  3029. if ( (endpoint >= ESP_MIRROR_EP_BASE ) &&
  3030. (endpoint <= ESP_MIRROR_EP_BASE + ESP_MAX_MIRRORS ) )
  3031. {
  3032. return TRUE;
  3033. }
  3034. return FALSE;
  3035. }
  3036. /*********************************************************************
  3037. * @fn esp_MirrorUpdateAttribute
  3038. *
  3039. * @brief Update Attributes in Mirror
  3040. *
  3041. * @param endpoint - Endpoint of the mirror to free
  3042. * cluster - Cluster ID
  3043. * pReport - Pointer to reported attributes
  3044. *
  3045. * @return TRUE - if Data updated
  3046. * FALSE - Otherwise
  3047. */
  3048. static uint8 esp_MirrorUpdateAttribute( uint8 endpoint, uint16 cluster, zclReport_t *pReport )
  3049. {
  3050. espMirrorInfo_t *pInfo = esp_GetMirrorInfo( endpoint );
  3051. if ( pInfo != NULL )
  3052. {
  3053. zclAttrRec_t *pAttributes = pInfo->pAttr;
  3054. uint8 i;
  3055. if ( pAttributes != NULL )
  3056. {
  3057. // Check if the attribute already exists
  3058. for ( i = ESP_MIRROR_USER_ATTRIBUTES_POSITION; i < ESP_MIRROR_MAX_ATTRIBUTES; i++ )
  3059. {
  3060. if ( pAttributes[i].clusterID == cluster )
  3061. {
  3062. if ( pAttributes[i].attr.attrId == pReport->attrID )
  3063. {
  3064. if ( pAttributes[i].attr.dataPtr )
  3065. {
  3066. // Update the attribute data
  3067. zclSerializeData( pReport->dataType, pReport->attrData, pAttributes[i].attr.dataPtr );
  3068. return TRUE;
  3069. }
  3070. }
  3071. }
  3072. }
  3073. // Look for a free attribute slot and add the attribute
  3074. for ( i = ESP_MIRROR_USER_ATTRIBUTES_POSITION; i < ESP_MIRROR_MAX_ATTRIBUTES; i++ )
  3075. {
  3076. if ( pAttributes[i].attr.dataPtr == NULL )
  3077. {
  3078. uint8 dataLength = zclGetDataTypeLength( pReport->dataType );
  3079. if ( dataLength > 0 )
  3080. {
  3081. pAttributes[i].clusterID = cluster;
  3082. pAttributes[i].attr.attrId = pReport->attrID;
  3083. pAttributes[i].attr.dataType = pReport->dataType;
  3084. pAttributes[i].attr.accessControl = ACCESS_CONTROL_READ;
  3085. pAttributes[i].attr.dataPtr = osal_mem_alloc( dataLength );
  3086. if ( pAttributes[i].attr.dataPtr != NULL )
  3087. {
  3088. zclSerializeData( pReport->dataType, pReport->attrData, pAttributes[i].attr.dataPtr );
  3089. return TRUE;
  3090. }
  3091. }
  3092. }
  3093. }
  3094. }
  3095. }
  3096. return FALSE;
  3097. }
  3098. /*********************************************************************
  3099. * @fn esp_MirrorProcessZCLMsg
  3100. *
  3101. * @brief Process ZCL messages for mirror endpoints.
  3102. *
  3103. * @param pInMsg - ZCL Message
  3104. *
  3105. * @return none
  3106. */
  3107. static void esp_MirrorProcessZCLMsg( zclIncomingMsg_t *pInMsg )
  3108. {
  3109. uint8 i;
  3110. if ( pInMsg->zclHdr.commandID == ZCL_CMD_REPORT )
  3111. {
  3112. zclReportCmd_t *reportCmd = (zclReportCmd_t *)pInMsg->attrCmd;
  3113. if ( reportCmd != NULL)
  3114. {
  3115. for (i = 0; i < reportCmd->numAttr; i++)
  3116. {
  3117. // Update the attribute
  3118. esp_MirrorUpdateAttribute( pInMsg->endPoint, pInMsg->clusterId, &reportCmd->attrList[i] );
  3119. }
  3120. }
  3121. // Build a response
  3122. espMirrorInfo_t *pInfo = esp_GetMirrorInfo( pInMsg->srcAddr.endPoint );
  3123. if ( pInfo != NULL )
  3124. {
  3125. if ( pInfo->notificationControl & SE_NOTIFICATION_REPORT_ATTR_RSP_BIT )
  3126. {
  3127. // Send a mirror report attr rsp using the notification set from the mirror info
  3128. zclSE_SimpleMetering_Send_MirrorReportAttrRsp( pInMsg->endPoint, &pInMsg->srcAddr,
  3129. &pInfo->notificationSet, TRUE,
  3130. pInMsg->zclHdr.transSeqNum);
  3131. }
  3132. }
  3133. }
  3134. }
  3135. #endif // SE_UK_EXT && SE_MIRROR
  3136. /****************************************************************************
  3137. ****************************************************************************/