ota_upgrade_host.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  1. /*
  2. * Copyright (c) 2019 Actions Semiconductor Co., Ltd
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. /**
  7. * @file
  8. * @brief OTA upgrade interface
  9. */
  10. #include <kernel.h>
  11. #include <string.h>
  12. #include <device.h>
  13. #include <drivers/flash.h>
  14. #include <soc.h>
  15. #include <fw_version.h>
  16. #include <partition/partition.h>
  17. #include <mem_manager.h>
  18. #include <crc.h>
  19. #include <ota_upgrade.h>
  20. #include <ota_backend.h>
  21. #include <ota_trans.h>
  22. #include "ota_image.h"
  23. #include <ota_storage.h>
  24. #include "ota_manifest.h"
  25. #include "ota_breakpoint.h"
  26. #include "ota_file_patch.h"
  27. #include <os_common_api.h>
  28. #include <drivers/nvram_config.h>
  29. #include <sys/ring_buffer.h>
  30. #define OTA_HOST_DATA_BUFFER_SIZE (16*1024)//3072
  31. #define OTA_MANIFESET_FILE_NAME "ota.xml"
  32. #define OTA_FLAG_USE_RECOVERY (1 << 0)
  33. #define OTA_FLAG_USE_RECOVERY_APP (1 << 1)
  34. #define ota_use_recovery(ota) ((ota)->flags & OTA_FLAG_USE_RECOVERY)
  35. #define ota_use_recovery_app(ota) ((ota)->flags & OTA_FLAG_USE_RECOVERY_APP)
  36. #define EIO_READ (1001)
  37. struct ota_host_upgrade_info {
  38. int state;
  39. int backend_type;
  40. unsigned int flags;
  41. ota_notify_t notify;
  42. struct ota_image *img;
  43. struct ota_trans *trans;
  44. int data_buf_size;
  45. u8_t *data_buf;
  46. struct ota_manifest manifest;
  47. struct ota_breakpoint bp;
  48. };
  49. struct ota_upgrade_image_info{
  50. u8_t *buffer;
  51. int size;
  52. u32_t crc;
  53. int ctn;
  54. };
  55. void ota_host_update_state(struct ota_host_upgrade_info *ota, enum ota_state state)
  56. {
  57. int old_state;
  58. SYS_LOG_INF("upadte ota state: %d\n", state);
  59. old_state = ota->state;
  60. ota->state = state;
  61. if (ota->notify) {
  62. ota->notify(state, old_state);
  63. }
  64. }
  65. static int ota_host_is_need_upgrade(struct ota_host_upgrade_info *ota)
  66. {
  67. #ifdef CONFIG_OTA_IMAGE_CHECK
  68. struct ota_breakpoint *bp = &ota->bp;
  69. const struct fw_version *img_ver;
  70. struct ota_backend *backend;
  71. int backend_type;
  72. img_ver = &ota->manifest.fw_ver;
  73. SYS_LOG_INF("ota fw version:");
  74. fw_version_dump(img_ver);
  75. backend = ota_image_get_backend(ota->img);
  76. backend_type = ota_backend_get_type(backend);
  77. if (backend_type != OTA_BACKEND_TYPE_TEMP_PART &&
  78. bp->backend_type != OTA_BACKEND_TYPE_UNKNOWN &&
  79. bp->backend_type != backend_type) {
  80. SYS_LOG_ERR("backend type is chagned(%d -> %d), need erase old firmware",
  81. bp->backend_type, ota_backend_get_type(backend));
  82. return -1;
  83. }
  84. #endif
  85. #if 0
  86. if (strcmp(cur_ver->board_name, img_ver->board_name)) {
  87. /* skip */
  88. SYS_LOG_ERR("unmatched board name, skip ota");
  89. return -1;
  90. }
  91. if ((bp->state == OTA_BP_STATE_WRITING_IMG ||
  92. bp->state == OTA_BP_STATE_UPGRADE_WRITING ||
  93. bp->state == OTA_BP_STATE_UPGRADE_PENDING) &&
  94. (bp->new_version != 0 &&
  95. bp->new_version != img_ver->version_code)) {
  96. /* FIXME: has new version fw, need erase partition */
  97. SYS_LOG_INF("has new version fw, need erase old firmware");
  98. return -1;
  99. }
  100. if (cur_ver->version_code >= img_ver->version_code) {
  101. /* skip */
  102. SYS_LOG_INF("ota image is same or older, skip ota");
  103. return 0;
  104. }
  105. #endif
  106. return 0;
  107. }
  108. int ota_host_upgrade_check(struct ota_host_upgrade_info *ota)
  109. {
  110. // struct ota_breakpoint *bp = &ota->bp;
  111. // struct ota_backend *backend;
  112. int err = 0;
  113. //int need_upgrade;
  114. SYS_LOG_INF("handle upgrade");
  115. if (ota->state != OTA_INIT) {
  116. SYS_LOG_ERR("ota state <%d> is not OTA_INIT, skip upgrade", ota->state);
  117. return -EINVAL;
  118. }
  119. err = ota_image_open(ota->img);
  120. if (err) {
  121. SYS_LOG_INF("ota image open failed");
  122. return -EIO;
  123. }
  124. err = ota_manifest_parse_file(&ota->manifest, ota->img, OTA_MANIFESET_FILE_NAME);
  125. if (err) {
  126. SYS_LOG_INF("cannot get manifest file in image");
  127. return -1;
  128. // goto exit;
  129. }
  130. err = ota_host_is_need_upgrade(ota);
  131. ota_host_update_state(ota, OTA_RUNNING);
  132. return err;
  133. #if 0
  134. /* need upgrade? */
  135. need_upgrade = ota_is_need_upgrade(ota);
  136. if (need_upgrade == 0) {
  137. SYS_LOG_INF("skip upgrade");
  138. goto exit;
  139. } else if (need_upgrade < 0) {
  140. SYS_LOG_INF("new firmware is not same to the upgrading firmware, need erase at next boot");
  141. ota_breakpoint_update_state(bp, OTA_BP_STATE_UPGRADING_FAIL);
  142. ota_update_state(ota, OTA_FAIL);
  143. err = -1;
  144. goto exit;
  145. }
  146. SYS_LOG_INF("burn firmware image");
  147. backend = ota_image_get_backend(ota->img);
  148. /* update breakpoint for new firmware */
  149. bp->backend_type = ota_backend_get_type(backend);
  150. bp->new_version = ota->manifest.fw_ver.version_code;
  151. ota->data_buf = mem_malloc(ota->data_buf_size);
  152. if (!ota->data_buf) {
  153. SYS_LOG_ERR("faield to allocate %d bytes", ota->data_buf_size);
  154. return -ENOMEM;
  155. }
  156. ota_update_state(ota, OTA_RUNNING);
  157. if (!ota_use_recovery(ota) || ota_use_recovery_app(ota)) {
  158. ota_breakpoint_update_state(bp, OTA_BP_STATE_UPGRADE_WRITING);
  159. err = ota_do_upgrade(ota);
  160. if (err) {
  161. SYS_LOG_INF("upgrade failed, err %d", err);
  162. if (err != -EIO && err != -EAGAIN) {
  163. ota_breakpoint_update_state(bp, OTA_BP_STATE_UPGRADING_FAIL);
  164. }
  165. goto exit;
  166. }
  167. ota_breakpoint_update_state(bp, OTA_BP_STATE_UPGRADE_DONE);
  168. } else {
  169. ota_breakpoint_update_state(bp, OTA_BP_STATE_WRITING_IMG);
  170. err = ota_write_temp_img(ota);
  171. if (err) {
  172. SYS_LOG_INF("write ota image failed, err %d", err);
  173. if (err != -EIO && err != -EAGAIN) {
  174. ota_breakpoint_update_state(bp, OTA_BP_STATE_WRITING_IMG_FAIL);
  175. }
  176. goto exit;
  177. }
  178. ota_breakpoint_update_state(bp, OTA_BP_STATE_UPGRADE_PENDING);
  179. }
  180. SYS_LOG_INF("upgrade successfully!");
  181. ota_image_ioctl(ota->img, OTA_BACKEND_IOCTL_REPORT_IMAGE_VALID, 1);
  182. ota_update_state(ota, OTA_DONE);
  183. exit:
  184. if (err) {
  185. ota_image_ioctl(ota->img, OTA_BACKEND_IOCTL_REPORT_IMAGE_VALID, 0);
  186. ota_update_state(ota, OTA_FAIL);
  187. if (err == -EAGAIN) {
  188. /* wait for upgrade resume */
  189. SYS_LOG_INF("ota status -> OTA_INIT, wait for upgrading resume!");
  190. ota_update_state(ota, OTA_INIT);
  191. }
  192. }
  193. if (ota->data_buf) {
  194. mem_free(ota->data_buf);
  195. ota->data_buf = NULL;
  196. }
  197. ota_image_close(ota->img);
  198. #endif
  199. return err;
  200. }
  201. int ota_host_upgrade_attach_trans(struct ota_host_upgrade_info *ota, struct ota_trans *trans)
  202. {
  203. ota->trans = trans;
  204. return 0;
  205. }
  206. int ota_host_upgrade_attach_backend(struct ota_host_upgrade_info *ota, struct ota_backend *backend)
  207. {
  208. struct ota_backend *img_backend = ota_image_get_backend(ota->img);
  209. SYS_LOG_INF("attach backend type %d", backend->type);
  210. if (img_backend != NULL) {
  211. SYS_LOG_ERR("already attached backend %d", img_backend->type);
  212. return -EBUSY;
  213. }
  214. ota_image_bind(ota->img, backend);
  215. return 0;
  216. }
  217. void ota_host_upgrade_detach_backend(struct ota_host_upgrade_info *ota, struct ota_backend *backend)
  218. {
  219. struct ota_backend *img_backend = ota_image_get_backend(ota->img);
  220. SYS_LOG_INF("detach backend %p", backend);
  221. if (img_backend == backend)
  222. ota_image_unbind(ota->img, backend);
  223. }
  224. int ota_host_upgrade_is_in_progress(struct ota_host_upgrade_info *ota)
  225. {
  226. struct ota_breakpoint *bp = &ota->bp;
  227. int bp_state;
  228. bp_state = ota_breakpoint_get_current_state(bp);
  229. switch (bp_state) {
  230. case OTA_BP_STATE_UPGRADE_PENDING:
  231. case OTA_BP_STATE_UPGRADE_WRITING:
  232. case OTA_BP_STATE_UPGRADE_DONE:
  233. return 1;
  234. default:
  235. break;
  236. }
  237. return 0;
  238. }
  239. u32_t ota_host_upgrade_get_image_size(struct ota_host_upgrade_info *ota)
  240. {
  241. struct ota_image *img = ota->img;
  242. return ota_image_get_datasize(img);
  243. }
  244. u32_t ota_host_upgrade_get_head_crc(struct ota_host_upgrade_info *ota)
  245. {
  246. struct ota_image *img = ota->img;
  247. return ota_image_get_checksum(img);
  248. }
  249. u32_t ota_host_upgrade_get_image_ver(struct ota_host_upgrade_info *ota)
  250. {
  251. //struct ota_image *img = ota->img;
  252. //return img->hdr.header_version;
  253. return 0;
  254. }
  255. int ota_host_upgrade_send_image(struct ota_host_upgrade_info *ota,int offset,int len)
  256. {
  257. struct ota_image *img = ota->img;
  258. int err = 0, send_len = 0, res_len = len;
  259. struct ota_upgrade_image_info image_info;
  260. int unit_size, max_size;
  261. // u32_t crc;
  262. SYS_LOG_INF("state %d",ota->state);
  263. memset(&image_info, 0 , sizeof(struct ota_upgrade_image_info));
  264. unit_size = ota_trans_ioctl(ota->trans, OTA_TRANS_IOCTL_UNITSIZE_GET, NULL);
  265. if (0 == unit_size) {
  266. SYS_LOG_ERR("unit_size %d.",unit_size);
  267. return -EAGAIN;
  268. } else {
  269. max_size = (OTA_HOST_DATA_BUFFER_SIZE/unit_size*unit_size);
  270. }
  271. do {
  272. if(ota->state != OTA_RUNNING) {
  273. SYS_LOG_INF("error state %d",ota->state);
  274. return -EPERM;
  275. }
  276. if(res_len > max_size) {
  277. send_len = max_size;
  278. } else {
  279. send_len = res_len;
  280. }
  281. err = ota_image_read(img, offset, ota->data_buf, send_len);
  282. if (err) {
  283. SYS_LOG_ERR("cannot read data, offs 0x%x", offset);
  284. return -EAGAIN;
  285. }
  286. image_info.buffer = ota->data_buf;
  287. image_info.size = send_len;
  288. // image_info.crc = crc;
  289. SYS_LOG_INF("send_len %d",send_len);
  290. err = ota_trans_ioctl(ota->trans,OTA_TRANS_IOCTL_SEND_IMAGE,(void *)&image_info);
  291. if (err) {
  292. SYS_LOG_ERR("send data error 0x%x", offset);
  293. return err;
  294. }
  295. offset += send_len;
  296. res_len -= send_len;
  297. image_info.ctn = 1;
  298. //os_sleep(2);
  299. } while(res_len > 0);
  300. return err;
  301. }
  302. struct ota_host_upgrade_info *ota_host_upgrade_init(struct ota_upgrade_param *param)
  303. {
  304. struct ota_host_upgrade_info *ota;
  305. SYS_LOG_INF("init");
  306. ota = mem_malloc(sizeof(struct ota_host_upgrade_info));
  307. if (!ota)
  308. return NULL;
  309. memset(ota, 0x0, sizeof(struct ota_host_upgrade_info));
  310. /* allocate data buffer later */
  311. ota->data_buf_size = OTA_HOST_DATA_BUFFER_SIZE;
  312. ota->data_buf = mem_malloc(ota->data_buf_size);
  313. // ota_breakpoint_init(&ota->bp);
  314. // ota_partition_update_prepare(ota);
  315. ota->img = ota_image_init();
  316. if (!ota->img) {
  317. SYS_LOG_ERR("image init failed");
  318. return NULL;
  319. }
  320. ota->notify = param->notify;
  321. ota->trans = NULL;
  322. ota_host_update_state(ota, OTA_INIT);
  323. return ota;
  324. }
  325. void ota_host_upgrade_exit(struct ota_host_upgrade_info *ota)
  326. {
  327. SYS_LOG_INF("exit");
  328. /* TODO */
  329. if (ota) {
  330. if (ota->img){
  331. ota_image_exit(ota->img);
  332. }
  333. if(ota->data_buf){
  334. mem_free(ota->data_buf);
  335. }
  336. mem_free(ota);
  337. }
  338. }