ota_trans_bt.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020
  1. /*
  2. * Copyright (c) 2019 Actions Semiconductor Co., Ltd
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. /**
  7. * @file
  8. * @brief OTA bluetooth backend interface
  9. */
  10. #include <kernel.h>
  11. #include <string.h>
  12. #include <stream.h>
  13. #include <soc.h>
  14. #include <mem_manager.h>
  15. #include <ota_trans_bt.h>
  16. #include <os_common_api.h>
  17. #include <bt_manager.h>
  18. #include <ota_api.h>
  19. #define PROT_OTA_FACTORY_OFFLINE (1)
  20. struct cli_prot_head {
  21. u8_t svc_id;
  22. u8_t cmd;
  23. u8_t param_type;
  24. u16_t param_len;
  25. } __attribute__((packed));
  26. struct cli_tlv_head {
  27. u8_t type;
  28. u16_t len;
  29. u8_t value[0];
  30. } __attribute__((packed));
  31. struct cli_tlv_data {
  32. u8_t type;
  33. u16_t len;
  34. u16_t max_len;
  35. u8_t *value_ptr;
  36. };
  37. typedef int (*cli_prot_cmd_handler_t)(struct cli_prot_context *ctx, u16_t param_len);
  38. struct cli_prot_cmd {
  39. u8_t cmd;
  40. cli_prot_cmd_handler_t handler;
  41. };
  42. #if 1
  43. int ota_cli_send_cmd(struct cli_prot_context *ctx, u8_t cmd,u8_t *buf, int size);
  44. int cli_tlv_unpack_head(struct cli_prot_context *ctx, struct cli_tlv_data *tlv);
  45. int cli_prot_get_rx_data(struct cli_prot_context *ctx, u8_t *buf, int size);
  46. int cli_prot_skip_rx_data(struct cli_prot_context *ctx, int size);
  47. int cli_drop_all_rx_data(struct cli_prot_context *ctx, int wait_ms);
  48. u8_t *cli_tlv_pack_data(u8_t *buf, u8_t type, u16_t len, u32_t number);
  49. int cli_tlv_unpack_data(struct cli_prot_context *ctx, u8_t type, int *len,
  50. u8_t *value_ptr, int max_len);
  51. #define TLV_PACK_U8(buf, type, value) cli_tlv_pack_data(buf, type, sizeof(u8_t), value)
  52. #define TLV_PACK_U16(buf, type, value) cli_tlv_pack_data(buf, type, sizeof(u16_t), value)
  53. #define TLV_PACK_U32(buf, type, value) cli_tlv_pack_data(buf, type, sizeof(u32_t), value)
  54. #define TLV_UNPACK_U8(ctx, type, value_ptr) \
  55. cli_tlv_unpack_data(ctx, type, NULL, (u8_t *)value_ptr, sizeof(u8_t))
  56. #define TLV_UNPACK_U16(ctx, type, value_ptr) \
  57. cli_tlv_unpack_data(ctx, type, NULL, (u8_t *)value_ptr, sizeof(u16_t))
  58. #define TLV_UNPACK_U32(ctx, type, value_ptr) \
  59. cli_tlv_unpack_data(ctx, type, NULL, (u8_t *)value_ptr, sizeof(u32_t))
  60. #endif
  61. #define print_hex1(str, buf, size) do {printk("%s\n", str); print_buffer(buf, 1, size, 16, 0);} while(0)
  62. /* support check data checksum in each ota unit */
  63. /* for sppble_stream callback */
  64. static struct ota_trans_bt *g_trans_bt;
  65. int cli_prot_get_rx_data(struct cli_prot_context *ctx, uint8_t *buf, int size)
  66. {
  67. int read_size;
  68. while (size > 0) {
  69. read_size = stream_read(ctx->sppble_stream, buf, size);
  70. if (read_size <= 0) {
  71. SYS_LOG_ERR("need read %d bytes, but only got %d bytes",
  72. size, read_size);
  73. return -EIO;
  74. }
  75. size -= read_size;
  76. buf += read_size;
  77. }
  78. return 0;
  79. }
  80. int cli_prot_skip_rx_data(struct cli_prot_context *ctx, int size)
  81. {
  82. int err;
  83. uint8_t c;
  84. while (size > 0) {
  85. err = cli_prot_get_rx_data(ctx, &c, sizeof(uint8_t));
  86. if (err) {
  87. SYS_LOG_ERR("failed to get data");
  88. return err;
  89. }
  90. size--;
  91. }
  92. return 0;
  93. }
  94. int cli_drop_all_rx_data(struct cli_prot_context *ctx, int wait_ms)
  95. {
  96. int err, data_len;
  97. int ms = wait_ms;
  98. while (wait_ms > 0) {
  99. data_len = stream_tell(ctx->sppble_stream);
  100. if (data_len > 0) {
  101. SYS_LOG_INF("drop data len 0x%x", data_len);
  102. err = cli_prot_skip_rx_data(ctx, data_len);
  103. if (err)
  104. return err;
  105. wait_ms = ms;
  106. }
  107. os_sleep(20);
  108. wait_ms -= 20;
  109. }
  110. return 0;
  111. }
  112. uint8_t *cli_tlv_pack(uint8_t *buf, const struct cli_tlv_data *tlv)
  113. {
  114. uint16_t len;
  115. len = tlv->len;
  116. *buf++ = tlv->type;
  117. *buf++ = len & 0xff;
  118. *buf++ = len >> 8;
  119. if (tlv->value_ptr) {
  120. memcpy(buf, tlv->value_ptr, len);
  121. buf += len;
  122. }
  123. return buf;
  124. }
  125. uint8_t *cli_tlv_pack_data(uint8_t *buf, uint8_t type, uint16_t len, uint32_t number)
  126. {
  127. struct cli_tlv_data tlv;
  128. tlv.type = type;
  129. tlv.len = len;
  130. tlv.value_ptr = (uint8_t *)&number;
  131. return cli_tlv_pack(buf, &tlv);
  132. }
  133. int cli_tlv_unpack_head(struct cli_prot_context *ctx, struct cli_tlv_data *tlv)
  134. {
  135. int err, total_len;
  136. /* read type */
  137. err = cli_prot_get_rx_data(ctx, &tlv->type, sizeof(tlv->type));
  138. if (err) {
  139. SYS_LOG_ERR("failed to read tlv type");
  140. return err;
  141. }
  142. /* read length */
  143. err = cli_prot_get_rx_data(ctx, (uint8_t *)&tlv->len, sizeof(tlv->len));
  144. if (err) {
  145. SYS_LOG_ERR("failed to read tlv type");
  146. return err;
  147. }
  148. total_len = sizeof(tlv->type) + sizeof(tlv->len);
  149. return total_len;
  150. }
  151. int cli_tlv_unpack(struct cli_prot_context *ctx, struct cli_tlv_data *tlv)
  152. {
  153. uint16_t data_len;
  154. int err, total_len;
  155. total_len = cli_tlv_unpack_head(ctx, tlv);
  156. if (tlv->len <= 0)
  157. return total_len;
  158. data_len = tlv->len;
  159. if (data_len > tlv->max_len) {
  160. data_len = tlv->max_len;
  161. }
  162. /* read value */
  163. if (tlv->value_ptr) {
  164. err = cli_prot_get_rx_data(ctx, tlv->value_ptr, data_len);
  165. if (err) {
  166. SYS_LOG_ERR("failed to read tlv value");
  167. return err;
  168. }
  169. total_len += data_len;
  170. }
  171. return total_len;
  172. }
  173. int cli_tlv_unpack_data(struct cli_prot_context *ctx, uint8_t type, int *len,
  174. uint8_t *value_ptr, int max_len)
  175. {
  176. struct cli_tlv_data tlv;
  177. int rlen;
  178. tlv.value_ptr = value_ptr;
  179. tlv.max_len = max_len;
  180. rlen = cli_tlv_unpack(ctx, &tlv);
  181. if (rlen < 0) {
  182. SYS_LOG_ERR("cli_tlv_unpack failed, err 0x%x", rlen);
  183. return rlen;
  184. }
  185. if (tlv.type != type) {
  186. SYS_LOG_ERR("unmatched type, need 0x%x but got 0x%x", type, tlv.type);
  187. return -EIO;
  188. }
  189. if (len)
  190. *len = tlv.len;
  191. return rlen;
  192. }
  193. int cli_prot_send_data(struct cli_prot_context *ctx, uint8_t *buf, int size)
  194. {
  195. int err;
  196. err = stream_write(ctx->sppble_stream, buf, size);
  197. if (err < 0) {
  198. SYS_LOG_ERR("failed to send data, size %d, err %d", size, err);
  199. return -EIO;
  200. }
  201. return 0;
  202. }
  203. int ota_cli_send_cmd(struct cli_prot_context *ctx, uint8_t cmd,
  204. uint8_t *buf, int size)
  205. {
  206. struct cli_prot_head *head;
  207. int err;
  208. head = (struct cli_prot_head *)buf;
  209. head->svc_id = SERVICE_ID_OTA;
  210. head->cmd = cmd;
  211. head->param_type = TLV_TYPE_MAIN;
  212. head->param_len = size - sizeof(struct cli_prot_head);
  213. SYS_LOG_INF("send cmd: %d", cmd);
  214. //print_buffer(buf, 1, size, 16, buf);
  215. err = cli_prot_send_data(ctx, buf, size);
  216. if (err) {
  217. SYS_LOG_ERR("failed to send cmd %d, err %d", cmd, err);
  218. return err;
  219. }
  220. return 0;
  221. }
  222. int ota_ioctl_request_upgrade_ack(struct cli_prot_context *ctx, u16_t param_size)
  223. {
  224. int err, head_len;
  225. struct cli_tlv_data tlv;
  226. u8_t host_features, device_features;
  227. struct ota_trans *trans = &g_trans_bt->trans;
  228. SYS_LOG_INF("upgrade request: param_size %d", param_size);
  229. ctx->host_features = 0;
  230. device_features = 0;
  231. while (param_size > 0) {
  232. head_len = cli_tlv_unpack_head(ctx, &tlv);
  233. if (head_len <= 0)
  234. return -EIO;
  235. switch (tlv.type) {
  236. case TLV_TYPE_OTA_SUPPORT_FEATURES:
  237. err = cli_prot_get_rx_data(ctx, &host_features, 1);
  238. if (err) {
  239. SYS_LOG_ERR("failed to read tlv value");
  240. return err;
  241. }
  242. ctx->host_features = host_features;
  243. SYS_LOG_INF("host support features: 0x%x", host_features);
  244. break;
  245. default:
  246. /* skip other parameters by now */
  247. err = cli_prot_skip_rx_data(ctx, tlv.len);
  248. if (err)
  249. return -EIO;
  250. break;
  251. }
  252. param_size -= head_len + tlv.len;
  253. }
  254. ctx->state = PROT_STATE_IDLE;
  255. if (trans->cb) {
  256. trans->cb(trans,OTA_TRANS_REQUEST_UPGRADE_ACK,NULL);
  257. }
  258. return 0;
  259. }
  260. int ota_ioctl_connect_negotiation_ack(struct cli_prot_context *ctx, u16_t param_len)
  261. {
  262. u16_t app_wait_timeout, device_restart_timeout, ota_unit_size, interval;
  263. int head_len;
  264. int err;
  265. struct cli_tlv_data tlv;
  266. struct ota_trans *trans = &g_trans_bt->trans;
  267. SYS_LOG_INF("param_len %d\n", param_len);
  268. while (param_len > 0) {
  269. head_len = cli_tlv_unpack_head(ctx, &tlv);
  270. if (head_len <= 0)
  271. return -EIO;
  272. switch (tlv.type) {
  273. case TLV_TYPE_OTA_WAIT_TIMEOUT:
  274. err = cli_prot_get_rx_data(ctx, (u8_t *)&app_wait_timeout, 2);
  275. if (err) {
  276. SYS_LOG_ERR("failed to read tlv value");
  277. return err;
  278. }
  279. ctx->app_wait_timeout = app_wait_timeout;
  280. // SYS_LOG_INF("host wait_timeout: 0x%x", app_wait_timeout);
  281. break;
  282. case TLV_TYPE_OTA_RESTART_TIMEOUT:
  283. err = cli_prot_get_rx_data(ctx, (u8_t *)&device_restart_timeout, 2);
  284. if (err) {
  285. SYS_LOG_ERR("failed to read tlv value");
  286. return err;
  287. }
  288. ctx->device_restart_timeout = device_restart_timeout;
  289. // SYS_LOG_INF("device_restart_timeout: 0x%x", device_restart_timeout);
  290. break;
  291. case TLV_TYPE_OTA_UINT_SIZE:
  292. err = cli_prot_get_rx_data(ctx, (u8_t *)&ota_unit_size, 2);
  293. if (err) {
  294. SYS_LOG_ERR("failed to read tlv value");
  295. return err;
  296. }
  297. ctx->ota_unit_size = ota_unit_size;
  298. SYS_LOG_INF("ota_unit_size: 0x%x", ota_unit_size);
  299. break;
  300. case TLV_TYPE_OTA_INTERVAL:
  301. err = cli_prot_get_rx_data(ctx, (u8_t *)&interval, 2);
  302. if (err) {
  303. SYS_LOG_ERR("failed to read tlv value");
  304. return err;
  305. }
  306. ctx->ota_interval = interval;
  307. // SYS_LOG_INF("interval: 0x%x", interval);
  308. break;
  309. default:
  310. /* skip other parameters by now */
  311. err = cli_prot_skip_rx_data(ctx, tlv.len);
  312. if (err)
  313. return -EIO;
  314. break;
  315. }
  316. param_len -= head_len + tlv.len;
  317. }
  318. ctx->state = PROT_STATE_IDLE;
  319. if (trans->cb) {
  320. trans->cb(trans,OTA_TRANS_CONNECT_NEGOTIATION_ACK,NULL);
  321. }
  322. return err;
  323. }
  324. int ota_ioctl_require_image_data(struct cli_prot_context *ctx, u16_t param_size)
  325. {
  326. u32_t ota_file_offset, ota_file_len;
  327. u8_t ota_apply_bitmap;
  328. int head_len;
  329. int err;
  330. struct cli_tlv_data tlv;
  331. struct ota_trans *trans = &g_trans_bt->trans;
  332. struct ota_trans_image_info image;
  333. // SYS_LOG_INF("param_len %d\n", param_size);
  334. while (param_size > 0) {
  335. head_len = cli_tlv_unpack_head(ctx, &tlv);
  336. if (head_len <= 0)
  337. return -EIO;
  338. switch (tlv.type) {
  339. case TLV_TYPE_OTA_FILE_OFFSET:
  340. err = cli_prot_get_rx_data(ctx, (u8_t *)&ota_file_offset, 4);
  341. if (err) {
  342. SYS_LOG_ERR("failed to read tlv value");
  343. return err;
  344. }
  345. // SYS_LOG_INF("ota_file_offset: 0x%x", ota_file_offset);
  346. break;
  347. case TLV_TYPE_OTA_FILE_LEN:
  348. err = cli_prot_get_rx_data(ctx, (u8_t *)&ota_file_len, 4);
  349. if (err) {
  350. SYS_LOG_ERR("failed to read tlv value");
  351. return err;
  352. }
  353. // SYS_LOG_INF("ota_file_len: 0x%x", ota_file_len);
  354. break;
  355. case TLV_TYPE_OTA_APPLY_BITMAP:
  356. err = cli_prot_get_rx_data(ctx, (u8_t *)&ota_apply_bitmap, 1);
  357. if (err) {
  358. SYS_LOG_ERR("failed to read tlv value");
  359. return err;
  360. }
  361. // SYS_LOG_INF("ota_apply_bitmap: 0x%x", ota_apply_bitmap);
  362. break;
  363. default:
  364. /* skip other parameters by now */
  365. err = cli_prot_skip_rx_data(ctx, tlv.len);
  366. if (err)
  367. return -EIO;
  368. break;
  369. }
  370. param_size -= head_len + tlv.len;
  371. }
  372. ctx->state = PROT_STATE_IDLE;
  373. if (trans->cb) {
  374. SYS_LOG_INF("ota_file_offset 0x%x ota_file_len 0x%x\n", ota_file_offset,ota_file_len);
  375. image.image_offset = ota_file_offset;
  376. image.read_len = ota_file_len;
  377. trans->cb(trans,OTA_TRANS_REQUEST_IMAGE_DATA,&image);
  378. }
  379. return 0;
  380. }
  381. int ota_ioctl_validate_image_report(struct cli_prot_context *ctx,u16_t param_size)
  382. {
  383. int err, send_len;
  384. u8_t *send_buf;
  385. int head_len;
  386. u8_t valid_report;
  387. struct cli_tlv_data tlv;
  388. struct ota_trans *trans = &g_trans_bt->trans;
  389. SYS_LOG_INF("%x",(uint32)ctx);
  390. while (param_size > 0) {
  391. head_len = cli_tlv_unpack_head(ctx, &tlv);
  392. if (head_len <= 0)
  393. return -EIO;
  394. switch (tlv.type) {
  395. case TLV_TYPE_OTA_VALID_REPORT:
  396. err = cli_prot_get_rx_data(ctx, (u8_t *)&valid_report, 1);
  397. if (err) {
  398. SYS_LOG_ERR("failed to read tlv value");
  399. return err;
  400. }
  401. SYS_LOG_INF("valid_report: 0x%x", valid_report);
  402. break;
  403. default:
  404. /* skip other parameters by now */
  405. err = cli_prot_skip_rx_data(ctx, tlv.len);
  406. if (err)
  407. return -EIO;
  408. break;
  409. }
  410. param_size -= head_len + tlv.len;
  411. }
  412. send_buf = ctx->send_buf + sizeof(struct cli_prot_head);
  413. send_len = send_buf - ctx->send_buf;
  414. err = ota_cli_send_cmd(ctx, OTA_CMD_D2H_VALIDATE_IMAGE, ctx->send_buf, send_len);
  415. if (err) {
  416. SYS_LOG_ERR("failed to send cmd %d, error %d",
  417. OTA_CMD_D2H_VALIDATE_IMAGE, err);
  418. return err;
  419. }
  420. ctx->state = PROT_STATE_IDLE;
  421. if (trans->cb) {
  422. trans->cb(trans,OTA_TRANS_VALIDATE_REPORT,&valid_report);
  423. }
  424. return 0;
  425. }
  426. int ota_ioctl_remote_report_satus(struct cli_prot_context *ctx,u16_t param_size)
  427. {
  428. int err;
  429. u32_t status_code ;
  430. int head_len;
  431. struct cli_tlv_data tlv;
  432. struct ota_trans *trans = &g_trans_bt->trans;
  433. SYS_LOG_INF("%x",(uint32)ctx);
  434. while (param_size > 0) {
  435. head_len = cli_tlv_unpack_head(ctx, &tlv);
  436. if (head_len <= 0)
  437. return -EIO;
  438. switch (tlv.type) {
  439. case TLV_TYPE_OTA_STATUS_CODE:
  440. err = cli_prot_get_rx_data(ctx, (u8_t *)&status_code, 4);
  441. if (err) {
  442. SYS_LOG_ERR("failed to read tlv value");
  443. return err;
  444. }
  445. SYS_LOG_INF("status_code: 0x%x", status_code);
  446. break;
  447. default:
  448. /* skip other parameters by now */
  449. err = cli_prot_skip_rx_data(ctx, tlv.len);
  450. if (err)
  451. return -EIO;
  452. break;
  453. }
  454. param_size -= head_len + tlv.len;
  455. }
  456. ctx->state = PROT_STATE_IDLE;
  457. if (trans->cb) {
  458. trans->cb(trans,OTA_TRANS_UPGRADE_STATUS_NOTIFY,&status_code);
  459. }
  460. return 0;
  461. }
  462. struct cli_prot_cmd ota_cli_cmds[] = {
  463. {OTA_CMD_H2D_REQUEST_UPGRADE, ota_ioctl_request_upgrade_ack,},
  464. {OTA_CMD_H2D_CONNECT_NEGOTIATION, ota_ioctl_connect_negotiation_ack,},
  465. {OTA_CMD_D2H_REQUIRE_IMAGE_DATA, ota_ioctl_require_image_data,},
  466. {OTA_CMD_D2H_VALIDATE_IMAGE, ota_ioctl_validate_image_report,},
  467. {OTA_CMD_D2H_REPORT_STATUS,ota_ioctl_remote_report_satus,}
  468. };
  469. int ota_trans_process_command(struct cli_prot_context *ctx, u32_t *processed_cmd)
  470. {
  471. struct cli_prot_head head;
  472. cli_prot_cmd_handler_t cmd_handler;
  473. int i, err;
  474. if (ctx->state != PROT_STATE_IDLE) {
  475. SYS_LOG_ERR("current state is not idle");
  476. return -EIO;
  477. }
  478. err = cli_prot_get_rx_data(ctx, (u8_t *)&head, sizeof(struct cli_prot_head));
  479. if (err) {
  480. SYS_LOG_ERR("cannot read head bytes");
  481. return -EIO;
  482. }
  483. SYS_LOG_INF("cli head: svc_id 0x%x, cmd_id 0x%x, param type 0x%x, len 0x%x",
  484. head.svc_id, head.cmd, head.param_type, head.param_len);
  485. ctx->state = PROT_STATE_DATA;
  486. if (head.svc_id != SERVICE_ID_OTA) {
  487. SYS_LOG_ERR("invalid svc_id: %d", head.svc_id);
  488. return -EIO;
  489. }
  490. if (head.param_type != TLV_TYPE_MAIN) {
  491. SYS_LOG_ERR("invalid param type: %d", head.svc_id);
  492. return -EIO;
  493. }
  494. for (i = 0; i < ARRAY_SIZE(ota_cli_cmds); i++) {
  495. if (ota_cli_cmds[i].cmd == head.cmd) {
  496. cmd_handler = ota_cli_cmds[i].handler;
  497. err = cmd_handler(ctx, head.param_len);
  498. if (processed_cmd){
  499. *processed_cmd = head.cmd;
  500. }
  501. if (err) {
  502. SYS_LOG_ERR("cmd_handler %p, err: %d", cmd_handler, err);
  503. return err;
  504. }
  505. }
  506. }
  507. if (i > ARRAY_SIZE(ota_cli_cmds)) {
  508. SYS_LOG_ERR("invalid cmd: %d", head.cmd);
  509. return -1;
  510. }
  511. ctx->state = PROT_STATE_IDLE;
  512. return err;
  513. }
  514. int ota_ioctl_request_upgrade(struct cli_prot_context *ctx,struct ota_trans_image_head_info * head_info)
  515. {
  516. int err, send_len;
  517. u8_t *send_buf;
  518. u32_t version = head_info->version;
  519. u32_t head_crc = head_info->head_crc;
  520. u8_t temp = 0;
  521. u32_t feature = 1;
  522. u32_t ota_type = PROT_OTA_FACTORY_OFFLINE;
  523. SYS_LOG_INF("%x %x %x",(uint32)ctx,version,head_crc);
  524. ctx->host_features = 1;
  525. send_buf = ctx->send_buf + sizeof(struct cli_prot_head);
  526. send_buf = TLV_PACK_U32(send_buf,0x01,version);
  527. send_buf = TLV_PACK_U32(send_buf,0x03,head_crc);
  528. send_buf = TLV_PACK_U8(send_buf, 0x04, temp);
  529. send_buf = TLV_PACK_U8(send_buf, 0x09, feature);
  530. send_buf = TLV_PACK_U32(send_buf, 0x0A, ota_type);
  531. send_len = send_buf - ctx->send_buf;
  532. err = ota_cli_send_cmd(ctx, OTA_CMD_H2D_REQUEST_UPGRADE, ctx->send_buf, send_len);
  533. if (err) {
  534. SYS_LOG_ERR("failed to send cmd %d, error %d",
  535. OTA_CMD_H2D_REQUEST_UPGRADE, err);
  536. return err;
  537. }
  538. ctx->state = PROT_STATE_IDLE;
  539. return 0;
  540. }
  541. int ota_ioctl_connect_negotiation(struct cli_prot_context *ctx)
  542. {
  543. int err, send_len;
  544. SYS_LOG_INF("%x",(uint32)ctx);
  545. send_len = sizeof(struct cli_prot_head);
  546. err = ota_cli_send_cmd(ctx, OTA_CMD_H2D_CONNECT_NEGOTIATION, ctx->send_buf, send_len);
  547. if (err) {
  548. SYS_LOG_ERR("failed to send cmd %d, error %d",
  549. OTA_CMD_H2D_CONNECT_NEGOTIATION, err);
  550. return err;
  551. }
  552. ctx->state = PROT_STATE_IDLE;
  553. return 0;
  554. }
  555. int ota_ioctl_negotiation_result(struct cli_prot_context *ctx)
  556. {
  557. int err, send_len;
  558. u8_t *send_buf;
  559. u8_t negotiation_result = 1;
  560. struct ota_trans *trans = &g_trans_bt->trans;
  561. SYS_LOG_INF("%x",(uint32)ctx);
  562. send_buf = ctx->send_buf + sizeof(struct cli_prot_head);
  563. send_buf = TLV_PACK_U8(send_buf, 0x01, negotiation_result);
  564. send_len = send_buf - ctx->send_buf;
  565. err = ota_cli_send_cmd(ctx, OTA_CMD_H2D_NEGOTIATION_RESULT, ctx->send_buf, send_len);
  566. if (err) {
  567. SYS_LOG_ERR("failed to send cmd %d, error %d",
  568. OTA_CMD_H2D_NEGOTIATION_RESULT, err);
  569. return err;
  570. }
  571. ctx->state = PROT_STATE_IDLE;
  572. ctx->negotiation_done = 1;
  573. if (trans->cb) {
  574. trans->cb(trans,OTA_TRANS_NEGOTIATION_RESULT_ACK,NULL);
  575. }
  576. return 0;
  577. }
  578. int ota_ioctl_send_image_data(struct cli_prot_context *ctx,struct ota_trans_upgrade_image * image_info)
  579. {
  580. int err, send_len;
  581. u8_t *send_buf;
  582. int image_size = image_info->size;
  583. u8_t *image_buffer = image_info->buffer;
  584. u16_t unit_size = ctx->ota_unit_size;
  585. u8_t * crc_pos;
  586. u32_t crc;
  587. SYS_LOG_INF("%x %d %x",(uint32)ctx,ctx->ota_unit_size,image_size);
  588. if (0 == image_info->ctn) {
  589. ctx->last_psn = 0;
  590. }
  591. while(image_size)
  592. {
  593. send_buf = ctx->send_buf + sizeof(struct cli_prot_head);
  594. *(send_buf++) = ctx->last_psn;
  595. crc_pos = send_buf;
  596. send_buf += sizeof(u32_t);
  597. if(image_size > unit_size)
  598. {
  599. memcpy(send_buf,image_buffer,unit_size);
  600. crc = utils_crc32(0,send_buf, unit_size);
  601. image_size -= unit_size;
  602. image_buffer += unit_size;
  603. send_buf += unit_size;
  604. }
  605. else
  606. {
  607. memcpy(send_buf,image_buffer,image_size);
  608. crc = utils_crc32(0,send_buf, image_size);
  609. send_buf += image_size;
  610. image_size = 0;
  611. }
  612. *(crc_pos++) = (u8_t)(crc & 0xff);
  613. *(crc_pos++) = (u8_t)((crc >> 8) & 0xff);
  614. *(crc_pos++) = (u8_t)((crc >> 16) & 0xff);
  615. *(crc_pos++) = (u8_t)((crc >> 24) & 0xff);
  616. send_len = send_buf - ctx->send_buf;
  617. SYS_LOG_INF("%d:",send_len);
  618. // print_hex1("image",ctx->send_buf,32);
  619. err = ota_cli_send_cmd(ctx, OTA_CMD_H2D_SEND_IMAGE_DATA_WITH_CRC, ctx->send_buf, send_len);
  620. if (err) {
  621. SYS_LOG_ERR("failed to send cmd %d, error %d",
  622. OTA_CMD_H2D_CONNECT_NEGOTIATION, err);
  623. return err;
  624. }
  625. ctx->state = PROT_STATE_IDLE;
  626. ctx->last_psn += 1;
  627. //os_sleep(1);
  628. }
  629. return 0;
  630. }
  631. int ota_trans_bt_open(struct ota_trans *trans)
  632. {
  633. struct ota_trans_bt *trans_bt = CONTAINER_OF(trans,
  634. struct ota_trans_bt, trans);
  635. struct cli_prot_context *cli_ctx = &trans_bt->cli_ctx;
  636. int err;
  637. if (cli_ctx->sppble_stream) {
  638. err = stream_open(cli_ctx->sppble_stream, MODE_IN_OUT);
  639. if (err) {
  640. SYS_LOG_ERR("stream_open Failed");
  641. return err;
  642. } else {
  643. cli_ctx->sppble_stream_opened = 1;
  644. }
  645. }
  646. SYS_LOG_INF("open sppble_stream %p", cli_ctx->sppble_stream);
  647. return 0;
  648. }
  649. int ota_trans_bt_close(struct ota_trans *trans)
  650. {
  651. struct ota_trans_bt *trans_bt = CONTAINER_OF(trans,
  652. struct ota_trans_bt, trans);
  653. struct cli_prot_context *cli_ctx = &trans_bt->cli_ctx;
  654. int err;
  655. SYS_LOG_INF("close: type %d", trans->type);
  656. if (cli_ctx->sppble_stream_opened) {
  657. err = stream_close(cli_ctx->sppble_stream);
  658. if (err) {
  659. SYS_LOG_ERR("stream_close Failed");
  660. } else {
  661. cli_ctx->sppble_stream_opened = 0;
  662. }
  663. /* clear internal status */
  664. cli_ctx->negotiation_done = 0;
  665. }
  666. return 0;
  667. }
  668. void ota_trans_bt_exit(struct ota_trans *trans)
  669. {
  670. struct ota_trans_bt *trans_bt = CONTAINER_OF(trans,
  671. struct ota_trans_bt, trans);
  672. struct cli_prot_context *cli_ctx = &trans_bt->cli_ctx;
  673. /* avoid connect again after exit */
  674. g_trans_bt = NULL;
  675. if (cli_ctx->sppble_stream) {
  676. stream_destroy(cli_ctx->sppble_stream);
  677. }
  678. if (trans_bt->cli_ctx.send_buf)
  679. mem_free(trans_bt->cli_ctx.send_buf);
  680. mem_free(trans_bt);
  681. }
  682. int ota_trans_bt_ioctl(struct ota_trans *trans, int cmd, void* param)
  683. {
  684. struct ota_trans_bt *trans_bt = CONTAINER_OF(trans,
  685. struct ota_trans_bt, trans);
  686. struct cli_prot_context *cli_ctx = &trans_bt->cli_ctx;
  687. int err = 0;
  688. SYS_LOG_INF("cmd %d", cmd);
  689. switch(cmd)
  690. {
  691. case OTA_TRANS_IOCTL_REQUEST_UPGRADE:
  692. err = ota_ioctl_request_upgrade(cli_ctx,(struct ota_trans_image_head_info *)param);
  693. break;
  694. case OTA_TRANS_IOCTL_CONNECT_NEGOTIATION:
  695. err = ota_ioctl_connect_negotiation(cli_ctx);
  696. break;
  697. case OTA_TRANS_IOCTL_NEGOTIATION_RESULT:
  698. err = ota_ioctl_negotiation_result(cli_ctx);
  699. break;
  700. case OTA_TRANS_IOCTL_SEND_IMAGE:
  701. err = ota_ioctl_send_image_data(cli_ctx,(struct ota_trans_upgrade_image *)param);
  702. break;
  703. case OTA_TRANS_IOCTL_UNITSIZE_GET:
  704. return cli_ctx->ota_unit_size;
  705. default :
  706. break;
  707. }
  708. if (err) {
  709. SYS_LOG_INF("send cmd 0x%x error", cmd);
  710. return -EIO;
  711. }
  712. return 0;
  713. }
  714. int ota_trans_bt_read(struct ota_trans *trans, int offset, void *buf, int size)
  715. {
  716. return 0;
  717. }
  718. static void ota_sppble_connect_cb(int connected)
  719. {
  720. struct ota_trans *trans;
  721. SYS_LOG_INF("connect: %d", connected);
  722. /* avoid connect again after exit */
  723. if (g_trans_bt) {
  724. trans = &g_trans_bt->trans;
  725. if (trans->cb) {
  726. SYS_LOG_INF("call cb %p", trans->cb);
  727. if(connected)
  728. {
  729. trans->cb(trans, OTA_TRANS_CONNECTED,NULL);
  730. }
  731. else
  732. {
  733. trans->cb(trans, OTA_TRANS_DISCONNECT,NULL);
  734. }
  735. }
  736. }
  737. }
  738. #if 0
  739. static void ota_sppble_sdap_cb(uint16 status)
  740. {
  741. struct ota_trans *trans;
  742. uint16 sdp_status = status;
  743. SYS_LOG_INF("sdp status: %d", status);
  744. if (g_trans_bt) {
  745. trans = &g_trans_bt->trans;
  746. if (trans->cb) {
  747. trans->cb(trans, OTA_TRANS_SDAP_RESULT,&sdp_status);
  748. }
  749. }
  750. }
  751. #endif
  752. static void ota_sppble_rxdata_cb(void)
  753. {
  754. struct ota_trans *trans;
  755. trans = &g_trans_bt->trans;
  756. struct ota_trans_bt *trans_bt = CONTAINER_OF(trans,
  757. struct ota_trans_bt, trans);
  758. struct cli_prot_context *cli_ctx = &trans_bt->cli_ctx;
  759. // SYS_LOG_INF("");
  760. /* avoid connect again after exit */
  761. if (g_trans_bt) {
  762. ota_trans_process_command(cli_ctx,NULL);
  763. }
  764. }
  765. static struct ota_trans_api ota_trans_api_bt = {
  766. /* .init = ota_backend_bt_init, */
  767. .exit = ota_trans_bt_exit,
  768. .open = ota_trans_bt_open,
  769. .close = ota_trans_bt_close,
  770. .read = ota_trans_bt_read,
  771. .ioctl = ota_trans_bt_ioctl,
  772. };
  773. struct ota_trans *ota_trans_bt_init(ota_trans_notify_cb_t cb,
  774. struct ota_trans_bt_init_param *param)
  775. {
  776. struct ota_trans_bt *trans_bt;
  777. struct sppble_stream_init_param init_param;
  778. struct cli_prot_context *cli_ctx;
  779. SYS_LOG_INF("init");
  780. trans_bt = mem_malloc(sizeof(struct ota_trans_bt));
  781. if (!trans_bt) {
  782. SYS_LOG_ERR("malloc failed");
  783. return NULL;
  784. }
  785. memset(trans_bt, 0x0, sizeof(struct ota_trans_bt));
  786. cli_ctx = &trans_bt->cli_ctx;
  787. memset(&init_param, 0, sizeof(struct sppble_stream_init_param));
  788. init_param.spp_uuid = (uint8_t *)param->spp_uuid;
  789. init_param.connect_cb = ota_sppble_connect_cb;
  790. //init_param.read_timeout = param->read_timeout; /* K_FOREVER, K_NO_WAIT, K_MSEC(ms) */
  791. //init_param.write_timeout = param->write_timeout;
  792. //init_param.read_buf_size = OTA_SPPBLE_BUFF_SIZE;
  793. init_param.rxdata_cb = ota_sppble_rxdata_cb;
  794. //init_param.sdap_cb = ota_sppble_sdap_cb;
  795. init_param.read_timeout = OS_FOREVER;
  796. init_param.write_timeout = OS_FOREVER;
  797. /* Just call stream_create once, for register spp/ble service
  798. * not need call stream_destroy
  799. */
  800. cli_ctx->sppble_stream = sppble_stream_create(&init_param);
  801. if (!cli_ctx->sppble_stream) {
  802. SYS_LOG_ERR("stream_create failed");
  803. }
  804. cli_ctx->send_buf = mem_malloc(OTA_SVC_TRANS_SEND_BUFFER_SIZE);
  805. cli_ctx->send_buf_size = OTA_SVC_TRANS_SEND_BUFFER_SIZE;
  806. cli_ctx->ota_unit_size = OTA_UNIT_SIZE;
  807. cli_ctx->state = PROT_STATE_IDLE;
  808. cli_ctx->negotiation_done = 0;
  809. g_trans_bt = trans_bt;
  810. ota_trans_init(&trans_bt->trans, OTA_TRANS_TYPE_BLUETOOTH,
  811. &ota_trans_api_bt, cb);
  812. return &trans_bt->trans;
  813. }