luat_ota.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. #include "luat_base.h"
  2. #include "luat_ota.h"
  3. #include "luat_fs.h"
  4. #include "luat_timer.h"
  5. #include "luat_mem.h"
  6. #include "luat_flash.h"
  7. #define LUAT_LOG_TAG "ota"
  8. #include "luat_log.h"
  9. LUAT_WEAK void luat_ota_reboot(int timeout_ms) {
  10. if (timeout_ms > 0)
  11. luat_timer_mdelay(timeout_ms);
  12. luat_os_reboot(1);
  13. }
  14. #ifdef LUAT_USE_OTA
  15. #include "luat_crypto.h"
  16. #include "luat_md5.h"
  17. #ifdef LUAT_USE_CRYPTO
  18. #include "mbedtls/md5.h"
  19. #undef luat_md5_init
  20. #undef luat_md5_update
  21. #undef luat_md5_finalize
  22. #if MBEDTLS_VERSION_NUMBER >= 0x03000000
  23. #define luat_md5_init mbedtls_md5_init
  24. #define luat_md5_starts mbedtls_md5_starts
  25. #define luat_md5_update mbedtls_md5_update
  26. #define luat_md5_finalize mbedtls_md5_finish
  27. #else
  28. #define luat_md5_init mbedtls_md5_init
  29. #define luat_md5_starts mbedtls_md5_starts_ret
  30. #define luat_md5_update mbedtls_md5_update_ret
  31. #define luat_md5_finalize mbedtls_md5_finish_ret
  32. #endif
  33. #endif
  34. #define OTA_CHECK_BUFF_SIZE (64) // 超过64字节的话, luat_md5报错, 待查
  35. typedef struct ota_md5
  36. {
  37. uint8_t buff[OTA_CHECK_BUFF_SIZE];
  38. #ifdef LUAT_USE_CRYPTO
  39. mbedtls_md5_context context;
  40. #else
  41. struct md5_context context;
  42. #endif
  43. struct md5_digest digest;
  44. }ota_md5_t;
  45. int luat_ota_checkfile(const char* path) {
  46. int ret = 0;
  47. FILE * fd = luat_fs_fopen(path, "rb");
  48. if (fd == NULL) {
  49. LLOGE("no such file");
  50. return -1;
  51. }
  52. size_t binsize = luat_fs_fsize(path);
  53. if (binsize < 512 || binsize > 1024*1024) {
  54. luat_fs_fclose(fd);
  55. LLOGE("%s is too small/big %d", path, binsize);
  56. return -1;
  57. }
  58. ota_md5_t* ota = luat_heap_malloc(sizeof(ota_md5_t));
  59. if (ota == NULL) {
  60. luat_fs_fclose(fd);
  61. LLOGE("out of memory when check ota file md5");
  62. return -1;
  63. }
  64. size_t len = 0;
  65. int remain = binsize - 16;
  66. luat_md5_init(&ota->context);
  67. #ifdef LUAT_USE_CRYPTO
  68. luat_md5_starts(&ota->context);
  69. #endif
  70. while (remain > 0) {
  71. if (remain > OTA_CHECK_BUFF_SIZE) {
  72. len = luat_fs_fread(ota->buff, OTA_CHECK_BUFF_SIZE, 1, fd);
  73. }
  74. else {
  75. len = luat_fs_fread(ota->buff, remain, 1, fd);
  76. }
  77. //LLOGD("ota read %d byte", len);
  78. if (len == 0) { // 不可能的事
  79. break;
  80. }
  81. if (len > 512) {
  82. luat_heap_free(ota);
  83. luat_fs_fclose(fd);
  84. LLOGE("read file fail");
  85. return -1;
  86. }
  87. remain -= len;
  88. luat_md5_update(&ota->context, ota->buff, len);
  89. }
  90. luat_md5_finalize(&ota->context, ota->digest.bytes);
  91. #ifdef LUAT_USE_CRYPTO
  92. mbedtls_md5_free(&ota->context);
  93. #endif
  94. // 应该还有16字节的md5
  95. //memset(ota->buff, 0, OTA_CHECK_BUFF_SIZE);
  96. luat_fs_fread(ota->buff, 16, 1, fd);
  97. // 读完就可以关了
  98. luat_fs_fclose(fd);
  99. // 判断一下md5
  100. // uint8_t *expect_md5 = ota->buff + 64;
  101. // uint8_t *face_md5 = ota->buff + 128;
  102. if (!memcmp(ota->buff, ota->digest.bytes, 16)) {
  103. LLOGD("ota file MD5 ok");
  104. ret = 0;
  105. }
  106. else {
  107. LLOGE("ota file MD5 FAIL");
  108. ret = -1;
  109. }
  110. luat_heap_free(ota);
  111. return ret;
  112. }
  113. #ifdef LUAT_USE_OTA
  114. int luat_ota(uint32_t luadb_addr){
  115. #ifdef LUAT_USE_ZLIB
  116. FILE *fd_out = NULL;
  117. FILE *fd_in = NULL;
  118. extern int zlib_decompress(FILE *source, FILE *dest);
  119. //检测是否有压缩升级文件
  120. if(luat_fs_fexist(UPDATE_TGZ_PATH)){
  121. LLOGI("found update.tgz, decompress ...");
  122. fd_in = luat_fs_fopen(UPDATE_TGZ_PATH, "r");
  123. if (fd_in == NULL){
  124. LLOGE("open the input file : %s error!", UPDATE_TGZ_PATH);
  125. goto _close_decompress;
  126. }
  127. luat_fs_remove(UPDATE_BIN_PATH);
  128. fd_out = luat_fs_fopen(UPDATE_BIN_PATH, "w+");
  129. if (fd_out == NULL){
  130. LLOGE("open the output file : %s error!", UPDATE_BIN_PATH);
  131. goto _close_decompress;
  132. }
  133. int ret = zlib_decompress(fd_in, fd_out);
  134. if (ret != 0){
  135. LLOGE("decompress file error!");
  136. }
  137. _close_decompress:
  138. if(fd_in != NULL){
  139. luat_fs_fclose(fd_in);
  140. }
  141. if(fd_out != NULL){
  142. luat_fs_fclose(fd_out);
  143. }
  144. //不论成功与否都删掉避免每次启动都执行一遍
  145. luat_fs_remove(UPDATE_TGZ_PATH);
  146. }
  147. #endif
  148. int ret = -1;
  149. //检测是否有升级文件
  150. if(luat_fs_fexist(UPDATE_BIN_PATH)){
  151. LLOGI("found update.bin, checking");
  152. if (luat_ota_checkfile(UPDATE_BIN_PATH) == 0) {
  153. LLOGI("update.bin ok, updating... %08X", luadb_addr);
  154. #define UPDATE_BUFF_SIZE 4096
  155. uint8_t* buff = luat_heap_malloc(UPDATE_BUFF_SIZE);
  156. int len = 0;
  157. int offset = 0;
  158. if (buff != NULL) {
  159. FILE* fd = luat_fs_fopen(UPDATE_BIN_PATH, "rb");
  160. if (fd){
  161. while (1) {
  162. memset(buff, 0, UPDATE_BUFF_SIZE);
  163. len = luat_fs_fread(buff, sizeof(uint8_t), UPDATE_BUFF_SIZE, fd);
  164. if (len < 1)
  165. break;
  166. luat_flash_erase(luadb_addr + offset, UPDATE_BUFF_SIZE);
  167. luat_flash_write((char*)buff, luadb_addr + offset, UPDATE_BUFF_SIZE);
  168. offset += len;
  169. }
  170. }else{
  171. ret = -1;
  172. LLOGW("update.bin open error");
  173. }
  174. ret = 0;
  175. }
  176. }
  177. else {
  178. ret = -1;
  179. LLOGW("update.bin NOT ok, skip");
  180. }
  181. luat_fs_remove(UPDATE_BIN_PATH);
  182. }
  183. return ret;
  184. }
  185. #endif
  186. #endif