ota_common.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  1. /******************************************************************************
  2. Filename: ota_common.c
  3. Revised: $Date: 2011-07-15 18:31:00 -0700 (Fri, 15 Jul 2011) $
  4. Revision: $Revision: 26808 $
  5. Description: This file contains code common to the OTA server,
  6. client, and dongle.
  7. Copyright 2010-2011 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. * INCLUDES
  36. */
  37. #include "hal_types.h"
  38. #include "ota_common.h"
  39. #ifdef _WIN32
  40. #include <string.h>
  41. #define osal_memcpy memcpy
  42. #define osal_strlen strlen
  43. #else
  44. #include "osal.h"
  45. #endif
  46. /******************************************************************************
  47. * MACROS
  48. */
  49. #define UINT16_BREAK_HEX(a, b) (((a) >> (12-(4*(b)))) & 0xF)
  50. #define UINT32_BREAK_HEX(a, b) (((a) >> (28-(4*(b)))) & 0xF)
  51. /*********************************************************************
  52. * CONSTANTS
  53. */
  54. /******************************************************************************
  55. * LOCAL VARIABLES
  56. */
  57. static char HEX_char[] = "0123456789ABCDEF";
  58. /******************************************************************************
  59. * LOCAL FUNCTIONS
  60. */
  61. static uint8 char2uint(char c);
  62. /******************************************************************************
  63. * @fn char2uint
  64. *
  65. * @brief Converts a hex character to a uint8
  66. *
  67. * @param c - Character to convert
  68. *
  69. * @return uint8 value of c
  70. */
  71. static uint8 char2uint(char c)
  72. {
  73. if (c >= '0' && c <= '9')
  74. {
  75. return c - '0';
  76. }
  77. if (c >= 'a' && c <= 'f')
  78. {
  79. return 0xA + c - 'a';
  80. }
  81. if (c >= 'A' && c <= 'F')
  82. {
  83. return 0xA + c - 'A';
  84. }
  85. return 0;
  86. }
  87. /******************************************************************************
  88. * @fn OTA_ParseHeader
  89. *
  90. * @brief Reads the OTA header from the input buffer.
  91. *
  92. * @param pHdr - pointer to the header information
  93. * @param pBuf - pointer to the input buffer
  94. *
  95. * @return new buffer pointer
  96. */
  97. uint8 *OTA_ParseHeader(OTA_ImageHeader_t *pHdr, uint8 *pBuf)
  98. {
  99. uint8 i;
  100. // Get the Magic Number
  101. pHdr->magicNumber = BUILD_UINT32(pBuf[0], pBuf[1], pBuf[2], pBuf[3]);
  102. pBuf += 4;
  103. // Get the Header Version
  104. pHdr->headerVersion = BUILD_UINT16(pBuf[0], pBuf[1]);
  105. pBuf += 2;
  106. // Get the Header Length
  107. pHdr->headerLength = BUILD_UINT16(pBuf[0], pBuf[1]);
  108. pBuf += 2;
  109. // Get the Field Control
  110. pHdr->fieldControl = BUILD_UINT16(pBuf[0], pBuf[1]);
  111. pBuf += 2;
  112. // Get the Manufacturer ID
  113. pHdr->fileId.manufacturer = BUILD_UINT16(pBuf[0], pBuf[1]);
  114. pBuf += 2;
  115. // Get the Image Type
  116. pHdr->fileId.type = BUILD_UINT16(pBuf[0], pBuf[1]);
  117. pBuf += 2;
  118. // Get the File Version
  119. pHdr->fileId.version = BUILD_UINT32(pBuf[0], pBuf[1], pBuf[2], pBuf[3]);
  120. pBuf += 4;
  121. // Get the Stack Version
  122. pHdr->stackVersion = BUILD_UINT16(pBuf[0], pBuf[1]);
  123. pBuf += 2;
  124. // Get the Header string
  125. for (i=0; i<OTA_HEADER_STR_LEN; i++)
  126. {
  127. pHdr->headerString[i] = *pBuf++;
  128. }
  129. // Get the Image Size
  130. pHdr->imageSize = BUILD_UINT32(pBuf[0], pBuf[1], pBuf[2], pBuf[3]);
  131. pBuf += 4;
  132. // Get the Security Credential Version
  133. if (pHdr->fieldControl & OTA_FC_SCV_PRESENT)
  134. {
  135. pHdr->secCredentialVer = *pBuf++;
  136. }
  137. // Get the Upgrade File Destination
  138. if (pHdr->fieldControl & OTA_FC_DSF_PRESENT)
  139. {
  140. for (i=0; i<Z_EXTADDR_LEN; i++)
  141. {
  142. pHdr->destIEEE[i] = *pBuf++;
  143. }
  144. }
  145. // Get the Min and Max Hardware Versions
  146. if (pHdr->fieldControl & OTA_FC_HWV_PRESENT)
  147. {
  148. pHdr->minHwVer = BUILD_UINT16(pBuf[0], pBuf[1]);
  149. pBuf += 2;
  150. pHdr->maxHwVer = BUILD_UINT16(pBuf[0], pBuf[1]);
  151. pBuf += 2;
  152. }
  153. return pBuf;
  154. }
  155. /******************************************************************************
  156. * @fn OTA_WriteHeader
  157. *
  158. * @brief Writes the OTA header to the output buffer.
  159. *
  160. * @param pHdr - pointer to the header information
  161. * @param pHdr - pointer to the output buffer
  162. *
  163. * @return none
  164. */
  165. uint8 *OTA_WriteHeader(OTA_ImageHeader_t *pHdr, uint8 *pBuf)
  166. {
  167. uint8 i;
  168. // Output the Magic Number
  169. // osal_buffer_uint32 not available under windows
  170. //pBuf = osal_buffer_uint32(pBuf, pHdr->magicNumber);
  171. *pBuf++ = BREAK_UINT32(pHdr->magicNumber, 0);
  172. *pBuf++ = BREAK_UINT32(pHdr->magicNumber, 1);
  173. *pBuf++ = BREAK_UINT32(pHdr->magicNumber, 2);
  174. *pBuf++ = BREAK_UINT32(pHdr->magicNumber, 3);
  175. // Output the Header Version
  176. *pBuf++ = LO_UINT16(pHdr->headerVersion);
  177. *pBuf++ = HI_UINT16(pHdr->headerVersion);
  178. // Output the Header Length
  179. *pBuf++ = LO_UINT16(pHdr->headerLength);
  180. *pBuf++ = HI_UINT16(pHdr->headerLength);
  181. // Output the Field Control
  182. *pBuf++ = LO_UINT16(pHdr->fieldControl);
  183. *pBuf++ = HI_UINT16(pHdr->fieldControl);
  184. // Output the Manufacturer ID
  185. *pBuf++ = LO_UINT16(pHdr->fileId.manufacturer);
  186. *pBuf++ = HI_UINT16(pHdr->fileId.manufacturer);
  187. // Output the Image Type
  188. *pBuf++ = LO_UINT16(pHdr->fileId.type);
  189. *pBuf++ = HI_UINT16(pHdr->fileId.type);
  190. // Output the File Version
  191. // osal_buffer_uint32 not available under windows
  192. //pBuf = osal_buffer_uint32(pBuf, pHdr->fileId.version);
  193. *pBuf++ = BREAK_UINT32(pHdr->fileId.version, 0);
  194. *pBuf++ = BREAK_UINT32(pHdr->fileId.version, 1);
  195. *pBuf++ = BREAK_UINT32(pHdr->fileId.version, 2);
  196. *pBuf++ = BREAK_UINT32(pHdr->fileId.version, 3);
  197. // Output the Stack Version
  198. *pBuf++ = LO_UINT16(pHdr->stackVersion);
  199. *pBuf++ = HI_UINT16(pHdr->stackVersion);
  200. // Output the Header string
  201. for (i=0; i<OTA_HEADER_STR_LEN; i++)
  202. {
  203. *pBuf++ = pHdr->headerString[i];
  204. }
  205. // Output the Image Size
  206. // osal_buffer_uint32 not available under windows
  207. //pBuf = osal_buffer_uint32(pBuf, pHdr->imageSize);
  208. *pBuf++ = BREAK_UINT32(pHdr->imageSize, 0);
  209. *pBuf++ = BREAK_UINT32(pHdr->imageSize, 1);
  210. *pBuf++ = BREAK_UINT32(pHdr->imageSize, 2);
  211. *pBuf++ = BREAK_UINT32(pHdr->imageSize, 3);
  212. // Output the Security Credential Version
  213. if (pHdr->fieldControl & OTA_FC_SCV_PRESENT)
  214. {
  215. *pBuf++ = pHdr->secCredentialVer;
  216. }
  217. // Output the Upgrade File Destination
  218. if (pHdr->fieldControl & OTA_FC_DSF_PRESENT)
  219. {
  220. for (i=0; i<Z_EXTADDR_LEN; i++)
  221. {
  222. *pBuf++ = pHdr->destIEEE[i];
  223. }
  224. }
  225. // Output the Min and Max Hardware Versions
  226. if (pHdr->fieldControl & OTA_FC_HWV_PRESENT)
  227. {
  228. *pBuf++ = LO_UINT16(pHdr->minHwVer);
  229. *pBuf++ = HI_UINT16(pHdr->minHwVer);
  230. *pBuf++ = LO_UINT16(pHdr->maxHwVer);
  231. *pBuf++ = HI_UINT16(pHdr->maxHwVer);
  232. }
  233. return pBuf;
  234. }
  235. /******************************************************************************
  236. * @fn OTA_GetFileName
  237. *
  238. * @brief Get the text of a filename from the file ID (zclOTA_FileID_t)
  239. *
  240. * @param pName - Buffer to hold the name
  241. * pFileID - Pointer to File ID structure
  242. * text - Text description of file
  243. *
  244. * @return none
  245. */
  246. void OTA_GetFileName(char *pName, zclOTA_FileID_t *pFileId, char *text)
  247. {
  248. int8 i, len;
  249. // Insert the manufacturer ID
  250. if (pFileId->manufacturer == 0xFFFF)
  251. {
  252. *pName++ = '*';
  253. }
  254. else
  255. {
  256. for (i=0; i<4; i++)
  257. {
  258. *pName++ = HEX_char[UINT16_BREAK_HEX(pFileId->manufacturer, i)];
  259. }
  260. }
  261. *pName++ = '-';
  262. // Insert the type
  263. if (pFileId->type == 0xFFFF)
  264. {
  265. *pName++ = '*';
  266. }
  267. else
  268. {
  269. for (i=0; i<4; i++)
  270. {
  271. *pName++ = HEX_char[UINT16_BREAK_HEX(pFileId->type, i)];
  272. }
  273. }
  274. *pName++ = '-';
  275. // Insert the type
  276. if (pFileId->version == 0xFFFFFFFF)
  277. {
  278. *pName++ = '*';
  279. }
  280. else
  281. {
  282. for (i=0; i<8; i++)
  283. {
  284. *pName++ = HEX_char[UINT32_BREAK_HEX(pFileId->version, i)];
  285. }
  286. }
  287. if (text)
  288. {
  289. len = (uint8) osal_strlen(text);
  290. if (len)
  291. {
  292. *pName++ = '-';
  293. osal_memcpy (pName, text, len);
  294. pName += len;
  295. }
  296. }
  297. osal_memcpy (pName, ".zigbee", 8);
  298. }
  299. /******************************************************************************
  300. * @fn OTA_SplitFileName
  301. *
  302. * @brief Get the file ID of an image from the filename text
  303. *
  304. * @param pName - Buffer to hold the name
  305. * pFileID - Pointer to File ID structure
  306. *
  307. * @return none
  308. */
  309. void OTA_SplitFileName(char *pName, zclOTA_FileID_t *pFileId)
  310. {
  311. // The OTA Upgrade image file name should contain the following information
  312. // at the beginning of the name with each field separated by a dash ("-"):
  313. // manufacturer code, image type and file version. The value of each field
  314. // stated should be in hexadecimal number and in capital letter. Each
  315. // manufacturer may append more information to the name as seen fit to
  316. // make the name more specific. The OTA Upgrade file extension should be
  317. // ".zigbee". An example of OTA Upgrade image file name and extension is
  318. // "1001-00AB-10053519-upgradeMe.zigbee".
  319. if (pName && pFileId)
  320. {
  321. uint8 len = (uint8) osal_strlen(pName);
  322. if (len >= 19)
  323. {
  324. uint8 i;
  325. pFileId->manufacturer = 0;
  326. for (i=0; i<4; i++)
  327. {
  328. pFileId->manufacturer |= ((uint16) char2uint(*pName++)) << (12 - (4*i));
  329. }
  330. pName++;
  331. pFileId->type = 0;
  332. for (i=0; i<4; i++)
  333. {
  334. pFileId->type |= ((uint16) char2uint(*pName++)) << (12 - (4*i));
  335. }
  336. pName++;
  337. pFileId->version = 0;
  338. for (i=0; i<8; i++)
  339. {
  340. pFileId->version |= ((uint32) char2uint(*pName++)) << (28 - (4*i));
  341. }
  342. }
  343. }
  344. }
  345. /******************************************************************************
  346. * @fn OTA_FileIdToStream
  347. *
  348. * @brief Writes a file ID to a stream
  349. *
  350. * @param pFileId - File ID
  351. * pStream - Stream
  352. *
  353. * @return new stream pointer
  354. */
  355. uint8 *OTA_FileIdToStream(zclOTA_FileID_t *pFileId, uint8 *pStream)
  356. {
  357. if (pStream)
  358. {
  359. *pStream++ = LO_UINT16(pFileId->manufacturer);
  360. *pStream++ = HI_UINT16(pFileId->manufacturer);
  361. *pStream++ = LO_UINT16(pFileId->type);
  362. *pStream++ = HI_UINT16(pFileId->type);
  363. // osal_buffer_uint32 not available under windows
  364. //pStream = osal_buffer_uint32(pStream, pFileId->version);
  365. *pStream++ = BREAK_UINT32(pFileId->version, 0);
  366. *pStream++ = BREAK_UINT32(pFileId->version, 1);
  367. *pStream++ = BREAK_UINT32(pFileId->version, 2);
  368. *pStream++ = BREAK_UINT32(pFileId->version, 3);
  369. }
  370. return pStream;
  371. }
  372. /******************************************************************************
  373. * @fn OTA_StreamToFileId
  374. *
  375. * @brief Reads a file ID from a stream
  376. *
  377. * @param pFileId - File ID
  378. * pStream - Stream
  379. *
  380. * @return new stream pointer
  381. */
  382. uint8 *OTA_StreamToFileId(zclOTA_FileID_t *pFileId, uint8 *pStream)
  383. {
  384. if (pStream)
  385. {
  386. pFileId->manufacturer = BUILD_UINT16(pStream[0], pStream[1]);
  387. pStream += 2;
  388. pFileId->type = BUILD_UINT16(pStream[0], pStream[1]);
  389. pStream += 2;
  390. pFileId->version = BUILD_UINT32(pStream[0], pStream[1], pStream[2], pStream[3]);
  391. pStream += 4;
  392. }
  393. return pStream;
  394. }
  395. /******************************************************************************
  396. * @fn OTA_AfAddrToStream
  397. *
  398. * @brief Writes an afAddrType_t to a stream.
  399. *
  400. * @param pAddr - Address
  401. * pStream - Stream
  402. *
  403. * @return new stream pointer
  404. *****************************************************************************/
  405. uint8 *OTA_AfAddrToStream(afAddrType_t *pAddr, uint8 *pStream)
  406. {
  407. if (pAddr && pStream)
  408. {
  409. *pStream++ = pAddr->addrMode;
  410. if (pAddr->addrMode == afAddr16Bit)
  411. {
  412. *pStream++ = LO_UINT16(pAddr->addr.shortAddr);
  413. *pStream++ = HI_UINT16(pAddr->addr.shortAddr);
  414. }
  415. else if (pAddr->addrMode == afAddr64Bit)
  416. {
  417. osal_memcpy(pStream, pAddr->addr.extAddr, Z_EXTADDR_LEN);
  418. pStream += Z_EXTADDR_LEN;
  419. }
  420. *pStream++ = pAddr->endPoint;
  421. *pStream++ = LO_UINT16(pAddr->panId);
  422. *pStream++ = HI_UINT16(pAddr->panId);
  423. }
  424. return pStream;
  425. }
  426. /******************************************************************************
  427. * @fn OTA_StreamToAfAddr
  428. *
  429. * @brief Reads an afAddrType_t from a stream.
  430. *
  431. * @param pAddr - Address
  432. * pStream - Stream
  433. *
  434. * @return new stream pointer
  435. *****************************************************************************/
  436. uint8 *OTA_StreamToAfAddr(afAddrType_t *pAddr, uint8 *pStream)
  437. {
  438. if (pAddr && pStream)
  439. {
  440. pAddr->addrMode = (afAddrMode_t) *pStream++;
  441. if (pAddr->addrMode == afAddr16Bit)
  442. {
  443. pAddr->addr.shortAddr = BUILD_UINT16(pStream[0], pStream[1]);
  444. pStream+= 2;
  445. }
  446. else if (pAddr->addrMode == afAddr64Bit)
  447. {
  448. osal_memcpy(pAddr->addr.extAddr, pStream, Z_EXTADDR_LEN);
  449. pStream += Z_EXTADDR_LEN;
  450. }
  451. pAddr->endPoint = *pStream++;
  452. pAddr->panId = BUILD_UINT16(pStream[0], pStream[1]);
  453. pStream+= 2;
  454. }
  455. return pStream;
  456. }