ipd.c 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791
  1. /**************************************************************************************************
  2. Filename: ipd.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 IPD 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 IPD configuration:
  37. General Basic
  38. General Alarms
  39. General Time
  40. General Key Establishment
  41. SE Price
  42. SE Message
  43. Key control:
  44. SW1: Join Network
  45. SW2: Send INTER-PAN Get Current Price Message
  46. SW3: N/A
  47. SW4: N/A
  48. *********************************************************************/
  49. /*********************************************************************
  50. * INCLUDES
  51. */
  52. #include "OSAL.h"
  53. #include "OSAL_Clock.h"
  54. #include "ZDApp.h"
  55. #include "ZDProfile.h"
  56. #include "ZDObject.h"
  57. #include "AddrMgr.h"
  58. #include "se.h"
  59. #include "ipd.h"
  60. #include "zcl_general.h"
  61. #include "zcl_se.h"
  62. #include "zcl_key_establish.h"
  63. #if defined( INTER_PAN )
  64. #include "stub_aps.h"
  65. #endif
  66. #include "onboard.h"
  67. /* HAL */
  68. #include "hal_lcd.h"
  69. #include "hal_led.h"
  70. #include "hal_key.h"
  71. #include "zcl_ota.h"
  72. #include "hal_ota.h"
  73. /*********************************************************************
  74. * MACROS
  75. */
  76. // There is no attribute in the Mandatory Reportable Attribute list for now
  77. #define zcl_MandatoryReportableAttribute( a ) ( a == NULL )
  78. /*********************************************************************
  79. * CONSTANTS
  80. */
  81. #define ipdNwkState devState
  82. /*********************************************************************
  83. * TYPEDEFS
  84. */
  85. typedef struct
  86. {
  87. uint16 addr;
  88. uint8 endpoint;
  89. } ipd_Server_t;
  90. /*********************************************************************
  91. * GLOBAL VARIABLES
  92. */
  93. // Initialize the checksum shadow and image length used by the bootloader
  94. #pragma location="CRC"
  95. const CODE otaCrc_t OTA_CRC =
  96. {
  97. 0xFFFF, // CRC
  98. 0xFFFF, // CRC Shadow
  99. };
  100. #pragma required=OTA_CRC
  101. #pragma location="PREAMBLE"
  102. const CODE preamble_t OTA_Preamble =
  103. {
  104. 0xFFFFFFFF, // Program Length
  105. OTA_MANUFACTURER_ID, // Manufacturer ID
  106. OTA_TYPE_ID, // Image Type
  107. 0x00000003 // Image Version
  108. };
  109. #pragma required=OTA_Preamble
  110. /*********************************************************************
  111. * GLOBAL FUNCTIONS
  112. */
  113. /*********************************************************************
  114. * LOCAL VARIABLES
  115. */
  116. static uint8 ipdOtaState; // state of OTA discovery and download
  117. ipd_Server_t ipdServerList[IPD_OTA_MAX_SERVERS];
  118. static uint8 ipdTaskID; // osal task id for IPD
  119. static uint8 ipdTransID; // transaction id
  120. static afAddrType_t ESPAddr; // ESP destination address
  121. #if SECURE
  122. static uint8 linkKeyStatus; // status variable returned from get link key function
  123. #endif
  124. static uint8 option; // tx options field
  125. #if defined (INTER_PAN)
  126. static uint8 rxOnIdle; // receiver on when idle flag
  127. // define endpoint structure to register with STUB APS for INTER-PAN support
  128. static endPointDesc_t ipdEp =
  129. {
  130. IPD_ENDPOINT,
  131. &ipdTaskID,
  132. (SimpleDescriptionFormat_t *)&ipdSimpleDesc,
  133. (afNetworkLatencyReq_t)0
  134. };
  135. #endif
  136. /*********************************************************************
  137. * LOCAL FUNCTIONS
  138. */
  139. static void ipd_HandleKeys( uint8 shift, uint8 keys );
  140. #if SECURE
  141. static uint8 ipd_KeyEstablish_ReturnLinkKey( uint16 shortAddr );
  142. #endif
  143. static void ipd_ProcessIdentifyTimeChange( void );
  144. /*************************************************************************/
  145. /*** Application Callback Functions ***/
  146. /*************************************************************************/
  147. // Foundation Callback functions
  148. static uint8 ipd_ValidateAttrDataCB( zclAttrRec_t *pAttr, zclWriteRec_t *pAttrInfo );
  149. // General Cluster Callback functions
  150. static void ipd_BasicResetCB( void );
  151. static void ipd_IdentifyCB( zclIdentify_t *pCmd );
  152. static void ipd_IdentifyQueryRspCB( zclIdentifyQueryRsp_t *pRsp );
  153. static void ipd_AlarmCB( zclAlarm_t *pAlarm );
  154. #ifdef SE_UK_EXT
  155. static void ipd_GetEventLogCB( uint8 srcEP, afAddrType_t *srcAddr,
  156. zclGetEventLog_t *pEventLog, uint8 seqNum );
  157. static void ipd_PublishEventLogCB( afAddrType_t *srcAddr,
  158. zclPublishEventLog_t *pEventLog );
  159. #endif // SE_UK_EXT
  160. static void ipd_ProcessZDOMsgs( zdoIncomingMsg_t *pMsg );
  161. static void ipd_AddServer( uint16 addr, uint8 endpoint );
  162. static void ipd_PopServer( uint16 *addr, uint8 *endpoint );
  163. static void ipd_ProcessOTAMsgs( zclOTA_CallbackMsg_t* pMsg );
  164. // SE Callback functions
  165. static void ipd_GetCurrentPriceCB( zclCCGetCurrentPrice_t *pCmd,
  166. afAddrType_t *srcAddr, uint8 seqNum );
  167. static void ipd_GetScheduledPriceCB( zclCCGetScheduledPrice_t *pCmd,
  168. afAddrType_t *srcAddr, uint8 seqNum );
  169. static void ipd_PublishPriceCB( zclCCPublishPrice_t *pCmd,
  170. afAddrType_t *srcAddr, uint8 seqNum );
  171. static void ipd_DisplayMessageCB( zclCCDisplayMessage_t *pCmd,
  172. afAddrType_t *srcAddr, uint8 seqNum );
  173. static void ipd_CancelMessageCB( zclCCCancelMessage_t *pCmd,
  174. afAddrType_t *srcAddr, uint8 seqNum );
  175. static void ipd_GetLastMessageCB( afAddrType_t *srcAddr, uint8 seqNum );
  176. static void ipd_MessageConfirmationCB( zclCCMessageConfirmation_t *pCmd,
  177. afAddrType_t *srcAddr, uint8 seqNum );
  178. #if defined ( SE_UK_EXT )
  179. static void ipd_PublishTariffInformationCB( zclCCPublishTariffInformation_t *pCmd,
  180. afAddrType_t *srcAddr, uint8 seqNum );
  181. static void ipd_PublishPriceMatrixCB( zclCCPublishPriceMatrix_t *pCmd,
  182. afAddrType_t *srcAddr, uint8 seqNum );
  183. static void ipd_PublishBlockThresholdsCB( zclCCPublishBlockThresholds_t *pCmd,
  184. afAddrType_t *srcAddr, uint8 seqNum );
  185. static void ipd_PublishConversionFactorCB( zclCCPublishConversionFactor_t *pCmd,
  186. afAddrType_t *srcAddr, uint8 seqNum );
  187. static void ipd_PublishCalorificValueCB( zclCCPublishCalorificValue_t *pCmd,
  188. afAddrType_t *srcAddr, uint8 seqNum );
  189. static void ipd_PublishCO2ValueCB( zclCCPublishCO2Value_t *pCmd,
  190. afAddrType_t *srcAddr, uint8 seqNum );
  191. static void ipd_PublishCPPEventCB( zclCCPublishCPPEvent_t *pCmd,
  192. afAddrType_t *srcAddr, uint8 seqNum );
  193. static void ipd_PublishBillingPeriodCB( zclCCPublishBillingPeriod_t *pCmd,
  194. afAddrType_t *srcAddr, uint8 seqNum );
  195. static void ipd_PublishConsolidatedBillCB( zclCCPublishConsolidatedBill_t *pCmd,
  196. afAddrType_t *srcAddr, uint8 seqNum );
  197. static void ipd_PublishCreditPaymentInfoCB( zclCCPublishCreditPaymentInfo_t *pCmd,
  198. afAddrType_t *srcAddr, uint8 seqNum );
  199. static void ipd_GetPrepaySnapshotResponseCB( zclCCGetPrepaySnapshotResponse_t *pCmd,
  200. afAddrType_t *srcAddr, uint8 seqNum );
  201. static void ipd_ChangePaymentModeResponseCB( zclCCChangePaymentModeResponse_t *pCmd,
  202. afAddrType_t *srcAddr, uint8 seqNum );
  203. static void ipd_ConsumerTopupResponseCB( zclCCConsumerTopupResponse_t *pCmd,
  204. afAddrType_t *srcAddr, uint8 seqNum );
  205. static void ipd_GetCommandsCB( uint8 prepayNotificationFlags,
  206. afAddrType_t *srcAddr, uint8 seqNum );
  207. static void ipd_PublishTopupLogCB( zclCCPublishTopupLog_t *pCmd,
  208. afAddrType_t *srcAddr, uint8 seqNum );
  209. static void ipd_PublishDebtLogCB( zclCCPublishDebtLog_t *pCmd,
  210. afAddrType_t *srcAddr, uint8 seqNum );
  211. #endif // SE_UK_EXT
  212. /************************************************************************/
  213. /*** Functions to process ZCL Foundation ***/
  214. /*** incoming Command/Response messages ***/
  215. /************************************************************************/
  216. static void ipd_ProcessZCLMsg( zclIncomingMsg_t *msg );
  217. #if defined ( ZCL_READ )
  218. static uint8 ipd_ProcessInReadRspCmd( zclIncomingMsg_t *pInMsg );
  219. #endif // ZCL_READ
  220. #if defined ( ZCL_WRITE )
  221. static uint8 ipd_ProcessInWriteRspCmd( zclIncomingMsg_t *pInMsg );
  222. #endif // ZCL_WRITE
  223. static uint8 ipd_ProcessInDefaultRspCmd( zclIncomingMsg_t *pInMsg );
  224. #if defined ( ZCL_DISCOVER )
  225. static uint8 ipd_ProcessInDiscRspCmd( zclIncomingMsg_t *pInMsg );
  226. #endif // ZCL_DISCOVER
  227. /*********************************************************************
  228. * ZCL General Clusters Callback table
  229. */
  230. static zclGeneral_AppCallbacks_t ipd_GenCmdCallbacks =
  231. {
  232. ipd_BasicResetCB, // Basic Cluster Reset command
  233. ipd_IdentifyCB, // Identify command
  234. ipd_IdentifyQueryRspCB, // Identify Query Response command
  235. NULL, // On/Off cluster commands
  236. NULL, // Level Control Move to Level command
  237. NULL, // Level Control Move command
  238. NULL, // Level Control Step command
  239. NULL, // Level Control Stop command
  240. NULL, // Group Response commands
  241. NULL, // Scene Store Request command
  242. NULL, // Scene Recall Request command
  243. NULL, // Scene Response command
  244. ipd_AlarmCB, // Alarm (Response) command
  245. #ifdef SE_UK_EXT
  246. ipd_GetEventLogCB, // Get Event Log command
  247. ipd_PublishEventLogCB, // Publish Event Log command
  248. #endif
  249. NULL, // RSSI Location command
  250. NULL // RSSI Location Response command
  251. };
  252. /*********************************************************************
  253. * ZCL SE Clusters Callback table
  254. */
  255. static zclSE_AppCallbacks_t ipd_SECmdCallbacks =
  256. {
  257. ipd_PublishPriceCB, // Publish Price
  258. NULL, // Publish Block Period
  259. #if defined ( SE_UK_EXT )
  260. ipd_PublishTariffInformationCB, // Publish Tariff Information
  261. ipd_PublishPriceMatrixCB, // Publish Price Matrix
  262. ipd_PublishBlockThresholdsCB, // Publish Block Thresholds
  263. ipd_PublishConversionFactorCB, // Publish Conversion Factor
  264. ipd_PublishCalorificValueCB, // Publish Calorific Value
  265. ipd_PublishCO2ValueCB, // Publish CO2 Value
  266. ipd_PublishCPPEventCB, // Publish CPP Event
  267. ipd_PublishBillingPeriodCB, // Publish Billing Period
  268. ipd_PublishConsolidatedBillCB, // Publish Consolidated Bill
  269. ipd_PublishCreditPaymentInfoCB, // Publish Credit Payment Info
  270. #endif // SE_UK_EXT
  271. ipd_GetCurrentPriceCB, // Get Current Price
  272. ipd_GetScheduledPriceCB, // Get Scheduled Price
  273. NULL, // Price Acknowledgement
  274. NULL, // Get Block Period
  275. #if defined ( SE_UK_EXT )
  276. NULL, // Get Tariff Information
  277. NULL, // Get Price Matrix
  278. NULL, // Get Block Thresholds
  279. NULL, // Get Conversion Factor
  280. NULL, // Get Calorific Value
  281. NULL, // Get CO2 Value
  282. NULL, // Get Billing Period
  283. NULL, // Get Consolidated Bill
  284. NULL, // CPP Event Response
  285. #endif // SE_UK_EXT
  286. NULL, // Load Control Event
  287. NULL, // Cancel Load Control Event
  288. NULL, // Cancel All Load Control Events
  289. NULL, // Report Event Status
  290. NULL, // Get Scheduled Event
  291. NULL, // Get Profile Response
  292. NULL, // Request Mirror Command
  293. NULL, // Mirror Remove Command
  294. NULL, // Request Fast Poll Mode Response
  295. #if defined ( SE_UK_EXT )
  296. NULL, // Get Snapshot Response
  297. #endif // SE_UK_EXT
  298. NULL, // Get Profile Command
  299. NULL, // Request Mirror Response
  300. NULL, // Mirror Remove Response
  301. NULL, // Request Fast Poll Mode Command
  302. #if defined ( SE_UK_EXT )
  303. NULL, // Get Snapshot Command
  304. NULL, // Take Snapshot Command
  305. NULL, // Mirror Report Attribute Response
  306. #endif // SE_UK_EXT
  307. ipd_DisplayMessageCB, // Display Message Command
  308. ipd_CancelMessageCB, // Cancel Message Command
  309. ipd_GetLastMessageCB, // Get Last Message Command
  310. ipd_MessageConfirmationCB, // Message Confirmation
  311. NULL, // Request Tunnel Response
  312. NULL, // Transfer Data
  313. NULL, // Transfer Data Error
  314. NULL, // Ack Transfer Data
  315. NULL, // Ready Data
  316. #if defined ( SE_UK_EXT )
  317. NULL, // Supported Tunnel Protocols Response
  318. NULL, // Tunnel Closure Notification
  319. #endif // SE_UK_EXT
  320. NULL, // Request Tunnel
  321. NULL, // Close Tunnel
  322. #if defined ( SE_UK_EXT )
  323. NULL, // Get Supported Tunnel Protocols
  324. #endif // SE_UK_EXT
  325. NULL, // Supply Status Response
  326. #if defined ( SE_UK_EXT )
  327. ipd_GetPrepaySnapshotResponseCB, // Get Prepay Snapshot Response
  328. ipd_ChangePaymentModeResponseCB, // Change Payment Mode Response
  329. ipd_ConsumerTopupResponseCB, // Consumer Topup Response
  330. ipd_GetCommandsCB, // Get Commands
  331. ipd_PublishTopupLogCB, // Publish Topup Log
  332. ipd_PublishDebtLogCB, // Publish Debt Log
  333. #endif // SE_UK_EXT
  334. NULL, // Select Available Emergency Credit Command
  335. NULL, // Change Supply Command
  336. #if defined ( SE_UK_EXT )
  337. NULL, // Change Debt
  338. NULL, // Emergency Credit Setup
  339. NULL, // Consumer Topup
  340. NULL, // Credit Adjustment
  341. NULL, // Change PaymentMode
  342. NULL, // Get Prepay Snapshot
  343. NULL, // Get Topup Log
  344. NULL, // Set Low Credit Warning Level
  345. NULL, // Get Debt Repayment Log
  346. NULL, // Publish Calendar
  347. NULL, // Publish Day Profile
  348. NULL, // Publish Week Profile
  349. NULL, // Publish Seasons
  350. NULL, // Publish Special Days
  351. NULL, // Get Calendar
  352. NULL, // Get Day Profiles
  353. NULL, // Get Week Profiles
  354. NULL, // Get Seasons
  355. NULL, // Get Special Days
  356. NULL, // Publish Change Tenancy
  357. NULL, // Publish Change Supplier
  358. NULL, // Change Supply
  359. NULL, // Change Password
  360. NULL, // Local Change Supply
  361. NULL, // Get Change Tenancy
  362. NULL, // Get Change Supplier
  363. NULL, // Get Change Supply
  364. NULL, // Supply Status Response
  365. NULL, // Get Password
  366. #endif // SE_UK_EXT
  367. };
  368. /*********************************************************************
  369. * @fn ipd_Init
  370. *
  371. * @brief Initialization function for the ZCL App Application.
  372. *
  373. * @param uint8 task_id - ipd task id
  374. *
  375. * @return none
  376. */
  377. void ipd_Init( uint8 task_id )
  378. {
  379. OTA_ImageHeader_t header;
  380. preamble_t preamble;
  381. ipdTaskID = task_id;
  382. ipdTransID = 0;
  383. char lcdBuf[20];
  384. #if HAL_OTA_XNV_IS_SPI
  385. XNV_SPI_INIT();
  386. #endif
  387. // Device hardware initialization can be added here or in main() (Zmain.c).
  388. // If the hardware is application specific - add it here.
  389. // If the hardware is other parts of the device add it in main().
  390. // setup ESP destination address
  391. ESPAddr.addrMode = (afAddrMode_t)Addr16Bit;
  392. ESPAddr.endPoint = IPD_ENDPOINT;
  393. ESPAddr.addr.shortAddr = 0;
  394. // Read the OTA File Header
  395. HalOTARead(0, (uint8 *)&header, sizeof(OTA_ImageHeader_t), HAL_OTA_DL);
  396. if (header.magicNumber == OTA_HDR_MAGIC_NUMBER)
  397. {
  398. zclOTA_DownloadedFileVersion = header.fileId.version;
  399. zclOTA_DownloadedZigBeeStackVersion = header.stackVersion;
  400. }
  401. // Load the OTA Attributes from the constant values in NV
  402. HalOTARead(PREAMBLE_OFFSET, (uint8 *)&preamble, sizeof(preamble_t), HAL_OTA_RC);
  403. zclOTA_ManufacturerId = preamble.manufacturerId;
  404. zclOTA_ImageType = preamble.imageType;
  405. zclOTA_CurrentFileVersion = preamble.imageVersion;
  406. // Register for SE endpoint
  407. zclSE_Init( &ipdSimpleDesc );
  408. // Register the ZCL General Cluster Library callback functions
  409. zclGeneral_RegisterCmdCallbacks( IPD_ENDPOINT, &ipd_GenCmdCallbacks );
  410. // Register the ZCL SE Cluster Library callback functions
  411. zclSE_RegisterCmdCallbacks( IPD_ENDPOINT, &ipd_SECmdCallbacks );
  412. // Register the application's attribute list
  413. zcl_registerAttrList( IPD_ENDPOINT, IPD_MAX_ATTRIBUTES, ipdAttrs );
  414. // Register the application's cluster option list
  415. zcl_registerClusterOptionList( IPD_ENDPOINT, IPD_MAX_OPTIONS, ipdOptions );
  416. // Register the application's attribute data validation callback function
  417. zcl_registerValidateAttrData( ipd_ValidateAttrDataCB );
  418. // Register the Application to receive the unprocessed Foundation command/response messages
  419. zcl_registerForMsg( ipdTaskID );
  420. // Register for all key events - This app will handle all key events
  421. RegisterForKeys( ipdTaskID );
  422. // Register with the ZDO to receive Match Descriptor Responses
  423. ZDO_RegisterForZDOMsg(task_id, Match_Desc_rsp);
  424. #if defined ( INTER_PAN )
  425. // Register with Stub APS
  426. StubAPS_RegisterApp( &ipdEp );
  427. #endif
  428. // Register for callback events from the ZCL OTA
  429. zclOTA_Register(ipdTaskID);
  430. // Indicate teh current image version on LCD
  431. osal_memset(lcdBuf, ' ', sizeof(lcdBuf));
  432. lcdBuf[19] = '\0';
  433. osal_memcpy(lcdBuf, "Ver: 0x", 7);
  434. _ltoa(zclOTA_CurrentFileVersion, (uint8*)&lcdBuf[7], 16);
  435. HalLcdWriteString(lcdBuf, HAL_LCD_LINE_3);
  436. // Start the timer to sync IPD timer with the osal timer
  437. osal_start_timerEx( ipdTaskID, IPD_UPDATE_TIME_EVT, IPD_UPDATE_TIME_PERIOD );
  438. }
  439. /*********************************************************************
  440. * @fn ipd_event_loop
  441. *
  442. * @brief Event Loop Processor for ipd.
  443. *
  444. * @param uint8 task_id - ipd task id
  445. * @param uint16 events - event bitmask
  446. *
  447. * @return none
  448. */
  449. uint16 ipd_event_loop( uint8 task_id, uint16 events )
  450. {
  451. afIncomingMSGPacket_t *MSGpkt;
  452. if ( events & SYS_EVENT_MSG )
  453. {
  454. while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( ipdTaskID )) )
  455. {
  456. switch ( MSGpkt->hdr.event )
  457. {
  458. case ZCL_OTA_CALLBACK_IND:
  459. ipd_ProcessOTAMsgs( (zclOTA_CallbackMsg_t*)MSGpkt );
  460. break;
  461. case ZDO_CB_MSG:
  462. ipd_ProcessZDOMsgs( (zdoIncomingMsg_t *)MSGpkt );
  463. break;
  464. case ZCL_INCOMING_MSG:
  465. // Incoming ZCL foundation command/response messages
  466. ipd_ProcessZCLMsg( (zclIncomingMsg_t *)MSGpkt );
  467. break;
  468. case KEY_CHANGE:
  469. ipd_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );
  470. break;
  471. case ZDO_STATE_CHANGE:
  472. if ((DEV_END_DEVICE == (devStates_t)(MSGpkt->hdr.status)))
  473. {
  474. #if SECURE
  475. {
  476. // check to see if link key had already been established
  477. linkKeyStatus = ipd_KeyEstablish_ReturnLinkKey(ESPAddr.addr.shortAddr);
  478. if (linkKeyStatus != ZSuccess)
  479. {
  480. cId_t cbkeCluster = ZCL_CLUSTER_ID_GEN_KEY_ESTABLISHMENT;
  481. zAddrType_t dstAddr;
  482. ipdOtaState = IPD_OTA_CBKE_STATE;
  483. // Send out a match for the key establishment
  484. dstAddr.addrMode = AddrBroadcast;
  485. dstAddr.addr.shortAddr = NWK_BROADCAST_SHORTADDR;
  486. ZDP_MatchDescReq( &dstAddr, NWK_BROADCAST_SHORTADDR, ZCL_SE_PROFILE_ID,
  487. 1, &cbkeCluster, 0, NULL, FALSE );
  488. }
  489. else
  490. {
  491. // link key already established, resume sending reports
  492. osal_start_timerEx( ipdTaskID, IPD_GET_PRICING_INFO_EVT, IPD_GET_PRICING_INFO_PERIOD );
  493. }
  494. }
  495. #else
  496. {
  497. osal_start_timerEx( ipdTaskID, IPD_GET_PRICING_INFO_EVT, IPD_GET_PRICING_INFO_PERIOD );
  498. }
  499. #endif
  500. // Per smart energy spec end device polling requirement of not to poll < 7.5 seconds.
  501. NLME_SetPollRate ( SE_DEVICE_POLL_RATE );
  502. }
  503. break;
  504. #if defined( ZCL_KEY_ESTABLISH )
  505. case ZCL_KEY_ESTABLISH_IND:
  506. if ((MSGpkt->hdr.status) == TermKeyStatus_Success)
  507. {
  508. cId_t otaCluster = ZCL_CLUSTER_ID_OTA;
  509. zAddrType_t dstAddr;
  510. // Send out a match for the ota cluster
  511. dstAddr.addrMode = AddrBroadcast;
  512. dstAddr.addr.shortAddr = NWK_BROADCAST_SHORTADDR;
  513. ZDP_MatchDescReq( &dstAddr, NWK_BROADCAST_SHORTADDR, ZCL_SE_PROFILE_ID,
  514. 1, &otaCluster, 0, NULL, FALSE );
  515. osal_start_timerEx( ipdTaskID, IPD_GET_PRICING_INFO_EVT, IPD_GET_PRICING_INFO_PERIOD );
  516. ipdOtaState = IPD_OTA_IDLE_STATE;
  517. }
  518. break;
  519. #endif
  520. default:
  521. break;
  522. }
  523. // Release the memory
  524. osal_msg_deallocate( (uint8 *)MSGpkt );
  525. }
  526. // return unprocessed events
  527. return (events ^ SYS_EVENT_MSG);
  528. }
  529. // event to intiate key establishment request
  530. if ( events & IPD_KEY_ESTABLISHMENT_REQUEST_EVT )
  531. {
  532. #if ZCL_KEY_ESTABLISH
  533. zclGeneral_KeyEstablish_InitiateKeyEstablishment(ipdTaskID, &ESPAddr, ipdTransID);
  534. #endif
  535. return ( events ^ IPD_KEY_ESTABLISHMENT_REQUEST_EVT );
  536. }
  537. // event to get current price
  538. if ( events & IPD_GET_PRICING_INFO_EVT )
  539. {
  540. zclSE_Pricing_Send_GetCurrentPrice( IPD_ENDPOINT, &ESPAddr, option, TRUE, 0 );
  541. osal_start_timerEx( ipdTaskID, IPD_GET_PRICING_INFO_EVT, IPD_GET_PRICING_INFO_PERIOD );
  542. return ( events ^ IPD_GET_PRICING_INFO_EVT );
  543. }
  544. // handle processing of identify timeout event triggered by an identify command
  545. if ( events & IPD_IDENTIFY_TIMEOUT_EVT )
  546. {
  547. if ( ipdIdentifyTime > 0 )
  548. {
  549. ipdIdentifyTime--;
  550. }
  551. ipd_ProcessIdentifyTimeChange();
  552. return ( events ^ IPD_IDENTIFY_TIMEOUT_EVT );
  553. }
  554. // event to get current time
  555. if ( events & IPD_UPDATE_TIME_EVT )
  556. {
  557. ipdTime = osal_getClock();
  558. osal_start_timerEx( ipdTaskID, IPD_UPDATE_TIME_EVT, IPD_UPDATE_TIME_PERIOD );
  559. return ( events ^ IPD_UPDATE_TIME_EVT );
  560. }
  561. // Discard unknown events
  562. return 0;
  563. }
  564. /*********************************************************************
  565. * @fn ipd_ProcessZDOMsgs
  566. *
  567. * @brief Called to process callbacks from the ZDO.
  568. *
  569. * @param none
  570. *
  571. * @return none
  572. */
  573. static void ipd_ProcessZDOMsgs( zdoIncomingMsg_t *pMsg )
  574. {
  575. // make sure message comes from TC to initiate Key Establishment
  576. if ((pMsg->clusterID == Match_Desc_rsp) &&
  577. (pMsg->srcAddr.addr.shortAddr == zgTrustCenterAddr))
  578. {
  579. ZDO_ActiveEndpointRsp_t *pRsp = ZDO_ParseEPListRsp( pMsg );
  580. if (pRsp)
  581. {
  582. switch (ipdOtaState)
  583. {
  584. case IPD_OTA_CBKE_STATE:
  585. if (pRsp->cnt)
  586. {
  587. // Record the trust center
  588. ESPAddr.endPoint = pRsp->epList[0];
  589. ESPAddr.addr.shortAddr = pMsg->srcAddr.addr.shortAddr;
  590. // send out key establishment request
  591. osal_set_event( ipdTaskID, IPD_KEY_ESTABLISHMENT_REQUEST_EVT);
  592. }
  593. break;
  594. case IPD_OTA_IDLE_STATE:
  595. // If we get a match, initiate download. A message will be sent to our task
  596. // indicating the result of the download.
  597. ipdOtaState = IPD_OTA_DL_STATE;
  598. // Request the IEEE address of the server to put into the
  599. // ATTRID_UPGRADE_SERVER_ID attribute
  600. ZDP_IEEEAddrReq(pMsg->srcAddr.addr.shortAddr, ZDP_ADDR_REQTYPE_SINGLE, 0, 0);
  601. // Add the match to a list. If the current download fails, then we can
  602. // try this new device.
  603. ipd_AddServer(pRsp->nwkAddr, pRsp->epList[0]);
  604. zclOTA_RequestNextUpdate(pRsp->nwkAddr, pRsp->epList[0]);
  605. break;
  606. case IPD_OTA_DL_STATE:
  607. // Add the match to a list. If the current download fails, then we can
  608. // try this new device.
  609. ipd_AddServer(pRsp->nwkAddr, pRsp->epList[0]);
  610. break;
  611. default:
  612. break;
  613. }
  614. osal_mem_free(pRsp);
  615. }
  616. }
  617. }
  618. /*********************************************************************
  619. * @fn ipd_ProcessOTAMsgs
  620. *
  621. * @brief Called to process callbacks from the ZCL OTA.
  622. *
  623. * @param none
  624. *
  625. * @return none
  626. */
  627. static void ipd_ProcessOTAMsgs( zclOTA_CallbackMsg_t* pMsg )
  628. {
  629. switch(pMsg->ota_event)
  630. {
  631. case ZCL_OTA_START_CALLBACK:
  632. if (pMsg->hdr.status == ZSuccess)
  633. {
  634. // Stop the price event
  635. osal_stop_timerEx(ipdTaskID, IPD_GET_PRICING_INFO_EVT);
  636. // Speed up the poll rate
  637. NLME_SetPollRate(SE_OTA_POLL_RATE);
  638. ipdOtaState = IPD_OTA_IDLE_STATE;
  639. }
  640. else
  641. {
  642. uint16 addr;
  643. uint8 endpoint = 0;
  644. // The server was not authorized to send us an image.
  645. // See if another server responded
  646. ipd_PopServer(&addr, &endpoint);
  647. if (endpoint != 0)
  648. {
  649. ipdOtaState = IPD_OTA_DL_STATE;
  650. zclOTA_RequestNextUpdate(addr, endpoint);
  651. }
  652. else
  653. {
  654. ipdOtaState = IPD_OTA_IDLE_STATE;
  655. }
  656. }
  657. break;
  658. case ZCL_OTA_DL_COMPLETE_CALLBACK:
  659. if (pMsg->hdr.status == ZSuccess)
  660. {
  661. // Reset the CRC Shadow and reboot. The bootloader will see the
  662. // CRC shadow has been cleared and switch to the new image
  663. HalOTAInvRC();
  664. SystemReset();
  665. }
  666. else
  667. {
  668. // slow the poll rate back down.
  669. NLME_SetPollRate(SE_DEVICE_POLL_RATE);
  670. // Restart the pricing
  671. osal_start_timerEx( ipdTaskID, IPD_GET_PRICING_INFO_EVT, IPD_GET_PRICING_INFO_PERIOD );
  672. }
  673. break;
  674. default:
  675. break;
  676. }
  677. }
  678. /*********************************************************************
  679. * @fn ipd_AddServer
  680. *
  681. * @brief Adds an OTA server discovered by the match descriptor on
  682. * the OTA cluster.
  683. *
  684. * @param none
  685. *
  686. * @return none
  687. */
  688. static void ipd_AddServer( uint16 addr, uint8 endpoint )
  689. {
  690. int8 i;
  691. for (i=0; i<IPD_OTA_MAX_SERVERS; i++)
  692. {
  693. if (ipdServerList[i].endpoint == 0)
  694. {
  695. // Add the entry
  696. ipdServerList[i].endpoint = endpoint;
  697. ipdServerList[i].addr = addr;
  698. return;
  699. }
  700. }
  701. }
  702. /*********************************************************************
  703. * @fn ipd_PopServer
  704. *
  705. * @brief Pops an OTA server discovered by the match descriptor on
  706. * the OTA cluster from the list.
  707. *
  708. * @param none
  709. *
  710. * @return none
  711. */
  712. static void ipd_PopServer( uint16 *addr, uint8 *endpoint )
  713. {
  714. int8 i;
  715. for (i=0; i<IPD_OTA_MAX_SERVERS; i++)
  716. {
  717. if (ipdServerList[i].endpoint != 0)
  718. {
  719. // Get the addr and endpoint
  720. *endpoint = ipdServerList[i].endpoint;
  721. *addr = ipdServerList[i].addr;
  722. //Indicate the entry is not in use
  723. ipdServerList[i].endpoint = 0;
  724. return;
  725. }
  726. }
  727. }
  728. /*********************************************************************
  729. * @fn ipd_ProcessIdentifyTimeChange
  730. *
  731. * @brief Called to blink led for specified IdentifyTime attribute value
  732. *
  733. * @param none
  734. *
  735. * @return none
  736. */
  737. static void ipd_ProcessIdentifyTimeChange( void )
  738. {
  739. if ( ipdIdentifyTime > 0 )
  740. {
  741. osal_start_timerEx( ipdTaskID, IPD_IDENTIFY_TIMEOUT_EVT, 1000 );
  742. HalLedBlink ( HAL_LED_4, 0xFF, HAL_LED_DEFAULT_DUTY_CYCLE, HAL_LED_DEFAULT_FLASH_TIME );
  743. }
  744. else
  745. {
  746. HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
  747. osal_stop_timerEx( ipdTaskID, IPD_IDENTIFY_TIMEOUT_EVT );
  748. }
  749. }
  750. #if SECURE
  751. /*********************************************************************
  752. * @fn ipd_KeyEstablish_ReturnLinkKey
  753. *
  754. * @brief This function get the requested link key
  755. *
  756. * @param shortAddr - short address of the partner.
  757. *
  758. * @return none
  759. */
  760. static uint8 ipd_KeyEstablish_ReturnLinkKey( uint16 shortAddr )
  761. {
  762. uint8 status = ZFailure;
  763. AddrMgrEntry_t entry;
  764. // Look up the long address of the device
  765. entry.user = ADDRMGR_USER_DEFAULT;
  766. entry.nwkAddr = shortAddr;
  767. if ( AddrMgrEntryLookupNwk( &entry ) )
  768. {
  769. // check if APS link key has been established
  770. if ( APSME_IsLinkKeyValid( entry.extAddr ) == TRUE )
  771. {
  772. status = ZSuccess;
  773. }
  774. }
  775. else
  776. {
  777. // It's an unknown device
  778. status = ZInvalidParameter;
  779. }
  780. return status;
  781. }
  782. #endif
  783. /*********************************************************************
  784. * @fn ipd_HandleKeys
  785. *
  786. * @brief Handles all key events for this device.
  787. *
  788. * @param shift - true if in shift/alt.
  789. * @param keys - bit field for key events. Valid entries:
  790. * HAL_KEY_SW_4
  791. * HAL_KEY_SW_3
  792. * HAL_KEY_SW_2
  793. * HAL_KEY_SW_1
  794. *
  795. * @return none
  796. */
  797. static void ipd_HandleKeys( uint8 shift, uint8 keys )
  798. {
  799. // Shift is used to make each button/switch dual purpose.
  800. if ( shift )
  801. {
  802. if ( keys & HAL_KEY_SW_1 )
  803. {
  804. }
  805. if ( keys & HAL_KEY_SW_2 )
  806. {
  807. }
  808. if ( keys & HAL_KEY_SW_3 )
  809. {
  810. }
  811. if ( keys & HAL_KEY_SW_4 )
  812. {
  813. }
  814. }
  815. else
  816. {
  817. if ( keys & HAL_KEY_SW_1 )
  818. {
  819. ZDOInitDevice(0); // join the network
  820. }
  821. if ( keys & HAL_KEY_SW_2 )
  822. {
  823. #if defined( INTER_PAN )
  824. uint8 x = TRUE;
  825. ZMacGetReq( ZMacRxOnIdle, &rxOnIdle );
  826. ZMacSetReq( ZMacRxOnIdle, &x );
  827. afAddrType_t dstAddr;
  828. uint8 option = 1;
  829. // Send a request for public pricing information using the INTERP-DATA SAP.
  830. // The request is sent as a broadcast to all PANs within the discovered
  831. // channel. Receiving devices that implement the INTRP-DATA SAP will process
  832. // it and, if any such device is able to respond, it will respond directly
  833. // to the requestor. After receiving at least one response the requestor may
  834. // store the PAN ID and device address of one or more responders so that it
  835. // may query them directly in future.
  836. dstAddr.addrMode = afAddrBroadcast;
  837. dstAddr.addr.shortAddr = NWK_BROADCAST_SHORTADDR_DEVALL;
  838. dstAddr.endPoint = STUBAPS_INTER_PAN_EP;
  839. dstAddr.panId = 0xFFFF;
  840. zclSE_Pricing_Send_GetCurrentPrice( IPD_ENDPOINT, &dstAddr, option, TRUE, 0 );
  841. #endif
  842. }
  843. if ( keys & HAL_KEY_SW_3 )
  844. {
  845. }
  846. if ( keys & HAL_KEY_SW_4 )
  847. {
  848. }
  849. }
  850. }
  851. /*********************************************************************
  852. * @fn ipd_ValidateAttrDataCB
  853. *
  854. * @brief Check to see if the supplied value for the attribute data
  855. * is within the specified range of the attribute.
  856. *
  857. * @param pAttr - pointer to attribute
  858. * @param pAttrInfo - pointer to attribute info
  859. *
  860. * @return TRUE if data valid. FALSE otherwise.
  861. */
  862. static uint8 ipd_ValidateAttrDataCB( zclAttrRec_t *pAttr, zclWriteRec_t *pAttrInfo )
  863. {
  864. uint8 valid = TRUE;
  865. switch ( pAttrInfo->dataType )
  866. {
  867. case ZCL_DATATYPE_BOOLEAN:
  868. if ( ( *(pAttrInfo->attrData) != 0 ) && ( *(pAttrInfo->attrData) != 1 ) )
  869. valid = FALSE;
  870. break;
  871. default:
  872. break;
  873. }
  874. return ( valid );
  875. }
  876. /*********************************************************************
  877. * @fn ipd_BasicResetCB
  878. *
  879. * @brief Callback from the ZCL General Cluster Library to set all
  880. * the attributes of all the clusters to their factory defaults
  881. *
  882. * @param none
  883. *
  884. * @return none
  885. */
  886. static void ipd_BasicResetCB( void )
  887. {
  888. // user should handle setting attributes to factory defaults here
  889. }
  890. /*********************************************************************
  891. * @fn ipd_IdentifyCB
  892. *
  893. * @brief Callback from the ZCL General Cluster Library when
  894. * it received an Identity Command for this application.
  895. *
  896. * @param pCmd - pointer to structure for Identify command
  897. *
  898. * @return none
  899. */
  900. static void ipd_IdentifyCB( zclIdentify_t *pCmd )
  901. {
  902. ipdIdentifyTime = pCmd->identifyTime;
  903. ipd_ProcessIdentifyTimeChange();
  904. }
  905. /*********************************************************************
  906. * @fn ipd_IdentifyQueryRspCB
  907. *
  908. * @brief Callback from the ZCL General Cluster Library when
  909. * it received an Identity Query Response Command for this application.
  910. *
  911. * @param pRsp - pointer to structure for Identity Query Response command
  912. *
  913. * @return none
  914. */
  915. static void ipd_IdentifyQueryRspCB( zclIdentifyQueryRsp_t *pRsp )
  916. {
  917. // add user code here
  918. }
  919. /*********************************************************************
  920. * @fn ipd_AlarmCB
  921. *
  922. * @brief Callback from the ZCL General Cluster Library when
  923. * it received an Alarm request or response command for
  924. * this application.
  925. *
  926. * @param pAlarm - pointer to structure for Alarm command
  927. *
  928. * @return none
  929. */
  930. static void ipd_AlarmCB( zclAlarm_t *pAlarm )
  931. {
  932. // add user code here
  933. }
  934. #ifdef SE_UK_EXT
  935. /*********************************************************************
  936. * @fn ipd_GetEventLogCB
  937. *
  938. * @brief Callback from the ZCL General Cluster Library when
  939. * it received a Get Event Log command for this
  940. * application.
  941. *
  942. * @param srcEP - source endpoint
  943. * @param srcAddr - pointer to source address
  944. * @param pEventLog - pointer to structure for Get Event Log command
  945. * @param seqNum - sequence number of this command
  946. *
  947. * @return none
  948. */
  949. static void ipd_GetEventLogCB( uint8 srcEP, afAddrType_t *srcAddr,
  950. zclGetEventLog_t *pEventLog, uint8 seqNum )
  951. {
  952. // add user code here, which could fragment the event log payload if
  953. // the entire payload doesn't fit into one Publish Event Log Command.
  954. // Note: the Command Index starts at 0 and is incremented for each
  955. // fragment belonging to the same command.
  956. // There's no event log for now! The Metering Device will support
  957. // logging for all events configured to do so.
  958. }
  959. /*********************************************************************
  960. * @fn ipd_PublishEventLogCB
  961. *
  962. * @brief Callback from the ZCL General Cluster Library when
  963. * it received a Publish Event Log command for this
  964. * application.
  965. *
  966. * @param srcAddr - pointer to source address
  967. * @param pEventLog - pointer to structure for Publish Event Log command
  968. *
  969. * @return none
  970. */
  971. static void ipd_PublishEventLogCB( afAddrType_t *srcAddr, zclPublishEventLog_t *pEventLog )
  972. {
  973. // add user code here
  974. }
  975. #endif // SE_UK_EXT
  976. /*********************************************************************
  977. * @fn ipd_GetCurrentPriceCB
  978. *
  979. * @brief Callback from the ZCL SE Profile Pricing Cluster Library when
  980. * it received a Get Current Price for
  981. * this application.
  982. *
  983. * @param pCmd - pointer to structure for Get Current Price command
  984. * @param srcAddr - pointer to source address
  985. * @param seqNum - sequence number for this command
  986. *
  987. * @return none
  988. */
  989. static void ipd_GetCurrentPriceCB( zclCCGetCurrentPrice_t *pCmd,
  990. afAddrType_t *srcAddr, uint8 seqNum )
  991. {
  992. #if defined ( ZCL_PRICING )
  993. // On receipt of Get Current Price command, the device shall send a
  994. // Publish Price command with the information for the current time.
  995. zclCCPublishPrice_t cmd;
  996. osal_memset( &cmd, 0, sizeof( zclCCPublishPrice_t ) );
  997. cmd.providerId = 0xbabeface;
  998. cmd.numberOfPriceTiers = 0xfe;
  999. zclSE_Pricing_Send_PublishPrice( IPD_ENDPOINT, srcAddr, &cmd, FALSE, seqNum );
  1000. #endif // ZCL_PRICING
  1001. }
  1002. /*********************************************************************
  1003. * @fn ipd_GetScheduledPriceCB
  1004. *
  1005. * @brief Callback from the ZCL SE Profile Pricing Cluster Library when
  1006. * it received a Get Scheduled Price for
  1007. * this application.
  1008. *
  1009. * @param pCmd - pointer to structure for Get Scheduled Price command
  1010. * @param srcAddr - pointer to source address
  1011. * @param seqNum - sequence number for this command
  1012. *
  1013. * @return none
  1014. */
  1015. static void ipd_GetScheduledPriceCB( zclCCGetScheduledPrice_t *pCmd,
  1016. afAddrType_t *srcAddr, uint8 seqNum )
  1017. {
  1018. // On receipt of Get Scheduled Price command, the device shall send a
  1019. // Publish Price command for all currently scheduled price events.
  1020. // The sample code as follows only sends one.
  1021. #if defined ( ZCL_PRICING )
  1022. zclCCPublishPrice_t cmd;
  1023. osal_memset( &cmd, 0, sizeof( zclCCPublishPrice_t ) );
  1024. cmd.providerId = 0xbabeface;
  1025. cmd.numberOfPriceTiers = 0xfe;
  1026. zclSE_Pricing_Send_PublishPrice( IPD_ENDPOINT, srcAddr, &cmd, FALSE, seqNum );
  1027. #endif // ZCL_PRICING
  1028. }
  1029. /*********************************************************************
  1030. * @fn ipd_PublishPriceCB
  1031. *
  1032. * @brief Callback from the ZCL SE Profile Pricing Cluster Library when
  1033. * it received a Publish Price for this application.
  1034. *
  1035. * @param pCmd - pointer to structure for Publish Price command
  1036. * @param srcAddr - pointer to source address
  1037. * @param seqNum - sequence number for this command
  1038. *
  1039. * @return none
  1040. */
  1041. static void ipd_PublishPriceCB( zclCCPublishPrice_t *pCmd,
  1042. afAddrType_t *srcAddr, uint8 seqNum )
  1043. {
  1044. if ( pCmd )
  1045. {
  1046. // display Provider ID field
  1047. HalLcdWriteString("Provider ID", HAL_LCD_LINE_1);
  1048. HalLcdWriteValue( pCmd->providerId, 10, HAL_LCD_LINE_2 );
  1049. }
  1050. #if defined ( INTER_PAN )
  1051. ZMacSetReq( ZMacRxOnIdle, &rxOnIdle ); // set receiver on when idle flag to FALSE
  1052. // after getting publish price command via INTER-PAN
  1053. #endif
  1054. }
  1055. /*********************************************************************
  1056. * @fn ipd_DisplayMessageCB
  1057. *
  1058. * @brief Callback from the ZCL SE Profile Message Cluster Library when
  1059. * it received a Display Message Command for
  1060. * this application.
  1061. *
  1062. * @param pCmd - pointer to structure for Display Message command
  1063. * @param srcAddr - pointer to source address
  1064. * @param seqNum - sequence number for this command
  1065. *
  1066. * @return none
  1067. */
  1068. static void ipd_DisplayMessageCB( zclCCDisplayMessage_t *pCmd,
  1069. afAddrType_t *srcAddr, uint8 seqNum )
  1070. {
  1071. // Upon receipt of the Display Message Command, the device shall
  1072. // display the message. If the Message Confirmation bit indicates
  1073. // the message originator require a confirmation of receipt from
  1074. // a Utility Customer, the device should display the message or
  1075. // alert the user until it is either confirmed via a button or by
  1076. // selecting a confirmation option on the device. Confirmation is
  1077. // typically used when the Utility is sending down information
  1078. // such as a disconnection notice, or prepaid billing information.
  1079. // Message duration is ignored when confirmation is requested and
  1080. // the message is displayed until confirmed.
  1081. #if defined ( LCD_SUPPORTED )
  1082. // Allowing that strings have a non-printing '\0' terminator.
  1083. if (pCmd->msgString.strLen <= HAL_LCD_MAX_CHARS+1)
  1084. {
  1085. HalLcdWriteString((char*)pCmd->msgString.pStr, HAL_LCD_LINE_3);
  1086. }
  1087. else
  1088. {
  1089. // Allow 3 digit message remainder size and space; and the ellipse ("...") plus the plus ("+"):
  1090. const uint8 left = HAL_LCD_MAX_CHARS - 4 - 4;
  1091. uint8 buf[HAL_LCD_MAX_CHARS];
  1092. (void)osal_memcpy(buf, pCmd->msgString.pStr, left);
  1093. (void)osal_memcpy(buf+left, "...+\0", 5); // Copy the "end-of-string" delimiter.
  1094. HalLcdWriteStringValue((char *)buf, pCmd->msgString.strLen-left, 10, HAL_LCD_LINE_3);
  1095. }
  1096. #endif // LCD_SUPPORTED
  1097. }
  1098. /*********************************************************************
  1099. * @fn ipd_CancelMessageCB
  1100. *
  1101. * @brief Callback from the ZCL SE Profile Message Cluster Library when
  1102. * it received a Cancel Message Command for
  1103. * this application.
  1104. *
  1105. * @param pCmd - pointer to structure for Cancel Message command
  1106. * @param srcAddr - pointer to source address
  1107. * @param seqNum - sequence number for this command
  1108. *
  1109. * @return none
  1110. */
  1111. static void ipd_CancelMessageCB( zclCCCancelMessage_t *pCmd,
  1112. afAddrType_t *srcAddr, uint8 seqNum )
  1113. {
  1114. // add user code here
  1115. }
  1116. /*********************************************************************
  1117. * @fn ipd_GetLastMessageCB
  1118. *
  1119. * @brief Callback from the ZCL SE Profile Message Cluster Library when
  1120. * it received a Get Last Message Command for
  1121. * this application.
  1122. *
  1123. * @param pCmd - pointer to structure for Get Last Message command
  1124. * @param srcAddr - pointer to source address
  1125. * @param seqNum - sequence number for this command
  1126. *
  1127. * @return none
  1128. */
  1129. static void ipd_GetLastMessageCB( afAddrType_t *srcAddr, uint8 seqNum )
  1130. {
  1131. // On receipt of Get Last Message command, the device shall send a
  1132. // Display Message command back to the sender
  1133. #if defined ( ZCL_MESSAGE )
  1134. zclCCDisplayMessage_t cmd;
  1135. uint8 msg[10] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29 };
  1136. // Fill in the command with information for the last message
  1137. cmd.messageId = 0xaabbccdd;
  1138. cmd.messageCtrl.transmissionMode = 0;
  1139. cmd.messageCtrl.importance = 1;
  1140. cmd.messageCtrl.confirmationRequired = 1;
  1141. cmd.durationInMinutes = 60;
  1142. cmd.msgString.strLen = 10;
  1143. cmd.msgString.pStr = msg;
  1144. zclSE_Message_Send_DisplayMessage( IPD_ENDPOINT, srcAddr, &cmd,
  1145. FALSE, seqNum );
  1146. #endif // ZCL_MESSAGE
  1147. }
  1148. /*********************************************************************
  1149. * @fn ipd_MessageConfirmationCB
  1150. *
  1151. * @brief Callback from the ZCL SE Profile Message Cluster Library when
  1152. * it received a Message Confirmation Command for
  1153. * this application.
  1154. *
  1155. * @param pCmd - pointer to structure for Message Confirmation command
  1156. * @param srcAddr - pointer to source address
  1157. * @param seqNum - sequence number for this command
  1158. *
  1159. * @return none
  1160. */
  1161. static void ipd_MessageConfirmationCB( zclCCMessageConfirmation_t *pCmd,
  1162. afAddrType_t *srcAddr, uint8 seqNum)
  1163. {
  1164. // add user code here
  1165. }
  1166. #if defined ( SE_UK_EXT )
  1167. /*********************************************************************
  1168. * @fn ipd_PublishTariffInformationCB
  1169. *
  1170. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1171. * it received a Publish Tariff Information for this application.
  1172. *
  1173. * @param pCmd - pointer to structure for Publish Tariff Information command
  1174. * @param srcAddr - pointer to source address
  1175. * @param seqNum - sequence number of this command
  1176. *
  1177. * @return none
  1178. */
  1179. static void ipd_PublishTariffInformationCB( zclCCPublishTariffInformation_t *pCmd,
  1180. afAddrType_t *srcAddr, uint8 seqNum )
  1181. {
  1182. // add user code here
  1183. }
  1184. /*********************************************************************
  1185. * @fn ipd_PublishPriceMatrixCB
  1186. *
  1187. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1188. * it received a Publish Price Matrix for this application.
  1189. *
  1190. * @param pCmd - pointer to structure for Publish Price Matrix command
  1191. * @param srcAddr - pointer to source address
  1192. * @param seqNum - sequence number of this command
  1193. *
  1194. * @return none
  1195. */
  1196. static void ipd_PublishPriceMatrixCB( zclCCPublishPriceMatrix_t *pCmd,
  1197. afAddrType_t *srcAddr, uint8 seqNum )
  1198. {
  1199. // add user code here
  1200. }
  1201. /*********************************************************************
  1202. * @fn ipd_PublishBlockThresholdsCB
  1203. *
  1204. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1205. * it received a Publish Block Thresholds for this application.
  1206. *
  1207. * @param pCmd - pointer to structure for Publish Block Thresholds command
  1208. * @param srcAddr - pointer to source address
  1209. * @param seqNum - sequence number of this command
  1210. *
  1211. * @return none
  1212. */
  1213. static void ipd_PublishBlockThresholdsCB( zclCCPublishBlockThresholds_t *pCmd,
  1214. afAddrType_t *srcAddr, uint8 seqNum )
  1215. {
  1216. // add user code here
  1217. }
  1218. /*********************************************************************
  1219. * @fn ipd_PublishConversionFactorCB
  1220. *
  1221. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1222. * it received a Publish Conversion Factor for this application.
  1223. *
  1224. * @param pCmd - pointer to structure for Publish Conversion Factor command
  1225. * @param srcAddr - pointer to source address
  1226. * @param seqNum - sequence number of this command
  1227. *
  1228. * @return none
  1229. */
  1230. static void ipd_PublishConversionFactorCB( zclCCPublishConversionFactor_t *pCmd,
  1231. afAddrType_t *srcAddr, uint8 seqNum )
  1232. {
  1233. // add user code here
  1234. }
  1235. /*********************************************************************
  1236. * @fn ipd_PublishCalorificValueCB
  1237. *
  1238. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1239. * it received a Publish Calorific Value for this application.
  1240. *
  1241. * @param pCmd - pointer to structure for Publish Calorific Value command
  1242. * @param srcAddr - pointer to source address
  1243. * @param seqNum - sequence number of this command
  1244. *
  1245. * @return none
  1246. */
  1247. static void ipd_PublishCalorificValueCB( zclCCPublishCalorificValue_t *pCmd,
  1248. afAddrType_t *srcAddr, uint8 seqNum )
  1249. {
  1250. // add user code here
  1251. }
  1252. /*********************************************************************
  1253. * @fn ipd_PublishCO2ValueCB
  1254. *
  1255. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1256. * it received a Publish CO2 Value for this application.
  1257. *
  1258. * @param pCmd - pointer to structure for Publish CO2 Value command
  1259. * @param srcAddr - pointer to source address
  1260. * @param seqNum - sequence number of this command
  1261. *
  1262. * @return none
  1263. */
  1264. static void ipd_PublishCO2ValueCB( zclCCPublishCO2Value_t *pCmd,
  1265. afAddrType_t *srcAddr, uint8 seqNum )
  1266. {
  1267. // add user code here
  1268. }
  1269. /*********************************************************************
  1270. * @fn ipd_PublishCPPEventCB
  1271. *
  1272. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1273. * it received a Publish CPP Event for this application.
  1274. *
  1275. * @param pCmd - pointer to structure for Publish CPP Event command
  1276. * @param srcAddr - pointer to source address
  1277. * @param seqNum - sequence number of this command
  1278. *
  1279. * @return none
  1280. */
  1281. static void ipd_PublishCPPEventCB( zclCCPublishCPPEvent_t *pCmd,
  1282. afAddrType_t *srcAddr, uint8 seqNum )
  1283. {
  1284. // add user code here
  1285. }
  1286. /*********************************************************************
  1287. * @fn ipd_PublishBillingPeriodCB
  1288. *
  1289. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1290. * it received a Publish Billing Period for this application.
  1291. *
  1292. * @param pCmd - pointer to structure for Publish Billing Period command
  1293. * @param srcAddr - pointer to source address
  1294. * @param seqNum - sequence number of this command
  1295. *
  1296. * @return none
  1297. */
  1298. static void ipd_PublishBillingPeriodCB( zclCCPublishBillingPeriod_t *pCmd,
  1299. afAddrType_t *srcAddr, uint8 seqNum )
  1300. {
  1301. // add user code here
  1302. }
  1303. /*********************************************************************
  1304. * @fn ipd_PublishConsolidatedBillCB
  1305. *
  1306. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1307. * it received a Publish Consolidated Bill for this application.
  1308. *
  1309. * @param pCmd - pointer to structure for Publish Consolidated Bill command
  1310. * @param srcAddr - pointer to source address
  1311. * @param seqNum - sequence number of this command
  1312. *
  1313. * @return none
  1314. */
  1315. static void ipd_PublishConsolidatedBillCB( zclCCPublishConsolidatedBill_t *pCmd,
  1316. afAddrType_t *srcAddr, uint8 seqNum )
  1317. {
  1318. // add user code here
  1319. }
  1320. /*********************************************************************
  1321. * @fn ipd_PublishCreditPaymentInfoCB
  1322. *
  1323. * @brief Callback from the ZCL SE Profile Price Cluster Library when
  1324. * it received a Publish Credit Payment Info for this application.
  1325. *
  1326. * @param pCmd - pointer to structure for Publish Credit Payment Info command
  1327. * @param srcAddr - pointer to source address
  1328. * @param seqNum - sequence number of this command
  1329. *
  1330. * @return none
  1331. */
  1332. static void ipd_PublishCreditPaymentInfoCB( zclCCPublishCreditPaymentInfo_t *pCmd,
  1333. afAddrType_t *srcAddr, uint8 seqNum )
  1334. {
  1335. // add user code here
  1336. }
  1337. /*********************************************************************
  1338. * @fn ipd_GetPrepaySnapshotResponseCB
  1339. *
  1340. * @brief Callback from the ZCL SE Profile Prepayment Cluster Library when
  1341. * it received a Get Prepay Snapshot Response for this application.
  1342. *
  1343. * @param pCmd - pointer to structure for Get Prepay Snapshot Response command
  1344. * @param srcAddr - pointer to source address
  1345. * @param seqNum - sequence number of this command
  1346. *
  1347. * @return none
  1348. */
  1349. static void ipd_GetPrepaySnapshotResponseCB( zclCCGetPrepaySnapshotResponse_t *pCmd,
  1350. afAddrType_t *srcAddr, uint8 seqNum )
  1351. {
  1352. // add user code here
  1353. }
  1354. /*********************************************************************
  1355. * @fn ipd_ChangePaymentModeResponseCB
  1356. *
  1357. * @brief Callback from the ZCL SE Profile Prepayment Cluster Library when
  1358. * it received a Change Payment Mode Response for this application.
  1359. *
  1360. * @param pCmd - pointer to structure for Change Payment Mode Response command
  1361. * @param srcAddr - pointer to source address
  1362. * @param seqNum - sequence number of this command
  1363. *
  1364. * @return none
  1365. */
  1366. static void ipd_ChangePaymentModeResponseCB( zclCCChangePaymentModeResponse_t *pCmd,
  1367. afAddrType_t *srcAddr, uint8 seqNum )
  1368. {
  1369. // add user code here
  1370. }
  1371. /*********************************************************************
  1372. * @fn ipd_ConsumerTopupResponseCB
  1373. *
  1374. * @brief Callback from the ZCL SE Profile Prepayment Cluster Library when
  1375. * it received a Consumer Topup Response for this application.
  1376. *
  1377. * @param pCmd - pointer to structure for Consumer Topup Response command
  1378. * @param srcAddr - pointer to source address
  1379. * @param seqNum - sequence number of this command
  1380. *
  1381. * @return none
  1382. */
  1383. static void ipd_ConsumerTopupResponseCB( zclCCConsumerTopupResponse_t *pCmd,
  1384. afAddrType_t *srcAddr, uint8 seqNum )
  1385. {
  1386. // add user code here
  1387. }
  1388. /*********************************************************************
  1389. * @fn ipd_GetCommandsCB
  1390. *
  1391. * @brief Callback from the ZCL SE Profile Prepayment Cluster Library when
  1392. * it received a Get Commands for this application.
  1393. *
  1394. * @param prepayNotificationFlags - prepayment notification flags
  1395. * @param srcAddr - pointer to source address
  1396. * @param seqNum - sequence number of this command
  1397. *
  1398. * @return none
  1399. */
  1400. static void ipd_GetCommandsCB( uint8 prepayNotificationFlags,
  1401. afAddrType_t *srcAddr, uint8 seqNum )
  1402. {
  1403. // add user code here
  1404. }
  1405. /*********************************************************************
  1406. * @fn ipd_PublishTopupLogCB
  1407. *
  1408. * @brief Callback from the ZCL SE Profile Prepayment Cluster Library when
  1409. * it received a Publish Topup Log for this application.
  1410. *
  1411. * @param pCmd - pointer to structure for Publish Topup Log command
  1412. * @param srcAddr - pointer to source address
  1413. * @param seqNum - sequence number of this command
  1414. *
  1415. * @return none
  1416. */
  1417. static void ipd_PublishTopupLogCB( zclCCPublishTopupLog_t *pCmd,
  1418. afAddrType_t *srcAddr, uint8 seqNum )
  1419. {
  1420. // add user code here
  1421. }
  1422. /*********************************************************************
  1423. * @fn ipd_PublishDebtLogCB
  1424. *
  1425. * @brief Callback from the ZCL SE Profile Prepayment Cluster Library when
  1426. * it received a Publish Debt Log for this application.
  1427. *
  1428. * @param pCmd - pointer to structure for Publish Debt Log command
  1429. * @param srcAddr - pointer to source address
  1430. * @param seqNum - sequence number of this command
  1431. *
  1432. * @return none
  1433. */
  1434. static void ipd_PublishDebtLogCB( zclCCPublishDebtLog_t *pCmd,
  1435. afAddrType_t *srcAddr, uint8 seqNum )
  1436. {
  1437. // add user code here
  1438. }
  1439. #endif // SE_UK_EXT
  1440. /******************************************************************************
  1441. *
  1442. * Functions for processing ZCL Foundation incoming Command/Response messages
  1443. *
  1444. *****************************************************************************/
  1445. /*********************************************************************
  1446. * @fn ipd_ProcessZCLMsg
  1447. *
  1448. * @brief Process ZCL Foundation incoming message
  1449. *
  1450. * @param pInMsg - message to process
  1451. *
  1452. * @return none
  1453. */
  1454. static void ipd_ProcessZCLMsg( zclIncomingMsg_t *pInMsg )
  1455. {
  1456. switch ( pInMsg->zclHdr.commandID )
  1457. {
  1458. #if defined ( ZCL_READ )
  1459. case ZCL_CMD_READ_RSP:
  1460. ipd_ProcessInReadRspCmd( pInMsg );
  1461. break;
  1462. #endif // ZCL_READ
  1463. #if defined ( ZCL_WRITE )
  1464. case ZCL_CMD_WRITE_RSP:
  1465. ipd_ProcessInWriteRspCmd( pInMsg );
  1466. break;
  1467. #endif // ZCL_WRITE
  1468. case ZCL_CMD_DEFAULT_RSP:
  1469. ipd_ProcessInDefaultRspCmd( pInMsg );
  1470. break;
  1471. #if defined ( ZCL_DISCOVER )
  1472. case ZCL_CMD_DISCOVER_RSP:
  1473. ipd_ProcessInDiscRspCmd( pInMsg );
  1474. break;
  1475. #endif // ZCL_DISCOVER
  1476. default:
  1477. break;
  1478. }
  1479. if ( pInMsg->attrCmd != NULL )
  1480. {
  1481. // free the parsed command
  1482. osal_mem_free( pInMsg->attrCmd );
  1483. pInMsg->attrCmd = NULL;
  1484. }
  1485. }
  1486. #if defined ( ZCL_READ )
  1487. /*********************************************************************
  1488. * @fn ipd_ProcessInReadRspCmd
  1489. *
  1490. * @brief Process the "Profile" Read Response Command
  1491. *
  1492. * @param pInMsg - incoming message to process
  1493. *
  1494. * @return none
  1495. */
  1496. static uint8 ipd_ProcessInReadRspCmd( zclIncomingMsg_t *pInMsg )
  1497. {
  1498. zclReadRspCmd_t *readRspCmd;
  1499. uint8 i;
  1500. readRspCmd = (zclReadRspCmd_t *)pInMsg->attrCmd;
  1501. for (i = 0; i < readRspCmd->numAttr; i++)
  1502. {
  1503. // Notify the originator of the results of the original read attributes
  1504. // attempt and, for each successfull request, the value of the requested
  1505. // attribute
  1506. }
  1507. return TRUE;
  1508. }
  1509. #endif // ZCL_READ
  1510. #if defined ( ZCL_WRITE )
  1511. /*********************************************************************
  1512. * @fn ipd_ProcessInWriteRspCmd
  1513. *
  1514. * @brief Process the "Profile" Write Response Command
  1515. *
  1516. * @param pInMsg - incoming message to process
  1517. *
  1518. * @return none
  1519. */
  1520. static uint8 ipd_ProcessInWriteRspCmd( zclIncomingMsg_t *pInMsg )
  1521. {
  1522. zclWriteRspCmd_t *writeRspCmd;
  1523. uint8 i;
  1524. writeRspCmd = (zclWriteRspCmd_t *)pInMsg->attrCmd;
  1525. for (i = 0; i < writeRspCmd->numAttr; i++)
  1526. {
  1527. // Notify the device of the results of the its original write attributes
  1528. // command.
  1529. }
  1530. return TRUE;
  1531. }
  1532. #endif // ZCL_WRITE
  1533. /*********************************************************************
  1534. * @fn ipd_ProcessInDefaultRspCmd
  1535. *
  1536. * @brief Process the "Profile" Default Response Command
  1537. *
  1538. * @param pInMsg - incoming message to process
  1539. *
  1540. * @return TRUE or FALSE
  1541. */
  1542. static uint8 ipd_ProcessInDefaultRspCmd( zclIncomingMsg_t *pInMsg )
  1543. {
  1544. zclDefaultRspCmd_t *defaultRspCmd = (zclDefaultRspCmd_t *)pInMsg->attrCmd;
  1545. // Device is notified of the Default Response command.
  1546. if (defaultRspCmd->statusCode == ZCL_STATUS_ABORT)
  1547. {
  1548. zclOTA_ImageUpgradeStatus = OTA_STATUS_NORMAL;
  1549. // Notify the application task the upgrade stopped
  1550. zclOTA_CallbackMsg_t *pMsg;
  1551. pMsg = (zclOTA_CallbackMsg_t*) osal_msg_allocate(sizeof(zclOTA_CallbackMsg_t));
  1552. if (pMsg)
  1553. {
  1554. pMsg->hdr.event = ZCL_OTA_CALLBACK_IND;
  1555. pMsg->hdr.status = ZOtaAbort;
  1556. pMsg->ota_event = ZCL_OTA_DL_COMPLETE_CALLBACK;
  1557. osal_msg_send(ipdTaskID, (uint8*) pMsg);
  1558. }
  1559. }
  1560. if (defaultRspCmd->statusCode == ZCL_STATUS_NO_IMAGE_AVAILABLE)
  1561. {
  1562. // handle this case in the future
  1563. }
  1564. return TRUE;
  1565. }
  1566. #if defined ( ZCL_DISCOVER )
  1567. /*********************************************************************
  1568. * @fn ipd_ProcessInDiscRspCmd
  1569. *
  1570. * @brief Process the "Profile" Discover Response Command
  1571. *
  1572. * @param pInMsg - incoming message to process
  1573. *
  1574. * @return none
  1575. */
  1576. static uint8 ipd_ProcessInDiscRspCmd( zclIncomingMsg_t *pInMsg )
  1577. {
  1578. zclDiscoverRspCmd_t *discoverRspCmd;
  1579. uint8 i;
  1580. discoverRspCmd = (zclDiscoverRspCmd_t *)pInMsg->attrCmd;
  1581. for ( i = 0; i < discoverRspCmd->numAttr; i++ )
  1582. {
  1583. // Device is notified of the result of its attribute discovery command.
  1584. }
  1585. return TRUE;
  1586. }
  1587. #endif // ZCL_DISCOVER
  1588. /****************************************************************************
  1589. ****************************************************************************/