ota_protocol.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857
  1. /**************************************************************************************************
  2. Phyplus Microelectronics Limited confidential and proprietary.
  3. All rights reserved.
  4. IMPORTANT: All rights of this software belong to Phyplus Microelectronics
  5. Limited ("Phyplus"). Your use of this Software is limited to those
  6. specific rights granted under the terms of the business contract, the
  7. confidential agreement, the non-disclosure agreement and any other forms
  8. of agreements as a customer or a partner of Phyplus. You may not use this
  9. Software unless you agree to abide by the terms of these agreements.
  10. You acknowledge that the Software may not be modified, copied,
  11. distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy
  12. (BLE) integrated circuit, either as a product or is integrated into your
  13. products. Other than for the aforementioned purposes, you may not use,
  14. reproduce, copy, prepare derivative works of, modify, distribute, perform,
  15. display or sell this Software and/or its documentation for any purposes.
  16. YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
  17. PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
  18. INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
  19. NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
  20. PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT,
  21. NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
  22. LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
  23. INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
  24. OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
  25. OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
  26. (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
  27. **************************************************************************************************/
  28. #include "bcomdef.h"
  29. #include "OSAL.h"
  30. #include "linkdb.h"
  31. #include "att.h"
  32. #include "gatt.h"
  33. #include "gatt_uuid.h"
  34. #include "gatt_profile_uuid.h"
  35. #include "gattservapp.h"
  36. #include "hal_mcu.h"
  37. //#include "ota.h"
  38. #include "ota_service.h"
  39. #include "ota_protocol.h"
  40. #include "ota_flash.h"
  41. #include "flash.h"
  42. #include "crc16.h"
  43. #include "version.h"
  44. #include "log.h"
  45. #include "error.h"
  46. #define OTA_MODE_OTA_APPLICATION 0
  47. #define OTA_MODE_OTA_FCT 1
  48. #define OTA_MODE_OTA 2
  49. #define OTA_MODE_RESOURCE 3
  50. #define OTA_MODE_OTA_NADDR 6 //ota no address plus
  51. #define OTA_MODE_SELECT_REG 0x4000f034
  52. #define OTA_BLOCK_REQ_TIMEOUT 4000
  53. #define OTA_BLOCK_BURST_TIMEOUT 1000
  54. #define Bytes2U32(u32val, b) {u32val = ((uint32_t)(b[0]&0xff)) | (((uint32_t)(b[1]&0xff))<<8)| (((uint32_t)(b[2]&0xff))<<16)| (((uint32_t)(b[3]&0xff))<<24);}
  55. #define Bytes2U16(u16val, b) {u16val = ((uint16_t)(b[0]&0xff)) | (((uint16_t)(b[1]&0xff))<<8);}
  56. enum{
  57. OTA_ST_UNCONNECTED = 0,
  58. OTA_ST_CONNECTED,
  59. //OTA_ST_PARAM,
  60. OTA_ST_WAIT_PARTITION_INFO,
  61. OTA_ST_DATA,
  62. OTA_ST_COMPLETE,
  63. OTA_ST_ERROR,
  64. };
  65. typedef struct{
  66. uint32_t flash_addr;
  67. uint32_t run_addr;
  68. uint32_t size;
  69. uint16_t checksum;
  70. }ota_part_t;
  71. typedef struct{
  72. uint8_t ota_state;
  73. uint8_t task_id;
  74. uint16_t tm_evt;
  75. bool ota_resource; //just upgrade resource data
  76. uint16_t mtu_a;
  77. bool notif_en;
  78. uint8_t part_num;
  79. uint8_t current_part;
  80. uint8_t bank_mode; //single bank or
  81. uint32_t bank_addr;
  82. bool reboot_flag;
  83. //uint8_t param_size;
  84. //uint8_t param_offset;
  85. //uint32_t param_buf[MAX_OTA_PARAM_SIZE/4];
  86. ota_part_t part[MAX_SECT_SUPPORT];
  87. uint32_t block_offset;
  88. uint32_t block_offset_retry;
  89. uint8_t* partition_buf;
  90. }ota_context_t;
  91. #define OTA_PBUF_SIZE (64*1024+16)
  92. uint8_t ota_patition_buffer[OTA_PBUF_SIZE] __attribute__((section("ota_partition_buffer_area")));
  93. static uint16_t s_ota_burst_size = 16;
  94. static bool s_ota_resource = FALSE;
  95. static bool s_ota_address_plus = TRUE;
  96. static ota_context_t s_ota_ctx;
  97. extern void jump_to_application(uint32_t run_addr);
  98. extern bool verify_mic(unsigned char* buf, int size);
  99. extern bool finidv(unsigned char* iv);
  100. static void start_timer(uint32_t timeout)
  101. {
  102. osal_start_timerEx(s_ota_ctx.task_id, s_ota_ctx.tm_evt, (uint32)timeout);
  103. }
  104. static void stop_timer(void)
  105. {
  106. osal_clear_event(s_ota_ctx.task_id, s_ota_ctx.tm_evt);
  107. osal_stop_timerEx(s_ota_ctx.task_id, s_ota_ctx.tm_evt);
  108. }
  109. static void reset_ctx(void){
  110. uint8_t task_id;
  111. uint16_t tm_evt;
  112. task_id = s_ota_ctx.task_id;
  113. tm_evt = s_ota_ctx.tm_evt;
  114. osal_memset(&s_ota_ctx, 0, sizeof(s_ota_ctx));
  115. s_ota_ctx.bank_mode = CFG_OTA_BANK_MODE;
  116. s_ota_ctx.ota_resource = s_ota_resource;
  117. s_ota_ctx.mtu_a = 20;
  118. s_ota_ctx.task_id = task_id;
  119. s_ota_ctx.tm_evt = tm_evt;
  120. }
  121. static int sector_crc(void)
  122. {
  123. uint16 crc = 0;
  124. ota_part_t* ppart = NULL;
  125. ppart = &s_ota_ctx.part[s_ota_ctx.current_part];
  126. crc = crc16(0, (void*)s_ota_ctx.partition_buf, ppart->size);
  127. if(crc != ppart->checksum)
  128. return PPlus_ERR_OTA_CRC;
  129. return PPlus_SUCCESS;
  130. }
  131. static int sector_crypto(void)
  132. {
  133. bool chk = FALSE;
  134. ota_part_t* ppart = NULL;
  135. uint8_t iv[16];
  136. if(s_ota_ctx.ota_resource)//resource no crypto
  137. return PPlus_SUCCESS;
  138. if(finidv(iv) == FALSE)
  139. return PPlus_SUCCESS;
  140. ppart = &s_ota_ctx.part[s_ota_ctx.current_part];
  141. chk = verify_mic(s_ota_ctx.partition_buf,ppart->size);
  142. if(chk == FALSE)
  143. return PPlus_ERR_OTA_CRYPTO;
  144. ppart->size -= 4; //remove MIC when store to flash
  145. ppart->checksum = crc16(0, (void*)s_ota_ctx.partition_buf, ppart->size); //figure out new checksum because the data length changed
  146. return PPlus_SUCCESS;
  147. }
  148. static void response(int state_cmd, int err)
  149. {
  150. attHandleValueNoti_t notif;
  151. osal_memset(&notif, 0, sizeof(notif));
  152. notif.len = 2;
  153. notif.value[0] = (uint8_t)err;
  154. notif.value[1] = (uint8_t)state_cmd;
  155. ota_Notify(&notif);
  156. }
  157. static void response_err(int error)
  158. {
  159. attHandleValueNoti_t notif;
  160. osal_memset(&notif, 0, sizeof(notif));
  161. notif.len = 1;
  162. notif.value[0] = error;
  163. notif.value[1] = 0xff;
  164. ota_Notify(&notif);
  165. }
  166. static void handle_error_fatal(int error)
  167. {
  168. response_err(error);
  169. if(s_ota_ctx.notif_en){
  170. s_ota_ctx.ota_state = OTA_ST_CONNECTED;
  171. s_ota_ctx.part_num = 0;
  172. s_ota_ctx.partition_buf = ota_patition_buffer;
  173. }
  174. else
  175. {
  176. reset_ctx();
  177. }
  178. }
  179. static void handle_error_state(void)
  180. {
  181. response_err(PPlus_ERR_OTA_INVALID_STATE);
  182. if(s_ota_ctx.notif_en){
  183. s_ota_ctx.ota_state = OTA_ST_CONNECTED;
  184. s_ota_ctx.part_num = 0;
  185. s_ota_ctx.partition_buf = ota_patition_buffer;
  186. }
  187. else
  188. {
  189. reset_ctx();
  190. }
  191. }
  192. bool validate_partition_parameter(ota_part_t* ppart)
  193. {
  194. if(s_ota_ctx.ota_resource){
  195. if(ppart->flash_addr != 0)
  196. return FALSE;
  197. if(ppart->run_addr&OTAF_BASE_ADDR != OTAF_BASE_ADDR || ppart->run_addr + ppart->size > OTAF_END_ADDR+1)
  198. return FALSE;
  199. if(ppart->run_addr < OTAF_1st_BOOTINFO_ADDR + OTAF_1st_BOOTINFO_SIZE)
  200. return FALSE;
  201. }
  202. else if(ppart->run_addr == ppart->flash_addr)
  203. {
  204. //check if address out of flash area
  205. if(ppart->flash_addr > OTAF_END_ADDR || ppart->flash_addr < OTAF_BASE_ADDR)
  206. return FALSE;
  207. //for XIP, only No FCT and single bank allowed
  208. if(USE_FCT && CFG_OTA_BANK_MODE!=OTA_SINGLE_BANK)
  209. return FALSE;
  210. }
  211. else{
  212. if(ppart->run_addr < SRAM0_BASE_ADDRESS || ppart->run_addr > SRAM0_BASE_ADDRESS + 138*1024)
  213. return FALSE;
  214. if((ppart->flash_addr | OTAF_BASE_ADDR) + ppart->size > OTAF_END_ADDR+1)
  215. return FALSE;
  216. }
  217. return TRUE;
  218. }
  219. static void handle_error(int error)
  220. {
  221. response_err(error);
  222. if(s_ota_ctx.notif_en){
  223. s_ota_ctx.ota_state = OTA_ST_CONNECTED;
  224. s_ota_ctx.part_num = 0;
  225. s_ota_ctx.partition_buf = ota_patition_buffer;
  226. }
  227. else
  228. {
  229. reset_ctx();
  230. }
  231. }
  232. void process_ctrl_cmd(uint8_t* cmdbuf, uint8_t size){
  233. ota_cmd_t cmd;
  234. int ret = PPlus_SUCCESS;
  235. if(size > sizeof(cmd)){
  236. return;
  237. }
  238. osal_memcpy(&cmd, cmdbuf, size);
  239. switch(cmd.cmd){
  240. #ifdef CFG_OTA_MESH
  241. case OTA_CMD_START_OTA:
  242. if(s_ota_ctx.ota_state != OTA_ST_CONNECTED){
  243. //case invalid state
  244. handle_error_state();
  245. break;
  246. }
  247. if(cmd.p.start.sector_num > MAX_SECT_SUPPORT){
  248. //case invalid state
  249. handle_error_fatal(PPlus_ERR_INVALID_PARAM);
  250. break;
  251. }
  252. s_ota_ctx.bank_mode = CFG_OTA_BANK_MODE;
  253. s_ota_ctx.ota_resource = FALSE;
  254. ota_flash_read_bootsector(&s_ota_ctx.bank_addr);
  255. s_ota_ctx.ota_state = OTA_ST_WAIT_PARTITION_INFO;
  256. s_ota_ctx.part_num = cmd.p.start.sector_num;
  257. //s_ota_ctx.param_size = cmd.p.start.param_size;
  258. s_ota_ctx.partition_buf = ota_patition_buffer;
  259. osal_memset(&(s_ota_ctx.part[0]), 0, sizeof(ota_part_t)*MAX_SECT_SUPPORT);
  260. //osal_memset(&(s_ota_ctx.param_buf[0]), 0xff, MAX_OTA_PARAM_SIZE);
  261. s_ota_burst_size = 16;
  262. if(cmd.p.start.burst_size > 0)
  263. s_ota_burst_size = cmd.p.start.burst_size;
  264. if(cmd.p.start.burst_size == 0xff)
  265. s_ota_burst_size = 0xffff;
  266. AT_LOG("s_ota_burst_size is %x\n", s_ota_burst_size);
  267. ret = otafm_format();
  268. response(OTA_RSP_START_OTA, ret);
  269. break;
  270. #else
  271. case OTA_CMD_START_OTA:
  272. if(s_ota_ctx.ota_state != OTA_ST_CONNECTED){
  273. //case invalid state
  274. handle_error_state();
  275. break;
  276. }
  277. if(cmd.p.start.sector_num > MAX_SECT_SUPPORT){
  278. //case invalid state
  279. handle_error_fatal(PPlus_ERR_INVALID_PARAM);
  280. break;
  281. }
  282. s_ota_ctx.bank_mode = CFG_OTA_BANK_MODE;
  283. s_ota_ctx.ota_resource = s_ota_resource;
  284. ota_flash_read_bootsector(&s_ota_ctx.bank_addr);
  285. s_ota_ctx.ota_state = OTA_ST_WAIT_PARTITION_INFO;
  286. s_ota_ctx.part_num = cmd.p.start.sector_num;
  287. //s_ota_ctx.param_size = cmd.p.start.param_size;
  288. s_ota_ctx.partition_buf = ota_patition_buffer;
  289. osal_memset(&(s_ota_ctx.part[0]), 0, sizeof(ota_part_t)*MAX_SECT_SUPPORT);
  290. //osal_memset(&(s_ota_ctx.param_buf[0]), 0xff, MAX_OTA_PARAM_SIZE);
  291. s_ota_burst_size = 16;
  292. if(cmd.p.start.burst_size > 0)
  293. s_ota_burst_size = cmd.p.start.burst_size;
  294. if(cmd.p.start.burst_size == 0xff)
  295. s_ota_burst_size = 0xffff;
  296. AT_LOG("s_ota_burst_size is %x\n", s_ota_burst_size);
  297. if(!s_ota_ctx.ota_resource){
  298. //if(cmd.p.start.param_size >0)
  299. // s_ota_ctx.ota_state = OTA_ST_PARAM;
  300. ret = ota_flash_erase(s_ota_ctx.bank_addr);
  301. }
  302. response(OTA_RSP_START_OTA, ret);
  303. break;
  304. #endif
  305. case OTA_CMD_PARTITION_INFO:
  306. {
  307. uint8_t idx = cmd.p.part.index;
  308. ota_part_t* ppart = &s_ota_ctx.part[idx];
  309. if(s_ota_ctx.ota_state != OTA_ST_WAIT_PARTITION_INFO){
  310. //case invalid state
  311. handle_error_state();
  312. break;
  313. }
  314. Bytes2U32(ppart->flash_addr,cmd.p.part.flash_addr);
  315. Bytes2U32(ppart->run_addr,cmd.p.part.run_addr);
  316. Bytes2U32(ppart->size,cmd.p.part.size);
  317. Bytes2U16(ppart->checksum,cmd.p.part.checksum);
  318. //check parameter
  319. if(!s_ota_ctx.ota_resource){
  320. if(ppart->run_addr > OTAF_BASE_ADDR && ppart->run_addr <OTAF_END_ADDR){
  321. ppart->flash_addr = ppart->run_addr;
  322. }
  323. }
  324. if(!validate_partition_parameter(ppart)){
  325. handle_error(PPlus_ERR_INVALID_PARAM);
  326. break;
  327. }
  328. s_ota_ctx.ota_state = OTA_ST_DATA;
  329. s_ota_ctx.current_part = idx;
  330. s_ota_ctx.block_offset = 0;
  331. s_ota_ctx.block_offset_retry = 0;
  332. s_ota_ctx.partition_buf = ota_patition_buffer;
  333. osal_memset(ota_patition_buffer, 0xff, OTA_PBUF_SIZE);
  334. response(OTA_RSP_PARTITION_INFO, PPlus_SUCCESS);
  335. break;
  336. }
  337. /* case OTA_CMD_BLOCK_INFO:
  338. {
  339. uint8_t b_idx = cmd.p.block.index;
  340. if(s_ota_ctx.ota_state != OTA_ST_WAIT_BLOCK_INFO){
  341. //case invalid state
  342. handle_error_state();
  343. return;
  344. }
  345. s_ota_ctx.ota_state = OTA_ST_DATA;
  346. s_ota_ctx.block_idx = b_idx;
  347. s_ota_ctx.block_offset = 0;
  348. s_ota_ctx.block_offset_retry = 0;
  349. Bytes2U16(s_ota_ctx.block_size ,cmd.p.block.size);
  350. response(OTA_RSP_BLOCK_INFO, PPlus_SUCCESS);
  351. start_timer(OTA_BLOCK_REQ_TIMEOUT);
  352. break;
  353. } */
  354. case OTA_CMD_REBOOT:
  355. {
  356. s_ota_ctx.reboot_flag = FALSE;
  357. if(size == 1){
  358. NVIC_SystemReset();
  359. }
  360. else if(size == 2){
  361. if(cmd.p.reboot_flag == 1)
  362. {
  363. s_ota_ctx.reboot_flag = TRUE;
  364. response(OTA_RSP_REBOOT, PPlus_SUCCESS);
  365. break;
  366. }
  367. }
  368. response(OTA_RSP_REBOOT, PPlus_ERR_INVALID_PARAM);
  369. break;
  370. }
  371. case OTA_CMD_ERASE:
  372. {
  373. uint32_t flash_addr;
  374. uint32_t flash_size;
  375. if(s_ota_ctx.ota_state != OTA_ST_WAIT_PARTITION_INFO){
  376. //case invalid state
  377. handle_error_state();
  378. break;
  379. }
  380. if(!s_ota_ctx.ota_resource){
  381. //case invalid state
  382. handle_error_state();
  383. break;
  384. }
  385. Bytes2U32(flash_addr,cmd.p.erase.flash_addr);
  386. Bytes2U32(flash_size,cmd.p.erase.size);
  387. //erase
  388. ret = ota_flash_erase_area(flash_addr, flash_size);
  389. if(ret != PPlus_SUCCESS){
  390. handle_error(ret);
  391. break;
  392. }
  393. response(OTA_RSP_ERASE, PPlus_SUCCESS);
  394. break;
  395. }
  396. default:
  397. s_ota_ctx.ota_state = OTA_ST_ERROR;
  398. response(OTA_RSP_ERROR, PPlus_ERR_NOT_SUPPORTED);
  399. break;
  400. }
  401. }
  402. /*
  403. boot sector, total 256 bytes, 64 words:
  404. count by words:
  405. (0) : number of(N)
  406. (1~3) : reserved
  407. (4~7) : partition 1 information: flash address, run address, partition size, checksum
  408. ...
  409. (N*4 ~ (N*4+3) : partition N information: flash address, run address, partition size, checksum
  410. (20 ~63) : reserved
  411. */
  412. #ifdef CFG_OTA_MESH
  413. static int write_app_boot_sector(void)
  414. {
  415. //write application boot sector data
  416. int idx;
  417. int ret;
  418. uint32_t bs[4];
  419. osal_memset(bs, 0, 16);
  420. bs[0] = 0x4641544f; //"OTAF"
  421. bs[1] = s_ota_ctx.part_num;
  422. bs[2] = 0xffffffff;
  423. bs[3] = 0xffffffff;
  424. ret = otafm_write_boot_sector(bs, 16, 0);
  425. if(ret)
  426. return ret;
  427. for(idx = 0; idx < s_ota_ctx.part_num; idx ++){
  428. bs[0] = s_ota_ctx.part[idx].flash_addr;
  429. bs[1] = s_ota_ctx.part[idx].run_addr;
  430. bs[2] = s_ota_ctx.part[idx].size;
  431. bs[3] = (uint32_t)s_ota_ctx.part[idx].checksum;
  432. ret = otafm_write_boot_sector(bs, 16, 16*(idx+1));
  433. if(ret)
  434. return ret;
  435. }
  436. return ret;
  437. }
  438. static void partition_program(void)
  439. {
  440. int ret;
  441. ota_part_t* ppart = NULL;
  442. uint32_t flash_addr = 0;
  443. ppart = &s_ota_ctx.part[s_ota_ctx.current_part];
  444. flash_addr = ppart->flash_addr;
  445. ret = otafm_write_partition(flash_addr, (uint32_t*)s_ota_ctx.partition_buf, ppart->size);
  446. if(ret != PPlus_SUCCESS){
  447. handle_error(ret);
  448. return;
  449. }
  450. //case all partition data finished
  451. if(s_ota_ctx.current_part+1 == s_ota_ctx.part_num){
  452. if(!s_ota_ctx.ota_resource)
  453. ret = write_app_boot_sector();
  454. s_ota_ctx.ota_state = OTA_ST_COMPLETE;
  455. response(OTA_RSP_OTA_COMPLETE,PPlus_SUCCESS);
  456. }
  457. else{
  458. s_ota_ctx.ota_state = OTA_ST_WAIT_PARTITION_INFO;
  459. response(OTA_RSP_PARTITION_COMPLETE, PPlus_SUCCESS);
  460. }
  461. }
  462. #else //normal OTA
  463. static int write_app_boot_sector(void)
  464. {
  465. //write application boot sector data
  466. int idx;
  467. int ret;
  468. uint32_t bs[4];
  469. osal_memset(bs, 0, 16);
  470. flash_sector_erase(OTAF_2nd_BOOTINFO_ADDR);
  471. bs[0] = s_ota_ctx.part_num;
  472. if(CFG_OTA_BANK_MODE==OTA_SINGLE_BANK)
  473. bs[1] = OTAF_SINGLE_BANK;
  474. else
  475. bs[1] = (s_ota_ctx.bank_addr == OTAF_APP_BANK_0_ADDR) ? OTAF_DUAL_BANK_0 : OTAF_DUAL_BANK_1;
  476. bs[2] = 0;
  477. bs[3] = 0xffffffff;
  478. ret = ota_flash_write_boot_sector(bs, 16, 0);
  479. if(ret)
  480. return ret;
  481. for(idx = 0; idx < s_ota_ctx.part_num; idx ++){
  482. bs[0] = s_ota_ctx.part[idx].flash_addr;
  483. bs[1] = s_ota_ctx.part[idx].run_addr;
  484. bs[2] = s_ota_ctx.part[idx].size;
  485. bs[3] = (uint32_t)s_ota_ctx.part[idx].checksum;
  486. ret = ota_flash_write_boot_sector(bs, 16, 16*(idx+1));
  487. if(ret)
  488. return ret;
  489. }
  490. return PPlus_SUCCESS;
  491. }
  492. static void partition_program(void)
  493. {
  494. int ret;
  495. ota_part_t* ppart = NULL;
  496. uint32_t flash_addr = 0;
  497. ppart = &s_ota_ctx.part[s_ota_ctx.current_part];
  498. //write partition data
  499. if(s_ota_ctx.ota_resource)
  500. {
  501. flash_addr = ppart->run_addr;
  502. }
  503. else if(ppart->flash_addr == ppart->run_addr)
  504. {
  505. uint32_t er_addr, er_size;
  506. flash_addr = ppart->run_addr;
  507. er_addr = flash_addr & 0xfffff000;//make address 4k align
  508. er_size = flash_addr + ppart->size + 0xfff - er_addr;
  509. er_size = er_size & 0xfffff000;
  510. ret = ota_flash_erase_area(er_addr, er_size);
  511. if(ret != PPlus_SUCCESS){
  512. handle_error(ret);
  513. return;
  514. }
  515. }
  516. else
  517. {
  518. flash_addr = ppart->flash_addr + s_ota_ctx.bank_addr;
  519. }
  520. ret = ota_flash_write_partition(flash_addr, (uint32_t*)s_ota_ctx.partition_buf, ppart->size);
  521. if(ret != PPlus_SUCCESS){
  522. handle_error(ret);
  523. return;
  524. }
  525. //case all partition data finished
  526. if(s_ota_ctx.current_part+1 == s_ota_ctx.part_num){
  527. if(!s_ota_ctx.ota_resource)
  528. ret = write_app_boot_sector();
  529. s_ota_ctx.ota_state = OTA_ST_COMPLETE;
  530. response(OTA_RSP_OTA_COMPLETE,PPlus_SUCCESS);
  531. }
  532. else{
  533. s_ota_ctx.ota_state = OTA_ST_WAIT_PARTITION_INFO;
  534. response(OTA_RSP_PARTITION_COMPLETE, PPlus_SUCCESS);
  535. }
  536. }
  537. #endif
  538. static void process_ota_partition_data(uint8_t* data, uint8_t size)
  539. {
  540. uint32_t block_offset = s_ota_ctx.block_offset;
  541. ota_part_t* ppart = NULL;
  542. ppart = &s_ota_ctx.part[s_ota_ctx.current_part];
  543. osal_memcpy(s_ota_ctx.partition_buf + block_offset, data, size);
  544. block_offset += size;
  545. AT_LOG("boff[%d], rty[%d]\n", block_offset,s_ota_ctx.block_offset_retry);
  546. if(block_offset > ppart->size){
  547. handle_error(PPlus_ERR_OTA_DATA_SIZE);
  548. return;
  549. }
  550. s_ota_ctx.block_offset = block_offset;
  551. if(s_ota_ctx.block_offset - s_ota_ctx.block_offset_retry == OTA_DATA_BURST_SIZE){
  552. response(OTA_RSP_BLOCK_BURST, PPlus_SUCCESS);
  553. s_ota_ctx.block_offset_retry = s_ota_ctx.block_offset;
  554. start_timer(OTA_BLOCK_REQ_TIMEOUT);
  555. }
  556. else{
  557. start_timer(OTA_BLOCK_BURST_TIMEOUT);
  558. }
  559. if(block_offset == ppart->size){
  560. stop_timer();
  561. //cec check
  562. if(sector_crc() != PPlus_SUCCESS){
  563. handle_error(PPlus_ERR_OTA_CRC);
  564. return;
  565. }
  566. if(sector_crypto()!=PPlus_SUCCESS){
  567. handle_error(PPlus_ERR_OTA_CRYPTO);
  568. return;
  569. }
  570. partition_program();
  571. return;
  572. }
  573. }
  574. /*
  575. static void process_ota_param_data(uint8_t* data, uint8_t size)
  576. {
  577. uint8_t offset = s_ota_ctx.param_offset;
  578. uint8_t* param_buf = (uint8_t*)(s_ota_ctx.param_buf);
  579. osal_memcpy(param_buf + offset, data, size);
  580. offset += size;
  581. if(offset > s_ota_ctx.param_size){
  582. handle_error(PPlus_ERR_OTA_DATA_SIZE);
  583. return;
  584. }
  585. if(offset == s_ota_ctx.param_size){
  586. //case param data finished
  587. s_ota_ctx.ota_state = OTA_ST_WAIT_PARTITION_INFO;
  588. response(OTA_RSP_PARAM, PPlus_SUCCESS);
  589. }
  590. return;
  591. }
  592. */
  593. void process_ota_data(uint8_t* data, uint8_t size){
  594. switch(s_ota_ctx.ota_state){
  595. case OTA_ST_DATA:
  596. process_ota_partition_data(data, size);
  597. break;
  598. //case OTA_ST_PARAM:
  599. // process_ota_param_data(data, size);
  600. // break;
  601. default:
  602. handle_error_state();
  603. break;
  604. }
  605. }
  606. void process_service_evt(ota_Evt_t* pev)
  607. {
  608. AT_LOG("PSE: ev[%d], st[%d ]\n",pev->ev, s_ota_ctx.ota_state);
  609. switch(pev->ev){
  610. case OTA_EVT_CONTROL:
  611. process_ctrl_cmd(pev->data, pev->size);
  612. break;
  613. case OTA_EVT_DATA:
  614. process_ota_data(pev->data, pev->size);
  615. break;
  616. case OTA_EVT_CONNECTED:
  617. break;
  618. case OTA_EVT_DISCONNECTED:
  619. LOG("[OTA_EVT_DISCONNECTED]Disconnected!\n");
  620. if(s_ota_ctx.reboot_flag){
  621. LOG("Reboot!\n");
  622. NVIC_SystemReset();
  623. }
  624. reset_ctx();
  625. break;
  626. case OTA_EVT_NOTIF_ENABLE:
  627. s_ota_ctx.ota_state = OTA_ST_CONNECTED;
  628. s_ota_ctx.notif_en = TRUE;
  629. break;
  630. case OTA_EVT_NOTIF_DISABLE:
  631. s_ota_ctx.ota_state = OTA_ST_UNCONNECTED;
  632. s_ota_ctx.notif_en = FALSE;
  633. break;
  634. default:
  635. break;
  636. }
  637. }
  638. void __attribute__((section("ota_app_loader_area"))) otaProtocol_RunApp(void)
  639. {
  640. uint32_t* prunpc = (uint32_t*)(0x1fff4800);
  641. jump_to_application(prunpc[1]);
  642. }
  643. int __attribute__((section("ota_app_loader_area"))) run_application(void)
  644. {
  645. int ret;
  646. HAL_ENTER_CRITICAL_SECTION();
  647. ret = ota_flash_load_app();
  648. if(ret == PPlus_SUCCESS){
  649. otaProtocol_RunApp();
  650. }
  651. HAL_EXIT_CRITICAL_SECTION();
  652. return PPlus_SUCCESS;
  653. }
  654. int run_fct(void)
  655. {
  656. HAL_ENTER_CRITICAL_SECTION();
  657. {
  658. #if(CFG_FLASH >= 512)
  659. int ret = ota_flash_load_fct();
  660. if(ret != PPlus_SUCCESS)
  661. #endif
  662. otaProtocol_RunApp();
  663. }
  664. HAL_EXIT_CRITICAL_SECTION();
  665. return PPlus_SUCCESS;
  666. }
  667. void otaProtocol_mtu(uint16_t mtu)
  668. {
  669. s_ota_ctx.mtu_a = mtu - 3;
  670. //response(OTA_RSP_BLOCK_BURST, PPlus_ERR_OTA_BAD_DATA);
  671. }
  672. void otaProtocol_TimerEvt(void)
  673. {
  674. s_ota_ctx.block_offset = s_ota_ctx.block_offset_retry;
  675. response(OTA_RSP_BLOCK_BURST, PPlus_ERR_OTA_BAD_DATA);
  676. }
  677. void otaProtocol_BootMode(void)
  678. {
  679. uint32_t ota_mode = read_reg(OTA_MODE_SELECT_REG) & 0xf;
  680. uint32_t reg = ((SDK_VER_MAJOR &0xf) << 4) | ((SDK_VER_MINOR &0xf)<< 8) | ((SDK_VER_REVISION &0xff)<<12);
  681. #ifdef SDK_VER_TEST_BUILD
  682. reg |= (((SDK_VER_TEST_BUILD - 'a' + 1)&0xf) << 20);
  683. #endif
  684. write_reg(OTA_MODE_SELECT_REG,reg);
  685. switch(ota_mode){
  686. case OTA_MODE_OTA_APPLICATION:
  687. run_application();
  688. break;
  689. case OTA_MODE_OTA_FCT:
  690. run_fct();
  691. break;
  692. case OTA_MODE_RESOURCE:
  693. s_ota_resource = TRUE;
  694. break;
  695. case OTA_MODE_OTA_NADDR:
  696. s_ota_address_plus = FALSE;
  697. default:
  698. break;
  699. }
  700. }
  701. bool otaProtocol_address_plus(void)
  702. {
  703. return s_ota_address_plus;
  704. }
  705. int otaProtocol_init(uint8_t task_id, uint16_t tm_evt)
  706. {
  707. s_ota_ctx.task_id = task_id;
  708. s_ota_ctx.tm_evt = tm_evt;
  709. reset_ctx();
  710. ota_flash_read_bootsector(&s_ota_ctx.bank_addr);
  711. ota_AddService(process_service_evt);
  712. return PPlus_SUCCESS;
  713. }