diff options
Diffstat (limited to 'ports/cc3200/ftp/updater.c')
| -rw-r--r-- | ports/cc3200/ftp/updater.c | 202 |
1 files changed, 202 insertions, 0 deletions
diff --git a/ports/cc3200/ftp/updater.c b/ports/cc3200/ftp/updater.c new file mode 100644 index 000000000..5be2c6063 --- /dev/null +++ b/ports/cc3200/ftp/updater.c @@ -0,0 +1,202 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2015 Daniel Campora + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include <stdint.h> +#include <stdbool.h> + +#include "py/mpconfig.h" +#include "py/obj.h" +#include "simplelink.h" +#include "flc.h" +#include "updater.h" +#include "shamd5.h" +#include "modnetwork.h" +#include "modwlan.h" +#include "debug.h" +#include "osi.h" + +/****************************************************************************** + DEFINE PRIVATE CONSTANTS + ******************************************************************************/ +#define UPDATER_IMG_PATH "/flash/sys/mcuimg.bin" +#define UPDATER_SRVPACK_PATH "/flash/sys/servicepack.ucf" +#define UPDATER_SIGN_PATH "/flash/sys/servicepack.sig" +#define UPDATER_CA_PATH "/flash/cert/ca.pem" +#define UPDATER_CERT_PATH "/flash/cert/cert.pem" +#define UPDATER_KEY_PATH "/flash/cert/private.key" + +/****************************************************************************** + DEFINE TYPES + ******************************************************************************/ +typedef struct { + char *path; + _i32 fhandle; + _u32 fsize; + _u32 foffset; +} updater_data_t; + +/****************************************************************************** + DECLARE PRIVATE DATA + ******************************************************************************/ +static updater_data_t updater_data = { .path = NULL, .fhandle = -1, .fsize = 0, .foffset = 0 }; +static OsiLockObj_t updater_LockObj; +static sBootInfo_t sBootInfo; + +/****************************************************************************** + DEFINE PUBLIC FUNCTIONS + ******************************************************************************/ +__attribute__ ((section (".boot"))) +void updater_pre_init (void) { + // create the updater lock + ASSERT(OSI_OK == sl_LockObjCreate(&updater_LockObj, "UpdaterLock")); +} + +bool updater_check_path (void *path) { + sl_LockObjLock (&updater_LockObj, SL_OS_WAIT_FOREVER); + if (!strcmp(UPDATER_IMG_PATH, path)) { + updater_data.fsize = IMG_SIZE; + updater_data.path = IMG_UPDATE1; +// the launchxl doesn't have enough flash space for 2 user update images +#ifdef WIPY + // check which one should be the next active image + _i32 fhandle; + if (!sl_FsOpen((unsigned char *)IMG_BOOT_INFO, FS_MODE_OPEN_READ, NULL, &fhandle)) { + ASSERT (sizeof(sBootInfo_t) == sl_FsRead(fhandle, 0, (unsigned char *)&sBootInfo, sizeof(sBootInfo_t))); + sl_FsClose(fhandle, 0, 0, 0); + // if we still have an image pending for verification, keep overwriting it + if ((sBootInfo.Status == IMG_STATUS_CHECK && sBootInfo.ActiveImg == IMG_ACT_UPDATE2) || + (sBootInfo.ActiveImg == IMG_ACT_UPDATE1 && sBootInfo.Status != IMG_STATUS_CHECK)) { + updater_data.path = IMG_UPDATE2; + } + } +#endif + } else if (!strcmp(UPDATER_SRVPACK_PATH, path)) { + updater_data.path = IMG_SRVPACK; + updater_data.fsize = SRVPACK_SIZE; + } else if (!strcmp(UPDATER_SIGN_PATH, path)) { + updater_data.path = SRVPACK_SIGN; + updater_data.fsize = SIGN_SIZE; + } else if (!strcmp(UPDATER_CA_PATH, path)) { + updater_data.path = CA_FILE; + updater_data.fsize = CA_KEY_SIZE; + } else if (!strcmp(UPDATER_CERT_PATH, path)) { + updater_data.path = CERT_FILE; + updater_data.fsize = CA_KEY_SIZE; + } else if (!strcmp(UPDATER_KEY_PATH, path)) { + updater_data.path = KEY_FILE; + updater_data.fsize = CA_KEY_SIZE; + } else { + sl_LockObjUnlock (&updater_LockObj); + return false; + } + return true; +} + +bool updater_start (void) { + _u32 AccessModeAndMaxSize = FS_MODE_OPEN_WRITE; + SlFsFileInfo_t FsFileInfo; + bool result = false; + + sl_LockObjLock (&wlan_LockObj, SL_OS_WAIT_FOREVER); + if (0 != sl_FsGetInfo((_u8 *)updater_data.path, 0, &FsFileInfo)) { + // file doesn't exist, create it + AccessModeAndMaxSize = FS_MODE_OPEN_CREATE(updater_data.fsize, 0); + } + if (!sl_FsOpen((_u8 *)updater_data.path, AccessModeAndMaxSize, NULL, &updater_data.fhandle)) { + updater_data.foffset = 0; + result = true; + } + sl_LockObjUnlock (&wlan_LockObj); + return result; +} + +bool updater_write (uint8_t *buf, uint32_t len) { + bool result = false; + + sl_LockObjLock (&wlan_LockObj, SL_OS_WAIT_FOREVER); + if (len == sl_FsWrite(updater_data.fhandle, updater_data.foffset, buf, len)) { + updater_data.foffset += len; + result = true; + } + sl_LockObjUnlock (&wlan_LockObj); + + return result; +} + +void updater_finnish (void) { + _i32 fhandle; + + if (updater_data.fhandle > 0) { + sl_LockObjLock (&wlan_LockObj, SL_OS_WAIT_FOREVER); + // close the file being updated + sl_FsClose(updater_data.fhandle, NULL, NULL, 0); +#ifdef WIPY + // if we still have an image pending for verification, leave the boot info as it is + if (!strncmp(IMG_PREFIX, updater_data.path, strlen(IMG_PREFIX)) && sBootInfo.Status != IMG_STATUS_CHECK) { +#else + if (!strncmp(IMG_PREFIX, updater_data.path, strlen(IMG_PREFIX))) { +#endif +#ifdef DEBUG + if (!sl_FsOpen((unsigned char *)IMG_BOOT_INFO, FS_MODE_OPEN_READ, NULL, &fhandle)) { + + ASSERT (sizeof(sBootInfo_t) == sl_FsRead(fhandle, 0, (unsigned char *)&sBootInfo, sizeof(sBootInfo_t))); + sl_FsClose(fhandle, 0, 0, 0); +#endif + // open the boot info file for writing + ASSERT (sl_FsOpen((unsigned char *)IMG_BOOT_INFO, FS_MODE_OPEN_WRITE, NULL, &fhandle) == 0); +#ifdef DEBUG + } + else { + // the boot info file doesn't exist yet + _u32 BootInfoCreateFlag = _FS_FILE_OPEN_FLAG_COMMIT | _FS_FILE_PUBLIC_WRITE | _FS_FILE_PUBLIC_READ; + ASSERT (sl_FsOpen ((unsigned char *)IMG_BOOT_INFO, FS_MODE_OPEN_CREATE((2 * sizeof(sBootInfo_t)), + BootInfoCreateFlag), NULL, &fhandle) == 0); + } +#endif + + // save the new boot info +#ifdef WIPY + sBootInfo.PrevImg = sBootInfo.ActiveImg; + if (sBootInfo.ActiveImg == IMG_ACT_UPDATE1) { + sBootInfo.ActiveImg = IMG_ACT_UPDATE2; + } else { + sBootInfo.ActiveImg = IMG_ACT_UPDATE1; + } +// the launchxl doesn't have enough flash space for 2 user updates +#else + sBootInfo.PrevImg = IMG_ACT_FACTORY; + sBootInfo.ActiveImg = IMG_ACT_UPDATE1; +#endif + sBootInfo.Status = IMG_STATUS_CHECK; + ASSERT (sizeof(sBootInfo_t) == sl_FsWrite(fhandle, 0, (unsigned char *)&sBootInfo, sizeof(sBootInfo_t))); + sl_FsClose(fhandle, 0, 0, 0); + } + sl_LockObjUnlock (&wlan_LockObj); + updater_data.fhandle = -1; + } + sl_LockObjUnlock (&updater_LockObj); +} + |
