1 /*
2 * Copyright (C) 2015-2018 Alibaba Group Holding Limited
3 */
4
5 #include "iotx_ota_internal.h"
6
7 #if (OTA_SIGNAL_CHANNEL) == 1
8 #include "ota_mqtt.c"
9 #elif (OTA_SIGNAL_CHANNEL) == 2
10 #include "ota_coap.c"
11 #else
12 #error "NOT support yet!"
13 #endif
14
15 /* check whether the progress state is valid or not */
16 /* return: true, valid progress state; false, invalid progress state. */
ota_check_progress(IOT_OTA_Progress_t progress)17 static int ota_check_progress(IOT_OTA_Progress_t progress)
18 {
19 return ((progress >= IOT_OTAP_BURN_FAILED) &&
20 (progress <= IOT_OTAP_FETCH_PERCENTAGE_MAX));
21 }
22
ota_callback(void * pcontext,const char * msg,uint32_t msg_len,iotx_ota_topic_types_t type)23 static int ota_callback(void *pcontext, const char *msg, uint32_t msg_len,
24 iotx_ota_topic_types_t type)
25 {
26 const char *pvalue;
27 uint32_t val_len;
28
29 OTA_Struct_pt h_ota = (OTA_Struct_pt)pcontext;
30
31 if (h_ota->state == IOT_OTAS_FETCHING) {
32 OTA_LOG_INFO("In downloading state");
33 return -1;
34 }
35
36 switch (type) {
37 case IOTX_OTA_TOPIC_TYPE_DEVICE_REQUEST:
38 case IOTX_OTA_TOPIC_TYPE_DEVICE_UPGRATE:
39 {
40 pvalue = otalib_JsonValueOf(msg, msg_len, "message", &val_len);
41 if (NULL == pvalue) {
42 OTA_LOG_ERROR("invalid json doc of OTA ");
43 return -1;
44 }
45
46 /* check whether is positive message */
47 if (!((strlen("success") == val_len) &&
48 (0 == strncmp(pvalue, "success", val_len)))) {
49 OTA_LOG_ERROR("fail state of json doc of OTA");
50 return -1;
51 }
52
53 /* get value of 'data' key */
54 pvalue = otalib_JsonValueOf(msg, msg_len, "data", &val_len);
55 if (NULL == pvalue) {
56 OTA_LOG_ERROR("Not 'data' key in json doc of OTA");
57 return -1;
58 }
59
60 if (0 != otalib_GetParams(pvalue, val_len, &h_ota->purl,
61 &h_ota->version, h_ota->md5sum,
62 &h_ota->size_file)) {
63 OTA_LOG_ERROR("Get config parameter failed");
64 return -1;
65 }
66
67 h_ota->ch_fetch =
68 ofc_Init(h_ota->purl, h_ota->size_fetched);
69 if (h_ota->ch_fetch == NULL) {
70 OTA_LOG_ERROR("Initialize fetch module failed");
71 return -1;
72 }
73
74 h_ota->type = IOT_OTAT_FOTA;
75 h_ota->state = IOT_OTAS_PUSHED;
76 }
77 break;
78
79 case IOTX_OTA_TOPIC_TYPE_CONFIG_GET:
80 {
81 pvalue = otalib_JsonValueOf(msg, msg_len, "code", &val_len);
82 if (NULL == pvalue) {
83 OTA_LOG_ERROR("invalid json doc of OTA ");
84 return -1;
85 }
86
87 /* check whether is positive message */
88 if (!((strlen("200") == val_len) &&
89 (0 == strncmp(pvalue, "200", val_len)))) {
90 OTA_LOG_ERROR("fail state of json doc of OTA");
91 return -1;
92 }
93
94 /* get value of 'data' key */
95 pvalue = otalib_JsonValueOf(msg, msg_len, "data", &val_len);
96 if (NULL == pvalue) {
97 OTA_LOG_ERROR("Not 'data' key in json doc of OTA");
98 return -1;
99 }
100
101 if (0 != otalib_GetConfigParams(
102 pvalue, val_len, &h_ota->configId, &h_ota->configSize,
103 &h_ota->sign, &h_ota->signMethod, &h_ota->cota_url,
104 &h_ota->getType)) {
105 OTA_LOG_ERROR("Get firmware parameter failed");
106 return -1;
107 }
108
109 h_ota->size_file = h_ota->configSize;
110 h_ota->size_fetched = 0;
111 if (NULL != h_ota->md5) {
112 otalib_MD5Deinit(h_ota->md5);
113 }
114 h_ota->md5 = otalib_MD5Init();
115
116 if (NULL != h_ota->sha256) {
117 otalib_Sha256Deinit(h_ota->sha256);
118 }
119 h_ota->sha256 = otalib_Sha256Init();
120
121 h_ota->ch_fetch = ofc_Init(h_ota->cota_url, h_ota->size_fetched);
122 if (h_ota->ch_fetch == NULL) {
123 OTA_LOG_ERROR("Initialize fetch module failed");
124 return -1;
125 }
126
127 h_ota->type = IOT_OTAT_COTA;
128 h_ota->state = IOT_OTAS_PUSHED;
129 }
130 break;
131
132 case IOTX_OTA_TOPIC_TYPE_CONFIG_PUSH:
133 {
134 /* get value of 'params' key */
135 pvalue = otalib_JsonValueOf(msg, msg_len, "params", &val_len);
136 if (NULL == pvalue) {
137 OTA_LOG_ERROR("Not 'data' key in json doc of OTA");
138 return -1;
139 }
140
141 if (0 != otalib_GetConfigParams(
142 pvalue, val_len, &h_ota->configId, &h_ota->configSize,
143 &h_ota->sign, &h_ota->signMethod, &h_ota->cota_url,
144 &h_ota->getType)) {
145 OTA_LOG_ERROR("Get firmware parameter failed");
146 return -1;
147 }
148
149 h_ota->size_file = h_ota->configSize;
150 h_ota->size_fetched = 0;
151 if (NULL != h_ota->md5) {
152 otalib_MD5Deinit(h_ota->md5);
153 }
154 h_ota->md5 = otalib_MD5Init();
155
156 if (NULL != h_ota->sha256) {
157 otalib_Sha256Deinit(h_ota->sha256);
158 }
159 h_ota->sha256 = otalib_Sha256Init();
160
161 h_ota->ch_fetch = ofc_Init(h_ota->cota_url, h_ota->size_fetched);
162 if (h_ota->ch_fetch == NULL) {
163 OTA_LOG_ERROR("Initialize fetch module failed");
164 return -1;
165 }
166
167 h_ota->type = IOT_OTAT_COTA;
168 h_ota->state = IOT_OTAS_PUSHED;
169 }
170 break;
171
172 default:
173 return -1;
174 break;
175 }
176
177 if (h_ota->ota_event_cb != NULL) {
178 h_ota->ota_event_cb(h_ota);
179 }
180 return 0;
181 }
182
183 static int g_ota_is_initialized = 0;
184
IOT_OTA_SetOnPushedCallback(void * handle,int (* cb)(void * context))185 int IOT_OTA_SetOnPushedCallback(void *handle, int (*cb)(void *context))
186 {
187 OTA_Struct_pt h_ota = (OTA_Struct_pt)handle;
188 if (h_ota == NULL) {
189 return -1;
190 }
191
192 h_ota->ota_event_cb = cb;
193 return 0;
194 }
195 /* Initialize OTA module */
IOT_OTA_Init(const char * product_key,const char * device_name,void * ch_signal)196 void *IOT_OTA_Init(const char *product_key, const char *device_name,
197 void *ch_signal)
198 {
199 OTA_Struct_pt h_ota = NULL;
200
201 if (1 == g_ota_is_initialized) {
202 OTA_LOG_ERROR("iot ota has been initialized");
203 return NULL;
204 }
205
206 if ((NULL == product_key) || (NULL == device_name)) {
207 OTA_LOG_ERROR("one or more parameters is invalid");
208 return NULL;
209 }
210
211 h_ota = OTA_MALLOC(sizeof(OTA_Struct_t));
212 if (h_ota == NULL) {
213 OTA_LOG_ERROR("allocate failed");
214 return NULL;
215 }
216 memset(h_ota, 0, sizeof(OTA_Struct_t));
217 h_ota->type = IOT_OTAT_NONE;
218 h_ota->state = IOT_OTAS_UNINITED;
219
220 h_ota->ch_signal =
221 osc_Init(product_key, device_name, ch_signal, ota_callback, h_ota);
222 if (NULL == h_ota->ch_signal) {
223 OTA_LOG_ERROR("initialize signal channel failed");
224 goto do_exit;
225 }
226
227 h_ota->md5 = otalib_MD5Init();
228 if (NULL == h_ota->md5) {
229 OTA_LOG_ERROR("initialize md5 failed");
230 goto do_exit;
231 }
232 h_ota->sha256 = otalib_Sha256Init();
233 if (NULL == h_ota->sha256) {
234 OTA_LOG_ERROR("initialize sha256 failed");
235 goto do_exit;
236 }
237
238 h_ota->product_key = product_key;
239 h_ota->device_name = device_name;
240 h_ota->state = IOT_OTAS_INITED;
241 g_ota_is_initialized = 1;
242 return h_ota;
243
244 do_exit:
245
246 if (NULL != h_ota->ch_signal) {
247 osc_Deinit(h_ota->ch_signal);
248 }
249
250 if (NULL != h_ota->md5) {
251 otalib_MD5Deinit(h_ota->md5);
252 }
253
254 if (NULL != h_ota->sha256) {
255 otalib_Sha256Deinit(h_ota->sha256);
256 }
257
258 if (NULL != h_ota) {
259 OTA_FREE(h_ota);
260 }
261
262 return NULL;
263
264 #undef AOM_INFO_MSG_LEN
265 }
266
267 /* deinitialize OTA module */
IOT_OTA_Deinit(void * handle)268 int IOT_OTA_Deinit(void *handle)
269 {
270 OTA_Struct_pt h_ota = (OTA_Struct_pt)handle;
271
272 if (NULL == h_ota) {
273 OTA_LOG_ERROR("handle is NULL");
274 return IOT_OTAE_INVALID_PARAM;
275 }
276
277 if (IOT_OTAS_UNINITED == h_ota->state) {
278 OTA_LOG_ERROR("handle is uninitialized");
279 h_ota->err = IOT_OTAE_INVALID_STATE;
280 return -1;
281 }
282
283 g_ota_is_initialized = 0;
284
285 if (NULL != h_ota->ch_signal) {
286 osc_Deinit(h_ota->ch_signal);
287 }
288
289 if (NULL != h_ota->ch_fetch) {
290 ofc_Deinit(&h_ota->ch_fetch);
291 }
292
293 if (NULL != h_ota->md5) {
294 otalib_MD5Deinit(h_ota->md5);
295 }
296
297 if (NULL != h_ota->sha256) {
298 otalib_Sha256Deinit(h_ota->sha256);
299 }
300
301 if (NULL != h_ota->purl) {
302 OTA_FREE(h_ota->purl);
303 }
304
305 if (NULL != h_ota->version) {
306 OTA_FREE(h_ota->version);
307 }
308
309 if (NULL != h_ota->configId) {
310 OTA_FREE(h_ota->configId);
311 }
312
313 if (NULL != h_ota->sign) {
314 OTA_FREE(h_ota->sign);
315 }
316
317 if (NULL != h_ota->signMethod) {
318 OTA_FREE(h_ota->signMethod);
319 }
320
321 if (NULL != h_ota->cota_url) {
322 OTA_FREE(h_ota->cota_url);
323 }
324
325 if (NULL != h_ota->getType) {
326 OTA_FREE(h_ota->getType);
327 }
328
329 OTA_FREE(h_ota);
330 return 0;
331 }
332
333 #define OTA_VERSION_STR_LEN_MIN (1)
334 #define OTA_VERSION_STR_LEN_MAX (32)
335
IOT_OTA_ReportVersion(void * handle,const char * version)336 int IOT_OTA_ReportVersion(void *handle, const char *version)
337 {
338 #define MSG_INFORM_LEN (128)
339
340 int ret, len;
341 char *msg_informed;
342 OTA_Struct_pt h_ota = (OTA_Struct_pt)handle;
343
344 if ((NULL == h_ota) || (NULL == version)) {
345 OTA_LOG_ERROR("one or more invalid parameter");
346 return IOT_OTAE_INVALID_PARAM;
347 }
348
349 len = strlen(version);
350 if ((len < OTA_VERSION_STR_LEN_MIN) || (len > OTA_VERSION_STR_LEN_MAX)) {
351 OTA_LOG_ERROR("version string is invalid: must be [1, 32] chars");
352 h_ota->err = IOT_OTAE_INVALID_PARAM;
353 return -1;
354 }
355
356 if (IOT_OTAS_UNINITED == h_ota->state) {
357 OTA_LOG_ERROR("handle is uninitialized");
358 h_ota->err = IOT_OTAE_INVALID_STATE;
359 return -1;
360 }
361
362 msg_informed = OTA_MALLOC(MSG_INFORM_LEN);
363 if (msg_informed == NULL) {
364 OTA_LOG_ERROR("allocate for msg_informed failed");
365 h_ota->err = IOT_OTAE_NOMEM;
366 return -1;
367 }
368
369 ret = otalib_GenInfoMsg(msg_informed, MSG_INFORM_LEN, h_ota->id, version);
370 if (ret != 0) {
371 OTA_LOG_ERROR("generate inform message failed");
372 h_ota->err = ret;
373 ret = -1;
374 goto do_exit;
375 }
376
377 ret = osc_ReportVersion(h_ota->ch_signal, msg_informed);
378 if (0 != ret) {
379 OTA_LOG_ERROR("Report version failed");
380 h_ota->err = ret;
381 ret = -1;
382 goto do_exit;
383 }
384 ret = 0;
385
386 do_exit:
387 if (NULL != msg_informed) {
388 OTA_FREE(msg_informed);
389 }
390 return ret;
391
392 #undef MSG_INFORM_LEN
393 }
394
iotx_req_image(void * handle,const char * version)395 int iotx_req_image(void *handle, const char *version)
396 {
397 #define MSG_REQUEST_LEN (128)
398
399 int ret, len;
400 char *msg_informed;
401 OTA_Struct_pt h_ota = (OTA_Struct_pt)handle;
402
403 if ((NULL == h_ota) || (NULL == version)) {
404 OTA_LOG_ERROR("one or more invalid parameter");
405 return IOT_OTAE_INVALID_PARAM;
406 }
407
408 len = strlen(version);
409 if ((len < OTA_VERSION_STR_LEN_MIN) || (len > OTA_VERSION_STR_LEN_MAX)) {
410 OTA_LOG_ERROR("version string is invalid: must be [1, 32] chars");
411 h_ota->err = IOT_OTAE_INVALID_PARAM;
412 return -1;
413 }
414
415 if (IOT_OTAS_UNINITED == h_ota->state) {
416 OTA_LOG_ERROR("handle is uninitialized");
417 h_ota->err = IOT_OTAE_INVALID_STATE;
418 return -1;
419 }
420
421 if (IOT_OTAS_FETCHING == h_ota->state) {
422 OTA_LOG_ERROR("ota is busying");
423 h_ota->err = IOT_OTAE_INVALID_STATE;
424 return -1;
425 }
426
427 msg_informed = OTA_MALLOC(MSG_REQUEST_LEN);
428 if (msg_informed == NULL) {
429 OTA_LOG_ERROR("allocate for msg_informed failed");
430 h_ota->err = IOT_OTAE_NOMEM;
431 return -1;
432 }
433
434 ret = otalib_GenInfoMsg(msg_informed, MSG_REQUEST_LEN, h_ota->id, version);
435 if (ret != 0) {
436 OTA_LOG_ERROR("generate request image message failed");
437 h_ota->err = ret;
438 ret = -1;
439 goto do_exit;
440 }
441
442 ret = osc_RequestImage(h_ota->ch_signal, msg_informed);
443 if (0 != ret) {
444 OTA_LOG_ERROR("Request image failed");
445 h_ota->err = ret;
446 ret = -1;
447 goto do_exit;
448 }
449 ret = 0;
450
451 do_exit:
452 if (NULL != msg_informed) {
453 OTA_FREE(msg_informed);
454 }
455 return ret;
456
457 #undef MSG_REQUEST_LEN
458 }
459
IOT_OTA_ReportProgress(void * handle,IOT_OTA_Progress_t progress,const char * msg)460 int IOT_OTA_ReportProgress(void *handle, IOT_OTA_Progress_t progress,
461 const char *msg)
462 {
463 #define MSG_REPORT_LEN (256)
464
465 int ret = -1;
466 char *msg_reported;
467 OTA_Struct_pt h_ota = (OTA_Struct_pt)handle;
468
469 if (NULL == handle) {
470 OTA_LOG_ERROR("handle is NULL");
471 return IOT_OTAE_INVALID_PARAM;
472 }
473
474 if (IOT_OTAS_UNINITED == h_ota->state) {
475 OTA_LOG_ERROR("handle is uninitialized");
476 h_ota->err = IOT_OTAE_INVALID_STATE;
477 return -1;
478 }
479 if (!ota_check_progress(progress)) {
480 OTA_LOG_ERROR("progress is a invalid parameter");
481 h_ota->err = IOT_OTAE_INVALID_PARAM;
482 return -1;
483 }
484
485 msg_reported = OTA_MALLOC(MSG_REPORT_LEN);
486 if (msg_reported == NULL) {
487 OTA_LOG_ERROR("allocate for msg_reported failed");
488 h_ota->err = IOT_OTAE_NOMEM;
489 return -1;
490 }
491
492 ret = otalib_GenReportMsg(msg_reported, MSG_REPORT_LEN, h_ota->id, progress,
493 msg);
494 if (0 != ret) {
495 OTA_LOG_ERROR("generate reported message failed");
496 h_ota->err = ret;
497 goto do_exit;
498 }
499
500 ret = osc_ReportProgress(h_ota->ch_signal, msg_reported);
501 if (0 != ret) {
502 OTA_LOG_ERROR("Report progress failed");
503 h_ota->err = ret;
504 goto do_exit;
505 }
506
507 ret = 0;
508
509 do_exit:
510 if (NULL != msg_reported) {
511 OTA_FREE(msg_reported);
512 }
513 return ret;
514
515 #undef MSG_REPORT_LEN
516 }
517
iotx_ota_get_config(void * handle,const char * configScope,const char * getType,const char * attributeKeys)518 int iotx_ota_get_config(void *handle, const char *configScope,
519 const char *getType, const char *attributeKeys)
520 {
521 #define MSG_REPORT_LEN (256)
522
523 int ret = -1;
524 char *msg_get;
525 char topic[OTA_MQTT_TOPIC_LEN] = { 0 };
526 OTA_Struct_pt h_ota = (OTA_Struct_pt)handle;
527 iotx_mqtt_topic_info_t topic_info;
528
529 memset(&topic_info, 0, sizeof(iotx_mqtt_topic_info_t));
530
531 if (NULL == handle) {
532 OTA_LOG_ERROR("handle is NULL");
533 return IOT_OTAE_INVALID_PARAM;
534 }
535
536 if (IOT_OTAS_UNINITED == h_ota->state) {
537 OTA_LOG_ERROR("handle is uninitialized");
538 h_ota->err = IOT_OTAE_INVALID_STATE;
539 return -1;
540 }
541
542 if (IOT_OTAS_FETCHING == h_ota->state) {
543 OTA_LOG_ERROR("ota is busying");
544 h_ota->err = IOT_OTAE_INVALID_STATE;
545 return -1;
546 }
547
548 msg_get = OTA_MALLOC(MSG_REPORT_LEN);
549 if (msg_get == NULL) {
550 OTA_LOG_ERROR("allocate for msg_reported failed");
551 h_ota->err = IOT_OTAE_NOMEM;
552 return -1;
553 }
554
555 if (0 > HAL_Snprintf(topic, OTA_MQTT_TOPIC_LEN,
556 "/sys/%s/%s/thing/config/get", h_ota->product_key,
557 h_ota->device_name)) {
558 goto do_exit;
559 };
560
561 if (0 > HAL_Snprintf(msg_get, MSG_REPORT_LEN,
562 "{\"id\" : "
563 "%d,\"version\":\"1.0\",\"params\":{\"configScope\":"
564 "\"%s\",\"getType\":\"%s\",\"attributeKeys\":\"%s\"},"
565 "\"method\":\"thing.config.get\"}",
566 h_ota->id, configScope, getType, attributeKeys)) {
567 goto do_exit;
568 };
569 OTA_LOG_INFO(msg_get);
570 topic_info.qos = IOTX_MQTT_QOS0;
571 topic_info.payload = (void *)msg_get;
572 topic_info.payload_len = strlen(msg_get);
573
574 ret = osc_RequestConfig(h_ota->ch_signal, topic, &topic_info);
575 if (ret < 0) {
576 OTA_LOG_ERROR("publish failed");
577 return IOT_OTAE_OSC_FAILED;
578 }
579
580 ret = 0;
581
582 do_exit:
583 if (NULL != msg_get) {
584 OTA_FREE(msg_get);
585 }
586 return ret;
587
588 #undef MSG_REPORT_LEN
589 }
590
591 /* check whether is downloading */
IOT_OTA_IsFetching(void * handle)592 int IOT_OTA_IsFetching(void *handle)
593 {
594 OTA_Struct_pt h_ota = (OTA_Struct_pt)handle;
595
596 if (NULL == handle) {
597 OTA_LOG_ERROR("handle is NULL");
598 return 0;
599 }
600
601 if (IOT_OTAS_UNINITED == h_ota->state) {
602 OTA_LOG_ERROR("handle is uninitialized");
603 h_ota->err = IOT_OTAE_INVALID_STATE;
604 return 0;
605 }
606
607 return (IOT_OTAS_PUSHED == h_ota->state ||
608 IOT_OTAS_FETCHING == h_ota->state);
609 }
610
611 /* check whether fetch over */
IOT_OTA_IsFetchFinish(void * handle)612 int IOT_OTA_IsFetchFinish(void *handle)
613 {
614 OTA_Struct_pt h_ota = (OTA_Struct_pt)handle;
615
616 if (NULL == handle) {
617 OTA_LOG_ERROR("handle is NULL");
618 return 0;
619 }
620
621 if (IOT_OTAS_UNINITED == h_ota->state) {
622 OTA_LOG_ERROR("handle is uninitialized");
623 h_ota->err = IOT_OTAE_INVALID_STATE;
624 return 0;
625 }
626
627 return (IOT_OTAS_FETCHED == h_ota->state);
628 }
629
IOT_OTA_FetchYield(void * handle,char * buf,uint32_t buf_len,uint32_t timeout_s)630 int IOT_OTA_FetchYield(void *handle, char *buf, uint32_t buf_len,
631 uint32_t timeout_s)
632 {
633 int ret;
634 OTA_Struct_pt h_ota = (OTA_Struct_pt)handle;
635
636 if ((NULL == handle) || (NULL == buf) || (0 == buf_len)) {
637 OTA_LOG_ERROR("invalid parameter");
638 return IOT_OTAE_INVALID_PARAM;
639 }
640
641 if (IOT_OTAS_PUSHED == h_ota->state) {
642 h_ota->state = IOT_OTAS_FETCHING;
643 } else if (IOT_OTAS_FETCHING != h_ota->state) {
644 h_ota->err = IOT_OTAE_INVALID_STATE;
645 return IOT_OTAE_INVALID_STATE;
646 }
647
648 if (h_ota->md5 == NULL) {
649 h_ota->md5 = otalib_MD5Init();
650 if (h_ota->md5 == NULL) {
651 return FAIL_RETURN;
652 }
653 }
654 if (h_ota->sha256 == NULL) {
655 h_ota->sha256 = otalib_Sha256Init();
656 if (h_ota->sha256 == NULL) {
657 return FAIL_RETURN;
658 }
659 }
660
661 if (h_ota->ch_fetch == NULL) {
662 if (h_ota->type == IOT_OTAT_FOTA) {
663 OTA_LOG_ERROR("h_ota->size_fetched: %d", h_ota->size_fetched);
664 h_ota->ch_fetch = ofc_Init(h_ota->purl, h_ota->size_fetched);
665 } else if (h_ota->type == IOT_OTAT_COTA) {
666 h_ota->ch_fetch = ofc_Init(h_ota->cota_url, h_ota->size_fetched);
667 }
668
669 if (h_ota->ch_fetch == NULL) {
670 OTA_LOG_ERROR("Re-Initialize HTTP handle failed");
671 return FAIL_RETURN;
672 }
673 }
674
675 ret = ofc_Fetch(h_ota->ch_fetch, buf, buf_len, timeout_s);
676 if (ret < 0) {
677 OTA_LOG_ERROR("OTA Internal Error: %d", ret);
678 ofc_Deinit(&h_ota->ch_fetch);
679 return ret;
680 } else if (0 == h_ota->size_fetched) {
681 otalib_MD5Deinit(h_ota->md5);
682 h_ota->md5 = otalib_MD5Init();
683 if (h_ota->md5 == NULL) {
684 OTA_LOG_ERROR("md5 init failed");
685 return -1;
686 }
687
688 otalib_Sha256Deinit(h_ota->sha256);
689 h_ota->sha256 = otalib_Sha256Init();
690 if (h_ota->sha256 == NULL) {
691 OTA_LOG_ERROR("sha256 init failed");
692 return -1;
693 }
694 /* force report status in the first */
695 IOT_OTA_ReportProgress(h_ota, IOT_OTAP_FETCH_PERCENTAGE_MIN,
696 "Enter in downloading state");
697 }
698
699 otalib_MD5Update(h_ota->md5, buf, ret);
700 otalib_Sha256Update(h_ota->sha256, buf, ret);
701 h_ota->size_last_fetched = ret;
702 h_ota->size_fetched += ret;
703
704 if (h_ota->size_fetched >= h_ota->size_file) {
705 h_ota->type = IOT_OTAT_NONE;
706 h_ota->state = IOT_OTAS_FETCHED;
707 }
708
709 return ret;
710 }
711
IOT_OTA_Ioctl(void * handle,IOT_OTA_CmdType_t type,void * buf,int buf_len)712 int IOT_OTA_Ioctl(void *handle, IOT_OTA_CmdType_t type, void *buf, int buf_len)
713 {
714 OTA_Struct_pt h_ota = (OTA_Struct_pt)handle;
715
716 if ((NULL == handle) || (NULL == buf) || (0 == buf_len)) {
717 OTA_LOG_ERROR("invalid parameter");
718 return IOT_OTAE_INVALID_PARAM;
719 }
720
721 if (h_ota->state < IOT_OTAS_PUSHED) {
722 h_ota->err = IOT_OTAE_INVALID_STATE;
723 return IOT_OTAE_INVALID_STATE;
724 }
725
726 switch (type) {
727 case IOT_OTAG_COTA_CONFIG_ID:
728 {
729 char **value = (char **)buf;
730 if (value == NULL || *value != NULL || h_ota->configId == NULL) {
731 OTA_LOG_ERROR("Invalid parameter");
732 h_ota->err = IOT_OTAE_INVALID_PARAM;
733 return -1;
734 } else {
735 *value = OTA_API_MALLOC(strlen(h_ota->configId) + 1);
736 if (*value == NULL) {
737 h_ota->err = IOT_OTAE_INVALID_PARAM;
738 return -1;
739 }
740 memset(*value, 0, strlen(h_ota->configId) + 1);
741 memcpy(*value, h_ota->configId, strlen(h_ota->configId));
742 return 0;
743 }
744 }
745 break;
746 case IOT_OTAG_COTA_CONFIG_SIZE:
747 {
748 if ((4 != buf_len) || (0 != ((unsigned long)buf & 0x3))) {
749 OTA_LOG_ERROR("Invalid parameter");
750 h_ota->err = IOT_OTAE_INVALID_PARAM;
751 return -1;
752 } else {
753 *((uint32_t *)buf) = h_ota->configSize;
754 return 0;
755 }
756 }
757 break;
758 case IOT_OTAG_COTA_SIGN:
759 {
760 char **value = (char **)buf;
761 if (value == NULL || *value != NULL || h_ota->sign == NULL) {
762 OTA_LOG_ERROR("Invalid parameter");
763 h_ota->err = IOT_OTAE_INVALID_PARAM;
764 return -1;
765 } else {
766 *value = OTA_API_MALLOC(strlen(h_ota->sign) + 1);
767 if (*value == NULL) {
768 h_ota->err = IOT_OTAE_INVALID_PARAM;
769 return -1;
770 }
771 memset(*value, 0, strlen(h_ota->sign) + 1);
772 memcpy(*value, h_ota->sign, strlen(h_ota->sign));
773 return 0;
774 }
775 }
776 break;
777 case IOT_OTAG_COTA_SIGN_METHOD:
778 {
779 char **value = (char **)buf;
780 if (value == NULL || *value != NULL || h_ota->signMethod == NULL) {
781 OTA_LOG_ERROR("Invalid parameter");
782 h_ota->err = IOT_OTAE_INVALID_PARAM;
783 return -1;
784 } else {
785 *value = OTA_API_MALLOC(strlen(h_ota->signMethod) + 1);
786 if (*value == NULL) {
787 h_ota->err = IOT_OTAE_INVALID_PARAM;
788 return -1;
789 }
790 memset(*value, 0, strlen(h_ota->signMethod) + 1);
791 memcpy(*value, h_ota->signMethod, strlen(h_ota->signMethod));
792 return 0;
793 }
794 }
795 break;
796 case IOT_OTAG_COTA_URL:
797 {
798 char **value = (char **)buf;
799 if (value == NULL || *value != NULL || h_ota->cota_url == NULL) {
800 OTA_LOG_ERROR("Invalid parameter");
801 h_ota->err = IOT_OTAE_INVALID_PARAM;
802 return -1;
803 } else {
804 *value = OTA_API_MALLOC(strlen(h_ota->cota_url) + 1);
805 if (*value == NULL) {
806 h_ota->err = IOT_OTAE_INVALID_PARAM;
807 return -1;
808 }
809 memset(*value, 0, strlen(h_ota->cota_url) + 1);
810 memcpy(*value, h_ota->cota_url, strlen(h_ota->cota_url));
811 return 0;
812 }
813 }
814 break;
815 case IOT_OTAG_COTA_GETTYPE:
816 {
817 char **value = (char **)buf;
818 if (value == NULL || *value != NULL || h_ota->getType == NULL) {
819 OTA_LOG_ERROR("Invalid parameter");
820 h_ota->err = IOT_OTAE_INVALID_PARAM;
821 return -1;
822 } else {
823 *value = OTA_API_MALLOC(strlen(h_ota->getType) + 1);
824 if (*value == NULL) {
825 h_ota->err = IOT_OTAE_INVALID_PARAM;
826 return -1;
827 }
828 memset(*value, 0, strlen(h_ota->getType) + 1);
829 memcpy(*value, h_ota->getType, strlen(h_ota->getType));
830 return 0;
831 }
832 }
833 break;
834 case IOT_OTAG_OTA_TYPE:
835 {
836 if ((4 != buf_len) || (0 != ((unsigned long)buf & 0x3))) {
837 OTA_LOG_ERROR("Invalid parameter");
838 h_ota->err = IOT_OTAE_INVALID_PARAM;
839 return -1;
840 } else {
841 *((uint32_t *)buf) = h_ota->type;
842 return 0;
843 }
844 }
845 break;
846 case IOT_OTAG_FETCHED_SIZE:
847 if ((4 != buf_len) || (0 != ((unsigned long)buf & 0x3))) {
848 OTA_LOG_ERROR("Invalid parameter");
849 h_ota->err = IOT_OTAE_INVALID_PARAM;
850 return -1;
851 } else {
852 *((uint32_t *)buf) = h_ota->size_fetched;
853 return 0;
854 }
855
856 case IOT_OTAG_FILE_SIZE:
857 if ((4 != buf_len) || (0 != ((unsigned long)buf & 0x3))) {
858 OTA_LOG_ERROR("Invalid parameter");
859 h_ota->err = IOT_OTAE_INVALID_PARAM;
860 return -1;
861 } else {
862 *((uint32_t *)buf) = h_ota->size_file;
863 return 0;
864 };
865
866 case IOT_OTAG_VERSION:
867 {
868 strncpy(buf, h_ota->version, buf_len);
869 ((char *)buf)[buf_len - 1] = '\0';
870 }
871 break;
872
873 case IOT_OTAG_MD5SUM:
874 strncpy(buf, h_ota->md5sum, buf_len);
875 ((char *)buf)[buf_len - 1] = '\0';
876 break;
877
878 case IOT_OTAG_CHECK_FIRMWARE:
879 if ((4 != buf_len) || (0 != ((unsigned long)buf & 0x3))) {
880 OTA_LOG_ERROR("Invalid parameter");
881 h_ota->err = IOT_OTAE_INVALID_PARAM;
882 return -1;
883 } else if (h_ota->state != IOT_OTAS_FETCHED) {
884 h_ota->err = IOT_OTAE_INVALID_STATE;
885 OTA_LOG_ERROR(
886 "Firmware can be checked in IOT_OTAS_FETCHED state only");
887 return -1;
888 } else {
889 char md5_str[33];
890 otalib_MD5Finalize(h_ota->md5, md5_str);
891 otalib_MD5Deinit(h_ota->md5);
892 h_ota->md5 = NULL;
893
894 OTA_LOG_DEBUG("origin=%s, now=%s", h_ota->md5sum, md5_str);
895 if (0 == strcmp(h_ota->md5sum, md5_str)) {
896 *((uint32_t *)buf) = 1;
897 } else {
898 *((uint32_t *)buf) = 0;
899 IOT_OTA_ReportProgress(h_ota, IOT_OTAP_CHECK_FALIED, NULL);
900 OTA_LOG_ERROR("image checksum compare failed");
901 }
902 return 0;
903 }
904 case IOT_OTAG_CHECK_CONFIG:
905 if ((4 != buf_len) || (0 != ((unsigned long)buf & 0x3))) {
906 OTA_LOG_ERROR("Invalid parameter");
907 h_ota->err = IOT_OTAE_INVALID_PARAM;
908 return -1;
909 } else if (h_ota->state != IOT_OTAS_FETCHED) {
910 h_ota->err = IOT_OTAE_INVALID_STATE;
911 OTA_LOG_ERROR(
912 "Config can be checked in IOT_OTAS_FETCHED state only");
913 return -1;
914 } else {
915 if (0 ==
916 strncmp(h_ota->signMethod, "Md5", strlen(h_ota->signMethod))) {
917 char md5_str[33];
918 otalib_MD5Finalize(h_ota->md5, md5_str);
919 OTA_LOG_DEBUG("origin=%s, now=%s", h_ota->sign, md5_str);
920 if (0 == strcmp(h_ota->sign, md5_str)) {
921 *((uint32_t *)buf) = 1;
922 } else {
923 *((uint32_t *)buf) = 0;
924 }
925 }
926 if (0 == strncmp(h_ota->signMethod, "Sha256",
927 strlen(h_ota->signMethod))) {
928 char sha256_str[65];
929 otalib_Sha256Finalize(h_ota->sha256, sha256_str);
930 OTA_LOG_DEBUG("origin=%s, now=%s", h_ota->sign, sha256_str);
931 if (0 == strcmp(h_ota->sign, sha256_str)) {
932 *((uint32_t *)buf) = 1;
933 } else {
934 *((uint32_t *)buf) = 0;
935 }
936 }
937 return 0;
938 }
939 case IOT_OTAG_RESET_FETCHED_SIZE:
940 {
941 h_ota->size_fetched = 0;
942 return 0;
943 }
944 case IOT_OTAG_RESET_STATE:
945 {
946 h_ota->type = IOT_OTAT_NONE;
947 h_ota->state = IOT_OTAS_INITED;
948 h_ota->size_fetched = 0;
949 return 0;
950 }
951 default:
952 OTA_LOG_ERROR("invalid cmd type");
953 h_ota->err = IOT_OTAE_INVALID_PARAM;
954 return -1;
955 }
956
957 return 0;
958 }
959
960 /* Get last error code */
IOT_OTA_GetLastError(void * handle)961 int IOT_OTA_GetLastError(void *handle)
962 {
963 OTA_Struct_pt h_ota = (OTA_Struct_pt)handle;
964
965 if (NULL == handle) {
966 OTA_LOG_ERROR("handle is NULL");
967 return IOT_OTAE_INVALID_PARAM;
968 }
969
970 return h_ota->err;
971 }
972