[Feature][S300][task-view-902][project] add s300 common project

Change-Id: I5e0ce7e50fb0b968befef03ad42bae55f43287d6
diff --git a/lynq/S300_COMMON/ap/app/wefota/Makefile b/lynq/S300_COMMON/ap/app/wefota/Makefile
new file mode 100755
index 0000000..c6f70a4
--- /dev/null
+++ b/lynq/S300_COMMON/ap/app/wefota/Makefile
@@ -0,0 +1,60 @@
+#*******************************************************************************

+# include ZTE application makefile

+#*******************************************************************************

+include $(zte_app_mak)

+include $(COMMON_MK)

+

+CPU_PUB_ROOT=$(TOPDIR_AP)/../pub

+##############USER COMIZE BEGIN################

+EXEC = wefota

+OBJS = wefota_main.o wefota_device.o wefota_socket.o

+

+

+#*******************************************************************************

+# include path

+#*******************************************************************************

+CFLAGS += -I./

+CFLAGS += -I../include

+CFLAGS += -I../zte_comm/nvserver

+CFLAGS += -I$(LIB_DIR)/libnvram

+CFLAGS += -I$(APP_DIR)/include                                                   

+CFLAGS += -g -Werror=implicit-function-declaration 

+

+CFLAGS += -I$(zte_app_path)/include

+CFLAGS += -I$(zte_lib_path)/libnvram

+CFLAGS += -I$(LINUX_DIR)

+CFLAGS += -I$(CPU_PUB_ROOT)/project/zx297520v3/include/nv

+CFLAGS += -O -Dlinux=1 -DHIGH_SPEED=1

+

+CFLAGS += -I$(zte_lib_path)/libsoftap

+CFLAGS += -I$(zte_lib_path)/libsoft_timer

+

+

+#*******************************************************************************

+# library

+#*******************************************************************************

+LDLIBS += -lnvram -L$(zte_lib_path)/libnvram -lpthread

+ifeq ($(LINUX_TYPE),uClinux)

+LDFLAGS += -Wl,--allow-multiple-definition,-elf2flt=-s131072

+endif

+

+

+LDLIBS  += -lsoftap -L$(zte_lib_path)/libsoftap

+LDLIBS  += -lsoft_timer -L$(zte_lib_path)/libsoft_timer

+

+##############USER COMIZE END##################

+

+all: $(EXEC)

+

+$(EXEC): $(OBJS) 

+	$(CC) $(LDFLAGS) -o $@ $(OBJS)  -Wl,--start-group $(LDLIBS) -Wl,--end-group

+	@cp $@ $@.elf

+

+

+romfs:

+	$(ROMFSINST)  /sbin/$(EXEC)

+

+clean:

+	-rm -f $(EXEC) *.elf *.gdb *.o

+

+

diff --git a/lynq/S300_COMMON/ap/app/wefota/wefota_device.c b/lynq/S300_COMMON/ap/app/wefota/wefota_device.c
new file mode 100755
index 0000000..b294271
--- /dev/null
+++ b/lynq/S300_COMMON/ap/app/wefota/wefota_device.c
@@ -0,0 +1,242 @@
+#include <stdio.h>

+#include <string.h>

+#include <stdlib.h>

+#include <time.h>

+#include <unistd.h>

+#include <fcntl.h>

+#include "wefota_device.h"

+

+static int g_first_check_tesk = 0;

+

+int get_iccid(char *iccid)

+{

+    if (iccid == NULL) {

+        return -1;

+    }

+    char buf[32] = {0}  ;

+    cfg_get_item("sim_iccid", buf, sizeof(buf));

+    strcpy(iccid, buf);

+    return 0;

+}

+

+int get_imei(char *imei)

+{

+    if (imei == NULL) {

+        return -1;

+    }

+    char buf[32] = {0};

+    cfg_get_item("imei", buf, sizeof(buf));

+    strcpy(imei, buf);

+    return 0;

+}

+

+int get_version(char *version)

+{

+    if (version == NULL) {

+        return -1;

+    }

+    char buf[30] = {0};

+    cfg_get_item("wa_version", buf, sizeof(buf));

+    strcpy(version, buf);

+    return 0;

+}

+

+int is_data_connected(void)

+{

+    char buf[32] = {0};

+    cfg_get_item("ppp_status", buf, sizeof(buf));

+    if (strcmp(buf, "ppp_connected") == 0) {

+        return 1;

+    }

+    return 0;

+}

+

+int get_wefota_server1_cfg(char *ip, int *port)

+{

+    if (ip == NULL || port == NULL) {

+        return -1;

+    }

+    char buf[32] = {0};

+    cfg_get_item("wefota_server1_ip", buf, sizeof(buf));

+    strcpy(ip, buf);

+    cfg_get_item("wefota_server1_port", buf, sizeof(buf));

+    *port = atoi(buf);

+    return 0;

+}

+

+int set_wefota_server2_cfg(const char *ip, int port)

+{

+    if (ip == NULL) {

+        return -1;

+    }

+    cfg_set("wefota_server2_ip", ip);

+    char buf[32] = {0}; 

+    sprintf(buf, "%d", port);

+    cfg_set("wefota_server2_port", buf);

+    return 0;

+}

+

+int get_last_work_time(int *time, int *interval)

+{

+    if (time == NULL || interval == NULL) {

+        return -1;

+    }

+    char buf[32] = {0};

+    cfg_get_item("wefota_last_work_time", buf, sizeof(buf));

+    *time = atoi(buf);

+    cfg_get_item("wefota_last_work_interval", buf, sizeof(buf));

+    *interval = atoi(buf);

+    return 0;

+}

+

+int set_last_work_time(int time, int interval)

+{

+    char buf[32] = {0};

+    sprintf(buf, "%d", time);

+    cfg_set("wefota_last_work_time", buf);

+    sprintf(buf, "%d", interval);

+    cfg_set("wefota_last_work_interval", buf);

+    return 0;

+}

+

+static int fota_is_file_exist(const char* path)

+{

+	if ( (path == NULL) || (*path == '\0') )

+		return 0;

+	if (access(path, R_OK) != 0)

+		return 0;

+

+	return 1;

+}

+

+static int fota_read_file(const char*path, char*buf, size_t sz)

+{

+	int fd = -1;

+	size_t cnt;

+

+	fd = open(path, O_RDONLY, 0);

+	if(fd < 0)

+	{

+		printf("fota_read_file failed to open %s\n", path);

+		cnt = -1;

+		return cnt;

+	}

+	cnt = read(fd, buf, sz - 1);

+	if(cnt <= 0)

+	{

+		printf("failed to read %s\n", path);

+		close(fd);

+		cnt = -1;

+		return cnt;

+	}

+	buf[cnt] = '\0';

+	if(buf[cnt - 1] == '\n')

+	{

+		cnt--;

+		buf[cnt] = '\0';

+	}

+	close(fd);

+

+	return cnt;

+}

+

+static int fota_read_file_int(const char* path, int *val)

+{

+	char buf[32];

+	char *end;

+	int ret;

+	int tmp;

+

+	ret = fota_read_file(path, buf, sizeof(buf));

+	if(ret < 0)

+		return -1;

+

+	tmp = strtol(buf, &end, 0);

+	if ((end == buf) || ((end < buf + sizeof(buf)) && (*end != '\0')))

+	{

+		return -1;

+	}

+

+	*val = tmp;

+

+	return 0;

+}

+

+static int fota_get_update_status(int *fota_status)

+{

+

+	int status = 0;

+	int ret = 0;

+	if(!fota_is_file_exist(FOTA_UPDATE_STATUS_FILE))

+	{

+		*fota_status = -1;

+		return -1;

+	}

+	ret = fota_read_file_int(FOTA_UPDATE_STATUS_FILE, &status);

+	if(ret < 0) {

+		*fota_status = -1;

+		return -1;

+	}

+	*fota_status = status;

+	return 0;

+}

+

+int start_wefota_install(void)

+{

+	int upgradeStatus = 0;

+	int result = 0;

+	

+	system("fota_upi -u verify");

+	result = fota_get_update_status(&upgradeStatus);

+	if(result < 0)

+	{

+		printf("failed to read the update_status file\n");

+		return -1;

+	}

+	else if(upgradeStatus != 0)

+	{

+		printf("verify failed\n");

+		return -1;

+	}

+	else

+	{

+		printf("verify success, start upgrade!\n");

+		system("fota_upi -u recovery");

+	}

+

+    return 0;

+}

+

+int wait_fota_conditions(void)

+{

+    // wait for data connected

+    while (1) {

+        if (is_data_connected()) {

+            break;

+        }

+        sleep(10);

+    }

+

+    // wait for sntp time sync

+    sleep(10);

+    srand(time(NULL));

+

+    // wait for fota time

+    while (1) {

+        int last_time = 0;

+        int interval = 0;

+        get_last_work_time(&last_time, &interval);

+        int cur_time = time(NULL);

+        if ((last_time + interval < cur_time) || g_first_check_tesk == 0) {

+            break;

+        }

+        sleep(10);

+    }

+

+    g_first_check_tesk = 1;

+    //set last work time

+    int interval = FOTA_INTERVAL_MIN + rand() % FOTA_INTERVAL_RANDOM;

+    set_last_work_time(time(NULL), interval);

+    

+    return 0;

+}

diff --git a/lynq/S300_COMMON/ap/app/wefota/wefota_device.h b/lynq/S300_COMMON/ap/app/wefota/wefota_device.h
new file mode 100755
index 0000000..d374db0
--- /dev/null
+++ b/lynq/S300_COMMON/ap/app/wefota/wefota_device.h
@@ -0,0 +1,22 @@
+#ifndef _WEFOTA_DEVICE_H_

+#define _WEFOTA_DEVICE_H_

+

+#include "cfg_api.h"

+

+#define FOTA_INTERVAL_MIN (3600 * 24)

+#define FOTA_INTERVAL_RANDOM (3600 * 2)

+#define FOTA_DOWNLOAD_FILEPATH "/cache/zte_fota/delta.package"

+#define FOTA_UPDATE_STATUS_FILE "/cache/zte_fota/update_status"

+

+int get_iccid(char *iccid);

+int get_imei(char *imei);

+int get_version(char *version);

+int is_data_connected(void);

+int get_wefota_server1_cfg(char *ip, int *port);

+int set_wefota_server2_cfg(const char *ip, int port);

+int get_last_work_time(int *time, int *interval);

+int set_last_work_time(int time, int interval);

+int start_wefota_install(void);

+int wait_fota_conditions(void);

+

+#endif
\ No newline at end of file
diff --git a/lynq/S300_COMMON/ap/app/wefota/wefota_main.c b/lynq/S300_COMMON/ap/app/wefota/wefota_main.c
new file mode 100755
index 0000000..14ee87c
--- /dev/null
+++ b/lynq/S300_COMMON/ap/app/wefota/wefota_main.c
@@ -0,0 +1,602 @@
+#include <stdio.h>

+#include <string.h>

+#include <stdlib.h>

+#include <unistd.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 %d offset:%d][data->length %d length:%d]\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:%d][delay:%d][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);

+

+    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));

+	strcpy(version.product, WEFOTA_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:%d]\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;

+}

+

+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;

+}

+

+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;

+    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;

+        }

+

+        ret = proc_get_diff_pack_end(sock);

+

+        close_udp_socket(sock);

+        sock = -1;

+

+        ret = proc_install_diff_pack();

+    }while(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;

+}

diff --git a/lynq/S300_COMMON/ap/app/wefota/wefota_main.h b/lynq/S300_COMMON/ap/app/wefota/wefota_main.h
new file mode 100755
index 0000000..4bca0d3
--- /dev/null
+++ b/lynq/S300_COMMON/ap/app/wefota/wefota_main.h
@@ -0,0 +1,112 @@
+#ifndef _WEFOTA_MAIN_H_

+#define _WEFOTA_MAIN_H_

+

+#define WEFOTA_HEADER_MAGIC 0x41544F46

+#define WEFOTA_HEADER_PROTOCOL 0x80

+#define WEFOTA_HEADER_TID 0x0A

+

+#define WEFOTA_HEADER_SIZE 107

+#define WEFOTA_REQ_MAX_LEN (WEFOTA_HEADER_SIZE + 68)

+

+#define WEFOTA_DIFF_PACK_DATA_MAX_LEN 1024

+#define WEFOTA_RESP_DIFF_PACK_DATA_MAX_LEN (WEFOTA_DIFF_PACK_DATA_MAX_LEN + 39)

+#define WEFOTA_RESP_MAX_LEN (WEFOTA_HEADER_SIZE + WEFOTA_RESP_DIFF_PACK_DATA_MAX_LEN)

+

+#define WEFOTA_MAX_RETRIES 3

+#define WEFOTA_TIMEOUT_SEC 1

+

+#define WEFOTA_PRODUCT_ID "10300"

+

+

+typedef enum _FOTA_Status{

+    FOTA_STATUS_IDLE = 0,

+    FOTA_STATUS_GET_IP_1,

+    FOTA_STATUS_CHECK_TASK,

+    FOTA_STATUS_GET_IP_2,

+    FOTA_STATUS_GET_VER_ID,

+    FOTA_STATUS_GET_DIFF_PACK_ID,

+    FOTA_STATUS_GET_DIFF_PACK_DATA,

+    FOTA_STATUS_GET_DIFF_PACK_END,

+    FOTA_STATUS_INSTALL_DIFF_PACK,

+    FOTA_STATUS_MAX

+} FOTA_Status;

+

+typedef struct _WeFOTA_MSG{

+    FOTA_Status status;

+    unsigned char req_code;

+    unsigned short req_count;

+    unsigned char resp_code;

+    unsigned short resp_count;

+} WeFOTA_MSG;

+

+#pragma pack(1)

+typedef struct _WeFOTAHeader{

+    unsigned int magic;        // 4 bytes

+    unsigned char protocol;      // 1 byte

+    unsigned char code;          // 1 byte

+    unsigned char cgi[9];        // 9 bytes

+    unsigned char imsi[15];      // 15 bytes

+    unsigned char iccid[20];     // 20 bytes

+    unsigned char devid[32];     // 32 bytes,16 meid and 16 imei

+    unsigned char gps[20];       // 20 bytes

+    unsigned char sig;           // 1 byte

+    unsigned short tid;          // 2 bytes

+    unsigned short count;        // 2 bytes

+} WeFOTAHeader;

+

+typedef struct _ServerAddr{

+    char ip[16];

+    unsigned short port;

+} ServerAddr;

+

+typedef struct _FotaTask{

+    unsigned char flag; 

+    unsigned int interval;

+    unsigned int delay;

+    char destVersion[32];

+} FotaTask;

+

+typedef struct _Version{

+    char product[8];

+    char orig_version[30];

+    char dest_version[30];

+} Version;

+

+typedef struct _VerID{

+    char product[8];

+    unsigned short orig_verid;

+    unsigned short dest_verid;

+} VerID;

+

+typedef struct _DiffPackInfo{

+    unsigned char diffPackID[15];

+    unsigned char MD5[16];

+    unsigned int size;

+} DiffPackInfo;

+

+typedef struct _DiffPackDataReq{

+    unsigned char diffPackID[15];

+    unsigned int offset;

+    unsigned int length;

+} DiffPackDataReq;

+

+typedef struct _DiffPackDataResp{

+    unsigned char diffPackID[15];

+    unsigned char MD5[16];

+    unsigned int offset;

+    unsigned int length;

+    unsigned char data[1024];

+} DiffPackDataResp;

+

+typedef struct _DiffPackEnd{

+    unsigned char diffPackID[15];

+    unsigned int costTime;

+} DiffPackEnd;

+

+#pragma pack()

+

+int wefaota_header_init(WeFOTAHeader *hdr);

+void set_fota_status(FOTA_Status status);

+FOTA_Status get_fota_status(void);

+

+#endif
\ No newline at end of file
diff --git a/lynq/S300_COMMON/ap/app/wefota/wefota_socket.c b/lynq/S300_COMMON/ap/app/wefota/wefota_socket.c
new file mode 100755
index 0000000..35c4ee1
--- /dev/null
+++ b/lynq/S300_COMMON/ap/app/wefota/wefota_socket.c
@@ -0,0 +1,77 @@
+#include <stdio.h>

+#include <stdlib.h>

+#include <string.h>

+#include <unistd.h>

+#include <sys/socket.h>

+#include "wefota_socket.h"

+#include "wefota_main.h"

+#include <errno.h>

+

+#define WEFOTA_RECV_TIMEOUT_SEC 3

+

+int create_udp_socket(void) {

+    int sock = socket(AF_INET, SOCK_DGRAM, 0);

+    if (sock < 0) {

+        perror("socket create failed");

+        return -1;

+    }

+    return sock;

+}

+

+void close_udp_socket(int sock) {

+    if (sock >= 0) {

+        close(sock);

+    }

+}

+

+int init_server_addr(struct sockaddr_in* addr, const char* ip, int port) {

+    if (addr == NULL || ip == NULL || port <= 0) {

+        return -1;

+    }

+

+    memset(addr, 0, sizeof(*addr));

+    addr->sin_family = AF_INET;

+    if (inet_pton(AF_INET, ip, &(addr->sin_addr)) <= 0) {

+        perror("wrong ip address");

+        return -1;

+    }

+    addr->sin_port = htons(port);

+    return 0;

+}

+

+int send_message(int sock, const void* msg, size_t len, struct sockaddr_in* server_addr) {

+    int sent = sendto(sock, msg, len, 0, 

+                         (struct sockaddr*)server_addr, sizeof(*server_addr));

+    if (sent < 0) {

+        perror("send message failed");

+        return -1;

+    }

+    printf("send message end, sent=%d\n", sent);

+    return 0;

+}

+

+int receive_message(int sock, void* response, size_t response_size, struct sockaddr_in* server_addr) {

+    set_recv_timeout(sock, WEFOTA_RECV_TIMEOUT_SEC);

+    socklen_t addr_len = sizeof(*server_addr);

+    int received = recvfrom(sock, response, response_size, 0,

+                               (struct sockaddr*)server_addr, &addr_len);

+	if (received < 0)

+	{

+		printf("error num:%d\n", errno);

+		perror("recvfrom");

+	}

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

+    return received;

+}

+

+int set_recv_timeout(int sock, int timeout_sec) {

+    struct timeval tv;

+    tv.tv_sec = timeout_sec;

+    tv.tv_usec = 0;

+    

+    if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {

+        perror("set socket timeout failed");

+        return -1;

+    }

+    return 0;

+}

diff --git a/lynq/S300_COMMON/ap/app/wefota/wefota_socket.h b/lynq/S300_COMMON/ap/app/wefota/wefota_socket.h
new file mode 100755
index 0000000..4c45117
--- /dev/null
+++ b/lynq/S300_COMMON/ap/app/wefota/wefota_socket.h
@@ -0,0 +1,14 @@
+#ifndef _WEFOTA_SOCKET_H_

+#define _WEFOTA_SOCKET_H_

+

+#include <arpa/inet.h>

+

+

+int create_udp_socket(void);

+void close_udp_socket(int sock);

+int init_server_addr(struct sockaddr_in* addr, const char* ip, int port);

+int send_message(int sock, const void* msg, size_t len, struct sockaddr_in* server_addr);

+int receive_message(int sock, void* response, size_t response_size, struct sockaddr_in* server_addr);

+int set_recv_timeout(int sock, int timeout_sec);

+

+#endif
\ No newline at end of file