Merge "[Bugfix][T106BUG-109][NetWork] call  lynq_oos_recover_timer_interval ret 6003"
diff --git a/cap/zx297520v3/sources/meta-zxic-custom/conf/distro/vehicle_dc_ref.conf b/cap/zx297520v3/sources/meta-zxic-custom/conf/distro/vehicle_dc_ref.conf
index 6ef9412..2ba0f08 100755
--- a/cap/zx297520v3/sources/meta-zxic-custom/conf/distro/vehicle_dc_ref.conf
+++ b/cap/zx297520v3/sources/meta-zxic-custom/conf/distro/vehicle_dc_ref.conf
@@ -194,6 +194,7 @@
         liblynq-at-factory \
         liblynq-gpio \
         liblynq-irq \
+        liblynq-at-common \
 	"
 
 zxic_lib += "${@bb.utils.contains('CONFIG_TEL_API_SUPPORT', 'RIL', 'libril', 'libtelsvr', d)}"
@@ -273,6 +274,7 @@
         lynq-qser-autosuspend-demo \
         lynq-gpio-demo \
         lynq-irq-demo \
+        lynq-gnss-update \
         "
 
 zxic_app_open += "${@bb.utils.contains('CONFIG_TEL_API_SUPPORT', 'RIL', 'rild', '', d)}"
diff --git a/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/liblynq-at-common/liblynq-at-common.bb b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/liblynq-at-common/liblynq-at-common.bb
new file mode 100755
index 0000000..01be6b1
--- /dev/null
+++ b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/liblynq-at-common/liblynq-at-common.bb
@@ -0,0 +1,57 @@
+#inherit externalsrc package
+
+DESCRIPTION = "liblynq-at-common"
+LICENSE = "CLOSED"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=3f86c7f456a6d0bbeca155e65084eee1"
+DEPENDS += "liblynq-log"
+#inherit workonsrc
+WORKONSRC = "${TOPDIR}/../src/lynq/lib/liblynq-at-common/"
+FILESEXTRAPATHS_prepend :="${TOPDIR}/../src/lynq/lib/:"
+SRC_URI = " \
+          file://liblynq-at-common\
+          "
+
+SRC-DIR = "${S}/../liblynq-at-common"
+
+TARGET_CC_ARCH += "${LDFLAGS}"
+SYSTEMD_PACKAGES = "${PN}"
+BB_INCLUDE_ADD = "--sysroot=${STAGING_DIR_HOST}"
+BB_LDFLAGS_ADD = "--sysroot=${STAGING_DIR_HOST} -Wl,--hash-style=gnu"
+
+EXTRA_OEMAKE = "'TARGET_PLATFORM = ${TARGET_PLATFORM}'"
+EXTRA_OEMAKE += "'LYNQ_CONFIG_VERSION = ${LYNQ_CONFIG_VERSION}' \
+                 'LYNQ_CONFIG_SW_VERSION = ${LYNQ_CONFIG_SW_VERSION}'"
+
+FILES_${PN} += "${base_libdir}/*.so "
+
+FILES_${PN}-dev = "/test \
+                   ${includedir}"
+
+FILES_${PN}-doc = "/doc"
+
+FILES_${PN}-dbg ="${base_bindir}/.debug \
+                  ${base_libdir}/.debug \
+                  ${base_sbindir}/.debug"
+
+INSANE_SKIP_${PN} += "already-stripped"
+INSANE_SKIP_${PN} += "installed-vs-shipped"
+
+
+#INHIBIT_PACKAGE_STRIP = "1"
+do_compile () {
+		oe_runmake all -C ${SRC-DIR} ROOT=${STAGING_DIR_HOST} OFLAGS="--sysroot=${STAGING_DIR_HOST} -Os -Wl,--hash-style=gnu -DTELEPHONYWARE"
+}
+
+do_install () {
+    oe_runmake install -C ${SRC-DIR} ROOT=${D}
+
+    if [ -d "${WORKONSRC}" ] ; then
+        install -d ${D}${includedir}/
+        cp -raf ${SRC-DIR}/include/ ${D}${includedir}/
+    fi
+}
+
+addtask bachclean
+do_bachclean () {
+    oe_runmake clean
+}
diff --git a/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/liblynq-qser-gnss/liblynq-qser-gnss.bb b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/liblynq-qser-gnss/liblynq-qser-gnss.bb
index 46f2a37..bebad96 100755
--- a/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/liblynq-qser-gnss/liblynq-qser-gnss.bb
+++ b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/liblynq-qser-gnss/liblynq-qser-gnss.bb
@@ -17,9 +17,11 @@
 BB_INCLUDE_ADD = "--sysroot=${STAGING_DIR_HOST}"

 BB_LDFLAGS_ADD = "--sysroot=${STAGING_DIR_HOST} -Wl,--hash-style=gnu"

 

+FILES_${PN} += "${bindir} /data/gnss_update"

+

 EXTRA_OEMAKE = "'TARGET_PLATFORM = ${TARGET_PLATFORM}'"

 

-FILES_${PN} = "${base_libdir}/*.so "

+FILES_${PN} += "${base_libdir}/*.so "

 

 FILES_${PN}-dev = "/test \

                    ${includedir}"

@@ -36,15 +38,21 @@
 

 #INHIBIT_PACKAGE_STRIP = "1"

 do_compile () {

-		oe_runmake all -C ${SRC-DIR} ROOT=${STAGING_DIR_HOST} OFLAGS="--sysroot=${STAGING_DIR_HOST} -Os -Wl,--hash-style=gnu -DTELEPHONYWARE"

+        oe_runmake all -C ${SRC-DIR} ROOT=${STAGING_DIR_HOST} OFLAGS="--sysroot=${STAGING_DIR_HOST} -Os -Wl,--hash-style=gnu -DTELEPHONYWARE"

 }

 

 do_install () {

     oe_runmake install -C ${SRC-DIR} ROOT=${D}

-	

+

     if [ -d "${WORKONSRC}" ] ; then

         install -d ${D}${includedir}/

         cp -raf ${SRC-DIR}/include/ ${D}${includedir}/

+        install -d ${D}/data/gnss_update

+        install -m 644 ${WORKONSRC}UC6228CI-R3.2.10.100Build8019_mfg.pkg ${D}/data/gnss_update

+        install -m 644 ${WORKONSRC}bootloader_r3.0.0_build6773_uartboot_921600.pkg ${D}/data/gnss_update

+        install -m 644 ${WORKONSRC}agps.conf ${D}/data/gnss_update

+        ln -sf ./UC6228CI-R3.2.10.100Build8019_mfg.pkg ${D}/data/gnss_update/firmware.pkg

+        ln -sf ./bootloader_r3.0.0_build6773_uartboot_921600.pkg ${D}/data/gnss_update/bootloader.pkg

     fi 

 }

 

diff --git a/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/lynq-gnss-update/files/lynq-gnss-update.cpp b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/lynq-gnss-update/files/lynq-gnss-update.cpp
new file mode 100755
index 0000000..29abd03
--- /dev/null
+++ b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/lynq-gnss-update/files/lynq-gnss-update.cpp
@@ -0,0 +1,1337 @@
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <errno.h>
+#include <time.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/times.h>
+#include <sys/types.h>
+#include <termios.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/wait.h>
+#include <ctype.h>
+#include <sched.h>
+#include <limits.h>
+#include <linux/serial.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define RTM_FILE_NAME "rtm.bin"
+
+#define PARA_ERR                -1
+#define FILE_CHECK_ERR          -2
+#define ENTER_UPDATE_MODE_ERR   -3
+#define UPDATE_ERR              -4
+#define UART_DEV_ERR            -5
+
+#define XMODEM_SOH 0x01
+#define XMODEM_STX 0x02
+#define XMODEM_EOT 0x04
+#define XMODEM_ACK 0x06
+#define XMODEM_NAK 0x15
+#define XMODEM_CAN 0x18
+#define XMODEM_CRC_CHR	'C'
+#define XMODEM_CRC_SIZE 2		/* Crc_High Byte + Crc_Low Byte */
+#define XMODEM_FRAME_ID_SIZE 2 		/* Frame_Id + 255-Frame_Id */
+#define XMODEM_DATA_SIZE_SOH 128  	/* for Xmodem protocol */
+#define XMODEM_DATA_SIZE_STX 1024 	/* for 1K xmodem protocol */
+#define USE_1K_XMODEM 1  		/* 1 for use 1k_xmodem 0 for xmodem */
+#define	TIMEOUT_USEC	0
+#define	TIMEOUT_SEC		10
+
+#if (USE_1K_XMODEM)
+#define XMODEM_DATA_SIZE 	XMODEM_DATA_SIZE_STX
+#define XMODEM_HEAD		XMODEM_STX
+#else
+#define XMODEM_DATA_SIZE 	XMODEM_DATA_SIZE_SOH
+#define XMODEM_HEAD 		XMODEM_SOH
+#endif
+
+
+/******************************************************************************
+ * 时间处理相关的宏
+ *****************************************************************************/
+// 时间超时标志
+int timeout_sign = 1;
+// 获取当前时间
+#define GET_TIME()  { gettimeofday(&time_m, NULL); \
+    time_m.tv_sec += TIMEOUT_SEC;\
+}
+// 设置从循环中退出的时间
+#define SET_TIME_OUT(x)  { gettimeofday(&time_m, NULL); \
+    time_m.tv_sec += x;\
+}
+// 检测时间是否超时,超时则退出当前函数
+#define CHK_TIME()  { gettimeofday(&time_n, NULL); \
+    if(time_n.tv_sec > time_m.tv_sec) { \
+    printf("\ntimeout!!!\n\n");\
+    close(fd); \
+    return ret; \
+} \
+}
+// 检测时间是否超时,超时则退出当前循环
+#define CHK_TIME_BREAK()  { gettimeofday(&time_n, NULL); \
+    if(time_n.tv_sec > time_m.tv_sec) { \
+    timeout_sign = 1; 	\
+    printf("\ntimeout!!!\n\n");\
+    break; \
+} \
+}
+// 检测延时是否到达,到达则退出当前循环
+#define DELAY_TIME_BREAK()  { gettimeofday(&time_n, NULL); \
+    if(time_n.tv_sec > time_m.tv_sec) { \
+    timeout_sign = 1; 	\
+    break; \
+} \
+}
+
+// 检测时间是否超时,超时则退出当前函数
+#define CHK_TIME1()  { gettimeofday(&time_n, NULL); \
+    if(time_n.tv_sec > time_m.tv_sec) { \
+    printf("\ntimeout!!!\n\n");\
+    if(datafile != NULL) \
+    fclose(datafile); \
+    return ret; \
+} \
+}
+
+
+/******************************************************************************
+ * APData 相关定义、声明
+ *****************************************************************************/
+// APData 数据头部定义
+typedef struct {
+    unsigned int  ih_magic;		// Image Header Magic Number
+    unsigned int  ih_dcrc;		// Image Data CRC checksum
+    unsigned int  ih_time;		// Image Creation Timestamp
+    unsigned int  ih_size;		// Image Data Size
+    unsigned int  ih_compress;		// Image Header compress or not:0, not compress
+    unsigned int  pkg_flash_addr;	// flash memory offset for package
+    unsigned int  pkg_run_addr;		// Run time address for this package
+    unsigned int  ih_hcrc;		// Image Header CRC checksum
+} uc_image_header_t;
+
+// APData 数据头部长度
+#define HEADERLEN 32
+// APData 接收状态类型
+typedef enum ReceStat{
+    WAIT_FD = 1,
+    WAIT_FC,
+    WAIT_FB,
+    WAIT_FA,
+    RECE_HEADER,
+    RECE_DATA,
+} RecvStat_t;
+// APData 接收状态变量
+static RecvStat_t recvStat = WAIT_FD;
+// APData 接收状态变量
+static int isStartReceive = 0;
+// APData 开始接收
+void af_start_receive();
+// APData 停止接收,在数据接收完成或出错时调用
+void af_stop_receive();
+// 获取isStartReceive 变量值
+int af_is_start_receive();
+// APData 数据接收入口
+int af_add_char(char *file, unsigned char c);
+// 校验 APData 数据头
+int af_check_header(unsigned char *pbuf, unsigned int len);
+// 校验 APData 数据区
+int af_check_data(unsigned int * pbuf, unsigned int len);
+// 获取 APData 数据长度
+int af_get_data_len();
+// APData 数据接收缓存
+
+int check_file(char *fname);
+
+/******************************************************************************
+ * 与接收机串口通讯相关定义、声明
+ *****************************************************************************/
+// select功能使用变量
+static int use_select = 1;
+// 初始化串口资源
+int initial_serialPort(char * serial_device);
+// 设置串口波特率
+static int set_baudrate(int fd, int baudrate);
+// 检测串口数据
+static int select_read(int fd, int timeout);
+// 读取串口数据
+static ssize_t deal_read(int fd, void *buf, size_t count);
+// 向接收机发送串口数据
+static void gps_dev_send(int fd, char *msg);
+// 通过xmodem协议向接收机发送串口数据
+int xmodem_send(int fd, char *fname);
+
+/******************************************************************************
+ * apflash 功能函数
+ *****************************************************************************/
+// 检测接收机发送的'YC'信号,如果收到,则标志着接收机进入boot模式,并可以通过xmodem发送数据
+int check_YC(char newchar);
+// 获取 APData 数据, 应该在接收机定位且星历数据接收完整时获取
+int getAPData(int fd, char *file);
+// 向接收机发送 APData 数据,有效的APData数据可以让CI模块迅速定位
+int sendAPData(int fd, char *ap);
+// 校验 APData 数据文件
+int checkAPData(char *apFile);
+// 为接收机加载BootLoader,该流程执行时,需要根据终端提示,给接收机下电和上电,确保接收机进入boot模式
+int downloadBL(int fd, char *bl);
+// 为接收机加载Firmware,该流程必须在加载BootLoader之后进行
+int downloadFW(int fd, char *fw);
+unsigned int recv_buf[1024 * 2];
+unsigned char *pbuf;
+int data_len;
+volatile int nmea_state = 0;
+volatile int nmea_reading = 0;
+// 校验文件
+void printGetapUsage(char *app)
+{
+    printf("\n%s getap -d receiverPort [-b baudrate] [-h] -a apfile \n", app);
+    printf("\tfunction: read APData from receiver\n");
+    printf("\tparas:\n");
+    printf("\t\treceiverPort: Port that connected to receiver\n");
+    printf("\t\tbaudrate: baudrate of receiverPort\n");
+}
+
+void printSendapUsage(char *app)
+{
+    printf("\n%s sendap -d receiverPort [-b baudrate] [-h] -a apfile\n", app);
+    printf("\tfunction: send APData to receiver\n");
+    printf("\tparas:\n");
+    printf("\t\treceiverPort: Port that connected to receiver\n");
+    printf("\t\tbaudrate: baudrate of receiverPort\n");
+}
+
+void printCheckapUsage(char *app)
+{
+    printf("\n%s checkap -a apfile [-h]\n", app);
+    printf("\tfunction: check APData\n");
+    printf("\tparas:\n");
+    printf("\t\tapfile: APData file\n");
+}
+
+void printDownloadblUsage(char *app)
+{
+    printf("\n%s downbl -d receiverPort [-b baudrate] -l bootloader [-h]\n", app);
+    printf("\tfunction: download bootloader to receiver\n");
+    printf("\tparas:\n");
+    printf("\t\treceiverPort: Port that connected to receiver\n");
+    printf("\t\tbaudrate: baudrate of receiverPort\n");
+    printf("\t\tbootloader: bootloader file\n");
+}
+
+void printDownloadfwUsage(char *app)
+{
+    printf("\n%s downfw -d receiverPort [-b baudrate] -f firmware [-h]\n", app);
+    printf("\tfunction: download firmware to receiver\n");
+    printf("\tparas:\n");
+    printf("\t\treceiverPort: Port that connected to receiver\n");
+    printf("\t\tbaudrate: baudrate of receiverPort\n");
+    printf("\t\tfirmware: firmware file\n");
+}
+
+void printUsage(char *app)
+{
+    printGetapUsage(app);
+    printSendapUsage(app);
+    printCheckapUsage(app);
+    printDownloadblUsage(app);
+    printDownloadfwUsage(app);
+}
+
+int exec_cmd(const char *cmd, char *result)
+{
+    FILE *pipe = popen(cmd, "r");
+    if(!pipe)
+        return -1;
+
+    char buffer[256] = {0};
+    while(!feof(pipe))
+    {
+        if(fgets(buffer, 256, pipe))
+        {
+            memset(buffer, 0, sizeof(buffer));
+        }
+    }
+    pclose(pipe);
+    return 0;
+}
+
+int mopen_open_gps(int state)
+{
+    char cmd[128] = "echo '86' > /sys/class/gpio/export && cd /sys/class/gpio/gpio86";
+    int ret;
+
+    if(0 == state)
+    {
+        nmea_state = 0;
+        for(int cont = 0; cont < 200; cont++)
+        {
+            if (nmea_reading == 0)
+            {
+                break;
+            }
+            usleep(10000);
+        }
+        ret = exec_cmd(cmd,NULL);
+        if(0 != ret)
+        {
+            printf("stop fail %x\n", ret);
+        }
+        char cmd2[128] = "echo '0' > /sys/class/gpio/gpio86/value && echo '86' > /sys/class/gpio/unexport";
+        ret = exec_cmd(cmd2,NULL);
+        if(0 != ret)
+        {
+            printf("stop fail %x\n", ret);
+        }
+    }
+
+    if(1 == state)
+    {
+        nmea_state = 1;
+
+        ret = exec_cmd(cmd,NULL);
+        if(0 != ret)
+        {
+            printf("start fail %x\n", ret);
+            return -1;
+        }
+        char cmd3[128] = "echo '1' > /sys/class/gpio/gpio86/value && echo '86' > /sys/class/gpio/unexport";
+        ret = exec_cmd(cmd3,NULL);
+        if(0 != ret)
+        {
+            printf("start fail %x\n", ret);
+            return -1;
+        }
+    }
+    return 0;
+}
+
+int main(int argc, char *argv[])
+{
+    int c;
+    int ret = 0;
+    int fd = -1;
+    int paraMask = 0;
+    int baud = 115200;
+    char devPort[200] = {0};
+    char fw[200] = {0};
+    char bl[200] = {0};
+    char ap[200] = {0};
+    int func = 0; // 1:getap, 2:sendap, 3:downbl, 4:downfw, 5:checkap
+
+    // Verify arguments
+    if (argc < 2) {
+        printf("Usage:\n");
+        printUsage(argv[0]);
+        exit(1);
+    }
+
+    if(strcmp(argv[1], "getap") == 0) {
+        func = 1;
+        paraMask = 1;
+    } else if (strcmp(argv[1], "sendap") == 0) {
+        func = 2;
+        paraMask = 1;
+    } else if (strcmp(argv[1], "downbl") == 0) {
+        func = 3;
+        paraMask = 9;
+    } else if (strcmp(argv[1], "downfw") == 0) {
+        func = 4;
+        paraMask = 5;
+    } else if (strcmp(argv[1], "checkap") == 0) {
+        func = 5;
+        paraMask = 16;
+    } else {
+        printf("Usage:\n");
+        printUsage(argv[0]);
+        exit(1);
+    }
+
+    for(;;) {
+        opterr = 0;
+        c = getopt(argc, argv, "d:b:f:l:a:h");
+        if(c < 0)
+            break;
+        switch(c) {
+        case 'd':
+            snprintf(devPort, 200, "%s", optarg);
+            printf("receiver port: %s\n", devPort);
+            paraMask &= ~1;
+            break;
+        case 'b':
+            baud = atoi(optarg);
+            printf("baud rate: %d\n", baud);
+            break;
+        case 'f':
+            snprintf(fw, 200, "%s", optarg);
+            printf("firmware: %s\n", fw);
+            paraMask &= ~4;
+            break;
+        case 'l':
+            snprintf(bl, 200, "%s", optarg);
+            printf("bootloader: %s\n", bl);
+            paraMask &= ~8;
+            break;
+        case 'a':
+            snprintf(ap, 200, "%s", optarg);
+            printf("apdata file: %s\n", ap);
+            paraMask &= ~16;
+            break;
+        case 'h':
+        default:
+            printf("Usage:\n");
+            if (func == 1)
+                printGetapUsage(argv[0]);
+            else if (func == 2)
+                printSendapUsage(argv[0]);
+            else if (func == 3)
+                printDownloadblUsage(argv[0]);
+            else if (func == 4)
+                printDownloadfwUsage(argv[0]);
+            else if (func == 5)
+                printCheckapUsage(argv[0]);
+            else
+                printUsage(argv[0]);
+            exit(1);
+        }
+    }
+    if (paraMask) {
+        if (func == 1)
+            printGetapUsage(argv[0]);
+        else if (func == 2)
+            printSendapUsage(argv[0]);
+        else if (func == 3)
+            printDownloadblUsage(argv[0]);
+        else if (func == 4)
+            printDownloadfwUsage(argv[0]);
+        else if (func == 5)
+            printCheckapUsage(argv[0]);
+        else
+            printUsage(argv[0]);
+        exit(1);
+    }
+
+    // Open serial port
+    if (func != 5) {
+        if ((fd = initial_serialPort(devPort)) == -1)
+        {
+            printf("Can't open COM\n");
+            return UART_DEV_ERR;
+        }
+        if (baud == 115200) {
+            set_baudrate(fd, B115200);
+        } else if (baud == 230400) {
+            set_baudrate(fd, B230400);
+        } else if (baud == 921600) {
+            set_baudrate(fd, B921600);
+        } else if (baud == 1843200) {
+            set_baudrate(fd, B1500000);
+        } else {
+            printf("baudrate %d not supported\n", baud);
+            close(fd);
+            exit(1);
+        }
+    }
+
+    // execute function
+    switch(func) {
+    case 1:
+        ret = getAPData(fd, ap);
+        break;
+    case 2:
+        ret = sendAPData(fd, ap);
+        break;
+    case 3:
+        ret = downloadBL(fd, bl);
+        break;
+    case 4:
+        ret = downloadFW(fd, fw);
+        break;
+    case 5:
+        ret = checkAPData(ap);
+        break;
+    default:break;
+    }
+    close(fd);
+    return ret;
+
+}
+
+int getAPData(int fd, char *file)
+{
+    int rByte = 0;
+    char rbuf[4096];
+    int ret = 0, i;
+    struct timeval time_m, time_n;
+
+    if (NULL == file) {
+        printf("Please input file!! \n");
+        return 1;
+    }
+    if (!fd)
+        return 1;
+    printf("Get apdata\n");
+    gps_dev_send(fd, "$ReqRecvFlash\r\n");
+    af_start_receive();
+    GET_TIME();
+    while(1) {
+        CHK_TIME();
+        if(select_read(fd,1) > 0)
+            usleep(50000);
+        else
+            continue;
+
+        rByte = deal_read(fd,&rbuf,sizeof(rbuf));
+        if(rByte >= 1){
+            if(af_is_start_receive()) {
+                for(i = 0; i < rByte; i++)
+                    af_add_char(file, rbuf[i]);
+            } else {
+                break;
+            }
+        }
+    }
+
+    checkAPData(file);
+    return 0;
+}
+
+int sendAPData(int fd, char *apFile)
+{
+    int rByte = 0;
+    char rbuf[4096];
+    int ret = 0;
+    struct timeval time_m, time_n;
+
+    if(access(apFile, F_OK) != -1)
+    {
+        // Download APData only if the file exits
+        printf("Download APData...\n");
+        if(xmodem_send(fd, apFile))
+        {
+            printf("xmodem error!\n");
+            close(fd);
+            return ENTER_UPDATE_MODE_ERR;
+        }
+        // Waiting for 'C'
+        GET_TIME();
+        while(1)
+        {
+            CHK_TIME();
+            if(select_read(fd,1) > 0)
+                usleep(500000);
+            else
+                continue;
+            rByte = deal_read(fd,&rbuf,sizeof(rbuf)-1);
+            rbuf[rByte] = 0;
+            if(rByte > 0)
+            {
+                if(rbuf[rByte - 1] == 'C')
+                    break;
+            }
+        }
+        printf("download APData success\n");
+    }
+    else
+    {
+        printf("file err!\n");
+        return 1;
+    }
+
+    return 0;
+}
+
+int checkAPData(char *apFile)
+{
+    printf("Checking %s\n", apFile);
+    if(check_file(apFile))
+    {
+        printf("file error!\n");
+        return FILE_CHECK_ERR;
+
+    }
+    else
+    {
+        printf("pass\r\n");
+    }
+    return 0;
+}
+
+int downloadFW(int fd, char *fw)
+{
+    int ret;
+    struct timeval time_m, time_n;
+    char rbuf[512];
+
+    if(NULL == fw) {
+        printf("Error: Can't find firmware.\n");
+        return -1;
+    }
+    printf("Download firmware...\n");
+    if(xmodem_send(fd, fw) < 0) {
+        printf("xmodem error! send firmware failed!\n");
+        close(fd);
+        return UPDATE_ERR;
+    }
+    set_baudrate(fd, B115200);
+    printf("Download firmware success\n");
+    return 0;
+}
+
+int downloadBL(int fd, char *bl)
+{
+    int rByte = 0;
+    char rbuf[4096];
+    char name[128];
+    int ret = 0;
+    struct timeval time_m, time_n;
+
+    if(NULL == bl) {
+        printf("Error: Can't find bootloader.\n");
+        return -1;
+    }
+    printf("------Please Powerdown the receiver!\n");
+    mopen_open_gps(0);
+    SET_TIME_OUT(3);
+    while(1) {
+        DELAY_TIME_BREAK(); //
+        if(select_read(fd,1) > 0)
+            usleep(50000);
+        else
+            continue;
+
+        rByte = deal_read(fd,&rbuf,sizeof(rbuf));
+    }
+    int start = 0,finish = 0;
+
+    memset(name, 0, sizeof(name));
+    sprintf(name,"M!T");
+    printf("waiting for YC, timeout is %d s\n", TIMEOUT_SEC);
+    printf("-------Please Powerup the receiver!\n");
+    mopen_open_gps(1);
+    // Waiting for 'YC'
+    GET_TIME();
+    while(1) {
+        int finish = 0, i;
+        CHK_TIME_BREAK(); //
+        rByte = write(fd, name, strlen(name));
+        rByte = select_read(fd,1);
+        if(rByte <= 0)
+            continue;
+        rByte = deal_read(fd, rbuf, sizeof(rbuf) - 1);
+        rbuf[rByte] = 0;
+        for (i = 0 ; i < rByte; i++)
+        {
+            if (check_YC(rbuf[i])) {
+                printf("Receive 'YC'\n");
+                finish = 1;
+                break;
+            }
+        }
+        if (finish)
+            break;
+    }
+    //wait 'YC' timeout deal
+    if (timeout_sign == 1)
+    {
+        //wait NAK
+        GET_TIME();
+        printf("2222\n");
+        while(1)
+        {
+            CHK_TIME();
+            if(select_read(fd,1) <= 0)
+                continue;
+
+            rByte = deal_read(fd, rbuf,sizeof(rbuf));
+            if (rbuf[rByte-1] == 'C')
+            {
+                printf("###read xmodem start character 'C'.\n");
+                break;
+            }
+        }
+    }
+    //use_select = 1;
+    printf("download bootloader...\n");
+
+    // Transfer bootloader via xmodem protocal
+    // if(xmodem_send(fd, "./bootloader.bin")) {
+    if(xmodem_send(fd, bl)) {
+        printf("xmodem error!\n");
+        close(fd);
+        return ENTER_UPDATE_MODE_ERR;
+    }
+    printf("download bootloader success\n");
+    return 0;
+}
+
+int check_YC(char newchar)
+{
+    int static state = 0;
+    int ret = 0;
+    switch (state) {
+    case 0:
+        if (newchar == 'Y')
+            state = 1;
+        break;
+    case 1:
+        if (newchar == 'C') {
+            state = 1;
+            ret = 1;
+        }
+        break;
+    default:
+        state = 0;
+    }
+    return ret;
+}
+
+const unsigned short CRC16_Table[256] = {
+    0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
+    0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
+    0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
+    0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
+    0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
+    0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
+    0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
+    0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
+    0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
+    0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
+    0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
+    0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
+    0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
+    0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
+    0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
+    0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
+    0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
+    0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
+    0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
+    0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
+    0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
+    0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
+    0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
+    0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
+    0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
+    0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
+    0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
+    0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
+    0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
+    0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
+    0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
+    0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
+};
+
+unsigned short crc16_ccitt(const unsigned char *buf, int len)
+{
+    register int counter;
+    register unsigned short crc = 0;
+    for (counter = 0; counter < len; counter++)
+        crc = (crc << 8) ^ CRC16_Table[((crc >> 8) ^ *(char *)buf++) & 0x00FF];
+    return crc;
+}
+
+
+unsigned int checksum32(unsigned int * pbuf, unsigned int len)
+{
+    unsigned int i, sumValue = 0;
+    len >>=2;
+
+    for(i=0;i<len;i++)
+    {
+        sumValue += *pbuf++;
+    }
+    return sumValue;
+}
+
+void af_start_receive()
+{
+    recvStat = WAIT_FD;
+    isStartReceive = 1;
+    return;
+}
+
+void af_stop_receive()
+{
+    int i;
+    printf("%s:%d\r\n", __FUNCTION__, __LINE__);
+    printf("%s:%d  recvStat = %d\r\n", __FUNCTION__, __LINE__, recvStat);
+    pbuf = (unsigned char *)recv_buf;
+    for(i = 0; i < 4636; i++){
+        if(i % 32 == 0)printf("\r\n");
+        printf("%02X ", pbuf[i]);
+    }
+    printf("\r\n");
+    isStartReceive = 0;
+    return;
+}
+
+int af_is_start_receive()
+{
+    return isStartReceive;
+}
+
+int af_check_header(unsigned char *pbuf, unsigned int len)
+{
+    unsigned int crc = crc16_ccitt(pbuf, len-4);
+
+    if(crc == *(unsigned int *)(pbuf + len - 4))
+        return 1;
+    else
+        return 0;
+}
+
+int af_check_data(unsigned int * pbuf, unsigned int len)
+{
+    unsigned int cs = checksum32(pbuf + 8, len);
+    if(cs == pbuf[1])
+        return 1;
+    else
+        return 0;
+}
+
+int af_get_data_len()
+{
+    int len = *(int *)(recv_buf+3);
+    return len;
+}
+
+int af_add_char(char *file, unsigned char c)
+{
+    int ret = 0;
+    switch(recvStat){
+    case WAIT_FD:
+        if(c == 0xfd){
+            pbuf = (unsigned char *)recv_buf;
+            pbuf[0] = c;
+            recvStat = WAIT_FC;
+            printf("------------received 0xfd\r\n");
+        }
+        break;
+    case WAIT_FC:
+        if(c == 0xfc){
+            pbuf[1] = c;
+            recvStat = WAIT_FB;
+            printf("------------received 0xfc\r\n");
+        }else{
+            af_stop_receive();
+        }
+        break;
+    case WAIT_FB:
+        if(c == 0xfb){
+            pbuf[2] = c;
+            recvStat = WAIT_FA;
+            printf("------------received 0xfb\r\n");
+        }else{
+            af_stop_receive();
+        }
+        break;
+    case WAIT_FA:
+        if(c == 0xfa){
+            pbuf[3] = c;
+            recvStat = RECE_HEADER;
+            pbuf += 4;
+            printf("------------received 0xfa\r\n");
+        }else{
+            af_stop_receive();
+        }
+        break;
+    case RECE_HEADER:
+        *pbuf = c;
+        pbuf++;
+        if((pbuf - (unsigned char *)recv_buf) == HEADERLEN){
+            if(af_check_header((unsigned char *)recv_buf, HEADERLEN)){
+                recvStat = RECE_DATA;
+                data_len = af_get_data_len();
+            }else{
+                af_stop_receive();
+            }
+        }
+        break;
+    case RECE_DATA:
+        *pbuf = c;
+        pbuf++;
+        if((pbuf - (unsigned char *)recv_buf) == data_len + HEADERLEN){
+            if(af_check_data(recv_buf, recv_buf[3])){
+                int fd = open(file, O_WRONLY|O_CREAT, S_IRWXU);
+                write(fd, recv_buf, pbuf - (unsigned char *)recv_buf);
+                printf("%s:%d rtm len = %ld\r\n", __FUNCTION__, __LINE__, pbuf-(unsigned char *)recv_buf);
+                close(fd);
+                printf("receive rtm\n");
+            }else{
+                printf("af_check_data false!");
+            }
+            af_stop_receive();
+        }
+        ret = 1;
+        break;
+    default:
+        printf("%s:recvStat = %d\r\n", __FUNCTION__, recvStat);
+        break;
+    }
+    return ret;
+}
+
+
+
+ssize_t deal_read(int fd, void *buf, size_t count)
+{
+    int ret = 0;
+
+    while (1)
+    {
+        ret = read(fd, buf, count);
+        if (ret == 0)
+        {
+            printf("read serial return 0, please check serial device.\n");
+            exit(UART_DEV_ERR);
+        }
+        if(ret < 0)
+        {
+            if ((errno == EAGAIN) || (errno == EINTR))
+            {
+                printf("read serial return -1, errno = %d, retry.\n", errno);
+                continue;
+            }
+            else
+            {
+                printf("read serial return -1, errno = %d, please check serial device.\n", errno);
+                exit(UART_DEV_ERR);
+            }
+        }
+        return ret;
+    }
+}
+
+unsigned short get_crc16 ( char *ptr, unsigned short count )
+{
+    unsigned short crc, i;
+
+    crc = 0;
+    while(count--)
+    {
+        crc = crc ^ (int) *ptr++ << 8;
+
+        for(i = 0; i < 8; i++)
+        {
+            if(crc & 0x8000)
+                crc = crc << 1 ^ 0x1021;
+            else
+                crc = crc << 1;
+        }
+    }
+
+    return (crc & 0xFFFF);
+}
+
+void dump_u(void *buf, int len)
+{
+    unsigned char *p = (unsigned char *)buf;
+    int i;
+
+    for(i = 0; i < len; i++) {
+        if(i % 16 == 0) printf("%04x:", i);
+        if(i % 16 == 8) printf(" -");
+        printf(" %02x", p[i]);
+        if(i % 16 == 15) printf("\n");
+    }
+    if(i % 16) printf("\n");
+}
+
+unsigned int get_file_size(const char * name)
+{
+    struct stat statbuff;
+    //unsigned int size, checksum;
+    if(stat(name, &statbuff) < 0)
+        return -1;
+    else
+        return statbuff.st_size;
+}
+
+
+int check_file(char * fname)
+{
+    FILE *fd;
+    uc_image_header_t header;
+    unsigned int buf[1024];
+    unsigned int fsize, checksum, i;
+    unsigned int len;
+    unsigned short crc;
+    size_t rByte;
+
+    if((fd=fopen(fname,"rb"))==NULL)
+    {
+        printf("\n can't open (%s) or not exist!(errno=%d:%s) \n", fname, errno, strerror(errno));
+        return -1;
+    }
+
+    fsize = get_file_size(fname);
+
+    printf("file size [%d]\n",fsize);
+
+    if(fsize == 0)
+        return -1;
+
+    while(fsize > sizeof(header)) {
+        rByte = fread((char *)&header, sizeof(char), sizeof(header), fd);
+
+        dump_u((char *)&header, sizeof(header));
+
+        crc = get_crc16 ( (char *) &header, sizeof(header)-4);
+        printf("crc16  [%08x]\n", crc);
+
+        if((header.ih_hcrc & 0xFFFF) != crc) {
+            fclose(fd);
+            return -1;
+        }
+
+        fsize -= sizeof(header);
+        fsize -= header.ih_size;
+        checksum = 0;
+        len = header.ih_size;
+        while(len > 0)
+        {
+            if(len >= 1024 )
+                rByte = 1024;
+            else
+                rByte = len;
+
+            memset(buf, 0, sizeof(buf));
+            rByte = fread((char *)buf, 1, rByte, fd);
+            for(i = 0; i < (rByte+3)/4; i++)
+                checksum += buf[i];
+
+            len -= rByte;
+        }
+        printf("checksum  [%08x]\n\n",checksum);
+
+        if( checksum != header.ih_dcrc) {
+            fclose(fd);
+            return -1;
+        }
+    }
+
+    fclose(fd);
+    return 0;
+}
+
+static int select_read(int fd, int timeout) //1ms
+{
+    fd_set set;
+    struct timeval t;
+    int ret;
+    int i = timeout;
+
+    if(use_select) {
+        do {
+            FD_ZERO(&set);
+            FD_SET(fd, &set);
+            t.tv_sec = 0;
+            t.tv_usec = 100;
+            ret = select(FD_SETSIZE, &set, NULL, NULL, &t );
+            if(ret == 0) continue;
+            if(ret < 0 && errno == EINTR)continue;
+            else return ret;
+        } while(i--);
+    } else {
+        struct timeval t0, t1;
+        long dt = 0;
+        int c;
+        printf("22222\n");
+        gettimeofday(&t0, NULL);
+        do {
+            c = 0;
+            ret = ioctl(fd, FIONREAD, &c);
+            if(c > 0) { ret = c; break; }
+
+            gettimeofday(&t1, NULL);
+            dt = t1.tv_usec - t0.tv_usec;
+            dt += (t1.tv_sec-t0.tv_sec)*1000*1000;
+        } while(dt/1000 < timeout);
+    }
+
+    return ret;
+}
+
+int set_baudrate(int fd, int baudrate)
+{
+    struct termios options, oldtio;
+
+    if(fcntl(fd, F_SETFL, 0) < 0) {
+        printf("fcntl failed!\n");
+        return -1;
+    }
+
+    if(tcgetattr(fd, &oldtio) != 0) {
+        printf("setup serial error!\n");
+        return -1;
+    }
+
+    /* Get the current options for the port... */
+    tcgetattr(fd, &options);
+
+    /* Set the baud rates to baudrate... */
+    cfsetispeed(&options,baudrate);
+    cfsetospeed(&options,baudrate);
+    tcsetattr(fd, TCSANOW, &options);
+
+    if (0 != tcgetattr(fd, &options))
+    {
+        printf("get options error!\n");
+        return -1;
+    }
+
+    /*
+         * 8bit Data,no partity,1 stop bit...
+         */
+    options.c_cflag &= ~PARENB;//无奇偶校验
+    options.c_cflag &= ~CSTOPB;//停止位,1位
+    options.c_cflag &= ~CSIZE; //数据位的位掩码
+    options.c_cflag |= CS8;    //数据位,8位
+
+    cfmakeraw(&options);
+
+    /*
+         * Set the new options for the port...
+         */
+    if (tcsetattr(fd, TCSANOW, &options) != 0)
+    {
+        printf("setup serial error!\n");
+        return -1 ;
+    }
+
+    return 0 ;
+}
+
+int initial_serialPort(char * serial_device)
+{
+    int fd;
+    fd = open( serial_device , O_RDWR );
+    if ( fd == -1 )
+    {
+        /* open error! */
+        printf("Can't open serial port(%s)!(errno=%d:%s) \n", serial_device, errno, strerror(errno));
+        return -1;
+    }
+
+    set_baudrate(fd, B9600);
+
+    return fd ;
+}
+
+static void gps_dev_send(int fd, char *msg)
+{
+    int i, n, ret;
+
+    i = strlen(msg);
+
+    n = 0;
+
+    printf("function gps_dev_send: %s", msg);
+    do {
+
+        ret = write(fd, msg + n, i - n);
+
+        if (ret < 0 && errno == EINTR) {
+            continue;
+        }
+
+        n += ret;
+
+    } while (n < i);
+
+    // drain cmd
+    tcdrain(fd);
+
+    return;
+}
+
+int xmodem_send(int fd, char *fname)
+{
+    char packet_data[XMODEM_DATA_SIZE];
+    char frame_data[XMODEM_DATA_SIZE + XMODEM_CRC_SIZE + XMODEM_FRAME_ID_SIZE + 1];
+    int ret = -1;
+
+    FILE *datafile;
+    int complete,retry_num,pack_counter,read_number,write_number,i;
+    unsigned short crc_value;
+    unsigned char ack_id = 'C';
+    struct timeval time_m, time_n;
+
+    datafile = NULL;
+    pack_counter = 0;	// 包计数器清零
+    complete = 0;
+    retry_num = 0;
+
+    printf("[%s]\n",fname);
+    //只读方式打开一个准备发送的文件,如果不存在就报错,退出程序。
+    if((datafile=fopen(fname,"rb"))==NULL)
+    {
+        printf("\n can't open (%s) or not exist!(errno=%d:%s) \n", fname, errno, strerror(errno));
+        return -1;
+    }
+    else
+    {
+        printf("Ready to send the file:%s\n",fname);
+    }
+
+    printf("Waiting for signal C/NAK!\n");
+    GET_TIME();
+    while(1)
+    {
+        CHK_TIME1();
+        if(select_read(fd,1) > 0)
+            usleep(10000);
+        else
+            continue;
+
+        //read(fd,&ack_id,1);
+        deal_read(fd,&ack_id,1);
+        if(ack_id == 'C')
+            break;
+    }
+
+    printf("The signal NAK: %02x ok!!!\n",ack_id);//打印接收到的NAK信息
+
+    while(!complete)
+    {
+        switch(ack_id)
+        {
+        case XMODEM_CRC_CHR:	// 接收到字符'C'开始启动传输,并使用CRC校验
+            printf("begining to Send file %s...\n",fname);
+
+        case XMODEM_ACK:        //0x06
+            retry_num = 0;
+            pack_counter++;
+
+            read_number = fread(packet_data, sizeof(char), XMODEM_DATA_SIZE, datafile);
+            //从打开的datafile指向的文件中读取
+            //XMODEM_DATA_SIZE 个(char)数据,
+            //放到packet_data这个数组中
+            if(read_number > 0)//read_number为返回的读取实际字节数
+            {
+                //printf("test:read_number:%d\n", read_number);
+                if(read_number < XMODEM_DATA_SIZE_STX)
+                {
+                    printf("Start filling the last frame!\n");
+                    for(; read_number < XMODEM_DATA_SIZE; read_number++)
+                        packet_data[read_number] = 0x1A;  // 不足128字节用0x1A填充
+                    //printf("replenish data.\n");
+                }
+
+                frame_data[0] = XMODEM_HEAD;  // 帧开始字符
+                frame_data[1] = (char)pack_counter;  // 信息包序号
+                frame_data[2] = (char)(255 - frame_data[1]);  // 信息包序号的补码
+
+                for(i=0; i < XMODEM_DATA_SIZE; i++)  // 128字节的数据段
+                    frame_data[i+3] = packet_data[i];//把收到的字符和信息头一起打包
+
+                crc_value = get_crc16(packet_data, XMODEM_DATA_SIZE); // 16位crc校验
+                frame_data[XMODEM_DATA_SIZE+3] = (unsigned char)(crc_value >> 8);// 高八位数据
+                frame_data[XMODEM_DATA_SIZE+4] = (unsigned char)(crc_value);     //低八位数据
+
+                /* 发送133字节数据 */
+                write_number = write( fd, frame_data, XMODEM_DATA_SIZE + 5);//向串口写一个包数据,即133字节数据
+                printf("."); //ADD: process
+                fflush(stdout);
+                //printf("waiting for next ACK... \n......\n");
+
+                GET_TIME();
+                while(1)
+                {
+                    CHK_TIME1();
+                    if(select_read(fd,1) > 0)
+                        usleep(10000);
+                    else
+                        continue;
+
+                    //read(fd,&ack_id,1);
+                    deal_read(fd,&ack_id,1);
+                    break;
+                }
+
+                if(ack_id == XMODEM_ACK) {
+                    //printf("ACK Ok!!Ready sending next pack!\n");
+                    ;
+                }
+                else
+                {
+                    printf("ACK Error!\n");
+                    printf("0x%02X\n",ack_id);
+                    //printf("pack_counter = %d\n", pack_counter);
+                }
+            }
+
+            else  // 文件发送完成
+            {
+                ack_id = XMODEM_EOT;
+                complete = 1;
+                printf("Complete ACK\n");
+
+                GET_TIME();
+                while(ack_id != XMODEM_ACK)
+                {
+                    CHK_TIME1();
+                    ack_id = XMODEM_EOT;
+                    write_number = write(fd,&ack_id,1);
+                    while((deal_read(fd, &ack_id, 1)) <= 0);
+                }
+                printf("Send file successful!!!\n");
+                fclose(datafile);
+                datafile = NULL;
+            }
+            break;
+
+        case XMODEM_NAK:
+            if( retry_num++ > 10)
+            {
+                printf("Retry too many times,Quit!\n");
+                complete = 1;
+            }
+            else //重试,发送
+            {
+                write_number = write(fd, frame_data, XMODEM_DATA_SIZE + 5);
+                printf("Retry for ACK,%d,%d...", pack_counter, write_number);
+
+                GET_TIME();
+                while(1)
+                {
+                    CHK_TIME1();
+                    if(select_read(fd,1) > 0)
+                        usleep(100);
+                    else
+                        continue;
+
+                    //read(fd,&ack_id,1);
+                    deal_read(fd,&ack_id,1);
+                    break;
+                }
+
+                if( ack_id == XMODEM_ACK )
+                    printf("OK\n");
+                else
+                    printf("Error!\n");
+            }
+            break;
+        default:
+            printf("Fatal Error! %d\n", ack_id);
+            complete = 1;
+            return -1;
+            break;
+        }
+    }
+
+    if( datafile != NULL )
+        fclose(datafile);
+
+    return 0;
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/lynq-gnss-update/lynq-gnss-update.bb b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/lynq-gnss-update/lynq-gnss-update.bb
new file mode 100755
index 0000000..9ada3c1
--- /dev/null
+++ b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/lynq-gnss-update/lynq-gnss-update.bb
@@ -0,0 +1,33 @@
+# Package summary

+SUMMARY = "lynq-gnss-update"

+# License, for example MIT

+LICENSE = "MIT"

+# License checksum file is always required

+LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"

+

+SRC_URI = " file://lynq-gnss-update.cpp"

+

+SRC-DIR = "${S}/../lynq-gnss-update"

+TARGET_CC_ARCH += "${LDFLAGS}"

+

+#Parameters passed to do_compile()

+EXTRA_OEMAKE = "'TARGET_PLATFORM = ${TARGET_PLATFORM}'\"

+EXTRA_OEMAKE += "'MOBILETEK_RIL_CFG = ${MOBILETEK_RIL_CFG}'"

+

+LOCAL_C_INCLUDES = "-I."

+

+LOCAL_LIBS = "-L. -ldl -lstdc++"

+

+#INHIBIT_PACKAGE_STRIP = "1"

+S = "${WORKDIR}"

+

+#INHIBIT_PACKAGE_STRIP = "1"

+do_compile () {

+

+	${CXX} -Wall lynq-gnss-update.cpp ${LOCAL_LIBS} ${LOCAL_C_INCLUDES} -o lynq-gnss-update

+}

+

+do_install() {

+	install -d ${D}${bindir}/

+	install -m 0755 ${S}/lynq-gnss-update ${D}${bindir}/

+}
\ No newline at end of file
diff --git a/cap/zx297520v3/sources/meta-zxic/recipes-kernel/linux/files/zx297520v3/linux-5_10-vehicle_dc_ref-normal-defconfig b/cap/zx297520v3/sources/meta-zxic/recipes-kernel/linux/files/zx297520v3/linux-5_10-vehicle_dc_ref-normal-defconfig
index b4b886e..6c84688 100755
--- a/cap/zx297520v3/sources/meta-zxic/recipes-kernel/linux/files/zx297520v3/linux-5_10-vehicle_dc_ref-normal-defconfig
+++ b/cap/zx297520v3/sources/meta-zxic/recipes-kernel/linux/files/zx297520v3/linux-5_10-vehicle_dc_ref-normal-defconfig
@@ -1975,24 +1975,22 @@
 # CONFIG_SND_SOC_ZX29_TI3100 is not set
 #dongyu@modify for codec start
 # CONFIG_SND_SOC_ZX29_NAU8810 is not set
-# CONFIG_SND_SOC_ZX29_TI3104 is not set
+CONFIG_SND_SOC_ZX29_TI3104=y
 # CONFIG_SND_SOC_ZX29_ES8374 is not set
 # CONFIG_SND_SOC_ZX29_ES8312 is not set
 # CONFIG_SND_SOC_ZX29_AK4940 is not set
 # CONFIG_SND_SOC_ZX29_MAX9867 is not set
 # CONFIG_SND_SOC_ZX29_ES8311 is not set
-CONFIG_SND_SOC_ZX29_ES8311=y
 CONFIG_SND_SOC_ZX_VOICE=y
 CONFIG_SND_SOC_ZX297520V3=y
 CONFIG_SND_SOC_ZX_I2S=y
 CONFIG_SND_SOC_ZX_PCM=y
 # CONFIG_SND_SOC_ZX_TDM is not set
 # CONFIG_SND_SOC_TLV320AIC31XX is not set
-CONFIG_SND_SOC_NAU8810=y
-# CONFIG_SND_SOC_TLV320AIC3X is not set
+# CONFIG_SND_SOC_NAU8810 is not set
+CONFIG_SND_SOC_TLV320AIC3X=y
 # CONFIG_SND_SOC_MAX9867 is not set
 # CONFIG_SND_SOC_ES8311 is not set
-CONFIG_SND_SOC_ES8311=y
 #dongyu@modify for codec end
 CONFIG_SND_EXTRA_CTRL=y
 CONFIG_USE_TOP_I2S0=y
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-at-common/LICENSE b/cap/zx297520v3/src/lynq/lib/liblynq-at-common/LICENSE
new file mode 100755
index 0000000..382fc78
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-at-common/LICENSE
@@ -0,0 +1,31 @@
+Copyright Statement:

+

+This software/firmware and related documentation ("Mobiletek Software") are

+protected under relevant copyright laws. The information contained herein is

+confidential and proprietary to Mobiletek Inc. and/or its licensors. Without

+the prior written permission of Mobiletek inc. and/or its licensors, any

+reproduction, modification, use or disclosure of Mobiletek Software, and

+information contained herein, in whole or in part, shall be strictly

+prohibited.

+

+Mobiletek Inc. (C) 2015. All rights reserved.

+

+BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES

+THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("Mobiletek SOFTWARE")

+RECEIVED FROM Mobiletek AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER

+ON AN "AS-IS" BASIS ONLY. Mobiletek EXPRESSLY DISCLAIMS ANY AND ALL

+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED

+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR

+NONINFRINGEMENT. NEITHER DOES Mobiletek PROVIDE ANY WARRANTY WHATSOEVER WITH

+RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,

+INCORPORATED IN, OR SUPPLIED WITH THE Mobiletek SOFTWARE, AND RECEIVER AGREES

+TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.

+RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO

+OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN Mobiletek

+SOFTWARE. Mobiletek SHALL ALSO NOT BE RESPONSIBLE FOR ANY Mobiletek SOFTWARE

+RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR

+STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND Mobiletek'S

+ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE Mobiletek SOFTWARE

+RELEASED HEREUNDER WILL BE, AT Mobiletek'S OPTION, TO REVISE OR REPLACE THE

+Mobiletek SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE

+CHARGE PAID BY RECEIVER TO Mobiletek FOR SUCH Mobiletek SOFTWARE AT ISSUE.
\ No newline at end of file
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-at-common/include/liblynq-at-common.h b/cap/zx297520v3/src/lynq/lib/liblynq-at-common/include/liblynq-at-common.h
new file mode 100755
index 0000000..5ca8ca8
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-at-common/include/liblynq-at-common.h
@@ -0,0 +1,14 @@
+#ifndef LIBLYNQ_AT_COMMON_H
+#define LIBLYNQ_AT_COMMON_H 1
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void ( *lynq_atsvc_incb )( const char *input,const int length);
+typedef void ( *lynq_atsvc_outcb )(char *output, int out_max_size, int mode);
+lynq_atsvc_incb lynq_register_at_common(lynq_atsvc_outcb out_cb);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
\ No newline at end of file
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-at-common/liblynq-at-common.cpp b/cap/zx297520v3/src/lynq/lib/liblynq-at-common/liblynq-at-common.cpp
new file mode 100755
index 0000000..cacdf2d
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-at-common/liblynq-at-common.cpp
@@ -0,0 +1,105 @@
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <error.h>
+#include <string.h>
+#include <errno.h>
+#include <liblog/lynq_deflog.h>
+#include "include/liblynq-at-common.h"
+
+DEFINE_LYNQ_LIB_LOG(LYNQ_AT_COMMON)
+
+lynq_atsvc_outcb handle_output;
+typedef struct
+{
+    char *cmd;
+    void (*func)(char *input);
+}Command;
+
+enum
+{
+    Response = 0,
+    Urc
+};
+
+void lynq_response_ok()
+{
+    char *str = "OK\n";
+    handle_output(str, strlen(str), Response);
+}
+
+void lynq_response_error(int error_code)
+{
+    char str[32] = {0};
+    sprintf(str, "+CME ERROR: %d\n", error_code);
+    handle_output(str, strlen(str), Response);
+}
+
+void lynq_handle_version()
+{
+    char buf[64] = {0};
+    sprintf(buf,"%s\n",LYNQ_SW_INSIDE_VERSION);
+    handle_output(buf, strlen(buf), Response);
+    lynq_response_ok();
+    return;
+}
+
+static Command commands[] = 
+{
+    {"CGIR",lynq_handle_version},
+    {NULL, NULL}
+};
+
+Command* find_command(char *input)
+{
+    ALOGD("function %s line %d input %s\n", __FUNCTION__, __LINE__, input);
+    int i;
+    int ret = -1;
+    for (i = 0; commands[i].cmd; i++)
+    {
+        ret = strncmp(input, commands[i].cmd, strlen(commands[i].cmd));
+        if(ret == 0)
+        {
+            ALOGD("function %s line %d find input %s commands[i].cmd %s  strlen %d ret %d\n", __FUNCTION__, __LINE__, input, commands[i].cmd, strlen(commands[i].cmd), ret);
+            return (&commands[i]);
+        }
+    }
+    ALOGD("function %s line %d not find ret %d \n", __FUNCTION__, __LINE__, ret);
+    return ((Command *)NULL);
+}
+
+void lynq_at_common_cb(char *input, int input_max_size)
+{
+    if(handle_output != NULL)
+    {
+        ALOGD("function %s line %d input %s\n", __FUNCTION__, __LINE__, input);
+        if(input != NULL)
+        {
+            char *handle_string = input + strlen("AT+");
+            ALOGE("HJAHS:%s\n",handle_string);
+            if(!strlen(handle_string))
+            {
+                ALOGE("function %s line %d strlen %d\n", __FUNCTION__, __LINE__, strlen(handle_string));
+                return;
+            }
+            ALOGD("function %s line %d  handle_string %s\n", __FUNCTION__, __LINE__, handle_string);
+            Command *cmd = find_command(handle_string);
+            if(cmd != NULL)
+            {
+                ALOGD("function %s line %d\n", __FUNCTION__, __LINE__);
+                (*(cmd->func))(handle_string);
+                return;
+            }
+        }
+    }
+}
+
+lynq_atsvc_incb lynq_register_at_common(lynq_atsvc_outcb out_cb)
+{
+    if(out_cb != NULL)
+    {
+        handle_output = out_cb;
+        ALOGD("function %s line %d\n", __FUNCTION__, __LINE__);
+        return lynq_at_common_cb;
+    }
+}
\ No newline at end of file
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-at-common/makefile b/cap/zx297520v3/src/lynq/lib/liblynq-at-common/makefile
new file mode 100755
index 0000000..2cfedec
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-at-common/makefile
@@ -0,0 +1,76 @@
+

+SHELL = /bin/sh

+RM = rm -f

+

+LOCAL_CFLAGS := -Wall \

+                -std=gnu++14 \

+                -g -Os \

+                -flto \

+                -fPIC \

+                -fpermissive \

+

+ifeq ($(strip $(TARGET_PLATFORM)), T106)

+LOCAL_CFLAGS += -DBINDER_IPC_32BIT=1 -DHAVE_ENDIAN_H -DHAVE_PTHREADS -DHAVE_SYS_UIO_H -DHAVE_POSIX_FILEMAP -DHAVE_STRLCPY -DHAVE_PRCTL -DHAVE_MEMSET16 -DHAVE_MEMSET32 -DANDROID_SMP=0

+endif

+ifeq ($(strip $(TARGET_PLATFORM)), T106)

+LOCAL_CFLAGS += -DMOBILETEK_TARGET_PLATFORM_T106

+LOCAL_CFLAGS += -DLYNQ_SW_INSIDE_VERSION=\"$(LYNQ_CONFIG_VERSION)\"

+LOCAL_CFLAGS += -DLYNQ_SW_VERSION=\"$(LYNQ_CONFIG_SW_VERSION)\"

+endif

+$(warning ################# lynq at common demo ROOT: $(ROOT),includedir:$(includedir))

+LOCAL_PATH   = .

+

+LOCAL_C_INCLUDES = \

+  -I. \

+  -I$(LOCAL_PATH)/include/ \

+  -I$(ROOT)$(includedir)/logger \

+  -I$(ROOT)$(includedir)/liblog \

+

+

+LOCAL_LIBS := \

+    -L. \

+    -ldl \

+    -lstdc++ \

+    -llog \

+    -lcutils \

+    -lutils \

+    -lbinder \

+    -lpthread \

+    -llynq-log \

+

+

+SOURCES = $(wildcard *.cpp)

+

+EXECUTABLE = liblynq-at-common.so

+

+OBJECTS=$(SOURCES:.cpp=.o)

+

+.PHONY: build clean install pack_rootfs

+

+all: build

+$(EXECUTABLE): $(OBJECTS)

+	$(CXX) -shared -Wl,--no-undefined $(OBJECTS) $(LOCAL_LIBS) $(LOCAL_CFLAGS) $(LOCAL_C_INCLUDES) -o $@

+

+%.o : %.cpp

+	$(CXX) $(LOCAL_C_INCLUDES) $(LOCAL_CFLAGS) $(LOCAL_LIBS) -o $@ -c $<

+

+build:  $(EXECUTABLE)

+	$(warning ########## build $(EXECUTABLE)  ##########)

+

+install:

+	mkdir -p $(ROOT)$(base_libdir)/

+	install $(EXECUTABLE) $(ROOT)$(base_libdir)/

+	mkdir -p $(ROOT)$(includedir)/$(NAME)/sdk

+

+pack_rootfs:

+	mkdir -p $(PACK_INITRAMFS_TO)$(base_libdir)/

+	cp -af $(EXECUTABLE) $(PACK_INITRAMFS_TO)$(base_libdir)/

+	$(CROSS)strip $(PACK_INITRAMFS_TO)$(base_libdir)/$(EXECUTABLE)

+	mkdir -p $(PACK_TO)$(base_libdir)/

+	cp -af $(EXECUTABLE) $(PACK_TO)$(base_libdir)/

+	$(CROSS)strip $(PACK_TO)$(base_libdir)/$(EXECUTABLE)

+	

+.PHONY: clean

+clean:

+	$(RM) $(OBJECTS) $(EXECUTABLE)

+	-find . -name "*.o" -delete

diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-at-factory/liblynq-at-factory.cpp b/cap/zx297520v3/src/lynq/lib/liblynq-at-factory/liblynq-at-factory.cpp
index ac73582..b82cb42 100755
--- a/cap/zx297520v3/src/lynq/lib/liblynq-at-factory/liblynq-at-factory.cpp
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-at-factory/liblynq-at-factory.cpp
@@ -3,6 +3,7 @@
 #include <stdlib.h>

 #include <sys/socket.h>

 #include <sys/time.h>

+#include <unistd.h>

 #include <error.h>

 #include <string.h>

 #include <netinet/in.h>

@@ -14,19 +15,16 @@
 #include <arpa/inet.h>

 #include <net/if.h>

 #include <errno.h>

-#include <log/log.h>

 #include <liblog/lynq_deflog.h>

 #include "include/libat/lynq_at_factory.h"

 

 #define FACTORY_STRING "AT+LYNQFACTORY="

 #define USER_LOG_TAG "AT_FACTORY"

-DEFINE_LYNQ_LIB_LOG(LYNQ_POWERALARM)

+DEFINE_LYNQ_LIB_LOG(LYNQ_AT_FACTORY)

 

 

 #undef LOG_TAG

 #define LOG_TAG "AT_FACTORY"

-#define MTK 0

-#define ZXIC 1

 

 lynq_atsvc_outcb handle_output;

 

@@ -44,14 +42,14 @@
 

 void lynq_response_ok()

 {

-    char *str = "OK";

+    char *str = "OK\n";

     handle_output(str, strlen(str), Response);

 }

 

 void lynq_response_error(int error_code)

 {

     char str[32] = {0};

-    sprintf(str, "+CME ERROR: %d", error_code);

+    sprintf(str, "+CME ERROR: %d\n", error_code);

     handle_output(str, strlen(str), Response);

 }

 

@@ -64,11 +62,11 @@
     char flag[64] = {0};

 

     #ifdef MOBILETEK_TARGET_PLATFORM_T106

-    if(lynq_adc_num == 1)

+    if(lynq_adc_num == 0)

     {

         sprintf(lynq_adc_dev,"cat /sys/kernel/debug/pmu_zx29/adc1");

     }

-    else if(lynq_adc_num == 2)

+    else if(lynq_adc_num == 1)

     {

         sprintf(lynq_adc_dev,"cat /sys/kernel/debug/pmu_zx29/adc2");

     }

@@ -148,8 +146,7 @@
     int size = 0;

     char res[64] = {0};

     int greep = input[0] - '0';

-    sprintf(res,"the greep:%d\n",greep);//The first digit represents grouping

-    handle_output(res, strlen(res), Response);

+    ALOGD(res,"the greep:%d\n",greep);//The first digit represents grouping

 

     for (int i = 1; input[i] != '\0'; i++)

     {

@@ -202,7 +199,7 @@
     int count = 0;

     if((fp = fopen(GPIO_FILE, "r")) == NULL)

     {

-        RLOGD("open %s error!\n", GPIO_FILE);

+        ALOGE("open %s error!\n", GPIO_FILE);

         return -1;

     }

     while (!feof(fp))

@@ -214,16 +211,16 @@
             strcpy(platform, strstr(StrLine, "platform:") + sizeof("platform:") - 1);

             if(!strcmp(platform,"T106"))

             {

-                RLOGD("platform:error\n");

+                ALOGD("platform:error\n");

                 return -1;

             }

-            RLOGD("platform:%s\n",platform);

+            ALOGD("platform:%s\n",platform);

         }

         

         else if(strstr(StrLine, "total:") != NULL)

         {

             strcpy(total, strstr(StrLine, "total:") + sizeof("total:") - 1);

-            RLOGD("total:%s\n",total);

+            ALOGD("total:%s\n",total);

         }

         

         else if((strstr(StrLine, "gpio:") != NULL))

@@ -257,14 +254,14 @@
         ret = sc_gpio_uninit(test_gpio_handle[50]);

         if(ret)

         {

-            RLOGD("uninit 50 fail\n");

+            ALOGE("uninit 50 fail\n");

             return -1;

         }

     }

     test_gpio_handle[50] = sc_gpio_init(50, 0, 0, 0);

     if(test_gpio_handle[50] == NULL)

     {

-        RLOGD("init 50 fail\n");

+        ALOGE("init 50 fail\n");

         return -1;

     }

     for(int m = 0; m < total_length; m++)

@@ -274,14 +271,14 @@
             ret = sc_gpio_uninit(test_gpio_handle[lynq_gpio_arr[m]]);

             if(ret)

             {

-                RLOGD("uninit%d fail\n",lynq_gpio_arr[m]);

+                ALOGE("uninit%d fail\n",lynq_gpio_arr[m]);

                 return -1;

             }

         }

         test_gpio_handle[lynq_gpio_arr[m]] = sc_gpio_init(lynq_gpio_arr[m], 1, status, 0);

         if(test_gpio_handle[lynq_gpio_arr[m]] == NULL)

         {

-            RLOGD("init%d fail\n",lynq_gpio_arr[m]);

+            ALOGE("init%d fail\n",lynq_gpio_arr[m]);

             return -1;

         }

     }

@@ -304,16 +301,18 @@
     if(ret)

     {

         return -1;

-        RLOGD("uninit 50 fail\n");

+        ALOGE("uninit 50 fail\n");

     }

+    test_gpio_handle[50] = NULL;

     for(int m = 0; m < total_length; m++)

     {

         ret = sc_gpio_uninit(test_gpio_handle[lynq_gpio_total_arr[m]]);

         if(ret)

         {

             return -1;

-            RLOGD("uninit%d fail\n",lynq_gpio_total_arr[m]);

+            ALOGE("uninit%d fail\n",lynq_gpio_total_arr[m]);

         }

+        test_gpio_handle[lynq_gpio_total_arr[m]] = NULL;

     }

     return 0;

 }

@@ -336,18 +335,17 @@
 

     if((total_length = load_gpio(lynq_gpio_total_arr)) < 0)

     {

-        RLOGD("Don't have this platform gpio configure\n");

+        ALOGE("Don't have this platform gpio configure\n");

         return;

     }

-    RLOGD("start function %s line %d input %s\n", __FUNCTION__, __LINE__, input);

-    handle_output(input, strlen(input), Response);

+    ALOGD("start function %s line %d input %s\n", __FUNCTION__, __LINE__, input);

     input = input + strlen("gpio");

     if((valid_length = lynq_gpio_analysis(input, lynq_gpio_arr, lynq_gpio_total_arr, total_length)) < 0)

     {

         lynq_response_error(100);

         return;

     }

-    RLOGD("The Valid count:%d\n",valid_length);

+    ALOGE("The Valid count:%d\n",valid_length);

     for(i=0; i < sizeof(lynq_gpio_arr)/sizeof(int); i++)

     {

         for(j=0;j<3;j++)

@@ -362,21 +360,21 @@
                 ret = set_all_gpio_status_and_check(lynq_gpio_total_arr, 0, total_length);

                 if (ret == 1)

                 {

-                    RLOGD("can't pull up or pull down gpio-50\n");

+                    ALOGE("can't pull up or pull down gpio-50\n");

                     continue;

                 }

                 else if(ret == 0)

                 {

-                    RLOGD("all gpio can pull up or pull dpwn\n");

+                    ALOGE("all gpio can pull up or pull dpwn\n");

                     need_int = 0;

                 }

                 else if(ret == -1)

                 {

-                    RLOGD("gpio init or uninit fail\n");

+                    ALOGE("gpio init or uninit fail\n");

                     lynq_response_error(100);

                     return;

                 }

-                RLOGD("finsh configure function %s line %d input %s\n", __FUNCTION__, __LINE__, input);  

+                ALOGD("finsh configure function %s line %d input %s\n", __FUNCTION__, __LINE__, input);  

             }

 

             lynq_gpio_low = 0;

@@ -388,18 +386,18 @@
                 ret = sc_gpio_value_get(test_gpio_handle[50], &value);

                 if(ret)

                 {

-                    RLOGD("sc_gpio_value_get");

+                    ALOGD("sc_gpio_value_get");

                 }

                 if(value == 1)

                 {

-                    RLOGD("high function %s line %d input %s\n", __FUNCTION__, __LINE__, input);

+                    ALOGD("high function %s line %d input %s\n", __FUNCTION__, __LINE__, input);

                     lynq_gpio_high = 1;

                     lynq_gpio_test_env_error = 0;

                     break;

                 }

                 else

                 {

-                    RLOGD("high function %s line %d input %s num %d\n", __FUNCTION__, __LINE__, input,lynq_gpio_arr[i]);

+                    ALOGD("high function %s line %d input %s num %d\n", __FUNCTION__, __LINE__, input,lynq_gpio_arr[i]);

                     if(i == 0 && j == 0)

                     {

                         lynq_gpio_test_env_error = set_all_gpio_status_and_check(lynq_gpio_total_arr, 1, total_length) == 0 ? 0 : 1;

@@ -411,30 +409,30 @@
             ret = sc_gpio_value_set(test_gpio_handle[lynq_gpio_arr[i]], 0);

             if(ret)

                 {

-                    RLOGD("sc_gpio_value_set gpio%d fail\n",lynq_gpio_arr[i]);

+                    ALOGD("sc_gpio_value_set gpio%d fail\n",lynq_gpio_arr[i]);

                 }

             ret = sc_gpio_value_get(test_gpio_handle[50], &value);

             if(ret)

                 {

-                    RLOGD("sc_gpio_value_get fail\n");

+                    ALOGE("sc_gpio_value_get fail\n");

                 }

             if(value == 0)

             {

-                RLOGD("*low function %s line %d input %s\n", __FUNCTION__, __LINE__, input);

+                ALOGD("*low function %s line %d input %s\n", __FUNCTION__, __LINE__, input);

                 lynq_gpio_low = 1;

             }

             else

             {

-                RLOGD("low function fail %s line %d input %s num %d\n", __FUNCTION__, __LINE__, input,lynq_gpio_arr[i]);

+                ALOGE("low function fail %s line %d input %s num %d\n", __FUNCTION__, __LINE__, input,lynq_gpio_arr[i]);

             }

             bzero(lynq_show_gpio_state, 64);

             if((lynq_gpio_low != 1) || (lynq_gpio_high != 1))

             {

-                RLOGD("fail function %s line %d input %s\n", __FUNCTION__, __LINE__, input);

+                ALOGE("fail function %s line %d input %s\n", __FUNCTION__, __LINE__, input);

             }

             else

             {

-                RLOGD("success function %s line %d input %s\n", __FUNCTION__, __LINE__, input);

+                ALOGD("success function %s line %d input %s\n", __FUNCTION__, __LINE__, input);

                 sprintf(lynq_show_gpio_state,"gpio%d\n",lynq_gpio_arr[i]);

                 handle_output(lynq_show_gpio_state, strlen(lynq_show_gpio_state), Response);

                 break; // do not retry when pass

@@ -455,24 +453,24 @@
 

     if(lynq_gpio_test_env_error == 1)

     {

-        RLOGD("tool error\n");

+        ALOGE("tool error\n");

         handle_output("tool error\n", strlen("tool error\n"), Response);

     }

 

     if(lynq_gpio_beta_state == 1)

     {

-        RLOGD("total success function %s line %d input %s\n", __FUNCTION__, __LINE__, input);

+        ALOGD("total success function %s line %d input %s\n", __FUNCTION__, __LINE__, input);

         lynq_response_ok();

     }

     else

     {

-        RLOGD("total fail function %s line %d input %s\n", __FUNCTION__, __LINE__, input);

+        ALOGE("total fail function %s line %d input %s\n", __FUNCTION__, __LINE__, input);

         lynq_response_error(100);

     }

     ret = all_gpio_uninit(total_length, lynq_gpio_total_arr);

     if(ret)

     {

-        RLOGD("all_gpio_uninit fail\n");

+        ALOGD("all_gpio_uninit fail\n");

         lynq_response_error(100);

         return;

     }

@@ -498,13 +496,13 @@
         if(difftime(time_end,time_start)>2)

         {

             sprintf(reason_buf,"%d:time_out\n",count);

-            RLOGD(reason_buf, strlen(reason_buf), Response);

+            ALOGD(reason_buf, strlen(reason_buf), Response);

             return -1;

         }

         if(ret<0)

         {

             sprintf(reason_buf,"%d:recv_fail\n",count);

-            RLOGD(reason_buf, strlen(reason_buf), Response);

+            ALOGD(reason_buf, strlen(reason_buf), Response);

             return -1;

         }

 

@@ -514,34 +512,34 @@
         }

         // Analyzing Ethernet frame headers

         struct ethhdr *eth_header = (struct ethhdr *)buf_recv;

-        RLOGD("Source MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", eth_header->h_source[0], eth_header->h_source[1], eth_header->h_source[2], eth_header->h_source[3], eth_header->h_source[4], eth_header->h_source[5]);

-        RLOGD("Destination MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", eth_header->h_dest[0], eth_header->h_dest[1], eth_header->h_dest[2], eth_header->h_dest[3], eth_header->h_dest[4], eth_header->h_dest[5]);

-        RLOGD("Ethernet Type: %04X\n", ntohs(eth_header->h_proto));

+        ALOGD("Source MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", eth_header->h_source[0], eth_header->h_source[1], eth_header->h_source[2], eth_header->h_source[3], eth_header->h_source[4], eth_header->h_source[5]);

+        ALOGD("Destination MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", eth_header->h_dest[0], eth_header->h_dest[1], eth_header->h_dest[2], eth_header->h_dest[3], eth_header->h_dest[4], eth_header->h_dest[5]);

+        ALOGD("Ethernet Type: %04X\n", ntohs(eth_header->h_proto));

         // Analyzing IP headers

         struct iphdr *ip_header = (struct iphdr *)(buf_recv + sizeof(struct ethhdr));

-        RLOGD("Source IP: %s\n", inet_ntoa(*(struct in_addr *)&ip_header->saddr));

-        RLOGD("Destination IP: %s\n", inet_ntoa(*(struct in_addr *)&ip_header->daddr));

-        RLOGD("Protocol: %d\n", ip_header->protocol);

+        ALOGD("Source IP: %s\n", inet_ntoa(*(struct in_addr *)&ip_header->saddr));

+        ALOGD("Destination IP: %s\n", inet_ntoa(*(struct in_addr *)&ip_header->daddr));

+        ALOGD("Protocol: %d\n", ip_header->protocol);

         // Analyzing UDP headers

         struct udphdr *udp_header = (struct udphdr *)(buf_recv + sizeof(struct iphdr) + sizeof(struct ethhdr));

-        RLOGD("Source Port: %d\n", ntohs(udp_header->source));

-        RLOGD("Destination Port: %d\n", ntohs(udp_header->dest));

-        RLOGD("UDP Length: %d\n", ntohs(udp_header->len));

+        ALOGD("Source Port: %d\n", ntohs(udp_header->source));

+        ALOGD("Destination Port: %d\n", ntohs(udp_header->dest));

+        ALOGD("UDP Length: %d\n", ntohs(udp_header->len));

         // Compare data

         buf_cmp = buf_recv + sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr);

         if(memcmp(buf_send, buf_cmp, send_len))

         {

-            RLOGD("rec data fail and retry!!\n");

+            ALOGD("rec data fail and retry!!\n");

             continue;

         }

         // raw_socket will received data twice

         else

         {

             corrent_cont++;

-            RLOGD("rec data success and again!!\n");

+            ALOGD("rec data success and again!!\n");

             if(corrent_cont == 2)

             {

-                RLOGD("cammpare OK!!\n");

+                ALOGD("cammpare OK!!\n");

                 return 0;

             }

             continue;

@@ -723,7 +721,7 @@
     //  Received correctly 120 times

     if(check_ok_count >= 120)

     {

-        RLOGD("rgmii OK!!\n");

+        ALOGD("rgmii OK!!\n");

         lynq_response_ok();

     }

     else

@@ -760,7 +758,7 @@
 

 Command* find_command(char *input)

 {

-    RLOGD("function %s line %d input %s\n", __FUNCTION__, __LINE__, input);

+    ALOGD("function %s line %d input %s\n", __FUNCTION__, __LINE__, input);

     int i;

     int ret = -1;

     for (i = 0; commands[i].cmd; i++)

@@ -768,11 +766,11 @@
         ret = strncmp(input, commands[i].cmd, strlen(commands[i].cmd));

         if(ret == 0)

         {

-            RLOGD("function %s line %d find input %s commands[i].cmd %s  strlen %d ret %d\n", __FUNCTION__, __LINE__, input, commands[i].cmd, strlen(commands[i].cmd), ret);

+            ALOGD("function %s line %d find input %s commands[i].cmd %s  strlen %d ret %d\n", __FUNCTION__, __LINE__, input, commands[i].cmd, strlen(commands[i].cmd), ret);

             return (&commands[i]);

         }

     }

-    RLOGD("function %s line %d not find ret %d \n", __FUNCTION__, __LINE__, ret);

+    ALOGD("function %s line %d not find ret %d \n", __FUNCTION__, __LINE__, ret);

     return ((Command *)NULL);

 }

 

@@ -780,20 +778,20 @@
 {

     if(handle_output != NULL)

     {

-        RLOGD("function %s line %d input %s\n", __FUNCTION__, __LINE__, input);

+        ALOGD("function %s line %d input %s\n", __FUNCTION__, __LINE__, input);

         if(input != NULL)

         {

             char *handle_string = input + strlen(FACTORY_STRING);

             if(!strlen(handle_string))

             {

-                RLOGD("function %s line %d strlen %d\n", __FUNCTION__, __LINE__, strlen(handle_string));

+                ALOGD("function %s line %d strlen %d\n", __FUNCTION__, __LINE__, strlen(handle_string));

                 return;

             }

-            RLOGD("function %s line %d  handle_string %s\n", __FUNCTION__, __LINE__, handle_string);

+            ALOGD("function %s line %d  handle_string %s\n", __FUNCTION__, __LINE__, handle_string);

             Command *cmd = find_command(handle_string);

             if(cmd != NULL)

             {

-                RLOGD("function %s line %d\n", __FUNCTION__, __LINE__);

+                ALOGD("function %s line %d\n", __FUNCTION__, __LINE__);

                 (*(cmd->func))(handle_string);

                 return;

             }

@@ -806,7 +804,7 @@
     if(out_cb != NULL)

     {

         handle_output = out_cb;

-        RLOGD("function %s line %d\n", __FUNCTION__, __LINE__);

+        ALOGD("function %s line %d\n", __FUNCTION__, __LINE__);

         return lynq_at_factory_cb;

     }

 }

diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/UC6228CI-R3.2.10.100Build8019_mfg.pkg b/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/UC6228CI-R3.2.10.100Build8019_mfg.pkg
new file mode 100755
index 0000000..5310f03
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/UC6228CI-R3.2.10.100Build8019_mfg.pkg
Binary files differ
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/agps.conf b/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/agps.conf
new file mode 100755
index 0000000..71ed385
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/agps.conf
@@ -0,0 +1,2 @@
+ ID1: IcoeTempID1Expire20231031
+ Base 64 PW: YVoyWXNXcWp0RFRqVXlVeQ==
\ No newline at end of file
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/bootloader_r3.0.0_build6773_uartboot_921600.pkg b/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/bootloader_r3.0.0_build6773_uartboot_921600.pkg
new file mode 100755
index 0000000..3cfd1fb
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/bootloader_r3.0.0_build6773_uartboot_921600.pkg
Binary files differ
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/include/lynq_qser_gnss.h b/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/include/lynq_qser_gnss.h
index 6c6c051..1fe5ab3 100755
--- a/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/include/lynq_qser_gnss.h
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/include/lynq_qser_gnss.h
@@ -114,6 +114,9 @@
 int qser_Gnss_Stop(uint32_t h_gnss);
 int qser_Gnss_Delete_Aiding_Data(uint32_t h_gnss,DELETE_AIDING_DATA_TYPE_T flags);
 int qser_Gnss_InjectTime(uint32_t h_gnss,LYNQ_INJECT_TIME_INTO_T *time_info);
+int qser_firmware_update(uint32_t* ph_gnss);
+int qser_Gnss_injectEphemeris(uint32_t h_gnss);
+int qser_Gnss_download_tle();
 #ifdef __cplusplus
 }
 #endif
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/include/mbtk_gnss_internal.h b/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/include/mbtk_gnss_internal.h
index eb7002c..dfced9c 100755
--- a/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/include/mbtk_gnss_internal.h
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/include/mbtk_gnss_internal.h
@@ -302,7 +302,7 @@
 int mopen_gnss_set_nema_config(uint32 h_gnss, int mode);
 int mopen_gnss_download_tle(void);
 int mopen_gnss_injects_aidpos(uint32 h_gnss);
-int mopen_gnss_firmware_update(void);
+int mopen_gnss_firmware_update(uint32 ph_gnss);
 int mbtk_at_gnss_start_ttff(int type, int timeout_sec, int count);
 int lynq_gnss_send_cmd(uint32 h_gnss, const char *cmd, int cmd_len);
 int mopen_gnss_write(int fd, const char* buf, unsigned int buf_len);
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/include/mbtk_http.h b/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/include/mbtk_http.h
new file mode 100755
index 0000000..c1c6e9e
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/include/mbtk_http.h
@@ -0,0 +1,364 @@
+/*************************************************************
+Description:
+    MBTK HTTP Header file.
+Author:
+    LiuBin
+Date:
+    2020/4/29 17:25:55
+*************************************************************/
+#ifndef _MBTK_HTTP_2_H
+#define _MBTK_HTTP_2_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdio.h>
+#include "mbtk_type.h"
+//#include "mbtk_sock2.h"
+
+
+/*************************************************************
+    Constants and Macros
+*************************************************************/
+#define MBTK_HTTP_URI_MAX 512
+#define MBTK_HTTP_HOST_MAX 50
+#define MBTK_HTTP_URL_MAX (MBTK_HTTP_URI_MAX + MBTK_HTTP_HOST_MAX)
+#define MBTK_HTTP_PORT_DEF 80
+#define MBTK_HTTPS_PORT_DEF 443
+#define HTTP_HANDLE_MAX 3
+#define HTTP_SESSION_MAX 5
+#define HTTP_REQUEST_HEADER_MAX 30
+#define HTTP_RESPONSE_HEADER_MAX 30
+#define HTTP_CONTENT_LEN_MAX 1024
+#define HTTP_MSG_LEN_MAX 1024
+
+#define HTTP_IPC_MSG_PATH "/dev"
+#define HTTP_IPC_MSG_ID 'H'
+
+/*************************************************************
+    Definitions:enum,struct,union,class
+*************************************************************/
+typedef enum {
+    HTTP_VERSION_1_0 = 0,
+    HTTP_VERSION_1_1,
+    HTTP_VERSION_2,
+    HTTP_VERSION_3
+} mbtk_http_version_enum;
+
+typedef enum {
+    HTTP_OPTION_HEAD = 0,
+    HTTP_OPTION_GET,
+    HTTP_OPTION_POST,
+    HTTP_OPTION_PUT,
+    HTTP_OPTION_DELETE,
+    HTTP_OPTION_OPTIONS,
+    HTTP_OPTION_TRACE,
+    HTTP_OPTION_CONNECT,
+    HTTP_OPTION_LINK,
+    HTTP_OPTION_UNLINK
+} mbtk_http_option_enum;
+
+#if 0
+typedef enum {
+    HTTP_HEADER_GENERAL = 0,
+    HTTP_HEADER_REQUEST,
+    HTTP_HEADER_RESPONSE,
+    HTTP_HEADER_ENTITY,
+    HTTP_HEADER_OTHERS
+} mbtk_http_header_type_e;
+
+typedef enum {
+    // General field start.
+    HTTP_HEADER_INDEX_CACHE_CONTROL = 0,
+    HTTP_HEADER_INDEX_CONNECTION,
+    HTTP_HEADER_INDEX_DATE,
+    HTTP_HEADER_INDEX_PRAGMA,
+    HTTP_HEADER_INDEX_TRAILER,
+    HTTP_HEADER_INDEX_TRANSFER_ENCODING,
+    HTTP_HEADER_INDEX_UPGRADE,
+    HTTP_HEADER_INDEX_VIA,
+    HTTP_HEADER_INDEX_WARNING,
+    // General field end.
+    // Request field start.
+    HTTP_HEADER_INDEX_ACCEPT,
+    HTTP_HEADER_INDEX_ACCEPT_CHARSET,
+    HTTP_HEADER_INDEX_ACCEPT_ENCODING,
+    HTTP_HEADER_INDEX_ACCEPT_LANGUAGE,
+    HTTP_HEADER_INDEX_AUTHORIZATION,
+    HTTP_HEADER_INDEX_EXPECT,
+    HTTP_HEADER_INDEX_FROM,
+    HTTP_HEADER_INDEX_HOST,
+    HTTP_HEADER_INDEX_IF_MATCH,
+    HTTP_HEADER_INDEX_IF_MODIFIED_SINCE,
+    HTTP_HEADER_INDEX_IF_NONE_MATCH,
+    HTTP_HEADER_INDEX_IF_RANGE,
+    HTTP_HEADER_INDEX_IF_UNMODIFIED_SINCE,
+    HTTP_HEADER_INDEX_MAX_FORWARDS,
+    HTTP_HEADER_INDEX_PROXY_AUTHORIZATION,
+    HTTP_HEADER_INDEX_RANGE,
+    HTTP_HEADER_INDEX_REFERER,
+    HTTP_HEADER_INDEX_TE,
+    HTTP_HEADER_INDEX_USER_AGENT,
+    // Request field end.
+    // Response field start.
+    HTTP_HEADER_INDEX_ACCEPT_RANGES,
+    HTTP_HEADER_INDEX_AGE,
+    HTTP_HEADER_INDEX_ETAG,
+    HTTP_HEADER_INDEX_LOCATION,
+    HTTP_HEADER_INDEX_PROXY_AUTHENTICATE,
+    HTTP_HEADER_INDEX_RETRY_AFTER,
+    HTTP_HEADER_INDEX_SERVER,
+    HTTP_HEADER_INDEX_VARY,
+    HTTP_HEADER_INDEX_WWW_AUTHENTICATE,
+    // Response field end.
+    // Entity field start.
+    HTTP_HEADER_INDEX_ALLOW,
+    HTTP_HEADER_INDEX_CONTENT_ENCODING,
+    HTTP_HEADER_INDEX_CONTENT_LANGUAGE,
+    HTTP_HEADER_INDEX_CONTENT_LENGTH,
+    HTTP_HEADER_INDEX_CONTENT_LOCATION,
+    HTTP_HEADER_INDEX_CONTENT_MD5,
+    HTTP_HEADER_INDEX_CONTENT_RANGE,
+    HTTP_HEADER_INDEX_CONTENT_TYPE,
+    HTTP_HEADER_INDEX_EXPIRES,
+    HTTP_HEADER_INDEX_LAST_MODIFIED,
+    // Entity field end.
+    // Other field start.
+    HTTP_HEADER_INDEX_SET_COOKIE,
+    HTTP_HEADER_INDEX_COOKIE,
+    HTTP_HEADER_INDEX_X_FRAME_OPTIONS,
+    HTTP_HEADER_INDEX_X_XSS_PROTECTION,
+    HTTP_HEADER_INDEX_DNT,
+    HTTP_HEADER_INDEX_P3P
+    // Other field end.
+} mbtk_http_header_index_e;
+#endif
+
+typedef enum {
+    HTTP_SESSION_STATE_NON = 0,
+    HTTP_SESSION_STATE_CONN,
+    HTTP_SESSION_STATE_WRITE_HEADER,
+    HTTP_SESSION_STATE_WRITE_CONTENT,
+    HTTP_SESSION_STATE_WRITE_END,
+    HTTP_SESSION_STATE_READ_HEADER,
+    HTTP_SESSION_STATE_READ_CONTENT,
+    HTTP_SESSION_STATE_READ_END
+} http_session_state_e;
+
+typedef enum {
+    MBTK_HTTP_STATE_CODE_200 = 200,
+    MBTK_HTTP_STATE_CODE_204 = 204,
+    MBTK_HTTP_STATE_CODE_206 = 206,
+    MBTK_HTTP_STATE_CODE_301 = 301,
+    MBTK_HTTP_STATE_CODE_302 = 302,
+    MBTK_HTTP_STATE_CODE_303 = 303,
+    MBTK_HTTP_STATE_CODE_304 = 304,
+    MBTK_HTTP_STATE_CODE_307 = 307,
+    MBTK_HTTP_STATE_CODE_400 = 400,
+    MBTK_HTTP_STATE_CODE_401 = 401,
+    MBTK_HTTP_STATE_CODE_403 = 403,
+    MBTK_HTTP_STATE_CODE_404 = 404,
+    MBTK_HTTP_STATE_CODE_500 = 500,
+    MBTK_HTTP_STATE_CODE_503 = 503
+} mbtk_http_state_code_e;
+
+typedef enum {
+    MBTK_HTTP_DATA_NON = 0,
+    MBTK_HTTP_DATA_HEADER,
+    MBTK_HTTP_DATA_CONTENT,
+    MBTK_HTTP_DATA_COMPLETE
+} mbtk_http_data_type_enum;
+
+typedef void (*mbtk_http_data_callback_func)(
+    int session_id, mbtk_http_data_type_enum type,
+    void *data,int data_len);
+
+typedef struct mbtk_http_header {
+    char name[30];
+    char *value;
+} mbtk_http_header_t;
+
+typedef struct {
+    int header_cnt;
+    mbtk_http_header_t *req_h[HTTP_REQUEST_HEADER_MAX];
+
+    int content_len;    // Post content lenght
+    int content_len_send; // Post content lenght for send.
+    char *content;
+} mbtk_http_session_req_t;
+
+typedef struct {
+    int state_code;
+    mbtk_http_version_enum version;
+
+    int content_length;
+    bool is_chunked;
+    int header_cnt;
+    mbtk_http_header_t *rsp_h[HTTP_RESPONSE_HEADER_MAX];
+} mbtk_http_session_rsp_t;
+
+typedef struct mbtk_http_session{
+    int handle_id;
+    int id;
+    int sock_fd;
+    FILE *sock_file;
+    http_session_state_e state;
+    char host[MBTK_HTTP_HOST_MAX + 1];
+    mbtk_http_option_enum option;
+    mbtk_http_version_enum version;
+    char uri[MBTK_HTTP_URI_MAX + 1];
+    int port;
+    bool is_ssl;
+
+    mbtk_http_session_req_t req;
+    mbtk_http_session_rsp_t rsp;
+} mbtk_http_session_t;
+
+typedef struct mbtk_http_handle{
+    int id;
+    bool show_rsp_header;
+    mbtk_http_data_callback_func data_cb;
+
+    int session_cnt;
+    mbtk_http_session_t *session[HTTP_SESSION_MAX];
+} mbtk_http_handle_t;
+
+#if 0
+typedef enum {
+    HTTP_MSG_SESSION_CREATE_REQ,
+    HTTP_MSG_SESSION_CREATE_RSP,
+    HTTP_MSG_SESSION_FREE_REQ,
+    HTTP_MSG_SESSION_FREE_RSP,
+    HTTP_MSG_SESSION_URL_SET_REQ,
+    HTTP_MSG_SESSION_URL_SET_RSP,
+    HTTP_MSG_SESSION_HEAD_SET_REQ,
+    HTTP_MSG_SESSION_HEAD_SET_RSP,
+    HTTP_MSG_SESSION_CONTENT_SET_REQ,
+    HTTP_MSG_SESSION_CONTENT_SET_RSP,
+    HTTP_MSG_SESSION_ACTION_REQ,
+    HTTP_MSG_SESSION_ACTION_RSP,
+    HTTP_MSG_SESSION_CONTENT_SEND_REQ,
+    HTTP_MSG_SESSION_CONTENT_SEND_RSP
+} mbtk_http_msg_type_enum;
+#endif
+
+typedef enum {
+    HTTP_MSG_SESSION_CREATE,
+    HTTP_MSG_SESSION_FREE,
+    HTTP_MSG_SESSION_HEAD_SET,
+    HTTP_MSG_SESSION_CONTENT_SET,
+    HTTP_MSG_SESSION_ACTION,
+    HTTP_MSG_SESSION_CONTENT_SEND,
+    HTTP_MSG_HANDLE_EXIT
+} mbtk_http_msg_type_enum;
+
+typedef enum {
+    MBTK_HTTP_ERR_SUCCESS,
+    MBTK_HTTP_ERR_UNKNOWN
+} mbtk_http_err_enum;
+
+typedef struct {
+    mbtk_http_msg_type_enum type;
+    int int_arg1;
+    int int_arg2;
+    char str_small[30];
+    char str_large[HTTP_MSG_LEN_MAX];
+} mbtk_http_msg_req_t;
+
+typedef struct {
+    mbtk_http_msg_type_enum type;
+    mbtk_http_err_enum err;
+
+    mbtk_http_data_type_enum data_type;
+    int buff_len;
+    char buff[HTTP_MSG_LEN_MAX];
+} mbtk_http_msg_rsp_t;
+
+/*************************************************************
+    Extern variables
+*************************************************************/
+#if 0
+const mbtk_http_header_field_t mbtk_http_headers[] = {
+    {HTTP_HEADER_INDEX_CACHE_CONTROL, HTTP_HEADER_GENERAL,"Cache-Control"},
+    {HTTP_HEADER_INDEX_CONNECTION, HTTP_HEADER_GENERAL,"Connection"},
+    {HTTP_HEADER_INDEX_DATE, HTTP_HEADER_GENERAL,"Date"},
+    {HTTP_HEADER_INDEX_PRAGMA, HTTP_HEADER_GENERAL,"Pragma"},
+    {HTTP_HEADER_INDEX_TRAILER, HTTP_HEADER_GENERAL,"Trailer"},
+    {HTTP_HEADER_INDEX_TRANSFER_ENCODING, HTTP_HEADER_GENERAL,"Transfer-Encoding"},
+    {HTTP_HEADER_INDEX_UPGRADE, HTTP_HEADER_GENERAL,"Upgrade"},
+    {HTTP_HEADER_INDEX_VIA, HTTP_HEADER_GENERAL,"Via"},
+    {HTTP_HEADER_INDEX_WARNING, HTTP_HEADER_GENERAL,"Warning"},
+    {HTTP_HEADER_INDEX_ACCEPT, HTTP_HEADER_REQUEST,"Accept"},
+    {HTTP_HEADER_INDEX_ACCEPT_CHARSET, HTTP_HEADER_REQUEST,"Accept-Charset"},
+    {HTTP_HEADER_INDEX_ACCEPT_ENCODING, HTTP_HEADER_REQUEST,"Accept-Encoding"},
+    {HTTP_HEADER_INDEX_ACCEPT_LANGUAGE, HTTP_HEADER_REQUEST,"Accept-Language"},
+    {HTTP_HEADER_INDEX_AUTHORIZATION, HTTP_HEADER_REQUEST,"Authorization"},
+    {HTTP_HEADER_INDEX_EXPECT, HTTP_HEADER_REQUEST,"Expect"},
+    {HTTP_HEADER_INDEX_FROM, HTTP_HEADER_REQUEST,"From"},
+    {HTTP_HEADER_INDEX_HOST, HTTP_HEADER_REQUEST,"Host"},
+    {HTTP_HEADER_INDEX_IF_MATCH, HTTP_HEADER_REQUEST,"If-Match"},
+    {HTTP_HEADER_INDEX_IF_MODIFIED_SINCE, HTTP_HEADER_REQUEST,"If-Modified-Since"},
+    {HTTP_HEADER_INDEX_IF_NONE_MATCH, HTTP_HEADER_REQUEST,"If-None-Match"},
+    {HTTP_HEADER_INDEX_IF_RANGE, HTTP_HEADER_REQUEST,"If-Range"},
+    {HTTP_HEADER_INDEX_IF_UNMODIFIED_SINCE, HTTP_HEADER_REQUEST,"If-Unmodified-Since"},
+    {HTTP_HEADER_INDEX_MAX_FORWARDS, HTTP_HEADER_REQUEST,"Max-Forwards"},
+    {HTTP_HEADER_INDEX_PROXY_AUTHORIZATION, HTTP_HEADER_REQUEST,"Proxy-Authorization"},
+    {HTTP_HEADER_INDEX_RANGE, HTTP_HEADER_REQUEST,"Range"},
+    {HTTP_HEADER_INDEX_REFERER, HTTP_HEADER_REQUEST,"Referer"},
+    {HTTP_HEADER_INDEX_TE, HTTP_HEADER_REQUEST,"TE"},
+    {HTTP_HEADER_INDEX_USER_AGENT, HTTP_HEADER_REQUEST,"User-Agent"},
+    {HTTP_HEADER_INDEX_ACCEPT_RANGES, HTTP_HEADER_RESPONSE,"Accept-Ranges"},
+    {HTTP_HEADER_INDEX_AGE, HTTP_HEADER_RESPONSE,"Age"},
+    {HTTP_HEADER_INDEX_ETAG, HTTP_HEADER_RESPONSE,"ETag"},
+    {HTTP_HEADER_INDEX_LOCATION, HTTP_HEADER_RESPONSE,"Location"},
+    {HTTP_HEADER_INDEX_PROXY_AUTHENTICATE, HTTP_HEADER_RESPONSE,"Proxy-Authenticate"},
+    {HTTP_HEADER_INDEX_RETRY_AFTER, HTTP_HEADER_RESPONSE,"Retry-After"},
+    {HTTP_HEADER_INDEX_SERVER, HTTP_HEADER_RESPONSE,"Server"},
+    {HTTP_HEADER_INDEX_VARY, HTTP_HEADER_RESPONSE,"Vary"},
+    {HTTP_HEADER_INDEX_WWW_AUTHENTICATE, HTTP_HEADER_RESPONSE,"WWW-Authenticate"},
+    {HTTP_HEADER_INDEX_ALLOW, HTTP_HEADER_ENTITY,"Allow"},
+    {HTTP_HEADER_INDEX_CONTENT_ENCODING, HTTP_HEADER_ENTITY,"Content-Encoding"},
+    {HTTP_HEADER_INDEX_CONTENT_LANGUAGE, HTTP_HEADER_ENTITY,"Content-Language"},
+    {HTTP_HEADER_INDEX_CONTENT_LENGTH, HTTP_HEADER_ENTITY,"Content-Length"},
+    {HTTP_HEADER_INDEX_CONTENT_LOCATION, HTTP_HEADER_ENTITY,"Content-Location"},
+    {HTTP_HEADER_INDEX_CONTENT_MD5, HTTP_HEADER_ENTITY,"Content-MD5"},
+    {HTTP_HEADER_INDEX_CONTENT_RANGE, HTTP_HEADER_ENTITY,"Content-Range"},
+    {HTTP_HEADER_INDEX_CONTENT_TYPE, HTTP_HEADER_ENTITY,"Content-Type"},
+    {HTTP_HEADER_INDEX_EXPIRES, HTTP_HEADER_ENTITY,"Expires"},
+    {HTTP_HEADER_INDEX_LAST_MODIFIED, HTTP_HEADER_ENTITY,"Last-Modified"},
+    {HTTP_HEADER_INDEX_SET_COOKIE, HTTP_HEADER_OTHERS,"Set-Cookie"},
+    {HTTP_HEADER_INDEX_COOKIE, HTTP_HEADER_OTHERS,"Cookie"},
+    {HTTP_HEADER_INDEX_X_FRAME_OPTIONS, HTTP_HEADER_OTHERS,"X-Frame-Options"},
+    {HTTP_HEADER_INDEX_X_XSS_PROTECTION, HTTP_HEADER_OTHERS,"X-XSS-Protection"},
+    {HTTP_HEADER_INDEX_DNT, HTTP_HEADER_OTHERS,"DNT"},
+    {HTTP_HEADER_INDEX_P3P, HTTP_HEADER_OTHERS,"P3P"}
+};
+#endif
+/*************************************************************
+    Public Function Declaration
+*************************************************************/
+int mbtk_http_handle_get(bool show_rsp_header,mbtk_http_data_callback_func data_cb);
+int mbtk_http_handle_free(int handle_id);
+int mbtk_http_session_create(int handle_id, mbtk_http_option_enum option,
+        mbtk_http_version_enum version);
+int mbtk_http_session_option_reset(int handle_id, int session_id, mbtk_http_option_enum option);
+int mbtk_http_session_free(int handle_id,int session_id);
+int mbtk_http_session_url_set(int handle_id,int session_id,void *url);
+int mbtk_http_session_head_add(int handle_id,int session_id,
+        char *name, char *value);
+int mbtk_http_session_content_set(int handle_id,int session_id,
+        char *content,uint32 content_len);
+int mbtk_http_session_start(int handle_id,int session_id);
+int mbtk_http_session_content_send(int handle_id,int session_id,
+        char *data,int data_len);
+const mbtk_http_session_t* mbtk_http_session_get(int handle_id,int session_id);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _MBTK_HTTP_2_H */
+
+
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/include/mbtk_http_base.h b/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/include/mbtk_http_base.h
new file mode 100755
index 0000000..e8ae710
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/include/mbtk_http_base.h
@@ -0,0 +1,44 @@
+#include <cstdio>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int mbtk_http_init();
+int mbtk_http_deinit();
+int mbtk_http_open
+(
+    //bool is_ssl,
+    //bool ingnore_cert,
+    const void *host,
+    int *port
+);
+int mbtk_http_read
+(
+    int sock_fd,
+    void *buf,
+    uint16_t len,
+    int timeout_ms
+);
+
+int mbtk_http_read_line
+(
+    int sock_fd,
+    void *buf,
+    uint16_t len
+);
+int mbtk_http_write
+(
+    int sock_fd,
+    void *buf,
+    uint16_t len
+);
+int mbtk_http_close(int sock_fd);
+
+#ifdef __cplusplus
+}
+#endif
\ No newline at end of file
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/include/mbtk_type.h b/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/include/mbtk_type.h
new file mode 100755
index 0000000..c5fc1a0
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/include/mbtk_type.h
@@ -0,0 +1,127 @@
+#ifndef MBTK_TYPE_INCLUDE
+#define MBTK_TYPE_INCLUDE
+#include <stdio.h>
+#include <stdbool.h>
+#include <sys/types.h>
+
+#ifndef MBTK_PLATFORM_LINUX
+#define MBTK_PLATFORM_LINUX
+#endif
+
+#ifndef MBTK_PLATFORM_QCOMM
+//#define MBTK_PLATFORM_QCOMM
+#endif
+
+#define MBTK_SUCCESS 0
+#define MBTK_FAILE (-1)
+
+#ifndef UNUSED
+#define UNUSED(param) ((void) param)
+#define UNUSEDPARAM UNUSED
+#endif
+
+#ifndef TRUE
+#define TRUE   1   /* Boolean true value. */
+#endif
+
+#ifndef true
+#define true   1   /* Boolean true value. */
+#endif
+
+#ifndef FALSE
+#define FALSE  0   /* Boolean false value. */
+#endif
+
+#ifndef false
+#define false  0   /* Boolean false value. */
+#endif
+
+
+#ifndef NULL
+#define NULL  0
+#endif
+
+
+#ifndef null
+#define null  0
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/**
+ * Compiler-digit : 16
+ * char : 1     (%c)
+ * char* : 2
+ * short int : 2
+ * int : 2      (%d)
+ * unsigned int : 2  (%u)
+ * float : 4    (%f)
+ * double : 8   (%f)
+ * long : 4
+ * unsigned long : 4
+ * long long : 8
+ * unsigned long long : 8
+ *
+ *
+ * Compiler-digit : 32
+ * char : 1
+ * char* : 4
+ * short int : 2
+ * int : 4
+ * unsigned int : 4
+ * float : 4
+ * double : 8
+ * long : 4
+ * unsigned long : 4
+ * long long : 8
+ * unsigned long long : 8
+ *
+ *
+ * Compiler-digit : 64
+ * char : 1
+ * char* : 8
+ * short int : 2
+ * int : 4
+ * unsigned int : 4
+ * float : 4
+ * double : 8
+ * long : 8
+ * unsigned long : 8
+ * long long : 8
+ * unsigned long long : 8
+ */
+typedef unsigned char boolean; /* Boolean value type. */
+// typedef unsigned char bool; /* Boolean value type. */
+typedef unsigned long long uint64; /* Unsigned 64 bit value */
+typedef unsigned long long uint64_t; /* Unsigned 64 bit value */
+typedef unsigned int uint32; /* Unsigned 32 bit value */
+typedef unsigned int uint32_t; /* Unsigned 32 bit value */
+typedef unsigned short uint16; /* Unsigned 16 bit value */
+typedef unsigned short uint16_t;
+typedef unsigned char uint8; /* Unsigned 8  bit value */
+typedef unsigned char uint8_t;
+typedef signed long long int64; /* Signed 64 bit value */
+typedef signed long long sint64; /* Signed 64 bit value */
+typedef signed int int32; /* Signed 32 bit value */
+typedef signed int sint32; /* Signed 32 bit value */
+typedef signed short int16; /* Signed 16 bit value */
+typedef signed short sint16; /* Signed 16 bit value */
+typedef signed char int8; /* Signed 8  bit value */
+typedef signed char sint8; /* Signed 8  bit value */
+typedef unsigned char byte; /* byte type */
+
+
+typedef struct
+{
+    char *buffer;
+    int size;
+    int size_max;
+}mbtk_buffer_t;
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* MBTK_TYPE_INCLUDE */
+
+
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/src/lynq_qser_gnss.cpp b/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/src/lynq_qser_gnss.cpp
index 65414ed..a7f7191 100755
--- a/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/src/lynq_qser_gnss.cpp
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/src/lynq_qser_gnss.cpp
@@ -222,6 +222,39 @@
     return 0;
 }
 
+int qser_firmware_update(uint32_t* ph_gnss)
+{
+    int ret;
+    mopen_gnss_firmware_update(*ph_gnss);
+    if(ret < 0)
+    {
+        return -1;
+    }
+    return 0;
+}
+
+int qser_Gnss_download_tle()
+{
+    int ret;
+    ret = mopen_gnss_download_tle();
+    if(ret < 0)
+    {
+        return -1;
+    }
+    return 0;
+}
+
+int qser_Gnss_injectEphemeris(uint32_t h_gnss)
+{
+    int ret;
+    ret = mopen_gnss_injects_aidpos(h_gnss);
+    if(ret < 0)
+    {
+        return -1;
+    }
+    return 0;
+}
+
 void atsvc_incb_entity(char *input,int length);
 int lynq_at_cgps(int at_type,int gnss_state_type);
 int lynq_at_cgpsnmea(int at_type,int gnss_state_type);
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/src/mbtk_gnss.cpp b/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/src/mbtk_gnss.cpp
index c2f3056..5721c83 100755
--- a/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/src/mbtk_gnss.cpp
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/src/mbtk_gnss.cpp
@@ -16,7 +16,10 @@
 #include <sys/ioctl.h>
 #include <malloc.h>
 #include <sys/time.h>
+#include <liblog/lynq_deflog.h>
 #include "mbtk_gnss_internal.h"
+#include "mbtk_http.h"
+#include "mbtk_type.h"
 #include "ringbuffer.h"
 #ifdef __cplusplus
 extern "C" {
@@ -376,7 +379,7 @@
                 g_no_sv < (no_sv - 1) && no_sv > 5) {
 
             g_no_sv = no_sv;
-            lynq_gnss_get_ap_data();
+            //lynq_gnss_get_ap_data();
         }
     }
 }
@@ -1197,12 +1200,196 @@
     return 0;
 }
 
-#define AGNSS_TLE_FILE  "/tmp/agnss_tle"
+#define AGNSS_TLE_FILE  "/mnt/userdata/agnss_tle"
 
+static void http_data_cb_func(
+    int session_id, mbtk_http_data_type_enum type,
+    void *data,int data_len)
+{
+    static int agnss_fd = 0;
+    int ret = 0;
 
+    if(type == MBTK_HTTP_DATA_HEADER) {
+        printf("Header(%d):%s\n", data_len, (char*)data);
+        if(agnss_fd > 0)
+            return;
+        unlink(AGNSS_TLE_FILE);
+        agnss_fd = open(AGNSS_TLE_FILE, O_RDWR|O_CREAT|O_TRUNC, 0644);
+        if (agnss_fd <= 0)
+        printf("file open error\n");
+        printf("agnss file open: %d\n", agnss_fd);
+    } else if(type == MBTK_HTTP_DATA_CONTENT) {
+        printf("http Data(%d)\n", data_len);
 
+        ret = write(agnss_fd, (char*)data, data_len);
+        if (ret < 0) {
+            printf("%s: error writing to file!\n", __FUNCTION__);
+        } else if (ret < data_len) {
+            printf("%s: wrote less the buffer size!\n", __FUNCTION__);
+        }
+    } else {
+        printf(">>>>>Complete<<<<<\n");
+        if(agnss_fd <= 0)
+            return;
+        close(agnss_fd);
+        agnss_fd = 0;
+    }
+}
 
-#define AGNSS_CONFIG_FILE  "/etc/mbtk/gps.conf"
+static int gnss_http_requst(char *id, char *pw)
+{
+    char tmp[128] = {0};
+    
+    int http_handle = mbtk_http_handle_get(TRUE, http_data_cb_func);
+    if(http_handle < 0)
+    {
+        printf("mbtk_http_handle_get() fail.");
+        return -1;
+    }
+    int http_session = mbtk_http_session_create(http_handle, HTTP_OPTION_POST, HTTP_VERSION_1_1);
+    if(http_handle < 0)
+    {
+        printf("mbtk_http_session_create() fail.");
+        return -2;
+    }
+    if(mbtk_http_session_url_set(http_handle, http_session, "http://unicore-api.rx-networks.cn/rxn-api/locationApi/rtcm")) {
+        printf("mbtk_http_session_url_set() fail.\n");
+        return -3;
+    }
+
+    char* post_data = "[{\"rtAssistance\":{\"format\":\"rtcm\",\"msgs\":[\"GPS:2NAF\",\"BDS:2NAF\",\"QZS:2NAF\"]}}]\r\n";
+
+    mbtk_http_session_head_add(http_handle, http_session, \
+    "Host", "unicore-api.rx-networks.cn");
+
+    sprintf(tmp, "RXN-BASIC cId=%s,mId=Unicore,dId=12-23-34-45-58,pw=%s", id, pw);
+    mbtk_http_session_head_add(http_handle, http_session, \
+    "Authorization", tmp);
+
+    mbtk_http_session_head_add(http_handle, http_session, \
+            "Content-Type", "application/json");
+
+    mbtk_http_session_head_add(http_handle, http_session, \
+            "Accept", "application/octet-stream");
+    mbtk_http_session_content_set(http_handle, http_session,
+                                  post_data, strlen(post_data));
+
+    if(mbtk_http_session_start(http_handle, http_session)) {
+        printf("mbtk_http_session_start() fail.\n");
+        return -4;
+    }
+    if(mbtk_http_handle_free(http_handle))
+    {
+        printf("mbtk_http_handle_free() fail.");
+        return -5;
+    }
+
+    return 0;
+}
+
+/**********************************
+
+ ID1: TempID1Expire20221031
+ Base 64 PW1: RlJYdkFTNE9DWXJhN2ZWTA==
+**************************************/
+#define AGNSS_CONFIG_FILE  "/data/gnss_update/agps.conf"
+
+/**
+ * @brief      mopen_gnss_download_tle
+ *
+ * @details    下载星历数据
+ *             (卫星星历,又称为两行轨道数据(TLE,Two-Line Orbital Element))
+ *             保存到文件:AGNSS_TLE_FILE
+ * @param      param
+ *
+ * @return     return type
+ */
+int mopen_gnss_download_tle(void)
+{
+    FILE *fp;
+    char StrLine[64];
+    char _id[28] = {0};
+    char _passwd[28] = {0};
+    int i;
+    if((fp = fopen(AGNSS_CONFIG_FILE, "r")) == NULL)
+    {
+        printf("open %s error!\n", AGNSS_CONFIG_FILE);
+        return -1;
+    }
+
+    while (!feof(fp))
+    {
+        memset(StrLine, 0, 64);
+        fgets(StrLine, 64, fp);
+        gnss_log("%s\n", StrLine);
+        i = strstr_n(StrLine, ": ");
+        if(i && strstr_n(StrLine, "ID"))
+        {
+            memcpy(_id, &StrLine[i + 1], strlen(StrLine) - i - 2);
+            printf("%s\n",_id);
+        }
+        else if( i && strstr_n(StrLine, "Base 64"))
+        {
+            memcpy(_passwd, &StrLine[i + 1], strlen(StrLine) - i - 1);
+            printf("%s\n",_passwd);
+        }
+    }
+    fclose(fp);
+    gnss_log("%s : %s[%d], %s[%d]\n", __FUNCTION__, _id, strlen(_id), _passwd, strlen(_passwd));
+    return gnss_http_requst(_id, _passwd);
+}
+
+/**
+ * @brief      mopen_gnss_injects_aidpos
+ *
+ * @details    注入星历, 128 bytes
+ *
+ * @param      param
+ *
+ * @return     return type
+ */
+int mopen_gnss_injects_aidpos(uint32 h_gnss)
+{
+    int ret;
+    int agnss_fd = 0;
+    int size = 0;
+
+    if(0 == h_gnss)
+    {
+        printf("%s handler invalid.\n", __func__);
+        return -1;
+    }
+
+    agnss_fd = open(AGNSS_TLE_FILE, O_RDWR);
+    if (agnss_fd <= 0)
+    {
+        printf("%s open file FAIL. errno:%d\n", __FUNCTION__, errno);
+        return -1;
+    }
+    char* databuf = (char*)malloc(128);
+    if(databuf == NULL)
+    {
+        gnss_log("%s malloc() fail.", __FUNCTION__);
+        return -1;
+    }
+    memset(databuf, 0, 128);
+    while(0 < (size = read(agnss_fd, databuf, 128)))
+    {
+        gnss_log("%s Write[%d]\r\n", __FUNCTION__, size);
+        ret = lynq_gnss_send_cmd(h_gnss, databuf, size);
+        if(ret < 0)
+        {
+            printf("%s send cmd FAIL. ret:%d\n", __FUNCTION__, ret);
+            break;
+        }
+        memset(databuf, 0, 128);
+    }
+    close(agnss_fd);
+    free(databuf);
+    lynq_gnss_get_aidinfo(h_gnss);
+
+    return 0;
+}
 
 
 /**
@@ -1273,100 +1460,59 @@
     return 0;
 }
 
-#define GNSS_AP_DATA_FILE  "/etc/mbtk/rtm.bin"
-
-int lynq_gnss_get_ap_data(void)
-{
-    int state = 0;
-    uint32 *ph_gnss = NULL;
-    gnss_handler_func_t cb;
-    int current_mode;
-    const char* cmd = "mbtk_gnss_update getap -d /dev/ttyS2 -b 115200 -a /etc/mbtk/rtm.bin";
-
-    if(access(GNSS_AP_DATA_FILE, F_OK) != -1) {
-        unlink(GNSS_AP_DATA_FILE);
-    }
-    mbtk_gnss_handle->getap_status = 1;
-    sleep(1);
-    printf("Mopen Gnss Get Ap Data -> \n");
-    int ret = exec_cmd(cmd, NULL);
-
-    usleep(100000);
-    mbtk_gnss_handle->getap_status = 0;
-    if(0 != ret) {
-        printf("Gnss getap result: %x\n", ret);
-        return -1;
-    }
-    LOGI("%s %d: %d.\n", __FUNCTION__, __LINE__, ret);
-    return ret;
-}
 /*
-  sync : 1
+update API:
+Gnss_Update_File_Path:"/data/gnss_update/firmware.pkg"
+Gnss_Bootloader_File_Path: "/data/gnss_update/bootloader.pkg"
  */
-int mopen_gnss_firmware_update(void)
+int mopen_gnss_firmware_update(uint32 ph_gnss)
 {
+    int ret;
     int state = 0;
-    uint32 *ph_gnss = NULL;
-    gnss_handler_func_t cb;
-    int current_mode;
-    const char* cmd_1 = "mbtk_gnss_update downbl -d /dev/ttyS2 \
-            -l /mnt/userdata/bootloader_r3.0.0_build6773_uartboot_921600.pkg";
-
-            const char* cmd_2 = "mbtk_gnss_update sendap -d /dev/ttyS2 -b 921600 -a /etc/mbtk/rtm.bin";
-
-    const char* cmd_3 = "mbtk_gnss_update downfw -d /dev/ttyS2 -b 921600\
-            -f /mnt/userdata/UC6228CI-R3.2.10.100Build8019_mfg.pkg";
-            // /etc/mbtk/UC6228CI-R3.4.0.0Build7258_mfg.pkg
-
-            if (mbtk_gnss_handle) {
-            printf("%s gnss thread runing!!!\n", __func__);
-            if (mbtk_gnss_handle->gnss_handler_func)
-            cb = mbtk_gnss_handle->gnss_handler_func;
-
-            ph_gnss = mbtk_gnss_handle->phandle;
-            current_mode = mbtk_gnss_handle->mode;
-            // 主线程是否在运行
-            if (mbtk_gnss_handle->gnss_pthread)
+    printf("load_datafile start\n");
+    struct mbtk_gnss_handle_t *gnss_handle = (struct mbtk_gnss_handle_t* )ph_gnss;
+    const char* cmd_1 = "lynq-gnss-update downbl -d /dev/ttyS2  -b 230400 -l /data/gnss_update/bootloader.pkg";
+    const char* cmd_2 = "lynq-gnss-update downfw -d /dev/ttyS2 -b 921600 -f /data/gnss_update/firmware.pkg";
+    const char* cmd_3 = "echo \"\$PDTINFO\r\n\" > /dev/ttyS2";
+    if (ph_gnss)
+    {
+        printf("%s gnss thread runing!!!\n", __func__);
+        // 主线程是否在运行
+        if (gnss_handle->gnss_pthread)
             state = 1;
-            lynq_gnss_client_deinit((uint32)mbtk_gnss_handle);
-}
-            printf("Mopen Gnss Bootloader Update -> \n");
-    int ret = exec_cmd(cmd_1, NULL);
-    if(0 != ret) {
-        printf("Gnss update result: %x\n", ret);
+        lynq_gnss_client_deinit(ph_gnss);
+    }
+    printf("Mopen Gnss Bootloader Update -> \n");
+    ret = exec_cmd(cmd_1, NULL);
+    if(0 != ret)
+    {
+        ALOGE("Gnss update result: %x\n", ret);
         return -1;
     }
 
-    /*if(access(GNSS_AP_DATA_FILE, F_OK) != -1)
-    {
-        printf("Mopen Gnss Send AP Data  -> \n");
-        ret = exec_cmd(cmd_2, NULL);
-        if(0 != ret) {
-            printf("Gnss update result: %x\n", ret);
-        }
-    }*/
-
     printf("Mopen Gnss Firmware Update -> \n");
+    ret = exec_cmd(cmd_2, NULL);
+    if(0 != ret)
+    {
+        ALOGE("Gnss update result: %x\n", ret);
+        return -1;
+    }
+
+    printf("PDTINFO  -> \n");
     ret = exec_cmd(cmd_3, NULL);
-    if(0 != ret) {
-        printf("Gnss update result: %x\n", ret);
-        return -2;
+    if(0 != ret)
+    {
+        ALOGE("PDTINFO  ->  %x\n", ret);
+        return -1;
     }
 
     if (0 == firmware_extren_state)
         firmware_extren_state = 1;
-    if (state && ph_gnss) {
-        ret = lynq_gnss_client_init(ph_gnss);
-        if (cb) {
-            mbtk_gnss_handle->gnss_handler_func = cb;
-            mbtk_gnss_handle->mode = current_mode;
-        }
-    }
 
-    LOGI("%s %d: %d.\n", __FUNCTION__, __LINE__, ret);
     return ret;
 }
 
+
 /*update ephemeris from network*/
 #define AGNSS_TLE_FILE "/mnt/userdata/agnss_tle" //deposit ephemeris
 
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/src/mbtk_http.cpp b/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/src/mbtk_http.cpp
new file mode 100755
index 0000000..1963359
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/src/mbtk_http.cpp
@@ -0,0 +1,1370 @@
+/*************************************************************
+Description:
+    MBTK HTTP c file.
+Author:
+    
+Date:
+  
+*************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <log/log.h>
+#include <liblog/lynq_deflog.h>
+#include "mbtk_http_base.h"
+#include "mbtk_http.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*************************************************************
+    Constants and Macros
+*************************************************************/
+
+/*************************************************************
+    Variables:local
+*************************************************************/
+static mbtk_http_handle_t http_handles[HTTP_HANDLE_MAX] =
+{
+    {
+        .id = -1,
+        .data_cb = NULL,
+        .session_cnt = 0,
+        .session = {NULL}
+    }
+};
+
+/*************************************************************
+    Variables:public
+*************************************************************/
+
+
+/*************************************************************
+    Local Function Declaration
+*************************************************************/
+
+
+/*************************************************************
+    Local Function Definitions
+*************************************************************/
+static void http_session_free(mbtk_http_session_t *session)
+{
+    if(session)
+    {
+        if(session->req.header_cnt > 0)
+        {
+            int index;
+            for(index = 0; index < HTTP_REQUEST_HEADER_MAX; index++)
+            {
+                if(session->req.req_h[index] != NULL)
+                {
+                    if(session->req.req_h[index]->value)
+                        free(session->req.req_h[index]->value);
+                    free(session->req.req_h[index]);
+                    session->req.req_h[index] = NULL;
+                }
+            }
+            session->req.header_cnt = 0;
+        }
+
+        if(session->req.content)
+        {
+            free(session->req.content);
+            session->req.content = NULL;
+        }
+
+        if(session->rsp.header_cnt > 0)
+        {
+            int index;
+            for(index = 0; index < HTTP_REQUEST_HEADER_MAX; index++)
+            {
+                if(session->rsp.rsp_h[index] != NULL)
+                {
+                    if(session->rsp.rsp_h[index]->value)
+                        free(session->rsp.rsp_h[index]->value);
+                    free(session->rsp.rsp_h[index]);
+                    session->rsp.rsp_h[index] = NULL;
+                }
+            }
+            session->rsp.header_cnt = 0;
+        }
+
+        free(session);
+    }
+}
+
+static int http_session_close(mbtk_http_session_t *session)
+{
+    if(session)
+    {
+        if(session->sock_fd > 0)
+        {
+            if(mbtk_http_close(session->sock_fd))
+            {
+                RLOGD("mbtk_http_close() fail.");
+                return -1;
+            }
+            session->sock_fd = -1;
+        }
+
+        session->state = HTTP_SESSION_STATE_NON;
+
+        return 0;
+    }
+
+    return -1;
+}
+
+
+static bool http_handle_check(int handle_id)
+{
+    if(handle_id < 0 || handle_id >= HTTP_HANDLE_MAX
+       || http_handles[handle_id].id < 0)
+    {
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+static bool http_session_check(int handle_id, int session_id)
+{
+    if(handle_id < 0 || handle_id >= HTTP_HANDLE_MAX
+       || http_handles[handle_id].id < 0
+       || http_handles[handle_id].id != handle_id)
+    {
+        return FALSE;
+    }
+
+    if(session_id < 0 || session_id >= HTTP_SESSION_MAX
+       || http_handles[handle_id].session[session_id] == NULL
+       || http_handles[handle_id].session[session_id]->id != session_id)
+    {
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+static bool http_is_space_char(char ch)
+{
+    if(ch == ' ' || ch == '\r' || ch == '\t' || ch == '\n')
+        return TRUE;
+
+    return FALSE;
+}
+
+static bool http_str_empty(char *str)
+{
+    if(str == NULL || strlen(str) == 0)
+        return TRUE;
+
+    return FALSE;
+}
+
+
+static int http_url_parse
+(
+    void* url,
+    void *host,
+    void *uri,
+    int *port,
+    bool *is_ssl
+)
+{
+    if(strlen(url) == 0)
+    {
+        return -1;
+    }
+    char *url_ptr = (char*)url;
+    char *host_ptr = (char*)host;
+
+    RLOGD("URL[%d]:%s",strlen(url_ptr),url_ptr);
+
+    if(!memcmp(url_ptr,"https://",8))
+    {
+        *is_ssl = TRUE;
+        url_ptr += 8;
+    }
+    else if(!memcmp(url_ptr,"http://",7))
+    {
+        *is_ssl = FALSE;
+        url_ptr += 7;
+    }
+    else
+    {
+        *is_ssl = FALSE;
+    }
+
+    // ptr point to host.
+    while(*url_ptr)
+    {
+        if(*url_ptr == ':' || *url_ptr == '/') // Host end
+            break;
+        if(http_is_space_char(*url_ptr))
+        {
+            url_ptr++;
+            continue;
+        }
+        *host_ptr++ = *url_ptr++;
+    }
+
+    // "www.baidu.com"
+    if(*url_ptr == '\0')   // No port and uri
+    {
+        if(*is_ssl)
+        {
+            *port = MBTK_HTTPS_PORT_DEF;
+        }
+        else
+        {
+            *port = MBTK_HTTP_PORT_DEF;
+        }
+        memcpy(uri,"/",1);
+
+        RLOGD("HTTP parse success:'%s','%s', %d, %d",(char*)host,(char*)uri,*port,*is_ssl);
+        return 0;
+    }
+    else
+    {
+        //LOGI("Host end with:%x",*url_ptr);
+        if(*url_ptr == ':')   // Port exist.
+        {
+            *port = atoi(url_ptr + 1);
+
+            // Point to '/' or NULL
+            while(*url_ptr && *url_ptr != '/')
+            {
+                url_ptr++;
+            }
+
+            // "www.baidu.com:80"
+            if(*url_ptr == '\0')   // No uri
+            {
+                if(*port == 0)
+                {
+                    if(*is_ssl)
+                    {
+                        *port = MBTK_HTTPS_PORT_DEF;
+                    }
+                    else
+                    {
+                        *port = MBTK_HTTP_PORT_DEF;
+                    }
+                }
+                memcpy(uri,"/",1);
+
+                RLOGD("HTTP parse success:'%s','%s', %d, %d",(char*)host,(char*)uri,*port,*is_ssl);
+                return 0;
+            }
+        }
+
+        // "www.baidu.com/xxx" or "www.baidu.com:80/xxx"
+        // Now,url_ptr point to '/'
+        if(*url_ptr != '/')
+        {
+            RLOGD("URI must start with '/'.");
+            return -1;
+        }
+
+        //LOGI("URL3[%d]:%s",strlen(url_ptr),url_ptr);
+
+        memcpy(uri,url_ptr,strlen(url_ptr));
+
+        if(*port == 0)
+        {
+            if(*is_ssl)
+            {
+                *port = MBTK_HTTPS_PORT_DEF;
+            }
+            else
+            {
+                *port = MBTK_HTTP_PORT_DEF;
+            }
+        }
+
+        RLOGD("HTTP parse success:'%s','%s', %d, %d",(char*)host,(char*)uri,*port,*is_ssl);
+        return 0;
+    }
+}
+
+static int http_session_req_head_add(mbtk_http_session_t *session,bool replace,
+                                     char *name, char *value)
+{
+    if(session == NULL || value == NULL)
+        return -1;
+
+    RLOGD("Add request header - %s:%s",name,value);
+
+    int i = 0;
+    while(i < HTTP_REQUEST_HEADER_MAX)
+    {
+        if(session->req.req_h[i]
+           && !strncasecmp(session->req.req_h[i]->name,name,strlen(name)))   // Is change value
+        {
+            break;
+        }
+        i++;
+    }
+
+    if(i == HTTP_REQUEST_HEADER_MAX)   // Should add new header.
+    {
+        i = 0;
+        while(i < HTTP_REQUEST_HEADER_MAX)
+        {
+            if(session->req.req_h[i] == NULL)   // Find NULL request.
+            {
+                session->req.req_h[i] = (mbtk_http_header_t*)malloc(sizeof(mbtk_http_header_t));
+                if(session->req.req_h[i] == NULL)
+                {
+                    RLOGD("malloc() fail.");
+                    return -1;
+                }
+
+                memset(session->req.req_h[i],0x0,sizeof(mbtk_http_header_t));
+                memcpy(session->req.req_h[i]->name, name, strlen(name));
+                session->req.req_h[i]->value = NULL;
+                session->req.header_cnt++;
+                break;
+            }
+            i++;
+        }
+    }
+    else     // Is change value
+    {
+        if(!replace)
+        {
+            RLOGD("Found this header[%s],no replace.",name);
+            return 0;
+        }
+    }
+
+    if(i == HTTP_REQUEST_HEADER_MAX)
+    {
+        RLOGD("Request header is full.");
+        return -1;
+    }
+
+    if(session->req.req_h[i]->value)
+    {
+        free(session->req.req_h[i]->value);
+    }
+    session->req.req_h[i]->value = (char*)malloc(strlen(value) + 1);
+    if(session->req.req_h[i]->value == NULL)
+    {
+        RLOGD("malloc() fail.");
+        return -1;
+    }
+    memset(session->req.req_h[i]->value,0x0,strlen(value) + 1);
+    memcpy(session->req.req_h[i]->value,value,strlen(value));
+
+    return 0;
+}
+
+#if 0
+static int http_session_rsp_head_add(mbtk_http_session_t *session,
+                                     char *name, char *value)
+{
+    if(session == NULL || value == NULL)
+        return -1;
+
+    int i = 0;
+    while(i < HTTP_REQUEST_HEADER_MAX)
+    {
+        if(session->rsp.rsp_h[i] == NULL)   // Find NULL request.
+        {
+            session->rsp.rsp_h[i] = (mbtk_http_header_t*)malloc(sizeof(mbtk_http_header_t));
+            if(session->rsp.rsp_h[i] == NULL)
+            {
+                RLOGD("malloc() fail.");
+                return -1;
+            }
+
+            memcpy(session->rsp.rsp_h[i]->name,name,strlen(name));
+            session->rsp.rsp_h[i]->value = (char*)malloc(strlen(value) + 1);
+            if(session->rsp.rsp_h[i]->value == NULL)
+            {
+                RLOGD("malloc() fail.");
+                return -1;
+            }
+            memset(session->rsp.rsp_h[i]->value,0x0,strlen(value) + 1);
+            memcpy(session->rsp.rsp_h[i]->value,value,strlen(value));
+
+            session->rsp.header_cnt++;
+            return 0;
+        }
+        i++;
+    }
+
+    return -1;
+}
+#endif
+
+static char* http_option_str_get(mbtk_http_option_enum option)
+{
+    switch(option)
+    {
+        case HTTP_OPTION_HEAD:
+            return "HEAD";
+        case HTTP_OPTION_GET:
+            return "GET";
+        case HTTP_OPTION_POST:
+            return "POST";
+        case HTTP_OPTION_PUT:
+            return "PUT";
+        case HTTP_OPTION_DELETE:
+            return "DELETE";
+        case HTTP_OPTION_OPTIONS:
+            return "OPTIONS";
+        case HTTP_OPTION_TRACE:
+            return "TRACE";
+        case HTTP_OPTION_CONNECT:
+            return "CONNECT";
+        case HTTP_OPTION_LINK:
+            return "LINK";
+        case HTTP_OPTION_UNLINK:
+            return "UNLINK";
+        default:
+            return "";
+    }
+}
+
+static char* http_version_str_get(mbtk_http_version_enum version)
+{
+    switch(version)
+    {
+        case HTTP_VERSION_1_0:
+            return "1.0";
+        case HTTP_VERSION_1_1:
+            return "1.1";
+        case HTTP_VERSION_2:
+            return "2";
+        case HTTP_VERSION_3:
+            return "3";
+        default:
+            return "";
+    }
+}
+
+static char* http_header_find(mbtk_http_session_t *session,char* name)
+{
+    int i = 0;
+    while(i < HTTP_REQUEST_HEADER_MAX)
+    {
+        if(session->req.req_h[i] &&
+           !strncasecmp(session->req.req_h[i]->name,name,strlen(name)))
+        {
+            return session->req.req_h[i]->value;
+        }
+
+        i++;
+    }
+    return NULL;
+}
+
+static int http_header_str_get(mbtk_http_header_t *header,char *header_str,int header_str_len)
+{
+    if(header == NULL || header->value == NULL
+       || header_str == NULL)
+        return 0;
+
+    int len = 0;
+    len = snprintf(header_str,header_str_len,"%s: %s\r\n",
+                   header->name, header->value);
+
+    return len;
+}
+
+static mbtk_http_version_enum http_version_get_by_str(char *version_str)
+{
+    if(!memcmp(version_str,"1.0",3))
+        return HTTP_VERSION_1_0;
+    else if(!memcmp(version_str,"1.1",3))
+        return HTTP_VERSION_1_1;
+    else if(!memcmp(version_str,"2",1))
+        return HTTP_VERSION_2;
+    else if(!memcmp(version_str,"3",1))
+        return HTTP_VERSION_3;
+    else
+        return HTTP_VERSION_1_1;
+}
+
+static int http_header_read(mbtk_http_session_t *session)
+{
+#define BUFFER_SIZE 2048
+    char line[BUFFER_SIZE];
+    char *ptr = NULL;
+    int len = 0;
+    while((len = mbtk_http_read_line(session->sock_fd,line,BUFFER_SIZE)) > 0)
+    {
+        if(!memcmp(line,"\r\n",2))
+        {
+            RLOGD("Read empty line.");
+            break;
+        }
+
+        // Delete "\r\n"
+        ptr = line + len - 1; // Point to last char.
+        while(http_is_space_char(*ptr))
+        {
+            *ptr = '\0';
+            len--;
+            ptr--;
+        }
+
+        RLOGD("LINE:%s",line);
+
+        if(http_handles[session->handle_id].show_rsp_header &&
+           http_handles[session->handle_id].data_cb)
+        {
+            http_handles[session->handle_id].data_cb(session->id,
+                    MBTK_HTTP_DATA_HEADER,line,len);
+        }
+
+        if(!memcmp(line,"HTTP/",5))   // "HTTP/1.1 200 OK"
+        {
+            session->rsp.state_code = atoi(line + 9);
+            session->rsp.version = http_version_get_by_str(line + 5);
+        }
+        else     // Is response header item.
+        {
+            if(!strncasecmp(line,"Content-Length",14))
+            {
+                ptr = line + 14;
+                while(ptr && !isdigit(*ptr))
+                {
+                    ptr++;
+                }
+
+                if(ptr)
+                {
+                    session->rsp.content_length = atol(ptr);
+                }
+            }
+            else if(!strncasecmp(line,"Transfer-Encoding",17))
+            {
+                ptr = line + 17;
+                while(ptr && !isalpha(*ptr))
+                {
+                    ptr++;
+                }
+
+                if(ptr && !memcmp(ptr,"chunked",7))
+                {
+                    session->rsp.is_chunked = TRUE;
+                }
+            }
+        }
+    }
+#undef BUFFER_SIZE
+
+    RLOGD("RSP:HTTP/%s %d, is_chunked:%d,Content-Length:%d",http_version_str_get(session->rsp.version),
+         session->rsp.state_code,session->rsp.is_chunked,session->rsp.content_length);
+
+    return 0;
+}
+
+static int http_session_start_write(mbtk_http_session_t *session)
+{
+    RLOGD("Start HTTP write.");
+
+#define BUFFER_SIZE 1024
+    session->state = HTTP_SESSION_STATE_WRITE_HEADER;
+    char buff[BUFFER_SIZE];
+    int len = 0;
+    int index = 0;
+    len += snprintf(buff + len,BUFFER_SIZE - len,"%s %s HTTP/%s\r\n",
+                    http_option_str_get(session->option),
+                    session->uri,
+                    http_version_str_get(session->version));
+
+    // if no set "Host",should set default host.
+    char *host = http_header_find(session,"Host");
+    if(!host)
+    {
+        len += snprintf(buff + len,BUFFER_SIZE - len,"Host: %s\r\n", session->host);
+    }
+
+    if(mbtk_http_write(session->sock_fd,buff,len) != len)
+    {
+        RLOGD("mbtk_http_write() fail.");
+        return -1;
+    }
+
+    char header_str[BUFFER_SIZE];
+    int header_str_len = 0;
+    while(index < HTTP_REQUEST_HEADER_MAX)
+    {
+        if(session->req.req_h[index] &&
+           (header_str_len = http_header_str_get(session->req.req_h[index], header_str, BUFFER_SIZE)) > 0)
+        {
+            if(mbtk_http_write(session->sock_fd,header_str,header_str_len) != header_str_len)
+            {
+                RLOGD("mbtk_http_write() fail.");
+                return -1;
+            }
+        }
+        index++;
+    }
+
+    // Write request header success.
+    RLOGD("HTTP write header complete.");
+
+#undef BUFFER_SIZE
+
+    // Write "\r\n"
+    if(mbtk_http_write(session->sock_fd,"\r\n",2) != 2)
+    {
+        RLOGD("mbtk_http_write() fail.");
+        return -1;
+    }
+
+    RLOGD("Start write HTTPsession->option. %d", session->option);
+    if(session->option == HTTP_OPTION_POST)
+    {
+        session->state = HTTP_SESSION_STATE_WRITE_CONTENT;
+        RLOGD("Start write HTTP content data.");
+
+        if(session->req.content && session->req.content_len > 0)
+        {
+            if(mbtk_http_write(session->sock_fd,session->req.content,session->req.content_len) != session->req.content_len)
+            {
+                RLOGD("mbtk_http_write() fail.");
+                return -1;
+            }
+
+            session->state = HTTP_SESSION_STATE_WRITE_END;
+        }
+    }
+    else
+    {
+        session->state = HTTP_SESSION_STATE_WRITE_END;
+
+        RLOGD("HTTP write complete.");
+    }
+    return 0;
+}
+
+/*static int http_session_read_by_chunk(mbtk_http_session_t *session)
+{
+#undef BUFFER_SIZE
+#define BUFFER_SIZE 2048
+    http_chunk_code chunk_code;
+    http_chunker_t chunker;
+    char read_buf[BUFFER_SIZE + 1];
+    int read_len = 0;
+    char chunk_buf[BUFFER_SIZE + 1];
+    int chunk_len;
+    http_chunk_init(&chunker);
+    while(TRUE)
+    {
+        read_len = mbtk_http_read(session->sock_fd,read_buf,BUFFER_SIZE,3000);
+        //read_len = mbtk_http_read_line(session->sock_file,read_buf,BUFFER_SIZE);
+        if(read_len <= 0)
+        {
+            RLOGD("Read fail.");
+            return -1;
+        }
+
+        chunk_code = http_chunk_parse(&chunker, read_buf, read_len, chunk_buf, &chunk_len);
+        if(chunk_code > CHUNKE_OK)   // Fail.
+        {
+            RLOGD("http_chunk_parse() fail[err - %d].",chunk_code);
+            return -1;
+        }
+
+        RLOGD("Read chunk_len:%d",chunk_len);
+        chunk_buf[chunk_len] = '\0';
+
+        if(http_handles[session->handle_id].data_cb)
+            http_handles[session->handle_id].data_cb(session->id,
+                    MBTK_HTTP_DATA_CONTENT,chunk_buf,chunk_len);
+
+        if(CHUNKE_STOP == chunk_code)
+        {
+            if(http_handles[session->handle_id].data_cb)
+                http_handles[session->handle_id].data_cb(session->id,
+                        MBTK_HTTP_DATA_COMPLETE,NULL,0);
+
+            break;
+        }
+    }
+
+    RLOGD("Chunk read success.");
+
+    return 0;
+}*/
+
+static int http_session_read_by_length(mbtk_http_session_t *session)
+{
+#undef BUFFER_SIZE
+#define BUFFER_SIZE 2048
+    char read_buf[BUFFER_SIZE + 1];
+    int read_len = 0;
+    int64 read_count = 0;
+    while(TRUE)
+    {
+        memset(read_buf,0x0,BUFFER_SIZE + 1);
+        read_len = mbtk_http_read(session->sock_fd,read_buf,BUFFER_SIZE,3000);
+        if(read_len <= 0)
+        {
+            RLOGD("Read fail.");
+            return -1;
+        }
+
+        if(read_count + read_len >= session->rsp.content_length)   // Read data complete.
+        {
+            if(http_handles[session->handle_id].data_cb)
+            {
+                http_handles[session->handle_id].data_cb(session->id,
+                        MBTK_HTTP_DATA_CONTENT,read_buf,session->rsp.content_length - read_count);
+
+                http_handles[session->handle_id].data_cb(session->id,
+                        MBTK_HTTP_DATA_COMPLETE,NULL,0);
+            }
+            break;
+        }
+
+        if(http_handles[session->handle_id].data_cb)
+            http_handles[session->handle_id].data_cb(session->id,
+                    MBTK_HTTP_DATA_CONTENT,read_buf,read_len);
+
+        read_count += read_len;
+    }
+
+    return 0;
+}
+
+static int http_session_read_by_general(mbtk_http_session_t *session)
+{
+#undef BUFFER_SIZE
+#define BUFFER_SIZE 2048
+    char read_buf[BUFFER_SIZE + 1];
+    int read_len = 0;
+    while(TRUE)
+    {
+        read_len = mbtk_http_read(session->sock_fd,read_buf,BUFFER_SIZE,1000);
+        if(read_len <= 0)
+        {
+            if(read_len == -2 || read_len == 0) // Timeout or end
+                break;
+
+            RLOGD("Read end[read_len - %d].",read_len);
+            //return -1;
+            break;
+        }
+
+        read_buf[read_len] = '\0';
+
+        if(http_handles[session->handle_id].data_cb)
+            http_handles[session->handle_id].data_cb(session->id,
+                    MBTK_HTTP_DATA_CONTENT,read_buf,read_len);
+    }
+
+    if(http_handles[session->handle_id].data_cb)
+        http_handles[session->handle_id].data_cb(session->id,
+                MBTK_HTTP_DATA_COMPLETE,NULL,0);
+
+    return 0;
+}
+
+static int http_session_start_read(mbtk_http_session_t *session)
+{
+    RLOGD("Start HTTP read.");
+    int result = 0;
+//    usleep(500000);
+    session->state = HTTP_SESSION_STATE_READ_HEADER;
+    if(http_header_read(session))
+    {
+        result = -1;
+        goto read_end;
+    }
+
+    if(session->option != HTTP_OPTION_HEAD)
+    {
+        session->state = HTTP_SESSION_STATE_READ_CONTENT;
+        /*if(session->rsp.is_chunked)
+        {
+            if(http_session_read_by_chunk(session))
+            {
+                result = -1;
+                goto read_end;
+            }
+        }*/
+        if(session->rsp.content_length > 0)
+        {
+            if(http_session_read_by_length(session))
+            {
+                result = -1;
+                goto read_end;
+            }
+        }
+        else
+        {
+            if(http_session_read_by_general(session))
+            {
+                result = -1;
+                goto read_end;
+            }
+        }
+    }
+    else
+    {
+        if(http_handles[session->handle_id].data_cb)
+            http_handles[session->handle_id].data_cb(session->id,
+                    MBTK_HTTP_DATA_COMPLETE,NULL,0);
+    }
+
+read_end:
+    session->state = HTTP_SESSION_STATE_READ_END;
+
+    RLOGD("HTTP request complete[result - %d].",result);
+    if(http_session_close(session))
+    {
+        return -1;
+    }
+
+#if 0
+    // Free session after HTTP request complete.
+    http_session_free(session);
+    http_handles[handle_id].session[session_id] = NULL;
+    http_handles[handle_id].session_cnt--;
+#endif
+
+    return result;
+}
+
+static bool http_session_req_check(mbtk_http_session_t *session)
+{
+    if(session == NULL || session->port == 0 ||
+       strlen(session->host) == 0)
+    {
+        RLOGD("Session not set host or port.");
+        return FALSE;
+    }
+
+    if(session->option != HTTP_OPTION_HEAD &&
+       session->option != HTTP_OPTION_POST &&
+       session->option != HTTP_OPTION_GET)
+    {
+        RLOGD("Only support HEAD/GET/POST");
+        return FALSE;
+    }
+
+#if 0
+    if(session->version != HTTP_VERSION_1_0 &&
+       session->version != HTTP_VERSION_1_1)
+    {
+        RLOGD("Only support HTTP 1.0/1.1");
+        return FALSE;
+    }
+#endif
+
+    if(session->option == HTTP_OPTION_POST)
+    {
+        char *value = NULL;
+        value = http_header_find(session, "Content-Length");
+        if(!value)
+        {
+            RLOGD("POST must set 'Content-Length'");
+            return FALSE;
+        }
+        if(session->req.content_len != atoi(value))
+        {
+            RLOGD("POST 'Content-Length' error.");
+            return FALSE;
+        }
+
+        value = http_header_find(session, "Content-Type");
+        if(!value)
+        {
+            RLOGD("POST must set 'Content-Type'");
+            return FALSE;
+        }
+    }
+
+    return TRUE;
+}
+
+
+/*************************************************************
+    Public Function Definitions
+*************************************************************/
+int mbtk_http_handle_get(bool show_rsp_header,mbtk_http_data_callback_func data_cb)
+{
+    int index = 0;
+    int i = 0;
+    for(; index < HTTP_HANDLE_MAX; index++)
+    {
+        if(http_handles[index].id < 0)   // Find free handle
+        {
+            break;
+        }
+    }
+
+    if(index == HTTP_HANDLE_MAX)
+    {
+        RLOGD("HTTP Handle is full.");
+        return -1;
+    }
+
+    memset(&(http_handles[index]),0x0,sizeof(mbtk_http_handle_t));
+    http_handles[index].id = index;
+    http_handles[index].show_rsp_header = show_rsp_header;
+    http_handles[index].data_cb = data_cb;
+    http_handles[index].session_cnt = 0;
+    for(i = 0; i < HTTP_SESSION_MAX; i++)
+    {
+        http_handles[index].session[i] = NULL;
+    }
+
+    if(mbtk_http_init())
+    {
+        RLOGD("mbtk_http_init() fail.");
+        return -1;
+    }
+
+    return http_handles[index].id;
+}
+
+int mbtk_http_handle_free(int handle_id)
+{
+    int i = 0;
+    if(!http_handle_check(handle_id))
+    {
+        RLOGD("Handle error.");
+        return -1;
+    }
+
+    http_handles[handle_id].id = -1;
+    http_handles[handle_id].data_cb = NULL;
+    if(http_handles[handle_id].session_cnt > 0)
+    {
+        for(i = 0; i < HTTP_SESSION_MAX; i++)
+        {
+            if(http_handles[handle_id].session[i] != NULL)
+            {
+                if(http_handles[handle_id].session[i]->state != HTTP_SESSION_STATE_NON)
+                {
+                    if(http_session_close(http_handles[handle_id].session[i]))
+                    {
+                        return -1;
+                    }
+                }
+
+                http_session_free(http_handles[handle_id].session[i]);
+                http_handles[handle_id].session[i] = NULL;
+            }
+        }
+
+        http_handles[handle_id].session_cnt = 0;
+    }
+
+    if(mbtk_http_deinit())
+    {
+        RLOGD("mbtk_http_deinit() fail.");
+        return -1;
+    }
+
+    return 0;
+}
+
+int mbtk_http_session_create(int handle_id, mbtk_http_option_enum option,
+                             mbtk_http_version_enum version)
+{
+    int handle_index = 0;
+    int session_index = 0;
+    if(!http_handle_check(handle_id))
+    {
+        RLOGD("Handle error.");
+        return -1;
+    }
+
+    for(; handle_index < HTTP_HANDLE_MAX; handle_index++)
+    {
+        if(http_handles[handle_index].id == handle_id)   // Find handle
+        {
+            break;
+        }
+    }
+
+    if(handle_index == HTTP_HANDLE_MAX)
+    {
+        RLOGD("No found handle[handle - %d].",handle_id);
+        return -1;
+    }
+
+    if(http_handles[handle_index].session_cnt >= HTTP_SESSION_MAX)
+    {
+        RLOGD("Session is full.");
+        return -1;
+    }
+
+    for(; session_index < HTTP_SESSION_MAX; session_index++)
+    {
+        if(http_handles[handle_index].session[session_index] == NULL)   // Find first NULL session
+        {
+            break;
+        }
+    }
+
+    if(session_index == HTTP_SESSION_MAX)
+    {
+        RLOGD("Session is full.");
+        return -1;
+    }
+
+    mbtk_http_session_t* session = (mbtk_http_session_t*)malloc(sizeof(mbtk_http_session_t));
+    if(session == NULL)
+    {
+        RLOGD("malloc() fail.");
+        return -1;
+    }
+    memset(session,0x0,sizeof(mbtk_http_session_t));
+    session->sock_fd = -1;
+    session->sock_file = NULL;
+    session->handle_id = handle_id;
+    session->id = session_index;
+    session->state = HTTP_SESSION_STATE_NON;
+    session->is_ssl = FALSE;
+    session->version = version;
+    session->option = option;
+    session->req.content_len = 0;
+    session->req.content_len_send = 0;
+    session->rsp.is_chunked = FALSE;
+    session->rsp.content_length = 0;
+    session->rsp.header_cnt = 0;
+    http_handles[handle_index].session[session_index] = session;
+    http_handles[handle_index].session_cnt++;
+
+    return session->id;
+}
+
+int mbtk_http_session_option_reset(int handle_id, int session_id, mbtk_http_option_enum option)
+{
+    if(!http_session_check(handle_id,session_id))
+    {
+        RLOGD("Session error.");
+        return -1;
+    }
+
+    mbtk_http_session_t *session = http_handles[handle_id].session[session_id];
+    if(session->state != HTTP_SESSION_STATE_NON)
+    {
+        RLOGD("Session state error.[%d]",session->state);
+        return -1;
+    }
+
+    session->option = option;
+    return 0;
+}
+
+int mbtk_http_session_free(int handle_id,int session_id)
+{
+    if(!http_session_check(handle_id,session_id))
+    {
+        RLOGD("Session error.");
+        return -1;
+    }
+
+    mbtk_http_session_t *session = http_handles[handle_id].session[session_id];
+    if(session->state != HTTP_SESSION_STATE_NON)
+    {
+        if(http_session_close(session))
+        {
+            return -1;
+        }
+    }
+
+    http_session_free(session);
+    http_handles[handle_id].session[session_id] = NULL;
+    http_handles[handle_id].session_cnt--;
+    return 0;
+}
+
+int mbtk_http_session_url_set(int handle_id,int session_id,void *url)
+{
+    if(!http_session_check(handle_id,session_id))
+    {
+        RLOGD("Session error.");
+        return -1;
+    }
+
+    mbtk_http_session_t *session = http_handles[handle_id].session[session_id];
+    if(session->state == HTTP_SESSION_STATE_NON)
+        return http_url_parse(url, session->host,session->uri,&(session->port),&(session->is_ssl));
+    else
+    {
+        RLOGD("Currenr session is process[state - %d].",session->state);
+        return -1;
+    }
+}
+
+int mbtk_http_session_head_add(int handle_id,int session_id,
+                               char *name, char *value)
+{
+    if(!http_session_check(handle_id,session_id))
+    {
+        RLOGD("Session error.");
+        return -1;
+    }
+
+    if(http_str_empty(name) || http_str_empty(value))
+    {
+        RLOGD("Param error.");
+        return -1;
+    }
+
+    mbtk_http_session_t *session = http_handles[handle_id].session[session_id];
+    if(session->state == HTTP_SESSION_STATE_NON)
+    {
+        int result = http_session_req_head_add(session,TRUE,name,value);
+        if(!result && !strncasecmp(name,"Content-Length",14))
+        {
+            session->req.content_len = atoi(value);
+        }
+        return result;
+    }
+    else
+    {
+        RLOGD("Currenr session is process[state - %d].",session->state);
+        return -1;
+    }
+}
+
+int mbtk_http_session_content_set(int handle_id,int session_id,
+                                  char *content,uint32 content_len)
+{
+    if(!http_session_check(handle_id,session_id))
+    {
+        RLOGD("Session error.");
+        return -1;
+    }
+
+    if(content_len <= 0 || content_len > HTTP_CONTENT_LEN_MAX)
+    {
+        RLOGD("Content lenght error[%d].",content_len);
+        return -1;
+    }
+
+    mbtk_http_session_t *session = http_handles[handle_id].session[session_id];
+    if(session->state == HTTP_SESSION_STATE_NON)
+    {
+        if(session->option != HTTP_OPTION_POST)
+        {
+            RLOGD("Content only for post.");
+            return -1;
+        }
+
+        if(session->req.content)
+        {
+            free(session->req.content);
+            session->req.content_len = 0;
+        }
+
+        session->req.content = (char*)malloc(content_len);
+        if(session->req.content == NULL)
+        {
+            RLOGD("malloc() fail.");
+            return -1;
+        }
+
+        char *content_type = NULL;
+        if(strlen(content) == content_len)   //
+        {
+            content_type = "text/plain";
+        }
+        else
+        {
+            content_type = "application/octet-stream";
+        }
+
+        if(http_session_req_head_add(session, FALSE, "Content-Type", content_type))
+        {
+            RLOGD("Set 'Content-Type' fail.");
+            return -1;
+        }
+
+        memcpy(session->req.content,content,content_len);
+        session->req.content_len = content_len;
+
+        char len_str[20] = {0};
+        snprintf(len_str,20,"%d",content_len);
+        if(http_session_req_head_add(session,FALSE,"Content-Length",len_str))
+        {
+            RLOGD("Set 'Content-Length' fail.");
+            return -1;
+        }
+
+
+        return 0;
+    }
+    else
+    {
+        RLOGD("Currenr session is process[state - %d].",session->state);
+        return -1;
+    }
+}
+
+int mbtk_http_session_start(int handle_id,int session_id)
+{
+    if(!http_session_check(handle_id,session_id))
+    {
+        printf("Session error.");
+        return -1;
+    }
+
+    mbtk_http_session_t *session = http_handles[handle_id].session[session_id];
+    if(session->state == HTTP_SESSION_STATE_NON)
+    {
+        if(!http_session_req_check(session))
+        {
+            printf("http_session_req_check() fail.");
+            return -1;
+        }
+
+        // Must set "Connection" for post.
+        if(session->option == HTTP_OPTION_POST)
+        {
+            if(http_session_req_head_add(session,FALSE,"Connection","KeepAlive"))
+            {
+                printf("Set 'Content-Length' fail.");
+                return -1;
+            }
+        }
+
+        printf("HTTP request start.\n");
+        printf("host:%s\n, port:%d\n, uri:%s\n",session->host,session->port,session->uri);
+        printf("is_ssl:%d\n, version:%d\n, option:%d\n, content_len:%d\n",session->is_ssl,
+             session->version,session->option,session->req.content_len);
+
+        int sock_fd = mbtk_http_open(session->host,&(session->port));//session->is_ssl,TRUE,
+        if(sock_fd < 0)
+        {
+            printf("open fail\n");
+            return -1;
+        }
+        session->sock_fd = sock_fd;
+//        int fd = mbtk_sock_fd_get(sock_fd);
+//        if(fd < 0) {
+//            LOGE("mbtk_sock_fd_get() fail.");
+//            return -1;
+//        }
+        // session->sock_file = fdopen(sock_fd,"r");
+        session->state = HTTP_SESSION_STATE_CONN;
+
+//        if(!session->sock_file) {
+//            LOGE("fdopen() fail.");
+//            return -1;
+//        }
+
+        printf("HTTP connected.");
+
+        if(http_session_start_write(session))
+        {
+            return -1;
+        }
+
+        if(session->state == HTTP_SESSION_STATE_WRITE_END)
+        {
+            if(http_session_start_read(session))
+            {
+                return -1;
+            }
+        }
+        else
+        {
+            printf("Waitting post content data...");
+        }
+
+        return 0;
+    }
+    else
+    {
+        printf("Currenr session is process[state - %d].",session->state);
+        return -1;
+    }
+}
+
+int mbtk_http_session_content_send(int handle_id,int session_id,
+                                   char *data,int data_len)
+{
+    if(!http_session_check(handle_id,session_id))
+    {
+        RLOGD("Session error.");
+        return -1;
+    }
+
+    if(data_len <= 0 || data_len > HTTP_CONTENT_LEN_MAX)
+    {
+        RLOGD("Content lenght error[%d].",data_len);
+        return -1;
+    }
+
+    RLOGD("Post send:%d - %s",data_len,data);
+
+    mbtk_http_session_t *session = http_handles[handle_id].session[session_id];
+    if(session->state == HTTP_SESSION_STATE_WRITE_CONTENT)
+    {
+        if(session->option != HTTP_OPTION_POST)
+        {
+            RLOGD("Content only for post.");
+            return -1;
+        }
+
+        if(session->req.content || session->req.content_len <= 0)
+        {
+            RLOGD("This post not spit package.");
+            return -1;
+        }
+
+        // Discard excess data.
+        if(session->req.content_len_send + data_len > session->req.content_len)
+            data_len = session->req.content_len - session->req.content_len_send;
+
+        if(data_len != mbtk_http_write(session->sock_fd,data,data_len))
+        {
+            return -1;
+        }
+
+        session->req.content_len_send += data_len;
+
+        RLOGD("HTTP post data send: %d / %d",session->req.content_len_send,
+             session->req.content_len);
+
+        // Post data send complete.
+        if(session->req.content_len_send >= session->req.content_len)
+        {
+            session->state = HTTP_SESSION_STATE_WRITE_END;
+
+            RLOGD("HTTP write complete.");
+            if(http_session_start_read(session))
+            {
+                return -1;
+            }
+        }
+
+        return 0;
+    }
+    else
+    {
+        RLOGD("Currenr session state error[%d].",session->state);
+        return -1;
+    }
+}
+
+const mbtk_http_session_t* mbtk_http_session_get(int handle_id,int session_id)
+{
+    if(!http_session_check(handle_id,session_id))
+    {
+        RLOGD("Session error.");
+        return NULL;
+    }
+
+    return http_handles[handle_id].session[session_id];
+}
+
+#ifdef __cplusplus
+}
+#endif
\ No newline at end of file
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/src/mbtk_http_base.cpp b/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/src/mbtk_http_base.cpp
new file mode 100755
index 0000000..607a199
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/src/mbtk_http_base.cpp
@@ -0,0 +1,240 @@
+#include <sys/epoll.h>
+#include <string.h>
+#include <log/log.h>
+#include <liblog/lynq_deflog.h>
+//#include "mbtk_log.h"
+#include "mbtk_http_base.h"
+#include "mbtk_http.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static bool http_sock_inited = FALSE;
+static int http_handle = -1;
+static int http_fd = -1;
+//static void http_sock_cb_func(int handle, int fd, int event);
+
+/*static mbtk_init_info =
+{
+    MBTK_NET_LINUX,
+    NULL,
+    http_sock_cb_func
+} http_init_info;*/
+
+
+
+/*static void http_sock_cb_func(int handle, int fd, int event)
+{
+    if(http_handle == handle && http_fd == fd) {
+        if(event & EPOLLIN) { // READ
+
+        } else if(event & EPOLLRDHUP) { // Close
+
+        } else {
+            RLOGD("Unknown event:%x",event);
+        }
+    }
+}*/
+
+int mbtk_sock_open()
+{
+
+    return 0;
+}
+
+int mbtk_http_init()
+{
+    if(http_sock_inited) {
+        RLOGD("HTTP has inited.");
+        return -1;
+    }
+
+    http_handle = socket(AF_INET,SOCK_STREAM,0);
+    if(http_handle < 0)
+    {
+        RLOGD("mbtk_sock_init() fail.");
+        return -1;
+    }
+
+    http_sock_inited = TRUE;
+    return 0;
+}
+
+int mbtk_http_deinit()
+{
+    if(!http_sock_inited) {
+        RLOGD("HTTP not inited.");
+        return -1;
+    }
+
+    close(http_handle);
+    http_handle = -1;
+    http_sock_inited = FALSE;
+    return 0;
+}
+
+
+int mbtk_http_open
+(
+    const void *host,
+    int *port
+)
+{
+    struct addrinfo server;
+    struct addrinfo* serverInfo;
+    int ret;
+
+    server.ai_family = AF_INET;
+    server.ai_socktype = SOCK_STREAM;
+    server.ai_protocol = IPPROTO_TCP;
+    server.ai_flags = AI_PASSIVE;
+    char portStr[6];
+    snprintf(portStr, sizeof(portStr), "%d", *port);
+    memset(&server, 0, sizeof(server));
+    ret = getaddrinfo(host, portStr, &server, &serverInfo);
+    if (ret != 0)
+    {
+        printf("ret = %s\n",gai_strerror(ret));
+        printf("getaddrinfo error: \n");
+        return -1;
+    }
+    ret = connect(http_handle, serverInfo->ai_addr, serverInfo->ai_addrlen);
+    if(ret < 0)
+    {
+        printf("connect fail http_handle:%d\n",http_handle);
+        close(http_handle);
+        freeaddrinfo(serverInfo);
+        return -1;
+    }
+    printf("http_handle: %d\n",http_handle);
+    return http_handle;
+}
+
+/*=============================================
+FUNCTION
+    mbtk_http_read
+
+DESCRIPTION
+    read content from socket.
+
+DEPENDENCIES
+    None
+
+PARAMETERS
+    *buf      Store read content.
+    len       the length of Content.
+    timeout   Set timeout
+
+RETURN VALUE
+    Length of read content
+
+SIDE EFFECTS
+    None
+=============================================*/
+int mbtk_http_read
+(
+    int sock_fd,
+    void *buf,
+    uint16_t len,
+    int timeout_ms
+)
+{
+    sleep(timeout_ms / 1000);
+    int read_len = recv(sock_fd, buf, len, 0);
+    if(read_len < 0)
+    {
+            return -1;
+    }
+    else
+    {
+        return read_len;
+    }
+}
+
+
+int mbtk_http_read_line
+(
+    int sock_fd,
+    void *buf,
+    uint16_t len
+)
+{
+    if(sock_fd > 0) {
+        char *buf_ptr = (char*)buf;
+        char read_buf[1];
+        int read_len = 0;
+        while(TRUE) {
+            if(recv(sock_fd, read_buf, 1, 0) == 1) {
+                *buf_ptr++ = read_buf[0];
+                read_len++;
+
+                if(read_buf[0] == '\n' || read_len >= len) {
+                    return read_len;
+                }
+            } else {
+                return -1;
+            }
+        }
+    }
+
+
+    return -1;
+}
+
+
+/*=============================================
+FUNCTION
+    mbtk_http_write
+
+DESCRIPTION
+    Write content to socket.
+
+DEPENDENCIES
+    None
+
+PARAMETERS
+    *buf    Content to be transferred
+    len     the length of Content.
+
+RETURN VALUE
+    Length of written content
+
+SIDE EFFECTS
+    None
+=============================================*/
+int mbtk_http_write(int sock_fd, void *buf, uint16_t len)
+{
+    RLOGD("Write[%d]:%s",len,(char*)buf);
+    return send(sock_fd, buf, len, 0);
+}
+
+/*=============================================
+FUNCTION
+    mbtk_http_close
+
+DESCRIPTION
+    close HTTP service.
+
+DEPENDENCIES
+    None
+
+PARAMETERS
+    *err    Error number
+
+RETURN VALUE
+    TURE or FALSE
+
+SIDE EFFECTS
+    None
+=============================================*/
+int mbtk_http_close(int sock_fd)
+{
+
+    close(sock_fd);
+    sock_fd = -1;
+    return 0;
+}
+
+#ifdef __cplusplus
+}
+#endif
\ No newline at end of file
diff --git a/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/arch/arm/boot/dts/zx297520v3-pinctrl.dtsi b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/arch/arm/boot/dts/zx297520v3-pinctrl.dtsi
index 3da6c4e..f9f558d 100755
--- a/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/arch/arm/boot/dts/zx297520v3-pinctrl.dtsi
+++ b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/arch/arm/boot/dts/zx297520v3-pinctrl.dtsi
@@ -346,7 +346,7 @@
 	};
 
 	sc_ext_int10: sc_ext_int10 {
-		pins = "EXT_INT10";
+		pins = "GPIO129";   /*jb.qi add for EXT_INIT10 success*/
 		function = "EXT_INT10";
 		bias-disable;
 	};
diff --git a/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/arch/arm/boot/dts/zx297520v3-vehicle_dc_ref.dts b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/arch/arm/boot/dts/zx297520v3-vehicle_dc_ref.dts
index 1067603..da48fcc 100755
--- a/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/arch/arm/boot/dts/zx297520v3-vehicle_dc_ref.dts
+++ b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/arch/arm/boot/dts/zx297520v3-vehicle_dc_ref.dts
@@ -130,14 +130,14 @@
 //	status = "okay";
 };
 &codec_ti3104 {
-//	status = "okay";
+	status = "okay";
 };	
 &zx29_ti3104 {
 	pinctrl-0 = <&i2s0_pins>;
-//	status = "okay";
+	status = "okay";
 };
 &codec_nau8810 {
-	status = "okay";
+//	status = "okay";
 };	
 &zx29_nau8810 {
 	pinctrl-0 = <&i2s0_pins>;
@@ -155,11 +155,11 @@
 //	status = "okay";
 };
 &codec_es8311 {
-	status = "okay";
+//	status = "okay";
 };	
 &zx29_es8311 {
 	pinctrl-0 = <&i2s0_pins>;
-	status = "okay";
+//	status = "okay";
 };
 &gmac {
     port-nums = <1>;
@@ -190,7 +190,7 @@
 	
 	label = "GPIO Key USER1";//ap int
 	linux,code = <KEY_STOP>;
-	status = "okay";
+	status = "disabled";
 };
 &gpio_key1 {
 	//autorepeat;
diff --git a/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/arch/arm/boot/dts/zx297520v3.dtsi b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/arch/arm/boot/dts/zx297520v3.dtsi
index 24faec9..7a57181 100755
--- a/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/arch/arm/boot/dts/zx297520v3.dtsi
+++ b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/arch/arm/boot/dts/zx297520v3.dtsi
@@ -488,13 +488,13 @@
 			codec_ti3104: ti3104@18 {         
 				compatible = "ti,tlv320aic3104";
 				reg = <0x18>;		
-				reset-gpios = <&bgpio 122 GPIO_ACTIVE_HIGH>;/*RST*/
+				reset-gpios = <&bgpio 119 GPIO_ACTIVE_HIGH>;/*RST*/
 				ai3x-micbias-vg = <MICBIAS_2_0V>;
 
-				clocks = <&clkc CLKOUT1_CLK>;
+				clocks = <&clkc CLKOUT2_CLK>;
 				clock-names = "clk_out";			
 				pinctrl-names = "clk_out","reset_gpio122";			
-				pinctrl-0 = <&clk1_func_pins>;
+				pinctrl-0 = <&clk2_func_pins>;
 				pinctrl-1 = <&codec_reset_pins>;
 				status = "disabled";
 			};
diff --git a/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/sound/soc/codecs/tlv320aic3x.c b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/sound/soc/codecs/tlv320aic3x.c
index 4f01cbc..09ef085 100755
--- a/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/sound/soc/codecs/tlv320aic3x.c
+++ b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/sound/soc/codecs/tlv320aic3x.c
@@ -1018,6 +1018,15 @@
 	struct aic3x_priv *info = dev_get_drvdata(dev);
 	struct device_node *np = dev->of_node;
 
+        #if 1
+        unsigned tmp;
+        void __iomem 	*reg_base;
+        reg_base = ioremap(0x13B000+0x94 ,4);
+        tmp  = ioread32(reg_base);
+        tmp |= (1<<0)|(1<<2);
+        iowrite32(tmp,reg_base);
+        #endif
+
 	dev_info(dev, "%s:start!\n", __func__);
 
 	if(dev == NULL){
@@ -1059,7 +1068,7 @@
 	
 	clk = of_clk_get_by_name(np, "clk_out");	
 	if (IS_ERR(clk)) {
-		dev_err(dev, "Could not get clk_out\n");
+		dev_err(dev, "Could not get clk_out0\n");
 		ret = PTR_ERR(clk);
 		goto err_put_pinctrl;
 	}			
@@ -1203,7 +1212,7 @@
 		regmap_read(info->regmap, AIC3X_PAGE_SELECT, &pre_page);
 	
 		regmap_write(info->regmap, AIC3X_PAGE_SELECT, 0);
-		for (i = regmin; i < regmax; i++) {
+		for (i = regmin; i <= regmax; i++) {
 	
 			//val = snd_soc_component_read(info->component, i); 	
 			regmap_read(info->regmap, i, &val);
@@ -1260,6 +1269,7 @@
 		if( ret == 0)
 		{
 			dev_info(dev, "reg_read start\n");
+			/*
 			if(param1 > 1){
 				dev_err(dev, "reg_read param invalidate fail,param1=%d \n",param1);
 				return -1;		
@@ -1268,10 +1278,14 @@
 			if(param2 > regmax){
 				dev_err(dev, "reg_read param invalidate fail,param2=%d \n",param2);
 				return -1;		
-			}	
-	
+			}
+		        */
 
-			
+                        if(param1 < 0 || param1 > 109){
+				dev_err(dev, "reg_read param invalidate fail,param1=%d \n",param1);
+				return -1;
+			}
+
 			regmap_read(info->regmap, AIC3X_PAGE_SELECT, &pre_page);
 			
 			regmap_write(info->regmap, AIC3X_PAGE_SELECT, regpage);
@@ -1295,6 +1309,8 @@
 			//u32 offset = param1;
 			//u32 mask = param2;
 			dev_info(dev, "reg_write start\n");  
+
+			/*
 			if(param1 > 1){
 				dev_err(dev, "reg_write param invalidate fail,param1=%d \n",param1);
 				return -1;		
@@ -1303,9 +1319,14 @@
 			if(param2 > regmax){
 				dev_err(dev, "reg_write param invalidate fail,param1=%d \n",param1);
 				return -1;		
-			}	
+			}
+			*/
 
-			
+			if(param1 < 0 || param1 > 109){
+				dev_err(dev, "reg_write param invalidate fail,param1=%d \n",param1);
+				return -1;
+			}
+
 			regmap_read(info->regmap, AIC3X_PAGE_SELECT, &pre_page);
 			
 			regmap_write(info->regmap, AIC3X_PAGE_SELECT, regpage);
@@ -1846,13 +1867,15 @@
 	.name = "tlv320aic3x-hifi",
 	.playback = {
 		.stream_name = "Playback",
-		.channels_min = 2,
+		//.channels_min = 2,
+		.channels_min = 1,
 		.channels_max = 2,
 		.rates = AIC3X_RATES,
 		.formats = AIC3X_FORMATS,},
 	.capture = {
 		.stream_name = "Capture",
-		.channels_min = 2,
+		//.channels_min = 2,
+		.channels_min = 1,
 		.channels_max = 2,
 		.rates = AIC3X_RATES,
 		.formats = AIC3X_FORMATS,},