123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531 |
- /******************************************************************************
- Filename: ota_common.c
- Revised: $Date: 2011-07-15 18:31:00 -0700 (Fri, 15 Jul 2011) $
- Revision: $Revision: 26808 $
- Description: This file contains code common to the OTA server,
- client, and dongle.
- Copyright 2010-2011 Texas Instruments Incorporated. All rights reserved.
- IMPORTANT: Your use of this Software is limited to those specific rights
- granted under the terms of a software license agreement between the user
- who downloaded the software, his/her employer (which must be your employer)
- and Texas Instruments Incorporated (the "License"). You may not use this
- Software unless you agree to abide by the terms of the License. The License
- limits your use, and you acknowledge, that the Software may not be modified,
- copied or distributed unless embedded on a Texas Instruments microcontroller
- or used solely and exclusively in conjunction with a Texas Instruments radio
- frequency transceiver, which is integrated into your product. Other than for
- the foregoing purpose, you may not use, reproduce, copy, prepare derivative
- works of, modify, distribute, perform, display or sell this Software and/or
- its documentation for any purpose.
- YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
- PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
- INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
- NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
- TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
- NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
- LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
- INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
- OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
- OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
- (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
- Should you have any questions regarding your right to use this Software,
- contact Texas Instruments Incorporated at www.TI.com.
- ******************************************************************************/
- /******************************************************************************
- * INCLUDES
- */
- #include "hal_types.h"
- #include "ota_common.h"
- #ifdef _WIN32
- #include <string.h>
- #define osal_memcpy memcpy
- #define osal_strlen strlen
- #else
- #include "osal.h"
- #endif
- /******************************************************************************
- * MACROS
- */
- #define UINT16_BREAK_HEX(a, b) (((a) >> (12-(4*(b)))) & 0xF)
- #define UINT32_BREAK_HEX(a, b) (((a) >> (28-(4*(b)))) & 0xF)
- /*********************************************************************
- * CONSTANTS
- */
- /******************************************************************************
- * LOCAL VARIABLES
- */
- static char HEX_char[] = "0123456789ABCDEF";
- /******************************************************************************
- * LOCAL FUNCTIONS
- */
- static uint8 char2uint(char c);
- /******************************************************************************
- * @fn char2uint
- *
- * @brief Converts a hex character to a uint8
- *
- * @param c - Character to convert
- *
- * @return uint8 value of c
- */
- static uint8 char2uint(char c)
- {
- if (c >= '0' && c <= '9')
- {
- return c - '0';
- }
- if (c >= 'a' && c <= 'f')
- {
- return 0xA + c - 'a';
- }
- if (c >= 'A' && c <= 'F')
- {
- return 0xA + c - 'A';
- }
- return 0;
- }
- /******************************************************************************
- * @fn OTA_ParseHeader
- *
- * @brief Reads the OTA header from the input buffer.
- *
- * @param pHdr - pointer to the header information
- * @param pBuf - pointer to the input buffer
- *
- * @return new buffer pointer
- */
- uint8 *OTA_ParseHeader(OTA_ImageHeader_t *pHdr, uint8 *pBuf)
- {
- uint8 i;
- // Get the Magic Number
- pHdr->magicNumber = BUILD_UINT32(pBuf[0], pBuf[1], pBuf[2], pBuf[3]);
- pBuf += 4;
- // Get the Header Version
- pHdr->headerVersion = BUILD_UINT16(pBuf[0], pBuf[1]);
- pBuf += 2;
- // Get the Header Length
- pHdr->headerLength = BUILD_UINT16(pBuf[0], pBuf[1]);
- pBuf += 2;
- // Get the Field Control
- pHdr->fieldControl = BUILD_UINT16(pBuf[0], pBuf[1]);
- pBuf += 2;
- // Get the Manufacturer ID
- pHdr->fileId.manufacturer = BUILD_UINT16(pBuf[0], pBuf[1]);
- pBuf += 2;
- // Get the Image Type
- pHdr->fileId.type = BUILD_UINT16(pBuf[0], pBuf[1]);
- pBuf += 2;
- // Get the File Version
- pHdr->fileId.version = BUILD_UINT32(pBuf[0], pBuf[1], pBuf[2], pBuf[3]);
- pBuf += 4;
- // Get the Stack Version
- pHdr->stackVersion = BUILD_UINT16(pBuf[0], pBuf[1]);
- pBuf += 2;
- // Get the Header string
- for (i=0; i<OTA_HEADER_STR_LEN; i++)
- {
- pHdr->headerString[i] = *pBuf++;
- }
- // Get the Image Size
- pHdr->imageSize = BUILD_UINT32(pBuf[0], pBuf[1], pBuf[2], pBuf[3]);
- pBuf += 4;
- // Get the Security Credential Version
- if (pHdr->fieldControl & OTA_FC_SCV_PRESENT)
- {
- pHdr->secCredentialVer = *pBuf++;
- }
- // Get the Upgrade File Destination
- if (pHdr->fieldControl & OTA_FC_DSF_PRESENT)
- {
- for (i=0; i<Z_EXTADDR_LEN; i++)
- {
- pHdr->destIEEE[i] = *pBuf++;
- }
- }
- // Get the Min and Max Hardware Versions
- if (pHdr->fieldControl & OTA_FC_HWV_PRESENT)
- {
- pHdr->minHwVer = BUILD_UINT16(pBuf[0], pBuf[1]);
- pBuf += 2;
- pHdr->maxHwVer = BUILD_UINT16(pBuf[0], pBuf[1]);
- pBuf += 2;
- }
- return pBuf;
- }
- /******************************************************************************
- * @fn OTA_WriteHeader
- *
- * @brief Writes the OTA header to the output buffer.
- *
- * @param pHdr - pointer to the header information
- * @param pHdr - pointer to the output buffer
- *
- * @return none
- */
- uint8 *OTA_WriteHeader(OTA_ImageHeader_t *pHdr, uint8 *pBuf)
- {
- uint8 i;
- // Output the Magic Number
- // osal_buffer_uint32 not available under windows
- //pBuf = osal_buffer_uint32(pBuf, pHdr->magicNumber);
- *pBuf++ = BREAK_UINT32(pHdr->magicNumber, 0);
- *pBuf++ = BREAK_UINT32(pHdr->magicNumber, 1);
- *pBuf++ = BREAK_UINT32(pHdr->magicNumber, 2);
- *pBuf++ = BREAK_UINT32(pHdr->magicNumber, 3);
- // Output the Header Version
- *pBuf++ = LO_UINT16(pHdr->headerVersion);
- *pBuf++ = HI_UINT16(pHdr->headerVersion);
- // Output the Header Length
- *pBuf++ = LO_UINT16(pHdr->headerLength);
- *pBuf++ = HI_UINT16(pHdr->headerLength);
- // Output the Field Control
- *pBuf++ = LO_UINT16(pHdr->fieldControl);
- *pBuf++ = HI_UINT16(pHdr->fieldControl);
- // Output the Manufacturer ID
- *pBuf++ = LO_UINT16(pHdr->fileId.manufacturer);
- *pBuf++ = HI_UINT16(pHdr->fileId.manufacturer);
- // Output the Image Type
- *pBuf++ = LO_UINT16(pHdr->fileId.type);
- *pBuf++ = HI_UINT16(pHdr->fileId.type);
- // Output the File Version
- // osal_buffer_uint32 not available under windows
- //pBuf = osal_buffer_uint32(pBuf, pHdr->fileId.version);
- *pBuf++ = BREAK_UINT32(pHdr->fileId.version, 0);
- *pBuf++ = BREAK_UINT32(pHdr->fileId.version, 1);
- *pBuf++ = BREAK_UINT32(pHdr->fileId.version, 2);
- *pBuf++ = BREAK_UINT32(pHdr->fileId.version, 3);
- // Output the Stack Version
- *pBuf++ = LO_UINT16(pHdr->stackVersion);
- *pBuf++ = HI_UINT16(pHdr->stackVersion);
- // Output the Header string
- for (i=0; i<OTA_HEADER_STR_LEN; i++)
- {
- *pBuf++ = pHdr->headerString[i];
- }
- // Output the Image Size
- // osal_buffer_uint32 not available under windows
- //pBuf = osal_buffer_uint32(pBuf, pHdr->imageSize);
- *pBuf++ = BREAK_UINT32(pHdr->imageSize, 0);
- *pBuf++ = BREAK_UINT32(pHdr->imageSize, 1);
- *pBuf++ = BREAK_UINT32(pHdr->imageSize, 2);
- *pBuf++ = BREAK_UINT32(pHdr->imageSize, 3);
- // Output the Security Credential Version
- if (pHdr->fieldControl & OTA_FC_SCV_PRESENT)
- {
- *pBuf++ = pHdr->secCredentialVer;
- }
- // Output the Upgrade File Destination
- if (pHdr->fieldControl & OTA_FC_DSF_PRESENT)
- {
- for (i=0; i<Z_EXTADDR_LEN; i++)
- {
- *pBuf++ = pHdr->destIEEE[i];
- }
- }
- // Output the Min and Max Hardware Versions
- if (pHdr->fieldControl & OTA_FC_HWV_PRESENT)
- {
- *pBuf++ = LO_UINT16(pHdr->minHwVer);
- *pBuf++ = HI_UINT16(pHdr->minHwVer);
- *pBuf++ = LO_UINT16(pHdr->maxHwVer);
- *pBuf++ = HI_UINT16(pHdr->maxHwVer);
- }
- return pBuf;
- }
- /******************************************************************************
- * @fn OTA_GetFileName
- *
- * @brief Get the text of a filename from the file ID (zclOTA_FileID_t)
- *
- * @param pName - Buffer to hold the name
- * pFileID - Pointer to File ID structure
- * text - Text description of file
- *
- * @return none
- */
- void OTA_GetFileName(char *pName, zclOTA_FileID_t *pFileId, char *text)
- {
- int8 i, len;
- // Insert the manufacturer ID
- if (pFileId->manufacturer == 0xFFFF)
- {
- *pName++ = '*';
- }
- else
- {
- for (i=0; i<4; i++)
- {
- *pName++ = HEX_char[UINT16_BREAK_HEX(pFileId->manufacturer, i)];
- }
- }
- *pName++ = '-';
- // Insert the type
- if (pFileId->type == 0xFFFF)
- {
- *pName++ = '*';
- }
- else
- {
- for (i=0; i<4; i++)
- {
- *pName++ = HEX_char[UINT16_BREAK_HEX(pFileId->type, i)];
- }
- }
- *pName++ = '-';
- // Insert the type
- if (pFileId->version == 0xFFFFFFFF)
- {
- *pName++ = '*';
- }
- else
- {
- for (i=0; i<8; i++)
- {
- *pName++ = HEX_char[UINT32_BREAK_HEX(pFileId->version, i)];
- }
- }
- if (text)
- {
- len = (uint8) osal_strlen(text);
- if (len)
- {
- *pName++ = '-';
- osal_memcpy (pName, text, len);
- pName += len;
- }
- }
- osal_memcpy (pName, ".zigbee", 8);
- }
- /******************************************************************************
- * @fn OTA_SplitFileName
- *
- * @brief Get the file ID of an image from the filename text
- *
- * @param pName - Buffer to hold the name
- * pFileID - Pointer to File ID structure
- *
- * @return none
- */
- void OTA_SplitFileName(char *pName, zclOTA_FileID_t *pFileId)
- {
- // The OTA Upgrade image file name should contain the following information
- // at the beginning of the name with each field separated by a dash ("-"):
- // manufacturer code, image type and file version. The value of each field
- // stated should be in hexadecimal number and in capital letter. Each
- // manufacturer may append more information to the name as seen fit to
- // make the name more specific. The OTA Upgrade file extension should be
- // ".zigbee". An example of OTA Upgrade image file name and extension is
- // "1001-00AB-10053519-upgradeMe.zigbee".
- if (pName && pFileId)
- {
- uint8 len = (uint8) osal_strlen(pName);
- if (len >= 19)
- {
- uint8 i;
- pFileId->manufacturer = 0;
- for (i=0; i<4; i++)
- {
- pFileId->manufacturer |= ((uint16) char2uint(*pName++)) << (12 - (4*i));
- }
- pName++;
- pFileId->type = 0;
- for (i=0; i<4; i++)
- {
- pFileId->type |= ((uint16) char2uint(*pName++)) << (12 - (4*i));
- }
- pName++;
- pFileId->version = 0;
- for (i=0; i<8; i++)
- {
- pFileId->version |= ((uint32) char2uint(*pName++)) << (28 - (4*i));
- }
- }
- }
- }
- /******************************************************************************
- * @fn OTA_FileIdToStream
- *
- * @brief Writes a file ID to a stream
- *
- * @param pFileId - File ID
- * pStream - Stream
- *
- * @return new stream pointer
- */
- uint8 *OTA_FileIdToStream(zclOTA_FileID_t *pFileId, uint8 *pStream)
- {
- if (pStream)
- {
- *pStream++ = LO_UINT16(pFileId->manufacturer);
- *pStream++ = HI_UINT16(pFileId->manufacturer);
- *pStream++ = LO_UINT16(pFileId->type);
- *pStream++ = HI_UINT16(pFileId->type);
- // osal_buffer_uint32 not available under windows
- //pStream = osal_buffer_uint32(pStream, pFileId->version);
- *pStream++ = BREAK_UINT32(pFileId->version, 0);
- *pStream++ = BREAK_UINT32(pFileId->version, 1);
- *pStream++ = BREAK_UINT32(pFileId->version, 2);
- *pStream++ = BREAK_UINT32(pFileId->version, 3);
- }
- return pStream;
- }
- /******************************************************************************
- * @fn OTA_StreamToFileId
- *
- * @brief Reads a file ID from a stream
- *
- * @param pFileId - File ID
- * pStream - Stream
- *
- * @return new stream pointer
- */
- uint8 *OTA_StreamToFileId(zclOTA_FileID_t *pFileId, uint8 *pStream)
- {
- if (pStream)
- {
- pFileId->manufacturer = BUILD_UINT16(pStream[0], pStream[1]);
- pStream += 2;
- pFileId->type = BUILD_UINT16(pStream[0], pStream[1]);
- pStream += 2;
- pFileId->version = BUILD_UINT32(pStream[0], pStream[1], pStream[2], pStream[3]);
- pStream += 4;
- }
- return pStream;
- }
- /******************************************************************************
- * @fn OTA_AfAddrToStream
- *
- * @brief Writes an afAddrType_t to a stream.
- *
- * @param pAddr - Address
- * pStream - Stream
- *
- * @return new stream pointer
- *****************************************************************************/
- uint8 *OTA_AfAddrToStream(afAddrType_t *pAddr, uint8 *pStream)
- {
- if (pAddr && pStream)
- {
- *pStream++ = pAddr->addrMode;
- if (pAddr->addrMode == afAddr16Bit)
- {
- *pStream++ = LO_UINT16(pAddr->addr.shortAddr);
- *pStream++ = HI_UINT16(pAddr->addr.shortAddr);
- }
- else if (pAddr->addrMode == afAddr64Bit)
- {
- osal_memcpy(pStream, pAddr->addr.extAddr, Z_EXTADDR_LEN);
- pStream += Z_EXTADDR_LEN;
- }
- *pStream++ = pAddr->endPoint;
- *pStream++ = LO_UINT16(pAddr->panId);
- *pStream++ = HI_UINT16(pAddr->panId);
- }
- return pStream;
- }
- /******************************************************************************
- * @fn OTA_StreamToAfAddr
- *
- * @brief Reads an afAddrType_t from a stream.
- *
- * @param pAddr - Address
- * pStream - Stream
- *
- * @return new stream pointer
- *****************************************************************************/
- uint8 *OTA_StreamToAfAddr(afAddrType_t *pAddr, uint8 *pStream)
- {
- if (pAddr && pStream)
- {
- pAddr->addrMode = (afAddrMode_t) *pStream++;
- if (pAddr->addrMode == afAddr16Bit)
- {
- pAddr->addr.shortAddr = BUILD_UINT16(pStream[0], pStream[1]);
- pStream+= 2;
- }
- else if (pAddr->addrMode == afAddr64Bit)
- {
- osal_memcpy(pAddr->addr.extAddr, pStream, Z_EXTADDR_LEN);
- pStream += Z_EXTADDR_LEN;
- }
- pAddr->endPoint = *pStream++;
- pAddr->panId = BUILD_UINT16(pStream[0], pStream[1]);
- pStream+= 2;
- }
- return pStream;
- }
|