blob: d04be2aab2d556c3f50192c3f6efe13c508456d3 [file] [log] [blame]
w.dengcc7a9bd2024-12-31 16:55:23 +08001#include <stdio.h>
2#include <string.h>
3#include <stdlib.h>
4#include <unistd.h>
5#include "wefota_main.h"
6#include "wefota_socket.h"
7#include "wefota_device.h"
8
9#define RECV_WHOLE_PACK 1
10
11static FOTA_Status s_status = FOTA_STATUS_IDLE;
12static struct sockaddr_in s_server1_addr = {0};
13static struct sockaddr_in s_server2_addr = {0};
14static unsigned char s_req[WEFOTA_REQ_MAX_LEN] = {0};
15static unsigned char s_resp[WEFOTA_RESP_MAX_LEN] = {0};
16static char s_destVersion[32] = {0};
17static VerID s_verID = {0};
18static DiffPackInfo s_diffpack_info = {0};
19static unsigned int s_costTime = 0;
20static unsigned int s_pack_date_count = 0;
21static DiffPackDataReq s_diffpack_data_req = {0};
22
23const WeFOTA_MSG s_wefota_msg_table[] = {
24 {FOTA_STATUS_IDLE, 0xFF, 0, 0x00, 0}, // no use
25 {FOTA_STATUS_GET_IP_1, 0x10, 0, 0x11, 18},
26 {FOTA_STATUS_CHECK_TASK, 0xBF, 32, 0xC0, 41},
27 {FOTA_STATUS_GET_IP_2, 0x10, 0, 0x11, 18},
28 {FOTA_STATUS_GET_VER_ID, 0x04, 68, 0x05, 12},
29 {FOTA_STATUS_GET_DIFF_PACK_ID, 0x00, 12, 0x02, 35},
30 {FOTA_STATUS_GET_DIFF_PACK_DATA, 0x01, 23, 0x03, WEFOTA_RESP_DIFF_PACK_DATA_MAX_LEN},
31 {FOTA_STATUS_GET_DIFF_PACK_END, 0x30, 19, 0x33, 0},
32 {FOTA_STATUS_INSTALL_DIFF_PACK, 0xFF, 0, 0x00, 0}, // no use
33 {FOTA_STATUS_MAX, 0xFF, 0, 0x00, 0}, // no use
34};
35
36void set_fota_status(FOTA_Status status) {
37 s_status = status;
38}
39
40FOTA_Status get_fota_status(void) {
41 return s_status;
42}
43
44int wefota_header_init(WeFOTAHeader *hdr) {
45 if(NULL == hdr) {
46 return -1;
47 }
48
49 memset(hdr, 0, sizeof(WeFOTAHeader));
50 hdr->magic = WEFOTA_HEADER_MAGIC; // maybe need htonl
51 hdr->protocol = WEFOTA_HEADER_PROTOCOL;
52 get_iccid(hdr->iccid);
53 get_imei(hdr->devid + 16);
54 hdr->tid = WEFOTA_HEADER_TID;
55
56 hdr->code = s_wefota_msg_table[s_status].req_code;
57 int count = s_wefota_msg_table[s_status].req_count;
58 hdr->count = htons(count);
59
60 printf("header:[imei:%s]\n", hdr->devid + 16);
61 return count;
62}
63
64int is_valid_resp_hdr(const WeFOTAHeader *hdr) {
65 if(NULL == hdr) {
66 return 0;
67 }
68 if(hdr->magic != WEFOTA_HEADER_MAGIC && hdr->magic != htonl(WEFOTA_HEADER_MAGIC)) {
69 return 0;
70 }
71 if(hdr->protocol != WEFOTA_HEADER_PROTOCOL) {
72 return 0;
73 }
74
75 return 1;
76}
77
78int init_wefota_server1_addr(void) {
79 char ip[16] = {0};
80 int port = 0;
81 get_wefota_server1_cfg(ip, &port);
82 return init_server_addr(&s_server1_addr, ip, port);
83}
84
85int init_wefota_server2_addr(const char *ip, int port) {
86 int ret = init_server_addr(&s_server2_addr, ip, port);
87 if(0 == ret) {
88 set_wefota_server2_cfg(ip, port);
89 }
90 return ret;
91}
92
93int recv_with_retry(int sock, struct sockaddr_in* server_addr,
94 unsigned char* response, size_t response_size, int max_retries) {
95 if (NULL == response || response_size < WEFOTA_HEADER_SIZE) {
96 return -1;
97 }
98 int retry_count = 0;
99 int recv_date_err = 0;
100 while (retry_count < max_retries) {
101 do {
102 recv_date_err = 0;
103 WeFOTAHeader *hdr = (WeFOTAHeader *)response;
104 int received = receive_message(sock, hdr, response_size, server_addr);
105 printf("received=%d\n", received);
106 if (received < WEFOTA_HEADER_SIZE) {
107 printf("recv header failed\n");
108 break;
109 }
110 if (0 == is_valid_resp_hdr(hdr)) {
111 printf("recv invalid header\n");
112 break;
113 }
114 printf("recv code=%d, count=%d)\n", hdr->code, hdr->count);
115 if (hdr->count + WEFOTA_HEADER_SIZE != received) {
116 printf("recv count error\n");
117 break;
118 }
119
120 if (s_status == FOTA_STATUS_GET_DIFF_PACK_DATA)
121 {
122 if (hdr->code == s_wefota_msg_table[s_status].resp_code && hdr->count == s_pack_date_count)
123 {
124 DiffPackDataResp * data = (DiffPackDataResp *)(s_resp + WEFOTA_HEADER_SIZE);
125 printf("proc_get_diff_pack_data recv [data->offset %d offset:%d][data->length %d length:%d]\n",
126 data->offset, s_diffpack_data_req.offset, data->length, s_diffpack_data_req.length);
127 if (data->offset == s_diffpack_data_req.offset || data->length == s_diffpack_data_req.length) {
128 return received;
129 }
130 }
131 printf("proc_get_diff_pack_data recv wrong data\n");
132 recv_date_err = 1;
133 break;
134 }
135 else
136 {
137 if (hdr->code == s_wefota_msg_table[s_status].resp_code
138 && hdr->count == s_wefota_msg_table[s_status].resp_count) { // code and count right
139 return received;
140 } else { // code or count wrong
141 break;
142 }
143 }
144 }while(0);
145
146 printf("retry (%d/%d)\n", retry_count + 1, max_retries);
147 if (recv_date_err == 0)
148 {
149 retry_count++;
150 }
151 }
152
153 return -1;
154}
155
156#ifdef RECV_WHOLE_PACK
157int send_with_retry(int sock, const unsigned char* msg, size_t len, struct sockaddr_in* server_addr,
158 unsigned char* response, size_t response_size, int max_retries) {
159 if (NULL == msg || NULL == response || 0 == len || response_size < WEFOTA_HEADER_SIZE) {
160 return -1;
161 }
162 int retry_count = 0;
163 while (retry_count < max_retries) {
164 do {
165 if (send_message(sock, msg, len, server_addr) < 0) {
166 printf("send message failed\n");
167 break;
168 }
169#if 0
170 WeFOTAHeader *hdr = (WeFOTAHeader *)response;;
171 int received = receive_message(sock, hdr, response_size, server_addr);
172 printf("received=%d\n", received);
173 if (received < WEFOTA_HEADER_SIZE) {
174 printf("recv header failed\n");
175 break;
176 }
177 if (0 == is_valid_resp_hdr(hdr)) {
178 printf("recv invalid header\n");
179 break;
180 }
181 printf("recv code=%d, count=%d)\n", hdr->code, hdr->count);
182 if (hdr->count + WEFOTA_HEADER_SIZE != received) {
183 printf("recv count error\n");
184 break;
185 }
186
187 if (s_status == FOTA_STATUS_GET_DIFF_PACK_DATA)
188 {
189 if (hdr->code == s_wefota_msg_table[s_status].resp_code && hdr->count == s_pack_date_count)
190 {
191 return received;
192 }
193 else
194 {
195 return -1;
196 }
197 }
198 else
199 {
200 if (hdr->code == s_wefota_msg_table[s_status].resp_code
201 && hdr->count == s_wefota_msg_table[s_status].resp_count) { // code and count right
202 return received;
203 } else { // code or count wrong
204 return -1;
205 }
206 }
207#endif
208 int received = recv_with_retry(sock, server_addr, response, response_size, max_retries);
209 if (received > 0)
210 {
211 return received;
212 }
213 }while(0);
214
215 printf("retry (%d/%d)\n", retry_count + 1, max_retries);
216 retry_count++;
217 sleep(WEFOTA_TIMEOUT_SEC);
218 }
219
220 return -1;
221}
222#else
223int send_with_retry(int sock, const unsigned char* msg, size_t len, struct sockaddr_in* server_addr,
224 unsigned char* response, size_t response_size, int max_retries) {
225 if (NULL == msg || NULL == response || 0 == len || response_size < WEFOTA_HEADER_SIZE) {
226 return -1;
227 }
228 int retry_count = 0;
229 while (retry_count < max_retries) {
230 do {
231 if (send_message(sock, msg, len, server_addr) < 0) {
232 printf("send message failed\n");
233 break;
234 }
235
236 WeFOTAHeader *hdr = (WeFOTAHeader *)response;;
237 int received = receive_message(sock, hdr, WEFOTA_HEADER_SIZE, server_addr);
238 printf("received=%d\n", received);
239 if (received != WEFOTA_HEADER_SIZE) {
240 printf("recv header failed\n");
241 break;
242 }
243 if (0 == is_valid_resp_hdr(hdr)) {
244 printf("recv invalid header\n");
245 break;
246 }
247 printf("recv code=%d, count=%d)\n", hdr->code, hdr->count);
248 if (hdr->count + WEFOTA_HEADER_SIZE > response_size) {
249 printf("recv count > response_size\n");
250 break;
251 }
252
253 if (hdr->code == s_wefota_msg_table[s_status].resp_code
254 && hdr->count == s_wefota_msg_table[s_status].resp_count) { // code and count right
255 if (hdr->count == 0) {
256 return 0;
257 } else {
258 received = receive_message(sock, response + WEFOTA_HEADER_SIZE, hdr->count, server_addr);
259 printf("recv data len=%d\n", received);
260 return received;
261 }
262 } else { // code or count wrong
263 if (hdr->count == 0) {
264 return -1;
265 } else {
266 received = receive_message(sock, response + WEFOTA_HEADER_SIZE, hdr->count, server_addr);
267 printf("recv data len=%d, drop\n", received);
268 return -1;
269 }
270 }
271 }while(0);
272
273 printf("retry (%d/%d)\n", retry_count + 1, max_retries);
274 retry_count++;
275 sleep(WEFOTA_TIMEOUT_SEC);
276 }
277
278 return -1;
279}
280#endif
281
282int proc_get_ip(int sock) {
283 int ret = -1;
284 WeFOTAHeader * hdr = (WeFOTAHeader *)s_req;
285 int count = wefota_header_init(hdr);
286 printf("proc_get_ip send code=%d, count=%d)\n", hdr->code, count);
287
288 if (0 > send_with_retry(sock, hdr, WEFOTA_HEADER_SIZE + count, &s_server1_addr, s_resp, sizeof(s_resp), WEFOTA_MAX_RETRIES)) {
289 printf("comm fail\n");
290 return ret;
291 }
292
293 ServerAddr * data = (ServerAddr *)(s_resp + WEFOTA_HEADER_SIZE);
294 ret = init_wefota_server2_addr(data->ip, (int)data->port);
295 return ret;
296}
297
298int proc_get_ip_1(int sock) {
299 set_fota_status(FOTA_STATUS_GET_IP_1);
300 return proc_get_ip(sock);
301}
302
303int proc_check_task(int sock) {
304 set_fota_status(FOTA_STATUS_CHECK_TASK);
305
306 int ret = -1;
307 WeFOTAHeader * hdr = (WeFOTAHeader *)s_req;
308 printf("proc_check_task header\n");
309 int count = wefota_header_init(hdr);
310 printf("proc_check_task send code=%d, count=%d)\n", hdr->code, count);
311
312 char originVersion [32] = {0};
313 get_version(originVersion);
314 memcpy(s_req + WEFOTA_HEADER_SIZE, originVersion, sizeof(originVersion));
315 printf("proc_check_task originVersion:[%s]\n", originVersion);
316
317 if (0 > send_with_retry(sock, hdr, WEFOTA_HEADER_SIZE + count, &s_server2_addr, s_resp, sizeof(s_resp), WEFOTA_MAX_RETRIES)) {
318 printf("comm fail\n");
319 return ret;
320 }
321
322 FotaTask * data = (FotaTask *)(s_resp + WEFOTA_HEADER_SIZE);
323 printf("proc_check_task recv:[flag:%d][interval:%d][delay:%d][destVersion:%s]\n", data->flag, data->interval, data->delay, data->destVersion);
324 if (data->flag == 1) {
325 strncpy(s_destVersion, data->destVersion, sizeof(s_destVersion));
326 printf("exist fota task\n");
327 return 0;
328 } else {
329 printf("no fota task\n");
330 return ret;
331 }
332}
333
334int proc_get_ip_2(int sock) {
335 set_fota_status(FOTA_STATUS_GET_IP_2);
336 return proc_get_ip(sock);
337}
338
339int proc_get_ver_id(int sock) {
340 set_fota_status(FOTA_STATUS_GET_VER_ID);
341
342 char product_id[32] = {0};
343 int ret = -1;
344 WeFOTAHeader * hdr = (WeFOTAHeader *)s_req;
345 int count = wefota_header_init(hdr);
346 printf("proc_get_ver_id send code=%d, count=%d)\n", hdr->code, count);
347
348 Version version = {0};
349 get_version(version.orig_version);
350 strncpy(version.dest_version, s_destVersion, sizeof(version.dest_version));
351 cfg_get_item("wefota_product_id", product_id, sizeof(product_id));
352 strcpy(version.product, product_id);
353 memcpy(s_req + WEFOTA_HEADER_SIZE, &version, sizeof(version));
354
355 if (0 > send_with_retry(sock, hdr, WEFOTA_HEADER_SIZE + count, &s_server2_addr, s_resp, sizeof(s_resp), WEFOTA_MAX_RETRIES)) {
356 printf("comm fail\n");
357 return ret;
358 }
359
360 VerID * data = (VerID *)(s_resp + WEFOTA_HEADER_SIZE);
361 s_verID = *data;
362 return 0;
363}
364
365int proc_get_diff_pack_id(int sock) {
366 set_fota_status(FOTA_STATUS_GET_DIFF_PACK_ID);
367
368 int ret = -1;
369 WeFOTAHeader * hdr = (WeFOTAHeader *)s_req;
370 int count = wefota_header_init(hdr);
371 printf("proc_get_diff_pack_id send code=%d, count=%d)\n", hdr->code, count);
372
373 memcpy(s_req + WEFOTA_HEADER_SIZE, &s_verID, sizeof(s_verID));
374
375 if (0 > send_with_retry(sock, hdr, WEFOTA_HEADER_SIZE + count, &s_server2_addr, s_resp, sizeof(s_resp), WEFOTA_MAX_RETRIES)) {
376 printf("comm fail\n");
377 return ret;
378 }
379
380 DiffPackInfo * data = (DiffPackInfo *)(s_resp + WEFOTA_HEADER_SIZE);
381 s_diffpack_info = *data;
382 printf("proc_get_diff_pack_id [diffPackID:%s][MD5:%s][size:%d]\n", s_diffpack_info.diffPackID, s_diffpack_info.MD5, s_diffpack_info.size);
383 if (s_diffpack_info.size == 0) {
384 printf("diff pack size==0\n");
385 return ret;
386 }
387 return 0;
388}
389
390int proc_get_diff_pack_data(int sock) {
391 set_fota_status(FOTA_STATUS_GET_DIFF_PACK_DATA);
392
393 unsigned int startTime = time(NULL);
394 int ret = -1;
395 int recv_packet_retry = 0;
396 WeFOTAHeader * hdr = (WeFOTAHeader *)s_req;
397 int count = wefota_header_init(hdr);
398 printf("proc_get_diff_pack_data send code=%d, count=%d)\n", hdr->code, count);
399 system("rm -rf /cache/zte_fota");
400 system("mkdir /cache/zte_fota");
401 FILE *fp = fopen(FOTA_DOWNLOAD_FILEPATH, "wb");
402 if (NULL == fp) {
403 printf("open file failed\n");
404 return ret;
405 }
406
407 unsigned int size = s_diffpack_info.size;
408 while (size > 0) {
409 unsigned int len = size > WEFOTA_DIFF_PACK_DATA_MAX_LEN ? WEFOTA_DIFF_PACK_DATA_MAX_LEN : size;
410 s_pack_date_count = len + 39;
411 unsigned int offset = s_diffpack_info.size - size;
412 DiffPackDataReq req = {0};
413 memcpy(req.diffPackID, s_diffpack_info.diffPackID, sizeof(req.diffPackID));
414 req.length = len;
415 req.offset = offset;
416 printf("proc_get_diff_pack_data request [offset %d][req.diffPackID %s][len %d][s_pack_date_count:%d][offset %d]\n",
417 offset, req.diffPackID, len, s_pack_date_count, offset);
418 memcpy(s_req + WEFOTA_HEADER_SIZE, &req, sizeof(req));
419 s_diffpack_data_req = req;
420 if (0 > send_with_retry(sock, hdr, WEFOTA_HEADER_SIZE + count, &s_server2_addr, s_resp, sizeof(s_resp), WEFOTA_MAX_RETRIES)) {
421 printf("comm fail\n");
422 fclose(fp);
423 return ret;
424 }
425
426 DiffPackDataResp * data = (DiffPackDataResp *)(s_resp + WEFOTA_HEADER_SIZE);
427 printf("proc_get_diff_pack_data recv [data->offset %d offset:%d][data->length %d en:%d]\n", data->offset, offset, data->length, len);
428 if (data->offset != offset || data->length != len) {
429 printf("offset or len error\n");
430 if (recv_packet_retry < 3)
431 {
432 printf("offset error, retry\n");
433 recv_packet_retry++;
434 continue;
435 }
436 fclose(fp);
437 return ret;
438 }
439 fwrite(data->data, 1, len, fp);
440 size -= len;
441 recv_packet_retry = 0;
442 }
443
444 fclose(fp);
445 s_costTime = time(NULL) - startTime;
446 return 0;
447}
448
449int proc_get_diff_pack_end(int sock) {
450 set_fota_status(FOTA_STATUS_GET_DIFF_PACK_END);
451
452 int ret = -1;
453 WeFOTAHeader * hdr = (WeFOTAHeader *)s_req;
454 int count = wefota_header_init(hdr);
455 printf("proc_get_diff_pack_end send code=%d, count=%d)\n", hdr->code, count);
456
457 DiffPackEnd end = {0};
458 memcpy(end.diffPackID, s_diffpack_info.diffPackID, sizeof(end.diffPackID));
459 end.costTime = s_costTime;
460 memcpy(s_req + WEFOTA_HEADER_SIZE, &end, sizeof(end));
461
462 if (0 > send_with_retry(sock, hdr, WEFOTA_HEADER_SIZE + count, &s_server2_addr, s_resp, sizeof(s_resp), WEFOTA_MAX_RETRIES)) {
463 printf("comm fail\n");
464 return ret;
465 }
466 return 0;
467}
468
469static int verify_md5(const unsigned char *expected_md5, const char *file_path)
470{
471 char command[256];
472 char expected_md5_str[33];
473 char md5sum_output[33];
474 int i = 0;
475
476 snprintf(command, sizeof(command), "md5sum \"%s\"", file_path);
477 FILE *pipe = popen(command, "r");
478 if (!pipe)
479 {
480 printf("verify_md5 pipe error\n");
481 return -1;
482 }
483
484 if (fgets(md5sum_output, sizeof(md5sum_output), pipe) == NULL)
485 {
486 printf("verify_md5 fgets error\n");
487 pclose(pipe);
488 return -1;
489 }
490
491 pclose(pipe);
492
493 for (i = 0; i < 16; ++i)
494 {
495 sprintf(expected_md5_str + i * 2, "%02x", expected_md5[i]);
496 }
497
498 if (strncmp(expected_md5_str, md5sum_output, 32) == 0)
499 {
500 printf("md5 check OK\n");
501 return 1;
502 }
503 else
504 {
505 printf("md5 check error\n");
506 return 0;
507 }
508}
509
510int proc_install_diff_pack(void)
511{
512 const char *file_path = "/cache/zte_fota/delta.package";
513 int result = 0;
514
515 printf("**********proc_install_diff_pack begin \n");
516 set_fota_status(FOTA_STATUS_INSTALL_DIFF_PACK);
517
518 result = verify_md5(s_diffpack_info.MD5, file_path);
519 if (result == 1)
520 {
521 return start_wefota_install();
522 }
523 else
524 {
525 return -1;
526 }
527
528}
529
530int wefota_proc(void) {
531 printf("**********wefota_proc\n");
532 int ret = -1;
533 int sock = -1;
534 do {
535 sock = create_udp_socket();
536 if (sock < 0) {
537 printf("**********create_udp_socket socket < 0 \n");
538 break;
539 }
540
541 ret = init_wefota_server1_addr();
542 if (ret < 0) {
543 printf("**********init_wefota_server1_addr error \n");
544 break;
545 }
546
547 ret = proc_get_ip_1(sock);
548 if (ret < 0) {
549 printf("**********proc_get_ip_1 error \n");
550 break;
551 }
552
553 ret = proc_check_task(sock);
554 if (ret < 0) {
555 printf("**********proc_check_task error \n");
556 break;
557 }
558
559 ret = proc_get_ip_2(sock);
560 if (ret < 0) {
561 printf("**********proc_get_ip_2 error \n");
562 break;
563 }
564
565 ret = proc_get_ver_id(sock);
566 if (ret < 0) {
567 printf("**********proc_get_ver_id error \n");
568 break;
569 }
570
571 ret = proc_get_diff_pack_id(sock);
572 if (ret < 0) {
573 printf("**********proc_get_diff_pack_id error \n");
574 break;
575 }
576
577 ret = proc_get_diff_pack_data(sock);
578 if (ret < 0) {
579 printf("**********proc_get_diff_pack_data error \n");
580 break;
581 }
582
583 ret = proc_get_diff_pack_end(sock);
584
585 close_udp_socket(sock);
586 sock = -1;
587
588 ret = proc_install_diff_pack();
589 }while(0);
590
591 if (sock >= 0) {
592 close_udp_socket(sock);
593 }
594 return ret;
595}
596
597int main(void) {
598 printf("**********main\n");
599 while (1) {
600 wait_fota_conditions();
601 wefota_proc();
602 }
603 return 0;
604}