updater.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /*
  2. * This file is part of the MicroPython project, http://micropython.org/
  3. *
  4. * The MIT License (MIT)
  5. *
  6. * Copyright (c) 2015 Daniel Campora
  7. *
  8. * Permission is hereby granted, free of charge, to any person obtaining a copy
  9. * of this software and associated documentation files (the "Software"), to deal
  10. * in the Software without restriction, including without limitation the rights
  11. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12. * copies of the Software, and to permit persons to whom the Software is
  13. * furnished to do so, subject to the following conditions:
  14. *
  15. * The above copyright notice and this permission notice shall be included in
  16. * all copies or substantial portions of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24. * THE SOFTWARE.
  25. */
  26. #include <stdint.h>
  27. #include <stdbool.h>
  28. #include "py/mpconfig.h"
  29. #include "py/obj.h"
  30. #include "simplelink.h"
  31. #include "flc.h"
  32. #include "updater.h"
  33. #include "shamd5.h"
  34. #include "modnetwork.h"
  35. #include "modwlan.h"
  36. #include "debug.h"
  37. #include "osi.h"
  38. /******************************************************************************
  39. DEFINE PRIVATE CONSTANTS
  40. ******************************************************************************/
  41. #define UPDATER_IMG_PATH "/flash/sys/mcuimg.bin"
  42. #define UPDATER_SRVPACK_PATH "/flash/sys/servicepack.ucf"
  43. #define UPDATER_SIGN_PATH "/flash/sys/servicepack.sig"
  44. #define UPDATER_CA_PATH "/flash/cert/ca.pem"
  45. #define UPDATER_CERT_PATH "/flash/cert/cert.pem"
  46. #define UPDATER_KEY_PATH "/flash/cert/private.key"
  47. /******************************************************************************
  48. DEFINE TYPES
  49. ******************************************************************************/
  50. typedef struct {
  51. char *path;
  52. _i32 fhandle;
  53. _u32 fsize;
  54. _u32 foffset;
  55. } updater_data_t;
  56. /******************************************************************************
  57. DECLARE PRIVATE DATA
  58. ******************************************************************************/
  59. static updater_data_t updater_data = { .path = NULL, .fhandle = -1, .fsize = 0, .foffset = 0 };
  60. static OsiLockObj_t updater_LockObj;
  61. static sBootInfo_t sBootInfo;
  62. /******************************************************************************
  63. DEFINE PUBLIC FUNCTIONS
  64. ******************************************************************************/
  65. __attribute__ ((section (".boot")))
  66. void updater_pre_init (void) {
  67. // create the updater lock
  68. ASSERT(OSI_OK == sl_LockObjCreate(&updater_LockObj, "UpdaterLock"));
  69. }
  70. bool updater_check_path (void *path) {
  71. sl_LockObjLock (&updater_LockObj, SL_OS_WAIT_FOREVER);
  72. if (!strcmp(UPDATER_IMG_PATH, path)) {
  73. updater_data.fsize = IMG_SIZE;
  74. updater_data.path = IMG_UPDATE1;
  75. // the launchxl doesn't have enough flash space for 2 user update images
  76. #ifdef WIPY
  77. // check which one should be the next active image
  78. _i32 fhandle;
  79. if (!sl_FsOpen((unsigned char *)IMG_BOOT_INFO, FS_MODE_OPEN_READ, NULL, &fhandle)) {
  80. ASSERT (sizeof(sBootInfo_t) == sl_FsRead(fhandle, 0, (unsigned char *)&sBootInfo, sizeof(sBootInfo_t)));
  81. sl_FsClose(fhandle, 0, 0, 0);
  82. // if we still have an image pending for verification, keep overwriting it
  83. if ((sBootInfo.Status == IMG_STATUS_CHECK && sBootInfo.ActiveImg == IMG_ACT_UPDATE2) ||
  84. (sBootInfo.ActiveImg == IMG_ACT_UPDATE1 && sBootInfo.Status != IMG_STATUS_CHECK)) {
  85. updater_data.path = IMG_UPDATE2;
  86. }
  87. }
  88. #endif
  89. } else if (!strcmp(UPDATER_SRVPACK_PATH, path)) {
  90. updater_data.path = IMG_SRVPACK;
  91. updater_data.fsize = SRVPACK_SIZE;
  92. } else if (!strcmp(UPDATER_SIGN_PATH, path)) {
  93. updater_data.path = SRVPACK_SIGN;
  94. updater_data.fsize = SIGN_SIZE;
  95. } else if (!strcmp(UPDATER_CA_PATH, path)) {
  96. updater_data.path = CA_FILE;
  97. updater_data.fsize = CA_KEY_SIZE;
  98. } else if (!strcmp(UPDATER_CERT_PATH, path)) {
  99. updater_data.path = CERT_FILE;
  100. updater_data.fsize = CA_KEY_SIZE;
  101. } else if (!strcmp(UPDATER_KEY_PATH, path)) {
  102. updater_data.path = KEY_FILE;
  103. updater_data.fsize = CA_KEY_SIZE;
  104. } else {
  105. sl_LockObjUnlock (&updater_LockObj);
  106. return false;
  107. }
  108. return true;
  109. }
  110. bool updater_start (void) {
  111. _u32 AccessModeAndMaxSize = FS_MODE_OPEN_WRITE;
  112. SlFsFileInfo_t FsFileInfo;
  113. bool result = false;
  114. sl_LockObjLock (&wlan_LockObj, SL_OS_WAIT_FOREVER);
  115. if (0 != sl_FsGetInfo((_u8 *)updater_data.path, 0, &FsFileInfo)) {
  116. // file doesn't exist, create it
  117. AccessModeAndMaxSize = FS_MODE_OPEN_CREATE(updater_data.fsize, 0);
  118. }
  119. if (!sl_FsOpen((_u8 *)updater_data.path, AccessModeAndMaxSize, NULL, &updater_data.fhandle)) {
  120. updater_data.foffset = 0;
  121. result = true;
  122. }
  123. sl_LockObjUnlock (&wlan_LockObj);
  124. return result;
  125. }
  126. bool updater_write (uint8_t *buf, uint32_t len) {
  127. bool result = false;
  128. sl_LockObjLock (&wlan_LockObj, SL_OS_WAIT_FOREVER);
  129. if (len == sl_FsWrite(updater_data.fhandle, updater_data.foffset, buf, len)) {
  130. updater_data.foffset += len;
  131. result = true;
  132. }
  133. sl_LockObjUnlock (&wlan_LockObj);
  134. return result;
  135. }
  136. void updater_finnish (void) {
  137. _i32 fhandle;
  138. if (updater_data.fhandle > 0) {
  139. sl_LockObjLock (&wlan_LockObj, SL_OS_WAIT_FOREVER);
  140. // close the file being updated
  141. sl_FsClose(updater_data.fhandle, NULL, NULL, 0);
  142. #ifdef WIPY
  143. // if we still have an image pending for verification, leave the boot info as it is
  144. if (!strncmp(IMG_PREFIX, updater_data.path, strlen(IMG_PREFIX)) && sBootInfo.Status != IMG_STATUS_CHECK) {
  145. #else
  146. if (!strncmp(IMG_PREFIX, updater_data.path, strlen(IMG_PREFIX))) {
  147. #endif
  148. #ifdef DEBUG
  149. if (!sl_FsOpen((unsigned char *)IMG_BOOT_INFO, FS_MODE_OPEN_READ, NULL, &fhandle)) {
  150. ASSERT (sizeof(sBootInfo_t) == sl_FsRead(fhandle, 0, (unsigned char *)&sBootInfo, sizeof(sBootInfo_t)));
  151. sl_FsClose(fhandle, 0, 0, 0);
  152. #endif
  153. // open the boot info file for writing
  154. ASSERT (sl_FsOpen((unsigned char *)IMG_BOOT_INFO, FS_MODE_OPEN_WRITE, NULL, &fhandle) == 0);
  155. #ifdef DEBUG
  156. }
  157. else {
  158. // the boot info file doesn't exist yet
  159. _u32 BootInfoCreateFlag = _FS_FILE_OPEN_FLAG_COMMIT | _FS_FILE_PUBLIC_WRITE | _FS_FILE_PUBLIC_READ;
  160. ASSERT (sl_FsOpen ((unsigned char *)IMG_BOOT_INFO, FS_MODE_OPEN_CREATE((2 * sizeof(sBootInfo_t)),
  161. BootInfoCreateFlag), NULL, &fhandle) == 0);
  162. }
  163. #endif
  164. // save the new boot info
  165. #ifdef WIPY
  166. sBootInfo.PrevImg = sBootInfo.ActiveImg;
  167. if (sBootInfo.ActiveImg == IMG_ACT_UPDATE1) {
  168. sBootInfo.ActiveImg = IMG_ACT_UPDATE2;
  169. } else {
  170. sBootInfo.ActiveImg = IMG_ACT_UPDATE1;
  171. }
  172. // the launchxl doesn't have enough flash space for 2 user updates
  173. #else
  174. sBootInfo.PrevImg = IMG_ACT_FACTORY;
  175. sBootInfo.ActiveImg = IMG_ACT_UPDATE1;
  176. #endif
  177. sBootInfo.Status = IMG_STATUS_CHECK;
  178. ASSERT (sizeof(sBootInfo_t) == sl_FsWrite(fhandle, 0, (unsigned char *)&sBootInfo, sizeof(sBootInfo_t)));
  179. sl_FsClose(fhandle, 0, 0, 0);
  180. }
  181. sl_LockObjUnlock (&wlan_LockObj);
  182. updater_data.fhandle = -1;
  183. }
  184. sl_LockObjUnlock (&updater_LockObj);
  185. }