[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