add S300AI

Change-Id: Ice89434e8dc7b3be506380729d716f50aa75df14
diff --git a/lynq/S300AI/ap/app/wefota/wefota_main.c b/lynq/S300AI/ap/app/wefota/wefota_main.c
new file mode 100755
index 0000000..9afd5d9
--- /dev/null
+++ b/lynq/S300AI/ap/app/wefota/wefota_main.c
@@ -0,0 +1,803 @@
+#include <stdio.h>

+#include <string.h>

+#include <stdlib.h>

+#include <unistd.h>

+#include <fcntl.h>

+#include "wefota_main.h"

+#include "wefota_socket.h"

+#include "wefota_device.h"

+

+#define RECV_WHOLE_PACK 1

+

+static FOTA_Status s_status = FOTA_STATUS_IDLE;

+static struct sockaddr_in s_server1_addr = {0};

+static struct sockaddr_in s_server2_addr = {0};

+static unsigned char s_req[WEFOTA_REQ_MAX_LEN] = {0};

+static unsigned char s_resp[WEFOTA_RESP_MAX_LEN] = {0};

+static char s_destVersion[32] = {0};

+static VerID s_verID = {0};

+static DiffPackInfo s_diffpack_info = {0};

+static unsigned int s_costTime = 0;

+static unsigned int s_pack_date_count = 0;

+static DiffPackDataReq s_diffpack_data_req = {0};

+

+const WeFOTA_MSG s_wefota_msg_table[] = {

+    {FOTA_STATUS_IDLE, 0xFF, 0, 0x00, 0}, // no use

+    {FOTA_STATUS_GET_IP_1, 0x10, 0, 0x11, 18},

+    {FOTA_STATUS_CHECK_TASK, 0xBF, 32, 0xC0, 41},

+    {FOTA_STATUS_GET_IP_2, 0x10, 0, 0x11, 18},

+    {FOTA_STATUS_GET_VER_ID, 0x04, 68, 0x05, 12},

+    {FOTA_STATUS_GET_DIFF_PACK_ID, 0x00, 12, 0x02, 35},

+    {FOTA_STATUS_GET_DIFF_PACK_DATA, 0x01, 23, 0x03, WEFOTA_RESP_DIFF_PACK_DATA_MAX_LEN},

+    {FOTA_STATUS_GET_DIFF_PACK_END, 0x30, 19, 0x33, 0},

+    {FOTA_STATUS_INSTALL_DIFF_PACK, 0xFF, 0, 0x00, 0}, // no use

+    {FOTA_STATUS_MAX, 0xFF, 0, 0x00, 0}, // no use

+};

+

+void set_fota_status(FOTA_Status status) {

+    s_status = status;

+}

+

+FOTA_Status get_fota_status(void) {

+    return s_status;

+}

+

+int wefota_header_init(WeFOTAHeader *hdr) {

+    if(NULL == hdr) {

+        return -1;

+    }

+

+    memset(hdr, 0, sizeof(WeFOTAHeader));

+    hdr->magic = WEFOTA_HEADER_MAGIC; // maybe need htonl

+    hdr->protocol = WEFOTA_HEADER_PROTOCOL;

+    get_iccid(hdr->iccid);

+    get_imei(hdr->devid + 16);

+    hdr->tid = WEFOTA_HEADER_TID;

+    

+    hdr->code = s_wefota_msg_table[s_status].req_code;

+    int count = s_wefota_msg_table[s_status].req_count;

+    hdr->count = htons(count);

+

+	printf("header:[imei:%s]\n", hdr->devid + 16);

+    return count;

+}

+

+int is_valid_resp_hdr(const WeFOTAHeader *hdr) {

+    if(NULL == hdr) {

+        return 0;

+    }

+    if(hdr->magic != WEFOTA_HEADER_MAGIC && hdr->magic != htonl(WEFOTA_HEADER_MAGIC)) {

+        return 0;

+    }

+    if(hdr->protocol != WEFOTA_HEADER_PROTOCOL) {

+        return 0;

+    }

+

+    return 1;

+}

+

+int init_wefota_server1_addr(void) {

+    char ip[16] = {0};

+    int port = 0;

+    get_wefota_server1_cfg(ip, &port);

+    return init_server_addr(&s_server1_addr, ip, port);

+}

+

+int init_wefota_server2_addr(const char *ip, int port) {

+    int ret = init_server_addr(&s_server2_addr, ip, port);

+    if(0 == ret) {

+        set_wefota_server2_cfg(ip, port);

+    }

+    return ret;

+}

+

+int recv_with_retry(int sock, struct sockaddr_in* server_addr, 

+                    unsigned char* response, size_t response_size, int max_retries) {

+    if (NULL == response || response_size < WEFOTA_HEADER_SIZE) {

+        return -1;

+    }

+    int retry_count = 0;

+    int recv_date_err = 0;

+	while (retry_count < max_retries) {

+        do {

+            recv_date_err = 0;

+            WeFOTAHeader *hdr = (WeFOTAHeader *)response;

+            int received = receive_message(sock, hdr, response_size, server_addr);

+            printf("received=%d\n", received);

+            if (received < WEFOTA_HEADER_SIZE) {

+                printf("recv header failed\n");

+                break;

+            }

+            if (0 == is_valid_resp_hdr(hdr)) {

+                printf("recv invalid header\n");

+                break;

+            }

+            printf("recv code=%d, count=%d)\n", hdr->code, hdr->count);

+            if (hdr->count + WEFOTA_HEADER_SIZE != received) {

+                printf("recv count error\n");

+                break;

+            }

+

+			if (s_status == FOTA_STATUS_GET_DIFF_PACK_DATA)

+			{

+				if (hdr->code == s_wefota_msg_table[s_status].resp_code && hdr->count == s_pack_date_count)

+				{

+					DiffPackDataResp * data = (DiffPackDataResp *)(s_resp + WEFOTA_HEADER_SIZE);

+					printf("proc_get_diff_pack_data recv [data->offset %u offset:%u][data->length %u length:%u]\n", 

+					       data->offset, s_diffpack_data_req.offset, data->length, s_diffpack_data_req.length);

+					if (data->offset == s_diffpack_data_req.offset || data->length == s_diffpack_data_req.length) {

+						return received;

+					}

+				}

+				printf("proc_get_diff_pack_data recv wrong data\n");

+				recv_date_err = 1;

+				break;

+			}

+			else

+			{

+            	if (hdr->code == s_wefota_msg_table[s_status].resp_code

+                 	&& hdr->count == s_wefota_msg_table[s_status].resp_count) { // code and count right

+                	return received;

+            	} else { // code or count wrong

+                	break;

+            	}

+			}

+        }while(0);

+

+        printf("retry (%d/%d)\n", retry_count + 1, max_retries);

+		if (recv_date_err == 0)

+		{

+        	retry_count++;

+		}

+    }

+    

+    return -1;

+}

+

+#ifdef RECV_WHOLE_PACK

+int send_with_retry(int sock, const unsigned char* msg, size_t len, struct sockaddr_in* server_addr, 

+                    unsigned char* response, size_t response_size, int max_retries) {

+    if (NULL == msg || NULL == response || 0 == len || response_size < WEFOTA_HEADER_SIZE) {

+        return -1;

+    }

+    int retry_count = 0;

+    while (retry_count < max_retries) {

+        do {

+            if (send_message(sock, msg, len, server_addr) < 0) {

+                printf("send message failed\n");

+                break;

+            }

+#if 0

+            WeFOTAHeader *hdr = (WeFOTAHeader *)response;;

+            int received = receive_message(sock, hdr, response_size, server_addr);

+            printf("received=%d\n", received);

+            if (received < WEFOTA_HEADER_SIZE) {

+                printf("recv header failed\n");

+                break;

+            }

+            if (0 == is_valid_resp_hdr(hdr)) {

+                printf("recv invalid header\n");

+                break;

+            }

+            printf("recv code=%d, count=%d)\n", hdr->code, hdr->count);

+            if (hdr->count + WEFOTA_HEADER_SIZE != received) {

+                printf("recv count error\n");

+                break;

+            }

+

+			if (s_status == FOTA_STATUS_GET_DIFF_PACK_DATA)

+			{

+				if (hdr->code == s_wefota_msg_table[s_status].resp_code && hdr->count == s_pack_date_count)

+				{

+					return received;

+				}

+				else

+				{

+					return -1;

+				}

+			}

+			else

+			{

+            	if (hdr->code == s_wefota_msg_table[s_status].resp_code

+                 	&& hdr->count == s_wefota_msg_table[s_status].resp_count) { // code and count right

+                	return received;

+            	} else { // code or count wrong

+                	return -1;

+            	}

+			}

+#endif

+			int received = recv_with_retry(sock, server_addr, response, response_size, max_retries);

+			if (received > 0)

+			{

+				return received;

+			}

+        }while(0);

+

+        printf("retry (%d/%d)\n", retry_count + 1, max_retries);

+        retry_count++;

+        sleep(WEFOTA_TIMEOUT_SEC);

+    }

+    

+    return -1;

+}

+#else

+int send_with_retry(int sock, const unsigned char* msg, size_t len, struct sockaddr_in* server_addr, 

+                    unsigned char* response, size_t response_size, int max_retries) {

+    if (NULL == msg || NULL == response || 0 == len || response_size < WEFOTA_HEADER_SIZE) {

+        return -1;

+    }

+    int retry_count = 0;

+    while (retry_count < max_retries) {

+        do {

+            if (send_message(sock, msg, len, server_addr) < 0) {

+                printf("send message failed\n");

+                break;

+            }

+

+            WeFOTAHeader *hdr = (WeFOTAHeader *)response;;

+            int received = receive_message(sock, hdr, WEFOTA_HEADER_SIZE, server_addr);

+            printf("received=%d\n", received);

+            if (received != WEFOTA_HEADER_SIZE) {

+                printf("recv header failed\n");

+                break;

+            }

+            if (0 == is_valid_resp_hdr(hdr)) {

+                printf("recv invalid header\n");

+                break;

+            }

+            printf("recv code=%d, count=%d)\n", hdr->code, hdr->count);

+            if (hdr->count + WEFOTA_HEADER_SIZE > response_size) {

+                printf("recv count > response_size\n");

+                break;

+            }

+

+            if (hdr->code == s_wefota_msg_table[s_status].resp_code

+                 && hdr->count == s_wefota_msg_table[s_status].resp_count) { // code and count right

+                if (hdr->count == 0) {

+                    return 0;

+                } else {

+                    received = receive_message(sock, response + WEFOTA_HEADER_SIZE, hdr->count, server_addr);

+                    printf("recv data len=%d\n", received);

+                    return received;

+                }

+            } else { // code or count wrong

+                if (hdr->count == 0) {

+                    return -1;

+                } else {

+                    received = receive_message(sock, response + WEFOTA_HEADER_SIZE, hdr->count, server_addr);

+                    printf("recv data len=%d, drop\n", received);

+                    return -1;

+                }

+            }

+        }while(0);

+

+        printf("retry (%d/%d)\n", retry_count + 1, max_retries);

+        retry_count++;

+        sleep(WEFOTA_TIMEOUT_SEC);

+    }

+    

+    return -1;

+}

+#endif

+

+int proc_get_ip(int sock) {

+    int ret = -1;

+    WeFOTAHeader * hdr = (WeFOTAHeader *)s_req;

+    int count = wefota_header_init(hdr);

+    printf("proc_get_ip send code=%d, count=%d)\n", hdr->code, count);

+

+    if (0 > send_with_retry(sock, hdr, WEFOTA_HEADER_SIZE + count, &s_server1_addr, s_resp, sizeof(s_resp), WEFOTA_MAX_RETRIES)) {

+        printf("comm fail\n");

+        return ret;

+    }

+

+    ServerAddr * data = (ServerAddr *)(s_resp + WEFOTA_HEADER_SIZE);

+    ret = init_wefota_server2_addr(data->ip, (int)data->port);

+    return ret;

+}

+

+int proc_get_ip_1(int sock) {

+    set_fota_status(FOTA_STATUS_GET_IP_1);

+    return proc_get_ip(sock);

+}

+

+int proc_check_task(int sock) {

+    set_fota_status(FOTA_STATUS_CHECK_TASK);

+

+    int ret = -1;

+    WeFOTAHeader * hdr = (WeFOTAHeader *)s_req;

+	printf("proc_check_task header\n");

+    int count = wefota_header_init(hdr);

+    printf("proc_check_task send code=%d, count=%d)\n", hdr->code, count);

+

+    char originVersion [32] = {0};

+    get_version(originVersion);

+    memcpy(s_req + WEFOTA_HEADER_SIZE, originVersion, sizeof(originVersion));

+	printf("proc_check_task originVersion:[%s]\n", originVersion);

+

+    if (0 > send_with_retry(sock, hdr, WEFOTA_HEADER_SIZE + count, &s_server2_addr, s_resp, sizeof(s_resp), WEFOTA_MAX_RETRIES)) {

+        printf("comm fail\n");

+        return ret;

+    }

+

+    FotaTask * data = (FotaTask *)(s_resp + WEFOTA_HEADER_SIZE);

+	printf("proc_check_task recv:[flag:%d][interval:%u][delay:%u][destVersion:%s]\n", data->flag, data->interval, data->delay, data->destVersion);

+    if (data->flag == 1) {

+        strncpy(s_destVersion, data->destVersion, sizeof(s_destVersion));

+        printf("exist fota task\n");

+        return 0;

+    } else {

+        printf("no fota task\n");

+        return ret;

+    }

+}

+

+int proc_get_ip_2(int sock) {

+    set_fota_status(FOTA_STATUS_GET_IP_2);

+    return proc_get_ip(sock);

+}

+

+int proc_get_ver_id(int sock) {

+    set_fota_status(FOTA_STATUS_GET_VER_ID);

+

+    char product_id[32] = {0};

+    int ret = -1;

+    WeFOTAHeader * hdr = (WeFOTAHeader *)s_req;

+    int count = wefota_header_init(hdr);

+    printf("proc_get_ver_id send code=%d, count=%d)\n", hdr->code, count);

+

+    Version version = {0};

+    get_version(version.orig_version);

+    strncpy(version.dest_version, s_destVersion, sizeof(version.dest_version));

+    cfg_get_item("wefota_product_id", product_id, sizeof(product_id));

+	strcpy(version.product, product_id);

+    memcpy(s_req + WEFOTA_HEADER_SIZE, &version, sizeof(version));

+

+    if (0 > send_with_retry(sock, hdr, WEFOTA_HEADER_SIZE + count, &s_server2_addr, s_resp, sizeof(s_resp), WEFOTA_MAX_RETRIES)) {

+        printf("comm fail\n");

+        return ret;

+    }

+

+    VerID * data = (VerID *)(s_resp + WEFOTA_HEADER_SIZE);

+    s_verID = *data;

+    return 0;

+}

+

+int proc_get_diff_pack_id(int sock) {

+    set_fota_status(FOTA_STATUS_GET_DIFF_PACK_ID);

+

+    int ret = -1;

+    WeFOTAHeader * hdr = (WeFOTAHeader *)s_req;

+    int count = wefota_header_init(hdr);

+    printf("proc_get_diff_pack_id send code=%d, count=%d)\n", hdr->code, count);

+

+    memcpy(s_req + WEFOTA_HEADER_SIZE, &s_verID, sizeof(s_verID));

+

+    if (0 > send_with_retry(sock, hdr, WEFOTA_HEADER_SIZE + count, &s_server2_addr, s_resp, sizeof(s_resp), WEFOTA_MAX_RETRIES)) {

+        printf("comm fail\n");

+        return ret;

+    }

+

+    DiffPackInfo * data = (DiffPackInfo *)(s_resp + WEFOTA_HEADER_SIZE);

+    s_diffpack_info = *data;

+	printf("proc_get_diff_pack_id [diffPackID:%s][MD5:%s][size:%u]\n", s_diffpack_info.diffPackID, s_diffpack_info.MD5, s_diffpack_info.size);

+    if (s_diffpack_info.size == 0) {

+        printf("diff pack size==0\n");

+        return ret;

+    }

+    return 0;

+}

+

+#if 0

+int proc_get_diff_pack_data(int sock) {

+    set_fota_status(FOTA_STATUS_GET_DIFF_PACK_DATA);

+

+    unsigned int startTime = time(NULL);

+    int ret = -1;

+	int recv_packet_retry = 0;

+    WeFOTAHeader * hdr = (WeFOTAHeader *)s_req;

+    int count = wefota_header_init(hdr);

+    printf("proc_get_diff_pack_data send code=%d, count=%d)\n", hdr->code, count);

+	system("rm -rf /cache/zte_fota");

+	system("mkdir /cache/zte_fota");

+    FILE *fp = fopen(FOTA_DOWNLOAD_FILEPATH, "wb");

+    if (NULL == fp) {

+        printf("open file failed\n");

+        return ret;

+    }

+

+    unsigned int size = s_diffpack_info.size;

+    while (size > 0) {

+        unsigned int len = size > WEFOTA_DIFF_PACK_DATA_MAX_LEN ? WEFOTA_DIFF_PACK_DATA_MAX_LEN : size;

+		s_pack_date_count = len + 39;

+        unsigned int offset = s_diffpack_info.size - size;

+        DiffPackDataReq req = {0};

+        memcpy(req.diffPackID, s_diffpack_info.diffPackID, sizeof(req.diffPackID));

+		req.length = len;

+        req.offset = offset;

+		printf("proc_get_diff_pack_data request [offset %d][req.diffPackID %s][len %d][s_pack_date_count:%d][offset %d]\n",

+				offset, req.diffPackID, len, s_pack_date_count, offset);

+        memcpy(s_req + WEFOTA_HEADER_SIZE, &req, sizeof(req));

+		s_diffpack_data_req = req;

+        if (0 > send_with_retry(sock, hdr, WEFOTA_HEADER_SIZE + count, &s_server2_addr, s_resp, sizeof(s_resp), WEFOTA_MAX_RETRIES)) {

+            printf("comm fail\n");

+            fclose(fp);

+            return ret;

+        }

+

+        DiffPackDataResp * data = (DiffPackDataResp *)(s_resp + WEFOTA_HEADER_SIZE);

+		printf("proc_get_diff_pack_data recv [data->offset %d offset:%d][data->length %d en:%d]\n", data->offset, offset, data->length, len);

+        if (data->offset != offset || data->length != len) {

+            printf("offset or len error\n");

+			if (recv_packet_retry < 3)

+			{

+				printf("offset error, retry\n");

+				recv_packet_retry++;

+				continue;

+			}

+            fclose(fp);

+            return ret;

+        }

+        fwrite(data->data, 1, len, fp);

+        size -= len;

+		recv_packet_retry = 0;

+    }

+

+    fclose(fp);

+    s_costTime = time(NULL) - startTime;

+    return 0;

+}

+#endif

+

+static void send_request(int sockfd, struct sockaddr_in *server_addr, int offset)

+{

+    char request[16];

+    snprintf(request, sizeof(request), "%d", offset);

+    sendto(sockfd, request, strlen(request), 0, (struct sockaddr *)server_addr, sizeof(*server_addr));

+}

+

+static int receive_data(int sockfd, int filefd, struct sockaddr_in *server_addr, socklen_t addr_len, int *received)

+{

+    ssize_t bytes_received;

+    struct sockaddr_in from_addr;

+    socklen_t from_len = sizeof(from_addr);

+

+    bytes_received = recvfrom(sockfd, s_resp, WEFOTA_RESP_MAX_LEN, 0, (struct sockaddr *)&from_addr, &from_len);

+    if (bytes_received < 0)

+    {

+        printf("receive_data received < 0\n");

+        perror("recvfrom failed");

+        return -1;

+    }

+

+    DiffPackDataResp * data = (DiffPackDataResp *)(s_resp + WEFOTA_HEADER_SIZE);

+    int offset = data->offset / 1024;

+

+    printf("receive_data received offset:%u\n", data->offset);

+

+    if (received[offset])

+    {

+        return 0;

+    }

+

+    usleep(10000);

+    if (lseek(filefd, offset * 1024, SEEK_SET) < 0)

+    {

+        printf("receive_data lseek error\n");

+        perror("lseek failed");

+        return -1;

+    }

+    if (write(filefd, data->data, bytes_received - WEFOTA_HEADER_SIZE - 39) < 0)

+    {

+        printf("receive_data write error\n");

+        perror("write failed");

+        return -1;

+    }

+

+    received[offset] = 1;

+    printf("write packet %d,%u\n", offset, data->offset);

+

+    return 0;

+}

+

+int proc_get_diff_pack_data(int sock)

+{

+    set_fota_status(FOTA_STATUS_GET_DIFF_PACK_DATA);

+

+    unsigned int startTime = time(NULL);

+    int ret = -1;

+    int i = 0;

+    int recv_packet_retry = 0;

+    int upgradeStatus = -1;

+    WeFOTAHeader * hdr = (WeFOTAHeader *)s_req;

+    int count = wefota_header_init(hdr);

+    printf("proc_get_diff_pack_data send code=%d, count=%d)\n", hdr->code, count);

+

+    fota_get_update_status(&upgradeStatus);

+    printf("proc_get_diff_pack_data fota_get_update_status upgradeStatus=%d\n", upgradeStatus);

+    if (upgradeStatus == 0)

+    {

+        if(fota_is_file_exist(FOTA_DOWNLOAD_FILEPATH))

+        {

+            printf("proc_get_diff_pack_data upgradeStatus=0, Continue upgrading!!\n");

+            return FOTA_NEED_CONTINUE_PREVIOUS_UPGRADE;

+        }

+    }

+	

+    system("rm -rf /cache/zte_fota");

+    system("mkdir /cache/zte_fota");

+

+    int filefd = open(FOTA_DOWNLOAD_FILEPATH, O_WRONLY | O_CREAT | O_TRUNC, 0644);

+    if (filefd < 0)

+    {

+    printf("proc_get_diff_pack_data open failed\n");

+        perror("file open failed");

+        return ret;

+    }

+

+    unsigned int size = s_diffpack_info.size;

+    int total_packets = size / 1024;

+    if (size % 1024 != 0)

+    {

+        total_packets += 1;

+    }

+    int received[total_packets];

+    fd_set read_fds;

+    int max_fd;

+    struct timeval timeout;

+    int select_result = 0;

+    int max_retry_count = 0;

+

+    memset(received, 0, sizeof(received));

+    while (size > 0)

+    {

+        unsigned int len = size > WEFOTA_DIFF_PACK_DATA_MAX_LEN ? WEFOTA_DIFF_PACK_DATA_MAX_LEN : size;

+        s_pack_date_count = len + 39;

+        unsigned int offset = s_diffpack_info.size - size;

+        DiffPackDataReq req = {0};

+        memcpy(req.diffPackID, s_diffpack_info.diffPackID, sizeof(req.diffPackID));

+        req.length = len;

+        req.offset = offset;

+        printf("proc_get_diff_pack_data send request [offset %u][req.diffPackID %s][len %u][s_pack_date_count:%u][offset %u]\n",

+                offset, req.diffPackID, len, s_pack_date_count, offset);

+        memcpy(s_req + WEFOTA_HEADER_SIZE, &req, sizeof(req));

+        s_diffpack_data_req = req;

+        send_message(sock, hdr, WEFOTA_HEADER_SIZE + count, &s_server2_addr);

+        size -= len;

+    }

+

+    while (1)

+    {

+        FD_ZERO(&read_fds);

+        FD_SET(sock, &read_fds);

+        max_fd = sock;

+        while (1)

+        {

+            timeout.tv_sec = 3;

+            timeout.tv_usec = 0;

+            select_result = select(max_fd + 1, &read_fds, NULL, NULL, &timeout);

+            if (select_result < 0)

+            {

+                printf("proc_get_diff_pack_data select failed\n");

+                perror("select failed");

+                break;

+            }

+            else if (select_result == 0)

+            {

+                printf("proc_get_diff_pack_data No data to read, or timeout\n");

+                break;

+            }

+            if (FD_ISSET(sock, &read_fds))

+            {

+                if (receive_data(sock, filefd, &s_server2_addr, sizeof(s_server2_addr), received) < 0)

+                {

+                    break;

+                }

+            }

+        }

+

+        if (max_retry_count++ > WEFOTA_MAX_RETRY_COUNT)

+        {

+            printf("proc_get_diff_pack_data reach the maximum retry count, break!!!\n");

+            break;

+        }

+

+        int all_received = 1;

+        for (i = 0; i < total_packets; i++)

+        {

+            if (!received[i])

+            {

+                all_received = 0;

+                unsigned int len = s_diffpack_info.size - i * 1024 > WEFOTA_DIFF_PACK_DATA_MAX_LEN ? WEFOTA_DIFF_PACK_DATA_MAX_LEN : s_diffpack_info.size - i * 1024;

+                s_pack_date_count = len + 39;

+                unsigned int offset = i * 1024;

+                DiffPackDataReq req = {0};

+                memcpy(req.diffPackID, s_diffpack_info.diffPackID, sizeof(req.diffPackID));

+                req.length = len;

+                req.offset = offset;

+                printf("Re request, send request [offset %u]\n", offset);

+                memcpy(s_req + WEFOTA_HEADER_SIZE, &req, sizeof(req));

+                s_diffpack_data_req = req;

+                send_message(sock, hdr, WEFOTA_HEADER_SIZE + count, &s_server2_addr);

+            }

+        }

+

+        if (all_received)

+        {

+            printf("All packets received successfully.\n");

+            break;

+        }

+    }

+

+    close(filefd);

+    s_costTime = time(NULL) - startTime;

+    return 0;

+}

+

+

+int proc_get_diff_pack_end(int sock) {

+    set_fota_status(FOTA_STATUS_GET_DIFF_PACK_END);

+

+    int ret = -1;

+    WeFOTAHeader * hdr = (WeFOTAHeader *)s_req;

+    int count = wefota_header_init(hdr);

+    printf("proc_get_diff_pack_end send code=%d, count=%d)\n", hdr->code, count);

+

+    DiffPackEnd end = {0};

+    memcpy(end.diffPackID, s_diffpack_info.diffPackID, sizeof(end.diffPackID));

+    end.costTime = s_costTime;

+    memcpy(s_req + WEFOTA_HEADER_SIZE, &end, sizeof(end));

+

+    if (0 > send_with_retry(sock, hdr, WEFOTA_HEADER_SIZE + count, &s_server2_addr, s_resp, sizeof(s_resp), WEFOTA_MAX_RETRIES)) {

+        printf("comm fail\n");

+        return ret;

+    }

+    return 0;

+}

+

+static int verify_md5(const unsigned char *expected_md5, const char *file_path)

+{

+    char command[256];

+	char expected_md5_str[33];

+	char md5sum_output[33];

+	int i = 0;

+

+    snprintf(command, sizeof(command), "md5sum \"%s\"", file_path);

+    FILE *pipe = popen(command, "r");

+    if (!pipe)

+	{

+		printf("verify_md5 pipe error\n");

+        return -1;

+    }

+

+    if (fgets(md5sum_output, sizeof(md5sum_output), pipe) == NULL)

+	{

+		printf("verify_md5 fgets error\n");

+        pclose(pipe);

+        return -1;

+    }

+

+    pclose(pipe);

+

+    for (i = 0; i < 16; ++i)

+	{

+        sprintf(expected_md5_str + i * 2, "%02x", expected_md5[i]);

+    }

+

+    if (strncmp(expected_md5_str, md5sum_output, 32) == 0)

+	{

+		printf("md5 check OK\n");

+        return 1;

+    }

+	else

+	{

+		printf("md5 check error\n");

+        return 0;

+    }

+}

+

+int proc_install_diff_pack(void)

+{

+	const char *file_path = "/cache/zte_fota/delta.package";

+	int result = 0;

+

+	printf("**********proc_install_diff_pack begin \n");

+    set_fota_status(FOTA_STATUS_INSTALL_DIFF_PACK);

+

+	result = verify_md5(s_diffpack_info.MD5, file_path);

+	if (result == 1)

+	{

+		return start_wefota_install();

+	}

+	else

+	{

+		return -1;

+	}

+	

+}

+

+int wefota_proc(void) {

+	printf("**********wefota_proc\n");

+    int ret = -1;

+    int sock = -1;

+	set_wefota_upgrade_flag_cfg("1");

+    do {

+        sock = create_udp_socket();

+        if (sock < 0) {

+			printf("**********create_udp_socket socket < 0 \n");

+            break;

+        }

+        

+        ret = init_wefota_server1_addr();

+        if (ret < 0) {

+			printf("**********init_wefota_server1_addr error \n");

+            break;

+        }

+

+        ret = proc_get_ip_1(sock);

+        if (ret < 0) {

+			printf("**********proc_get_ip_1 error \n");

+            break;

+        }

+

+        ret = proc_check_task(sock);

+        if (ret < 0) {

+			printf("**********proc_check_task error \n");

+            break;

+        }

+

+        ret = proc_get_ip_2(sock);

+        if (ret < 0) {

+			printf("**********proc_get_ip_2 error \n");

+            break;

+        }

+

+        ret = proc_get_ver_id(sock);

+        if (ret < 0) {

+			printf("**********proc_get_ver_id error \n");

+            break;

+        }

+

+        ret = proc_get_diff_pack_id(sock);

+        if (ret < 0) {

+			printf("**********proc_get_diff_pack_id error \n");

+            break;

+        }

+

+        ret = proc_get_diff_pack_data(sock);

+        if (ret < 0) {

+			printf("**********proc_get_diff_pack_data error \n");

+            break;

+        }

+        else if (ret == FOTA_NEED_CONTINUE_PREVIOUS_UPGRADE)

+        {

+            printf("**********wefota_proc,The last upgrade was not completed, continue upgrading \n");

+            close_udp_socket(sock);

+            sock = -1;

+            wefota_upgrade_without_verify();

+            break;

+        }

+

+        ret = proc_get_diff_pack_end(sock);

+

+        close_udp_socket(sock);

+        sock = -1;

+

+        ret = proc_install_diff_pack();

+    }while(0);

+

+    set_wefota_upgrade_flag_cfg("0");

+    if (sock >= 0) {

+        close_udp_socket(sock);

+    }

+    return ret;

+}

+

+int main(void) {

+	printf("**********main\n");

+    while (1) {

+        wait_fota_conditions();

+        wefota_proc();

+    }

+    return 0;

+}