zcl_ota.c 71 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463
  1. /******************************************************************************
  2. Filename: zcl_ota.c
  3. Revised: $Date: 2011-07-18 05:10:28 -0700 (Mon, 18 Jul 2011) $
  4. Revision: $Revision: 26827 $
  5. Description: Zigbee Cluster Library - Over-the-Air Upgrade Cluster ( OTA )
  6. Copyright 2010-2011 Texas Instruments Incorporated. All rights reserved.
  7. IMPORTANT: Your use of this Software is limited to those specific rights
  8. granted under the terms of a software license agreement between the user
  9. who downloaded the software, his/her employer (which must be your employer)
  10. and Texas Instruments Incorporated (the "License"). You may not use this
  11. Software unless you agree to abide by the terms of the License. The License
  12. limits your use, and you acknowledge, that the Software may not be modified,
  13. copied or distributed unless embedded on a Texas Instruments microcontroller
  14. or used solely and exclusively in conjunction with a Texas Instruments radio
  15. frequency transceiver, which is integrated into your product. Other than for
  16. the foregoing purpose, you may not use, reproduce, copy, prepare derivative
  17. works of, modify, distribute, perform, display or sell this Software and/or
  18. its documentation for any purpose.
  19. YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
  20. PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
  21. INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
  22. NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
  23. TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
  24. NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
  25. LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
  26. INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
  27. OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
  28. OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
  29. (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
  30. Should you have any questions regarding your right to use this Software,
  31. contact Texas Instruments Incorporated at www.TI.com.
  32. ******************************************************************************/
  33. /******************************************************************************
  34. * INCLUDES
  35. */
  36. #include "ZComDef.h"
  37. #include "OSAL.h"
  38. #include "zcl.h"
  39. #include "zcl_general.h"
  40. #include "zcl_ota.h"
  41. #include "ota_common.h"
  42. #include "hal_lcd.h"
  43. #include "hal_led.h"
  44. #include "hal_ota.h"
  45. #include "MT_OTA.h"
  46. #include "ZDProfile.h"
  47. #include "ZDObject.h"
  48. #if defined ( INTER_PAN )
  49. #include "stub_aps.h"
  50. #endif
  51. #if defined OTA_MMO_SIGN
  52. #include "ota_signature.h"
  53. #endif
  54. /******************************************************************************
  55. * MACROS
  56. */
  57. /******************************************************************************
  58. * CONSTANTS
  59. */
  60. #define OTA_MAX_TRANSACTIONS 4
  61. #define OTA_TRANSACTION_EXPIRATION 1500
  62. #define ZCL_OTA_HDR_LEN_OFFSET 6 // Header length location in OTA upgrade image
  63. #define ZCL_OTA_STK_VER_OFFSET 18 // Stack version location in OTA upgrade image
  64. /******************************************************************************
  65. * GLOBAL VARIABLES
  66. */
  67. // OTA attribute variables
  68. uint8 zclOTA_UpgradeServerID[Z_EXTADDR_LEN];
  69. uint32 zclOTA_FileOffset = 0xFFFFFFFF;
  70. uint32 zclOTA_CurrentFileVersion = 0xFFFFFFFF;
  71. uint16 zclOTA_CurrentZigBeeStackVersion;
  72. uint32 zclOTA_DownloadedFileVersion = 0xFFFFFFFF;
  73. uint16 zclOTA_DownloadedZigBeeStackVersion = 0xFFFF;
  74. uint8 zclOTA_ImageUpgradeStatus;
  75. // Other OTA variables
  76. uint16 zclOTA_ManufacturerId; // Manufacturer ID
  77. uint16 zclOTA_ImageType; // Image type
  78. afAddrType_t zclOTA_serverAddr; // Server address
  79. uint8 zclOTA_AppTask = 0xFF; // Callback Task ID
  80. zclOTA_QueryImageRspParams_t queryResponse; // Global variable for sent query response
  81. /******************************************************************************
  82. * LOCAL VARIABLES
  83. */
  84. // Other OTA variables
  85. // Task ID
  86. static uint8 zclOTA_TaskID;
  87. // Sequence number
  88. static uint8 zclOTA_SeqNo = 0;
  89. static uint8 zclOTA_Permit = TRUE;
  90. #if defined OTA_MMO_SIGN
  91. static OTA_MmoCtrl_t zclOTA_MmoHash;
  92. static uint8 zclOTA_DataToHash[OTA_MMO_HASH_SIZE];
  93. static uint8 zclOTA_HashPos;
  94. static uint8 zclOTA_SignerIEEE[Z_EXTADDR_LEN];
  95. static uint8 zclOTA_SignatureData[OTA_SIGNATURE_LEN];
  96. static uint8 zclOTA_Certificate[OTA_CERTIFICATE_LEN];
  97. #endif // OTA_MMO_SIGN
  98. #if (defined OTA_CLIENT) && (OTA_CLIENT == TRUE)
  99. static uint32 zclOTA_DownloadedImageSize; // Downloaded image size
  100. static uint16 zclOTA_HeaderLen; // Image header length
  101. static uint16 zclOTA_UpdateDelay;
  102. static zclOTA_FileID_t zclOTA_CurrentDlFileId;
  103. static uint16 zclOTA_ElementTag;
  104. static uint32 zclOTA_ElementLen;
  105. static uint32 zclOTA_ElementPos;
  106. // Retry counters
  107. static uint8 zclOTA_BlockRetry;
  108. static uint8 zclOTA_UpgradeEndRetry;
  109. static uint8 zclOTA_ClientPdState;
  110. // OTA Header Magic Number Bytes
  111. static const uint8 zclOTA_HdrMagic[] = {0x1E, 0xF1, 0xEE, 0x0B};
  112. #endif // OTA_CLIENT
  113. /******************************************************************************
  114. * LOCAL FUNCTIONS
  115. */
  116. static ZStatus_t zclOTA_HdlIncoming( zclIncoming_t *pInMsg );
  117. #if (defined OTA_CLIENT) && (OTA_CLIENT == TRUE)
  118. static void zclOTA_StartTimer(uint16 eventId, uint32 minutes);
  119. static ZStatus_t sendImageBlockReq(afAddrType_t *dstAddr);
  120. static void zclOTA_ProcessZDOMsgs( zdoIncomingMsg_t *pMsg );
  121. static void zclOTA_ImageBlockWaitExpired(void);
  122. static void zclOTA_UpgradeComplete(uint8 status);
  123. static uint8 zclOTA_CmpFileId(zclOTA_FileID_t *f1, zclOTA_FileID_t *f2);
  124. static uint8 zclOTA_ProcessImageData(uint8 *pData, uint8 len);
  125. static ZStatus_t zclOTA_SendQueryNextImageReq( afAddrType_t *dstAddr, zclOTA_QueryNextImageReqParams_t *pParams );
  126. static ZStatus_t zclOTA_SendImageBlockReq( afAddrType_t *dstAddr, zclOTA_ImageBlockReqParams_t *pParams );
  127. static ZStatus_t zclOTA_SendUpgradeEndReq( afAddrType_t *dstAddr, zclOTA_UpgradeEndReqParams_t *pParams );
  128. static ZStatus_t zclOTA_ClientHdlIncoming( zclIncoming_t *pInMsg );
  129. #endif // OTA_CLIENT
  130. #if (defined OTA_SERVER) && (OTA_SERVER == TRUE)
  131. static ZStatus_t zclOTA_SendQueryNextImageRsp( afAddrType_t *dstAddr, zclOTA_QueryImageRspParams_t *pParams );
  132. static ZStatus_t zclOTA_SendImageBlockRsp( afAddrType_t *dstAddr, zclOTA_ImageBlockRspParams_t *pParams );
  133. static ZStatus_t zclOTA_SendUpgradeEndRsp( afAddrType_t *dstAddr, zclOTA_UpgradeEndRspParams_t *pParams );
  134. static ZStatus_t zclOTA_SendQuerySpecificFileRsp( afAddrType_t *dstAddr, zclOTA_QueryImageRspParams_t *pParams );
  135. static ZStatus_t zclOTA_Srv_QueryNextImageReq(afAddrType_t *pSrcAddr, zclOTA_QueryNextImageReqParams_t *pParam);
  136. static ZStatus_t zclOTA_Srv_ImageBlockReq(afAddrType_t *pSrcAddr, zclOTA_ImageBlockReqParams_t *pParam);
  137. static ZStatus_t zclOTA_Srv_ImagePageReq(afAddrType_t *pSrcAddr, zclOTA_ImagePageReqParams_t *pParam);
  138. static ZStatus_t zclOTA_Srv_UpgradeEndReq(afAddrType_t *pSrcAddr, zclOTA_UpgradeEndReqParams_t *pParam);
  139. static ZStatus_t zclOTA_Srv_QuerySpecificFileReq(afAddrType_t *pSrcAddr, zclOTA_QuerySpecificFileReqParams_t *pParam);
  140. static void zclOTA_ProcessNextImgRsp(uint8* pMSGpkt, zclOTA_FileID_t *pFileId, afAddrType_t *pAddr);
  141. static void zclOTA_ProcessFileReadRsp(uint8* pMSGpkt, zclOTA_FileID_t *pFileId, afAddrType_t *pAddr);
  142. static void zclOTA_ServerHandleFileSysCb(OTA_MtMsg_t* pMSGpkt);
  143. static ZStatus_t zclOTA_ServerHdlIncoming( zclIncoming_t *pInMsg );
  144. #endif // OTA_SERVER
  145. /******************************************************************************
  146. * OTA ATTRIBUTE DEFINITIONS - Uses REAL cluster IDs
  147. */
  148. #define ZCL_OTA_MAX_ATTRIBUTES 7
  149. CONST zclAttrRec_t zclOTA_Attrs[ZCL_OTA_MAX_ATTRIBUTES] =
  150. {
  151. {
  152. ZCL_CLUSTER_ID_OTA, // Cluster IDs - defined in the foundation (ie. zcl.h)
  153. { // Attribute record
  154. ATTRID_UPGRADE_SERVER_ID, // Attribute ID - Found in Cluster Library header (ie. zcl_general.h)
  155. ZCL_DATATYPE_IEEE_ADDR, // Data Type - found in zcl.h
  156. ACCESS_CONTROL_READ, // Variable access control - found in zcl.h
  157. (void *)&zclOTA_UpgradeServerID // Pointer to attribute variable
  158. }
  159. },
  160. {
  161. ZCL_CLUSTER_ID_OTA,
  162. { // Attribute record
  163. ATTRID_FILE_OFFSET,
  164. ZCL_DATATYPE_UINT32,
  165. ACCESS_CONTROL_READ,
  166. (void *)&zclOTA_FileOffset
  167. }
  168. },
  169. {
  170. ZCL_CLUSTER_ID_OTA,
  171. { // Attribute record
  172. ATTRID_CURRENT_FILE_VERSION,
  173. ZCL_DATATYPE_UINT32,
  174. ACCESS_CONTROL_READ,
  175. (void *)&zclOTA_CurrentFileVersion
  176. }
  177. },
  178. {
  179. ZCL_CLUSTER_ID_OTA,
  180. { // Attribute record
  181. ATTRID_CURRENT_ZIGBEE_STACK_VERSION,
  182. ZCL_DATATYPE_UINT16,
  183. ACCESS_CONTROL_READ,
  184. (void *)&zclOTA_CurrentZigBeeStackVersion
  185. }
  186. },
  187. {
  188. ZCL_CLUSTER_ID_OTA,
  189. { // Attribute record
  190. ATTRID_DOWNLOADED_FILE_VERSION,
  191. ZCL_DATATYPE_UINT32,
  192. ACCESS_CONTROL_READ,
  193. (void *)&zclOTA_DownloadedFileVersion
  194. }
  195. },
  196. {
  197. ZCL_CLUSTER_ID_OTA,
  198. { // Attribute record
  199. ATTRID_DOWNLOADED_ZIGBEE_STACK_VERSION,
  200. ZCL_DATATYPE_UINT16,
  201. ACCESS_CONTROL_READ,
  202. (void *)&zclOTA_DownloadedZigBeeStackVersion
  203. }
  204. },
  205. {
  206. ZCL_CLUSTER_ID_OTA,
  207. { // Attribute record
  208. ATTRID_IMAGE_UPGRADE_STATUS,
  209. ZCL_DATATYPE_UINT8,
  210. ACCESS_CONTROL_READ,
  211. (void *)&zclOTA_ImageUpgradeStatus
  212. }
  213. }
  214. };
  215. /******************************************************************************
  216. * OTA SIMPLE DESCRIPTOR
  217. */
  218. #ifndef OTA_HA
  219. #define ZCL_OTA_MAX_OPTIONS 1
  220. zclOptionRec_t zclOta_Options[ZCL_OTA_MAX_OPTIONS] =
  221. {
  222. {
  223. ZCL_CLUSTER_ID_OTA,
  224. ( AF_EN_SECURITY | AF_ACK_REQUEST ),
  225. },
  226. };
  227. #endif // OTA_HA
  228. #if defined OTA_SERVER && (OTA_SERVER == TRUE)
  229. // Cluster ID list for match descriptor of the OTA Server.
  230. #define ZCL_OTA_MAX_INCLUSTERS 1
  231. const cId_t zclOTA_InClusterList[ZCL_OTA_MAX_INCLUSTERS] =
  232. {
  233. ZCL_CLUSTER_ID_OTA
  234. };
  235. #else
  236. #define ZCL_OTA_MAX_INCLUSTERS 0
  237. #define zclOTA_InClusterList NULL
  238. #endif // OTA_SERVER
  239. #if defined OTA_CLIENT && (OTA_CLIENT == TRUE)
  240. // Cluster ID list for match descriptor of the OTA Client.
  241. #define ZCL_OTA_MAX_OUTCLUSTERS 1
  242. const cId_t zclOTA_OutClusterList[ZCL_OTA_MAX_OUTCLUSTERS] =
  243. {
  244. ZCL_CLUSTER_ID_OTA
  245. };
  246. #else
  247. #define ZCL_OTA_MAX_OUTCLUSTERS 0
  248. #define zclOTA_OutClusterList NULL
  249. #endif // OTA_CLIENT
  250. SimpleDescriptionFormat_t zclOTA_SimpleDesc =
  251. {
  252. ZCL_OTA_ENDPOINT, // int Endpoint;
  253. ZCL_OTA_SAMPLE_PROFILE_ID, // uint16 AppProfId[2];
  254. ZCL_OTA_SAMPLE_DEVICEID, // uint16 AppDeviceId[2];
  255. ZCL_OTA_DEVICE_VERSION, // int AppDevVer:4;
  256. ZCL_OTA_FLAGS, // int AppFlags:4;
  257. ZCL_OTA_MAX_INCLUSTERS, // byte AppNumInClusters;
  258. (cId_t *)zclOTA_InClusterList, // byte *pAppInClusterList;
  259. ZCL_OTA_MAX_OUTCLUSTERS, // byte AppNumInClusters;
  260. (cId_t *)zclOTA_OutClusterList // byte *pAppInClusterList;
  261. };
  262. // Endpoint for OTA Cluster
  263. static endPointDesc_t zclOTA_Ep =
  264. {
  265. ZCL_OTA_ENDPOINT,
  266. &zcl_TaskID,
  267. (SimpleDescriptionFormat_t *)&zclOTA_SimpleDesc,
  268. (afNetworkLatencyReq_t) 0
  269. };
  270. /******************************************************************************
  271. * @fn zclOTA_PermitOta
  272. *
  273. * @brief Called to enable/disable OTA operation.
  274. *
  275. * @param permit - TRUE to enable OTA, FALSE to diable OTA
  276. *
  277. * @return none
  278. */
  279. void zclOTA_PermitOta(uint8 permit)
  280. {
  281. zclOTA_Permit = permit;
  282. }
  283. /******************************************************************************
  284. * @fn zclOTA_Register
  285. *
  286. * @brief Called by an application to register for callback messages
  287. * from the OTA.
  288. *
  289. * @param applicationTaskId - Application Task ID
  290. *
  291. * @return none
  292. */
  293. void zclOTA_Register(uint8 applicationTaskId)
  294. {
  295. zclOTA_AppTask = applicationTaskId;
  296. }
  297. /******************************************************************************
  298. * @fn zclOTA_RequestNextUpdate
  299. *
  300. * @brief Called by an application after discovery of the OTA server
  301. * to initiate the query next image of the OTA server.
  302. *
  303. * @param srvAddr - Short address of the server
  304. * @param srvEndPoint - Endpoint on the server
  305. *
  306. * @return ZStatus_t
  307. */
  308. void zclOTA_RequestNextUpdate(uint16 srvAddr, uint8 srvEndPoint)
  309. {
  310. // Record the server address
  311. zclOTA_serverAddr.addrMode = afAddr16Bit;
  312. zclOTA_serverAddr.endPoint = srvEndPoint;
  313. zclOTA_serverAddr.addr.shortAddr = srvAddr;
  314. // Set an event to query the server
  315. osal_set_event(zclOTA_TaskID, ZCL_OTA_QUERY_SERVER_EVT);
  316. }
  317. /******************************************************************************
  318. * @fn zclOTA_Init
  319. *
  320. * @brief Call to initialize the OTA Client Task
  321. *
  322. * @param task_id
  323. *
  324. * @return none
  325. */
  326. void zclOTA_Init( uint8 task_id )
  327. {
  328. zclOTA_TaskID = task_id;
  329. // Register for the cluster endpoint
  330. afRegister( &zclOTA_Ep );
  331. // Register as a ZCL Plugin
  332. zcl_registerPlugin( ZCL_CLUSTER_ID_OTA,
  333. ZCL_CLUSTER_ID_OTA,
  334. zclOTA_HdlIncoming );
  335. // Initialize attribute variables
  336. zclOTA_CurrentZigBeeStackVersion = OTA_STACK_VER_PRO;
  337. zclOTA_ImageUpgradeStatus = OTA_STATUS_NORMAL;
  338. // Register attribute list
  339. zcl_registerAttrList( ZCL_OTA_ENDPOINT,
  340. ZCL_OTA_MAX_ATTRIBUTES,
  341. zclOTA_Attrs );
  342. #ifndef OTA_HA
  343. // Register the application's cluster option list
  344. zcl_registerClusterOptionList( ZCL_OTA_ENDPOINT, ZCL_OTA_MAX_OPTIONS, zclOta_Options );
  345. #endif // OTA_HA
  346. // Register with the ZDO to receive Network Address Responses
  347. ZDO_RegisterForZDOMsg(task_id, IEEE_addr_rsp);
  348. // The default upgradeServerID is FF:FF:FF:FF:FF:FF:FF:FF
  349. osal_memset(zclOTA_UpgradeServerID, 0xFF, sizeof(zclOTA_UpgradeServerID));
  350. #if defined (OTA_SERVER) && (OTA_SERVER == TRUE)
  351. // Register with the files system
  352. MT_OtaRegister(task_id);
  353. #endif // OTA_SERVER
  354. }
  355. /******************************************************************************
  356. * @fn zclOTA_event_loop
  357. *
  358. * @brief Event Loop Processor for OTA Client task.
  359. *
  360. * @param task_id - TaskId
  361. * events - events
  362. *
  363. * @return Unprocessed event bits
  364. */
  365. uint16 zclOTA_event_loop( uint8 task_id, uint16 events )
  366. {
  367. afIncomingMSGPacket_t *MSGpkt;
  368. if ( events & SYS_EVENT_MSG )
  369. {
  370. while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( task_id )) )
  371. {
  372. switch ( MSGpkt->hdr.event )
  373. {
  374. #if (defined OTA_CLIENT) && (OTA_CLIENT == TRUE)
  375. case ZDO_CB_MSG:
  376. zclOTA_ProcessZDOMsgs( (zdoIncomingMsg_t *)MSGpkt );
  377. break;
  378. #endif // OTA_CLIENT
  379. #if (defined OTA_SERVER) && (OTA_SERVER == TRUE)
  380. case MT_SYS_OTA_MSG:
  381. zclOTA_ServerHandleFileSysCb((OTA_MtMsg_t*)MSGpkt);
  382. break;
  383. #endif
  384. default:
  385. break;
  386. }
  387. // Release the memory
  388. osal_msg_deallocate( (uint8 *)MSGpkt );
  389. }
  390. // return unprocessed events
  391. return (events ^ SYS_EVENT_MSG);
  392. }
  393. #if (defined OTA_CLIENT) && (OTA_CLIENT == TRUE)
  394. if ( events & ZCL_OTA_IMAGE_BLOCK_WAIT_EVT )
  395. {
  396. // If the time has expired, perform the required action
  397. if (zclOTA_UpdateDelay == 0)
  398. {
  399. zclOTA_ImageBlockWaitExpired();
  400. }
  401. else
  402. {
  403. // Decrement the number of minutes to wait and reset the timer
  404. zclOTA_UpdateDelay--;
  405. osal_start_timerEx(zclOTA_TaskID, ZCL_OTA_IMAGE_BLOCK_WAIT_EVT, 60000);
  406. }
  407. return ( events ^ ZCL_OTA_IMAGE_BLOCK_WAIT_EVT );
  408. }
  409. if ( events & ZCL_OTA_UPGRADE_WAIT_EVT )
  410. {
  411. // If the time has expired, perform the required action
  412. if (zclOTA_UpdateDelay == 0)
  413. {
  414. if (zclOTA_ImageUpgradeStatus == OTA_STATUS_COUNTDOWN)
  415. {
  416. zclOTA_UpgradeComplete(ZSuccess);
  417. }
  418. else if (zclOTA_ImageUpgradeStatus == OTA_STATUS_UPGRADE_WAIT)
  419. {
  420. if (++zclOTA_UpgradeEndRetry > OTA_MAX_END_REQ_RETRIES)
  421. {
  422. // If we have not heard from the server for N retries, perform the upgrade
  423. zclOTA_UpgradeComplete(ZSuccess);
  424. }
  425. else
  426. {
  427. // Send another update end request
  428. zclOTA_UpgradeEndReqParams_t req;
  429. req.status = ZSuccess;
  430. osal_memcpy(&req.fileId, &zclOTA_CurrentDlFileId, sizeof(zclOTA_FileID_t));
  431. zclOTA_SendUpgradeEndReq(&zclOTA_serverAddr, &req);
  432. // Restart the timer for another hour
  433. zclOTA_StartTimer(ZCL_OTA_UPGRADE_WAIT_EVT, 3600);
  434. }
  435. }
  436. }
  437. else
  438. {
  439. // Decrement the number of minutes to wait and reset the timer
  440. zclOTA_UpdateDelay--;
  441. osal_start_timerEx(zclOTA_TaskID, ZCL_OTA_UPGRADE_WAIT_EVT, 60000);
  442. }
  443. return ( events ^ ZCL_OTA_UPGRADE_WAIT_EVT );
  444. }
  445. if (events & ZCL_OTA_IMAGE_QUERY_TO_EVT )
  446. {
  447. if (zclOTA_ImageUpgradeStatus == OTA_STATUS_NORMAL)
  448. {
  449. // Notify the application task of the timeout waiting for the download to start
  450. zclOTA_CallbackMsg_t *pMsg;
  451. pMsg = (zclOTA_CallbackMsg_t*) osal_msg_allocate(sizeof(zclOTA_CallbackMsg_t));
  452. if (pMsg)
  453. {
  454. pMsg->hdr.event = ZCL_OTA_CALLBACK_IND;
  455. pMsg->hdr.status = ZFailure;
  456. pMsg->ota_event = ZCL_OTA_START_CALLBACK;
  457. osal_msg_send(zclOTA_AppTask, (uint8*) pMsg);
  458. }
  459. }
  460. return ( events ^ ZCL_OTA_IMAGE_QUERY_TO_EVT );
  461. }
  462. if (events & ZCL_OTA_BLOCK_RSP_TO_EVT )
  463. {
  464. // We timed out waiting for a Block Response
  465. if (++zclOTA_BlockRetry > OTA_MAX_BLOCK_RETRIES)
  466. {
  467. // Send a failed update end request
  468. zclOTA_UpgradeEndReqParams_t req;
  469. req.status = ZOtaAbort;
  470. osal_memcpy(&req.fileId, &zclOTA_CurrentDlFileId, sizeof(zclOTA_FileID_t));
  471. zclOTA_SendUpgradeEndReq(&zclOTA_serverAddr, &req);
  472. zclOTA_UpgradeComplete(ZOtaAbort);
  473. }
  474. else
  475. {
  476. // Send another block request
  477. sendImageBlockReq(&zclOTA_serverAddr);
  478. }
  479. return ( events ^ ZCL_OTA_BLOCK_RSP_TO_EVT );
  480. }
  481. if (events & ZCL_OTA_QUERY_SERVER_EVT )
  482. {
  483. zclOTA_QueryNextImageReqParams_t queryParams;
  484. queryParams.fieldControl = 0;
  485. queryParams.fileId.manufacturer = OTA_MANUFACTURER_ID;
  486. queryParams.fileId.type = OTA_TYPE_ID;
  487. queryParams.fileId.version = zclOTA_CurrentFileVersion;
  488. zclOTA_SendQueryNextImageReq(&zclOTA_serverAddr, &queryParams);
  489. // Set a timer to wait for the response
  490. osal_start_timerEx(zclOTA_TaskID, ZCL_OTA_IMAGE_QUERY_TO_EVT, 10000);
  491. return ( events ^ ZCL_OTA_QUERY_SERVER_EVT );
  492. }
  493. #endif // OTA_CLIENT
  494. // Discard unknown events
  495. return 0;
  496. }
  497. /******************************************************************************
  498. * @fn zclOTA_HdlIncoming
  499. *
  500. * @brief Callback from ZCL to process incoming Commands specific
  501. * to this cluster library or Profile commands for attributes
  502. * that aren't in the attribute list
  503. *
  504. * @param pInMsg - pointer to the incoming message
  505. *
  506. * @return ZStatus_t
  507. */
  508. static ZStatus_t zclOTA_HdlIncoming( zclIncoming_t *pInMsg )
  509. {
  510. ZStatus_t stat = ZSuccess;
  511. if ( zcl_ClusterCmd( pInMsg->hdr.fc.type ) )
  512. {
  513. // Is this a manufacturer specific command?
  514. if ( pInMsg->hdr.fc.manuSpecific == 0 )
  515. {
  516. // Is command for server?
  517. if ( zcl_ServerCmd( pInMsg->hdr.fc.direction ) )
  518. {
  519. #if (defined OTA_SERVER) && (OTA_SERVER == TRUE)
  520. stat = zclOTA_ServerHdlIncoming( pInMsg );
  521. #else
  522. stat = ZCL_STATUS_UNSUP_CLUSTER_COMMAND;
  523. #endif // OTA_SERVER
  524. }
  525. else // Else command is for client
  526. {
  527. #if (defined OTA_CLIENT) && (OTA_CLIENT == TRUE)
  528. stat = zclOTA_ClientHdlIncoming( pInMsg );
  529. #else
  530. stat = ZCL_STATUS_UNSUP_CLUSTER_COMMAND;
  531. #endif // OTA_CLIENT
  532. }
  533. }
  534. else
  535. {
  536. // We don't support any manufacturer specific command.
  537. stat = ZCL_STATUS_UNSUP_MANU_CLUSTER_COMMAND;
  538. }
  539. }
  540. else
  541. {
  542. // Handle all the normal (Read, Write...) commands -- should never get here
  543. stat = ZFailure;
  544. }
  545. return ( stat );
  546. }
  547. #if (defined OTA_SERVER) && (OTA_SERVER == TRUE)
  548. /******************************************************************************
  549. * @fn zclOTA_SendImageNotify
  550. *
  551. * @brief Send an OTA Image Notify message.
  552. *
  553. * @param dstAddr - where you want the message to go
  554. * @param pParams - message parameters
  555. *
  556. * @return ZStatus_t
  557. */
  558. ZStatus_t zclOTA_SendImageNotify( afAddrType_t *dstAddr,
  559. zclOTA_ImageNotifyParams_t *pParams )
  560. {
  561. ZStatus_t status;
  562. uint8 buf[PAYLOAD_MAX_LEN_IMAGE_NOTIFY];
  563. uint8 *pBuf = buf;
  564. *pBuf++ = pParams->payloadType;
  565. *pBuf++ = pParams->queryJitter;
  566. if (pParams->payloadType >= NOTIFY_PAYLOAD_JITTER_MFG)
  567. {
  568. *pBuf++ = LO_UINT16(pParams->fileId.manufacturer);
  569. *pBuf++ = HI_UINT16(pParams->fileId.manufacturer);
  570. }
  571. if (pParams->payloadType >= NOTIFY_PAYLOAD_JITTER_MFG_TYPE)
  572. {
  573. *pBuf++ = LO_UINT16(pParams->fileId.type);
  574. *pBuf++ = HI_UINT16(pParams->fileId.type);
  575. }
  576. if (pParams->payloadType == NOTIFY_PAYLOAD_JITTER_MFG_TYPE_VERS)
  577. {
  578. pBuf = osal_buffer_uint32(pBuf, pParams->fileId.version);
  579. }
  580. status = zcl_SendCommand( ZCL_OTA_ENDPOINT, dstAddr, ZCL_CLUSTER_ID_OTA,
  581. COMMAND_IMAGE_NOTIFY, TRUE,
  582. ZCL_FRAME_SERVER_CLIENT_DIR, TRUE, 0,
  583. zclOTA_SeqNo++, (uint16) (pBuf - buf), buf );
  584. return status;
  585. }
  586. /******************************************************************************
  587. * @fn zclOTA_SendQueryNextImageRsp
  588. *
  589. * @brief Send an OTA Query Next Image Response message.
  590. *
  591. * @param dstAddr - where you want the message to go
  592. * @param pParams - message parameters
  593. *
  594. * @return ZStatus_t
  595. */
  596. ZStatus_t zclOTA_SendQueryNextImageRsp( afAddrType_t *dstAddr,
  597. zclOTA_QueryImageRspParams_t *pParams )
  598. {
  599. ZStatus_t status;
  600. uint8 buf[PAYLOAD_MAX_LEN_QUERY_NEXT_IMAGE_RSP];
  601. uint8 *pBuf = buf;
  602. *pBuf++ = pParams->status;
  603. if (pParams->status == ZCL_STATUS_SUCCESS)
  604. {
  605. *pBuf++ = LO_UINT16(pParams->fileId.manufacturer);
  606. *pBuf++ = HI_UINT16(pParams->fileId.manufacturer);
  607. *pBuf++ = LO_UINT16(pParams->fileId.type);
  608. *pBuf++ = HI_UINT16(pParams->fileId.type);
  609. pBuf = osal_buffer_uint32(pBuf, pParams->fileId.version);
  610. pBuf = osal_buffer_uint32(pBuf, pParams->imageSize);
  611. }
  612. status = zcl_SendCommand( ZCL_OTA_ENDPOINT, dstAddr, ZCL_CLUSTER_ID_OTA,
  613. COMMAND_QUERY_NEXT_IMAGE_RSP, TRUE,
  614. ZCL_FRAME_SERVER_CLIENT_DIR, TRUE, 0,
  615. zclOTA_SeqNo++, (uint16) (pBuf - buf), buf );
  616. return status;
  617. }
  618. /******************************************************************************
  619. * @fn zclOTA_SendImageBlockRsp
  620. *
  621. * @brief Send an OTA Image Block Response mesage.
  622. *
  623. * @param dstAddr - where you want the message to go
  624. * @param pParams - message parameters
  625. *
  626. * @return ZStatus_t
  627. */
  628. ZStatus_t zclOTA_SendImageBlockRsp( afAddrType_t *dstAddr,
  629. zclOTA_ImageBlockRspParams_t *pParams )
  630. {
  631. uint8 *buf;
  632. uint8 *pBuf;
  633. ZStatus_t status;
  634. uint8 len;
  635. if (pParams->status == ZCL_STATUS_SUCCESS)
  636. {
  637. len = PAYLOAD_MAX_LEN_IMAGE_BLOCK_RSP + pParams->rsp.success.dataSize;
  638. }
  639. else if (pParams->status == ZCL_STATUS_WAIT_FOR_DATA)
  640. {
  641. len = PAYLOAD_MIN_LEN_IMAGE_BLOCK_WAIT;
  642. }
  643. else
  644. {
  645. len = 1;
  646. }
  647. buf = osal_mem_alloc( len );
  648. if ( buf == NULL )
  649. {
  650. return (ZMemError);
  651. }
  652. pBuf = buf;
  653. *pBuf++ = pParams->status;
  654. if (pParams->status == ZCL_STATUS_SUCCESS)
  655. {
  656. *pBuf++ = LO_UINT16(pParams->rsp.success.fileId.manufacturer);
  657. *pBuf++ = HI_UINT16(pParams->rsp.success.fileId.manufacturer);
  658. *pBuf++ = LO_UINT16(pParams->rsp.success.fileId.type);
  659. *pBuf++ = HI_UINT16(pParams->rsp.success.fileId.type);
  660. pBuf = osal_buffer_uint32(pBuf, pParams->rsp.success.fileId.version);
  661. pBuf = osal_buffer_uint32(pBuf, pParams->rsp.success.fileOffset);
  662. *pBuf++ = pParams->rsp.success.dataSize;
  663. osal_memcpy(pBuf, pParams->rsp.success.pData, pParams->rsp.success.dataSize);
  664. }
  665. else if (pParams->status == ZCL_STATUS_WAIT_FOR_DATA)
  666. {
  667. pBuf = osal_buffer_uint32(pBuf, pParams->rsp.wait.currentTime);
  668. pBuf = osal_buffer_uint32(pBuf, pParams->rsp.wait.requestTime);
  669. }
  670. status = zcl_SendCommand( ZCL_OTA_ENDPOINT, dstAddr, ZCL_CLUSTER_ID_OTA,
  671. COMMAND_IMAGE_BLOCK_RSP, TRUE,
  672. ZCL_FRAME_SERVER_CLIENT_DIR, TRUE, 0,
  673. zclOTA_SeqNo++, len, buf );
  674. osal_mem_free(buf);
  675. return status;
  676. }
  677. /******************************************************************************
  678. * @fn zclOTA_SendUpgradeEndRsp
  679. *
  680. * @brief Send an OTA Upgrade End Response mesage.
  681. *
  682. * @param dstAddr - where you want the message to go
  683. * @param pParams - message parameters
  684. *
  685. * @return ZStatus_t
  686. */
  687. ZStatus_t zclOTA_SendUpgradeEndRsp( afAddrType_t *dstAddr,
  688. zclOTA_UpgradeEndRspParams_t *pParams )
  689. {
  690. ZStatus_t status;
  691. uint8 buf[PAYLOAD_MAX_LEN_UPGRADE_END_RSP];
  692. uint8 *pBuf = buf;
  693. *pBuf++ = LO_UINT16(pParams->fileId.manufacturer);
  694. *pBuf++ = HI_UINT16(pParams->fileId.manufacturer);
  695. *pBuf++ = LO_UINT16(pParams->fileId.type);
  696. *pBuf++ = HI_UINT16(pParams->fileId.type);
  697. pBuf = osal_buffer_uint32(pBuf, pParams->fileId.version);
  698. pBuf = osal_buffer_uint32(pBuf, pParams->currentTime);
  699. pBuf = osal_buffer_uint32(pBuf, pParams->upgradeTime);
  700. status = zcl_SendCommand( ZCL_OTA_ENDPOINT, dstAddr, ZCL_CLUSTER_ID_OTA,
  701. COMMAND_UPGRADE_END_RSP, TRUE,
  702. ZCL_FRAME_SERVER_CLIENT_DIR, TRUE, 0,
  703. zclOTA_SeqNo++, PAYLOAD_MAX_LEN_UPGRADE_END_RSP, buf );
  704. return status;
  705. }
  706. /******************************************************************************
  707. * @fn zclOTA_SendQuerySpecificFileRsp
  708. *
  709. * @brief Send an OTA Query Specific File Response mesage.
  710. *
  711. * @param dstAddr - where you want the message to go
  712. * @param pParams - message parameters
  713. *
  714. * @return ZStatus_t
  715. */
  716. ZStatus_t zclOTA_SendQuerySpecificFileRsp( afAddrType_t *dstAddr,
  717. zclOTA_QueryImageRspParams_t *pParams )
  718. {
  719. ZStatus_t status;
  720. uint8 buf[PAYLOAD_MAX_LEN_QUERY_SPECIFIC_FILE_RSP];
  721. uint8 *pBuf = buf;
  722. *pBuf++ = pParams->status;
  723. if (pParams->status == ZCL_STATUS_SUCCESS)
  724. {
  725. *pBuf++ = LO_UINT16(pParams->fileId.manufacturer);
  726. *pBuf++ = HI_UINT16(pParams->fileId.manufacturer);
  727. *pBuf++ = LO_UINT16(pParams->fileId.type);
  728. *pBuf++ = HI_UINT16(pParams->fileId.type);
  729. pBuf = osal_buffer_uint32(pBuf, pParams->fileId.version);
  730. pBuf = osal_buffer_uint32(pBuf, pParams->imageSize);
  731. }
  732. status = zcl_SendCommand( ZCL_OTA_ENDPOINT, dstAddr, ZCL_CLUSTER_ID_OTA,
  733. COMMAND_QUERY_SPECIFIC_FILE_RSP, TRUE,
  734. ZCL_FRAME_SERVER_CLIENT_DIR, TRUE, 0,
  735. zclOTA_SeqNo++, (uint16) (pBuf - buf), buf );
  736. return status;
  737. }
  738. #endif // OTA_SERVER
  739. #if (defined OTA_CLIENT) && (OTA_CLIENT == TRUE)
  740. /******************************************************************************
  741. * @fn zclOTA_SendQueryNextImageReq
  742. *
  743. * @brief Send an OTA Query Next Image Request mesage.
  744. *
  745. * @param dstAddr - where you want the message to go
  746. * @param pParams - message parameters
  747. *
  748. * @return ZStatus_t
  749. */
  750. ZStatus_t zclOTA_SendQueryNextImageReq( afAddrType_t *dstAddr,
  751. zclOTA_QueryNextImageReqParams_t *pParams )
  752. {
  753. ZStatus_t status;
  754. uint8 buf[PAYLOAD_MAX_LEN_QUERY_NEXT_IMAGE_REQ];
  755. uint8 *pBuf = buf;
  756. *pBuf++ = pParams->fieldControl;
  757. *pBuf++ = LO_UINT16(pParams->fileId.manufacturer);
  758. *pBuf++ = HI_UINT16(pParams->fileId.manufacturer);
  759. *pBuf++ = LO_UINT16(pParams->fileId.type);
  760. *pBuf++ = HI_UINT16(pParams->fileId.type);
  761. pBuf = osal_buffer_uint32(pBuf, pParams->fileId.version);
  762. if (pParams->fieldControl == 1)
  763. {
  764. *pBuf++ = LO_UINT16(pParams->hardwareVersion);
  765. *pBuf++ = HI_UINT16(pParams->hardwareVersion);
  766. }
  767. status = zcl_SendCommand( ZCL_OTA_ENDPOINT, dstAddr, ZCL_CLUSTER_ID_OTA,
  768. COMMAND_QUERY_NEXT_IMAGE_REQ, TRUE,
  769. ZCL_FRAME_CLIENT_SERVER_DIR, FALSE, 0,
  770. zclOTA_SeqNo++, (uint16) (pBuf - buf), buf );
  771. return status;
  772. }
  773. /******************************************************************************
  774. * @fn zclOTA_SendImageBlockReq
  775. *
  776. * @brief Send an OTA Image Block Request mesage.
  777. *
  778. * @param dstAddr - where you want the message to go
  779. * @param pParams - message parameters
  780. *
  781. * @return ZStatus_t
  782. */
  783. ZStatus_t zclOTA_SendImageBlockReq( afAddrType_t *dstAddr,
  784. zclOTA_ImageBlockReqParams_t *pParams )
  785. {
  786. ZStatus_t status;
  787. uint8 buf[PAYLOAD_MAX_LEN_IMAGE_BLOCK_REQ];
  788. uint8 *pBuf = buf;
  789. *pBuf++ = pParams->fieldControl;
  790. *pBuf++ = LO_UINT16(pParams->fileId.manufacturer);
  791. *pBuf++ = HI_UINT16(pParams->fileId.manufacturer);
  792. *pBuf++ = LO_UINT16(pParams->fileId.type);
  793. *pBuf++ = HI_UINT16(pParams->fileId.type);
  794. pBuf = osal_buffer_uint32(pBuf, pParams->fileId.version);
  795. pBuf = osal_buffer_uint32(pBuf, pParams->fileOffset);
  796. *pBuf++ = pParams->maxDataSize;
  797. if (pParams->fieldControl == 1)
  798. {
  799. osal_cpyExtAddr(pBuf, pParams->nodeAddr);
  800. pBuf += Z_EXTADDR_LEN;
  801. }
  802. status = zcl_SendCommand( ZCL_OTA_ENDPOINT, dstAddr, ZCL_CLUSTER_ID_OTA,
  803. COMMAND_IMAGE_BLOCK_REQ, TRUE,
  804. ZCL_FRAME_CLIENT_SERVER_DIR, FALSE, 0,
  805. zclOTA_SeqNo++, (uint16) (pBuf - buf), buf );
  806. return status;
  807. }
  808. /******************************************************************************
  809. * @fn zclOTA_SendUpgradeEndReq
  810. *
  811. * @brief Send an OTA Upgrade End Request mesage.
  812. *
  813. * @param dstAddr - where you want the message to go
  814. * @param pParams - message parameters
  815. *
  816. * @return ZStatus_t
  817. */
  818. ZStatus_t zclOTA_SendUpgradeEndReq( afAddrType_t *dstAddr,
  819. zclOTA_UpgradeEndReqParams_t *pParams )
  820. {
  821. ZStatus_t status;
  822. uint8 buf[PAYLOAD_MAX_LEN_UPGRADE_END_REQ];
  823. uint8 *pBuf = buf;
  824. *pBuf++ = pParams->status;
  825. *pBuf++ = LO_UINT16(pParams->fileId.manufacturer);
  826. *pBuf++ = HI_UINT16(pParams->fileId.manufacturer);
  827. *pBuf++ = LO_UINT16(pParams->fileId.type);
  828. *pBuf++ = HI_UINT16(pParams->fileId.type);
  829. pBuf = osal_buffer_uint32(pBuf, pParams->fileId.version);
  830. status = zcl_SendCommand( ZCL_OTA_ENDPOINT, dstAddr, ZCL_CLUSTER_ID_OTA,
  831. COMMAND_UPGRADE_END_REQ, TRUE,
  832. ZCL_FRAME_CLIENT_SERVER_DIR, FALSE, 0,
  833. zclOTA_SeqNo++, (uint16) (pBuf - buf), buf );
  834. return status;
  835. }
  836. /******************************************************************************
  837. * @fn zclOTA_StartTimer
  838. *
  839. * @brief Start a ZCL OTA timer.
  840. *
  841. * @param eventId - OSAL event set on timer expiration
  842. * @param seconds - timeout in seconds
  843. *
  844. * @return None
  845. */
  846. static void zclOTA_StartTimer(uint16 eventId, uint32 seconds)
  847. {
  848. // Record the number of whole minutes to wait
  849. zclOTA_UpdateDelay = (seconds / 60);
  850. // Set a timer for the remaining seconds to wait.
  851. osal_start_timerEx(zclOTA_TaskID, eventId, (seconds % 60) * 1000);
  852. }
  853. /******************************************************************************
  854. * @fn sendImageBlockReq
  855. *
  856. * @brief Send an Image Block Request.
  857. *
  858. * @param dstAddr - where you want the message to go
  859. *
  860. * @return ZStatus_t
  861. */
  862. static ZStatus_t sendImageBlockReq(afAddrType_t *dstAddr)
  863. {
  864. zclOTA_ImageBlockReqParams_t req;
  865. req.fieldControl = 0;
  866. req.fileId.manufacturer = zclOTA_ManufacturerId;
  867. req.fileId.type = zclOTA_ImageType;
  868. req.fileId.version = zclOTA_DownloadedFileVersion;
  869. req.fileOffset = zclOTA_FileOffset;
  870. if (zclOTA_DownloadedImageSize - zclOTA_FileOffset < OTA_MAX_MTU)
  871. {
  872. req.maxDataSize = zclOTA_DownloadedImageSize - zclOTA_FileOffset;
  873. }
  874. else
  875. {
  876. req.maxDataSize = OTA_MAX_MTU;
  877. }
  878. // Start a timer waiting for a response
  879. osal_start_timerEx(zclOTA_TaskID, ZCL_OTA_BLOCK_RSP_TO_EVT, OTA_MAX_BLOCK_RSP_WAIT_TIME);
  880. return zclOTA_SendImageBlockReq( dstAddr, &req);
  881. }
  882. /******************************************************************************
  883. * @fn zclOTA_ProcessImageData
  884. *
  885. * @brief Process image data as it is received from the host.
  886. *
  887. * @param pData - pointer to the data
  888. * @param len - length of the data
  889. *
  890. * @return status of the operation
  891. */
  892. uint8 zclOTA_ProcessImageData(uint8 *pData, uint8 len)
  893. {
  894. int8 i;
  895. #if defined OTA_MMO_SIGN
  896. uint8 skipHash = FALSE;
  897. #endif
  898. if (zclOTA_ImageUpgradeStatus != OTA_STATUS_IN_PROGRESS)
  899. {
  900. return ZCL_STATUS_ABORT;
  901. }
  902. #if (defined HAL_LED) && (HAL_LED == TRUE)
  903. // Toggle an LED to indicate we received a new block
  904. HalLedSet(HAL_LED_2, HAL_LED_MODE_TOGGLE);
  905. #endif
  906. // write data to secondary storage
  907. HalOTAWrite(zclOTA_FileOffset, pData, len, HAL_OTA_DL);
  908. for (i=0; i<len; i++)
  909. {
  910. #if defined OTA_MMO_SIGN
  911. // Skip the hash if we are receiving the signature element
  912. if ((zclOTA_ClientPdState >= ZCL_OTA_PD_ELEM_LEN1_STATE) &&
  913. (zclOTA_ClientPdState <= ZCL_OTA_PD_ELEMENT_STATE))
  914. {
  915. if (zclOTA_ElementTag == OTA_ECDSA_SIGNATURE_TAG_ID)
  916. {
  917. skipHash = TRUE;
  918. }
  919. }
  920. #endif
  921. switch (zclOTA_ClientPdState)
  922. {
  923. // verify header magic number
  924. case ZCL_OTA_PD_MAGIC_0_STATE:
  925. // Initialize control variables
  926. #if defined OTA_MMO_SIGN
  927. osal_memset(&zclOTA_MmoHash, 0, sizeof(zclOTA_MmoHash));
  928. zclOTA_HashPos = 0;
  929. #endif
  930. // Missing break intended
  931. case ZCL_OTA_PD_MAGIC_1_STATE:
  932. case ZCL_OTA_PD_MAGIC_2_STATE:
  933. case ZCL_OTA_PD_MAGIC_3_STATE:
  934. if (pData[i] != zclOTA_HdrMagic[zclOTA_ClientPdState])
  935. {
  936. return ZCL_STATUS_INVALID_IMAGE;
  937. }
  938. zclOTA_ClientPdState++;
  939. break;
  940. case ZCL_OTA_PD_HDR_LEN1_STATE:
  941. // get header length
  942. if (zclOTA_FileOffset == ZCL_OTA_HDR_LEN_OFFSET)
  943. {
  944. zclOTA_HeaderLen = pData[i];
  945. zclOTA_ClientPdState = ZCL_OTA_PD_HDR_LEN2_STATE;
  946. }
  947. break;
  948. case ZCL_OTA_PD_HDR_LEN2_STATE:
  949. zclOTA_HeaderLen |= (((uint16)pData[i]) << 8) & 0xFF00;
  950. zclOTA_ClientPdState = ZCL_OTA_PD_STK_VER1_STATE;
  951. break;
  952. case ZCL_OTA_PD_STK_VER1_STATE:
  953. // get stack version
  954. if (zclOTA_FileOffset == ZCL_OTA_STK_VER_OFFSET)
  955. {
  956. zclOTA_DownloadedZigBeeStackVersion = pData[i];
  957. zclOTA_ClientPdState = ZCL_OTA_PD_STK_VER2_STATE;
  958. }
  959. break;
  960. case ZCL_OTA_PD_STK_VER2_STATE:
  961. zclOTA_DownloadedZigBeeStackVersion |= (((uint16)pData[i]) << 8) & 0xFF00;
  962. zclOTA_ClientPdState = ZCL_OTA_PD_CONT_HDR_STATE;
  963. if (zclOTA_DownloadedZigBeeStackVersion != OTA_HDR_STACK_VERSION)
  964. {
  965. return ZCL_STATUS_INVALID_IMAGE;
  966. }
  967. break;
  968. case ZCL_OTA_PD_CONT_HDR_STATE:
  969. // Complete the header
  970. if (zclOTA_FileOffset == zclOTA_HeaderLen-1)
  971. {
  972. zclOTA_ClientPdState = ZCL_OTA_PD_ELEM_TAG1_STATE;
  973. }
  974. break;
  975. case ZCL_OTA_PD_ELEM_TAG1_STATE:
  976. zclOTA_ElementTag = pData[i];
  977. zclOTA_ClientPdState = ZCL_OTA_PD_ELEM_TAG2_STATE;
  978. break;
  979. case ZCL_OTA_PD_ELEM_TAG2_STATE:
  980. zclOTA_ElementTag |= (((uint16)pData[i]) << 8) & 0xFF00;
  981. zclOTA_ElementPos = 0;
  982. zclOTA_ClientPdState = ZCL_OTA_PD_ELEM_LEN1_STATE;
  983. break;
  984. case ZCL_OTA_PD_ELEM_LEN1_STATE:
  985. zclOTA_ElementLen = pData[i];
  986. zclOTA_ClientPdState = ZCL_OTA_PD_ELEM_LEN2_STATE;
  987. break;
  988. case ZCL_OTA_PD_ELEM_LEN2_STATE:
  989. zclOTA_ElementLen |= ((uint32)pData[i] << 8) & 0x0000FF00;
  990. zclOTA_ClientPdState = ZCL_OTA_PD_ELEM_LEN3_STATE;
  991. break;
  992. case ZCL_OTA_PD_ELEM_LEN3_STATE:
  993. zclOTA_ElementLen |= ((uint32)pData[i] << 16) & 0x00FF0000;
  994. zclOTA_ClientPdState = ZCL_OTA_PD_ELEM_LEN4_STATE;
  995. break;
  996. case ZCL_OTA_PD_ELEM_LEN4_STATE:
  997. zclOTA_ElementLen |= ((uint32)pData[i] << 24) & 0xFF000000;
  998. zclOTA_ClientPdState = ZCL_OTA_PD_ELEMENT_STATE;
  999. // Make sure the length of the element isn't bigger than the image
  1000. if (zclOTA_ElementLen > (zclOTA_DownloadedImageSize - zclOTA_FileOffset))
  1001. {
  1002. return ZCL_STATUS_INVALID_IMAGE;
  1003. }
  1004. #if defined OTA_MMO_SIGN
  1005. if (zclOTA_ElementTag == OTA_ECDSA_SIGNATURE_TAG_ID)
  1006. {
  1007. if (zclOTA_ElementLen != OTA_SIGNATURE_LEN + Z_EXTADDR_LEN)
  1008. {
  1009. return ZCL_STATUS_INVALID_IMAGE;
  1010. }
  1011. }
  1012. else if (zclOTA_ElementTag == OTA_ECDSA_CERT_TAG_ID)
  1013. {
  1014. if (zclOTA_ElementLen != OTA_CERTIFICATE_LEN)
  1015. {
  1016. return ZCL_STATUS_INVALID_IMAGE;
  1017. }
  1018. }
  1019. #endif
  1020. break;
  1021. case ZCL_OTA_PD_ELEMENT_STATE:
  1022. #if defined OTA_MMO_SIGN
  1023. if (zclOTA_ElementTag == OTA_ECDSA_SIGNATURE_TAG_ID)
  1024. {
  1025. if (zclOTA_ElementPos < Z_EXTADDR_LEN)
  1026. zclOTA_SignerIEEE[zclOTA_ElementPos] = pData[i];
  1027. else
  1028. zclOTA_SignatureData[zclOTA_ElementPos - Z_EXTADDR_LEN] = pData[i];
  1029. }
  1030. else if (zclOTA_ElementTag == OTA_ECDSA_CERT_TAG_ID)
  1031. {
  1032. zclOTA_Certificate[zclOTA_ElementPos] = pData[i];
  1033. }
  1034. #endif
  1035. if (++zclOTA_ElementPos == zclOTA_ElementLen)
  1036. {
  1037. // Element is complete
  1038. if (zclOTA_ElementTag == OTA_UPGRADE_IMAGE_TAG_ID)
  1039. {
  1040. // The serial flash can take up to 25 ms before it is ready for a read
  1041. uint32 k;
  1042. for (k=0; k<0xffff; k++)
  1043. {
  1044. asm("NOP");
  1045. }
  1046. // When the image is complete, verify CRC
  1047. if (HalOTAChkDL(HAL_OTA_CRC_OSET) != SUCCESS)
  1048. {
  1049. #if (defined HAL_LCD) && (HAL_LCD == TRUE)
  1050. HalLcdWriteString("OTA CRC Fail", HAL_LCD_LINE_3);
  1051. #endif
  1052. return ZCL_STATUS_INVALID_IMAGE;
  1053. }
  1054. }
  1055. zclOTA_ClientPdState = ZCL_OTA_PD_ELEM_TAG1_STATE;
  1056. }
  1057. break;
  1058. default:
  1059. break;
  1060. }
  1061. #if defined OTA_MMO_SIGN
  1062. // We need to skip the hash calculation on the signature element.
  1063. // When receiving a tag, we wait to receive the entire tag before
  1064. // adding the byte to the hash buffer because it could be the tag
  1065. // for the signature
  1066. if (zclOTA_ClientPdState == ZCL_OTA_PD_ELEM_TAG2_STATE)
  1067. {
  1068. skipHash = TRUE;
  1069. }
  1070. else if (zclOTA_ClientPdState == ZCL_OTA_PD_ELEM_LEN1_STATE)
  1071. {
  1072. if (zclOTA_ElementTag != OTA_ECDSA_SIGNATURE_TAG_ID)
  1073. {
  1074. // This tag is not for the signature.
  1075. // Put the Lower byte of the tag into the hash buffer now
  1076. // The high byte will be processed as usual below
  1077. zclOTA_DataToHash[zclOTA_HashPos++] = LO_UINT16(zclOTA_ElementTag);
  1078. // When the buffer reaches OTA_MMO_HASH_SIZE, update the Hash
  1079. if (zclOTA_HashPos == OTA_MMO_HASH_SIZE)
  1080. {
  1081. OTA_CalculateMmoR3(&zclOTA_MmoHash, zclOTA_DataToHash, OTA_MMO_HASH_SIZE, FALSE);
  1082. zclOTA_HashPos = 0;
  1083. }
  1084. skipHash = FALSE;
  1085. }
  1086. }
  1087. if (!skipHash)
  1088. {
  1089. // Maintain a buffer of data to hash
  1090. zclOTA_DataToHash[zclOTA_HashPos++] = pData[i];
  1091. // When the buffer reaches OTA_MMO_HASH_SIZE, update the Hash
  1092. if (zclOTA_HashPos == OTA_MMO_HASH_SIZE)
  1093. {
  1094. OTA_CalculateMmoR3(&zclOTA_MmoHash, zclOTA_DataToHash, OTA_MMO_HASH_SIZE, FALSE);
  1095. zclOTA_HashPos = 0;
  1096. }
  1097. }
  1098. #endif
  1099. // Check if the download is complete
  1100. if (++zclOTA_FileOffset >= zclOTA_DownloadedImageSize)
  1101. {
  1102. zclOTA_ImageUpgradeStatus = OTA_STATUS_COMPLETE;
  1103. #if defined OTA_MMO_SIGN
  1104. // Complete the hash calcualtion
  1105. OTA_CalculateMmoR3(&zclOTA_MmoHash, zclOTA_DataToHash, zclOTA_HashPos, TRUE);
  1106. // Validate the hash
  1107. if (OTA_ValidateSignature(zclOTA_MmoHash.hash, zclOTA_Certificate,
  1108. zclOTA_SignatureData, zclOTA_SignerIEEE) != ZSuccess)
  1109. return ZCL_STATUS_INVALID_IMAGE;
  1110. #endif
  1111. return ZSuccess;
  1112. }
  1113. }
  1114. return ZSuccess;
  1115. }
  1116. /******************************************************************************
  1117. * @fn zclOTA_ProcessImageNotify
  1118. *
  1119. * @brief Process received Image Notify command.
  1120. *
  1121. * @param pInMsg - pointer to the incoming message
  1122. *
  1123. * @return ZStatus_t
  1124. */
  1125. static ZStatus_t zclOTA_ProcessImageNotify( zclIncoming_t *pInMsg )
  1126. {
  1127. zclOTA_ImageNotifyParams_t param;
  1128. zclOTA_QueryNextImageReqParams_t req;
  1129. uint8 *pData;
  1130. // verify message length
  1131. if ((pInMsg->pDataLen > PAYLOAD_MAX_LEN_IMAGE_NOTIFY) ||
  1132. (pInMsg->pDataLen < PAYLOAD_MIN_LEN_IMAGE_NOTIFY))
  1133. {
  1134. // no further processing if invalid
  1135. return ZCL_STATUS_MALFORMED_COMMAND;
  1136. }
  1137. // verify in 'normal' state
  1138. if ((zclOTA_Permit == FALSE) ||
  1139. (zclOTA_ImageUpgradeStatus != OTA_STATUS_NORMAL))
  1140. {
  1141. return ZFailure;
  1142. }
  1143. // parse message
  1144. pData = pInMsg->pData;
  1145. param.payloadType = *pData++;
  1146. param.queryJitter = *pData++;
  1147. param.fileId.manufacturer = BUILD_UINT16(pData[0], pData[1]);
  1148. pData += 2;
  1149. param.fileId.type = BUILD_UINT16(pData[0], pData[1]);
  1150. pData += 2;
  1151. param.fileId.version = osal_build_uint32( pData, 4 );
  1152. // if message is broadcast
  1153. if (pInMsg->msg->wasBroadcast)
  1154. {
  1155. // verify manufacturer
  1156. if ((param.payloadType >= NOTIFY_PAYLOAD_JITTER_MFG) &&
  1157. (param.fileId.manufacturer != zclOTA_ManufacturerId))
  1158. {
  1159. return ZSuccess;
  1160. }
  1161. // verify image type
  1162. if ((param.payloadType >= NOTIFY_PAYLOAD_JITTER_MFG_TYPE) &&
  1163. (param.fileId.type != zclOTA_ImageType))
  1164. {
  1165. return ZSuccess;
  1166. }
  1167. // verify version; if version matches ignore
  1168. if ((param.payloadType >= NOTIFY_PAYLOAD_JITTER_MFG_TYPE_VERS) &&
  1169. (param.fileId.version == zclOTA_CurrentFileVersion))
  1170. {
  1171. return ZSuccess;
  1172. }
  1173. // get random value and compare to query jitter
  1174. if (((uint8) osal_rand() % 100) > param.queryJitter)
  1175. {
  1176. // if greater than query jitter ignore;
  1177. return ZSuccess;
  1178. }
  1179. }
  1180. // if unicast message, or broadcast and still made it here, send query next image
  1181. req.fieldControl = 0;
  1182. req.fileId.manufacturer = zclOTA_ManufacturerId;
  1183. req.fileId.type = zclOTA_ImageType;
  1184. req.fileId.version = zclOTA_CurrentFileVersion;
  1185. zclOTA_SendQueryNextImageReq( &(pInMsg->msg->srcAddr), &req);
  1186. return ZSuccess;
  1187. }
  1188. /******************************************************************************
  1189. * @fn zclOTA_ProcessQueryNextImageRsp
  1190. *
  1191. * @brief Process received Query Next Image Response.
  1192. *
  1193. * @param pInMsg - pointer to the incoming message
  1194. *
  1195. * @return ZStatus_t
  1196. */
  1197. static ZStatus_t zclOTA_ProcessQueryNextImageRsp( zclIncoming_t *pInMsg )
  1198. {
  1199. zclOTA_QueryImageRspParams_t param;
  1200. uint8 *pData;
  1201. uint8 status = ZFailure;
  1202. // verify message length
  1203. if ((pInMsg->pDataLen != PAYLOAD_MAX_LEN_QUERY_NEXT_IMAGE_RSP) &&
  1204. (pInMsg->pDataLen != PAYLOAD_MIN_LEN_QUERY_NEXT_IMAGE_RSP))
  1205. {
  1206. // no further processing if invalid
  1207. return ZCL_STATUS_MALFORMED_COMMAND;
  1208. }
  1209. // ignore message if in 'download in progress' state
  1210. if (zclOTA_ImageUpgradeStatus == OTA_STATUS_IN_PROGRESS)
  1211. {
  1212. return ZSuccess;
  1213. }
  1214. // get status
  1215. pData = pInMsg->pData;
  1216. param.status = *pData++;
  1217. // if status is success
  1218. if (param.status == ZCL_STATUS_SUCCESS)
  1219. {
  1220. // parse message
  1221. param.fileId.manufacturer = BUILD_UINT16(pData[0], pData[1]);
  1222. pData += 2;
  1223. param.fileId.type = BUILD_UINT16(pData[0], pData[1]);
  1224. pData += 2;
  1225. param.fileId.version = osal_build_uint32( pData, 4 );
  1226. pData += 4;
  1227. param.imageSize = osal_build_uint32( pData, 4 );
  1228. // verify manufacturer id and image type
  1229. if ((param.fileId.type == zclOTA_ImageType) &&
  1230. (param.fileId.manufacturer == zclOTA_ManufacturerId))
  1231. {
  1232. // store file version and image size
  1233. zclOTA_DownloadedFileVersion = param.fileId.version;
  1234. zclOTA_DownloadedImageSize = param.imageSize;
  1235. // initialize other variables
  1236. zclOTA_FileOffset = 0;
  1237. zclOTA_ClientPdState = ZCL_OTA_PD_MAGIC_0_STATE;
  1238. // set state to 'in progress'
  1239. zclOTA_ImageUpgradeStatus = OTA_STATUS_IN_PROGRESS;
  1240. // store server address
  1241. zclOTA_serverAddr = pInMsg->msg->srcAddr;
  1242. // Store the file ID
  1243. osal_memcpy(&zclOTA_CurrentDlFileId, &param.fileId, sizeof(zclOTA_FileID_t));
  1244. // send image block request
  1245. sendImageBlockReq(&(pInMsg->msg->srcAddr));
  1246. status = ZCL_STATUS_CMD_HAS_RSP;
  1247. // Request the IEEE address of the server to put into the
  1248. // ATTRID_UPGRADE_SERVER_ID attribute
  1249. ZDP_IEEEAddrReq(pInMsg->msg->srcAddr.addr.shortAddr, ZDP_ADDR_REQTYPE_SINGLE, 0, 0);
  1250. osal_stop_timerEx(zclOTA_TaskID, ZCL_OTA_IMAGE_QUERY_TO_EVT);
  1251. }
  1252. }
  1253. if (zclOTA_AppTask != 0xFF)
  1254. {
  1255. // Notify the application task of the failure
  1256. zclOTA_CallbackMsg_t *pMsg;
  1257. pMsg = (zclOTA_CallbackMsg_t*) osal_msg_allocate(sizeof(zclOTA_CallbackMsg_t));
  1258. if (pMsg)
  1259. {
  1260. pMsg->hdr.event = ZCL_OTA_CALLBACK_IND;
  1261. pMsg->hdr.status = param.status;
  1262. pMsg->ota_event = ZCL_OTA_START_CALLBACK;
  1263. osal_msg_send(zclOTA_AppTask, (uint8*) pMsg);
  1264. }
  1265. }
  1266. return status;
  1267. }
  1268. /******************************************************************************
  1269. * @fn zclOTA_ProcessImageBlockRsp
  1270. *
  1271. * @brief Process received Image Block Response.
  1272. *
  1273. * @param pInMsg - pointer to the incoming message
  1274. *
  1275. * @return ZStatus_t
  1276. */
  1277. static ZStatus_t zclOTA_ProcessImageBlockRsp( zclIncoming_t *pInMsg )
  1278. {
  1279. zclOTA_ImageBlockRspParams_t param;
  1280. zclOTA_UpgradeEndReqParams_t req;
  1281. uint8 *pData;
  1282. uint8 status = ZSuccess;
  1283. // verify in 'in progress' state
  1284. if (zclOTA_ImageUpgradeStatus != OTA_STATUS_IN_PROGRESS)
  1285. {
  1286. return ZSuccess;
  1287. }
  1288. // get status
  1289. pData = pInMsg->pData;
  1290. param.status = *pData++;
  1291. // if status is success
  1292. if (param.status == ZCL_STATUS_SUCCESS)
  1293. {
  1294. // verify message length
  1295. if (pInMsg->pDataLen < PAYLOAD_MAX_LEN_IMAGE_BLOCK_RSP)
  1296. {
  1297. // no further processing if invalid
  1298. return ZCL_STATUS_MALFORMED_COMMAND;
  1299. }
  1300. // parse message
  1301. param.rsp.success.fileId.manufacturer = BUILD_UINT16(pData[0], pData[1]);
  1302. pData += 2;
  1303. param.rsp.success.fileId.type = BUILD_UINT16(pData[0], pData[1]);
  1304. pData += 2;
  1305. param.rsp.success.fileId.version = osal_build_uint32( pData, 4 );
  1306. pData += 4;
  1307. param.rsp.success.fileOffset = osal_build_uint32( pData, 4 );
  1308. pData += 4;
  1309. param.rsp.success.dataSize = *pData++;
  1310. param.rsp.success.pData = pData;
  1311. // verify manufacturer, image type, file version, file offset
  1312. if ((param.rsp.success.fileId.type != zclOTA_ImageType) ||
  1313. (param.rsp.success.fileId.manufacturer != zclOTA_ManufacturerId) ||
  1314. (param.rsp.success.fileId.version != zclOTA_DownloadedFileVersion))
  1315. {
  1316. status = ZCL_STATUS_INVALID_IMAGE;
  1317. }
  1318. else
  1319. {
  1320. // Drop duplicate packets (retries)
  1321. if (param.rsp.success.fileOffset != zclOTA_FileOffset)
  1322. {
  1323. return ZSuccess;
  1324. }
  1325. status = zclOTA_ProcessImageData(param.rsp.success.pData, param.rsp.success.dataSize);
  1326. // Stop the timer and clear the retry count
  1327. zclOTA_BlockRetry = 0;
  1328. osal_stop_timerEx(zclOTA_TaskID, ZCL_OTA_BLOCK_RSP_TO_EVT);
  1329. if (status == ZSuccess)
  1330. {
  1331. if (zclOTA_ImageUpgradeStatus == OTA_STATUS_COMPLETE)
  1332. {
  1333. // send upgrade end req with success status
  1334. osal_memcpy(&req.fileId, &param.rsp.success.fileId, sizeof(zclOTA_FileID_t));
  1335. req.status = ZSuccess;
  1336. zclOTA_SendUpgradeEndReq( &(pInMsg->msg->srcAddr), &req );
  1337. }
  1338. else
  1339. {
  1340. sendImageBlockReq(&(pInMsg->msg->srcAddr));
  1341. }
  1342. }
  1343. }
  1344. }
  1345. // else if status is 'wait for data'
  1346. else if (param.status == ZCL_STATUS_WAIT_FOR_DATA)
  1347. {
  1348. // verify message length
  1349. if (pInMsg->pDataLen != PAYLOAD_MIN_LEN_IMAGE_BLOCK_WAIT)
  1350. {
  1351. // no further processing if invalid
  1352. return ZCL_STATUS_MALFORMED_COMMAND;
  1353. }
  1354. // parse message
  1355. param.rsp.wait.currentTime = osal_build_uint32( pData, 4 );
  1356. pData += 4;
  1357. param.rsp.wait.requestTime = osal_build_uint32( pData, 4 );
  1358. // Stop the timer and clear the retry count
  1359. zclOTA_BlockRetry = 0;
  1360. osal_stop_timerEx(zclOTA_TaskID, ZCL_OTA_BLOCK_RSP_TO_EVT);
  1361. // set timer for next image block req
  1362. zclOTA_StartTimer(ZCL_OTA_IMAGE_BLOCK_WAIT_EVT,
  1363. (param.rsp.wait.requestTime - param.rsp.wait.currentTime));
  1364. }
  1365. else if (param.status == ZCL_STATUS_ABORT)
  1366. {
  1367. // download aborted; set state to 'normal' state
  1368. zclOTA_ImageUpgradeStatus = OTA_STATUS_NORMAL;
  1369. // Stop the timer and clear the retry count
  1370. zclOTA_BlockRetry = 0;
  1371. osal_stop_timerEx(zclOTA_TaskID, ZCL_OTA_BLOCK_RSP_TO_EVT);
  1372. zclOTA_UpgradeComplete(ZOtaAbort);
  1373. return ZSuccess;
  1374. }
  1375. else
  1376. {
  1377. return ZCL_STATUS_MALFORMED_COMMAND;
  1378. }
  1379. if (status != ZSuccess)
  1380. {
  1381. // download failed; set state to 'normal'
  1382. zclOTA_ImageUpgradeStatus = OTA_STATUS_NORMAL;
  1383. // send upgrade end req with failure status
  1384. osal_memcpy(&req.fileId, &param.rsp.success.fileId, sizeof(zclOTA_FileID_t));
  1385. req.status = status;
  1386. zclOTA_SendUpgradeEndReq( &(pInMsg->msg->srcAddr), &req );
  1387. }
  1388. return ZSuccess;
  1389. }
  1390. /******************************************************************************
  1391. * @fn zclOTA_ProcessUpgradeEndRsp
  1392. *
  1393. * @brief Process received Upgrade End Response.
  1394. *
  1395. * @param pInMsg - pointer to the incoming message
  1396. *
  1397. * @return ZStatus_t
  1398. */
  1399. static ZStatus_t zclOTA_ProcessUpgradeEndRsp( zclIncoming_t *pInMsg )
  1400. {
  1401. zclOTA_UpgradeEndRspParams_t param;
  1402. zclOTA_FileID_t currentFileId = {zclOTA_ManufacturerId, zclOTA_ImageType, zclOTA_DownloadedFileVersion};
  1403. uint8 *pData;
  1404. // verify message length
  1405. if (pInMsg->pDataLen != PAYLOAD_MAX_LEN_UPGRADE_END_RSP)
  1406. {
  1407. // no further processing if invalid
  1408. return ZCL_STATUS_MALFORMED_COMMAND;
  1409. }
  1410. // parse message
  1411. pData = pInMsg->pData;
  1412. param.fileId.manufacturer = BUILD_UINT16(pData[0], pData[1]);
  1413. pData += 2;
  1414. param.fileId.type = BUILD_UINT16(pData[0], pData[1]);
  1415. pData += 2;
  1416. param.fileId.version = osal_build_uint32( pData, 4 );
  1417. pData += 4;
  1418. param.currentTime = osal_build_uint32( pData, 4 );
  1419. pData += 4;
  1420. param.upgradeTime = osal_build_uint32( pData, 4 );
  1421. // verify in 'download complete' or 'waiting for upgrade' state
  1422. if ((zclOTA_ImageUpgradeStatus == OTA_STATUS_COMPLETE) ||
  1423. ((zclOTA_ImageUpgradeStatus == OTA_STATUS_UPGRADE_WAIT) && (param.upgradeTime!=OTA_UPGRADE_TIME_WAIT)))
  1424. {
  1425. // verify manufacturer, image type
  1426. if (zclOTA_CmpFileId(&param.fileId, &currentFileId) == FALSE)
  1427. {
  1428. return ZSuccess;
  1429. }
  1430. // check upgrade time
  1431. if (param.upgradeTime != OTA_UPGRADE_TIME_WAIT)
  1432. {
  1433. uint32 notifyDelay = 0;
  1434. if (param.upgradeTime > param.currentTime)
  1435. {
  1436. // time to wait before notification
  1437. notifyDelay = param.upgradeTime - param.currentTime;
  1438. }
  1439. // set state to 'countdown'
  1440. zclOTA_ImageUpgradeStatus = OTA_STATUS_COUNTDOWN;
  1441. // set timer for upgrade complete notification
  1442. zclOTA_StartTimer(ZCL_OTA_UPGRADE_WAIT_EVT, notifyDelay);
  1443. }
  1444. else
  1445. {
  1446. // Wait for another upgrade end response
  1447. zclOTA_ImageUpgradeStatus = OTA_STATUS_UPGRADE_WAIT;
  1448. // Set a timer for 60 minutes to send another Upgrade End Rsp
  1449. zclOTA_StartTimer(ZCL_OTA_UPGRADE_WAIT_EVT, 3600);
  1450. zclOTA_UpgradeEndRetry = 0;
  1451. }
  1452. }
  1453. return ZSuccess;
  1454. }
  1455. /******************************************************************************
  1456. * @fn zclOTA_ProcessQuerySpecificFileRsp
  1457. *
  1458. * @brief Process received Query Specific File Response.
  1459. *
  1460. * @param pInMsg - pointer to the incoming message
  1461. *
  1462. * @return ZStatus_t
  1463. */
  1464. static ZStatus_t zclOTA_ProcessQuerySpecificFileRsp( zclIncoming_t *pInMsg )
  1465. {
  1466. zclOTA_QueryImageRspParams_t param;
  1467. uint8 *pData;
  1468. // verify message length
  1469. if ((pInMsg->pDataLen != PAYLOAD_MAX_LEN_QUERY_SPECIFIC_FILE_RSP) &&
  1470. (pInMsg->pDataLen != PAYLOAD_MIN_LEN_QUERY_SPECIFIC_FILE_RSP))
  1471. {
  1472. // no further processing if invalid
  1473. return ZCL_STATUS_MALFORMED_COMMAND;
  1474. }
  1475. // ignore message if in 'download in progress' state
  1476. if (zclOTA_ImageUpgradeStatus == OTA_STATUS_IN_PROGRESS)
  1477. {
  1478. return ZSuccess;
  1479. }
  1480. // get status
  1481. pData = pInMsg->pData;
  1482. param.status = *pData++;
  1483. // if status is success
  1484. if (param.status == ZCL_STATUS_SUCCESS)
  1485. {
  1486. // parse message
  1487. param.fileId.manufacturer = BUILD_UINT16(pData[0], pData[1]);
  1488. pData += 2;
  1489. param.fileId.type = BUILD_UINT16(pData[0], pData[1]);
  1490. pData += 2;
  1491. param.fileId.version = osal_build_uint32( pData, 4 );
  1492. pData += 4;
  1493. param.imageSize = osal_build_uint32( pData, 4 );
  1494. // verify manufacturer id and image type
  1495. if ((param.fileId.type == zclOTA_ImageType) &&
  1496. (param.fileId.manufacturer == zclOTA_ManufacturerId))
  1497. {
  1498. // store file version and image size
  1499. zclOTA_DownloadedFileVersion = param.fileId.version;
  1500. zclOTA_DownloadedImageSize = param.imageSize;
  1501. // initialize other variables
  1502. zclOTA_FileOffset = 0;
  1503. // set state to 'in progress'
  1504. zclOTA_ImageUpgradeStatus = OTA_STATUS_IN_PROGRESS;
  1505. // send image block request
  1506. sendImageBlockReq(&(pInMsg->msg->srcAddr));
  1507. }
  1508. }
  1509. return ZSuccess;
  1510. }
  1511. /******************************************************************************
  1512. * @fn zclOTA_ClientHdlIncoming
  1513. *
  1514. * @brief Handle incoming client commands.
  1515. *
  1516. * @param pInMsg - pointer to the incoming message
  1517. *
  1518. * @return ZStatus_t
  1519. */
  1520. static ZStatus_t zclOTA_ClientHdlIncoming( zclIncoming_t *pInMsg )
  1521. {
  1522. switch (pInMsg->hdr.commandID)
  1523. {
  1524. case COMMAND_IMAGE_NOTIFY:
  1525. return zclOTA_ProcessImageNotify( pInMsg );
  1526. case COMMAND_QUERY_NEXT_IMAGE_RSP:
  1527. return zclOTA_ProcessQueryNextImageRsp( pInMsg );
  1528. case COMMAND_IMAGE_BLOCK_RSP:
  1529. return zclOTA_ProcessImageBlockRsp( pInMsg );
  1530. case COMMAND_UPGRADE_END_RSP:
  1531. return zclOTA_ProcessUpgradeEndRsp( pInMsg );
  1532. case COMMAND_QUERY_SPECIFIC_FILE_RSP:
  1533. return zclOTA_ProcessQuerySpecificFileRsp( pInMsg );
  1534. default:
  1535. return ZFailure;
  1536. }
  1537. }
  1538. /******************************************************************************
  1539. * @fn zclOTA_CmpFileId
  1540. *
  1541. * @brief Called to compare two file IDs
  1542. *
  1543. * @param f1, f2 - Pointers to the two file IDs to compare
  1544. *
  1545. * @return TRUE if the file IDs are the same, else FALSE
  1546. */
  1547. static uint8 zclOTA_CmpFileId(zclOTA_FileID_t *f1, zclOTA_FileID_t *f2)
  1548. {
  1549. if ((f1->manufacturer == 0xFFFF) ||
  1550. (f2->manufacturer == 0xFFFF) ||
  1551. (f1->manufacturer == f2->manufacturer))
  1552. {
  1553. if ((f1->type == 0xFFFF) ||
  1554. (f2->type == 0xFFFF) ||
  1555. (f1->type == f2->type))
  1556. {
  1557. if ((f1->version == 0xFFFFFFFF) ||
  1558. (f2->version == 0xFFFFFFFF) ||
  1559. (f1->version == f2->version))
  1560. {
  1561. return TRUE;
  1562. }
  1563. }
  1564. }
  1565. return FALSE;
  1566. }
  1567. /******************************************************************************
  1568. * @fn zclOTA_ImageBlockWaitExpired
  1569. *
  1570. * @brief Perform action on image block wait timer expiration.
  1571. *
  1572. * @param none
  1573. *
  1574. * @return none
  1575. */
  1576. static void zclOTA_ImageBlockWaitExpired(void)
  1577. {
  1578. // verify in 'in progress' state
  1579. if (zclOTA_ImageUpgradeStatus == OTA_STATUS_IN_PROGRESS)
  1580. {
  1581. // request next block
  1582. sendImageBlockReq(&zclOTA_serverAddr);
  1583. }
  1584. }
  1585. /******************************************************************************
  1586. * @fn zclOTA_UpgradeComplete
  1587. *
  1588. * @brief Notify the application task that an upgrade has completed.
  1589. *
  1590. * @param status - The status of the upgrade
  1591. *
  1592. * @return none
  1593. */
  1594. static void zclOTA_UpgradeComplete(uint8 status)
  1595. {
  1596. // Go back to the normal state
  1597. zclOTA_ImageUpgradeStatus = OTA_STATUS_NORMAL;
  1598. if ((zclOTA_DownloadedImageSize == OTA_HEADER_LEN_MIN_ECDSA) ||
  1599. (zclOTA_DownloadedImageSize == OTA_HEADER_LEN_MIN))
  1600. {
  1601. status = ZFailure;
  1602. }
  1603. if (zclOTA_AppTask != 0xFF)
  1604. {
  1605. // Notify the application task the upgrade stopped
  1606. zclOTA_CallbackMsg_t *pMsg;
  1607. pMsg = (zclOTA_CallbackMsg_t*) osal_msg_allocate(sizeof(zclOTA_CallbackMsg_t));
  1608. if (pMsg)
  1609. {
  1610. pMsg->hdr.event = ZCL_OTA_CALLBACK_IND;
  1611. pMsg->hdr.status = status;
  1612. pMsg->ota_event = ZCL_OTA_DL_COMPLETE_CALLBACK;
  1613. osal_msg_send(zclOTA_AppTask, (uint8*) pMsg);
  1614. }
  1615. }
  1616. }
  1617. /******************************************************************************
  1618. * @fn zclOTA_ProcessZDOMsgs
  1619. *
  1620. * @brief Process callbacks from the ZDO.
  1621. *
  1622. * @param pMsg - a Pointer to the message from the ZDO
  1623. *
  1624. * @return none
  1625. */
  1626. static void zclOTA_ProcessZDOMsgs( zdoIncomingMsg_t *pMsg )
  1627. {
  1628. if (pMsg->clusterID == IEEE_addr_rsp)
  1629. {
  1630. ZDO_NwkIEEEAddrResp_t *pNwkAddrRsp = ZDO_ParseAddrRsp( pMsg );
  1631. // If this is from the OTA server, record the server's IEEE address
  1632. if (pNwkAddrRsp != NULL)
  1633. {
  1634. if (pNwkAddrRsp->nwkAddr == zclOTA_serverAddr.addr.shortAddr)
  1635. {
  1636. osal_memcpy(&zclOTA_UpgradeServerID, pNwkAddrRsp->extAddr, Z_EXTADDR_LEN);
  1637. }
  1638. osal_mem_free( pNwkAddrRsp );
  1639. }
  1640. }
  1641. }
  1642. #endif // OTA_CLIENT
  1643. #if defined (OTA_SERVER) && (OTA_SERVER == TRUE)
  1644. /******************************************************************************
  1645. * @fn zclOTA_ProcessNextImgRsp
  1646. *
  1647. * @brief Handles a response to a MT_OTA_NEXT_IMG_RSP.
  1648. *
  1649. * @param pMsg - The data from the server.
  1650. * pFileId - The ID of the OTA File.
  1651. * pAddr - The source of the message.
  1652. *
  1653. * @return none
  1654. */
  1655. void zclOTA_ProcessNextImgRsp(uint8* pMsg, zclOTA_FileID_t *pFileId,
  1656. afAddrType_t *pAddr)
  1657. {
  1658. zclOTA_QueryImageRspParams_t queryRsp;
  1659. uint8 options;
  1660. uint8 status;
  1661. // Get the status of the operation
  1662. status = *pMsg++;
  1663. // Get the options
  1664. options = *pMsg++;
  1665. // Copy the file ID
  1666. osal_memcpy(&queryRsp.fileId, pFileId, sizeof(zclOTA_FileID_t));
  1667. // Set the image size
  1668. if (status == ZSuccess)
  1669. {
  1670. queryRsp.status = ZSuccess;
  1671. queryRsp.imageSize = BUILD_UINT32(pMsg[0], pMsg[1], pMsg[2], pMsg[3]);
  1672. }
  1673. else
  1674. {
  1675. queryRsp.status = ZOtaNoImageAvailable;
  1676. queryRsp.imageSize = 0;
  1677. }
  1678. queryResponse = queryRsp; // save global variable for query image response. Used later in image block request check
  1679. // Send a response to the client
  1680. if (options & MT_OTA_QUERY_SPECIFIC_OPTION)
  1681. {
  1682. zclOTA_SendQuerySpecificFileRsp(pAddr, &queryRsp);
  1683. }
  1684. else
  1685. {
  1686. zclOTA_SendQueryNextImageRsp(pAddr, &queryRsp);
  1687. }
  1688. }
  1689. /******************************************************************************
  1690. * @fn zclOTA_ProcessFileReadRsp
  1691. *
  1692. * @brief Handles a response to a MT_OTA_FILE_READ_RSP.
  1693. *
  1694. * @param pMsg - The data from the server.
  1695. * pFileId - The ID of the OTA File.
  1696. * pAddr - The source of the message.
  1697. *
  1698. * @return none
  1699. */
  1700. void zclOTA_ProcessFileReadRsp(uint8* pMsg, zclOTA_FileID_t *pFileId,
  1701. afAddrType_t *pAddr)
  1702. {
  1703. zclOTA_ImageBlockRspParams_t blockRsp;
  1704. // Set the status
  1705. blockRsp.status = *pMsg++;
  1706. // Check the status of the file read
  1707. if (blockRsp.status == ZSuccess)
  1708. {
  1709. // Fill in the response parameters
  1710. osal_memcpy(&blockRsp.rsp.success.fileId, pFileId, sizeof(zclOTA_FileID_t));
  1711. blockRsp.rsp.success.fileOffset = BUILD_UINT32(pMsg[0], pMsg[1], pMsg[2], pMsg[3]);
  1712. pMsg += 4;
  1713. blockRsp.rsp.success.dataSize = *pMsg++;
  1714. blockRsp.rsp.success.pData = pMsg;
  1715. }
  1716. else
  1717. {
  1718. blockRsp.status = ZOtaAbort;
  1719. }
  1720. // Send the block response to the peer
  1721. zclOTA_SendImageBlockRsp(pAddr, &blockRsp);
  1722. }
  1723. /******************************************************************************
  1724. * @fn OTA_HandleFileSysCb
  1725. *
  1726. * @brief Handles File Server Callbacks.
  1727. *
  1728. * @param pMSGpkt - The data from the server.
  1729. *
  1730. * @return none
  1731. */
  1732. void zclOTA_ServerHandleFileSysCb(OTA_MtMsg_t* pMSGpkt)
  1733. {
  1734. zclOTA_FileID_t pFileId;
  1735. afAddrType_t pAddr;
  1736. uint8 *pMsg;
  1737. if (pMSGpkt != NULL)
  1738. {
  1739. // Get the File ID and AF Address
  1740. pMsg = pMSGpkt->data;
  1741. pMsg = OTA_StreamToFileId(&pFileId, pMsg);
  1742. pMsg = OTA_StreamToAfAddr(&pAddr, pMsg);
  1743. switch(pMSGpkt->cmd)
  1744. {
  1745. case MT_OTA_NEXT_IMG_RSP:
  1746. zclOTA_ProcessNextImgRsp(pMsg, &pFileId, &pAddr);
  1747. break;
  1748. case MT_OTA_FILE_READ_RSP:
  1749. zclOTA_ProcessFileReadRsp(pMsg, &pFileId, &pAddr);
  1750. break;
  1751. default:
  1752. break;
  1753. }
  1754. }
  1755. }
  1756. /******************************************************************************
  1757. * @fn zclOTA_Srv_QueryNextImageReq
  1758. *
  1759. * @brief Handle a Query Next Image Request.
  1760. *
  1761. * @param pSrcAddr - The source of the message
  1762. * pParam - message parameters
  1763. *
  1764. * @return ZStatus_t
  1765. *
  1766. * @note On a query next image, we must request a file listing
  1767. * from the File Server. Then open a file if
  1768. */
  1769. ZStatus_t zclOTA_Srv_QueryNextImageReq(afAddrType_t *pSrcAddr, zclOTA_QueryNextImageReqParams_t *pParam)
  1770. {
  1771. uint8 options = 0;
  1772. uint8 status;
  1773. if (zclOTA_Permit)
  1774. {
  1775. if (pParam->fieldControl)
  1776. {
  1777. options |= MT_OTA_HW_VER_PRESENT_OPTION;
  1778. }
  1779. // Request the next image for this device from the console via the MT File System
  1780. status = MT_OtaGetImage(pSrcAddr, &pParam->fileId, pParam->hardwareVersion, NULL, options);
  1781. }
  1782. else
  1783. {
  1784. status = ZOtaNoImageAvailable;
  1785. }
  1786. if (status != ZSuccess)
  1787. {
  1788. zclOTA_QueryImageRspParams_t queryRsp;
  1789. // Fill in the response parameters
  1790. osal_memcpy(&queryRsp.fileId, &pParam->fileId, sizeof(zclOTA_FileID_t));
  1791. queryRsp.status = ZOtaNoImageAvailable;
  1792. queryRsp.imageSize = 0;
  1793. // Send a failure response to the client
  1794. zclOTA_SendQueryNextImageRsp(pSrcAddr, &queryRsp);
  1795. }
  1796. return ZCL_STATUS_CMD_HAS_RSP;
  1797. }
  1798. /******************************************************************************
  1799. * @fn zclOTA_Srv_ImageBlockReq
  1800. *
  1801. * @brief Handle an Image Block Request.
  1802. *
  1803. * @param pSrcAddr - The source of the message
  1804. * pParam - message parameters
  1805. *
  1806. * @return ZStatus_t
  1807. */
  1808. ZStatus_t zclOTA_Srv_ImageBlockReq(afAddrType_t *pSrcAddr, zclOTA_ImageBlockReqParams_t *pParam)
  1809. {
  1810. uint8 status = ZFailure;
  1811. if (pParam->fileId.version != queryResponse.fileId.version)
  1812. {
  1813. status = ZCL_STATUS_NO_IMAGE_AVAILABLE;
  1814. }
  1815. else
  1816. {
  1817. if (zclOTA_Permit && (pParam != NULL))
  1818. {
  1819. uint8 len = pParam->maxDataSize;
  1820. if (len > OTA_MAX_MTU)
  1821. {
  1822. len = OTA_MAX_MTU;
  1823. }
  1824. // Read the data from the OTA Console
  1825. status = MT_OtaFileReadReq(pSrcAddr, &pParam->fileId, len, pParam->fileOffset);
  1826. // Send a wait response to the client
  1827. if (status != ZSuccess)
  1828. {
  1829. zclOTA_ImageBlockRspParams_t blockRsp;
  1830. // Fill in the response parameters
  1831. blockRsp.status = ZOtaWaitForData;
  1832. osal_memcpy(&blockRsp.rsp.success.fileId, &pParam->fileId, sizeof(zclOTA_FileID_t));
  1833. blockRsp.rsp.wait.currentTime = 0;
  1834. blockRsp.rsp.wait.requestTime = OTA_SEND_BLOCK_WAIT;
  1835. // Send the block to the peer
  1836. zclOTA_SendImageBlockRsp(pSrcAddr, &blockRsp);
  1837. }
  1838. status = ZCL_STATUS_CMD_HAS_RSP;
  1839. }
  1840. }
  1841. return status;
  1842. }
  1843. /******************************************************************************
  1844. * @fn zclOTA_Srv_ImagePageReq
  1845. *
  1846. * @brief Handle an Image Page Request. Note: Not currently supported.
  1847. *
  1848. * @param pSrcAddr - The source of the message
  1849. * pParam - message parameters
  1850. *
  1851. * @return ZStatus_t
  1852. */
  1853. ZStatus_t zclOTA_Srv_ImagePageReq(afAddrType_t *pSrcAddr, zclOTA_ImagePageReqParams_t *pParam)
  1854. {
  1855. // Send not supported resposne
  1856. return ZUnsupClusterCmd;
  1857. }
  1858. /******************************************************************************
  1859. * @fn zclOTA_Srv_UpgradeEndReq
  1860. *
  1861. * @brief Handle an Upgrade End Request.
  1862. *
  1863. * @param pSrcAddr - The source of the message
  1864. * pParam - message parameters
  1865. *
  1866. * @return ZStatus_t
  1867. */
  1868. ZStatus_t zclOTA_Srv_UpgradeEndReq(afAddrType_t *pSrcAddr, zclOTA_UpgradeEndReqParams_t *pParam)
  1869. {
  1870. uint8 status = ZFailure;
  1871. if (zclOTA_Permit && (pParam != NULL))
  1872. {
  1873. zclOTA_UpgradeEndRspParams_t rspParms;
  1874. if (pParam->status == ZSuccess)
  1875. {
  1876. osal_memcpy(&rspParms.fileId, &pParam->fileId, sizeof(zclOTA_FileID_t));
  1877. rspParms.currentTime = osal_GetSystemClock();
  1878. rspParms.upgradeTime = rspParms.currentTime + OTA_UPGRADE_DELAY;
  1879. // Send the response to the peer
  1880. zclOTA_SendUpgradeEndRsp(pSrcAddr, &rspParms);
  1881. }
  1882. // Notify the Console Tool
  1883. MT_OtaSendStatus(pSrcAddr->addr.shortAddr, MT_OTA_DL_COMPLETE, pParam->status, 0);
  1884. status = ZCL_STATUS_CMD_HAS_RSP;
  1885. }
  1886. return status;
  1887. }
  1888. /******************************************************************************
  1889. * @fn zclOTA_Srv_QuerySpecificFileReq
  1890. *
  1891. * @brief Handles a Query Specific File Request.
  1892. *
  1893. * @param pSrcAddr - The source of the message
  1894. * pParam - message parameters
  1895. *
  1896. * @return ZStatus_t
  1897. */
  1898. ZStatus_t zclOTA_Srv_QuerySpecificFileReq(afAddrType_t *pSrcAddr, zclOTA_QuerySpecificFileReqParams_t *pParam)
  1899. {
  1900. uint8 status;
  1901. // Request the image from the console
  1902. if (zclOTA_Permit)
  1903. {
  1904. status = MT_OtaGetImage(pSrcAddr, &pParam->fileId, 0, pParam->nodeAddr, MT_OTA_QUERY_SPECIFIC_OPTION);
  1905. }
  1906. else
  1907. {
  1908. status = ZOtaNoImageAvailable;
  1909. }
  1910. if (status != ZSuccess)
  1911. {
  1912. zclOTA_QueryImageRspParams_t queryRsp;
  1913. // Fill in the response parameters
  1914. osal_memcpy(&queryRsp.fileId, &pParam->fileId, sizeof(zclOTA_FileID_t));
  1915. queryRsp.status = ZOtaNoImageAvailable;
  1916. queryRsp.imageSize = 0;
  1917. // Send a failure response to the client
  1918. zclOTA_SendQuerySpecificFileRsp(pSrcAddr, &queryRsp);
  1919. }
  1920. return ZCL_STATUS_CMD_HAS_RSP;
  1921. }
  1922. /******************************************************************************
  1923. * @fn zclOTA_ProcessQueryNextImageReq
  1924. *
  1925. * @brief Process received Query Next Image Request.
  1926. *
  1927. * @param pInMsg - pointer to the incoming message
  1928. *
  1929. * @return ZStatus_t
  1930. */
  1931. static ZStatus_t zclOTA_ProcessQueryNextImageReq( zclIncoming_t *pInMsg )
  1932. {
  1933. zclOTA_QueryNextImageReqParams_t param;
  1934. uint8 *pData;
  1935. /* verify message length */
  1936. if ((pInMsg->pDataLen != PAYLOAD_MAX_LEN_QUERY_NEXT_IMAGE_REQ) &&
  1937. (pInMsg->pDataLen != PAYLOAD_MIN_LEN_QUERY_NEXT_IMAGE_REQ))
  1938. {
  1939. /* no further processing if invalid */
  1940. return ZCL_STATUS_MALFORMED_COMMAND;
  1941. }
  1942. /* parse message parameters */
  1943. pData = pInMsg->pData;
  1944. param.fieldControl = *pData++;
  1945. param.fileId.manufacturer = BUILD_UINT16(pData[0], pData[1]);
  1946. pData += 2;
  1947. param.fileId.type = BUILD_UINT16(pData[0], pData[1]);
  1948. pData += 2;
  1949. param.fileId.version = osal_build_uint32( pData, 4 );
  1950. pData += 4;
  1951. if ((param.fieldControl & 0x01) != 0)
  1952. {
  1953. param.hardwareVersion = BUILD_UINT16(pData[0], pData[1]);
  1954. }
  1955. /* call callback */
  1956. return zclOTA_Srv_QueryNextImageReq(&pInMsg->msg->srcAddr, &param);
  1957. }
  1958. /******************************************************************************
  1959. * @fn zclOTA_ProcessImageBlockReq
  1960. *
  1961. * @brief Process received Image Block Request.
  1962. *
  1963. * @param pInMsg - pointer to the incoming message
  1964. *
  1965. * @return ZStatus_t
  1966. */
  1967. static ZStatus_t zclOTA_ProcessImageBlockReq( zclIncoming_t *pInMsg )
  1968. {
  1969. zclOTA_ImageBlockReqParams_t param;
  1970. uint8 *pData;
  1971. /* verify message length */
  1972. if ((pInMsg->pDataLen != PAYLOAD_MAX_LEN_IMAGE_BLOCK_REQ) &&
  1973. (pInMsg->pDataLen != PAYLOAD_MIN_LEN_IMAGE_BLOCK_REQ))
  1974. {
  1975. /* no further processing if invalid */
  1976. return ZCL_STATUS_MALFORMED_COMMAND;
  1977. }
  1978. /* parse message parameters */
  1979. pData = pInMsg->pData;
  1980. param.fieldControl = *pData++;
  1981. param.fileId.manufacturer = BUILD_UINT16(pData[0], pData[1]);
  1982. pData += 2;
  1983. param.fileId.type = BUILD_UINT16(pData[0], pData[1]);
  1984. pData += 2;
  1985. param.fileId.version = osal_build_uint32( pData, 4 );
  1986. pData += 4;
  1987. param.fileOffset = osal_build_uint32( pData, 4 );
  1988. pData += 4;
  1989. param.maxDataSize = *pData++;
  1990. if ((param.fieldControl & 0x01) != 0)
  1991. {
  1992. osal_cpyExtAddr(param.nodeAddr, pData);
  1993. }
  1994. /* call callback */
  1995. return zclOTA_Srv_ImageBlockReq(&pInMsg->msg->srcAddr, &param);
  1996. }
  1997. /******************************************************************************
  1998. * @fn zclOTA_ProcessImagePageReq
  1999. *
  2000. * @brief Process received Image Page Request.
  2001. *
  2002. * @param pInMsg - pointer to the incoming message
  2003. *
  2004. * @return ZStatus_t
  2005. */
  2006. static ZStatus_t zclOTA_ProcessImagePageReq( zclIncoming_t *pInMsg )
  2007. {
  2008. zclOTA_ImagePageReqParams_t param;
  2009. uint8 *pData;
  2010. /* verify message length */
  2011. if ((pInMsg->pDataLen != PAYLOAD_MAX_LEN_IMAGE_PAGE_REQ) &&
  2012. (pInMsg->pDataLen != PAYLOAD_MIN_LEN_IMAGE_PAGE_REQ))
  2013. {
  2014. /* no further processing if invalid */
  2015. return ZCL_STATUS_MALFORMED_COMMAND;
  2016. }
  2017. /* parse message parameters */
  2018. pData = pInMsg->pData;
  2019. param.fieldControl = *pData++;
  2020. param.fileId.manufacturer = BUILD_UINT16(pData[0], pData[1]);
  2021. pData += 2;
  2022. param.fileId.type = BUILD_UINT16(pData[0], pData[1]);
  2023. pData += 2;
  2024. param.fileId.version = osal_build_uint32( pData, 4 );
  2025. pData += 4;
  2026. param.fileOffset = osal_build_uint32( pData, 4 );
  2027. pData += 4;
  2028. param.maxDataSize = *pData++;
  2029. param.pageSize = BUILD_UINT16(pData[0], pData[1]);
  2030. pData += 2;
  2031. param.responseSpacing = BUILD_UINT16(pData[0], pData[1]);
  2032. pData += 2;
  2033. if ((param.fieldControl & 0x01) != 0)
  2034. {
  2035. osal_cpyExtAddr(param.nodeAddr, pData);
  2036. }
  2037. /* call callback */
  2038. return zclOTA_Srv_ImagePageReq(&pInMsg->msg->srcAddr, &param);
  2039. }
  2040. /******************************************************************************
  2041. * @fn zclOTA_ProcessUpgradeEndReq
  2042. *
  2043. * @brief Process received Upgrade End Request.
  2044. *
  2045. * @param pInMsg - pointer to the incoming message
  2046. *
  2047. * @return ZStatus_t
  2048. */
  2049. static ZStatus_t zclOTA_ProcessUpgradeEndReq( zclIncoming_t *pInMsg )
  2050. {
  2051. zclOTA_UpgradeEndReqParams_t param;
  2052. uint8 *pData;
  2053. /* verify message length */
  2054. if ((pInMsg->pDataLen != PAYLOAD_MAX_LEN_UPGRADE_END_REQ) &&
  2055. (pInMsg->pDataLen != PAYLOAD_MIN_LEN_UPGRADE_END_REQ))
  2056. {
  2057. /* no further processing if invalid */
  2058. return ZCL_STATUS_MALFORMED_COMMAND;
  2059. }
  2060. /* parse message parameters */
  2061. pData = pInMsg->pData;
  2062. param.status = *pData++;
  2063. if (param.status == ZCL_STATUS_SUCCESS)
  2064. {
  2065. param.fileId.manufacturer = BUILD_UINT16(pData[0], pData[1]);
  2066. pData += 2;
  2067. param.fileId.type = BUILD_UINT16(pData[0], pData[1]);
  2068. pData += 2;
  2069. param.fileId.version = osal_build_uint32( pData, 4 );
  2070. }
  2071. /* call callback */
  2072. return zclOTA_Srv_UpgradeEndReq(&pInMsg->msg->srcAddr, &param);
  2073. }
  2074. /******************************************************************************
  2075. * @fn zclOTA_ProcessQuerySpecificFileReq
  2076. *
  2077. * @brief Process received Image Page Request.
  2078. *
  2079. * @param pInMsg - pointer to the incoming message
  2080. *
  2081. * @return ZStatus_t
  2082. */
  2083. static ZStatus_t zclOTA_ProcessQuerySpecificFileReq( zclIncoming_t *pInMsg )
  2084. {
  2085. zclOTA_QuerySpecificFileReqParams_t param;
  2086. uint8 *pData;
  2087. /* verify message length */
  2088. if (pInMsg->pDataLen != PAYLOAD_MAX_LEN_QUERY_SPECIFIC_FILE_REQ)
  2089. {
  2090. /* no further processing if invalid */
  2091. return ZCL_STATUS_MALFORMED_COMMAND;
  2092. }
  2093. /* parse message parameters */
  2094. pData = pInMsg->pData;
  2095. osal_cpyExtAddr(param.nodeAddr, pData);
  2096. pData += Z_EXTADDR_LEN;
  2097. param.fileId.manufacturer = BUILD_UINT16(pData[0], pData[1]);
  2098. pData += 2;
  2099. param.fileId.type = BUILD_UINT16(pData[0], pData[1]);
  2100. pData += 2;
  2101. param.fileId.version = osal_build_uint32( pData, 4 );
  2102. pData += 4;
  2103. param.stackVersion = BUILD_UINT16(pData[0], pData[1]);
  2104. /* call callback */
  2105. return zclOTA_Srv_QuerySpecificFileReq(&pInMsg->msg->srcAddr, &param);
  2106. }
  2107. /******************************************************************************
  2108. * @fn zclOTA_ServerHdlIncoming
  2109. *
  2110. * @brief Handle incoming server commands.
  2111. *
  2112. * @param pInMsg - pointer to the incoming message
  2113. *
  2114. * @return ZStatus_t
  2115. */
  2116. static ZStatus_t zclOTA_ServerHdlIncoming( zclIncoming_t *pInMsg )
  2117. {
  2118. switch (pInMsg->hdr.commandID)
  2119. {
  2120. case COMMAND_QUERY_NEXT_IMAGE_REQ:
  2121. return zclOTA_ProcessQueryNextImageReq( pInMsg );
  2122. case COMMAND_IMAGE_BLOCK_REQ:
  2123. return zclOTA_ProcessImageBlockReq( pInMsg );
  2124. case COMMAND_IMAGE_PAGE_REQ:
  2125. return zclOTA_ProcessImagePageReq( pInMsg );
  2126. case COMMAND_UPGRADE_END_REQ:
  2127. return zclOTA_ProcessUpgradeEndReq( pInMsg );
  2128. case COMMAND_QUERY_SPECIFIC_FILE_REQ:
  2129. return zclOTA_ProcessQuerySpecificFileReq( pInMsg );
  2130. default:
  2131. return ZFailure;
  2132. }
  2133. }
  2134. #endif // OTA_SERVER