Squashed 'LYNQ_PUBLIC/' content from commit 79d8f932f

git-subtree-dir: LYNQ_PUBLIC
git-subtree-split: 79d8f932fb4ebc4b5aec6c5ace97634912394272
Change-Id: If2527ba937f56fe989487bf71e996f7cfd9fbe61
diff --git a/IC_src/mtk/lib/liblynq-codec/LICENSE b/IC_src/mtk/lib/liblynq-codec/LICENSE
new file mode 100644
index 0000000..77f59ed
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-codec/LICENSE
@@ -0,0 +1,31 @@
+Copyright Statement:
+
+This software/firmware and related documentation ("MediaTek Software") are
+protected under relevant copyright laws. The information contained herein is
+confidential and proprietary to MediaTek Inc. and/or its licensors. Without
+the prior written permission of MediaTek inc. and/or its licensors, any
+reproduction, modification, use or disclosure of MediaTek Software, and
+information contained herein, in whole or in part, shall be strictly
+prohibited.
+
+MediaTek Inc. (C) 2015. All rights reserved.
+
+BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ON AN "AS-IS" BASIS ONLY. MEDIATEK 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 MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
+RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK 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 MEDIATEK
+SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
+RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
+ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
+RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
+MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
diff --git a/IC_src/mtk/lib/liblynq-codec/Makefile b/IC_src/mtk/lib/liblynq-codec/Makefile
new file mode 100644
index 0000000..b24b4e8
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-codec/Makefile
@@ -0,0 +1,63 @@
+PREFIX   = ../install
+CROSS    = arm-none-linux-
+ROOT     = $(PREFIX)/$(CROSS:%-=%)
+
+#For Yocto use
+
+RFX_TEST_CLIENT = false
+RFX_TEST_AOSP = false
+
+$(warning ########## libvendor_ril BB_TELEFWK_OPTION $(BB_TELEFWK_OPTION) ##########)
+
+		   
+
+SUBDIRS +=  liblynq-codec
+
+
+
+
+
+$(warning ########## lynq-rilcmd SUBDIRS  $(SUBDIRS) ##########)
+export SIM_COUNT?=1
+
+.PHONY: all build clean pack_rootfs
+
+all: build
+
+build: clean
+
+clean:
+	$(warning ########## clean ril ##########)
+	for i in $(SUBDIRS); do			\
+		(cd $$i && make clean);			\
+		if [ $$? != 0 ]; then		\
+			exit 1;					\
+		fi							\
+	done
+
+build:
+	$(warning ########## build ril ##########)
+	for i in $(SUBDIRS); do			\
+		(cd $$i && make);			\
+		if [ $$? != 0 ]; then		\
+			exit 1;					\
+		fi							\
+	done
+
+install:
+	$(warning ########## install ril ##########)
+	for i in $(SUBDIRS); do			\
+		(cd $$i && make install);			\
+		if [ $$? != 0 ]; then		\
+			exit 1;					\
+		fi							\
+	done
+
+pack_rootfs:
+	$(warning ########## pack_rootfs ril ##########)
+	for i in $(SUBDIRS); do			\
+		(cd $$i && make pack_rootfs);			\
+		if [ $$? != 0 ]; then		\
+			exit 1;					\
+		fi							\
+	done
diff --git a/IC_src/mtk/lib/liblynq-codec/include/lynq_codec.h b/IC_src/mtk/lib/liblynq-codec/include/lynq_codec.h
new file mode 100755
index 0000000..2e3cf37
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-codec/include/lynq_codec.h
@@ -0,0 +1,29 @@
+#ifndef __LYNQ_CODEC_H__
+#define __LYNQ_CODEC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+     LYNQ_CALL = 1,
+     LYNQ_RTP,
+     LYNQ_MEDIA,
+}media_src_t;
+
+typedef enum {
+    CODEC_CLOSE = 0,
+    CODEC_OPEN,
+}codec_op;
+
+void set_codec(media_src_t src, codec_op open_close);
+const char * get_customer_tone_path();
+int get_customer_tone_sample_rate();
+int customer_set_pa_volume(const int volume);
+int customer_get_pa_volume(int* volume);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  //__LYNQ_CODEC_H__
diff --git a/IC_src/mtk/lib/liblynq-codec/liblynq-codec/lynq_codec.c b/IC_src/mtk/lib/liblynq-codec/liblynq-codec/lynq_codec.c
new file mode 100755
index 0000000..9cd770d
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-codec/liblynq-codec/lynq_codec.c
@@ -0,0 +1,486 @@
+#include <stdio.h>

+#include <stdlib.h>

+#include "lynq_codec.h"

+#include <syslog.h>

+#include <log/log.h>

+

+#define LOG_TAG "CODEC_API"

+

+static void write_codec_reg(const char * val)

+{

+    if (val == NULL)

+    {

+        RLOGE("Invalid input\n");

+        return;

+    }

+

+    FILE* fp=fopen("/sys/kernel/debug/regmap/0-0018/registers", "w");

+    if (fp == NULL)

+    {

+        RLOGE("Failed to open file\n");

+        return;

+    }

+    fwrite(val, strlen(val), 1, fp);

+    fclose(fp);

+}

+

+void set_zk_3104_codec(int open)

+{

+    RLOGD("set_codec %d",open);

+

+    if(open==0)

+    {

+        system("echo out 201 0 >/sys/devices/platform/10005000.pinctrl/mt_gpio");

+        system("echo out 113 0 >/sys/devices/platform/10005000.pinctrl/mt_gpio");

+        system("echo out 29 0 >/sys/devices/platform/10005000.pinctrl/mt_gpio");

+        /*dongyu@2023.7.12 ZK ADC/DAC power supply default off state, turn on during call, turn off after hang up start*/

+        write_codec_reg("0x13 0x00");

+        write_codec_reg("0x16 0x00");

+        write_codec_reg("0x25 0x00");

+        /*dongyu@2023.7.12 ZK ADC/DAC power supply default off state, turn on during call, turn off after hang up end*/

+    }

+    else

+    {

+        system("echo out 201 1 >/sys/devices/platform/10005000.pinctrl/mt_gpio");

+        usleep(10);//just open need usleep 10us

+        system("echo out 113 1 >/sys/devices/platform/10005000.pinctrl/mt_gpio");

+        usleep(10);//just open need usleep 10us

+        system("echo out 29 1 >/sys/devices/platform/10005000.pinctrl/mt_gpio");

+        write_codec_reg("0x00 0x00");

+        write_codec_reg("0x01 0x00");

+        write_codec_reg("0x02 0x00");

+        write_codec_reg("0x03 0x80");

+        write_codec_reg("0x04 0x04");

+        write_codec_reg("0x05 0x00");

+        write_codec_reg("0x06 0x00");

+        write_codec_reg("0x07 0xa0");

+        write_codec_reg("0x08 0x20");

+        write_codec_reg("0x09 0x00");

+        write_codec_reg("0x0a 0x00");

+        write_codec_reg("0x0b 0x32");

+        write_codec_reg("0x0c 0x00");

+        write_codec_reg("0x0d 0x00");

+        write_codec_reg("0x0f 0x10");

+        write_codec_reg("0x10 0x20");

+        write_codec_reg("0x11 0xf8");

+        write_codec_reg("0x12 0xff");

+        /*dongyu@2023.7.12 ZK ADC/DAC 0x13 power supply default off state, turn on during call, turn off after hang up*/

+        write_codec_reg("0x13 0x7a");

+        write_codec_reg("0x14 0x78");

+        write_codec_reg("0x15 0x00");

+        /*dongyu@2023.7.12 ZK ADC/DAC 0x16 power supply default off state, turn on during call, turn off after hang up*/

+        write_codec_reg("0x16 0x78");

+        write_codec_reg("0x17 0x78");

+        write_codec_reg("0x18 0x78");

+        write_codec_reg("0x19 0x80");

+        write_codec_reg("0x1a 0x00");

+        write_codec_reg("0x1b 0xfe");

+        write_codec_reg("0x1c 0x00");

+        write_codec_reg("0x1d 0x00");

+        write_codec_reg("0x1e 0xfe");

+        write_codec_reg("0x1f 0x00");

+        write_codec_reg("0x20 0x18");

+        write_codec_reg("0x21 0x18");

+        write_codec_reg("0x22 0x00");

+        write_codec_reg("0x23 0x00");

+        write_codec_reg("0x24 0xc0");

+        /*dongyu@2023.7.12 ZK ADC/DAC 0x25 power supply default off state, turn on during call, turn off after hang up*/

+        write_codec_reg("0x25 0xc0");

+        write_codec_reg("0x26 0x00");

+        write_codec_reg("0x27 0x00");

+        write_codec_reg("0x28 0x00");

+        write_codec_reg("0x29 0x00");

+        write_codec_reg("0x2a 0x00");

+        write_codec_reg("0x2b 0x02");

+        write_codec_reg("0x2c 0x02");

+        write_codec_reg("0x2d 0x00");

+        write_codec_reg("0x2e 0x02");

+        write_codec_reg("0x2f 0x85");

+        write_codec_reg("0x30 0x00");

+        write_codec_reg("0x31 0x80");

+        write_codec_reg("0x32 0x85");

+        write_codec_reg("0x33 0x9f");

+        write_codec_reg("0x34 0x00");

+        write_codec_reg("0x35 0x80");

+        write_codec_reg("0x36 0x82");

+        write_codec_reg("0x37 0x00");

+        write_codec_reg("0x38 0x00");

+        write_codec_reg("0x39 0x82");

+        write_codec_reg("0x3a 0x9f");

+        write_codec_reg("0x3b 0x00");

+        write_codec_reg("0x3c 0x00");

+        write_codec_reg("0x3d 0x00");

+        write_codec_reg("0x3e 0x00");

+        write_codec_reg("0x3f 0x80");

+        write_codec_reg("0x40 0xaf");

+        write_codec_reg("0x41 0x0d");

+        write_codec_reg("0x42 0x00");

+        write_codec_reg("0x43 0x80");

+        write_codec_reg("0x44 0x00");

+        write_codec_reg("0x45 0x00");

+        write_codec_reg("0x46 0x02");

+        write_codec_reg("0x47 0xaf");

+        write_codec_reg("0x48 0x0d");

+        write_codec_reg("0x49 0x00");

+        write_codec_reg("0x4a 0x00");

+        write_codec_reg("0x4b 0x00");

+        write_codec_reg("0x4c 0x00");

+        write_codec_reg("0x4d 0x00");

+        write_codec_reg("0x4e 0x00");

+        write_codec_reg("0x4f 0x00");

+        write_codec_reg("0x50 0x00");

+        write_codec_reg("0x51 0x00");

+        write_codec_reg("0x52 0x00");

+        write_codec_reg("0x53 0x00");

+        write_codec_reg("0x54 0x02");

+        write_codec_reg("0x55 0xbf");

+        write_codec_reg("0x56 0x9b");

+        write_codec_reg("0x57 0x00");

+        write_codec_reg("0x58 0x02");

+        write_codec_reg("0x59 0xbf");

+        write_codec_reg("0x5a 0x00");

+        write_codec_reg("0x5b 0x00");

+        write_codec_reg("0x5c 0xbf");

+        write_codec_reg("0x5d 0x08");

+        write_codec_reg("0x5e 0xde");

+        write_codec_reg("0x5f 0x0c");

+        write_codec_reg("0x60 0x00");

+        write_codec_reg("0x61 0x00");

+        write_codec_reg("0x62 0x00");

+        write_codec_reg("0x63 0x00");

+        write_codec_reg("0x64 0x00");

+        write_codec_reg("0x65 0x01");

+        write_codec_reg("0x66 0xa2");

+        write_codec_reg("0x67 0x00");

+        write_codec_reg("0x68 0x00");

+        write_codec_reg("0x69 0x00");

+        write_codec_reg("0x6a 0x00");

+        write_codec_reg("0x6b 0x00");

+        write_codec_reg("0x6c 0x40");

+        write_codec_reg("0x6d 0x00");

+    }

+}

+

+/*hqing add for Geely demand on 11/07/2022, after playing audio, codec should sleep*/

+static void set_gsw_3104_codec(codec_op open)

+{

+    if(open==0)

+    {

+        system("echo out 201 0 >/sys/devices/platform/10005000.pinctrl/mt_gpio");    

+        system("echo out 181 0 >/sys/devices/platform/10005000.pinctrl/mt_gpio");

+    }

+    else

+    {

+        system("echo out 181 1 >/sys/devices/platform/10005000.pinctrl/mt_gpio");

+        usleep(10);//just open need usleep 10us

+

+        write_codec_reg("0x00 0x00");

+        write_codec_reg("0x01 0x00");

+        write_codec_reg("0x02 0x00");

+        write_codec_reg("0x03 0x80");

+        write_codec_reg("0x04 0x04");

+        write_codec_reg("0x05 0x00");

+        write_codec_reg("0x06 0x00");

+        write_codec_reg("0x07 0xa0");

+        write_codec_reg("0x08 0x20");

+        write_codec_reg("0x09 0x00");

+        write_codec_reg("0x0a 0x00");

+        write_codec_reg("0x0b 0x32");

+        write_codec_reg("0x0c 0x00");

+        write_codec_reg("0x0d 0x00");

+        write_codec_reg("0x0f 0x10");

+        write_codec_reg("0x10 0x20");

+        write_codec_reg("0x11 0xf8");

+        write_codec_reg("0x12 0xff");

+        write_codec_reg("0x13 0x04");

+        write_codec_reg("0x14 0x78");

+        write_codec_reg("0x15 0x78");

+        write_codec_reg("0x16 0x04");

+        write_codec_reg("0x17 0x78");

+        write_codec_reg("0x18 0x78");

+        write_codec_reg("0x19 0x80");

+        write_codec_reg("0x1a 0x00");

+        write_codec_reg("0x1b 0xfe");

+        write_codec_reg("0x1c 0x00");

+        write_codec_reg("0x1d 0x00");

+        write_codec_reg("0x1e 0xfe");

+        write_codec_reg("0x1f 0x00");

+        write_codec_reg("0x20 0x18");

+        write_codec_reg("0x21 0x18");

+        write_codec_reg("0x22 0x00");

+        write_codec_reg("0x23 0x00");

+        write_codec_reg("0x24 0xc0");

+        write_codec_reg("0x25 0xc0");

+        write_codec_reg("0x26 0x00");

+        write_codec_reg("0x27 0x00");

+        write_codec_reg("0x28 0x00");

+        write_codec_reg("0x29 0x00");

+        write_codec_reg("0x2a 0x00");

+        write_codec_reg("0x2b 0x02");

+        write_codec_reg("0x2c 0x02");

+        write_codec_reg("0x2d 0x00");

+        write_codec_reg("0x2e 0x02");

+        write_codec_reg("0x2f 0x85");

+        write_codec_reg("0x30 0x00");

+        write_codec_reg("0x31 0x80");

+        write_codec_reg("0x32 0x85");

+        write_codec_reg("0x33 0x00"); //dongyu@2023.9.18 Disables CODEC lineout output by default

+        write_codec_reg("0x34 0x00");

+        write_codec_reg("0x35 0x80");

+        write_codec_reg("0x36 0x82");

+        write_codec_reg("0x37 0x00");

+        write_codec_reg("0x38 0x00");

+        write_codec_reg("0x39 0x82");

+        write_codec_reg("0x3a 0x00"); //dongyu@2023.9.18 Disables CODEC lineout output by default

+        write_codec_reg("0x3b 0x00");

+        write_codec_reg("0x3c 0x00");

+        write_codec_reg("0x3d 0x00");

+        write_codec_reg("0x3e 0x00");

+        write_codec_reg("0x3f 0x80");

+        write_codec_reg("0x40 0xaf");

+        write_codec_reg("0x41 0x00"); //dongyu@2023.9.18 Disables CODEC lineout output by default

+        write_codec_reg("0x42 0x00");

+        write_codec_reg("0x43 0x80");

+        write_codec_reg("0x44 0x00");

+        write_codec_reg("0x45 0x00");

+        write_codec_reg("0x46 0x02");

+        write_codec_reg("0x47 0xaf");

+        write_codec_reg("0x48 0x00"); //dongyu@2023.9.18 Disables CODEC lineout output by default

+        write_codec_reg("0x49 0x00");

+        write_codec_reg("0x4a 0x00");

+        write_codec_reg("0x4b 0x00");

+        write_codec_reg("0x4c 0x00");

+        write_codec_reg("0x4d 0x00");

+        write_codec_reg("0x4e 0x00");

+        write_codec_reg("0x4f 0x00");

+        write_codec_reg("0x50 0x00");

+        write_codec_reg("0x51 0x02");

+        write_codec_reg("0x52 0xbf");

+        write_codec_reg("0x53 0x00");

+        write_codec_reg("0x54 0x00");

+        write_codec_reg("0x55 0x00");

+        write_codec_reg("0x56 0x9b");

+        write_codec_reg("0x57 0x00");

+        write_codec_reg("0x58 0x00");

+        write_codec_reg("0x59 0x00");

+        write_codec_reg("0x5a 0x00");

+        write_codec_reg("0x5b 0x02");

+        write_codec_reg("0x5c 0xbf");

+        write_codec_reg("0x5d 0x08");

+        write_codec_reg("0x5e 0xde");

+        write_codec_reg("0x5f 0x0c");

+        write_codec_reg("0x60 0x00");

+        write_codec_reg("0x61 0x00");

+        write_codec_reg("0x62 0x00");

+        write_codec_reg("0x63 0x00");

+        write_codec_reg("0x64 0x00");

+        write_codec_reg("0x65 0x01");

+        write_codec_reg("0x66 0xa2");

+        write_codec_reg("0x67 0x00");

+        write_codec_reg("0x68 0x00");

+        write_codec_reg("0x69 0x00");

+        write_codec_reg("0x6a 0x00");

+        write_codec_reg("0x6b 0x00");

+        write_codec_reg("0x6c 0x40");

+        write_codec_reg("0x6d 0x00");

+    }

+}

+

+

+#ifdef ZK_CODEC_CFG

+

+/*dongyu@2023.5.31 Add ZK set codec tlv320aic3x API register start*/

+

+void set_codec(media_src_t src, codec_op open_close)

+{

+    RLOGD("set_zk_3104_codec src=[%d] op=[%d]", src, open);

+    set_zk_3104_codec(open_close);

+}

+

+const char * get_customer_tone_path()

+{

+    return "/tmp/tone.wav";

+}

+

+int get_customer_tone_sample_rate()

+{

+    return 44100;

+}

+

+int customer_set_pa_volume(const int volume)

+{

+    int file;

+    char *filename = "/dev/i2c-0";

+    int addr = 0x6c;

+    char buf[2];

+

+    if (volume < 1 || volume > 4)

+    {

+        RLOGE("Invalid volume specified\n");

+        return -1;

+    }

+

+    if ((file = open(filename, O_RDWR)) < 0)

+    {

+        RLOGE("Failed to open i2c bus\n");

+        return -1;

+    }

+

+    if (ioctl(file, I2C_SLAVE, addr) < 0)

+    {

+        RLOGE("Failed to acquire bus access and/or talk to slave\n");

+        close(file);

+        return -1;

+    }

+

+    switch (volume) {

+        case 1:

+            buf[0] = 0x03;

+            buf[1] = 0x00;  //Gain set to 20 dB

+            break;

+        case 2:

+            buf[0] = 0x03;

+            buf[1] = 0x78;  //Gain set to 26 dB

+            break;

+        case 3:

+            buf[0] = 0x03;

+            buf[1] = 0x80;  //Gain set to 32 dB

+            break;

+        case 4:

+            buf[0] = 0x03;

+            buf[1] = 0xc0;  //Gain set to 36 dB

+            break;

+    }

+

+    if (write(file, buf, 2) != 2)

+    {

+        RLOGE("Failed to write to the i2c bus\n");

+        close(file);

+        return -1;

+    }

+

+    RLOGE("Set the 0x%02x register value to 0x%02x\n", buf[0], buf[1]);

+

+    close(file);

+

+    return 0;

+}

+

+int customer_get_pa_volume(int* volume)

+{

+    int file;

+    char *filename = "/dev/i2c-0";

+    int addr = 0x6c;

+    char buf[2];

+

+    if (volume < 1 || volume > 4)

+    {

+        RLOGE("Invalid volume specified\n");

+        return -1;

+    }

+

+    if ((file = open(filename, O_RDWR)) < 0)

+    {

+        RLOGE("Failed to open i2c bus\n");

+        return -1;

+    }

+

+    if (ioctl(file, I2C_SLAVE, addr) < 0)

+    {

+        RLOGE("Failed to acquire bus access and/or talk to slave\n");

+        close(file);

+        return -1;

+    }

+

+    switch (volume) {

+        case 1:

+            buf[0] = 0x03;

+            buf[1] = 0x00;  //Gain set to 20 dB

+            break;

+        case 2:

+            buf[0] = 0x03;

+            buf[1] = 0x78;  //Gain set to 26 dB

+            break;

+        case 3:

+            buf[0] = 0x03;

+            buf[1] = 0x80;  //Gain set to 32 dB

+            break;

+        case 4:

+            buf[0] = 0x03;

+            buf[1] = 0xc0;  //Gain set to 36 dB

+            break;

+    }

+

+    if (write(file, buf, 2) != 2)

+    {

+        RLOGE("Failed to write to the i2c bus\n");

+        close(file);

+        return -1;

+    }

+

+    RLOGE("Set the 0x%02x register value to 0x%02x\n", buf[0], buf[1]);

+

+    close(file);

+

+    return 0;

+}

+

+#elif defined(GSW_CODEC_CFG)

+

+void set_codec(media_src_t src, codec_op open_close)

+{

+    RLOGD("set_gsw_3104_codec src=[%d] op=[%d]", src, open);

+    set_gsw_3104_codec(open_close);

+}

+

+const char * get_customer_tone_path()

+{

+    return "/tmp/tone.wav";

+}

+

+int get_customer_tone_sample_rate()

+{

+    return 44100;

+}

+

+int customer_set_pa_volume(const int volume)

+{

+    RLOGE("not implement\n");

+    return -1;

+}

+

+int customer_get_pa_volume(int* volume)

+{

+    RLOGE("not implement\n");

+    return -1;

+}

+

+#else

+const char * get_customer_tone_path()

+{

+    return "/tmp/tone.wav";

+}

+

+int get_customer_tone_sample_rate()

+{

+    return 44100;

+}

+

+int customer_set_pa_volume(const int volume)

+{

+    RLOGE("not implement\n");

+    return -1;

+}

+

+int customer_get_pa_volume(int* volume)

+{

+    RLOGE("not implement\n");

+    return -1;

+}

+

+void set_codec(media_src_t src, codec_op open_close)

+{

+    RLOGE("not implement\n");

+}

+

+#endif

diff --git a/IC_src/mtk/lib/liblynq-codec/liblynq-codec/makefile b/IC_src/mtk/lib/liblynq-codec/liblynq-codec/makefile
new file mode 100755
index 0000000..b0fe68a
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-codec/liblynq-codec/makefile
@@ -0,0 +1,78 @@
+SHELL = /bin/sh
+RM = rm -f
+
+LOCAL_CFLAGS := -Wall \
+                -g -Os \
+                -flto \
+                -fPIC \
+                -DRIL_SHLIB \
+                -DATCI_PARSE \
+                -DKEEP_ALIVE \
+                -DECALL_SUPPORT \
+
+
+ifeq ($(strip $(MOBILETEK_CODEC_CFG)), GSW)
+    LOCAL_CFLAGS += -DGSW_CODEC_CFG
+
+endif
+
+ifeq ($(strip $(MOBILETEK_CODEC_CFG)), ZK)
+    LOCAL_CFLAGS += -DZK_CODEC_CFG
+endif
+
+$(warning ################# RITA ROOT: $(ROOT),includedir:$(includedir))
+LOCAL_PATH   = .
+
+LOCAL_C_INCLUDES = \
+  -I. \
+  -I$(ROOT)$(includedir)/logger \
+  -I$(LOCAL_PATH)/../include \
+  -I$(ROOT)$(includedir)/glib-2.0 \
+  -I$(ROOT)$(libdir)/glib-2.0/include \
+  -I$(ROOT)$(includedir)/gstreamer-1.0 \
+  -I$(ROOT)$(libdir)/gstreamer-1.0/include\
+
+
+
+LOCAL_LIBS := \
+    -L. \
+    -ldl \
+    -lstdc++ \
+    -llog \
+
+
+
+SOURCES = $(wildcard *.c wildcard *.h)
+
+EXECUTABLE = liblynq-codec.so
+
+OBJECTS=$(SOURCES:.c=.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 : %.c
+	$(CC) $(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)
diff --git a/IC_src/mtk/lib/liblynq-driver/LICENSE b/IC_src/mtk/lib/liblynq-driver/LICENSE
new file mode 100644
index 0000000..77f59ed
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-driver/LICENSE
@@ -0,0 +1,31 @@
+Copyright Statement:
+
+This software/firmware and related documentation ("MediaTek Software") are
+protected under relevant copyright laws. The information contained herein is
+confidential and proprietary to MediaTek Inc. and/or its licensors. Without
+the prior written permission of MediaTek inc. and/or its licensors, any
+reproduction, modification, use or disclosure of MediaTek Software, and
+information contained herein, in whole or in part, shall be strictly
+prohibited.
+
+MediaTek Inc. (C) 2015. All rights reserved.
+
+BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ON AN "AS-IS" BASIS ONLY. MEDIATEK 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 MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
+RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK 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 MEDIATEK
+SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
+RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
+ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
+RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
+MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
diff --git a/IC_src/mtk/lib/liblynq-driver/MODULE_LICENSE_APACHE2 b/IC_src/mtk/lib/liblynq-driver/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-driver/MODULE_LICENSE_APACHE2
diff --git a/IC_src/mtk/lib/liblynq-driver/Makefile b/IC_src/mtk/lib/liblynq-driver/Makefile
new file mode 100644
index 0000000..b74de2c
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-driver/Makefile
@@ -0,0 +1,63 @@
+PREFIX   = ../install
+CROSS    = arm-none-linux-
+ROOT     = $(PREFIX)/$(CROSS:%-=%)
+
+#For Yocto use
+
+RFX_TEST_CLIENT = false
+RFX_TEST_AOSP = false
+
+$(warning ########## libvendor_ril BB_TELEFWK_OPTION $(BB_TELEFWK_OPTION) ##########)
+
+		   
+
+SUBDIRS +=  liblynq-driver
+
+
+
+
+
+$(warning ########## lynq-rilcmd SUBDIRS  $(SUBDIRS) ##########)
+export SIM_COUNT?=1
+
+.PHONY: all build clean pack_rootfs
+
+all: build
+
+build: clean
+
+clean:
+	$(warning ########## clean ril ##########)
+	for i in $(SUBDIRS); do			\
+		(cd $$i && make clean);			\
+		if [ $$? != 0 ]; then		\
+			exit 1;					\
+		fi							\
+	done
+
+build:
+	$(warning ########## build ril ##########)
+	for i in $(SUBDIRS); do			\
+		(cd $$i && make);			\
+		if [ $$? != 0 ]; then		\
+			exit 1;					\
+		fi							\
+	done
+
+install:
+	$(warning ########## install ril ##########)
+	for i in $(SUBDIRS); do			\
+		(cd $$i && make install);			\
+		if [ $$? != 0 ]; then		\
+			exit 1;					\
+		fi							\
+	done
+
+pack_rootfs:
+	$(warning ########## pack_rootfs ril ##########)
+	for i in $(SUBDIRS); do			\
+		(cd $$i && make pack_rootfs);			\
+		if [ $$? != 0 ]; then		\
+			exit 1;					\
+		fi							\
+	done
diff --git a/IC_src/mtk/lib/liblynq-driver/NOTICE b/IC_src/mtk/lib/liblynq-driver/NOTICE
new file mode 100644
index 0000000..c5b1efa
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-driver/NOTICE
@@ -0,0 +1,190 @@
+
+   Copyright (c) 2005-2008, The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
diff --git a/IC_src/mtk/lib/liblynq-driver/README b/IC_src/mtk/lib/liblynq-driver/README
new file mode 100644
index 0000000..9a7e82f
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-driver/README
@@ -0,0 +1,13 @@
+WHAT IT DOES?
+=============
+MTK ril proxy core library
+
+HOW IT WAS BUILT?
+==================
+This module is source code released.
+
+HOW TO USE IT?
+==============
+MTK ril proxy daemon will use this library to communicate with GSM and C2K RILD.
+
+All the source code of this folder were written by MediaTek co..
diff --git a/IC_src/mtk/lib/liblynq-driver/include/liblynq-driver/libdriver.h b/IC_src/mtk/lib/liblynq-driver/include/liblynq-driver/libdriver.h
new file mode 100755
index 0000000..348385d
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-driver/include/liblynq-driver/libdriver.h
@@ -0,0 +1,17 @@
+#ifndef __LYNQ_DRIVER_CONTROL_H__
+#define __LYNQ_DRIVER_CONTROL_H__
+typedef int BOOL;
+typedef void (*triggerCallback)(const char*, int);
+void disconnect_key();
+void register_key_info();
+int trigger_loop();
+//BOOL ServiceIsReady(void);
+void registerTriggerCallback(triggerCallback callback);
+int lynq_set_gpio (char * mode,int gpio_numb,int param);
+void lynq_get_gpio (int gpio_numb,char *response);
+
+int lynq_i2c_write(char *dev_node, int addr, char reg, char data);
+int lynq_i2c_read(char *dev_node, int addr, char reg, char *read_value);
+int lynq_setGpio_values(const char *state, int gpio_numb, int param);
+int lynq_getGpio_values(int gpio_numb, char* mode, char* dir, char* dout, char* drive);
+#endif  //__LOG_H__
diff --git a/IC_src/mtk/lib/liblynq-driver/liblynq-driver/driver_control.c b/IC_src/mtk/lib/liblynq-driver/liblynq-driver/driver_control.c
new file mode 100755
index 0000000..837e841
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-driver/liblynq-driver/driver_control.c
@@ -0,0 +1,466 @@
+#include <stdio.h>
+#include <string.h>
+#include <pthread.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <gio/gio.h>
+#include <log/log.h>
+#include <glib.h>
+/*dongyu@2023.7.11 Add I2C read/write interface start*/
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <linux/i2c-dev.h>
+/*dongyu@2023.7.11 Add I2C read/write interface end*/
+#include "libdriver.h"
+#define GPIO_SERVICE "gpio.lynq" /*well-known bus name */
+#define GPIO_DATA_INTERFACE "gpio.lynq.Data" /*interface name*/
+#define GPIO_DATA_PATH "/gpio/lynq/data" /*object name*/
+#define LOG_TAG "GPIO_CONTROL"
+static GMainLoop *loop = NULL;
+static GDBusProxy *pProxy = NULL;
+triggerCallback mtriggerCallback = NULL;;
+
+void proxy_signals_on_signal (GDBusProxy  *proxy,
+                              const gchar *sender_name,
+                              const gchar *signal_name,
+                              GVariant    *parameters,
+                              gpointer     user_data)
+{
+    gint32 status;
+    RLOGD("signal_name: %s\n", signal_name);
+    g_variant_get (parameters,"(i)",&status);
+    //RLOGD("listen singal ok,%d",status);
+    if(mtriggerCallback){
+        mtriggerCallback(signal_name,status);
+    }
+    else
+    {
+        RLOGE("mbroadcastcallback NULL");
+    }
+    printf("trigger status is %d\n",status);
+}
+
+BOOL registerClientSignalHandler(GDBusProxy *proxy)
+{
+    gulong signal_handler_id;
+    signal_handler_id = g_signal_connect(proxy, "g-signal",
+                      G_CALLBACK (proxy_signals_on_signal), NULL);
+    RLOGD("proxy is ready");
+    if (signal_handler_id == 0) {
+        RLOGD("listen singal fail!");
+        return FALSE;
+    }
+    return TRUE;
+}
+void registerTriggerCallback(triggerCallback callback)
+{
+    if (NULL != callback){
+        //memcpy(&mbroadcastcallback, callback, sizeof(broadcastCallback));
+        mtriggerCallback = callback;
+    }
+    else{
+        RLOGD("registerSignalCallback: parameter point is NULL");
+    }
+}
+void *run(void* arg)
+{
+    
+    /** start the main event loop which manages all available sources of events */
+    g_main_loop_run(loop);
+    return ((void*)0);
+}
+
+void disconnect_key(void)
+{
+    if(pProxy != NULL) {
+        g_object_unref (pProxy);
+    }
+    if(loop != NULL) {
+        g_main_loop_unref(loop);
+    }
+}
+int thread_create(void)
+{
+    int err;
+    pthread_t thr;
+
+    err = pthread_create(&thr, NULL, run, NULL);
+    if(0 != err){
+            RLOGD("Can't create thread: %s\n", strerror(err));
+    }
+    else{       
+            RLOGD("New thread created: %s\n", strerror(err));
+    }
+
+    return err;
+}
+int trigger_loop()
+{
+    g_main_loop_run(loop);
+}
+
+BOOL service_ready(void)
+{
+    gchar *owner_name = NULL;
+    owner_name = g_dbus_proxy_get_name_owner((GDBusProxy*)pProxy);
+    if(NULL != owner_name)
+    {
+        RLOGD("Owner Name: %s\n", owner_name);        
+        g_free(owner_name);
+        return TRUE;
+    }
+    else
+    {   
+        g_print("Owner Name is NULL.");     
+        return FALSE;
+    }
+}
+
+void register_key_info(void){
+     GError *error = NULL;
+     RLOGD("go!\n");	
+        loop = g_main_loop_new(NULL, FALSE);
+
+        pProxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+                                         G_DBUS_PROXY_FLAGS_NONE,
+                                         NULL, /* GDBusInterfaceInfo */
+                                         GPIO_SERVICE,
+                                         GPIO_DATA_PATH,
+                                         GPIO_DATA_INTERFACE,
+                                         NULL, /* GCancellable */
+                                         &error);
+    if (pProxy == NULL)
+    {
+      RLOGD ("Error creating proxy: %s\n", error->message);
+      disconnect_key();
+    }
+    if (registerClientSignalHandler(pProxy)== FALSE){
+      RLOGD ("register Error");
+      disconnect_key();
+    }
+    while(service_ready() != TRUE);
+    thread_create();
+}
+
+int lynq_set_gpio (char * mode,int gpio_numb,int param)
+{
+    GDBusConnection *c1;
+    GVariant *result;
+    GError *error;
+    GMainLoop *loop;
+    gint32  set_result = -1;
+    g_type_init();
+    loop = g_main_loop_new(NULL, FALSE);   /** create main loop, but do not start it.*/
+    error = NULL;
+    c1 = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
+    g_assert_no_error (error);
+    error = NULL;
+    g_assert (c1 != NULL);
+    g_assert (!g_dbus_connection_is_closed (c1));
+    result = g_dbus_connection_call_sync (c1,
+                                        GPIO_SERVICE,  /* bus name */
+                                        GPIO_DATA_PATH, /* object path */
+                                        GPIO_DATA_INTERFACE,  /* interface name */
+                                        "setGpio",                 /* method name */
+                                        g_variant_new ("(sii)", mode,gpio_numb,param),  /* parameters */
+                                         G_VARIANT_TYPE ("(i)"),                    /* return type */
+                                        G_DBUS_CALL_FLAGS_NONE,
+                                        -1,
+                                        NULL,
+                                        &error);
+    g_assert_no_error (error);
+    g_assert (result != NULL);
+    g_variant_get(result, "(i)", &(set_result));
+   // RLOGD("%s, %s, %d,result:%d", __FILE__, __FUNCTION__, __LINE__,set_result);
+    g_variant_unref (result);
+    //g_main_loop_run (loop);
+    g_main_loop_unref (loop);
+    return set_result;
+}
+/*
+int set_gpio143(){
+  int   result;
+  result = set_gpio (GPIO_MODE,WIFI_LED_CONTROL,1);
+  return result;
+ // sprintf(output, "gpio set stauts %d\n",result);
+ // printf("%s",output);
+ // emResultNotify(output);
+}*/
+void lynq_get_gpio (int gpio_numb,char *response)
+{
+    GDBusConnection *c1;
+    GError *error;
+    GMainLoop *loop;
+    //char output[2048] = {0};
+    //gchar *response;
+    GVariant *get;
+    gsize n_elts=0;
+    GVariantIter *iter;
+    //guchar *response;
+    gchar *get_res;
+//	const char *p;
+    g_type_init();
+    loop = g_main_loop_new(NULL, FALSE);   /** create main loop, but do not start it.*/
+    error = NULL;
+    c1 = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
+    g_assert_no_error (error);
+    error = NULL;
+    g_assert (c1 != NULL);
+    g_assert (!g_dbus_connection_is_closed (c1));
+    error = NULL;
+    get = g_dbus_connection_call_sync (c1,
+                                        GPIO_SERVICE,  
+                                        GPIO_DATA_PATH, 
+                                        GPIO_DATA_INTERFACE,  
+                                        "getGpio",                 
+                                        g_variant_new ("(i)",gpio_numb), 
+                                         G_VARIANT_TYPE ("(s)"),                     
+                                        G_DBUS_CALL_FLAGS_NONE,
+                                        -1,
+                                        NULL,
+                                        &error);
+    g_assert_no_error (error);
+    g_assert (get != NULL);
+    g_variant_get (get, "(s)",&get_res);
+    strcpy(response, get_res);
+    g_variant_unref (get);
+    RLOGD("get_gpio,%s",response);
+    g_main_loop_unref (loop);
+}
+/*
+void get_gpio143(){
+  char output[1024] = {0};
+  char output1[2048] = {0};
+  get_gpio (WIFI_LED_CONTROL,output);
+  printf("get_gpio143,%s\n",output);
+ 
+}
+*/
+
+/*dongyu@2023.7.12 Add I2C read/write interface start*/
+/*****************************************************************************************************
+@file driver_control.c
+@brief The lynq_i2c_read function is used to read data from an I2C device. It accepts four parameters:
+        - dev_node¡êoPath to the I2C device node
+        - addr¡êoI2C device address
+        - reg¡êoRegister address to be read
+        - read_value¡êoRegister address data read
+        - return: If successful, return 0; if unsuccessful, return -1
+@author dongyu
+@date 2023-7-12
+@version V1.0
+@copyright MobileTek
+*****************************************************************************************************/
+int lynq_i2c_read(char *dev_node, int addr, char reg, char *read_value)
+{
+    int file;
+    char buf[1];
+
+    if (dev_node == NULL)
+    {
+        RLOGD("lynq_i2c_read Invalid dev_node\n");
+        return -1;
+    }
+
+    if ((file = open(dev_node, O_RDWR)) < 0)
+    {
+        RLOGD("Failed to open i2c bus\n");
+        return -1;
+    }
+
+    if (ioctl(file, I2C_SLAVE, addr) < 0)
+    {
+        RLOGD("Failed to acquire bus access and/or talk to slave\n");
+        close(file);
+        return -1;
+    }
+
+    buf[0] = reg;
+    if (write(file, buf, 1) != 1)
+    {
+        RLOGD("Failed to write to the i2c bus\n");
+        close(file);
+        return -1;
+    }
+
+    if (read(file, read_value, 1) != 1)
+    {
+        RLOGD("Failed to read from the i2c bus\n");
+        close(file);
+        return -1;
+    }
+
+    RLOGD("Read value: %02x\n", *read_value);
+
+    close(file);
+
+    return 0;
+}
+
+/*****************************************************************************************************
+@file driver_control.c
+@brief The lynq_i2c_write function is used to write data to an I2C device. It accepts four parameters:
+        - dev_node¡êoPath to the I2C device node
+        - addr¡êoI2C device address
+        - reg¡êoRegister address to be written
+        - data¡êoData to be written
+        - return: If successful, return 0; if unsuccessful, return -1
+@author dongyu
+@date 2023-7-12
+@version V1.0
+@copyright MobileTek
+*****************************************************************************************************/
+int lynq_i2c_write(char *dev_node, int addr, char reg, char data)
+{
+    int file;
+    char buf[2];
+
+    if (dev_node == NULL)
+    {
+        RLOGD("lynq_i2c_write Invalid dev_node\n");
+        return -1;
+    }
+
+    if ((file = open(dev_node, O_RDWR)) < 0)
+    {
+        RLOGD("Failed to open i2c bus\n");
+        return -1;
+    }
+
+    if (ioctl(file, I2C_SLAVE, addr) < 0)
+    {
+        RLOGD("Failed to acquire bus access and/or talk to slave\n");
+        close(file);
+        return -1;
+    }
+
+    buf[0] = reg;
+    buf[1] = data;
+    if (write(file, buf, 2) != 2)
+    {
+        RLOGD("Failed to write to the i2c bus\n");
+        close(file);
+        return -1;
+    }
+
+    RLOGD("Write value: %02x\n", data);
+
+    close(file);
+
+    return 0;
+}
+/*dongyu@2023.7.12 Add I2C read/write interface end*/
+
+/*dongyu@2023.7.11 Configurable General Purpose Interface for GPIO Packages start*/
+int lynq_getGpio_values(int gpio_numb, char* mode, char* dir, char* dout, char* drive)
+{
+    char command[100];
+    char response[100] = {0};
+
+    if (mode == NULL || dir == NULL || dout == NULL || drive == NULL)
+    {
+        RLOGD("lynq_getGpio_values pointers are NULL, returning -1\n");
+        return -1;
+    }
+
+    if (gpio_numb >= 0 && gpio_numb <= 180)
+    {
+        sprintf(command, "echo start 0 > /sys/devices/platform/10005000.pinctrl/mt_gpio");
+        if(system(command) != 0)
+        {
+            RLOGD("0~180 Range command execution failure!\n");
+            return -1;
+        }
+    }
+    else if (gpio_numb > 180 && gpio_numb <= 234)
+    {
+        sprintf(command, "echo start 180 > /sys/devices/platform/10005000.pinctrl/mt_gpio");
+        if(system(command) != 0)
+        {
+            RLOGD("180~234 Range command execution failure!\n");
+            return -1;
+        }
+    }
+    else
+    {
+        RLOGD("The gpio_numb parameter takes values in the range 0 ~ 234!\n");
+        return -1;
+    }
+
+    sprintf(command, "cat /sys/devices/platform/10005000.pinctrl/mt_gpio | grep -E \"^%03d\"", gpio_numb);
+    FILE* fp = popen(command, "r");
+    if (fp == NULL)
+    {
+        RLOGD("Failed to open pipe!\n");
+        return -1;
+    }
+    fgets(response, 100, fp);
+    pclose(fp);
+
+    if (strlen(response) < 10)
+    {
+        RLOGD("Response is either empty or shorter than expected!\n");
+        return -1;
+    }
+    *mode = response[4];
+    *dir = response[5];
+    *dout = response[6];
+    *drive = response[9];
+
+    return 0;
+}
+
+static int lynq_setGpio_execution(const char *state, int gpio_numb, int param)
+{
+    char command[100];
+    sprintf(command, "echo %s %d %d >/sys/devices/platform/10005000.pinctrl/mt_gpio", state, gpio_numb, param);
+    int result = system(command);
+    if (result != 0)
+    {
+        RLOGD("Failed to execute command: %s\n", command);
+        return -1;
+    }
+    return 0;
+}
+
+int lynq_setGpio_values(const char *state, int gpio_numb, int param)
+{
+    int result;
+    char mode, dir, dout, drive;
+    if (state == NULL)
+    {
+        RLOGD("lynq_setGpio_values pointers are NULL, returning -1\n");
+        return -1;
+    }
+
+    lynq_getGpio_values(gpio_numb, &mode, &dir, &dout, &drive);
+
+    if ((strcmp(state, "mode") == 0 || strcmp(state, "driving") == 0) && \
+                    (gpio_numb >= 0 && gpio_numb <= 234) && (param >= 0 && param <= 7))
+    {
+        result = lynq_setGpio_execution(state, gpio_numb, param);
+        if (result != 0)
+        {
+            return result;
+        }
+    }
+    else if ((strcmp(state, "dir") == 0 || strcmp(state, "out") == 0) && \
+                    (gpio_numb >= 0 && gpio_numb <= 234) && (param >= 0 && param <= 1) && mode == '0')
+    {
+        result = lynq_setGpio_execution(state, gpio_numb, param);
+        if (result != 0)
+        {
+            return result;
+        }
+    }
+    else
+    {
+        RLOGD("The parameter you entered is invalid!\n");
+        return -1;
+    }
+
+    return 0;
+}
+/*dongyu@2023.7.11 Configurable General Purpose Interface for GPIO Packages end*/
diff --git a/IC_src/mtk/lib/liblynq-driver/liblynq-driver/makefile b/IC_src/mtk/lib/liblynq-driver/liblynq-driver/makefile
new file mode 100644
index 0000000..6439920
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-driver/liblynq-driver/makefile
@@ -0,0 +1,109 @@
+SHELL = /bin/sh
+RM = rm -f
+
+LOCAL_CFLAGS := -Wall \
+                -g -Os \
+                -flto \
+                -fPIC \
+                -DRIL_SHLIB \
+                -DATCI_PARSE \
+                -DKEEP_ALIVE \
+                -DECALL_SUPPORT \
+
+$(warning ################# C2K support: $(RAT_CONFIG_C2K_SUPPORT))
+ifeq ($(strip $(RAT_CONFIG_C2K_SUPPORT)), yes)
+    LOCAL_CFLAGS += -DC2K_SUPPORT
+
+endif
+
+ifeq ($(strip $(MTK_MULTI_SIM_SUPPORT)), dsds)
+    LOCAL_CFLAGS += -DANDROID_SIM_COUNT_2 \
+                     -DANDROID_MULTI_SIM \
+                     -DMODE_DSDS
+endif
+
+ifeq ($(strip $(MTK_MULTI_SIM_SUPPORT)), dsss)
+    LOCAL_CFLAGS += -DMODE_DSSS
+endif
+
+$(warning ################# TARGET_PLATFORM: $(TARGET_PLATFORM))
+ifeq ($(strip $(TARGET_PLATFORM)), mt2731)
+#$(warning #################add for debug $(ROOT), $(includedir))
+$(warning ################# TARGET_PLATFORM_MT2731)
+    LOCAL_CFLAGS += -DTARGET_PLATFORM_MT2731 \
+                    -DMD_93_SUPPORT
+else ifeq ($(strip $(TARGET_PLATFORM)), mt2635)
+$(warning ################# TARGET_PLATFORM_MT2635)
+    LOCAL_CFLAGS += -DTARGET_PLATFORM_MT2635 \
+                    -DMD_90_SUPPORT
+endif
+
+$(warning ################# RITA ROOT: $(ROOT),includedir:$(includedir))
+LOCAL_PATH   = .
+
+LOCAL_C_INCLUDES = \
+  -I. \
+  -I$(LOCAL_PATH)/../include/liblynq-driver \
+  -I$(ROOT)$(includedir)/logger \
+  -I$(ROOT)$(includedir)/gstreamer-1.0 \
+  -I$(ROOT)$(includedir)/glib-2.0 \
+  -I$(ROOT)$(libdir)/glib-2.0/include \
+  -I$(ROOT)$(libdir)/gstreamer-1.0/include\
+  -I$(ROOT)$(includedir)/dbus-1.0 \
+  -I$(ROOT)$(libdir)/dbus-1.0/include \
+
+
+LOCAL_LIBS := \
+    -L. \
+    -ldl \
+    -lstdc++ \
+    -llog \
+    -lcutils \
+    -lutils \
+    -lpower \
+    -lbinder \
+    -lpthread \
+    -lpal \
+    -lgstreamer-1.0 \
+    -lglib-2.0 \
+    -lgstbase-1.0 \
+    -lgstreamer-1.0 \
+    -lgobject-2.0 \
+    -lgio-2.0 \
+    -ldtmf \
+    -ldbus-1 \
+
+SOURCES = $(wildcard *.c wildcard *.h)
+
+EXECUTABLE = liblynq-driver.so
+
+OBJECTS=$(SOURCES:.c=.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 : %.c
+	$(CC) $(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)
diff --git a/IC_src/mtk/lib/liblynq-fota/MD5/md5.c b/IC_src/mtk/lib/liblynq-fota/MD5/md5.c
new file mode 100755
index 0000000..5dd9ff3
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/MD5/md5.c
@@ -0,0 +1,161 @@
+#include "string.h"
+#include "md5.h"
+
+unsigned char PADDING[]={0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+void MD5Init(MD5_CTX *context)
+{
+	context->count[0] = 0;
+	context->count[1] = 0;
+	context->state[0] = 0x67452301;
+	context->state[1] = 0xEFCDAB89;
+	context->state[2] = 0x98BADCFE;
+	context->state[3] = 0x10325476;
+}
+void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen)
+{
+	unsigned int i = 0,index = 0,partlen = 0;
+	index = (context->count[0] >> 3) & 0x3F;
+	partlen = 64 - index;
+	context->count[0] += inputlen << 3;
+	if(context->count[0] < (inputlen << 3))
+		context->count[1]++;
+	context->count[1] += inputlen >> 29;
+
+	if(inputlen >= partlen)
+	{
+		memcpy(&context->buffer[index],input,partlen);
+		MD5Transform(context->state,context->buffer);
+		for(i = partlen;i+64 <= inputlen;i+=64)
+			MD5Transform(context->state,&input[i]);
+		index = 0;        
+	}  
+	else
+	{
+		i = 0;
+	}
+	memcpy(&context->buffer[index],&input[i],inputlen-i);
+}
+void MD5Final(MD5_CTX *context,unsigned char digest[16])
+{
+	unsigned int index = 0,padlen = 0;
+	unsigned char bits[8];
+	index = (context->count[0] >> 3) & 0x3F;
+	padlen = (index < 56)?(56-index):(120-index);
+	MD5Encode(bits,context->count,8);
+	MD5Update(context,PADDING,padlen);
+	MD5Update(context,bits,8);
+	MD5Encode(digest,context->state,16);
+}
+void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len)
+{
+	unsigned int i = 0,j = 0;
+	while(j < len)
+	{
+		output[j] = input[i] & 0xFF;  
+		output[j+1] = (input[i] >> 8) & 0xFF;
+		output[j+2] = (input[i] >> 16) & 0xFF;
+		output[j+3] = (input[i] >> 24) & 0xFF;
+		i++;
+		j+=4;
+	}
+}
+void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len)
+{
+	unsigned int i = 0,j = 0;
+	while(j < len)
+	{
+		output[i] = (input[j]) |
+			(input[j+1] << 8) |
+			(input[j+2] << 16) |
+			(input[j+3] << 24);
+		i++;
+		j+=4; 
+	}
+}
+void MD5Transform(unsigned int state[4],unsigned char block[64])
+{
+	unsigned int a = state[0];
+	unsigned int b = state[1];
+	unsigned int c = state[2];
+	unsigned int d = state[3];
+	unsigned int x[64];
+	MD5Decode(x,block,64);
+	FF(a, b, c, d, x[ 0], 7, 0xd76aa478); /* 1 */
+	FF(d, a, b, c, x[ 1], 12, 0xe8c7b756); /* 2 */
+	FF(c, d, a, b, x[ 2], 17, 0x242070db); /* 3 */
+	FF(b, c, d, a, x[ 3], 22, 0xc1bdceee); /* 4 */
+	FF(a, b, c, d, x[ 4], 7, 0xf57c0faf); /* 5 */
+	FF(d, a, b, c, x[ 5], 12, 0x4787c62a); /* 6 */
+	FF(c, d, a, b, x[ 6], 17, 0xa8304613); /* 7 */
+	FF(b, c, d, a, x[ 7], 22, 0xfd469501); /* 8 */
+	FF(a, b, c, d, x[ 8], 7, 0x698098d8); /* 9 */
+	FF(d, a, b, c, x[ 9], 12, 0x8b44f7af); /* 10 */
+	FF(c, d, a, b, x[10], 17, 0xffff5bb1); /* 11 */
+	FF(b, c, d, a, x[11], 22, 0x895cd7be); /* 12 */
+	FF(a, b, c, d, x[12], 7, 0x6b901122); /* 13 */
+	FF(d, a, b, c, x[13], 12, 0xfd987193); /* 14 */
+	FF(c, d, a, b, x[14], 17, 0xa679438e); /* 15 */
+	FF(b, c, d, a, x[15], 22, 0x49b40821); /* 16 */
+
+	/* Round 2 */
+	GG(a, b, c, d, x[ 1], 5, 0xf61e2562); /* 17 */
+	GG(d, a, b, c, x[ 6], 9, 0xc040b340); /* 18 */
+	GG(c, d, a, b, x[11], 14, 0x265e5a51); /* 19 */
+	GG(b, c, d, a, x[ 0], 20, 0xe9b6c7aa); /* 20 */
+	GG(a, b, c, d, x[ 5], 5, 0xd62f105d); /* 21 */
+	GG(d, a, b, c, x[10], 9,  0x2441453); /* 22 */
+	GG(c, d, a, b, x[15], 14, 0xd8a1e681); /* 23 */
+	GG(b, c, d, a, x[ 4], 20, 0xe7d3fbc8); /* 24 */
+	GG(a, b, c, d, x[ 9], 5, 0x21e1cde6); /* 25 */
+	GG(d, a, b, c, x[14], 9, 0xc33707d6); /* 26 */
+	GG(c, d, a, b, x[ 3], 14, 0xf4d50d87); /* 27 */
+	GG(b, c, d, a, x[ 8], 20, 0x455a14ed); /* 28 */
+	GG(a, b, c, d, x[13], 5, 0xa9e3e905); /* 29 */
+	GG(d, a, b, c, x[ 2], 9, 0xfcefa3f8); /* 30 */
+	GG(c, d, a, b, x[ 7], 14, 0x676f02d9); /* 31 */
+	GG(b, c, d, a, x[12], 20, 0x8d2a4c8a); /* 32 */
+
+	/* Round 3 */
+	HH(a, b, c, d, x[ 5], 4, 0xfffa3942); /* 33 */
+	HH(d, a, b, c, x[ 8], 11, 0x8771f681); /* 34 */
+	HH(c, d, a, b, x[11], 16, 0x6d9d6122); /* 35 */
+	HH(b, c, d, a, x[14], 23, 0xfde5380c); /* 36 */
+	HH(a, b, c, d, x[ 1], 4, 0xa4beea44); /* 37 */
+	HH(d, a, b, c, x[ 4], 11, 0x4bdecfa9); /* 38 */
+	HH(c, d, a, b, x[ 7], 16, 0xf6bb4b60); /* 39 */
+	HH(b, c, d, a, x[10], 23, 0xbebfbc70); /* 40 */
+	HH(a, b, c, d, x[13], 4, 0x289b7ec6); /* 41 */
+	HH(d, a, b, c, x[ 0], 11, 0xeaa127fa); /* 42 */
+	HH(c, d, a, b, x[ 3], 16, 0xd4ef3085); /* 43 */
+	HH(b, c, d, a, x[ 6], 23,  0x4881d05); /* 44 */
+	HH(a, b, c, d, x[ 9], 4, 0xd9d4d039); /* 45 */
+	HH(d, a, b, c, x[12], 11, 0xe6db99e5); /* 46 */
+	HH(c, d, a, b, x[15], 16, 0x1fa27cf8); /* 47 */
+	HH(b, c, d, a, x[ 2], 23, 0xc4ac5665); /* 48 */
+
+	/* Round 4 */
+	II(a, b, c, d, x[ 0], 6, 0xf4292244); /* 49 */
+	II(d, a, b, c, x[ 7], 10, 0x432aff97); /* 50 */
+	II(c, d, a, b, x[14], 15, 0xab9423a7); /* 51 */
+	II(b, c, d, a, x[ 5], 21, 0xfc93a039); /* 52 */
+	II(a, b, c, d, x[12], 6, 0x655b59c3); /* 53 */
+	II(d, a, b, c, x[ 3], 10, 0x8f0ccc92); /* 54 */
+	II(c, d, a, b, x[10], 15, 0xffeff47d); /* 55 */
+	II(b, c, d, a, x[ 1], 21, 0x85845dd1); /* 56 */
+	II(a, b, c, d, x[ 8], 6, 0x6fa87e4f); /* 57 */
+	II(d, a, b, c, x[15], 10, 0xfe2ce6e0); /* 58 */
+	II(c, d, a, b, x[ 6], 15, 0xa3014314); /* 59 */
+	II(b, c, d, a, x[13], 21, 0x4e0811a1); /* 60 */
+	II(a, b, c, d, x[ 4], 6, 0xf7537e82); /* 61 */
+	II(d, a, b, c, x[11], 10, 0xbd3af235); /* 62 */
+	II(c, d, a, b, x[ 2], 15, 0x2ad7d2bb); /* 63 */
+	II(b, c, d, a, x[ 9], 21, 0xeb86d391); /* 64 */
+	state[0] += a;
+	state[1] += b;
+	state[2] += c;
+	state[3] += d;
+}
\ No newline at end of file
diff --git "a/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/Backup/main\0507919\051.c" "b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/Backup/main\0507919\051.c"
new file mode 100755
index 0000000..2d0b84b
--- /dev/null
+++ "b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/Backup/main\0507919\051.c"
@@ -0,0 +1,12 @@
+#include <stdio.h>

+#incldue "md5_encode.h"

+

+int main()

+{

+	int ret;

+	ret=md5_file_verfy("111","222");

+	printf("ret:%d\n",ret);

+

+	return 0;	

+	

+}
\ No newline at end of file
diff --git "a/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/Backup/md5_encode\0502203\051.h" "b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/Backup/md5_encode\0502203\051.h"
new file mode 100755
index 0000000..89939b0
--- /dev/null
+++ "b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/Backup/md5_encode\0502203\051.h"
@@ -0,0 +1,15 @@
+
+int ota_file_open(char* path, char* flag);
+
+int ota_file_seek(int handle, int offset,  int flag);
+
+int ota_file_read(char* buffer, size_t count, int file);
+
+void ota_file_close(int handle);
+
+int md5_file_verfy(char* filePath, char* file_md5);
+
+
+
+
+
diff --git "a/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/Backup/md5_encode\0505411\051.c" "b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/Backup/md5_encode\0505411\051.c"
new file mode 100755
index 0000000..106cee1
--- /dev/null
+++ "b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/Backup/md5_encode\0505411\051.c"
@@ -0,0 +1,82 @@
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include "md5.h"
+
+
+
+
+int ota_file_open(char* path, char* flag)
+{
+#if 0
+	if(strcmp(flag, "r") == 0 || strcmp(flag, "rb") == 0)
+		return mtk_device_wrap_open(path, O_RDONLY);
+	else if(strcmp(flag, "r+") == 0 || strcmp(flag, "rb+") == 0)
+		return mtk_device_wrap_open(path, O_RDWR | O_CREAT);
+	else if(strcmp(flag, "w+") == 0 ||strcmp(flag, "wb+") == 0 || strcmp(flag, "w") == 0  || strcmp(flag, "wb") == 0 )	
+		return mtk_device_wrap_open(path, O_RDWR | O_CREAT | O_TRUNC);
+	else if(strcmp(flag, "a+") == 0 ||strcmp(flag, "ab+") == 0 || strcmp(flag, "a") == 0  || strcmp(flag, "ab") == 0 )	
+		return mtk_device_wrap_open(path, O_RDWR | O_CREAT | O_APPEND);	
+#endif
+}
+
+
+int ota_file_seek(int handle, int offset,  int flag)
+{
+//	return mtk_device_wrap_seek(handle,offset,flag);
+}
+
+
+
+int ota_file_read(char* buffer, size_t count, int file)
+{
+//	return mtk_device_wrap_read(file,buffer,count);
+}
+
+
+
+void ota_file_close(int handle)
+{
+//	mtk_device_wrap_close(handle);
+}
+
+
+int md5_file_verfy(char* filePath, char* file_md5)
+{
+	int ret = FALSE;
+	int handle;
+
+	printf("calc file md5: %s\n", filePath);
+	handle = ota_file_open(filePath, "rb",0);	
+	if(handle >= 0){
+		ota_file_seek(handle, 0, SEEK_END,0);
+		
+		{
+			int read_len = 0; 
+			unsigned char buffer[1024] = {0};
+			unsigned char decrypt[16];
+			int i;
+			MD5_CTX md5;  
+			MD5Init(&md5);
+			while ((read_len = ota_file_read(buffer, 1, 1024, handle,0))){   
+				MD5Update(&md5, (unsigned char*)buffer, read_len); 
+			}
+			MD5Final(&md5, (unsigned char*)decrypt);
+			memset(buffer, 0, 1024);
+			for(i = 0; i < 16; i++)  
+			{  
+				sprintf((char*)(buffer + i * 2), "%02x",decrypt[i]);  
+			}
+			printf("md5:%s\n", buffer);
+			printf("md5:%s\n", file_md5);
+			
+			ret = strcmp((const char*)buffer, (const char*)file_md5) == 0;
+		}
+		ota_file_close(handle,0);
+	}
+	return ret;
+}
+
diff --git a/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/cache/parse/main.c.sisc b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/cache/parse/main.c.sisc
new file mode 100755
index 0000000..70e9321
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/cache/parse/main.c.sisc
Binary files differ
diff --git a/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/cache/parse/md5.c.sisc b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/cache/parse/md5.c.sisc
new file mode 100755
index 0000000..934a8b0
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/cache/parse/md5.c.sisc
Binary files differ
diff --git a/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/cache/parse/md5.h.sisc b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/cache/parse/md5.h.sisc
new file mode 100755
index 0000000..5ecf4aa
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/cache/parse/md5.h.sisc
Binary files differ
diff --git a/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/cache/parse/md5_encode.c.sisc b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/cache/parse/md5_encode.c.sisc
new file mode 100755
index 0000000..913feaa
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/cache/parse/md5_encode.c.sisc
Binary files differ
diff --git a/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/cache/parse/md5_encode.h.sisc b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/cache/parse/md5_encode.h.sisc
new file mode 100755
index 0000000..09ce7a0
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/cache/parse/md5_encode.h.sisc
Binary files differ
diff --git a/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/md5_0628.bookmarks.xml b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/md5_0628.bookmarks.xml
new file mode 100755
index 0000000..2e78352
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/md5_0628.bookmarks.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>

+<SourceInsightBookmarks

+	AppVer="4.00.0096"

+	AppVerMinReader="4.00.0009"

+	>

+	<Bookmarks/>

+</SourceInsightBookmarks>

diff --git a/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/md5_0628.siproj_settings.xml b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/md5_0628.siproj_settings.xml
new file mode 100755
index 0000000..53541bc
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/md5_0628.siproj_settings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>

+<ProjectSettings

+	AppVer="4.00.0096"

+	AppVerMinReader="4.00.0034"

+	GlobalConfiguration="1"

+	GlobalWorkspace="0"

+	LocalsInDb="0"

+	IndexMembers="1"

+	IndexFragments="1"

+	UseMasterFileList="0"

+	SourceDir="..\"

+	BackupDir="%PROJECT_DATA_DIR%\Backup"

+	MasterFileList="%PROJECT_SOURCE_DIR%\%PROJECT_NAME%_filelist.txt"

+	IsImportProject="0"

+	>

+	<Imports>

+		<ImportedLibs/>

+	</Imports>

+	<ParseConditions>

+		<Defines/>

+	</ParseConditions>

+</ProjectSettings>

diff --git a/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/md5_0628.siwork b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/md5_0628.siwork
new file mode 100755
index 0000000..bcd4a37
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/md5_0628.siwork
Binary files differ
diff --git a/IC_src/mtk/lib/liblynq-fota/MD5/md5_encode.c b/IC_src/mtk/lib/liblynq-fota/MD5/md5_encode.c
new file mode 100755
index 0000000..918d634
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/MD5/md5_encode.c
@@ -0,0 +1,264 @@
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <log/log.h>
+//xf.li@20230822 add for ab recover start
+#include <errno.h>
+//xf.li@20230822 add for ab recover end
+#include "md5.h"
+#include "mtk_device_wrap.h"
+#include "liblog/lynq_deflog.h"
+#define LOG_TAG "LYNQ_FOTA"
+
+int ota_file_open(char* path, char* flag)
+{
+#if 1
+	if(strcmp(flag, "r") == 0 || strcmp(flag, "rb") == 0)
+		return mtk_device_wrap_open(path, O_RDONLY);
+	else if(strcmp(flag, "r+") == 0 || strcmp(flag, "rb+") == 0)
+		return mtk_device_wrap_open(path, O_RDWR | O_CREAT);
+	else if(strcmp(flag, "w+") == 0 ||strcmp(flag, "wb+") == 0 || strcmp(flag, "w") == 0  || strcmp(flag, "wb") == 0 )	
+		return mtk_device_wrap_open(path, O_RDWR | O_CREAT | O_TRUNC);
+	else if(strcmp(flag, "a+") == 0 ||strcmp(flag, "ab+") == 0 || strcmp(flag, "a") == 0  || strcmp(flag, "ab") == 0 )	
+		return mtk_device_wrap_open(path, O_RDWR | O_CREAT | O_APPEND);	
+#endif
+}
+
+
+int ota_file_seek(int handle, int offset,  int flag)
+{
+	return mtk_device_wrap_seek(handle,offset,flag);
+}
+
+
+
+int ota_file_read(char* buffer, size_t count, int file)
+{
+	return mtk_device_wrap_read(file,buffer,count);
+}
+
+
+
+void ota_file_close(int handle)
+{
+	mtk_device_wrap_close(handle);
+}
+
+#define MD5_READ_BUFFER_LEN 4*1024
+int lynq_md5_file_verfy(char* filePath, char* file_md5)
+{
+	int ret = -1;
+	int handle;
+
+	LYVERBLOG("[+MD5]:calc file md5: %s\n", filePath);
+	handle = open(filePath, O_RDONLY);	
+	LYVERBLOG("[+MD5]:handle:%d\n",handle);
+	if(handle >= 0){
+		{
+			int read_len = 0; 
+			unsigned char buffer[MD5_READ_BUFFER_LEN] = {0};
+			unsigned char decrypt[16];
+			int i;
+			MD5_CTX md5;  
+			MD5Init(&md5);
+			//strcpy(buffer,"12345");
+			while ((read_len = read(handle,buffer, MD5_READ_BUFFER_LEN)) > 0)
+			{   
+				//printf("readlen:%d\n",read_len);
+				MD5Update(&md5, (unsigned char*)buffer, read_len); 				
+				memset(buffer,0,sizeof(buffer));
+			}
+			MD5Final(&md5, (unsigned char*)decrypt);
+			memset(buffer, 0, MD5_READ_BUFFER_LEN);
+			for(i = 0; i < 16; i++)  
+			{  
+				sprintf((char*)(buffer + i * 2), "%02x",decrypt[i]);  
+			}
+			LYVERBLOG("[+MD5]:md5:%s\n", buffer);
+			LYVERBLOG("[+MD5]:md5:%s\n", file_md5);
+			
+			ret = strncmp((const char*)buffer, (const char*)file_md5,32);
+			LYVERBLOG("[+MD5]:ret:%d\n", ret);
+		}
+		close(handle);
+	}
+	return ret;
+}
+//xf.li@20230822 add for ab recover start
+#define MD5_VERFY_ERROR 5
+int lynq_md5_file_verfy_ab(char* filePath, char* file_md5)
+{
+	int ret = -1;
+	int handle;
+
+	RLOGD("[+MD5]:calc file md5: %s\n", filePath);
+	handle = open(filePath, O_RDONLY);	
+	RLOGD("[+MD5]:handle:%d\n",handle);
+	if(handle == -1)
+	{
+		RLOGD("[+MD5]: can't open the file, errno is %d\n",errno);
+	}
+	if(handle >= 0)
+	{
+		int read_len = 0; 
+		unsigned char buffer[MD5_READ_BUFFER_LEN] = {0};
+		unsigned char decrypt[16];
+		int i;
+		MD5_CTX md5;  
+		MD5Init(&md5);
+		while ((read_len = read(handle,buffer, MD5_READ_BUFFER_LEN)) > 0)
+		{   
+			MD5Update(&md5, (unsigned char*)buffer, read_len); 				
+			memset(buffer,0,sizeof(buffer));
+			usleep(1000);
+		}
+		MD5Final(&md5, (unsigned char*)decrypt);
+		memset(buffer, 0, MD5_READ_BUFFER_LEN);
+		for(i = 0; i < 16; i++)  
+		{  
+			sprintf((char*)(buffer + i * 2), "%02x",decrypt[i]);  
+		}
+		RLOGD("[+MD5]:buffer md5:%s\n", buffer);
+		RLOGD("[+MD5]:file_md5 md5:%s\n", file_md5);
+		
+		ret = strncmp((const char*)buffer, (const char*)file_md5,32);
+		RLOGD("[+MD5]:ret:%d\n", ret);
+		close(handle);
+	}
+	if(ret != 0)
+	{
+		return MD5_VERFY_ERROR;
+	}
+	return ret;
+}
+int calculate_file_md5_value(char* filePath, unsigned char buffer_out[])
+{
+	//int ret = -1;
+	int handle;
+
+	RLOGD("[+MD5]:calc file md5: %s\n", filePath);
+	handle = open(filePath, O_RDONLY);
+	RLOGD("[+MD5]:handle:%d\n",handle);
+	if(handle == -1)
+	{
+		RLOGD("[+MD5]: can't open the file, errno is %d\n",errno);
+	}
+	if(handle >= 0)
+	{
+		int read_len = 0; 
+		unsigned char buffer[MD5_READ_BUFFER_LEN] = {0};
+		unsigned char decrypt[16];
+		int i;
+		MD5_CTX md5;  
+		MD5Init(&md5);
+		while ((read_len = read(handle,buffer, MD5_READ_BUFFER_LEN)) > 0)
+		{   
+			MD5Update(&md5, (unsigned char*)buffer, read_len); 				
+			memset(buffer,0,sizeof(buffer));
+			usleep(1000);
+		}
+		MD5Final(&md5, (unsigned char*)decrypt);
+		memset(buffer, 0, MD5_READ_BUFFER_LEN);
+		for(i = 0; i < 16; i++)  
+		{  
+			sprintf((char*)(buffer + i * 2), "%02x",decrypt[i]);  
+		}
+		RLOGD("[+MD5]: md5 of %s : %s\n", filePath, buffer);
+		memcpy(buffer_out, buffer, MD5_READ_BUFFER_LEN);
+		close(handle);
+	}
+	else
+	{
+		return -1;
+	}
+	return 0;
+}
+
+int lynq_md5_two_file_verfy(char* filePath_1, char* filePath_2)
+{
+	int ret = -1;
+	int handle_1, handle_2;
+	unsigned char buffer_1[MD5_READ_BUFFER_LEN] = {0};
+	unsigned char buffer_2[MD5_READ_BUFFER_LEN] = {0};
+	
+	ret = calculate_file_md5_value(filePath_1, buffer_1);
+	if(ret < 0)
+	{
+		RLOGD("[+MD5]:calculate file1 md5 value ERROE!!!\n");
+		return ret;
+	}
+	ret = calculate_file_md5_value(filePath_2, buffer_2);
+	if(ret < 0)
+	{
+		RLOGD("[+MD5]:calculate file2 md5 value ERROE!!!\n");
+		return ret;
+	}
+	RLOGD("buffer_1 is %s, buffer_2 is %s\n", buffer_1, buffer_2);
+	ret = strncmp((const char*)buffer_1, (const char*)buffer_2, 32);
+	RLOGD("[+MD5]:strncmp ret:%d\n", ret);
+
+	if(ret != 0)
+	{
+		return MD5_VERFY_ERROR;
+	}
+	return 0;
+}
+//xf.li@20230822 add for ab recover end
+#if 0
+int md5_file_verfy_new(char* filePath, char* file_md5,int packe_len)
+{
+	int ret = -1;
+	int handle;
+	int tatal_packe_len = 0;
+
+	LYVERBLOG("[+MD5]:calc file md5: %s\n", filePath);
+	handle = mtk_device_wrap_open(filePath, O_RDONLY);	
+	LYVERBLOG("[+MD5]:handle:%d\n",handle);
+	if(handle >= 0){
+		{
+			int read_len = 0; 
+			unsigned char buffer[MD5_READ_BUFFER_LEN] = {0};
+			unsigned char decrypt[16];
+			int i;
+			MD5_CTX md5;  
+			MD5Init(&md5);
+			//strcpy(buffer,"12345");
+			tatal_packe_len = packe_len;
+			LYVERBLOG("[+MD5]:tatal_packe_len:%d\n", tatal_packe_len);
+			while ((read_len = mtk_device_wrap_read(handle,buffer, MD5_READ_BUFFER_LEN)) > 0)
+			{   
+				//printf("readlen:%d\n",read_len);
+				if(tatal_packe_len >= read_len)
+				{
+					MD5Update(&md5, (unsigned char*)buffer, read_len); 
+					tatal_packe_len -= read_len;
+				}
+				else if(tatal_packe_len > 0)
+				{
+					LYVERBLOG("[+MD5]:tatal_packe_len:%d\n", tatal_packe_len);
+					MD5Update(&md5, (unsigned char*)buffer, tatal_packe_len); 
+					tatal_packe_len -= read_len;
+				}
+				LYVERBLOG("[+MD5]:tatal_packe_len:%d\n", tatal_packe_len);			
+				memset(buffer,0,sizeof(buffer));
+			}
+			MD5Final(&md5, (unsigned char*)decrypt);
+			memset(buffer, 0, MD5_READ_BUFFER_LEN);
+			for(i = 0; i < 16; i++)  
+			{  
+				sprintf((char*)(buffer + i * 2), "%02x",decrypt[i]);  
+			}
+			LYVERBLOG("[+MD5]:md5:%s\n", buffer);
+			LYVERBLOG("[+MD5]:md5:%s\n", file_md5);
+			
+			ret = strncmp((const char*)buffer, (const char*)file_md5,32);
+			LYVERBLOG("[+MD5]:ret:%d\n", ret);
+		}
+		mtk_device_wrap_close(handle);
+	}
+	return ret;
+}
+#endif
\ No newline at end of file
diff --git a/IC_src/mtk/lib/liblynq-fota/include/iot_rock.h b/IC_src/mtk/lib/liblynq-fota/include/iot_rock.h
new file mode 100755
index 0000000..a6e6821
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/include/iot_rock.h
@@ -0,0 +1,166 @@
+#ifndef _IOT_ROCK_H_

+#define _IOT_ROCK_H_

+

+#include <sys/types.h>

+#include <sys/stat.h>

+#include <fcntl.h>

+#include <unistd.h>

+

+/* public */

+

+#define E_ROCK_SUCCESS (0)

+#define E_ROCK_INVALID_DELTA (-1)

+#define E_ROCK_DELTA_MISMATCH (-2)

+#define E_ROCK_DELTA_CHUNK_MISMATCH (-3)

+#define E_ROCK_READ_DELTA_ERROR (-4)

+#define E_ROCK_READ_BLOCK_ERROR (-11)

+#define E_ROCK_WRITE_BLOCK_ERROR (-12)

+#define E_ROCK_RAM_NOT_ENOUGH (-20)

+#define E_ROCK_INVALID_CTX	(-30)

+#define E_ROCK_FOTA_ADDR (-50)

+

+

+#define PATCH_SYSTEM   (1)

+#define PATCH_BOOT     (2)

+#define PATCH_TEE      (3)

+#define PATCH_MD1IMG   (4)

+#define PATCH_MD1DSP   (5)

+#define PATCH_VBMETA   (6)

+#define PATCH_OEMAPP   (7)

+#define PATCH_OEMAPP2  (8)

+#define PATCH_MEDMCU   (9)

+#define PATCH_SPM      (10)

+#define PATCH_PROTECT  (11)

+#define PATCH_MCF1     (12)

+#define PATCH_MCF2     (13)

+#define PATCH_MCUPM    (14)

+#define PATCH_SSPM     (15)

+#define PATCH_DPM      (16)

+#define PATCH_PIIMG    (17)

+#define PATCH_HSMOS    (18)

+#define PATCH_BL2      (19)

+#define PATCH_BL33     (20)

+

+#define FULL_SYSTEM    (65)

+#define FULL_BOOT      (66)

+#define FULL_TEE       (67)

+#define FULL_MD1IMG    (68)

+#define FULL_MD1DSP    (69) 

+#define FULL_VBMETA    (70)

+#define FULL_OEMAPP    (71)

+#define FULL_OEMAPP2   (72)

+#define FULL_MEDMCU    (73)

+#define FULL_SPM       (74)

+#define FULL_PROTECT   (75)

+#define FULL_MCF1      (76)

+#define FULL_MCF2      (77)

+#define FULL_MCUPM     (78) 

+#define FULL_SSPM      (79)

+#define FULL_DPM       (80)

+#define FULL_PIIMG     (81)

+#define FULL_HSMOS     (82)

+#define FULL_BL2       (83)

+#define FULL_BL33      (84)

+

+

+

+

+

+

+

+

+#define MAX_OTA_ROLE   (128) 

+#define REAL_OTA_ROLE  (20)

+

+

+

+#define MODE_NORMAL           0

+#define MODE_A2B              1

+#define MODE_B2A              2

+

+#define WAIT            0xff

+#define PASS             0

+#define ERROR           -1

+

+typedef struct {

+	void* user_context;

+	unsigned int rom_base;	// old rom start

+	unsigned char* ram_base;	// ram working buffer start

+	unsigned int ram_len; 		// ram working buffer len

+

+	unsigned int backup_base;	// ram backup storage start

+	unsigned int backup_len; 		// ram backup storage len

+

+	unsigned int update_nvram;	// nvram update flag

+

+	int read_rom_directly;

+	int first_run;

+} IOT_UPDATA_CONTEXT;

+

+

+

+

+typedef struct {

+

+    char fota_flag[32];	    //fota 标志保留 

+    int  update_result;     //升级结果

+	int  ota_run;            //  

+	char cid[32];

+	char did[32];

+} UPDATE_INFO;

+

+

+typedef struct {

+	int  need_update;

+    int  check_delta;

+    int  check_rom;

+	int  update_result;

+	

+} UPDATE_STATUS;

+

+

+typedef struct {

+	int  ota_run;

+    UPDATE_STATUS  update_status[MAX_OTA_ROLE];

+	int  update_result;

+	int  switch_slot;

+	

+} OTA_STATUS;

+

+

+

+

+

+//#define DELTA_HEARD_SIZE	(4*5)

+

+//#define DELTA_HEARD_SIZE	    (4*11 + 4*11)

+#define DELTA_HEARD_SIZE	    512

+#define DELTA_FULL_HEARD_SIZE   8

+

+

+

+int iot_patch(IOT_UPDATA_CONTEXT* update_ctx);

+

+unsigned int iot_hash(unsigned char *buf,unsigned int len, unsigned int* value);

+int lynq_md5_file_verfy(char* filePath, char* file_md5);

+//xf.li@20230822 add for ab recover start

+int lynq_md5_file_verfy_ab(char* filePath, char* file_md5);

+int calculate_file_md5_value(char* filePath, unsigned char buffer_out[]);

+int lynq_md5_two_file_verfy(char* filePath_1, char* filePath_2);

+//xf.li@20230822 add for ab recover end

+//int md5_file_verfy_new(char* filePath, char* file_md5,int packe_len);

+int lynq_rock_main(int first_run);

+int lynq_fota_func(void);

+int lynq_nand_open(const char *pathname, int flags);

+ssize_t lynq_nand_read(int fd, void *buf, size_t count);

+ssize_t lynq_nand_write(int fd, void *buf, size_t count);

+int lynq_nand_close(int fd);

+int lynq_get_upgrade_status(void);

+void lynq_reboot_device(void);

+int lynq_fota_nrestart(void);

+int lynq_fota_set_addr_value(char *value,int size);

+int lynq_fota_get_addr_value(char *tmp);

+#endif

+

+

+

diff --git a/IC_src/mtk/lib/liblynq-fota/include/iot_rock_ipl.h b/IC_src/mtk/lib/liblynq-fota/include/iot_rock_ipl.h
new file mode 100755
index 0000000..77c7c2a
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/include/iot_rock_ipl.h
@@ -0,0 +1,22 @@
+#ifndef _IOT_ROCK_IPL_H_

+#define _IOT_ROCK_IPL_H_

+

+void rock_trace(void* ctx, const char* fmt, ...);

+void rock_progress(void* ctx, int percent);

+int rock_read_block(void* ctx, unsigned char* dest, unsigned int start, unsigned int size);

+int rock_read_delta(void* ctx, unsigned char* dest, unsigned int offset, unsigned int size);

+int rock_write_block(void* ctx, unsigned char* src, unsigned int start, unsigned int size);

+int rock_process_block(void* ctx, unsigned char* data, unsigned int start, unsigned int size);

+int rock_get_blocksize(void* ctx);

+

+int rock_read_file(void* ctx,  void* name, unsigned char* dest, unsigned int offset, unsigned int size);

+int rock_write_file(void* ctx,  void* name, unsigned char* src, unsigned int offset, unsigned int size);

+

+int rock_delete_file(void* ctx, void* name);

+

+int rock_fatal(void* ctx, int error_code);

+

+int rock_mismatch(void* ctx, unsigned char* buf, unsigned int start, unsigned int size, 

+							unsigned int source_hash,unsigned int target_hash);

+#endif

+

diff --git a/IC_src/mtk/lib/liblynq-fota/include/md5.h b/IC_src/mtk/lib/liblynq-fota/include/md5.h
new file mode 100755
index 0000000..f0e3a1b
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/include/md5.h
@@ -0,0 +1,48 @@
+#ifndef MD5_H
+#define MD5_H
+
+typedef struct
+{
+	unsigned int count[2];
+	unsigned int state[4];
+	unsigned char buffer[64];   
+}MD5_CTX;
+
+
+#define F(x,y,z) ((x & y) | (~x & z))
+#define G(x,y,z) ((x & z) | (y & ~z))
+#define H(x,y,z) (x^y^z)
+#define I(x,y,z) (y ^ (x | ~z))
+#define ROTATE_LEFT(x,n) ((x << n) | (x >> (32-n)))
+#define FF(a,b,c,d,x,s,ac) \
+{ \
+	a += F(b,c,d) + x + ac; \
+	a = ROTATE_LEFT(a,s); \
+	a += b; \
+}
+#define GG(a,b,c,d,x,s,ac) \
+{ \
+	a += G(b,c,d) + x + ac; \
+	a = ROTATE_LEFT(a,s); \
+	a += b; \
+}
+#define HH(a,b,c,d,x,s,ac) \
+{ \
+	a += H(b,c,d) + x + ac; \
+	a = ROTATE_LEFT(a,s); \
+	a += b; \
+}
+#define II(a,b,c,d,x,s,ac) \
+{ \
+	a += I(b,c,d) + x + ac; \
+	a = ROTATE_LEFT(a,s); \
+	a += b; \
+}                                            
+void MD5Init(MD5_CTX *context);
+void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen);
+void MD5Final(MD5_CTX *context,unsigned char digest[16]);
+void MD5Transform(unsigned int state[4],unsigned char block[64]);
+void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len);
+void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len);
+
+#endif
\ No newline at end of file
diff --git a/IC_src/mtk/lib/liblynq-fota/include/md5_encode.h b/IC_src/mtk/lib/liblynq-fota/include/md5_encode.h
new file mode 100755
index 0000000..c3e5d38
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/include/md5_encode.h
@@ -0,0 +1,33 @@
+#ifndef MD5_ENCODE_H_
+#define MD5_ENCODE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+//打开文件
+int ota_file_open(char* path, char* flag);
+//文件偏移位置
+int ota_file_seek(int handle, int offset,  int flag);
+//读文件内容
+int ota_file_read(char* buffer, size_t count, int file);
+//关闭文件
+void ota_file_close(int handle);
+
+
+/*** 
+ * @description:                校验文件的MD5
+ * @param filePath              文件路径
+ * @param file_md5              待校验MD5值
+ * @return  		0:校验成功;  其他:校验失败 
+ */
+int md5_file_verfy(char* filePath, char* file_md5);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/IC_src/mtk/lib/liblynq-fota/include/sha.h b/IC_src/mtk/lib/liblynq-fota/include/sha.h
new file mode 100755
index 0000000..05f9941
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/include/sha.h
@@ -0,0 +1,75 @@
+/* sha.h
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+**     * Redistributions of source code must retain the above copyright
+**       notice, this list of conditions and the following disclaimer.
+**     * Redistributions in binary form must reproduce the above copyright
+**       notice, this list of conditions and the following disclaimer in the
+**       documentation and/or other materials provided with the distribution.
+**     * Neither the name of Google Inc. nor the names of its contributors may
+**       be used to endorse or promote products derived from this software
+**       without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR
+** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+** EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef _EMBEDDED_SHA_H_
+#define _EMBEDDED_SHA_H_
+
+#include <inttypes.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct SHA_CTX {
+    uint64_t count;
+    uint32_t state[5];
+#if defined(HAVE_ENDIAN_H) && defined(HAVE_LITTLE_ENDIAN)
+    union {
+        uint8_t b[64];
+        uint32_t w[16];
+    } buf;
+#else
+    uint8_t buf[64];
+#endif
+} SHA_CTX;
+
+void SHA_init(SHA_CTX* ctx);
+void SHA_update(SHA_CTX* ctx, const void* data, int len);
+const uint8_t* SHA_final(SHA_CTX* ctx);
+
+/* Convenience method. Returns digest parameter value. */
+const uint8_t* SHA(const void* data, int len, uint8_t* digest);
+
+#define SHA_DIGEST_SIZE 20
+
+typedef enum check_status_t{
+	ERROR_SHA = -3,			// sha1输入参数错误
+	PATCH_ERR = -2,			// 检测hash既不等于source_hash也不等于target_hash, 一般错误情况
+	NOT_EXIST_FILE = -1,	// 检测文件不存在
+	SOURCE_SUCC = 0,		// 检测hash等于目标source_hash, 一般正常情况
+	PATCH_SUCC = 1,			// 检测hash等于目标target_hash, up to data
+}Check_status;
+
+int ParseSha1(const char* str, uint8_t* digest);
+
+const uint8_t* ROCK_SHA(const char *file_name, uint8_t *digest);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/IC_src/mtk/lib/liblynq-fota/lib/libiotpatch.a b/IC_src/mtk/lib/liblynq-fota/lib/libiotpatch.a
new file mode 100755
index 0000000..023c16e
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/lib/libiotpatch.a
Binary files differ
diff --git a/IC_src/mtk/lib/liblynq-fota/lib/libmd5.a b/IC_src/mtk/lib/liblynq-fota/lib/libmd5.a
new file mode 100755
index 0000000..1cebf1f
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/lib/libmd5.a
Binary files differ
diff --git a/IC_src/mtk/lib/liblynq-fota/makefile b/IC_src/mtk/lib/liblynq-fota/makefile
new file mode 100755
index 0000000..4fe83ea
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/makefile
@@ -0,0 +1,79 @@
+SHELL = /bin/sh
+RM = rm -f
+
+LOCAL_CFLAGS := -Wall \
+                -g -Os \
+                -flto \
+                -fpermissive \
+                -DRIL_SHLIB \
+                -DATCI_PARSE \
+                -DKEEP_ALIVE \
+                -D__LINUX_OS__ \
+                -DECALL_SUPPORT
+
+CFLAGS += -fPIC -O2 $(INCLUDE) -D_LARGEFILE64_SOURCE
+
+$(warning ################# rock ROOT: $(ROOT),includedir:$(includedir))
+LOCAL_PATH   = .
+
+LOCAL_C_INCLUDES = \
+  -I. \
+  -I./include \
+  -I$(LOCAL_PATH)/../include \
+  -I$(ROOT)$(includedir)/logger \
+  -I$(ROOT)$(includedir)/liblog \
+  -I$(ROOT)$(includedir)/ftp \
+  -I$(ROOT)$(includedir)/glib-2.0 \
+  -I$(ROOT)$(libdir)/glib-2.0/include \
+
+
+
+LOCAL_LIBS := \
+    -L. \
+    -L./lib \
+    -ldl \
+    -lpthread \
+    -llog \
+    -lstdc++ \
+    -liotpatch \
+	-lmd5	\
+    -lnandapi  \
+    -lbootctrl  \
+    -llynq-log \
+    -llynq-protcl \
+    -llynq-uci \
+
+SOURCES = $(wildcard *.c wildcard *.h rock_ua/*.c  MD5/*c)
+
+EXECUTABLE = liblynq-fota.so
+
+OBJECTS=$(SOURCES:.c=.o)
+
+
+.PHONY: build clean install pack_rootfs 
+
+all: build
+$(EXECUTABLE): $(OBJECTS)
+	$(CXX) -shared -Wl,--no-undefined $(OBJECTS) $(LOCAL_LIBS) $(CFLAGS) $(LOCAL_CFLAGS) $(LOCAL_C_INCLUDES) -o $@
+
+%.o : %.c
+	$(CC) $(LOCAL_C_INCLUDES) $(CFLAGS) $(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)
\ No newline at end of file
diff --git a/IC_src/mtk/lib/liblynq-fota/rock_ua/rock_ua.c b/IC_src/mtk/lib/liblynq-fota/rock_ua/rock_ua.c
new file mode 100755
index 0000000..c970ce1
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/rock_ua/rock_ua.c
@@ -0,0 +1,2079 @@
+// 2017-07-31 carota Rock FOTA ua porting file
+
+
+#define ROCK_FOTA_SUPPORT
+
+#ifdef ROCK_FOTA_SUPPORT
+
+
+#include "iot_rock.h"
+#include "iot_rock_ipl.h"
+#include "sha.h"
+#include <log/log.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <stdint.h>
+
+
+#include <hardware/boot_control.h>
+#include <hardware/hardware.h>
+#include <sys/reboot.h>
+
+
+
+#include "liblog/lynq_deflog.h"
+#include "mtk_device_wrap.h"
+#include <include/lynq_uci.h>
+
+#define ROCK_DEFAULT_BLOCK_SIZE 0x40000
+#define ROCK_RAM_LEN  (1024*1024)
+
+#define LOG_TAG "LYNQ_FOTA"
+#define ROCK_BACKUP_LEN ROCK_DEFAULT_BLOCK_SIZE
+
+
+
+#define FILENAME_SIZE   50
+
+
+
+//#define DEV_DELTA       "/dev/disk/by-partlabel/delta"
+#if 0
+#define DEV_DELTA       "/dev/disk/by-partlabel/delta"
+#else
+#define DEV_DELTA       "/dev/mtd41"    
+#endif
+
+
+
+char partition_filename_a[][FILENAME_SIZE] = {
+    {"/dev/disk/by-partlabel/system_a"},
+    {"/dev/disk/by-partlabel/boot_a"},
+    {"/dev/disk/by-partlabel/tee_a"},
+    {"/dev/disk/by-partlabel/md1img_a"},
+    {"/dev/disk/by-partlabel/md1dsp_a"},
+    {"/dev/disk/by-partlabel/vbmeta_a"},
+    {"/dev/disk/by-partlabel/oemapp_a"},
+    {"/dev/disk/by-partlabel/oemapp2_a"},
+    {"/dev/disk/by-partlabel/medmcu_a"},
+    {"/dev/disk/by-partlabel/spm_a"},
+    {"/dev/disk/by-partlabel/protect_a"},    
+    {"/dev/disk/by-partlabel/mcf1_a"},
+    {"/dev/disk/by-partlabel/mcf2_a"},
+    {"/dev/disk/by-partlabel/mcupm_a"},
+    {"/dev/disk/by-partlabel/sspm_a"},    
+    {"/dev/disk/by-partlabel/dpm_a"},
+    {"/dev/disk/by-partlabel/pi_img_a"},    
+    {"/dev/disk/by-partlabel/hsm_os_a"},
+    {"/dev/disk/by-partlabel/bl2_a"},    
+    {"/dev/disk/by-partlabel/bl33_a"}
+};
+
+
+char partition_filename_b[][FILENAME_SIZE] = {
+    {"/dev/disk/by-partlabel/system_b"},
+    {"/dev/disk/by-partlabel/boot_b"},
+    {"/dev/disk/by-partlabel/tee_b"},
+    {"/dev/disk/by-partlabel/md1img_b"},
+    {"/dev/disk/by-partlabel/md1dsp_b"},
+    {"/dev/disk/by-partlabel/vbmeta_b"},
+    {"/dev/disk/by-partlabel/oemapp_b"},
+    {"/dev/disk/by-partlabel/oemapp2_b"},
+    {"/dev/disk/by-partlabel/medmcu_b"},    
+    {"/dev/disk/by-partlabel/spm_b"},
+    {"/dev/disk/by-partlabel/protect_b"},
+    {"/dev/disk/by-partlabel/mcf1_b"},
+    {"/dev/disk/by-partlabel/mcf2_b"},
+    {"/dev/disk/by-partlabel/mcupm_b"},
+    {"/dev/disk/by-partlabel/sspm_b"},    
+    {"/dev/disk/by-partlabel/dpm_b"},
+    {"/dev/disk/by-partlabel/pi_img_b"},
+    {"/dev/disk/by-partlabel/hsm_os_b"},
+    {"/dev/disk/by-partlabel/bl2_b"},    
+    {"/dev/disk/by-partlabel/bl33_b"}
+};
+
+
+
+
+char partition_filename[][FILENAME_SIZE] = {
+    {"system"},
+    {"boot"},
+    {"tee"},
+    {"md1img"},
+    {"md1dsp"},
+    {"vbmeta"},
+    {"oemapp"},
+    {"oemapp2"},
+    {"medmcu"},
+    {"spm"},
+    {"protect"},
+    {"mcf1"},
+    {"mcf2"},
+    {"mcupm"},
+    {"sspm"},
+    {"dpm"},
+    {"pi_img"},
+    {"hsm_os"},
+    {"bl2"},
+    {"bl33"}
+};
+//+10 
+
+unsigned int  delta_head[128]={0};  //512/4   128/2=64
+
+
+
+#define FOTA_UCI_MODULE "lynq_fota"
+#define FOTA_UCI_FILE "lynq_uci"
+#define FOTA_UCI_ADDR "lynq_fota_addr"
+#define FOTA_UCI_STATE "lynq_fota_state"
+
+#define FILE_UPDATE_STATE  "/data/.update_status"
+#define FILE_UPDATE_FLAG   "/tmp/update_flag"
+#define FILE_FOTA_STATE    "/data/.fota_status"
+
+#define NAND_PAGE_SIZE  4096
+
+
+#define BOOTDEV_TYPE_NAND 1
+
+#define BACKUP_ADDR_FLAG    0xffffffff
+#define FILE_BACKUP      "/data/.backup"
+
+#define SLOT_A    0
+#define SLOT_B    1
+
+#define FULL_HEAD "full-ota"
+
+//xf.li@20230822 add for ab rollback start
+#define DEV_SYSTEM_A    "/dev/disk/by-partlabel/system_a"
+#define DEV_SYSTEM_B    "/dev/disk/by-partlabel/system_b"
+
+#define DEV_BOOT_A      "/dev/disk/by-partlabel/boot_a"
+#define DEV_BOOT_B      "/dev/disk/by-partlabel/boot_b"
+
+#define DEV_SPM_A      "/dev/disk/by-partlabel/spm_a"
+#define DEV_SPM_B      "/dev/disk/by-partlabel/spm_b"
+
+#define DEV_MD1IMG_A    "/dev/disk/by-partlabel/md1img_a"
+#define DEV_MD1IMG_B    "/dev/disk/by-partlabel/md1img_b"
+
+#define DEV_TEE_A       "/dev/disk/by-partlabel/tee_a"
+#define DEV_TEE_B       "/dev/disk/by-partlabel/tee_b" 
+
+#define DEV_VBMETA_A       "/dev/disk/by-partlabel/vbmeta_a"
+#define DEV_VBMETA_B       "/dev/disk/by-partlabel/vbmeta_b"
+
+#define DEV_BL2_A         "/dev/disk/by-partlabel/bl2_a"
+#define DEV_BL2_B         "/dev/disk/by-partlabel/bl2_b"
+
+#define DEV_BL33_A        "/dev/disk/by-partlabel/bl33_a"
+#define DEV_BL33_B        "/dev/disk/by-partlabel/bl33_b"
+
+#define DEV_MEDMCU_A        "/dev/disk/by-partlabel/medmcu_a"
+#define DEV_MEDMCU_B        "/dev/disk/by-partlabel/medmcu_b"
+
+#define DEV_OEMAPP_A        "/dev/disk/by-partlabel/oemapp_a"
+#define DEV_OEMAPP_B        "/dev/disk/by-partlabel/oemapp_b"
+
+#define DEV_OEMAPP2_A        "/dev/disk/by-partlabel/oemapp2_a"
+#define DEV_OEMAPP2_B        "/dev/disk/by-partlabel/oemapp2_b"
+
+
+#define DEV_MISC        "/dev/disk/by-partlabel/misc"
+
+#define BACKUP_UBI_NUM  31 //max ubi number
+#define MTD_SYSTEM_A 14
+#define MTD_SYSTEM_B 15
+#define MD5_RETRY_TIME 3
+#define MD5_VERFY_ERROR 5
+#define MD5_READ_BUFFER_LEN 4*1024
+#define FOTA_FIRST 0
+#define RECOVER_FIRST 1
+int fota_interrupt = 1;
+//xf.li@20230822 add for ab rollback end
+
+
+//int fd_system_a,fd_system_b,fd_boot_a,fd_boot_b,fd_tee_a,fd_tee_b,fd_bl2,fd_bl33,fd_delta,fd_curr,fd_log,fd_update_status,fd_md1img_a,fd_md1img_b,fd_fota_status,fd_md1dsp_a,fd_md1dsp_b,fd_vbmeta_a,fd_vbmeta_b,fd_oemapp_a,fd_oemapp_b,fd_oemapp2_a,fd_oemapp2_b,fd_medmcu_a,fd_medmcu_b,fd_bl33_a,fd_bl33_b;
+int fd_delta,fd_curr,fd_log,fd_update_status,fd_fota_status;
+int fd_write,fd_read;
+
+static unsigned int  delta_offset = 0;
+static unsigned int  now_patch = 0;
+unsigned int  current_slot = 0;
+unsigned char rock_debug_buffer[512];
+
+
+
+OTA_STATUS  fota_status;
+UPDATE_INFO up_info;
+
+
+extern const hw_module_t HAL_MODULE_INFO_SYM;
+boot_control_module_t* module;
+
+static void lynq_init_wake_lock_func(void);
+static void lynq_fota_grab_artial_wake_lock(void);
+static void lynq_fota_release_wake_lock(void);
+int check(int sys_size);
+int check_cpu();
+
+static const char hex_chars[] = "0123456789abcdef";
+
+/**
+ * @brief The following is the wake up
+ * start
+ */
+
+#define ANDROID_WAKE_LOCK_NAME "fota-interface"
+
+void *dlHandle_wakelock;
+
+enum {
+    PARTIAL_WAKE_LOCK = 1,  // the cpu stays on, but the screen is off
+    FULL_WAKE_LOCK = 2      // the screen is also on
+};
+
+// while you have a lock held, the device will stay on at least at the
+// level you request.
+
+int (*acquire_wake_lock)(int lock, const char* id);
+int (*release_wake_lock)(const char* id);
+
+void convert_hex(unsigned char *sha, unsigned char *shastr)
+{
+    int i;
+    int j = 0;
+    unsigned int c;
+
+    for (i = 0; i < 20; i++) {
+        c = (sha[i] >> 4) & 0x0f;
+        shastr[j++] = hex_chars[c];
+        shastr[j++] = hex_chars[sha[i] & 0x0f];
+    }
+    shastr[40] = '\0';
+}  
+
+
+
+
+int rock_mismatch(void* ctx, unsigned char* buf, unsigned int start, unsigned int size, 
+                            unsigned int source_hash,unsigned int target_hash) {
+
+      return 0;
+}
+                            
+int rock_fatal(void* ctx, int error_code) {
+    return 0;
+}
+
+void rock_trace(void* ctx, const char* fmt, ...) {
+
+    va_list     ap;
+    memset(rock_debug_buffer,0x0,sizeof(rock_debug_buffer));
+    va_start (ap, fmt);
+
+    
+    vsnprintf(rock_debug_buffer,sizeof(rock_debug_buffer),fmt,ap);
+    LYDBGLOG("+[UA]: %s",rock_debug_buffer);
+    
+
+    va_end (ap);
+
+}
+
+static int save_fota_status()
+{
+    int err;
+    fd_fota_status = open(FILE_FOTA_STATE,O_RDWR | O_CREAT,0777);
+
+    if (fd_fota_status < 0) {
+        err = errno;
+        RLOGD("+[UA]: save_fota_status: Error opening metadata file: %s\n",strerror(errno));
+        return -err;
+    }
+    
+    write(fd_fota_status, &fota_status,sizeof(fota_status));
+    sync();
+    
+    close(fd_fota_status);
+}
+
+static int save_fota_info()
+{
+    int err;
+    fd_update_status = open(FILE_UPDATE_STATE,O_RDWR);
+
+    if (fd_update_status < 0) {
+        err = errno;
+        RLOGD("+[UA]: save_fota_status: Error opening metadata file: %s\n",strerror(errno));
+        return -err;
+    }
+
+    write(fd_update_status, &up_info, sizeof(fota_status));
+    sync();
+    close(fd_update_status);
+}
+
+
+
+void rock_progress(void* ctx, int percent) {
+    int i = 0;
+    static int tmp_percent = -1;
+    rock_trace(ctx, "rock update progress %d\n", percent);
+
+    if (tmp_percent != percent) {
+        tmp_percent = percent;
+        if (percent > 20) {
+            i = fota_status.ota_run;
+            if (fota_status.update_status[i-1].check_delta != PASS) {
+                fota_status.update_status[i-1].check_delta = PASS;
+                fota_status.update_status[i-1].check_rom= PASS;
+                save_fota_status();
+            }
+        }
+    }
+}
+
+int rock_process_block(void* ctx, unsigned char* data, unsigned int start, unsigned int size){
+    //rock_trace(ctx, "rock update progress block %d\n", size);
+
+    int writen = 0;
+    int ret,err;
+    
+    
+    if (start == BACKUP_ADDR_FLAG) {
+        int fd_backup = open(FILE_BACKUP,O_RDWR | O_CREAT,0777);
+        while (writen < size) {
+            write(fd_backup,data,ROCK_DEFAULT_BLOCK_SIZE);
+            sync();
+            writen += ROCK_DEFAULT_BLOCK_SIZE;
+        }
+        close(fd_backup);
+        return size;
+    }
+    
+    
+    
+    writen = 0;
+   
+    if (mtk_device_wrap_seek(fd_write, start, SEEK_SET) < 0) {
+        err = errno;
+        rock_trace(ctx, "mtk_device_wrap_seek write\n");
+        return err;
+    } 
+
+    while (writen < size) {
+        ret = mtk_device_wrap_write(fd_write,data+writen, ROCK_DEFAULT_BLOCK_SIZE);
+        writen += ROCK_DEFAULT_BLOCK_SIZE;
+    }       
+    
+    
+    return size;
+}
+
+int rock_write_block(void* ctx, unsigned char* src, unsigned int start, unsigned int size){
+
+#if 0
+
+    int writen = 0;
+    int ret,err;
+    
+    
+    if (start == BACKUP_ADDR_FLAG) {
+        int fd_backup = open(FILE_BACKUP,O_RDWR | O_CREAT,0777);
+        while (writen < size) {
+            write(fd_backup,src,ROCK_DEFAULT_BLOCK_SIZE);
+            sync();
+            writen += ROCK_DEFAULT_BLOCK_SIZE;
+        }
+        close(fd_backup);
+        return size;
+    }
+    
+    writen = 0;
+   
+    if (mtk_device_wrap_seek(fd_curr, start, SEEK_SET) < 0) {
+        err = errno;
+        rock_trace(ctx, "mtk_device_wrap_seek write\n");
+        return err;
+    } 
+
+    while (writen < size) {
+        ret = mtk_device_wrap_write(fd_curr,src+writen, ROCK_DEFAULT_BLOCK_SIZE);
+        writen += ROCK_DEFAULT_BLOCK_SIZE;
+    }    
+    
+
+#endif
+
+    return size;
+
+}
+
+int rock_read_block(void* ctx, unsigned char* dest, unsigned int start, unsigned int size){
+
+
+    int ret,err;
+    
+
+    if (start == BACKUP_ADDR_FLAG) {
+        int fd_backup = open(FILE_BACKUP,O_RDONLY);
+        read(fd_backup,dest,size);
+        sync();
+        close(fd_backup);
+        return size;
+    }
+    
+
+
+    if (mtk_device_wrap_seek(fd_read, start, SEEK_SET) < 0) {
+        err = errno;
+        rock_trace(ctx, "mtk_device_wrap_seek read block err\n");
+    }
+
+    do {
+
+        ret = mtk_device_wrap_read(fd_read, dest, size);
+
+        if (ret == 0) {
+            break;
+        } else if (ret < 0) {
+            if (errno == EINTR) {
+                continue;
+            }
+            err = -errno;
+            rock_trace(ctx,"%s Error reading metadata file\n");
+
+            mtk_device_wrap_close(fd_read);
+
+            return err;
+        }
+        size -= ret;
+        dest += ret;
+    } while(size > 0);
+
+
+    return ret;    
+   
+    
+}
+
+
+int rock_read_delta(void* ctx, unsigned char* dest, unsigned int offset, unsigned int size){
+
+    int ret = 0,err = 0;
+    
+    
+    if (lseek(fd_delta, offset + delta_offset, SEEK_SET) < 0) {
+        err = -errno;
+        rock_trace(ctx, "mtk_device_wrap_seek df_delta err\n");
+        return err;
+    }
+
+    do {
+
+        ret = read(fd_delta, dest, size);
+
+        if (ret == 0) {
+            break;
+        } else if (ret < 0) {
+            if (errno == EINTR) {
+                continue;
+            }
+            err = -errno;
+            rock_trace(ctx," Error reading metadata file\n");
+
+            close(fd_delta);
+
+            return err;
+        }
+        size -= ret;
+        dest += ret;
+    } while(size > 0);
+
+    return ret;    
+
+}
+
+int rock_get_blocksize(void* ctx) {
+    return ROCK_DEFAULT_BLOCK_SIZE;
+}
+
+int rock_read_file(void* ctx,  void* name, unsigned char* dest, unsigned int offset, unsigned int size){return 0;}
+int rock_write_file(void* ctx,  void* name, unsigned char* src, unsigned int offset, unsigned int size){return 0;}
+int rock_delete_file(void* ctx, void* name){return 0;}
+/* ROCK IPL end */
+
+
+
+static int init_dev_fd()
+{
+
+    int err;
+    char lynq_fota_addr[64] = {0};
+    char fota_name[]= "fota.delta";
+    int n;
+    if(0 != lynq_fota_get_addr_value(lynq_fota_addr))
+    {
+        return E_ROCK_FOTA_ADDR;
+    }
+    RLOGD("+[UA]: get fota pack addr: %s\n",lynq_fota_addr);
+    fd_delta = open(lynq_fota_addr,O_RDWR);
+
+    if (fd_delta < 0) {
+        err = errno;
+        RLOGD("+[UA]: Error opening metadata file: %s\n",strerror(errno));
+        return -err;
+    }
+
+    fd_update_status = open(FILE_UPDATE_STATE,O_RDWR | O_CREAT,0777);
+    if (fd_update_status < 0) {
+        err = errno;
+        RLOGD("+[UA]: Error opening metadata file: %s\n",strerror(errno));
+        return -err;
+    }
+    memset(&up_info, 0, sizeof(up_info));
+    lseek(fd_update_status,0,SEEK_SET);
+    read(fd_update_status,(unsigned char *)&up_info,sizeof(up_info));
+    close(fd_update_status);
+    return 0;
+}
+
+
+
+
+
+static int close_dev_fd(int fd)
+{
+    close(fd);
+}
+
+
+
+static int reboot_device() {
+    
+  reboot(RB_AUTOBOOT);
+  
+  while (1) pause();
+}
+
+
+
+int test_write_delta(char *source, char *target)
+{
+    int fd_source,fd_target,size;
+     
+    char delta_data[ROCK_DEFAULT_BLOCK_SIZE];
+     
+    fd_source = open(source,O_RDONLY);
+     
+    if (fd_source < 0) {
+        RLOGD("+[UA]: open source  error\n");
+        return 1;
+    }
+
+    fd_target = mtk_device_wrap_open(target,O_RDWR);
+ 
+    if (fd_target < 0) {
+        mtk_device_wrap_close(fd_target);
+        close(fd_source);
+        RLOGD("+[UA]: open target  error\n");
+        return 1;
+    } 
+    
+    while(( size = read(fd_source,delta_data,ROCK_DEFAULT_BLOCK_SIZE))>0) {
+           mtk_device_wrap_write(fd_target,delta_data,ROCK_DEFAULT_BLOCK_SIZE);
+    }
+    
+    mtk_device_wrap_close(fd_target);
+    close(fd_source);
+    return 0;
+}
+
+
+int nand_copyto_nand(char *source, char *target)
+{
+    int fd_source,fd_target,size;
+     
+    char delta_data[ROCK_DEFAULT_BLOCK_SIZE];
+     
+    fd_source = mtk_device_wrap_open(source,O_RDONLY);
+     
+    if (fd_source < 0) {
+        RLOGD("+[UA]: open source  error\n");
+        return 1;
+    }
+
+    fd_target = mtk_device_wrap_open(target,O_RDWR);
+ 
+    if (fd_target < 0) {
+        mtk_device_wrap_close(fd_target);
+        mtk_device_wrap_close(fd_source);
+        RLOGD("+[UA]: open target  error\n");
+        return 1;
+    } 
+    
+    while(( size = mtk_device_wrap_read(fd_source,delta_data,ROCK_DEFAULT_BLOCK_SIZE))>0) {
+           mtk_device_wrap_write(fd_target,delta_data,ROCK_DEFAULT_BLOCK_SIZE);
+    }
+    
+    mtk_device_wrap_close(fd_target);
+    mtk_device_wrap_close(fd_source);
+    return 0;
+}
+
+int delta_copyto_nand(unsigned int start,int size)
+{
+ 
+    char delta_data[NAND_PAGE_SIZE];
+    unsigned int ret = 0;
+    int err;
+
+
+    if (lseek(fd_delta, start, SEEK_SET) < 0) {
+        LYERRLOG("+[UA]: delta_copyto_nand seek err\n");
+        return -1;
+    }
+ 
+     if (mtk_device_wrap_seek(fd_curr, 0, SEEK_SET) < 0) {
+        LYERRLOG("+[UA]: delta_copyto_nand seek err\n");
+        return -1;
+    }
+ 
+ 
+    do {
+        memset(delta_data,0,NAND_PAGE_SIZE);
+        ret = read(fd_delta, delta_data, NAND_PAGE_SIZE);
+
+        if (ret == 0) {
+            break;
+        } else if (ret < 0) {
+            if (errno == EINTR) {
+                continue;
+            }
+            err = -errno;
+
+            return err;
+        }
+  
+        size -= NAND_PAGE_SIZE;
+        mtk_device_wrap_write(fd_curr,delta_data,NAND_PAGE_SIZE);
+        //mtk_device_wrap_write(fd_curr,delta_data,ret);
+
+    } while(size > 0);
+  
+ 
+ return 0;
+ 
+}
+
+
+unsigned char ram_buffer[ROCK_RAM_LEN];
+
+int check(int sys_size)
+{
+    int fd;
+    int i=0;
+    int j=0;
+    int num=i;
+    int n = 0;
+    const uint8_t data[] = { 0x74, 0x77, 0x6f, 0x63, 0x6f, 0x72, 0x65};
+    const char * core_flag="twocore\n";
+    
+    uint8_t buffer[16]; 
+
+    if(sys_size == 0)//for only upgrade oemapp and oemapp2
+    {
+        return 0;
+    }
+    n = strlen(core_flag);
+    lseek(fd_delta,520,SEEK_SET);
+    lseek(fd_delta,sys_size,SEEK_CUR);
+    lseek(fd_delta, -1*n, SEEK_CUR);
+    read(fd_delta, buffer, n);
+    lseek(fd_delta,0,SEEK_SET);//file reset
+    if (memcmp(buffer, core_flag, n) == 0)
+    {
+        return 0;
+    }
+    return -1;
+
+}
+
+int check_cpu(void)
+{
+    int i=0;
+    int ret;
+    char buffer[3][64];
+    FILE *fp;
+    char num;
+    fp = popen("od -x /proc/device-tree/chosen/atag,devinfo","r");
+
+    for(i=0;i<3;i++)
+    {
+        fgets(buffer[i], 64, fp);
+    }
+
+    for(i=0;i<3;i++)
+    {
+        RLOGD("buffer[i] = %s\n",buffer[i]);
+    }
+    RLOGD("%c\n", buffer[2][14]);
+
+    num = buffer[2][14];
+
+
+    RLOGD("num=%c\n", num);
+    if(num == '0' || num == '1')
+    {
+        printf("this is four core\n");
+        return 4;
+    }
+    else if(num == '2' || num == '3')
+    {
+        printf("this is two core\n");
+        return 2;
+    }
+    else
+    {
+        RLOGD("this char is error\n");
+        return -1;
+    }
+    pclose(fp);
+
+    return -1;
+}
+
+
+
+static int rock_update_main(unsigned int rom_base,  unsigned int backup_base, unsigned int backup_len, int read_rom_directly, int first_run, int switch_slot_flag, int 
+reboot_flag, int backup_mode) {
+    int status,err,start,fd;
+    int ret = 0;
+    int i = 0;
+    int retry_cnt = 0;
+    int cpu_flag;
+    IOT_UPDATA_CONTEXT ctx;
+
+    //OTA_STATUS  fota_status;
+
+
+    const hw_module_t* hw_module;
+    unsigned int  slot;
+
+    unsigned int  update_mode = MODE_NORMAL;
+    unsigned int  delta_size;
+    unsigned char full_header[9];
+    
+    char digest_s[SHA_DIGEST_SIZE];
+    char digest_t[SHA_DIGEST_SIZE];
+    char str_sha[40];
+    char cmd_sys[100];
+    int core_num;
+    int sha_size = 0;
+    int is_need_fullupdate = 0;
+    int fd_partition_a,fd_partition_b;
+//xf.li@20230830 add for ab_recover start
+    fd = open(FILE_UPDATE_FLAG,O_RDWR | O_CREAT,0777);
+    if (fd < 0)
+    {
+        RLOGD("+[UA]: can't open file /tmp/update_flag.\n");
+        return -1;
+    }
+    close(fd);
+//xf.li@20230830 add for ab_recover end
+    hw_module = &HAL_MODULE_INFO_SYM;
+
+    if (!hw_module ||
+        strcmp(BOOT_CONTROL_HARDWARE_MODULE_ID, hw_module->id) != 0) {
+        ret = -EINVAL;
+    }
+    if (ret != 0) {
+        RLOGD("+[UA]: Error loading boot_control HAL implementation.\n");
+        return -1;
+    }
+
+    module = (boot_control_module_t*)hw_module;
+    module->init(module);
+
+
+    if (module == NULL) {
+        RLOGD("+[UA]: Error getting bootctrl module.\n");
+        return  -1;
+    }
+
+    lynq_init_wake_lock_func();
+    lynq_fota_grab_artial_wake_lock();
+     /*************    Bootctrl Init  End  *************/
+
+    current_slot = module->getCurrentSlot(module);
+    
+    int is_successful = module->isSlotMarkedSuccessful(module, current_slot);
+  
+    RLOGD("Booting slot = %d, : isSlotMarkedSuccessful= %d\n",current_slot,is_successful);
+
+
+
+    memset(&ctx, 0, sizeof(ctx));
+    ctx.rom_base = 0;
+    ctx.ram_base =(unsigned char *)&ram_buffer[0];
+    ctx.ram_len = ROCK_RAM_LEN;
+    ctx.backup_base = BACKUP_ADDR_FLAG;
+    //ctx.backup_len = ROCK_DEFAULT_BLOCK_SIZE;
+    ctx.backup_len = 0;        
+    ctx.update_nvram = 0;
+    ctx.read_rom_directly = read_rom_directly;
+    //ctx.first_run = first_run;
+    ctx.first_run = 1;
+
+    if(0 != init_dev_fd())
+    {
+        RLOGD("+[UA]: get fota addr error\n");
+        system("echo fota-interface >/sys/power/wake_unlock");
+        return E_ROCK_FOTA_ADDR;
+    }
+
+
+    memset(&fota_status,0,sizeof(fota_status));
+    RLOGD("+[UA]: up_info.ota_run = %d\n",up_info.ota_run);
+
+#if 0    
+    if ((up_info.ota_run>PATCH_BL33)||(up_info.ota_run<PATCH_SYSTEM))
+    {
+        up_info.ota_run = 0;
+    }    
+#endif 
+
+    up_info.ota_run = 0;
+    if(backup_mode == 1)
+    {
+        if(current_slot == 0)
+        {
+            update_mode = MODE_A2B;
+        }else
+        {
+            update_mode = MODE_B2A;
+        }
+    }
+    else
+    {
+        update_mode = MODE_NORMAL;
+    }
+    
+    RLOGD("+[UA]: up_info.fota_flag = %s\n",up_info.fota_flag);
+    RLOGD("+[UA]: update_mode = %d\n",update_mode);
+    
+    //memset(&da_head, 0, sizeof(da_head));
+
+    //read(fd_delta, (unsigned char*)&da_head, sizeof(da_head));
+
+    memset(&delta_head, 0, sizeof(delta_head));
+    read(fd_delta, (char *)&delta_head[0], sizeof(delta_head));
+
+
+    delta_size = 0;
+    sha_size = 0;
+    for (i = 0;i<REAL_OTA_ROLE; i++)    {
+        if (delta_head[i] > 0) {
+            fota_status.update_status[i].need_update = 1;
+            delta_size+=delta_head[i];
+            
+        }
+        RLOGD("+[UA]: %s,delta size = %d\n",partition_filename[i],delta_head[i]);    
+    }
+    
+    
+    for(i = MAX_OTA_ROLE/2;i<(MAX_OTA_ROLE/2+REAL_OTA_ROLE); i++) {
+        if (delta_head[i] > 0) {
+            fota_status.update_status[i].need_update = 1;
+            sha_size+=delta_head[i];
+        }
+        RLOGD("+[UA]: %s,full size = %d, i=%d\n",partition_filename[i-MAX_OTA_ROLE/2],delta_head[i], i);
+    }
+
+    core_num= check_cpu();
+    if(core_num == 2)
+    {
+        cpu_flag = check(delta_head[64]);
+        if(cpu_flag < 0)
+        {
+            RLOGD("cpu core is error\n");
+            system("echo fota-interface >/sys/power/wake_unlock");
+            return -1;
+        }
+        else
+        {
+            RLOGD("cpu core match\n");
+        }
+    }
+    else if(core_num == 4)
+    {
+        RLOGD("the cpu core is four!!!\n");
+    }
+    else
+    {
+        RLOGD("read the cpu core fail");
+        system("echo fota-interface >/sys/power/wake_unlock");
+        return -1;
+    }
+
+    fota_status.switch_slot = WAIT;
+    save_fota_status();
+
+    //delta_size = da_head.sys + da_head.boot + da_head.tee + da_head.md1img + da_head.md1dsp + da_head.vbmeta + da_head.oemapp + da_head.oemapp2 + da_head.medmcu+da_head.bl33;
+    
+    //sha_size = da_head.full_sys + da_head.full_boot + da_head.full_tee + da_head.full_md1img + da_head.full_md1dsp + da_head.full_vbmeta + da_head.full_oemapp + da_head.full_oemapp2 + da_head.full_medmcu+da_head.full_bl33
+
+
+
+
+    is_need_fullupdate = 0;
+    if(sha_size>0) {
+        is_need_fullupdate = 1;
+        sha_size+=8;
+    }
+
+    sha_size+=delta_size;
+    
+    memset(digest_s,0,SHA_DIGEST_SIZE);
+    memset(digest_t,0,SHA_DIGEST_SIZE);
+    memset(str_sha,0,40);
+    
+    lseek(fd_delta, sha_size + sizeof(delta_head), SEEK_SET);
+    read(fd_delta, digest_s, SHA_DIGEST_SIZE);
+    convert_hex(digest_s,str_sha);
+    RLOGD("+[UA]: delta save sha = %s\n",str_sha);
+    
+    ROCK_SHA_FILE_COMMON(fd_delta,sizeof(delta_head),sha_size,digest_t);
+    memset(str_sha,0,40);
+    convert_hex(digest_t,str_sha);
+    RLOGD("+[UA]: delta calc sha = %s\n",str_sha);
+    
+    if(memcmp(digest_s,digest_t,SHA_DIGEST_SIZE)==0) {
+    
+        RLOGD("sha verify pass\n");
+    
+    }else{
+        RLOGD("delta sha verify fial!\n");
+        
+        system("echo fota-interface >/sys/power/wake_unlock");
+        return -1;
+    
+    }
+    
+    memset(digest_s,0,SHA_DIGEST_SIZE);
+    memset(digest_t,0,SHA_DIGEST_SIZE);
+    
+    
+    //delta_offset = DELTA_HEARD_SIZE;
+    delta_offset = sizeof(delta_head);
+    
+    for(i = 0;i<REAL_OTA_ROLE; i++){    //diff
+        //now_patch = i+1;
+        if (i>0) {
+            delta_offset+=delta_head[i-1];
+        }
+        if((delta_head[i]>0) && (up_info.ota_run<=(i+1))){ 
+                        now_patch = i + 1;
+#if 0
+            if (up_info.ota_run == now_patch) //升级ps断电?
+            {
+                ctx.first_run = 0;
+
+            }else{
+                ctx.first_run = 1;
+            }
+#endif             
+            ctx.first_run = 1;  //always
+            RLOGD("+[UA]: PATCH %s,ctx.first_run = %d\n", partition_filename[i] ,ctx.first_run);
+            up_info.ota_run = now_patch;
+        
+            if(current_slot==SLOT_B) {
+                sprintf(cmd_sys,"flash_eraseall %s",partition_filename_a[i]);
+            }else{
+                sprintf(cmd_sys,"flash_eraseall %s",partition_filename_b[i]);
+            }
+            system(cmd_sys);
+
+
+            fd_partition_a = mtk_device_wrap_open(partition_filename_a[i],O_RDWR);
+            if (fd_partition_a < 0) {
+                err = errno;
+                RLOGD("+[UA]: Error opening id_a[%d] file: %s\n",i,strerror(errno));
+                system("echo fota-interface >/sys/power/wake_unlock");
+                return -err;
+            }
+
+            fd_partition_b = mtk_device_wrap_open(partition_filename_b[i],O_RDWR);
+            if (fd_partition_b < 0) {
+                err = errno;
+                RLOGD("+[UA]: Error opening id_b[%d] file: %s\n",i,strerror(errno));
+                system("echo fota-interface >/sys/power/wake_unlock");
+                return -err;
+            }            
+            if(current_slot==SLOT_B){
+                fd_read  = fd_partition_b;
+                fd_write = fd_partition_a;    
+            } else {
+                fd_read  = fd_partition_a;
+                fd_write = fd_partition_b;
+            }
+
+            fota_status.ota_run = i;
+            fota_status.update_status[i].check_delta = WAIT;
+            fota_status.update_status[i].check_rom = WAIT;
+            fota_status.update_status[i].update_result= WAIT;
+
+            save_fota_status();
+        
+        
+            up_info.ota_run = i+1;
+            save_fota_info();
+
+            RLOGD("+[UA]: Start upgrading %s.\n",partition_filename[i]);
+            status = iot_patch(&ctx);
+            RLOGD("+[UA]: %s upgrade result:%d\n",partition_filename[i],status);
+        
+            //up_info.ota_run = 0;
+        
+            //fota_status.ota_run = 0;
+            fota_status.update_status[i].update_result= status; 
+            fota_status.update_result= status;
+
+            if((status == 0)||(status ==1))
+            {
+
+                fota_status.update_status[i].check_delta = PASS;
+                fota_status.update_status[i].check_rom = PASS;
+                RLOGD("+[UA]: %s upgrade success!!!\n",partition_filename[i]);
+               
+            }else if(status == E_ROCK_INVALID_DELTA) {
+                fota_status.update_status[i].check_delta = ERROR;
+                fota_status.update_status[i].check_rom = WAIT;
+            }else if((status == E_ROCK_DELTA_MISMATCH)||(status == E_ROCK_DELTA_CHUNK_MISMATCH)) {
+                fota_status.update_status[i].check_delta = PASS;
+                fota_status.update_status[i].check_rom = ERROR;
+
+            }else{
+        
+            //fota_status.update_status[PATCH_SYSTEM -1].check_delta = PASS;
+            //fota_status.update_status[PATCH_SYSTEM -1].check_rom = WAIT;
+            }
+
+            save_fota_status();
+
+        
+            if ((status != 0) &&(status != 1))
+            {
+
+                up_info.fota_flag[0] = 'e';
+                up_info.fota_flag[1] = 'n';
+                up_info.fota_flag[2] = 'd';
+                up_info.update_result = status;
+                up_info.ota_run = 0;
+                save_fota_info();
+            
+                mtk_device_wrap_close(fd_read);
+                mtk_device_wrap_close(fd_write);
+    
+                system("echo fota-interface >/sys/power/wake_unlock");
+                return status;
+            }
+                mtk_device_wrap_close(fd_read);
+                mtk_device_wrap_close(fd_write);        
+        
+        }
+    
+    }
+    
+    
+    
+    if (is_need_fullupdate == 1)
+    {
+
+        now_patch = 0;
+        up_info.ota_run = 0;
+        
+        memset(&fota_status,0,sizeof(fota_status));
+        fota_status.switch_slot = WAIT;
+        save_fota_status();
+        
+        if (lseek(fd_delta, DELTA_HEARD_SIZE + delta_size, SEEK_SET) < 0) {
+            err = errno;
+            RLOGD("+[UA]: mtk_device_wrap_seek df_delta err\n");
+            system("echo fota-interface >/sys/power/wake_unlock");
+            return -1;
+        }
+        
+        read(fd_delta, full_header, DELTA_FULL_HEARD_SIZE);
+        
+
+        if (memcmp(full_header, "full-ota", DELTA_FULL_HEARD_SIZE) != 0) {
+            RLOGD("+[UA]: invalid full delta header\r\n");
+            up_info.fota_flag[0] = 'e';
+            up_info.fota_flag[1] = 'n';
+            up_info.fota_flag[2] = 'd';
+            up_info.update_result = -1;
+            up_info.ota_run = 0;
+            save_fota_info();
+
+            //for (i = FULL_SYSTEM;i<=FULL_BL33;i++){
+            
+            for (i = MAX_OTA_ROLE/2;i<(MAX_OTA_ROLE/2+REAL_OTA_ROLE);i++){
+                  if (fota_status.update_status[i].need_update ==1) {
+                    fota_status.ota_run = i;
+                    fota_status.update_status[i].check_delta = ERROR;
+                    fota_status.update_status[i].check_rom= WAIT;
+                    fota_status.update_status[i].update_result= ERROR;
+                }
+            }
+            fota_status.update_result = ERROR;
+            save_fota_status();
+            system("echo fota-interface >/sys/power/wake_unlock");
+            return -1;
+        }
+    }
+    
+    
+    
+    delta_offset = DELTA_HEARD_SIZE + delta_size + DELTA_FULL_HEARD_SIZE;
+    
+    for(i = MAX_OTA_ROLE/2;i<(MAX_OTA_ROLE/2+REAL_OTA_ROLE);i++) {
+    
+        if (i>MAX_OTA_ROLE/2) {
+            delta_offset+=delta_head[i-1];
+        }    
+        if(delta_head[i]>0) {
+
+            if(current_slot==SLOT_B) {
+                sprintf(cmd_sys,"flash_eraseall %s",partition_filename_a[i-MAX_OTA_ROLE/2]);
+            } else {
+                sprintf(cmd_sys,"flash_eraseall %s",partition_filename_b[i-MAX_OTA_ROLE/2]);
+            }
+            system(cmd_sys);
+        
+            if(current_slot==SLOT_B) {
+                fd_partition_a = mtk_device_wrap_open(partition_filename_a[i-MAX_OTA_ROLE/2],O_RDWR);
+                if (fd_partition_a < 0) {
+                    err = errno;
+                    RLOGD("+[UA]: Error opening full id_a[%d] file: %s\n",i,strerror(errno));
+                    system("echo fota-interface >/sys/power/wake_unlock");
+                    return -err;
+                }
+                fd_curr = fd_partition_a;
+            }else{
+                fd_partition_b = mtk_device_wrap_open(partition_filename_b[i-MAX_OTA_ROLE/2],O_RDWR);
+                if (fd_partition_b < 0) {
+                    err = errno;
+                    RLOGD("+[UA]: Error opening full_id_b[%d] file: %s\n",i,strerror(errno));
+                    system("echo fota-interface >/sys/power/wake_unlock");
+                    return -err;
+                }
+                fd_curr = fd_partition_b;            
+            }
+            fota_status.ota_run = i+1;
+            save_fota_status();
+            up_info.ota_run = i+1;
+            save_fota_info();
+            retry_cnt = 0;
+            RLOGD("+[UA]: Start upgrading %s full.\n",partition_filename[i-MAX_OTA_ROLE/2]);
+            do{
+                status = delta_copyto_nand(delta_offset,delta_head[i]);
+
+                ROCK_SHA_FILE_COMMON(fd_delta,delta_offset,delta_head[i],digest_s);
+                ROCK_SHA_FILE(fd_curr,0,delta_head[i],digest_t);
+                retry_cnt++;
+            }while((strncmp(digest_s,digest_t,SHA_DIGEST_SIZE)!=0)&&(retry_cnt <= 3));
+        
+            mtk_device_wrap_close(fd_curr);
+        
+            RLOGD("+[UA]: %s full retry_cnt = %d\n",partition_filename[i-MAX_OTA_ROLE/2],retry_cnt);
+        
+            if (retry_cnt>3) {
+                if (status == 0) {
+                    status = retry_cnt;
+                }
+                if(current_slot==SLOT_B) {
+                    nand_copyto_nand(partition_filename_b[i-MAX_OTA_ROLE/2],partition_filename_a[i-MAX_OTA_ROLE/2]);
+                }
+                else{
+                    nand_copyto_nand(partition_filename_a[i-MAX_OTA_ROLE/2],partition_filename_b[i-MAX_OTA_ROLE/2]);
+                }
+            }
+        
+            RLOGD("+[UA]: %s full upgrade result:%d\n",partition_filename[i-MAX_OTA_ROLE/2],status);
+
+            fota_status.update_result = status;
+            fota_status.update_status[i].update_result = status;
+            save_fota_status();
+
+            if (status != 0)
+            {
+
+                up_info.fota_flag[0] = 'e';
+                up_info.fota_flag[1] = 'n';
+                up_info.fota_flag[2] = 'd';
+                up_info.update_result = status;
+                up_info.ota_run = 0;
+                save_fota_info();
+                system("echo fota-interface >/sys/power/wake_unlock");
+                return status;
+            }
+    
+        }            
+    
+    }
+    
+    
+
+
+    if(update_mode != MODE_NORMAL){ //need backup
+        if(current_slot == SLOT_A) {
+            up_info.fota_flag[0] = 'B';
+            up_info.fota_flag[1] = '-';
+            up_info.fota_flag[2] = 'A';
+
+        }else{
+            up_info.fota_flag[0] = 'A';
+            up_info.fota_flag[1] = '-';
+            up_info.fota_flag[2] = 'B';
+
+        }
+
+    }else{
+        up_info.fota_flag[0] = 'e';
+        up_info.fota_flag[1] = 'n';
+        up_info.fota_flag[2] = 'd';
+
+    }
+
+
+    up_info.update_result = status;
+    up_info.ota_run = 0;
+    save_fota_info();
+
+    //close_dev_fd(fd_curr);
+    
+
+    
+    close(fd_update_status);
+    sync();
+    
+
+    slot = (current_slot == 0) ? 1 : 0;
+    
+    RLOGD("+[UA]: slot SLOT = %d\n",slot);
+    
+        if(switch_slot_flag==1)
+        {
+            module->setActiveBootSlot(module,slot);
+            RLOGD("+[UA]: upgrade is success!!!!\n");
+        }
+
+    fota_status.ota_run = 0;
+    fota_status.switch_slot = PASS;
+    fota_status.update_result = status;
+    save_fota_status();
+    
+    sleep(5);
+    sync();
+    sleep(5);
+
+    system("echo fota-interface >/sys/power/wake_unlock");
+
+    if(reboot_flag==1){
+    reboot_device();
+    }
+
+    return status;
+}
+
+
+
+static void rock_fail_handler()
+{
+    int ret = 0;
+    RLOGD("rock_fail_handler start\n");
+    //ret = rock_update_main(0, 0, 0, 0, 1, 1);
+    if(ret)
+    {
+        RLOGD("fota update fail again!\n");
+    }
+}
+
+/* main entrpoint */
+int lynq_rock_main(int first_run)
+{
+
+    int ret = 0;
+    
+#if 0
+    
+    printf("-********copy delta ***-\n");
+    test_write_delta("/data/delta",DEV_DELTA);
+
+#endif 
+    
+        ret = rock_update_main(0, 0, 0, 0, first_run, 1, 1, 1);
+        RLOGD("rock_update_main ret = %d\n", ret);
+        if(ret)
+        {
+            RLOGD("fota update fail!\n");
+        }
+        return ret;
+}
+
+#endif
+
+//xf.li@20230403 add for verfy start
+int lynq_file_md5_verfy(char *source, unsigned char *source_md5, char *target)
+{
+    int fd, size, ret, is_system = 0;
+    int need_copy = 1;
+    int system_mtd_num = 0;
+    int system_ubi_num = BACKUP_UBI_NUM;//max ubi number
+    char cmd_ubi_attach[128] = {0};
+    char cmd_ubi_detach[128] = {0};
+    char md5_target_file_patch[128] = {0};
+
+    RLOGD("in lynq_file_md5_verfy, source:%s, target:%s\n", source, target);
+    if(strcmp(source, DEV_SYSTEM_A) == 0 || strcmp(source, DEV_SYSTEM_B) == 0)
+    {
+        RLOGD("verfy system.img\n");
+        is_system = 1;
+        if(strcmp(source, DEV_SYSTEM_A) == 0)
+        {
+            system_mtd_num = MTD_SYSTEM_B;
+        }
+        else if(strcmp(source, DEV_SYSTEM_B) == 0)
+        {
+            system_mtd_num = MTD_SYSTEM_A;
+        }
+        else
+        {
+            RLOGD("source:%s, target:%s\n", source, target);
+        }
+        for( ; system_ubi_num >= 10; system_ubi_num--)//try from ubi31 to ubi10
+        {
+            sprintf(md5_target_file_patch, "/dev/ubi%d", system_ubi_num);
+            RLOGD("ubi_num = %d\n", system_ubi_num);
+            if((access(md5_target_file_patch, F_OK)) == -1)   
+            {
+                RLOGD("no the ubi file, can use this ubi.\n");
+                break;
+            }
+        }
+        if(system_ubi_num < 10)
+        {
+            RLOGE("no the ubi file, can use this ubi.\n");
+            return -1;
+        }
+    }
+    //=========================caculate md5sum start=====================
+    if(is_system == 1)
+    {
+        RLOGD("in system caculate\n");
+        RLOGD("system_mtd_num = %d, ubi_num = %d\n", system_mtd_num, system_ubi_num);
+        sprintf(cmd_ubi_attach, "ubiattach /dev/ubi_ctrl -m %d -d %d", system_mtd_num, system_ubi_num);
+        RLOGD("cmd_ubi_attach:%s", cmd_ubi_attach);
+        ret = system(cmd_ubi_attach);
+        if(ret != 0)
+        {
+            RLOGE("ubi attach error!!!\n");
+            return need_copy;
+        }
+        RLOGD("attach over\n");
+        //attach success
+        sprintf(md5_target_file_patch, "/dev/ubi%d_0", system_ubi_num);
+        RLOGD("md5_target_file_patch:%s", md5_target_file_patch);
+        //make sure the ubi volume is exist
+        if((access(md5_target_file_patch, F_OK)) == -1)   
+        {   
+            RLOGD("no the ubi file.\n");
+            sprintf(cmd_ubi_detach, "ubidetach -m %d", system_mtd_num);
+            ret = system(cmd_ubi_detach);
+            if(ret != 0)
+            {
+                RLOGD("ubi dettach error!!!\n");
+            }
+
+            return need_copy;
+        }
+        //calculate md5sum
+        //ret = lynq_md5_two_file_verfy("/dev/ubi0_0", md5_target_file_patch);
+        ret = lynq_md5_file_verfy_ab(md5_target_file_patch, source_md5);
+        if(ret == MD5_VERFY_ERROR)
+        {
+            //ubidetach
+            sprintf(cmd_ubi_detach, "ubidetach -m %d", system_mtd_num);
+            ret = system(cmd_ubi_detach);
+            if(ret != 0)
+            {
+                RLOGD("ubi dettach error!!!\n");
+            }
+            return need_copy;
+        }
+        if(ret != 0)
+        {
+            //ubidetach
+            sprintf(cmd_ubi_detach, "ubidetach -m %d", system_mtd_num);
+            ret = system(cmd_ubi_detach);
+            if(ret != 0)
+            {
+                RLOGD("ubi dettach error!!!\n");
+            }
+            RLOGD("calculate system error!!!\n");
+            return -1;
+        }
+
+        RLOGD("verfy system.img over\n");
+    }
+    else
+    {
+        RLOGD("verfy else img\n");
+        //calculate md5sum
+        //ret = lynq_md5_two_file_verfy(source, target);
+        ret = lynq_md5_file_verfy_ab(target, source_md5);
+        if(ret == MD5_VERFY_ERROR)
+        {
+            return need_copy;
+        }
+        if(ret != 0)
+        {
+            RLOGD("calculate %s and %s error!!!\n", source, target);
+            return -1;
+        }
+    }
+    //====================caculate md5sum end======================
+    return 0;
+}
+//xf.li@20230403 add for verfy end
+
+
+//xf.li@20230401 add for ab rollback start
+
+int backup_nand_copyto_nand(char *source, char *target)
+{
+    int fd_source, fd_target, size;
+    int ret = -1;
+    int sleep_count = 0;
+    char cmd_erase_target[128] = {0};
+    int retry = MD5_RETRY_TIME;
+	unsigned char source_md5[MD5_READ_BUFFER_LEN] = {0};
+	char delta_data[ROCK_DEFAULT_BLOCK_SIZE];
+    //caclculate source md5 start
+    if(strcmp(source, DEV_SYSTEM_A) == 0 || strcmp(source, DEV_SYSTEM_B) == 0)
+    {
+        RLOGD("backup_nand_copyto_nand: verfy system.img\n");
+        
+        ret = calculate_file_md5_value("/dev/ubi0_0", source_md5);
+        if(ret < 0)
+        {
+            RLOGD("[+MD5]:calculate source md5 value ERROE!!!\n");
+            return ret;
+        }
+        RLOGD("source_md5 is %s\n", source_md5);   
+    }
+    else
+    {
+        ret = calculate_file_md5_value(source, source_md5);
+        if(ret < 0)
+        {
+            RLOGD("[+MD5]:calculate source md5 value ERROE!!!\n");
+            return ret;
+        }
+        RLOGD("source_md5 is %s\n", source_md5);
+    }
+    //caclculate source md5 end
+    //ret = lynq_file_md5_verfy(source, target);//verfy md5 value
+    ret = lynq_file_md5_verfy(source, source_md5, target);//verfy md5 value
+    RLOGD("+[UA]: md5_file_verfy :ret=%d\n", ret);
+    if(ret == 0)
+    {
+        RLOGD("+[UA]: nand_copyto_nand don't neet copy\n");
+    }
+    for(; ret > 0 && retry > 0; retry--)
+    {   
+        //erase nand-target start
+        if(fota_interrupt == FOTA_FIRST && (access(FILE_UPDATE_FLAG, F_OK)) == 0)
+        {
+            RLOGD("+[UA]: fota runing\n");
+            return -1;
+        }
+        acquire_wake_lock(PARTIAL_WAKE_LOCK, "ab_recover");//lock
+        RLOGD("+[UA]: ready to flash_erase\n");
+        sprintf(cmd_erase_target, "flash_erase %s 0 0", target);
+        ret = system(cmd_erase_target);
+        release_wake_lock("ab_recover");//unlock
+        if(ret != 0)
+        {
+            RLOGD("+[UA]: erase %s fail\n", target);
+            return -1;
+        }
+        sleep(1);//sleep 1s
+
+        //erase nand-target end
+        RLOGD("+[UA]: ready to copy\n");
+        fd_source = mtk_device_wrap_open(source, O_RDONLY);
+        if (fd_source < 0) {
+            RLOGD("+[UA]: open source error\n");
+            return -1;
+        }
+
+        fd_target = mtk_device_wrap_open(target, O_RDWR);
+        if (fd_target < 0) {
+            RLOGD("+[UA]: open target  error\n");
+            return -1;
+        } 
+        ret = 0;//init ret
+        acquire_wake_lock(PARTIAL_WAKE_LOCK, "ab_recover");//lock
+        while(( size = mtk_device_wrap_read(fd_source,delta_data,ROCK_DEFAULT_BLOCK_SIZE))>0)
+        {
+            if(fota_interrupt == FOTA_FIRST && (access(FILE_UPDATE_FLAG, F_OK)) == 0)
+            {
+                RLOGD("+[UA]: fota runing\n");
+                ret = -1;
+                break;
+            }
+            usleep(40000);//sleep 40ms
+            mtk_device_wrap_write(fd_target,delta_data,ROCK_DEFAULT_BLOCK_SIZE);
+            usleep(60000);//sleep 60ms
+            sleep_count++;
+            if(sleep_count >= 20)
+            {
+                //unlock
+                release_wake_lock("ab_recover");
+                sleep(1);//sleep 1s
+                //lock
+                acquire_wake_lock(PARTIAL_WAKE_LOCK, "ab_recover");
+                sleep_count = 0;
+                RLOGD("+[UA]: try sleep one time");
+            }
+        }
+        release_wake_lock("ab_recover");//unlock
+        RLOGD("+[UA]: copy end\n");
+        mtk_device_wrap_close(fd_target);
+	    mtk_device_wrap_close(fd_source);
+        if(ret < 0)
+        {
+            RLOGD("+[UA]: ret < 0\n");
+            return -1;
+        }
+        RLOGD("+[UA]: ready to md5_verfy\n");
+        //ret = lynq_file_md5_verfy(source, target);//verfy md5 value
+        ret = lynq_file_md5_verfy(source, source_md5, target);//verfy md5 value
+        RLOGD("+[UA]: md5_file_verfy :ret=%d\n", ret);
+        if(ret == 0)
+        {
+            RLOGD("+[UA]: nand_copyto_nand copy success\n");
+            break;
+        }
+    }
+    if(ret != 0)
+    {
+        RLOGD("+[UA]: md5_file_verfy FAIL!!!\n");
+    }
+	return ret;
+}
+//xf.li@20230401 add for ab rollback end
+
+//xf.li@20230822 add for ab rollback start
+
+int lynq_backup_main()
+{
+    const hw_module_t* hw_module;
+    hw_module = &HAL_MODULE_INFO_SYM;
+    int is_successful;
+    int ret = 0;
+    if (!hw_module || strcmp(BOOT_CONTROL_HARDWARE_MODULE_ID, hw_module->id) != 0) 
+    {
+        ret = -1;
+    }
+    RLOGD("ret = %d\n", ret);
+    if (ret != 0)
+    {
+        RLOGD("+[UA]: Error loading boot_control HAL implementation.\n");
+        return -1;
+    }
+    module = (boot_control_module_t*)hw_module;
+    module->init(module);
+    if (module == NULL) 
+    {
+        RLOGD("+[UA]: Error getting bootctrl module.\n");
+        return  -1;
+    }
+    lynq_init_wake_lock_func();
+    current_slot = module->getCurrentSlot(module);
+    is_successful = module->isSlotMarkedSuccessful(module, current_slot);
+    RLOGD("+[UA]: Booting slot = %d, : isSlotMarkedSuccessful= %d\n",current_slot,is_successful);
+    fota_interrupt = RECOVER_FIRST;
+    if(current_slot==SLOT_B)
+    {
+        ret = backup_nand_copyto_nand(DEV_SPM_B,DEV_SPM_A);
+        if(ret != 0)
+        {
+            RLOGD("+[UA]: backup spm_a fail\n");
+            return 1;
+        }
+        fota_interrupt = FOTA_FIRST;
+        ret = backup_nand_copyto_nand(DEV_SYSTEM_B,DEV_SYSTEM_A);
+        if(ret != 0)
+        {
+            RLOGD("+[UA]: backup system_a fail\n");
+            return 1;
+        }
+        ret = backup_nand_copyto_nand(DEV_BOOT_B,DEV_BOOT_A);
+        if(ret != 0)
+        {
+            RLOGD("+[UA]: backup boot_a fail\n");
+            return 1;
+        }
+        ret = backup_nand_copyto_nand(DEV_TEE_B,DEV_TEE_A);
+        if(ret != 0)
+        {
+            RLOGD("+[UA]: backup tee_a fail\n");
+            return 1;
+        }
+        ret = backup_nand_copyto_nand(DEV_MD1IMG_B,DEV_MD1IMG_A);
+        if(ret != 0)
+        {
+            RLOGD("+[UA]: backup md1img_a fail\n");
+            return 1;
+        }
+        ret = backup_nand_copyto_nand(DEV_VBMETA_B,DEV_VBMETA_A);
+        if(ret != 0)
+        {
+            RLOGD("+[UA]: backup vbmeta_a fail\n");
+            return 1;
+        }
+        ret = backup_nand_copyto_nand(DEV_MEDMCU_B,DEV_MEDMCU_A);
+        if(ret != 0)
+        {
+            RLOGD("+[UA]: backup medmcu_a fail\n");
+            return 1;
+        }
+        ret = backup_nand_copyto_nand(DEV_BL2_B,DEV_BL2_A);
+        if(ret != 0)
+        {
+            RLOGD("+[UA]: backup bl2_a fail\n");
+            return 1;
+        }
+        ret = backup_nand_copyto_nand(DEV_BL33_B,DEV_BL33_A);
+        if(ret != 0)
+        {
+            RLOGD("+[UA]: backup bl33_a fail\n");
+            return 1;
+        }
+        ret = backup_nand_copyto_nand(DEV_OEMAPP_B,DEV_OEMAPP_A);
+        if(ret != 0)
+        {
+            RLOGD("+[UA]: backup oemapp_a fail\n");
+            return 1;
+        }
+        ret = backup_nand_copyto_nand(DEV_OEMAPP2_B,DEV_OEMAPP2_A);
+        if(ret != 0)
+        {
+            RLOGD("+[UA]: backup oemapp2_a fail\n");
+            return 1;
+        }
+    }
+    else
+    {
+        ret = backup_nand_copyto_nand(DEV_SPM_A,DEV_SPM_B);
+        if(ret != 0)
+        {
+            RLOGD("+[UA]: backup spm_a fail\n");
+            return 1;
+        }
+        fota_interrupt = FOTA_FIRST;
+        ret = backup_nand_copyto_nand(DEV_SYSTEM_A,DEV_SYSTEM_B);
+        if(ret != 0)
+        {
+            RLOGD("+[UA]: backup system_b fail\n");
+            return 1;
+        }
+        ret = backup_nand_copyto_nand(DEV_BOOT_A,DEV_BOOT_B);
+        if(ret != 0)
+        {
+            RLOGD("+[UA]: backup boot_b fail\n");
+            return 1;
+        }
+        
+        ret = backup_nand_copyto_nand(DEV_TEE_A,DEV_TEE_B);
+        if(ret != 0)
+        {
+            RLOGD("+[UA]: backup tee_b fail\n");
+            return 1;
+        }
+        ret = backup_nand_copyto_nand(DEV_MD1IMG_A,DEV_MD1IMG_B);
+        if(ret != 0)
+        {
+            RLOGD("+[UA]: backup md1img_b fail\n");
+            return 1;
+        }
+        ret = backup_nand_copyto_nand(DEV_VBMETA_A,DEV_VBMETA_B);
+        if(ret != 0)
+        {
+            RLOGD("+[UA]: backup vbmeta_b fail\n");
+            return 1;
+        }
+        ret = backup_nand_copyto_nand(DEV_MEDMCU_A,DEV_MEDMCU_B);
+        if(ret != 0)
+        {
+            RLOGD("+[UA]: backup medmcu_b fail\n");
+            return 1;
+        }
+        ret = backup_nand_copyto_nand(DEV_BL2_A,DEV_BL2_B);
+        if(ret != 0)
+        {
+            RLOGD("+[UA]: backup bl2_a fail\n");
+            return 1;
+        }
+        ret = backup_nand_copyto_nand(DEV_BL33_A,DEV_BL33_B);
+        if(ret != 0)
+        {
+            RLOGD("+[UA]: backup bl33_a fail\n");
+            return 1;
+        }
+        ret = backup_nand_copyto_nand(DEV_OEMAPP_A,DEV_OEMAPP_B);
+        if(ret != 0)
+        {
+            RLOGD("+[UA]: backup oemapp_b fail\n");
+            return 1;
+        }
+        ret = backup_nand_copyto_nand(DEV_OEMAPP2_A,DEV_OEMAPP2_B);
+        if(ret != 0)
+        {
+            RLOGD("+[UA]: backup oemapp2_b fail\n");
+            return 1;
+        }
+    }
+    RLOGD("+[UA]: lynq_backup_main success \n");
+    return 0;
+}
+//xf.li@20230822 add for ab rollback end
+
+
+int lynq_check_oemapp(char* name)
+{
+    FILE *fp;
+    char check_result[64];
+    if(strcmp(name, "oemapp") == 0)
+    {
+        RLOGD("lynq_check_oemapp oemapp");
+        if(system("df -lh|grep oemapp |grep -v oemapp2") != 0)
+        {
+            return 0;
+        }
+        else
+        {
+            return 1;
+        }
+    }
+    else if(strcmp(name, "oemapp2") == 0)
+    {
+        RLOGD("lynq_check_oemapp oemapp2");
+        if(system("df -lh|grep oemapp2") != 0)
+        {
+            return 0;
+        }
+        else
+        {
+            return 1;
+        }
+    }
+}
+
+//lt add @2021.9.23 for  deal with power down \ backup or upgrade.
+int lynq_fota_func(void) 
+{
+    int fd;
+    int first_run = 1;
+    int ret = 0;
+    UPDATE_INFO lynq_up_info;
+    //xf.li@20230822 add for ab backup start
+    unsigned int current_slot, other_slot;
+    int is_other_slot_bootable;
+    const hw_module_t* hw_module;
+    //xf.li@20230822 add for ab backup end
+    RLOGD("[+UP]: ******lynq_fota_func start******\n");
+    //xf.li@20230822 add for ab backup start
+    //----------get current slot and whether other slot  is bootable
+    hw_module = &HAL_MODULE_INFO_SYM;
+    if (!hw_module ||
+        strcmp(BOOT_CONTROL_HARDWARE_MODULE_ID, hw_module->id) != 0) {
+        ret = -EINVAL;
+    }
+    if (ret != 0) {
+        RLOGD("+[UA]: Error loading boot_control HAL implementation.\n");
+        return -1;
+    }
+    module = (boot_control_module_t*)hw_module;
+    module->init(module);
+    if (module == NULL) {
+        RLOGD("+[UA]: Error getting bootctrl module.\n");
+        return  -1;
+    }
+    current_slot = module->getCurrentSlot(module);
+    other_slot = (current_slot == 0) ? 1 : 0;
+    is_other_slot_bootable = module->isSlotBootable(module, other_slot);
+    //-----------end
+    RLOGD("current slot:%u, is_other_slot_bootable : %d\n",current_slot, is_other_slot_bootable);
+    //xf.li@20230822 add for ab backup end
+
+    memset(&lynq_up_info, 0, sizeof(lynq_up_info));
+    fd = open(FILE_UPDATE_STATE,O_RDWR | O_CREAT,0777);
+    if (fd < 0)
+    {
+        return -1;
+    }
+    read(fd,(unsigned char *)&lynq_up_info,sizeof(lynq_up_info));
+    close(fd);
+
+    RLOGD("[+UP]: lynq_up_info.ota_run=%d\n",lynq_up_info.ota_run);
+    if((lynq_check_oemapp("oemapp") == 0) || (lynq_check_oemapp("oemapp2") == 0))
+    {
+        RLOGD("ENTER LYNQ_CHECK_OEMAPP\n");
+        system("echo mode 001 0 > /sys/devices/platform/10005000.pinctrl/mt_gpio");
+        system("echo dir 001 1 > /sys/devices/platform/10005000.pinctrl/mt_gpio");
+        system("echo out 001 1 > /sys/devices/platform/10005000.pinctrl/mt_gpio");
+        RLOGD("need setUnbootable.\n");
+        module->setSlotAsUnbootable(module,current_slot);
+        RLOGD("+[UA]: setSlotAsUnbootable!!!!\n");
+        sync();
+        if(((lynq_up_info.fota_flag[0]=='A')&&(lynq_up_info.fota_flag[1]=='-')&&(lynq_up_info.fota_flag[2]=='B'))||
+        ((lynq_up_info.fota_flag[0]=='B')&&(lynq_up_info.fota_flag[1]=='-')&&(lynq_up_info.fota_flag[2]=='A')))
+        {
+            RLOGD("mark oemapp mount fail\n");
+            lynq_set_value(FOTA_UCI_MODULE,FOTA_UCI_STATE, "1");
+        }
+        sleep(5);
+        reboot_device();
+    }
+
+
+    if(lynq_up_info.ota_run != 0)
+    { 
+        //Power off, call UA
+        RLOGD("[+UP]: ***Power off, call UA***\n");
+        ret = rock_update_main(0, 0, 0, 0, first_run, 1, 0, 1);
+        RLOGD("rock_update_main ret = %d\n", ret);
+        if(ret) 
+        {
+            RLOGD("fota update fail!\n");
+        }
+    }
+
+    if(((lynq_up_info.fota_flag[0]=='A')&&(lynq_up_info.fota_flag[1]=='-')&&(lynq_up_info.fota_flag[2]=='B'))||
+        ((lynq_up_info.fota_flag[0]=='B')&&(lynq_up_info.fota_flag[1]=='-')&&(lynq_up_info.fota_flag[2]=='A')))
+    {
+        //Upgrade the other side and call UA
+        RLOGD("[+UP]: ***Upgrade the other side and call UA***\n");
+        ret = rock_update_main(0, 0, 0, 0, first_run, 0, 0, 0);
+        RLOGD("rock_update_main ret = %d\n", ret);
+        if(ret)
+        {
+            RLOGD("fota update fail!\n");
+        }
+    }
+    //xf.li@20230822 add for ab backup start
+    else if(is_other_slot_bootable == 0) 
+    {
+        RLOGD("need backup\n");
+        ret = lynq_backup_main();
+        if(ret != 0)
+        {
+            RLOGD("ERROE: backup fail!!!\n");
+        }
+        else
+        {
+            RLOGD("backup success!!!\n");
+            module->setCompleteBackup(module, current_slot);
+        }
+    }
+    else
+    {
+        RLOGD("Don't need backup\n");
+    }
+    //xf.li@20230822 add for ab backup end
+    
+    return 0;
+}    
+
+int lynq_nand_open(const char *pathname, int flags)
+{
+//    printf("pathname:%s---flags:%d",pathname,flags);
+    return open(pathname,flags);
+}
+
+ssize_t lynq_nand_read(int fd, void *buf, size_t count)
+{
+//    printf("rfd:%d---buf:%s---count:%d",fd,buf,count);
+    return read(fd,buf,count);
+}
+
+ssize_t lynq_nand_write(int fd, void *buf, size_t count)
+{
+ //   printf("wfd:%d---buf:%s---count:%d",fd,buf,count);
+    return write(fd,buf,count);
+}
+
+int lynq_nand_close(int fd)
+{
+    return close(fd);
+}
+
+/**
+ * @brief Obtain the upgrade result
+ * 
+ * @param void
+ * @return 0xff:open file fail,0:upgrade success,1,upgrade wait 
+ */
+ int lynq_get_upgrade_status(void)
+{
+    int lynq_state_fd;
+    int lynq_upgrade_wait = 1;
+    OTA_STATUS lynq_ota_status;
+
+    memset(&lynq_ota_status, 0, sizeof(lynq_ota_status));
+
+    lynq_state_fd = open(FILE_FOTA_STATE,O_RDWR | O_CREAT,0777);
+
+    if (lynq_state_fd < 0) 
+    {
+        return 0xff;
+    }
+    read(lynq_state_fd,(unsigned char *)&lynq_ota_status,sizeof(lynq_ota_status));
+    close(lynq_state_fd);
+    if((lynq_ota_status.ota_run != 0) && (lynq_ota_status.update_result == 0))
+    {
+        return lynq_upgrade_wait;
+    }
+    return lynq_ota_status.update_result;
+}
+
+/**
+ * @brief reboot device
+ * 
+ * @param void
+ * @return void
+ */
+ void lynq_reboot_device(void)
+{
+    reboot_device();
+    return ;
+}
+
+/**
+ * @brief fota no resatrt
+ * 
+ * @param void
+ * @return 0:fota success -Other values:fota fail
+ */
+
+int lynq_fota_nrestart(void)
+{
+
+    int ret = 0;
+#if 0
+    printf("-********copy delta ***-\n");
+    test_write_delta("/data/delta",DEV_DELTA);
+#endif
+
+    ret = rock_update_main(0, 0, 0, 0, 1, 1, 0, 1);
+    RLOGD("rock_update_nrestart ret = %d\n", ret);
+    if(ret)
+    {
+        RLOGD("fota update fail!\n");
+    }
+    return ret;
+}
+
+/**
+ * @brief Set the upgrade package address
+ * 
+ * @param1 value:fota addr
+ * @param1 szie:fota addr length
+ * @return 0:set success other:set fail
+ */
+int lynq_fota_set_addr_value(char *value,int size)
+{
+    if(size < 64)
+    {
+        return lynq_set_value(FOTA_UCI_MODULE,FOTA_UCI_ADDR, value);
+    }
+    return -1;
+}
+/**
+ * @brief get the upgrade package address
+ * 
+ * @param1 value:fota addr
+ * @return 0:get success other:set fail
+ */
+int lynq_fota_get_addr_value(char *tmp)
+{
+    return lynq_get_value(FOTA_UCI_FILE, FOTA_UCI_MODULE,FOTA_UCI_ADDR, tmp);
+}
+
+/**
+ * @brief Porting wakes up the demo content
+ */
+static void lynq_init_wake_lock_func(void)
+{
+    const char *lynqLibPath_WakeLock = "/usr/lib64/libpower.so";
+
+    dlHandle_wakelock = dlopen(lynqLibPath_WakeLock, RTLD_NOW);
+    if (dlHandle_wakelock == NULL) 
+    {
+        printf("dlopen lynqLibPath_WakeLock failed: %s", dlerror());
+        exit(EXIT_FAILURE);
+    }
+    
+    acquire_wake_lock = (int(*)(int,const char*))dlsym(dlHandle_wakelock, "acquire_wake_lock");
+    if (acquire_wake_lock == NULL) {
+        printf("acquire_wake_lock not defined or exported in %s", lynqLibPath_WakeLock);
+        exit(EXIT_FAILURE);
+    }
+    release_wake_lock = (int(*)( const char*))dlsym(dlHandle_wakelock, "release_wake_lock");
+    if (release_wake_lock == NULL) {
+        printf("release_wake_lock not defined or exported in %s", lynqLibPath_WakeLock);
+        exit(EXIT_FAILURE);
+    }
+    dlerror(); // Clear any previous dlerror
+
+  return;
+}
+
+/**
+ * @brief fota wake lock
+ * 
+ * @param1 value:void
+ * @return ;
+ */
+static void lynq_fota_grab_artial_wake_lock(void) 
+{
+    acquire_wake_lock(PARTIAL_WAKE_LOCK, ANDROID_WAKE_LOCK_NAME);
+}
+
+/**
+ * @brief get the upgrade package address
+ * 
+ * @param1 value:void
+ * @return ;
+ */
+static void lynq_fota_release_wake_lock(void) 
+{
+    release_wake_lock(ANDROID_WAKE_LOCK_NAME);
+}
+/**
+ * @brief This is the wake up call
+ * end
+ */
diff --git a/IC_src/mtk/lib/liblynq-fota/rock_ua/sha.c b/IC_src/mtk/lib/liblynq-fota/rock_ua/sha.c
new file mode 100755
index 0000000..5ac6b53
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/rock_ua/sha.c
@@ -0,0 +1,428 @@
+/* sha.c
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+**     * Redistributions of source code must retain the above copyright
+**       notice, this list of conditions and the following disclaimer.
+**     * Redistributions in binary form must reproduce the above copyright
+**       notice, this list of conditions and the following disclaimer in the
+**       documentation and/or other materials provided with the distribution.
+**     * Neither the name of Google Inc. nor the names of its contributors may
+**       be used to endorse or promote products derived from this software
+**       without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR
+** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+** EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "sha.h"
+
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "mtk_device_wrap.h"
+
+// Some machines lack byteswap.h and endian.h.  These have to use the
+// slower code, even if they're little-endian.
+
+#if defined(HAVE_ENDIAN_H) && defined(HAVE_LITTLE_ENDIAN)
+
+#include <byteswap.h>
+#include <memory.h>
+
+
+
+// This version is about 28% faster than the generic version below,
+// but assumes little-endianness.
+
+static inline uint32_t ror27(uint32_t val) {
+    return (val >> 27) | (val << 5);
+}
+static inline uint32_t ror2(uint32_t val) {
+    return (val >> 2) | (val << 30);
+}
+static inline uint32_t ror31(uint32_t val) {
+    return (val >> 31) | (val << 1);
+}
+
+static void SHA1_Transform(SHA_CTX* ctx) {
+    uint32_t W[80];
+    register uint32_t A, B, C, D, E;
+    int t;
+
+    A = ctx->state[0];
+    B = ctx->state[1];
+    C = ctx->state[2];
+    D = ctx->state[3];
+    E = ctx->state[4];
+
+#define SHA_F1(A,B,C,D,E,t)                     \
+    E += ror27(A) +                             \
+        (W[t] = bswap_32(ctx->buf.w[t])) +      \
+        (D^(B&(C^D))) + 0x5A827999;             \
+    B = ror2(B);
+
+    for (t = 0; t < 15; t += 5) {
+        SHA_F1(A,B,C,D,E,t + 0);
+        SHA_F1(E,A,B,C,D,t + 1);
+        SHA_F1(D,E,A,B,C,t + 2);
+        SHA_F1(C,D,E,A,B,t + 3);
+        SHA_F1(B,C,D,E,A,t + 4);
+    }
+    SHA_F1(A,B,C,D,E,t + 0);  // 16th one, t == 15
+
+#undef SHA_F1
+
+#define SHA_F1(A,B,C,D,E,t)                                     \
+    E += ror27(A) +                                             \
+        (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) +   \
+        (D^(B&(C^D))) + 0x5A827999;                             \
+    B = ror2(B);
+
+    SHA_F1(E,A,B,C,D,t + 1);
+    SHA_F1(D,E,A,B,C,t + 2);
+    SHA_F1(C,D,E,A,B,t + 3);
+    SHA_F1(B,C,D,E,A,t + 4);
+
+#undef SHA_F1
+
+#define SHA_F2(A,B,C,D,E,t)                                     \
+    E += ror27(A) +                                             \
+        (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) +   \
+        (B^C^D) + 0x6ED9EBA1;                                   \
+    B = ror2(B);
+
+    for (t = 20; t < 40; t += 5) {
+        SHA_F2(A,B,C,D,E,t + 0);
+        SHA_F2(E,A,B,C,D,t + 1);
+        SHA_F2(D,E,A,B,C,t + 2);
+        SHA_F2(C,D,E,A,B,t + 3);
+        SHA_F2(B,C,D,E,A,t + 4);
+    }
+
+#undef SHA_F2
+
+#define SHA_F3(A,B,C,D,E,t)                                     \
+    E += ror27(A) +                                             \
+        (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) +   \
+        ((B&C)|(D&(B|C))) + 0x8F1BBCDC;                         \
+    B = ror2(B);
+
+    for (; t < 60; t += 5) {
+        SHA_F3(A,B,C,D,E,t + 0);
+        SHA_F3(E,A,B,C,D,t + 1);
+        SHA_F3(D,E,A,B,C,t + 2);
+        SHA_F3(C,D,E,A,B,t + 3);
+        SHA_F3(B,C,D,E,A,t + 4);
+    }
+
+#undef SHA_F3
+
+#define SHA_F4(A,B,C,D,E,t)                                     \
+    E += ror27(A) +                                             \
+        (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) +   \
+        (B^C^D) + 0xCA62C1D6;                                   \
+    B = ror2(B);
+
+    for (; t < 80; t += 5) {
+        SHA_F4(A,B,C,D,E,t + 0);
+        SHA_F4(E,A,B,C,D,t + 1);
+        SHA_F4(D,E,A,B,C,t + 2);
+        SHA_F4(C,D,E,A,B,t + 3);
+        SHA_F4(B,C,D,E,A,t + 4);
+    }
+
+#undef SHA_F4
+
+    ctx->state[0] += A;
+    ctx->state[1] += B;
+    ctx->state[2] += C;
+    ctx->state[3] += D;
+    ctx->state[4] += E;
+}
+
+void SHA_update(SHA_CTX* ctx, const void* data, int len) {
+    int i = ctx->count % sizeof(ctx->buf);
+    const uint8_t* p = (const uint8_t*)data;
+
+    ctx->count += len;
+
+    while (len > sizeof(ctx->buf) - i) {
+        memcpy(&ctx->buf.b[i], p, sizeof(ctx->buf) - i);
+        len -= sizeof(ctx->buf) - i;
+        p += sizeof(ctx->buf) - i;
+        SHA1_Transform(ctx);
+        i = 0;
+    }
+
+    while (len--) {
+        ctx->buf.b[i++] = *p++;
+        if (i == sizeof(ctx->buf)) {
+            SHA1_Transform(ctx);
+            i = 0;
+        }
+    }
+}
+
+
+const uint8_t* SHA_final(SHA_CTX* ctx) {
+    uint64_t cnt = ctx->count * 8;
+    int i;
+
+    SHA_update(ctx, (uint8_t*)"\x80", 1);
+    while ((ctx->count % sizeof(ctx->buf)) != (sizeof(ctx->buf) - 8)) {
+        SHA_update(ctx, (uint8_t*)"\0", 1);
+    }
+    for (i = 0; i < 8; ++i) {
+        uint8_t tmp = cnt >> ((7 - i) * 8);
+        SHA_update(ctx, &tmp, 1);
+    }
+
+    for (i = 0; i < 5; i++) {
+        ctx->buf.w[i] = bswap_32(ctx->state[i]);
+    }
+
+    return ctx->buf.b;
+}
+
+#else   // #if defined(HAVE_ENDIAN_H) && defined(HAVE_LITTLE_ENDIAN)
+
+#define rol(bits, value) (((value) << (bits)) | ((value) >> (32 - (bits))))
+
+static void SHA1_transform(SHA_CTX *ctx) {
+    uint32_t W[80];
+    uint32_t A, B, C, D, E;
+    uint8_t *p = ctx->buf;
+    int t;
+
+    for(t = 0; t < 16; ++t) {
+        uint32_t tmp =  *p++ << 24;
+        tmp |= *p++ << 16;
+        tmp |= *p++ << 8;
+        tmp |= *p++;
+        W[t] = tmp;
+    }
+
+    for(; t < 80; t++) {
+        W[t] = rol(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
+    }
+
+    A = ctx->state[0];
+    B = ctx->state[1];
+    C = ctx->state[2];
+    D = ctx->state[3];
+    E = ctx->state[4];
+
+    for(t = 0; t < 80; t++) {
+        uint32_t tmp = rol(5,A) + E + W[t];
+
+        if (t < 20)
+            tmp += (D^(B&(C^D))) + 0x5A827999;
+        else if ( t < 40)
+            tmp += (B^C^D) + 0x6ED9EBA1;
+        else if ( t < 60)
+            tmp += ((B&C)|(D&(B|C))) + 0x8F1BBCDC;
+        else
+            tmp += (B^C^D) + 0xCA62C1D6;
+
+        E = D;
+        D = C;
+        C = rol(30,B);
+        B = A;
+        A = tmp;
+    }
+
+    ctx->state[0] += A;
+    ctx->state[1] += B;
+    ctx->state[2] += C;
+    ctx->state[3] += D;
+    ctx->state[4] += E;
+}
+
+void SHA_update(SHA_CTX *ctx, const void *data, int len) {
+    int i = ctx->count % sizeof(ctx->buf);
+    const uint8_t* p = (const uint8_t*)data;
+
+    ctx->count += len;
+
+    while (len--) {
+        ctx->buf[i++] = *p++;
+        if (i == sizeof(ctx->buf)) {
+            SHA1_transform(ctx);
+            i = 0;
+        }
+    }
+}
+const uint8_t *SHA_final(SHA_CTX *ctx) {
+    uint8_t *p = ctx->buf;
+    uint64_t cnt = ctx->count * 8;
+    int i;
+
+    SHA_update(ctx, (uint8_t*)"\x80", 1);
+    while ((ctx->count % sizeof(ctx->buf)) != (sizeof(ctx->buf) - 8)) {
+        SHA_update(ctx, (uint8_t*)"\0", 1);
+    }
+    for (i = 0; i < 8; ++i) {
+        uint8_t tmp = cnt >> ((7 - i) * 8);
+        SHA_update(ctx, &tmp, 1);
+    }
+
+    for (i = 0; i < 5; i++) {
+        uint32_t tmp = ctx->state[i];
+        *p++ = tmp >> 24;
+        *p++ = tmp >> 16;
+        *p++ = tmp >> 8;
+        *p++ = tmp >> 0;
+    }
+
+    return ctx->buf;
+}
+
+#endif // endianness
+
+void SHA_init(SHA_CTX* ctx) {
+    ctx->state[0] = 0x67452301;
+    ctx->state[1] = 0xEFCDAB89;
+    ctx->state[2] = 0x98BADCFE;
+    ctx->state[3] = 0x10325476;
+    ctx->state[4] = 0xC3D2E1F0;
+    ctx->count = 0;
+}
+
+/* Convenience function */
+const uint8_t* SHA(const void *data, int len, uint8_t *digest) {
+    const uint8_t *p;
+    int i;
+	
+    SHA_CTX ctx;
+    SHA_init(&ctx);
+    SHA_update(&ctx, data, len);
+    p = SHA_final(&ctx);
+    for (i = 0; i < SHA_DIGEST_SIZE; ++i) {
+        digest[i] = *p++;
+    }
+    return digest;
+}
+
+#define NAND_PAGE_SIZE_SHA  4096
+
+const uint8_t* ROCK_SHA_FILE_COMMON(int fd_sha, int offset,int totle_size, uint8_t *digest) {
+    const uint8_t *p;
+    int i = 0;
+    //int fd_sha;
+    int size = 0;
+    int totale_size_common = totle_size;
+    char data[NAND_PAGE_SIZE_SHA];
+	
+
+    lseek(fd_sha, offset, SEEK_SET);
+    SHA_CTX ctx;
+    SHA_init(&ctx);
+
+    do{
+        if(totale_size_common >= NAND_PAGE_SIZE_SHA)
+        {
+            size = read(fd_sha,data,NAND_PAGE_SIZE_SHA);
+        }
+        else
+        {
+            size = read(fd_sha,data,totale_size_common);
+        }
+        if (size == 0){
+		    break;
+		}			
+        SHA_update(&ctx, data, size);
+        totale_size_common -= size;
+
+    }while(totale_size_common>0);
+    p = SHA_final(&ctx);
+    for (i = 0; i < SHA_DIGEST_SIZE; ++i) 
+    {
+        digest[i] = *p++;
+    }
+    return digest;
+}
+
+const uint8_t* ROCK_SHA_FILE(int fd_sha, int offset,int totle_size, uint8_t *digest) {
+    const uint8_t *p;
+    int i = 0;
+    //int fd_sha;
+    int size = 0;
+    int totale_size_file = totle_size;
+    char data[NAND_PAGE_SIZE_SHA];
+	
+
+    mtk_device_wrap_seek(fd_sha, offset, SEEK_SET);
+    SHA_CTX ctx;
+    SHA_init(&ctx);
+
+    do{
+        if(totale_size_file >= NAND_PAGE_SIZE_SHA)
+        {
+            size = mtk_device_wrap_read(fd_sha,data,NAND_PAGE_SIZE_SHA);   
+        }
+        else
+        {
+            size = mtk_device_wrap_read(fd_sha,data,totale_size_file);
+        }
+	    if (size == 0){
+		    break;
+		}	
+        SHA_update(&ctx, data, size);
+        totale_size_file -= size;
+
+    }while(totale_size_file>0);
+    p = SHA_final(&ctx);
+    for (i = 0; i < SHA_DIGEST_SIZE; ++i) 
+    {
+        digest[i] = *p++;
+    }
+    return digest;
+}
+
+
+
+// Take a string 'str' of 40 hex digits and parse it into the 20
+// byte array 'digest'.  'str' may contain only the digest or be of
+// the form "<digest>:<anything>".  Return 0 on success, -1 on any
+// error.
+int ParseSha1(const char* str, uint8_t* digest) {
+    int i;
+    const char* ps = str;
+    uint8_t* pd = digest;
+    for (i = 0; i < SHA_DIGEST_SIZE * 2; ++i, ++ps) {
+        int digit;
+        if (*ps >= '0' && *ps <= '9') {
+            digit = *ps - '0';
+        } else if (*ps >= 'a' && *ps <= 'f') {
+            digit = *ps - 'a' + 10;
+        } else if (*ps >= 'A' && *ps <= 'F') {
+            digit = *ps - 'A' + 10;
+        } else {
+            return -1;
+        }
+        if (i % 2 == 0) {
+            *pd = digit << 4;
+        } else {
+            *pd |= digit;
+            ++pd;
+        }
+    }
+    if (*ps != '\0') return -1;
+    return 0;
+}
diff --git a/IC_src/mtk/lib/liblynq-gnss/include/lynq_gnss.h b/IC_src/mtk/lib/liblynq-gnss/include/lynq_gnss.h
new file mode 100755
index 0000000..362baaf
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-gnss/include/lynq_gnss.h
@@ -0,0 +1,122 @@
+#ifndef LYNQ_GNSS_H

+#define LYNQ_GNSS_H

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+#include "gpshal.h"

+#include "hal2mnl_interface.h"

+

+typedef enum{

+    LYNQ_MODE_GPS_GLONASS = 0,

+    LYNQ_MODE_GPS_BEIDOU,

+    LYNQ_MODE_GPS_GLONASS_BEIDOU,

+    LYNQ_MODE_GPS,

+    LYNQ_MODE_BEIDOU,

+    LYNQ_MODE_GLONASS,

+    LYNQ_MODE_GPS_GLONASS_BEIDOU_GALILEO,

+    LYNQ_MODE_GPS_GALILEO,

+    LYNQ_MODE_GPS_GLONASS_GALILEO,

+    LYNQ_MODE_GPS_GALILEO_ONLY,

+    LYNQ_MODE_GPS_GLONASS_BEIDOU_GALILEO_NAVIC,

+    LYNQ_MODE_GNSS_END

+}LYNQ_GNSS_MODE_CONFIGURATION;

+

+typedef enum{

+    LYNQ_SWITCH_DISABLE = 0,

+    LYNQ_SWITCH_ENABLE

+}LYNQ_CONF_SWITCH;

+

+typedef struct {

+    GpsLocation legacyLocation;

+

+    float           horizontalAccuracyMeters;

+

+    /**

+    * Represents expected vertical position accuracy in meters

+    * (68% confidence).

+    */

+    float           verticalAccuracyMeters;

+

+    /**

+    * Represents expected speed accuracy in meter per seconds

+    * (68% confidence).

+    */

+    float           speedAccuracyMetersPerSecond;

+

+    /**

+    * Represents expected bearing accuracy in degrees

+    * (68% confidence).

+    */

+    float           bearingAccuracyDegrees;

+} lynq_GpsLocation_ext;

+

+typedef void (*gps_location_callback_ext)(lynq_GpsLocation_ext* location);

+

+// typedef void (* gps_status_callback)(GpsStatus* status);

+

+// typedef void (* gps_nmea_callback)(GpsUtcTime timestamp, const char* nmea, int length);

+

+// typedef pthread_t (* gps_create_thread)(const char* name, void (*start)(void *), void* arg);

+

+//typedef void (*gnss_measurement_ext_callback) (GnssData_ext* data);

+

+

+typedef struct

+{

+    size_t size;

+    gps_location_callback_ext lynq_location_cb;

+    gps_status_callback lynq_status_cb;

+    gps_nmea_callback lynq_nmea_cb;

+    gps_create_thread lynq_create_thread_cb;

+}lynq_gnss_cb;

+

+typedef struct 

+{

+    size_t size;

+    gnss_measurement_ext_callback lynq_measurement_callback;

+}lynq_raw_gnss_cbs;

+

+typedef void ( *lynq_atsvc_incb )(const char *input,const int length);

+typedef void ( *lynq_atsvc_outcb )(char *output,int out_size,int type);

+lynq_atsvc_incb lynq_register_gnss(lynq_atsvc_outcb out_cb);

+lynq_atsvc_outcb atsvc_gnss_outcb;

+

+int lynq_gnss_init(void);

+

+int lynq_gnss_deinit(void);

+

+int lynq_gnss_callback_reg(lynq_gnss_cb* callbacks);

+

+int lynq_gnss_start(void);

+

+int lynq_gnss_stop(void);

+

+int lynq_gnss_inject_time(GpsUtcTime time, int64_t timeReference, int uncertainty);

+

+int lynq_gnss_inject_location(double latitude,double longitude,float  accuracy);

+

+int lynq_gnss_delete_aiding_data(GpsAidingData flags);

+

+int lynq_gnss_inject_fused_location(double latitude,double longitude,float accuracy);

+

+int lynq_gnss_start_raw_meas_mode(lynq_raw_gnss_cbs* raw_gnss_cbs);

+

+int lynq_gnss_stop_raw_meas_mode();

+

+int lynq_gnss_set_start_mode(LYNQ_GNSS_MODE_CONFIGURATION start_mode);

+

+int lynq_gnss_epo_switch(LYNQ_CONF_SWITCH switch_op);

+

+int lynq_gnss_output_frequency_set(int frequency);

+

+int lynq_agps_set_enabled(LYNQ_CONF_SWITCH agps_status);

+

+int lynq_agps_get_enabled_status(int *status);

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif
\ No newline at end of file
diff --git a/IC_src/mtk/lib/liblynq-gnss/makefile b/IC_src/mtk/lib/liblynq-gnss/makefile
new file mode 100755
index 0000000..f1ca7fc
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-gnss/makefile
@@ -0,0 +1,62 @@
+SHELL = /bin/sh

+RM = rm -f

+

+

+LOCAL_CFLAGS := \

+	-Wall \

+    -g \

+    -Wall \

+    -fPIC \

+    -shared \

+    -D__COMPILE_OPTION__ \

+    -D__LINUX_OS__ \

+

+CPPFLAGS=\

+  -std=c++11 \

+

+LOCAL_PATH = .

+

+LOCAL_C_INCLUDES = \

+    -I$(LOCAL_PATH)/include \

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

+	-I$(ROOT)$(includedir)/gps_hal/inc \

+	-I$(ROOT)$(includedir)/gps_hal/hardware \

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

+	

+LOCAL_LIBS := \

+    -L. \

+	-ldl \

+    -lrt \

+	-llog \

+	-lutils \

+	-lcutils \

+	-lgnsshal \

+	-lpthread \

+#    -llynq-log \

+

+$(warning libs=$(LOCAL_LIBS))

+

+CXXSRC=\

+

+SOURCES = $(wildcard *.c wildcard src/*.c)

+

+EXECUTABLE = liblynq-gnss.so

+

+COBJS=$(SOURCES:.c=.o)

+$(warning test)

+all: $(EXECUTABLE)

+$(EXECUTABLE): $(COBJS)

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

+

+%.o: %.c

+	$(warning ----->build $<)

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

+

+.PHONY: install clean

+install:

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

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

+

+clean:

+	rm -f $(EXECUTABLE) rm -rf *.o

+	find ./ -name *.o | xargs rm -rf

diff --git a/IC_src/mtk/lib/liblynq-gnss/src/lynq_agps.c b/IC_src/mtk/lib/liblynq-gnss/src/lynq_agps.c
new file mode 100644
index 0000000..b457941
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-gnss/src/lynq_agps.c
@@ -0,0 +1,510 @@
+#include <stdio.h>
+#include <sys/socket.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <netinet/in.h>
+#include <sys/un.h>
+#include <log/log.h>
+
+
+#include "lynq_gnss.h"
+#include "lynq_agps.h"
+
+#define LOG_TAG "LYNQ_AGPS"
+
+
+// -1 means failure
+int do_socket_connect(const char* path)
+{
+    struct sockaddr_un addr;
+    int fd = socket(PF_LOCAL, SOCK_STREAM, 0);
+    if(fd < 0) {
+        RLOGD("socket() failed fd=%d\n", fd);
+        return -1;
+    }
+
+    memset(&addr, 0, sizeof(addr));
+    addr.sun_path[0] = 0;
+    memcpy(addr.sun_path + 1, path, strlen(path));
+    addr.sun_family = AF_UNIX;
+
+    if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+        RLOGD("connect failed reason=[%s] path=[%s]\n", strerror(errno), path);
+        close(fd);
+        return -1;
+    }
+
+    return fd;
+}
+
+//get
+char get_byte(char* buff, int* offset)
+{
+    char ret = buff[*offset];
+    *offset += 1;
+    return ret;
+}
+
+short get_short(char* buff, int* offset)
+{
+    short ret = 0;
+    ret |= get_byte(buff, offset) & 0xff;
+    ret |= (get_byte(buff, offset) << 8);
+    return ret;
+}
+
+int get_int(char* buff, int* offset)
+{
+    int ret = 0;
+    ret |= get_short(buff, offset) & 0xffff;
+    ret |= (get_short(buff, offset) << 16);
+    return ret;
+}
+
+int socket_connect() {
+    return do_socket_connect("agpsd2");
+}
+
+//-1 means failure
+static int safe_write(int fd, void* buf, int len)
+{
+    int n, retry = 10;
+
+    if(fd < 0 || buf == NULL || len < 0) {
+        RLOGD("safe_write fd=%d buf=%p len=%d\n", fd, buf, len);
+        return -1;
+    }
+
+    while((n = write(fd, buf, len)) != len) {
+        if(errno == EINTR) continue;
+        if(errno == EAGAIN) {
+            if(retry-- > 0) {
+                usleep(100 * 1000);
+                continue;
+            }
+            goto exit;
+        }
+        goto exit;
+    }
+    return n;
+exit:
+    RLOGD("safe_write reason=[%s]%d\n", strerror(errno), errno);
+    return -1;
+}
+
+//-1 means failure
+static int safe_read(int fd, void* buf, int len)
+{
+    int n, retry = 10;
+
+    if(fd < 0 || buf == NULL || len < 0)
+    {
+        RLOGD("safe_read fd=%d buf=%p len=%d\n", fd, buf, len);
+        return -1;
+    }
+
+    if(len == 0)
+    {
+        return 0;
+    }
+
+    while((n = read(fd, buf, len)) < 0)
+    {
+        if(errno == EINTR) 
+        {
+            RLOGD("safe read interrupt");
+            continue;
+        }
+        if(errno == EAGAIN)
+        {
+            if(retry-- > 0)
+            {
+                usleep(100 * 1000);
+                continue;
+            }
+            goto exit;
+        }
+        goto exit;
+    }
+    return n;
+
+exit:
+    if(errno != EAGAIN)
+    {
+        RLOGD("safe_read reason=[%s] fd=%d len=%d buf=%p\n",
+            strerror(errno), fd, len, buf);
+    }
+    return -1;
+}
+
+static char socket_get_byte(int fd)
+{
+    int read_len = 0;
+    char buff[1] = {0};
+    int offset = 0;
+
+    read_len = safe_read(fd, buff, sizeof(buff));
+    if(read_len != sizeof(buff))
+    {
+        RLOGD("socket_get_byte read_len=%d\n", read_len);
+    }
+    return get_byte(buff, &offset);
+}
+
+static int socket_get_int(int fd)
+{
+    int read_len = 0;
+    char buff[4] = {0};
+    int offset = 0;
+
+    read_len = safe_read(fd, buff, sizeof(buff));
+    if(read_len != sizeof(buff))
+    {
+        RLOGD("socket_get_int read_len=%d\n", read_len);
+    }
+    return get_int(buff, &offset);
+}
+
+static char* socket_get_string(int fd, char* buff, int buff_len)
+{
+    int read_len = 0;
+
+    char ret = socket_get_byte(fd);
+    if(ret == 0)
+    {
+        return NULL;
+    }
+    else
+    {
+        int len = socket_get_int(fd);
+        if(len > buff_len)
+        {
+            RLOGD("socket_get_string your buff len=%d is too small, need len=%d\n",
+                buff_len, len);
+            return NULL;
+        }
+
+        read_len = safe_read(fd, buff, len);
+        if(read_len != len)
+        {
+            RLOGD("socket_get_string read_len=%d len=%d\n", read_len, len);
+            return NULL;
+        }
+
+        return buff;
+    }
+}
+
+
+static int socket_get_binary(int fd, char* buff)
+{
+    int read_len = 0;
+
+    int len = socket_get_int(fd);
+    if(len > 0)
+    {
+        read_len = safe_read(fd, buff, len);
+        if(read_len != len)
+        {
+            RLOGD("socket_get_binary read_len=%d len=%d\n", read_len, len);
+            return 0;
+        }
+    }
+    return len;
+}
+
+void put_byte(char* buff, int* offset, const char input)
+{
+    *((char*)&buff[*offset]) = input;
+    *offset += 1;
+}
+
+void put_short(char* buff, int* offset, const short input)
+{
+    put_byte(buff, offset, input & 0xff);
+    put_byte(buff, offset, (input >> 8) & 0xff);
+}
+
+void put_int(char* buff, int* offset, const int input)
+{
+    put_short(buff, offset, input & 0xffff);
+    put_short(buff, offset, (input >> 16) & 0xffff);
+}
+
+int set_template_1(app_mgr_cmd_enum cmd,char data)
+{
+    char buff[MAX_BUFF_SIZE] = {0};
+    int offset = 0;
+    int fd = 0;
+
+    fd = socket_connect();
+    if(fd < 0)
+    {
+        RLOGD("Socket connect fail");
+        return -1;
+    }
+    RLOGD("Set template start fd:%d cmd:%d data:%d",fd,cmd,data);
+    // write
+    put_int(buff, &offset, cmd);
+    put_byte(buff, &offset, data);
+    if(safe_write(fd, buff, offset) == -1)
+    {
+        RLOGD("set_template_1 Safe write fail");
+        close(fd);
+        return -1;
+    }
+
+    // read ACK
+    socket_get_byte(fd);
+
+    close(fd);
+    return 0;
+}
+
+int get_template_agps_config(app_mgr_cmd_enum cmd,agps_intf_agps_config *config)
+{
+    char buff[MAX_BUFF_SIZE] = {0};
+    int offset = 0;
+    int fd = 0;
+
+    fd = socket_connect();
+    if(fd < 0)
+    {
+        RLOGD("Socket connect fail");
+        return -1;
+    }
+    RLOGD("get_template_agps_config start fd:%d cmd:%d",fd,cmd);
+
+    // write
+    put_int(buff, &offset, cmd);
+    if(safe_write(fd, buff, offset) == -1)
+    {
+        RLOGD("get_template_agps_config Safe write fail");
+        close(fd);
+        return -1;
+    }
+
+    // read
+    config->agps_setting.agps_enable = socket_get_byte(fd);
+    config->agps_setting.agps_protocol = socket_get_int(fd);
+    config->agps_setting.gpevt = socket_get_byte(fd);
+
+    config->cp_setting.molr_pos_method = socket_get_int(fd);
+    config->cp_setting.external_addr_enable = socket_get_byte(fd);
+    socket_get_string(fd, config->cp_setting.external_addr, sizeof(config->cp_setting.external_addr));
+    config->cp_setting.mlc_number_enable = socket_get_byte(fd);
+    socket_get_string(fd, config->cp_setting.mlc_number, sizeof(config->cp_setting.mlc_number));
+    config->cp_setting.cp_auto_reset = socket_get_byte(fd);
+    config->cp_setting.epc_molr_lpp_payload_enable = socket_get_byte(fd);
+    config->cp_setting.epc_molr_lpp_payload_len =
+        socket_get_binary(fd, config->cp_setting.epc_molr_lpp_payload);
+
+    config->up_setting.ca_enable = socket_get_byte(fd);
+    config->up_setting.ni_request = socket_get_byte(fd);
+    config->up_setting.roaming = socket_get_byte(fd);
+    config->up_setting.cdma_preferred = socket_get_int(fd);
+    config->up_setting.pref_method = socket_get_int(fd);
+    config->up_setting.supl_version = socket_get_int(fd);
+    config->up_setting.tls_version = socket_get_int(fd);
+    config->up_setting.supl_log = socket_get_byte(fd);
+    config->up_setting.msa_enable = socket_get_byte(fd);
+    config->up_setting.msb_enable = socket_get_byte(fd);
+    config->up_setting.ecid_enable = socket_get_byte(fd);
+    config->up_setting.otdoa_enable = socket_get_byte(fd);
+    config->up_setting.qop_hacc = socket_get_int(fd);
+    config->up_setting.qop_vacc = socket_get_int(fd);
+    config->up_setting.qop_loc_age = socket_get_int(fd);
+    config->up_setting.qop_delay = socket_get_int(fd);
+    config->up_setting.lpp_enable = socket_get_byte(fd);
+    config->up_setting.cert_from_sdcard = socket_get_byte(fd);
+    if(cmd >= APP_MGR_CMD_GET_CONFIG_V14)
+    {
+        config->up_setting.auto_profile_enable = socket_get_byte(fd);
+        config->up_setting.ut2 = socket_get_byte(fd);
+        config->up_setting.ut3 = socket_get_byte(fd);
+        config->up_setting.apn_enable = socket_get_byte(fd);
+        config->up_setting.sync_to_slp = socket_get_byte(fd);
+        config->up_setting.udp_enable = socket_get_byte(fd);
+        config->up_setting.autonomous_enable = socket_get_byte(fd);
+        config->up_setting.aflt_enable = socket_get_byte(fd);
+        config->up_setting.imsi_enable = socket_get_byte(fd);
+
+        config->gnss_setting.sib8_sib16_enable = socket_get_byte(fd);
+        config->gnss_setting.gps_satellite_enable = socket_get_byte(fd);
+        config->gnss_setting.glonass_satellite_enable = socket_get_byte(fd);
+        config->gnss_setting.beidou_satellite_enable = socket_get_byte(fd);
+        config->gnss_setting.galileo_satellite_enable = socket_get_byte(fd);
+        config->gnss_setting.gps_satellite_support = socket_get_byte(fd);
+        config->gnss_setting.glonass_satellite_support = socket_get_byte(fd);
+        config->gnss_setting.beidou_satellite_support = socket_get_byte(fd);
+        config->gnss_setting.galileo_satellite_support = socket_get_byte(fd);
+
+        config->up_setting.supl_ver_minor = socket_get_byte(fd);
+        config->up_setting.supl_ver_ser_ind = socket_get_byte(fd);
+
+        config->gnss_setting.a_glonass_satellite_enable = socket_get_byte(fd);
+    }
+
+    socket_get_string(fd, config->cur_supl_profile.name, sizeof(config->cur_supl_profile.name));
+    socket_get_string(fd, config->cur_supl_profile.addr, sizeof(config->cur_supl_profile.addr));
+    config->cur_supl_profile.port = socket_get_int(fd);
+    config->cur_supl_profile.tls = socket_get_byte(fd);
+    socket_get_string(fd, config->cur_supl_profile.mcc_mnc, sizeof(config->cur_supl_profile.mcc_mnc));
+    socket_get_string(fd, config->cur_supl_profile.app_id, sizeof(config->cur_supl_profile.app_id));
+    socket_get_string(fd, config->cur_supl_profile.provider_id, sizeof(config->cur_supl_profile.provider_id));
+    socket_get_string(fd, config->cur_supl_profile.default_apn, sizeof(config->cur_supl_profile.default_apn));
+    socket_get_string(fd, config->cur_supl_profile.optional_apn, sizeof(config->cur_supl_profile.optional_apn));
+    socket_get_string(fd, config->cur_supl_profile.optional_apn_2, sizeof(config->cur_supl_profile.optional_apn_2));
+    socket_get_string(fd, config->cur_supl_profile.address_type, sizeof(config->cur_supl_profile.address_type));
+
+    if(cmd >= APP_MGR_CMD_GET_CONFIG_V14)
+    {
+        socket_get_string(fd, config->cdma_profile.name, sizeof(config->cdma_profile.name));
+        config->cdma_profile.mcp_enable = socket_get_byte(fd);;
+        socket_get_string(fd, config->cdma_profile.mcp_addr, sizeof(config->cdma_profile.mcp_addr));
+        config->cdma_profile.mcp_port = socket_get_int(fd);;
+        config->cdma_profile.pde_addr_valid = socket_get_byte(fd);;
+        config->cdma_profile.pde_ip_type = socket_get_int(fd);;
+        socket_get_string(fd, config->cdma_profile.pde_addr, sizeof(config->cdma_profile.pde_addr));
+        config->cdma_profile.pde_port = socket_get_int(fd);;
+        config->cdma_profile.pde_url_valid = socket_get_byte(fd);;
+        socket_get_string(fd, config->cdma_profile.pde_url_addr, sizeof(config->cdma_profile.pde_url_addr));
+    }
+
+    if(cmd >= APP_MGR_CMD_GET_CONFIG_V20)
+    {
+        //V15
+        config->agps_setting.e911_gps_icon_enable = socket_get_byte(fd);
+        //V16
+        config->agps_setting.e911_open_gps = socket_get_byte(fd);
+        //V17
+        config->gnss_setting.a_gps_satellite_enable = socket_get_byte(fd);
+        config->gnss_setting.a_beidou_satellite_enable = socket_get_byte(fd);
+        config->gnss_setting.a_galileo_satellite_enable = socket_get_byte(fd);
+        //V18
+        config->up_setting.sha_version = socket_get_int(fd);
+        config->up_setting.preferred_2g3g_cell_age = socket_get_int(fd);
+        config->up_setting.ut1 = socket_get_byte(fd);
+        config->up_setting.no_sensitive_log = socket_get_byte(fd);
+        config->up_setting.tls_reuse_enable = socket_get_byte(fd);
+        config->up_setting.imsi_cache_enable = socket_get_byte(fd);
+        config->up_setting.supl_raw_data_enable = socket_get_byte(fd);
+        config->up_setting.tc10_enable = socket_get_byte(fd);
+        config->up_setting.tc10_use_apn = socket_get_byte(fd);
+        config->up_setting.tc10_use_fw_dns = socket_get_byte(fd);
+        config->up_setting.allow_ni_for_gps_off = socket_get_byte(fd);
+        config->up_setting.force_otdoa_assist_req = socket_get_byte(fd);
+        config->cp_setting.reject_non911_nilr_enable = socket_get_byte(fd);
+        config->cp_setting.cp_2g_disable = socket_get_byte(fd);
+        config->cp_setting.cp_3g_disable = socket_get_byte(fd);
+        config->cp_setting.cp_4g_disable = socket_get_byte(fd);
+        config->agps_setting.tc10_ignore_fw_config = socket_get_byte(fd);
+        config->agps_setting.lppe_hide_wifi_bt_status = socket_get_byte(fd);
+        //V19
+        config->agps_setting.lppe_network_location_disable = socket_get_byte(fd);
+        config->cp_setting.cp_lppe_enable = socket_get_byte(fd);
+        config->up_setting.up_lppe_enable = socket_get_byte(fd);
+        //V20
+        config->cp_setting.support_cp_lppe = socket_get_byte(fd);
+        config->gnss_setting.mnl_support_lppe = socket_get_byte(fd);
+    }
+
+    if(cmd >= APP_MGR_CMD_GET_CONFIG_V21)
+    {
+        config->agps_setting.agps_nvram_enable = socket_get_byte(fd);
+        config->agps_setting.lbs_log_enable = socket_get_byte(fd);
+        config->agps_setting.lppe_crowd_source_confident = socket_get_int(fd);
+
+        config->up_setting.esupl_apn_mode = socket_get_int(fd);
+        config->up_setting.tcp_keepalive = socket_get_int(fd);
+        config->up_setting.aosp_profile_enable = socket_get_byte(fd);
+        config->up_setting.bind_nlp_setting_to_supl = socket_get_byte(fd);
+    }
+
+    if(cmd >= APP_MGR_CMD_GET_CONFIG_V22)
+    {
+        config->agps_setting.ignore_si_for_e911 = socket_get_byte(fd);
+        config->cp_setting.cp_lppe_wlan_enable = socket_get_byte(fd);
+        config->cp_setting.cp_lppe_srn_enable = socket_get_byte(fd);
+        config->cp_setting.cp_lppe_sensor_enable = socket_get_byte(fd);
+        config->cp_setting.cp_lppe_dbh_enable = socket_get_byte(fd);
+
+        config->up_setting.up_lppe_wlan_enable = socket_get_byte(fd);
+        config->up_setting.up_lppe_srn_enable = socket_get_byte(fd);
+        config->up_setting.up_lppe_sensor_enable = socket_get_byte(fd);
+        config->up_setting.up_lppe_dbh_enable = socket_get_byte(fd);
+        config->up_setting.ip_version_prefer = socket_get_int(fd);
+        config->up_setting.up_lppe_in_2g3g_disable = socket_get_byte(fd);
+        config->up_setting.up_rrlp_in_4g_disable = socket_get_byte(fd);
+        config->up_setting.up_si_disable = socket_get_byte(fd);
+    }
+
+    if(cmd >= APP_MGR_CMD_GET_CONFIG_V23)
+    {
+        config->up_setting.use_ni_slp = socket_get_byte(fd);
+        config->agps_setting.use_tc10_config = socket_get_byte(fd);
+        config->agps_setting.lppe_def_nlp_enable = socket_get_byte(fd);
+    }
+
+    if(cmd >= APP_MGR_CMD_GET_CONFIG_V24)
+    {
+        config->agps_setting.emergency_ext_secs = socket_get_int(fd);
+        config->up_setting.aosp_pos_mode_enable = socket_get_byte(fd);
+        config->up_setting.privacy_override_mode = socket_get_int(fd);
+    }
+
+    config->valid = 1;
+    // read ACK
+    socket_get_byte(fd);
+    RLOGD("Socket read ACK sucess, close fd");
+    close(fd);
+    return 0;
+}
+
+int agps_get_total_status(agps_intf_agps_config *config)
+{
+    if (NULL == config)
+    {
+        RLOGD("agps_get_total_status incoming paramter error");
+    }
+    int res = 0;
+    res = get_template_agps_config(APP_MGR_CMD_GET_CONFIG_V24,config);
+    return res;
+}
+
+
+int lynq_agps_set_enabled(LYNQ_CONF_SWITCH agps_status)
+{
+    int ret = -1;
+    RLOGD("[LYNQ_GNSS]set agps:%d",agps_status);
+    ret = set_template_1(APP_MGR_CMD_SET_AGPS_ENABLE,agps_status);
+    if (ret != 0)
+    {   
+        RLOGD("set AGPS error ret = %d",ret);
+        return ret;
+    }
+    return ret;
+}
+
+int lynq_agps_get_enabled_status(int *status)
+{
+    int ret = 0;
+    if (NULL == status)
+    {
+        RLOGD("incoming paramter error");
+        return -1;
+    }
+
+    agps_intf_agps_config config;
+    memset(&config, 0, sizeof(config));
+    ret = agps_get_total_status(&config);
+    if (ret != 0)
+    {
+        RLOGD("agps get status fail");
+        return ret;
+    }
+    *status = config.agps_setting.agps_enable;
+    RLOGD("[LYNQ_GNSS]agps status:%d",*status);
+    return ret;
+}
\ No newline at end of file
diff --git a/IC_src/mtk/lib/liblynq-gnss/src/lynq_agps.h b/IC_src/mtk/lib/liblynq-gnss/src/lynq_agps.h
new file mode 100644
index 0000000..f3da3d3
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-gnss/src/lynq_agps.h
@@ -0,0 +1,393 @@
+#ifndef LYNQ_AGPS_H
+#define LYNQ_AGPS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*Copy for agps_interface.h*/
+#define agps_bool char
+
+#define MAX_BUFF_SIZE 8192
+#define SUPL_PROFILES_NUM 30
+
+#define AGPS_INTF_STRING_LEN 64
+#define AGPS_SUPL_ADDR_LEN 128
+#define MNL_MCC_STRING_LEN 16
+#define EXTERNAL_ADD_LEN 20
+#define MLC_NUMBER_LEN 20
+#define EPC_MOLR_LPP_PAYLOAD_LEN 300
+#define SUPL_PROFILES_NUM 30
+#define PROFILING_MESSAGE_LEN 64
+#define PROFILING_ELEMENT_NUM 20
+
+typedef enum {
+    // Command Enum APP -> AGPSD
+    APP_MGR_CMD_CODER_TEST = 0,
+    APP_MGR_CMD_VERSION = 1,
+
+    APP_MGR_CMD_GET_CONFIG = 100,    //AgpsConfig
+    APP_MGR_CMD_GET_OMA_CP_SUPL_PROFILE = 101,
+    APP_MGR_CMD_GET_SYSTEM_PROPERTY = 102,
+    APP_MGR_CMD_GET_AGPS_PROFILING = 103,
+    APP_MGR_CMD_GET_EMULATOR_MODE = 104,
+    APP_MGR_CMD_GET_CONFIG_V2 = 105,
+    APP_MGR_CMD_GET_CONFIG_V3 = 106,    // add cert_from_sdcard
+    APP_MGR_CMD_GET_CONFIG_V14 = 117,
+    APP_MGR_CMD_GET_CONFIG_V20 = 123,
+    APP_MGR_CMD_GET_CONFIG_V21 = 124,
+    APP_MGR_CMD_GET_CONFIG_V22 = 125,
+    APP_MGR_CMD_GET_CONFIG_V23 = 126,
+    APP_MGR_CMD_GET_CONFIG_V24 = 127,
+
+    APP_MGR_CMD_SET_AGPS_ENABLE = 200,
+    APP_MGR_CMD_SET_PROTOCOL,
+    APP_MGR_CMD_SET_CDMA_PREF,
+    APP_MGR_CMD_SET_UP_PREF_METHOD,
+    APP_MGR_CMD_SET_POS_TECHNOLOGY_MSA,
+    APP_MGR_CMD_SET_POS_TECHNOLOGY_MSB,
+    APP_MGR_CMD_SET_POS_TECHNOLOGY_ECID,
+    APP_MGR_CMD_SET_POS_TECHNOLOGY_OTDOA,
+    APP_MGR_CMD_SET_SUPL_VERSION,
+    APP_MGR_CMD_SET_SUPL_PROFILE,    //AgpsProfil
+    APP_MGR_CMD_SET_QOP = 210,            //AgpsQoP
+    APP_MGR_CMD_SET_MOLR_POS_METHDO,
+    APP_MGR_CMD_SET_EXTERNAL_ADDR,
+    APP_MGR_CMD_SET_MLC_NUMBER,
+    APP_MGR_CMD_SET_CP_AUTO_RESET,
+    APP_MGR_CMD_SET_ALLOW_NI,
+    APP_MGR_CMD_SET_ALLOW_ROAMING,
+    APP_MGR_CMD_SET_SUPL_2_FILE,
+    APP_MGR_CMD_SET_RESET_TO_DEFAULT,
+    APP_MGR_CMD_SET_OMA_CP_SUPL_PROFILE,
+    APP_MGR_CMD_SET_NI_REQ = 220,  //un-implemented for test
+    APP_MGR_CMD_SET_EPC_MOLR_PDU_ENABLE,
+    APP_MGR_CMD_SET_EPC_MOLR_PDU,
+    APP_MGR_CMD_SET_TLS_VERSION,
+    APP_MGR_CMD_SET_CA_ENABLE,
+    APP_MGR_CMD_SET_UDP_ENABLE,
+    APP_MGR_CMD_SET_LPP_ENABLE,
+    APP_MGR_CMD_SET_CERT_FROM_SDCARD_ENABLE,
+    APP_MGR_CMD_SET_AUTO_PROFILE_ENABLE,
+    APP_MGR_CMD_SET_UT2,
+    APP_MGR_CMD_SET_UT3 = 230,
+    APP_MGR_CMD_SET_SUPL_APN_ENABLE,
+    APP_MGR_CMD_SET_SYNC_TO_SLP,
+    APP_MGR_CMD_SET_UDP_ENABLE_V2,
+    APP_MGR_CMD_SET_AUTONOMOUS_ENABLE,
+    APP_MGR_CMD_SET_AFLT_ENABLE,
+    APP_MGR_CMD_SET_IMSI_ENABLE,
+    APP_MGR_CMD_SET_SIB8_16_ENABLE,
+    APP_MGR_CMD_SET_GPS_ENABLE,
+    APP_MGR_CMD_SET_GLONASS_ENABLE,
+    APP_MGR_CMD_SET_BEIDOU_ENABLE = 240,
+    APP_MGR_CMD_SET_GALILEO_ENABLE,
+    APP_MGR_CMD_SET_SUPL_SHA_VERSION,
+    APP_MGR_CMD_SET_SUPL_TLS_VERSION,
+    APP_MGR_CMD_SET_SUPL_VER_MINOR,
+    APP_MGR_CMD_SET_SUPL_VER_SER_IND,
+    APP_MGR_CMD_SET_A_GLONASS_ENABLE,
+    APP_MGR_CMD_SET_PDE_PROFILE,
+    APP_MGR_CMD_SET_E911_GPS_ICON_ENABLE,
+    APP_MGR_CMD_SET_E911_OPEN_GPS_ENABLE,
+    APP_MGR_CMD_SET_A_GPS_ENABLE = 250,
+    APP_MGR_CMD_SET_A_BEIDOU_ENABLE,
+    APP_MGR_CMD_SET_A_GALILEO_ENABLE,
+    APP_MGR_CMD_SET_PREF_2G3G_CELL_AGE,
+    APP_MGR_CMD_SET_UT1,
+    APP_MGR_CMD_SET_NO_SENSITIVE_LOG,
+    APP_MGR_CMD_SET_TLS_REUSE_ENABLE,
+    APP_MGR_CMD_SET_IMSI_CACHE_ENABLE,
+    APP_MGR_CMD_SET_SUPL_RAW_DATA_ENABLE,
+    APP_MGR_CMD_SET_TC10_ENABLE,
+    APP_MGR_CMD_SET_TC10_USE_APN = 260,
+    APP_MGR_CMD_SET_TC10_USE_FW_DNS,
+    APP_MGR_CMD_SET_ALLOW_NI_FOR_GPS_OFF,
+    APP_MGR_CMD_SET_FORCE_OTDOA_ASSIST_REQ,
+    APP_MGR_CMD_SET_REJECT_NON911_NILR_ENABLE,
+    APP_MGR_CMD_SET_CP_2G_DISABLE,
+    APP_MGR_CMD_SET_CP_3G_DISABLE,
+    APP_MGR_CMD_SET_CP_4G_DISABLE,
+    APP_MGR_CMD_SET_TC10_IGNORE_FW_CONFIG,
+    APP_MGR_CMD_SET_LPPE_HIDE_WIFI_BT_STATUS,
+    APP_MGR_CMD_SET_LPPE_NETWORK_LOCATION_DISABLE = 270,
+    APP_MGR_CMD_SET_LPPE_CP_ENABLE,
+    APP_MGR_CMD_SET_LPPE_UP_ENABLE,
+    APP_MGR_CMD_SET_VZW_DEBUG_SCREEN_ENABLE,
+    APP_MGR_CMD_SET_AOSP_PROFILE_ENABLE,
+    APP_MGR_CMD_SET_BIND_NLP_SETTING_TO_SUPL,
+    APP_MGR_CMD_SET_ESUPL_APN_MODE,
+    APP_MGR_CMD_SET_TCP_KEEPALIVE,
+    APP_MGR_CMD_SET_AGPS_NVRAM_ENABLE,
+    APP_MGR_CMD_SET_LBS_LOG_ENABLE,
+    APP_MGR_CMD_SET_LPPE_CROWD_SOURCE_CONFIDENT = 280,
+    APP_MGR_CMD_SET_IGNORE_SI_FOR_E911,
+    APP_MGR_CMD_SET_LPPE_CP_WLAN_ENABLE,
+    APP_MGR_CMD_SET_LPPE_CP_SRN_ENABLE,
+    APP_MGR_CMD_SET_LPPE_CP_SENSOR_ENABLE,
+    APP_MGR_CMD_SET_LPPE_CP_DBH_ENABLE,
+    APP_MGR_CMD_SET_LPPE_UP_WLAN_ENABLE,
+    APP_MGR_CMD_SET_LPPE_UP_SRN_ENABLE,
+    APP_MGR_CMD_SET_LPPE_UP_SENSOR_ENABLE,
+    APP_MGR_CMD_SET_LPPE_UP_DBH_ENABLE,
+    APP_MGR_CMD_SET_IP_VERSION_PREFER = 290,
+    APP_MGR_CMD_SET_UP_LPP_IN_2G3G_DISABLE,
+    APP_MGR_CMD_SET_UP_RRLP_IN_4G_DISABLE,
+    APP_MGR_CMD_UP_SI_DISABLE,
+
+    // To implement
+    APP_MGR_CMD_SET_USE_NI_SLP,
+    APP_MGR_CMD_SET_USE_TC10_CONFIG,
+    APP_MGR_CMD_SET_LPPE_DEF_NLP_ENABLE,
+    APP_MGR_CMD_SET_AOSP_POS_MODE_ENABLE,
+    APP_MGR_CMD_SET_PRIVACY_OVERRIDE_MODE,
+    APP_MGR_CMD_SET_EMERGENCY_EXT_SECS, // 299
+
+
+    APP_MGR_CMD_START_PERIODIC = 300,
+    APP_MGR_CMD_ABORT_PERIODIC,
+    APP_MGR_CMD_START_AREA_EVENT,
+    APP_MGR_CMD_ABORT_AREA_EVENT,
+
+    APP_MGR_CMD_START_TEST_CASE = 400,
+    APP_MGR_CMD_START_TEST_BUTTON,
+    APP_MGR_CMD_START_RESET_AGPSD,
+    APP_MGR_CMD_START_EMULATOR_MODE,
+
+
+    // To implement
+    APP_MGR_CMD_SET_TC10_SUPL_SSL_METHOD = 500,
+    APP_MGR_CMD_SET_TC10_AUTO_SUPL_VER_FOR_NI,
+    APP_MGR_CMD_SET_TC10_SUPL_VER_SKT_NI,
+    APP_MGR_CMD_SET_TC10_USE_APN_NI,
+    APP_MGR_CMD_SET_TC10_USE_APN_SI,
+    APP_MGR_CMD_SET_CP_PRIVACY_OVERRIDE,
+    APP_MGR_CMD_SET_SUPL_ADDR_NI,
+    APP_MGR_CMD_SET_RRLP_GOOGLE_SUPL,
+    APP_MGR_CMD_SET_SUPL2_CAP_EXT_DISABLE,
+    APP_MGR_CMD_SET_NI_STATISTIC_ENABLE,
+    APP_MGR_CMD_SET_UP_OPERATION_MODE,  // 510
+    APP_MGR_CMD_SET_GLONASS_MSA_ENABLE,
+    APP_MGR_CMD_SET_GLONASS_MSB_ENABLE,
+    APP_MGR_CMD_SET_BEIDOU_MSA_ENABLE,
+    APP_MGR_CMD_SET_BEIDOU_MSB_ENABLE,
+    APP_MGR_CMD_SET_GALILEO_MSA_ENABLE,
+    APP_MGR_CMD_SET_GALILEO_MSB_ENABLE,
+    APP_MGR_CMD_SET_TC10_AUTO_SUPL_VER_FOR_ENI,
+    APP_MGR_CMD_SET_TC10_CP_LPP_GUARD_TIME_SEC,
+    APP_MGR_CMD_SET_TC10_CP_CAPABILITY_VALID_ENABLE,
+    APP_MGR_CMD_SET_TC10_CP_CAPABILITY_ENABLE, // 520
+    APP_MGR_CMD_SET_IGNORE_EMERGENCY_EXT_SECS_FROM_FRAMEWORK,
+    APP_MGR_CMD_GET_AGPSD_VERSION,
+    APP_MGR_CMD_GET_IMSI,
+} app_mgr_cmd_enum;
+
+typedef enum {
+    AGPS_INTF_PDE_IP_TYPE_IPV4 = 0,
+    AGPS_INTF_PDE_IP_TYPE_IPV6 = 1,
+} agps_intf_pde_ip_type;
+
+typedef enum {
+    AGPS_INTF_CDMA_PREFERRED_WCDMA = 0,
+    AGPS_INTF_CDMA_PREFERRED_CDMA = 1,
+    AGPS_INTF_CDMA_PREFERRED_CDMA_FORCE = 2,
+} agps_intf_cdma_preferred;
+
+typedef enum {
+    AGPS_INTF_PREF_METHOD_MSA = 0,
+    AGPS_INTF_PREF_METHOD_MSB = 1,
+    AGPS_INTF_PREF_METHOD_NO_PREF = 2,
+} agps_intf_pref_method;
+
+typedef enum {
+    AGPS_INTF_AGPS_PROTOCOL_UP = 0,
+    AGPS_INTF_AGPS_PROTOCOL_CP = 1,
+} agps_intf_agps_protocol;
+
+typedef enum {
+    AGPS_INTF_SUPL_VERSION_1 = 1,
+    AGPS_INTF_SUPL_VERSION_2 = 2,
+} agps_intf_supl_version;
+
+typedef enum {
+    AGPS_INTF_TLS_VERSION_1_0 = 0,
+    AGPS_INTF_TLS_VERSION_1_1 = 1,
+    AGPS_INTF_TLS_VERSION_1_2 = 2,
+} agps_intf_tls_version;
+
+typedef enum {
+    AGPS_INTF_ESUPL_APN_EIMS_IMS = 0,
+    AGPS_INTF_ESUPL_APN_EIMS = 1,
+    AGPS_INTF_ESUPL_APN_IMS = 2,
+    AGPS_INTF_ESUPL_APN_AS_NORMAL = 3,
+} agps_intf_esupl_apn;
+
+typedef enum {
+    AGPS_INTF_MOLR_POS_METHOD_LOC_EST = 0,
+    AGPS_INTF_MOLR_POS_METHOD_ASSIST_DATA = 1,
+} agps_intf_molr_pos_method;
+
+typedef struct {
+    char name[AGPS_INTF_STRING_LEN];
+    char addr[AGPS_SUPL_ADDR_LEN];
+    int port;
+    agps_bool tls;
+    char mcc_mnc[MNL_MCC_STRING_LEN];
+    char app_id[AGPS_INTF_STRING_LEN];
+    char provider_id[AGPS_INTF_STRING_LEN];
+    char default_apn[AGPS_INTF_STRING_LEN];
+    char optional_apn[AGPS_INTF_STRING_LEN];
+    char optional_apn_2[AGPS_INTF_STRING_LEN];
+    char address_type[AGPS_INTF_STRING_LEN];
+} agps_intf_supl_profile;
+
+typedef struct {
+    char name[AGPS_INTF_STRING_LEN];
+    agps_bool mcp_enable;
+    char mcp_addr[AGPS_INTF_STRING_LEN];
+    int mcp_port;
+    agps_bool pde_addr_valid;
+    agps_intf_pde_ip_type pde_ip_type;    //0=IPV4 1=IPV6
+    char pde_addr[AGPS_INTF_STRING_LEN];
+    int pde_port;
+    agps_bool pde_url_valid;
+    char pde_url_addr[AGPS_INTF_STRING_LEN];
+} agps_intf_cdma_profile;
+
+typedef struct {
+    agps_bool agps_enable;
+    agps_intf_agps_protocol agps_protocol;
+    agps_bool gpevt;
+    agps_bool e911_gps_icon_enable;
+    agps_bool e911_open_gps;
+    agps_bool tc10_ignore_fw_config;
+    agps_bool lppe_hide_wifi_bt_status;
+    agps_bool lppe_network_location_disable;
+    agps_bool agps_nvram_enable;
+    agps_bool lbs_log_enable;
+    int lppe_crowd_source_confident;
+    agps_bool ignore_si_for_e911; // North America operator 'V' asks us to ignore SI triggered by GMS
+    agps_bool use_tc10_config;
+    agps_bool lppe_def_nlp_enable;
+    int emergency_ext_secs;
+} agps_intf_agps_setting;
+
+typedef struct {
+    agps_intf_molr_pos_method molr_pos_method;
+    agps_bool external_addr_enable;
+    char external_addr[EXTERNAL_ADD_LEN];
+    agps_bool mlc_number_enable;
+    char mlc_number[MLC_NUMBER_LEN];
+    agps_bool cp_auto_reset;
+    agps_bool epc_molr_lpp_payload_enable;
+    int epc_molr_lpp_payload_len;
+    char epc_molr_lpp_payload[EPC_MOLR_LPP_PAYLOAD_LEN];
+    agps_bool cp_lppe_enable;
+    agps_bool support_cp_lppe;
+    agps_bool reject_non911_nilr_enable;
+    agps_bool cp_2g_disable;
+    agps_bool cp_3g_disable;
+    agps_bool cp_4g_disable;
+    agps_bool cp_lppe_wlan_enable;
+    agps_bool cp_lppe_srn_enable;
+    agps_bool cp_lppe_sensor_enable;
+    agps_bool cp_lppe_dbh_enable;
+} agps_intf_cp_setting;
+
+typedef struct {
+    agps_bool ca_enable;
+    agps_bool ni_request;
+    agps_bool roaming;
+    agps_intf_cdma_preferred cdma_preferred;
+    agps_intf_pref_method pref_method;
+    agps_intf_supl_version supl_version;
+    agps_intf_tls_version tls_version;
+    agps_bool supl_log;
+    agps_bool msa_enable;
+    agps_bool msb_enable;
+    agps_bool ecid_enable;
+    agps_bool otdoa_enable;
+    int qop_hacc;
+    int qop_vacc;
+    int qop_loc_age;
+    int qop_delay;
+    agps_bool lpp_enable;
+    agps_bool cert_from_sdcard;
+    agps_bool auto_profile_enable;
+    char ut2;
+    char ut3;
+    agps_bool apn_enable;
+    agps_bool sync_to_slp;
+    agps_bool udp_enable;
+    agps_bool autonomous_enable;
+    agps_bool aflt_enable;
+    agps_bool imsi_enable;
+    char supl_ver_minor;
+    char supl_ver_ser_ind;
+    int sha_version;    // 0: SHA1 for SUPL1.0 and SHA256 for SUPL2.0, 1: SHA1 for SUPL1.0 and SUPL2.0, 2: SHA256 for SUPL1.0 and SUPL2.0
+    int preferred_2g3g_cell_age;
+    char ut1;
+    agps_bool no_sensitive_log;
+    agps_bool tls_reuse_enable;
+    agps_bool imsi_cache_enable;
+    agps_bool supl_raw_data_enable;
+    agps_bool tc10_enable;
+    agps_bool tc10_use_apn;
+    agps_bool tc10_use_fw_dns;
+    agps_bool allow_ni_for_gps_off;
+    agps_bool force_otdoa_assist_req;
+    agps_bool up_lppe_enable;
+    agps_intf_esupl_apn esupl_apn_mode;
+    int tcp_keepalive;
+    agps_bool aosp_profile_enable;
+    agps_bool bind_nlp_setting_to_supl;
+    agps_bool up_lppe_wlan_enable;
+    agps_bool up_lppe_srn_enable;
+    agps_bool up_lppe_sensor_enable;
+    agps_bool up_lppe_dbh_enable;
+    int ip_version_prefer;            //0=IPv6 prefer   1=IPv4 prefer
+    agps_bool up_lppe_in_2g3g_disable; // For ATT SUPL server
+    agps_bool up_rrlp_in_4g_disable;  // For ATT SUPL server
+    agps_bool up_si_disable;          // For Sprint
+    agps_bool use_ni_slp;             // tc10 (ALPS04423530)
+    agps_bool aosp_pos_mode_enable;
+    int privacy_override_mode;
+} agps_intf_up_setting;
+
+typedef struct {
+    agps_bool sib8_sib16_enable;
+    agps_bool gps_satellite_enable;
+    agps_bool glonass_satellite_enable;
+    agps_bool beidou_satellite_enable;
+    agps_bool galileo_satellite_enable;
+    agps_bool a_glonass_satellite_enable;
+
+    agps_bool gps_satellite_support;
+    agps_bool glonass_satellite_support;
+    agps_bool beidou_satellite_support;
+    agps_bool galileo_satellite_support;
+
+    agps_bool a_gps_satellite_enable;
+    agps_bool a_beidou_satellite_enable;
+    agps_bool a_galileo_satellite_enable;
+
+    agps_bool mnl_support_lppe;
+} agps_intf_gnss_setting;
+
+typedef struct {
+    int supl_profiles_num;
+    agps_intf_supl_profile supl_profiles[SUPL_PROFILES_NUM];
+    agps_intf_supl_profile cur_supl_profile;
+    agps_intf_cdma_profile cdma_profile;
+    agps_intf_agps_setting agps_setting;
+    agps_intf_cp_setting cp_setting;
+    agps_intf_up_setting up_setting;
+    agps_intf_gnss_setting gnss_setting;
+    agps_bool valid;
+} agps_intf_agps_config;
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
\ No newline at end of file
diff --git a/IC_src/mtk/lib/liblynq-gnss/src/lynq_callback.c b/IC_src/mtk/lib/liblynq-gnss/src/lynq_callback.c
new file mode 100755
index 0000000..b8a402f
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-gnss/src/lynq_callback.c
@@ -0,0 +1,209 @@
+#include<pthread.h>

+#include<stdio.h>

+#include<unistd.h>

+#include<errno.h>

+#include<string.h>

+

+#include"lynq_gnsshal.h"

+#include"mtk_lbs_utility.h"

+#include"lynq_gnss.h"

+

+extern lynq_gnss_cb* lynq_callbacks;

+extern lynq_raw_gnss_cbs *lynq_meas_callbacks;

+

+void lynq_gps_location_callback(GpsLocation_ext* location)

+{   

+    GpsLocation_ext* loc = (GpsLocation_ext *)location;

+    lynq_GpsLocation_ext lynq_loc;

+   //lynq_loc.legacyLocation.size = loc->legacyLocation.size;

+    lynq_loc.legacyLocation.size = sizeof(lynq_GpsLocation_ext);

+    lynq_loc.legacyLocation.flags = loc->legacyLocation.flags;

+    lynq_loc.legacyLocation.latitude = loc->legacyLocation.latitude;

+    lynq_loc.legacyLocation.longitude = loc->legacyLocation.longitude;

+    lynq_loc.legacyLocation.altitude = loc->legacyLocation.altitude;

+    lynq_loc.legacyLocation.speed = loc->legacyLocation.speed;

+    lynq_loc.legacyLocation.bearing = loc->legacyLocation.bearing;

+    lynq_loc.legacyLocation.accuracy = loc->legacyLocation.accuracy;

+    lynq_loc.legacyLocation.timestamp = loc->legacyLocation.timestamp;

+    lynq_loc.horizontalAccuracyMeters = loc->horizontalAccuracyMeters;

+    lynq_loc.verticalAccuracyMeters = loc->speedAccuracyMetersPerSecond;

+    lynq_loc.bearingAccuracyDegrees = loc->bearingAccuracyDegrees;

+    lynq_callbacks->lynq_location_cb(&lynq_loc);

+}

+

+void lynq_gps_status_callback(GpsStatus* status)

+{

+    lynq_callbacks->lynq_status_cb(status);

+}

+

+void lynq_gps_sv_status_callback(GpsSvStatus* sv_info)

+{

+

+}

+

+void lynq_gps_nmea_callback(GpsUtcTime timestamp, const char* nmea, int length)

+{

+    lynq_callbacks->lynq_nmea_cb(timestamp,nmea,length);

+

+}

+

+void lynq_gps_set_capabilities(uint32_t capabilities)

+{

+

+}

+

+void lynq_gps_acquire_wakelock(void)

+{

+

+}

+

+void lynq_gps_release_wakelock(void)

+{

+

+}

+

+void lynq_gps_request_utc_time(void)

+{

+

+}

+

+void lynq_set_system_info_cb(const GnssSystemInfo* info)

+{

+

+}

+

+void lynq_gnss_sv_status_cb(GnssSvStatus_ext* sv_info)

+{

+

+}

+

+pthread_t lynq_gps_create_thread(const char* name, void (*start)(void *), void* arg)

+{

+    lynq_callbacks->lynq_create_thread_cb(name,(void *(*)(void *))start,arg);

+}

+

+void lynq_gnss_set_name_cb(const char* name, int length)

+{

+

+}

+

+void lynq_gnss_request_location_cb(bool independentFromGnss, bool isUserEmergency)

+{

+

+}

+

+void lynq_agnss_location_callback(GpsLocation_ext* location) {

+

+}

+

+

+GpsCallbacks_ext lynq_gps_callbacks_gnss = {

+    .size = sizeof(GpsCallbacks_ext),

+    .location_cb = lynq_gps_location_callback,

+    .status_cb = lynq_gps_status_callback,

+    .sv_status_cb = lynq_gps_sv_status_callback,

+    .nmea_cb = lynq_gps_nmea_callback,

+    .set_capabilities_cb = lynq_gps_set_capabilities,

+    .acquire_wakelock_cb = lynq_gps_acquire_wakelock,

+    .release_wakelock_cb = lynq_gps_release_wakelock,

+    .create_thread_cb = lynq_gps_create_thread,

+    .request_utc_time_cb = lynq_gps_request_utc_time,

+    .set_system_info_cb = lynq_set_system_info_cb,

+    .gnss_sv_status_cb = lynq_gnss_sv_status_cb,

+    .set_name_cb = lynq_gnss_set_name_cb,

+    .request_location_cb = lynq_gnss_request_location_cb,

+    .agps_location_cb = lynq_agnss_location_callback,

+};

+

+GpsCallbacks_ext* lynq__get_gps_callbacks(void)

+{

+    return &lynq_gps_callbacks_gnss;

+}

+

+void lynq_measurement_callback(GpsData *data)

+{

+

+}

+

+void lynq_gnss_measurement_callback(GnssData_ext* data) 

+{   

+    lynq_meas_callbacks->lynq_measurement_callback(data);

+    return;

+}

+

+GpsMeasurementCallbacks_ext lynq_test_raw_callbacks = {

+    .size = sizeof(GpsMeasurementCallbacks_ext),

+    .measurement_callback = lynq_measurement_callback,

+    .gnss_measurement_callback = lynq_gnss_measurement_callback,

+};

+

+GpsMeasurementCallbacks_ext* lynq_gnss_get_raw_callbacks(void)

+{

+    return &lynq_test_raw_callbacks;

+}

+

+

+void lynq_at_gps_location_callback(lynq_GpsLocation_ext* location)

+{

+

+}

+

+void lynq_at_gps_status_callback(GpsStatus* status)

+{

+

+}

+

+#define NMEA_ACC "ACCURACY"

+#define NMEA_GSA "GSA"

+#define NMEA_RMC "RMC"

+#define NMEA_GGA "GGA"

+#define NMEA_VTG "VTG"

+#define NMEA_GSV "GSV"

+

+void lynq_at_gps_nmea_callback(GpsUtcTime timestamp, const char* nmea, int length)

+{

+    if (at_gpsnmea_status == 1)

+    {

+        if(strncmp(nmea+3,NMEA_GSA,strlen(NMEA_GSA))==0 || strncmp(nmea+3,NMEA_RMC,strlen(NMEA_RMC)) == 0 || \

+            strncmp(nmea+3,NMEA_GGA,strlen(NMEA_GGA)) == 0 || strncmp(nmea+3,NMEA_VTG,strlen(NMEA_VTG)) == 0|| \

+            strncmp(nmea+3,NMEA_GSV,strlen(NMEA_GSV)) == 0)

+            {

+                atsvc_gnss_outcb(nmea,strlen(nmea),1);

+            }

+    }

+}

+

+

+

+pthread_t lynq_at_gps_create_thread(const char* name, void (*start)(void *), void* arg)

+{

+    pthread_t at_ntid = 0;

+    int ret = 0;

+

+    ret = pthread_create(&at_ntid, NULL, (void *(*)(void *))start, arg);

+

+    if(ret != 0)

+    {

+        printf("thread %s create fail(%s)!\r\n", name, strerror(errno));

+        at_ntid = 0;

+    }

+    else

+    {

+        printf("tread %s create success!\r\n", name);

+    }

+

+    return at_ntid;

+}

+

+lynq_gnss_cb lynq_at_gnss_callbacks = {

+    .size = sizeof(lynq_gnss_cb),

+    .lynq_location_cb =lynq_at_gps_location_callback,

+    .lynq_status_cb = lynq_at_gps_status_callback,

+    .lynq_nmea_cb = lynq_at_gps_nmea_callback,

+    .lynq_create_thread_cb = lynq_at_gps_create_thread,

+};

+

+lynq_gnss_cb* lynq_at_get__gnss_callbacks(void)

+{

+    return &lynq_at_gnss_callbacks;

+}

diff --git a/IC_src/mtk/lib/liblynq-gnss/src/lynq_gnss.c b/IC_src/mtk/lib/liblynq-gnss/src/lynq_gnss.c
new file mode 100755
index 0000000..a812738
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-gnss/src/lynq_gnss.c
@@ -0,0 +1,620 @@
+#include <stdarg.h>

+#include <stdio.h>

+#include <stdarg.h>

+#include <unistd.h>

+#include <sys/time.h>

+#include <time.h>

+#include <signal.h>

+#include <string.h>

+#include <errno.h>

+#include <sys/socket.h>

+#include <sys/un.h>

+#include <arpa/inet.h>

+#include <dlfcn.h>

+#include <stdlib.h>

+#include <semaphore.h>

+#include <pthread.h>

+#include <log/log.h>

+#include <stdlib.h>

+

+#include "lynq_gnss.h"

+#include "gpshal.h"

+#include "hal2mnl_interface.h"

+#include "lynq_gnsshal.h"

+#include "mtk_lbs_utility.h"

+#include "lynq_prop.h"

+#include "mnldinf_utility.h"

+

+#define LOG_TAG "LYNQ_GNSS"

+

+

+lynq_gnss_cb* lynq_callbacks =NULL ;

+lynq_raw_gnss_cbs* lynq_meas_callbacks = NULL;

+

+GpsCallbacks_ext* turn_cbs = NULL;

+GpsMeasurementCallbacks_ext* raw_cbs = NULL;

+

+lynq_gnss_cb* lynq_at_callbacks = NULL ;

+/**

+ * @brief mark gnss initialization state

+ * 0: deinit state

+ * 1: init state

+ */

+static int g_lynq_gnss_init_flag = 0;

+

+static int g_lynq_gnss_calback_flag = 0;

+

+/**

+ * @brief mark gnss raw meas state

+ * 0: deinit state

+ * 1: init state

+ */

+static int g_lynq_gnss_raw_meas_flag = 0;

+

+int lynq_gnss_init(void)

+{

+    if (g_lynq_gnss_init_flag == 1)

+    {

+        RLOGD("init twice is not allowed");

+        return -1;

+    }

+    if (g_lynq_gnss_calback_flag == 0)

+    {

+        RLOGD("Plz Reg callback before init");

+        return -1;

+    }

+    g_lynq_gnss_init_flag = 1;

+    gpshal_set_gps_state_intent(GPSHAL_STATE_INIT);

+    gpshal2mnl_gps_init();

+    g_gpshal_ctx.mnl_retry_timer = mnldinf_init_timer(gpshal_mnl_retry_routine);

+    return 0;

+}

+

+int lynq_gnss_callback_reg(lynq_gnss_cb* callbacks)

+{   

+    int i=0;

+    if (NULL == callbacks)

+    {

+        RLOGD("illegal callbacks!!!");

+        return -1;

+    }

+    mnldinf_wake_lock_init();

+    lynq_callbacks = callbacks;

+    turn_cbs = lynq__get_gps_callbacks();

+    if(turn_cbs == NULL)

+    {

+        RLOGD("callbacks error");

+        return -1;

+    }

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

+    {

+        RLOGD("The callback_gps_state:%s",gpshal_state_to_string(g_gpshal_ctx.gps_state));

+        if(gpshal_gpscbs_save(turn_cbs) != 0)

+        {

+            RLOGD("For cbs save error\r\n");

+        }

+        RLOGD("The callback_gps_state:%s",gpshal_state_to_string(g_gpshal_ctx.gps_state));

+        if(g_gpshal_ctx.gps_state != GPSHAL_STATE_UNKNOWN)

+        {

+            break;

+        }

+        sleep(1);

+    }

+    if(i>=5)

+    {

+        RLOGD("For cbs save error2\r\n");

+        return -1;

+    }

+    g_lynq_gnss_calback_flag = 1;

+    return 0;

+}

+

+int lynq_gnss_deinit(void)

+{

+    if (g_lynq_gnss_init_flag == 0)

+    {

+        RLOGD("deinit twice is not allowed");

+        return -1;

+    }

+    timer_t retry_timer;

+    gpshal_set_gps_state_intent(GPSHAL_STATE_CLEANUP);

+    gpshal2mnl_gps_cleanup();

+    RLOGD("WAKE_LOCK_Begin");

+    mnldinf_wake_lock_deinit();

+    RLOGD("WAKE_LOCK_END");

+    retry_timer = g_gpshal_ctx.mnl_retry_timer;

+    g_gpshal_ctx.mnl_retry_timer = INVALID_TIMERID;

+    RLOGD("timer deinit start");

+    if(mnldinf_deinit_timer(retry_timer) == -1) {

+        RLOGD("retry_timer deinit fail:%s", strerror(errno));

+        return -1;

+    }

+    RLOGD("timer de init end");

+    g_lynq_gnss_calback_flag = 0;

+    g_lynq_gnss_init_flag = 0;

+    return 0;

+}

+

+int lynq_gnss_start(void)

+{

+    if (g_lynq_gnss_init_flag == 0)

+    {

+        RLOGD("start is not allowed");

+        return -1;

+    }

+    //memset(&lynq_debug_data, 0, sizeof(DebugData));

+    gpshal_set_gps_state_intent(GPSHAL_STATE_START);

+    gpshal2mnl_gps_start();

+    return 0;

+}

+

+int lynq_gnss_stop(void)

+{

+    if (g_lynq_gnss_init_flag == 0)

+    {

+        RLOGD("stop is not allowed");

+        return -1;

+    }

+    gpshal_set_gps_state_intent(GPSHAL_STATE_STOP);

+    gpshal2mnl_gps_stop();

+    return 0;

+}

+

+int lynq_gnss_inject_time(GpsUtcTime time, int64_t timeReference, int uncertainty)

+{

+    if (hal2mnl_gps_inject_time(time, timeReference, uncertainty) == -1) {

+        RLOGD("hal2mnl_gps_inject_time failed because of safe_sendto fail ,strerror:%s \n", strerror(errno));

+        return -1;

+    }

+    return 0;

+}

+

+int lynq_gnss_inject_location(

+        double latitude,

+        double longitude,

+        float  accuracy) {

+    if (hal2mnl_gps_inject_location(latitude, longitude, accuracy) == -1) {

+        RLOGD("hal2mnl_gps_inject_location failed because of safe_sendto fail ,strerror:%s \n", strerror(errno));

+        return -1;

+    }

+    return 0;

+}

+

+int lynq_gnss_delete_aiding_data(GpsAidingData flags) {

+    if (hal2mnl_gps_delete_aiding_data(flags) == -1) {

+        RLOGD("hal2mnl_gps_delete_aiding_data failed because of safe_sendto fail ,strerror:%s \n", strerror(errno));

+        return -1;

+    }

+    return 0;

+}

+

+int lynq_gnss_inject_fused_location(

+        double latitude,

+        double longitude,

+        float  accuracy) {

+    // TODO:  hal2mnl_gps_inject_fused_location(latitude, longitude, accuracy);

+    UNUSED(latitude);

+    UNUSED(longitude);

+    UNUSED(accuracy);

+    return 0;  // 0:ok,   non-zero: error; but GPS JNI will ignore it

+}

+/*get extension*/

+int lynq_gnss_start_raw_meas_mode(lynq_raw_gnss_cbs* raw_gnss_cbs)

+{

+    if (g_lynq_gnss_raw_meas_flag == 1)

+    {

+        RLOGD("start twice is not allowed");

+        return -1;

+    }

+    g_lynq_gnss_raw_meas_flag = 1;

+

+    lynq_meas_callbacks = raw_gnss_cbs;

+    raw_cbs = lynq_gnss_get_raw_callbacks();

+    if (NULL == raw_cbs)

+    {

+        RLOGD("callbacks error");

+        return -2;

+    }

+    g_gpshal_ctx.meas_cbs = raw_cbs;

+    RLOGD("liblynq-gnss:Test for adress %p",g_gpshal_ctx.meas_cbs);

+    int ret = hal2mnl_set_gps_measurement(true, true);

+    return (ret > 0)?

+            GPS_GEOFENCE_OPERATION_SUCCESS :

+            GPS_GEOFENCE_ERROR_GENERIC;

+}

+

+int lynq_gnss_stop_raw_meas_mode()

+{

+    if (g_lynq_gnss_raw_meas_flag == 0)

+    {

+        RLOGD("must start raw meas first");

+        return -1;

+    }

+    if (hal2mnl_set_gps_measurement(false, false) == -1) {

+        LOGE("hal2mnl_set_gps_measurement failed because of safe_sendto fail ,strerror:%s \n", strerror(errno));

+    }

+    RLOGD("typethree test: stop gps raw measurement");

+    return 0;

+}

+

+int lynq_gnss_set_start_mode(LYNQ_GNSS_MODE_CONFIGURATION start_mode)

+{

+    int ret = 0;

+    switch (start_mode)

+    {

+        case LYNQ_MODE_GPS_GLONASS:

+            mnld_write_cfg(LYNQ_GNSS_MODE , LYNQ_CONF_GPS_GLONASS);

+            break;

+

+        case LYNQ_MODE_GPS_BEIDOU:

+            mnld_write_cfg(LYNQ_GNSS_MODE , LYNQ_CONF_GPS_BEIDOU);

+            break;

+

+        case LYNQ_MODE_GPS_GLONASS_BEIDOU:

+            mnld_write_cfg(LYNQ_GNSS_MODE , LYNQ_CONF_GPS_GLONASS_BEIDOU);

+            break;

+

+        case LYNQ_MODE_GPS:

+            mnld_write_cfg(LYNQ_GNSS_MODE , LYNQ_CONF_GPS);

+            break;

+

+        case LYNQ_MODE_BEIDOU:

+            mnld_write_cfg(LYNQ_GNSS_MODE , LYNQ_CONF_BEIDOU);

+            break;

+

+        case LYNQ_MODE_GLONASS:

+            mnld_write_cfg(LYNQ_GNSS_MODE , LYNQ_CONF_GLONASS);

+            break;

+

+        case LYNQ_MODE_GPS_GLONASS_BEIDOU_GALILEO:

+            mnld_write_cfg(LYNQ_GNSS_MODE , LYNQ_CONF_GPS_GLONASS_BEIDOU_GALILEO);

+

+            break;

+

+        case LYNQ_MODE_GPS_GALILEO:

+            mnld_write_cfg(LYNQ_GNSS_MODE , LYNQ_CONF_GPS_GALILEO);

+

+            break;  

+

+        case LYNQ_MODE_GPS_GLONASS_GALILEO:

+            mnld_write_cfg(LYNQ_GNSS_MODE , LYNQ_CONF_GPS_GLONASS_GALILEO);

+

+            break;

+

+        case LYNQ_MODE_GPS_GALILEO_ONLY:

+            mnld_write_cfg(LYNQ_GNSS_MODE , LYNQ_CONF_GPS_GALILEO_ONLY);

+

+            break;

+

+        case LYNQ_MODE_GPS_GLONASS_BEIDOU_GALILEO_NAVIC:

+            mnld_write_cfg(LYNQ_GNSS_MODE , LYNQ_CONF_GPS_GLONASS_BEIDOU_GALILEO_NAVIC);

+

+            break; 

+        default:

+            RLOGD("unknown type of GNSS MODE");

+            ret = -1;

+            break;

+    }

+    

+    return ret;

+}

+

+int lynq_gnss_debug_switch(LYNQ_CONF_SWITCH switch_op)

+{

+    int ret = 0;

+    switch (switch_op)

+    {

+        case LYNQ_SWITCH_DISABLE:

+            mnld_write_cfg(LYNQ_DEBUG_STATUS,LYNQ_CONFIG_DISABLE);

+            break;

+        case LYNQ_SWITCH_ENABLE:

+            mnld_write_cfg(LYNQ_DEBUG_STATUS,LYNQ_CONFIG_ENABLE);

+            break;

+        default:

+            RLOGD("unknown op");

+            ret = -1;

+            break;

+    }

+    return ret;

+}

+

+int lynq_gnss_epo_switch(LYNQ_CONF_SWITCH switch_op)

+{

+    int ret = 0;

+    switch (switch_op)

+    {

+        case LYNQ_SWITCH_DISABLE:

+            mnld_write_cfg(LYNQ_EPO_STATUS,LYNQ_CONFIG_DISABLE);

+            break;

+        case LYNQ_SWITCH_ENABLE:

+            mnld_write_cfg(LYNQ_EPO_STATUS,LYNQ_CONFIG_ENABLE);

+            break;

+        default:

+            RLOGD("unknown op");

+            ret = -1;

+            break;

+    }

+    return ret;

+}

+

+int lynq_gnss_output_frequency_set(int frequency)

+{

+    int frequency_turn = frequency;

+

+    int freq_num = 1000/frequency_turn;

+    char freq[LYNQ_MAX_FRREQUENCY];

+    sprintf(freq, "%d", freq_num);

+    mnld_write_cfg(LYNQ_OUTPUT_FREQUENCY,freq);

+    return 0;

+}

+

+lynq_atsvc_outcb atsvc_gnss_outcb;

+void atsvc_incb_entity(const char *input,const int length);

+int lynq_at_cgps(int at_type,char *at_paramter);

+int lynq_at_cgpsnmea(int at_type,char *at_paramter);

+

+int at_gps_status = 0;

+int at_gpsnmea_status = 0;

+

+int strUpper(char * str)

+{

+    int i=0;

+    while(1)

+    {

+        if(str[i]=='\0')

+        {

+            break;

+        }

+        if(str[i]>='a'&&str[i]<='z')

+        {

+             str[i]=str[i]-32;

+        }

+        i++;

+    }

+    return 0;      

+}

+

+int gnss_at_cmd_parse(char *cmd,char *parse_cmd[],int* at_type)

+{

+    if (NULL == cmd || NULL == parse_cmd || NULL == at_type)

+    {

+        return -1;

+    }

+    int ret = 0;

+    int at_type_jug = 0;

+    int cmd_size;

+    char cmd_buf[128] = {0};

+    char buffer1[128] = {0};

+    char buffer2[128] = {0};

+    bzero(cmd_buf,128);

+    bzero(buffer1,128);

+    bzero(buffer2,128);

+    cmd_size = strlen(cmd);

+    memcpy(cmd_buf,cmd,cmd_size);

+    strUpper(cmd_buf);

+    ret = sscanf(cmd_buf, "%[^=]=%[^=]", buffer1,buffer2);

+    if (ret == 1)

+    {

+        *at_type = 1;

+        sscanf(buffer1, "%[^?]", buffer2);

+        strcpy(parse_cmd[0],buffer2);

+        return 0;

+    }

+    else if (ret == 2)

+    {

+        at_type_jug = strcmp(buffer2,"?");

+        RLOGD("at_type_jug :%d",at_type_jug);

+        if (at_type_jug == 0)

+        {

+            *at_type = 0;

+            strcpy(parse_cmd[0],buffer1);

+            return 0;

+        }

+        else 

+        {

+            *at_type = 2;

+            RLOGD("Buffertest1:buffer1 :%s  buffer2 :%s",buffer1,buffer2);

+            strcpy(parse_cmd[0],buffer1);

+            strcpy(parse_cmd[1],buffer2);

+            RLOGD("buffer1 :%s  buffer2 :%s",parse_cmd[0],parse_cmd[1]);

+            return 0;

+        }

+    }

+    else

+    {

+        RLOGD("unknown paramters");

+        return -1;

+    }

+}

+

+lynq_atsvc_incb lynq_register_gnss(lynq_atsvc_outcb out_cb)

+{

+    char reg_return[100] = {0};

+    if(NULL == out_cb)

+    {

+        RLOGD("out cb is null");

+        return NULL;

+    }

+    atsvc_gnss_outcb=out_cb;

+    memcpy(reg_return,"gnss register success\r\n",24);

+    atsvc_gnss_outcb(reg_return,24,0);

+    return atsvc_incb_entity;

+}

+

+

+void atsvc_incb_entity(const char *input,const int length)

+{

+    int res = 0;

+    int income_at_type = 0;

+    char at_cmd[512]={0};

+    char gnss_at_cmd[100] = {0};

+    char *parse_atcmd[128]; //argv[0]:at cmd,argv[2]:at paramter

+    if(NULL == input)

+    {

+        RLOGD("input is null");

+        memcpy(gnss_at_cmd,"+CME ERROR: 100\r\n",strlen("+CME ERROR: 100\r\n"));

+        atsvc_gnss_outcb(gnss_at_cmd,strlen("+CME ERROR: 100\r\n"),0);

+        return -1;

+    }

+    if (strlen(input) >= 128)

+    {

+        RLOGD("input size more than 128");

+        memcpy(gnss_at_cmd,"+CME ERROR: 100\r\n",strlen("+CME ERROR: 100\r\n"));

+        atsvc_gnss_outcb(gnss_at_cmd,strlen("+CME ERROR: 100\r\n"),0);

+        return -1;

+    }

+    bzero(at_cmd,512);

+    memcpy(at_cmd,input,strlen(input));

+    res = gnss_at_cmd_parse(at_cmd,parse_atcmd,&income_at_type);

+    if (res != 0)

+    {

+        RLOGD("parse at cmd error");

+        return -1;

+    }

+

+    if (!strcmp(parse_atcmd[0], "AT+CGPS"))

+    {

+        res = lynq_at_cgps(income_at_type,parse_atcmd[1]);

+        if (res != 0)

+        {

+            RLOGD("cgps unknown error");

+        }

+    }

+    else if (!strcmp(parse_atcmd[0], "AT+CGPSNMEA"))

+    {

+        lynq_at_cgpsnmea(income_at_type,parse_atcmd[1]);

+    }

+    else 

+    {

+        memcpy(gnss_at_cmd,"+CME ERROR: 100\r\n",strlen("+CME ERROR: 100\r\n"));

+    }

+    memcpy(gnss_at_cmd,"OK\r\n",4);

+    atsvc_gnss_outcb(gnss_at_cmd,4,0);

+}

+

+

+int lynq_at_cgps(int at_type,char *at_paramter)

+{

+    int ret = 0;

+    char cgps_at_res[512]={};

+

+    if (at_type == LYNQ_ATCMD_TEST)

+    {

+        bzero(cgps_at_res,512);

+        memcpy(cgps_at_res,"+CGPS:(0,1)\r\n",strlen("+CGPS:(0,1)"));

+        atsvc_gnss_outcb(cgps_at_res,strlen("+CGPS:(0,1)\r\n"),0);

+        return 0;

+    }

+    else if(at_type == LYNQ_ATCMD_READ)

+    {

+        bzero(cgps_at_res,512);

+        sprintf(cgps_at_res,"+CGPS:<%d>",at_gps_status);

+        atsvc_gnss_outcb(cgps_at_res,strlen(cgps_at_res),0);

+        return 0;

+    }

+    else if(at_type == LYNQ_ATCMD_WRITE)

+    {

+        if (at_gps_status != atoi(at_paramter))

+        {

+            at_gps_status = atoi(at_paramter);

+        }

+        else

+        {

+            bzero(cgps_at_res,512);

+            memcpy(cgps_at_res,"+CGPS ERROR: same status\r\n",strlen("+CGPS ERROR: same status\r\n"));

+            atsvc_gnss_outcb(cgps_at_res,strlen(cgps_at_res),0);

+            return -1;

+        }

+        if (at_gps_status == 0)

+        {

+            ret = lynq_gnss_stop();

+            if (ret != 0)

+            {

+                RLOGD("lynq gnss stop fail");

+                return -1;

+            }

+            ret = lynq_gnss_deinit();

+            if (ret != 0)

+            {

+                RLOGD("lynq gnss deinit fail");

+                return -1;

+            }

+            bzero(cgps_at_res,512);

+            memcpy(cgps_at_res,"+CGPS OK\r\n",strlen("+CGPS OK\r\n"));

+            atsvc_gnss_outcb(cgps_at_res,strlen(cgps_at_res),0);

+        }

+        else if(at_gps_status == 1)

+        {

+            lynq_at_callbacks = lynq_at_get__gnss_callbacks();

+            ret = lynq_gnss_callback_reg(lynq_at_callbacks);

+            if (ret != 0)

+            {

+                RLOGD("lynq gnss callback reg fail");

+                return -1;

+            }

+            ret = lynq_gnss_init();

+            if (ret != 0)

+            {

+                RLOGD("lynq gnss init fail");

+                return -1;

+            }

+            ret = lynq_gnss_start();

+            if (ret != 0)

+            {

+                RLOGD("lynq gnss init fail");

+                return -1;

+            }

+            bzero(cgps_at_res,512);

+            memcpy(cgps_at_res,"+CGPS OK\r\n",strlen("+CGPS OK\r\n"));

+            atsvc_gnss_outcb(cgps_at_res,strlen(cgps_at_res),0);

+        }

+        else

+        {

+            RLOGD("unknown at paramters");

+            bzero(cgps_at_res,512);

+            memcpy(cgps_at_res,"+CGPS ERROR: 100\r\n",strlen("+CGPS ERROR: 100\r\n"));

+            atsvc_gnss_outcb(cgps_at_res,strlen("+CGPS ERROR: 100\r\n"),0);

+        }

+        return 0;

+    }

+}

+

+

+int lynq_at_cgpsnmea(int at_type,char *at_paramter)

+{

+    int ret = 0;

+    char cgpsnmea_at_res[512]={};

+

+    if (at_type == LYNQ_ATCMD_TEST)

+    {

+        bzero(cgpsnmea_at_res,512);

+        memcpy(cgpsnmea_at_res,"+CGPSNMEA:(0,1)\r\n",strlen("+CGPSNMEA:(0,1)"));

+        atsvc_gnss_outcb(cgpsnmea_at_res,strlen(cgpsnmea_at_res),0);

+        return 0;

+    }

+    else if(at_type == LYNQ_ATCMD_READ)

+    {

+        bzero(cgpsnmea_at_res,512);

+        sprintf(cgpsnmea_at_res,"+CGPSNMEA:<%d>",at_gpsnmea_status);

+        atsvc_gnss_outcb(cgpsnmea_at_res,strlen(cgpsnmea_at_res),0);

+        return 0;

+    }

+    else if(at_type == LYNQ_ATCMD_WRITE)

+    {

+        if (at_gpsnmea_status != atoi(at_paramter))

+        {

+            at_gpsnmea_status = atoi(at_paramter);

+            bzero(cgpsnmea_at_res,512);

+            memcpy(cgpsnmea_at_res,"+CGPSNMEA OK\r\n",strlen("+CGPSNMEA OK\r\n"));

+            atsvc_gnss_outcb(cgpsnmea_at_res,strlen(cgpsnmea_at_res),0);

+        }

+        else

+        {

+            RLOGD("unknown at paramters");

+            bzero(cgpsnmea_at_res,512);

+            memcpy(cgpsnmea_at_res,"+CGPSNMEA ERROR: 100\r\n",strlen("+CGPSNMEA ERROR: 100\r\n"));

+            atsvc_gnss_outcb(cgpsnmea_at_res,strlen(cgpsnmea_at_res),0);

+        }

+        return 0;

+    }

+}
\ No newline at end of file
diff --git a/IC_src/mtk/lib/liblynq-gnss/src/lynq_gnsshal.h b/IC_src/mtk/lib/liblynq-gnss/src/lynq_gnsshal.h
new file mode 100755
index 0000000..04938c9
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-gnss/src/lynq_gnsshal.h
@@ -0,0 +1,56 @@
+#ifndef LYNQ_GNSSHAL_H

+#define LYNQ_GNSSHAL_H

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+#include<pthread.h>

+#include "lynq_gnss.h"

+#include "hardware/gps_mtk.h"

+#include "hal2mnl_interface.h"

+#include "gpshal.h"

+#include "gps_mtk.h"

+

+#define LYNQ_GNSS_MODE "GNSS_MODE"

+#define LYNQ_DEBUG_STATUS "debug.dbg2file"

+#define LYNQ_EPO_STATUS  "EPO_enabled"

+#define LYNQ_OUTPUT_FREQUENCY  "fix_interval"

+

+#define LYNQ_CONF_GPS_GLONASS "0"

+#define LYNQ_CONF_GPS_BEIDOU "1"

+#define LYNQ_CONF_GPS_GLONASS_BEIDOU "2"

+#define LYNQ_CONF_GPS "3"

+#define LYNQ_CONF_BEIDOU "4"

+#define LYNQ_CONF_GLONASS "5"

+#define LYNQ_CONF_GPS_GLONASS_BEIDOU_GALILEO "6"

+#define LYNQ_CONF_GPS_GALILEO "7"

+#define LYNQ_CONF_GPS_GLONASS_GALILEO "8"

+#define LYNQ_CONF_GPS_GALILEO_ONLY "9"

+#define LYNQ_CONF_GPS_GLONASS_BEIDOU_GALILEO_NAVIC "10"

+

+#define LYNQ_CONFIG_DISABLE "0"

+#define LYNQ_CONFIG_ENABLE "1"

+

+#define LYNQ_MAX_FRREQUENCY 16

+

+GpsCallbacks_ext* lynq__get_gps_callbacks(void);

+

+GpsMeasurementCallbacks_ext* lynq_gnss_get_raw_callbacks(void);

+

+lynq_gnss_cb* lynq_at_get__gnss_callbacks(void);

+

+extern lynq_atsvc_outcb atsvc_gnss_outcb;

+extern int at_gpsnmea_status;

+

+typedef enum{

+    LYNQ_ATCMD_TEST = 0,

+    LYNQ_ATCMD_READ,

+    LYNQ_ATCMD_WRITE

+}LYNQ_ATCMD_TYPE;

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif
\ No newline at end of file
diff --git a/IC_src/mtk/lib/liblynq-gnss/src/lynq_prop.c b/IC_src/mtk/lib/liblynq-gnss/src/lynq_prop.c
new file mode 100755
index 0000000..deaacc2
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-gnss/src/lynq_prop.c
@@ -0,0 +1,107 @@
+#include <stdio.h>   

+#include <string.h>  

+#include <stdlib.h>

+#include <sys/time.h>

+#include <errno.h>

+#include <unistd.h>

+#include <log/log.h>

+ 

+#include "lynq_prop.h"

+

+#define PROPBUF_SIZE 512

+

+

+const char *mnl_prop_path[] = {

+    "/etc/gnss/mnl.prop",   /*mainly for target*/

+    "/sbin/mnl.prop",   /*mainly for emulator*/

+};

+ 

+int write_prop(const char *file_name, char* key, char* val) {

+    if(NULL == file_name||NULL == key|| NULL == val)

+    {

+        RLOGD("incoming char error");

+        return -1;

+    }

+    char linebuffer[PROPBUF_SIZE] = {0};

+    char buffer1[PROPBUF_SIZE] = {0};

+    char buffer2[PROPBUF_SIZE] = {0};

+

+    int line_len = 0;

+    int len = 0;

+    int res;

+    int changed = 0;

+    FILE *fp = NULL;

+

+    if (0 != access(file_name, F_OK)) {    // if file is not exit, create file

+         RLOGD("access file error(%s), Try to create file", file_name);

+

+         fp = fopen(file_name, "w");  //Create file

+         if (fp == NULL) {

+             RLOGD("create file %s fail(%s)", file_name, strerror(errno));

+             return -1;

+         }

+    } else {

+        fp = fopen(file_name, "r+");  //Read and write

+        if(fp == NULL)

+        {

+            RLOGD("open error, %s", strerror(errno));

+            return -1;

+        }

+    }

+

+    while(fgets(linebuffer, PROPBUF_SIZE, fp)) {

+        line_len = strlen(linebuffer);

+        len += line_len;

+        sscanf(linebuffer, "%[^=]=%[^=]", buffer1,buffer2);

+        RLOGD("buffer1:%s, buffer2:%s", buffer1, buffer2);

+        if(!strcmp(key, buffer1)) {

+            len -= strlen(linebuffer);

+            res = fseek(fp, len, SEEK_SET);

+            if(res < 0) {

+                RLOGD("fseek fail, %s", strerror(errno));

+                fclose(fp);

+                return -1;

+            }

+            RLOGD("Before modify [%s=%s] in file [%s]", buffer1, buffer2, file_name);

+            memset(buffer2, 0, PROPBUF_SIZE);

+            LYNQ_STRNCPY(buffer2, val, PROPBUF_SIZE);

+            strncat(buffer1, "=", PROPBUF_SIZE - strlen(buffer1) - 1);

+            strncat(buffer1, buffer2, PROPBUF_SIZE - strlen(buffer1) - 1);

+            strncat(buffer1, "\n", PROPBUF_SIZE - strlen(buffer1) - 1);

+            RLOGD("After modify [%s] in file [%s]", buffer1, file_name);

+            changed = 1;

+            fprintf(fp, "%s", buffer1);

+            fclose(fp);

+            return 0;

+        }

+    }

+    if(changed == 0) {  //Not find key

+        memset(linebuffer, 0, PROPBUF_SIZE);

+        strncat(linebuffer, "\n", PROPBUF_SIZE - strlen(linebuffer) - 1);

+        strncat(linebuffer, key, PROPBUF_SIZE - strlen(linebuffer) - 1);

+        strncat(linebuffer, "=", PROPBUF_SIZE - strlen(linebuffer) - 1);

+        strncat(linebuffer, val, PROPBUF_SIZE - strlen(linebuffer) - 1);

+        strncat(linebuffer, "\n", PROPBUF_SIZE - strlen(buffer1) - 1);

+        RLOGD("Add config [%s] to file [%s]", linebuffer, file_name);

+        res = fseek(fp, 0, SEEK_END);

+        if(res < 0) {

+            RLOGD("fseek fail, %s", strerror(errno));

+            fclose(fp);

+            return -1;

+        }

+        fprintf(fp, "%s", linebuffer);

+

+        fclose(fp);

+    }

+    return 0;

+}

+

+void mnld_write_cfg(char* key, char* val) {

+    int idx;

+    int cnt = sizeof(mnl_prop_path)/sizeof(mnl_prop_path[0]);

+

+    for (idx = 0; idx < cnt; idx++) {

+        if (!write_prop(mnl_prop_path[idx], key, val))

+            break;

+    }

+}
\ No newline at end of file
diff --git a/IC_src/mtk/lib/liblynq-gnss/src/lynq_prop.h b/IC_src/mtk/lib/liblynq-gnss/src/lynq_prop.h
new file mode 100755
index 0000000..cad51bf
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-gnss/src/lynq_prop.h
@@ -0,0 +1,27 @@
+#ifndef LYNQ_PROP_H

+#define LYNQ_PROP_H

+ 

+#ifdef _cplusplus

+extern "C" {

+#endif

+    

+#define MTK_GPS_DATA_PATH "\"/etc/gnss/\""

+

+#define LYNQ_STRNCPY(dst,src,size) do{\

+                                       strncpy((char *)(dst), (char *)(src), (size - 1));\

+                                      (dst)[size - 1] = '\0';\

+                                     }while(0)

+

+

+

+#define F_OK 0

+

+int write_prop(const char *file_name, char* key, char* val);

+

+void mnld_write_cfg(char* key, char* val);

+

+#ifdef _cplusplus

+}

+#endif

+ 

+#endif

diff --git a/IC_src/mtk/lib/liblynq-misc/LICENSE b/IC_src/mtk/lib/liblynq-misc/LICENSE
new file mode 100755
index 0000000..605b7ea
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-misc/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.
diff --git a/IC_src/mtk/lib/liblynq-misc/include/lynq_misc.h b/IC_src/mtk/lib/liblynq-misc/include/lynq_misc.h
new file mode 100755
index 0000000..4207191
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-misc/include/lynq_misc.h
@@ -0,0 +1,28 @@
+/**

+ * @file misc.h

+ * @author you.chen

+ * @brief 

+ * @version 1.0

+ * @date 2023-08-21

+ * 

+ * @copyright Copyright (c) 2023

+ * 

+ */

+#ifndef __LYNQ_MISC_H__

+#define __LYNQ_MISC_H__

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+/**

+ * @brief lynq_get_security_boot_flag get the flag in efuse

+ * @param enable_flag (output param, 1 for enabled)

+ * @return 0 success, -1 some error occur

+ */

+int lynq_get_security_boot_flag(int * enabled_flag);

+

+#ifdef __cplusplus

+}

+#endif 

+#endif //#ifndef __LYNQ_MISC_H__

diff --git a/IC_src/mtk/lib/liblynq-misc/lynq_misc.cpp b/IC_src/mtk/lib/liblynq-misc/lynq_misc.cpp
new file mode 100755
index 0000000..6e6fe8d
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-misc/lynq_misc.cpp
@@ -0,0 +1,42 @@
+#include <stdio.h>

+#include "lynq_misc.h"

+#include "log/log.h"

+

+#undef LOG_TAG

+#define LOG_TAG "MISC"

+

+int lynq_get_security_boot_flag(int * enabled_flag)

+{

+    int value, ret;

+    if (enabled_flag == NULL)

+    {

+        RLOGE("input param is null ptr");

+        return -1;

+    }

+    *enabled_flag = 0;

+    FILE *pfile=fopen("/proc/device-tree/chosen/atag,devinfo", "r");

+    if (pfile == NULL)

+    {

+        RLOGE("open devinfo fail");

+        return -1;

+    }

+    ret = fseek(pfile, 0x428, 0);

+    if (ret != 0)

+    {

+        RLOGE("seek file fail");

+        fclose(pfile);

+        return -1;

+    }

+    ret = fread(&value, sizeof (value), 1, pfile);

+    if (ret != 1)

+    {

+        RLOGE("read file fail");

+        fclose(pfile);

+        return -1;

+    }

+    fclose(pfile);

+

+    // the third bit of 32bits at 0x428 (index start with 0?), 1 for enabled, 0 not enabled

+    *enabled_flag = (value & 0x8) == 0 ? 0 : 1;

+    return 0;

+}

diff --git a/IC_src/mtk/lib/liblynq-misc/makefile b/IC_src/mtk/lib/liblynq-misc/makefile
new file mode 100755
index 0000000..5864273
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-misc/makefile
@@ -0,0 +1,58 @@
+SHELL = /bin/sh
+RM = rm -f
+
+LOCAL_CFLAGS := -Wall \
+                -g -Os \
+                -flto \
+                -fPIC       
+
+PWD := $(shell pwd)
+
+$(warning ################# lynq misc ROOT: $(ROOT),includedir:$(includedir), PWD :$(PWD))
+LOCAL_PATH   = .
+
+LOCAL_C_INCLUDES = \
+  -I. \
+  -I$(LOCAL_PATH)/include \
+  -I$(ROOT)$(includedir) \
+
+LOCAL_LIBS := \
+    -L. \
+    -ldl \
+    -llog \
+
+SOURCES = $(wildcard *.cpp)
+
+EXECUTABLE = liblynq-misc.so
+
+OBJECTS=$(SOURCES:.c=.o)
+all: $(EXECUTABLE)
+
+$(EXECUTABLE): $(OBJECTS)
+	$(CXX) -shared -Wl,--no-undefined $(OBJECTS) $(LOCAL_LIBS) $(LOCAL_CFLAGS) $(LOCAL_C_INCLUDES) -o $@
+
+%.o : %.c
+	$(CC) $(LOCAL_C_INCLUDES) $(LOCAL_CFLAGS) $(LOCAL_LIBS) -o $@ -c $<
+
+build:  $(EXECUTABLE)
+	$(warning ########## build $(EXECUTABLE)  ##########)
+
+install:
+	$(warning ################# lynq misc EXECUTABLE: $(EXECUTABLE),base:$(base_libdir))
+	mkdir -p $(ROOT)$(base_libdir)/
+	install $(EXECUTABLE) $(ROOT)$(base_libdir)/
+
+pack_rootfs:
+	$(warning ################# lynq misc PACK: $(PACK_INITRAMFS_TO),base:$(base_libdir))
+	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)
+
+
diff --git a/IC_src/mtk/lib/liblynq-rtk/include/liblynq-rtk.h b/IC_src/mtk/lib/liblynq-rtk/include/liblynq-rtk.h
new file mode 100755
index 0000000..8144df4
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-rtk/include/liblynq-rtk.h
@@ -0,0 +1,108 @@
+#ifndef LIBLYNQ_RTK_H
+#define LIBLYNQ_RTK_H
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum
+{
+	lynq_rtk_log_info,
+	lynq_rtk_log_warn,
+	lynq_rtk_log_err
+} lynq_rtk_log_level;
+
+typedef struct
+{
+    unsigned char  bPosFlag;
+    unsigned char  bTrackNo;
+    unsigned char  bSatNo;
+
+    unsigned char  bRtkFlag;
+    double         fDiffAge;
+    unsigned int   uGpsWeek;
+    double         fWeekSeconds;
+    double         fUTC;
+    double         fLeapSeconds;
+
+    double         fPosX;
+    double         fPosY;
+    double         fPosZ;
+    float          fPosXDelta;
+    float          fPosYDelta;
+    float          fPosZDelta;
+
+    double         fLat;
+    double         fLong;
+    double         fAlt;
+    double         fHeightOfGeoid;
+    float          fLatStd;
+    float          fLongStd;
+    float          fAltStd;
+
+    double         fVelX;
+    double         fVelY;
+    double         fVelZ;
+    float          fVelXDelta;
+    float          fVelYDelta;
+    float          fVelZDelta;
+
+    float          fVelN;
+    float          fVelE;
+    float          fVelU;
+    float          fVelNDelta;
+    float          fVelEDelta;
+    float          fVelUDelta;
+
+    float          fHorSpeed;
+    float          fHorSpeedDelta;
+
+    float          fTrueHeading;
+    float          fTrueHeadingDelta;
+
+    float          fHeading2Ant;
+    float          fHeading2AntDelta;
+
+    float          fRangeRms;
+    float          fPhaseRms;
+
+    float  	       fHDOP;
+    float 	       fPDOP;
+    float          fVDOP;
+    float          fCN0;
+
+    double         fClkTime;
+
+    int            iBaseStatus;
+    int            iRtkStatus;
+}lynq_rtk_result_info;
+
+typedef void (*lynq_rtk_out_debuginfo)(const char * pBuff, const int length, const int ilevel);
+typedef void (*lynq_rtk_out_postdata)(const unsigned char * pBuff, const int length);
+typedef void (*lynq_rtk_out_basesdkstatus)(const int status);
+typedef void (*lynq_rtk_out_status)(const int status);
+
+typedef void (*lynq_rtk_out_result)(const lynq_rtk_result_info * prtk);
+typedef void (*lynq_rtk_out_result_nmea)(const char * strnmea, const int length);
+
+extern void lynq_rtk_lib_version(char * version);
+extern void lynq_rtk_init();
+extern void lynq_rtk_set_userinfo(const char *username,const char *pwd);
+extern void lynq_rtk_set_deviceID(const char* device_id);
+extern void lynq_rtk_result_cb_reg(lynq_rtk_out_result result_cb);
+extern void lynq_rtk_result_nmea_cb_reg(lynq_rtk_out_result_nmea nmea_cb);
+extern void lynq_rtk_config_log_reg(lynq_rtk_out_debuginfo pdebuginfo);
+extern void lynq_rtk_config_post_reg(lynq_rtk_out_postdata ppostdata);
+extern void lynq_rtk_base_sdkstatus(lynq_rtk_out_basesdkstatus psdkstatus);
+extern void lynq_rtk_base_status(lynq_rtk_out_status pstatus);
+extern void lynq_rtk_rove_addnmea(const unsigned char * pBuff, const int iBuffLen);
+extern void lynq_rtk_rove_addrawmess(GnssData_ext* data);
+extern void lynq_rtk_setserverIP(const char* server_ip);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif 
\ No newline at end of file
diff --git a/IC_src/mtk/lib/liblynq-rtk/libRTKFUN.so b/IC_src/mtk/lib/liblynq-rtk/libRTKFUN.so
new file mode 100755
index 0000000..b1a15aa
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-rtk/libRTKFUN.so
Binary files differ
diff --git a/IC_src/mtk/lib/liblynq-rtk/libcmcc_sdk.so b/IC_src/mtk/lib/liblynq-rtk/libcmcc_sdk.so
new file mode 100755
index 0000000..b56dd84
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-rtk/libcmcc_sdk.so
Binary files differ
diff --git a/IC_src/mtk/lib/liblynq-rtk/liblynq-rtk.c b/IC_src/mtk/lib/liblynq-rtk/liblynq-rtk.c
new file mode 100755
index 0000000..460a1bb
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-rtk/liblynq-rtk.c
@@ -0,0 +1,192 @@
+#include <stdio.h>
+#include <string.h>
+#include <liblog/lynq_deflog.h>
+#include "rtk_fun.h"
+#include "liblynq-rtk.h"
+
+
+lynq_rtk_out_result lib_result_cb = NULL;
+lynq_rtk_out_result_nmea lib_nmea_cb = NULL;
+lynq_rtk_out_debuginfo lib_debuginfo = NULL;
+lynq_rtk_out_postdata lib_postdata = NULL;
+lynq_rtk_out_basesdkstatus lib_basesdkstatus = NULL;
+lynq_rtk_out_status lib_status = NULL;
+
+
+void librtk_out_result(const rtk_result_info * prtk)
+{
+    /*change rtk_result_info into lynq_result_info*/
+    if (NULL == prtk)
+    {
+        LYERRLOG("result info is NULL return : error");
+        return ;
+    }
+    lynq_rtk_result_info result_info;
+    memset(&result_info,0,sizeof(result_info));
+    memcpy(&result_info,prtk,sizeof(result_info));
+    lib_result_cb(&result_info);
+    return ;
+}
+
+void librtk_out_result_nmea(const char * strnmea, const int length)
+{
+    lib_nmea_cb(strnmea,length);
+    return ;
+}
+
+void librtk_out_debuginfo(const char * pBuff, const int length, const int ilevel)
+{
+    lib_debuginfo(pBuff,length,ilevel);
+    return ;
+}
+
+void librtk_out_postdata(const unsigned char * pBuff, const int length)
+{
+    lib_postdata(pBuff,length);
+    return ;
+}
+
+void librtk_out_basesdkstatus(const int status)
+{
+    lib_basesdkstatus(status);
+    return ;
+}
+
+void librtk_out_status(const int status)
+{
+    lib_status(status);
+    return;
+}
+
+
+
+void lynq_rtk_lib_version(char * version)
+{
+    if (NULL == version)
+    {
+        LYERRLOG("incoming version is NULL, error");
+        return ;
+    }
+    rtk_version(version);
+    return ;
+}
+
+void lynq_rtk_init()
+{
+    LYINFLOG("lib rtk init");
+    rtk_init();
+    return ;
+}
+
+void lynq_rtk_set_userinfo(const char *username,const char *pwd)
+{
+    if (NULL == username || NULL == pwd)
+    {
+        LYERRLOG("invalid username or pwd incoming ,error");
+        return ;
+    }
+    rtk_set_UserInfo(username,pwd);
+    return ;
+}
+
+void lynq_rtk_set_deviceID(const char* device_id)
+{
+    if (NULL == device_id)
+    {
+        LYERRLOG("invalid device_id incoming ,error");
+        return ;
+    }
+    rtk_set_DeviceID(device_id);
+    return ;
+}
+
+void lynq_rtk_result_cb_reg(lynq_rtk_out_result result_cb)
+{
+    if (NULL == result_cb)
+    {
+        LYERRLOG("invalid lynq_rtk_out_result incoming ,error");
+        return ;
+    }
+    lib_result_cb = result_cb;
+    rtk_result_cb(librtk_out_result);
+    return ;
+}
+
+void lynq_rtk_result_nmea_cb_reg(lynq_rtk_out_result_nmea nmea_cb)
+{
+    if (NULL == nmea_cb)
+    {
+        LYERRLOG("invalid lynq_rtk_out_result_nmea incoming ,error");
+        return ;
+    }
+    lib_nmea_cb = nmea_cb;
+    rtk_result_nmea_cb(librtk_out_result_nmea);
+    return ;
+}
+
+void lynq_rtk_config_log_reg(lynq_rtk_out_debuginfo pdebuginfo)
+{
+    if (NULL == pdebuginfo)
+    {
+        LYERRLOG("invalid lynq_rtk_out_debuginfo incoming ,error");
+        return ;
+    }
+    lib_debuginfo = pdebuginfo;
+    rtk_config_log(librtk_out_debuginfo);
+    return ;
+}
+
+void lynq_rtk_config_post_reg(lynq_rtk_out_postdata ppostdata)
+{
+    if (NULL == ppostdata)
+    {
+        LYERRLOG("invalid lynq_rtk_out_postdata incoming ,error");
+        return ;
+    }
+    lib_debuginfo = ppostdata;
+    rtk_config_post(librtk_out_debuginfo);
+    return ;
+}
+
+void lynq_rtk_base_sdkstatus(lynq_rtk_out_basesdkstatus psdkstatus)
+{
+    if (NULL == psdkstatus)
+    {
+        LYERRLOG("invalid lynq_rtk_out_basesdkstatus incoming ,error");
+        return ;
+    }
+    lib_basesdkstatus = psdkstatus;
+    rtk_base_sdkstatus(librtk_out_basesdkstatus);
+    return ;
+}
+
+void lynq_rtk_base_status(lynq_rtk_out_status pstatus)
+{
+    if (NULL == pstatus)
+    {
+        LYERRLOG("invalid lynq_rtk_out_status incoming ,error");
+        return ;
+    }
+    lib_status = pstatus;
+    rtk_status_update(librtk_out_status);
+    return ;
+}
+
+void lynq_rtk_rove_addnmea(const unsigned char * pBuff, const int iBuffLen)
+{
+    rtk_rove_addnmea(pBuff,iBuffLen);
+    return ;
+}
+
+void lynq_rtk_rove_addrawmess(GnssData_ext* data)
+{
+    rtk_rove_addrawmess(data);
+    return ;
+}
+
+void lynq_rtk_setserverIP(const char* server_ip)
+{
+    rtk_setServerIP(server_ip);
+    return ;
+}
+
diff --git a/IC_src/mtk/lib/liblynq-rtk/makefile b/IC_src/mtk/lib/liblynq-rtk/makefile
new file mode 100755
index 0000000..6469254
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-rtk/makefile
@@ -0,0 +1,56 @@
+SHELL = /bin/bash
+RM =rm -f
+
+
+LOCAL_CFLAGS := \
+	-Wall \
+    -g \
+    -Wall \
+    -fPIC \
+    -shared \
+    -D__COMPILE_OPTION__ \
+    -D__LINUX_OS__ \
+
+LOCAL_PATH   = .
+
+LOCAL_C_INCLUDES = \
+  -I. \
+  -I$(LOCAL_PATH)/include/ \
+  -I$(LOCAL_PATH)/ \
+  -I$(ROOT)$(includedir)/gps_hal \
+  -I$(ROOT)$(includedir)/gps_hal/inc \
+  -I$(ROOT)$(includedir)/gps_hal/hardware \
+  -I$(ROOT)$(includedir)/liblog \
+
+LOCAL_LIBS :=  \
+  -L . \
+  -ldl \
+  -lcmcc_sdk\
+  -lRTKFUN \
+  -llynq-log \
+  -lpthread \
+
+
+SOURCES = $(wildcard *.c wildcard src/*.c)
+EXECUTABLE = liblynq-rtk.so
+
+COBJS=$(SOURCES:.c=.o)
+all : $(EXECUTABLE)
+$(EXECUTABLE): $(COBJS)
+	$(CXX) -shared -Wl,--no-undefined $(COBJS) $(LOCAL_LIBS) $(LOCAL_CFLAGS) $(LOCAL_C_INCLUDES) -o $@
+
+%.o: %.c
+	$(warning ----->build $<)
+	$(CC) $(LOCAL_C_INCLUDES) $(LOCAL_CFLAGS) $(LOCAL_LIBS) -o $@ -c $<
+%.o : %.cpp
+	$(CXX) $(LOCAL_C_INCLUDES) $(LOCAL_CFLAGS) $(LOCAL_LIBS) -o $@ -c $<
+
+build:  $(EXECUTABLE)
+	$(warning ########## build $(EXECUTABLE)  ##########)
+.PHONY: install clean
+install:
+	mkdir -p $(ROOT)$(base_libdir)/
+	install $(EXECUTABLE) $(ROOT)$(base_libdir)/
+.PHONY: clean
+clean:
+	$(RM) $(COBJS) $(EXECUTABLE)
diff --git a/IC_src/mtk/lib/liblynq-rtk/rtk_fun.h b/IC_src/mtk/lib/liblynq-rtk/rtk_fun.h
new file mode 100755
index 0000000..76cbcdc
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-rtk/rtk_fun.h
@@ -0,0 +1,179 @@
+#ifndef _RTK_FUN_H_

+#define _RTK_FUN_H_

+

+#define  RTK_SUPPORT

+#define  ENABLE_RTKFUN		 //RTK�ĺ����ӿ�

+#define  ENABLE_RTKCHANGEFREQ    //

+

+#include "hardware/gps_mtk.h"

+#include "hardware/gps.h"

+

+

+typedef enum

+{

+	rtk_log_info,

+	rtk_log_warn,

+	rtk_log_err

+} rtk_log_level;

+

+typedef struct

+{

+	unsigned char  bPosFlag;   //��ǰ��״̬��0����Ч�� 1�����㣻 2��RTD(SBAS)�� 4��RTK fix�� 5��RTK float�� 6��Dead Reckoing�� 7��Fix pos mode�� 8��Sim mode

+	unsigned char  bTrackNo;   //����������

+	unsigned char  bSatNo;     //����������

+

+	unsigned char  bRtkFlag;   //RTKԭʼ��״̬(0:ʧ��  1:����   3:����̶�    4:�̶�    5:����    12:����   13:����ƽ��    14:�Ƶ�)

+	double	       fDiffAge;   //�������

+	unsigned int   uGpsWeek;   //GPSʱ����

+	double         fWeekSeconds;//GPSʱ��������

+	double         fUTC;       //UTCʱ�������1970-01-01 00:00:00��ʼ����

+	double		   fLeapSeconds;//����

+

+

+	double         fPosX; 	   //X����(m)(WGS84)

+	double         fPosY; 	   //Y����(m)(WGS84)

+	double         fPosZ;      //Z����(m)(WGS84)

+	float	       fPosXDelta; //X����ı�׼���

+	float	       fPosYDelta; //Y����ı�׼���

+	float	       fPosZDelta; //Z����ı�׼���

+

+	double         fLat;  	   //γ�ȣ���λ�ȣ�

+	double         fLong; 	   //���ȣ���λ�ȣ�

+	double         fAlt;       //���θߣ���λm��

+	double 		   fHeightOfGeoid;//�߳��쳣����λm��

+	float          fLatStd;    //γ�ȱ�׼��

+	float          fLongStd;   //���ȱ�׼��

+	float          fAltStd;    //���θ� ��׼��

+

+	double         fVelX; 	   //X������ٶȣ�m/s��

+	double         fVelY;      //Y������ٶ�

+	double         fVelZ;      //Z������ٶ�

+	float	       fVelXDelta; //X�����ٶȱ�׼��

+	float	       fVelYDelta; //Y�����ٶȱ�׼��

+	float	       fVelZDelta; //Z�����ٶȱ�׼��

+

+	float          fVelN; 	   //�������ٶȣ�m/s)

+	float          fVelE;      //�������ٶȣ�m/s)

+	float          fVelU;      //�췽���ٶȣ�m/s)

+	float          fVelNDelta; //�������ٶȱ�׼�m/s)

+	float          fVelEDelta; //�������ٶȱ�׼�m/s)

+	float          fVelUDelta; //�췽���ٶȱ�׼�m/s)

+

+	float	       fHorSpeed;  //�Ե��ٶȣ�m/s)

+	float	       fHorSpeedDelta;//�Ե��ٶȱ�׼�m/s)

+

+	float	       fTrueHeading;//���溽��,�켣����ǣ��ȣ����˶�����

+	float	       fTrueHeadingDelta;//�켣����DZ�׼��ȣ�

+

+	float		   fHeading2Ant; //˫���ߺ����ݲ�֧�֣����켣����Ǹ�ֵ��

+	float		   fHeading2AntDelta; //˫���ߺ��򾫶ȣ��ݲ�֧�֣����켣����ǵı�׼�ֵ��

+

+	float	       fRangeRms;  //α�ྫ��

+	float	       fPhaseRms;  //�ز�����

+

+	float  	       fHDOP;	   //HDOP

+	float 	       fPDOP;      //PDOP

+	float          fVDOP;      //VDOP

+	float	 	   fCN0;	   //��ǰ���붨λ���ǵľ�ֵCN0(dBHz)

+

+	double		   fClkTime;   //��ӦMTK���ڲ�gps_clock�е�time_ns�ֶ�

+

+	int 		   iBaseStatus;//ͬrtk_base_sdkstatus��������״̬

+	//RTK����״̬

+	//0x00000001��ʾ�޻�վ����

+	//0x00000002��ʾ��Ч���ǵ���10��

+	//0x00000004��ʾ��Ч��������Ⱦ�ֵ������ֵ��Ĭ��24��

+	//0x00000008��ʾRTK�������ʧ�ܣ�����ʧ�ܰ������ǹ��٣��۲������������ȵͣ���������ȣ�

+	//0x00000010��ʾRTKδ������㣨δ�������ԭ������޻�վ���ݡ��л�վ���ݵ��ӳٴ���200��PVT��λʧ�ܡ�ʱ���ж��쳣�ȣ�

+	int 		   iRtkStatus;

+

+}rtk_result_info;

+

+typedef void  (*rtk_out_debuginfo)(const char * pBuff, const int length, const int ilevel);

+typedef void  (*rtk_out_postdata)(const unsigned char * pBuff, const int length);

+typedef void  (*rtk_out_basesdkstatus)(const int status);

+typedef void  (*rtk_out_status)(const int status);

+

+typedef void  (*rtk_out_result)(const rtk_result_info * prtk);

+typedef void  (*rtk_out_result_nmea)(const char * strnmea, const int length);

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+//rtk��ʼ��

+extern void rtk_init();

+

+//ͨ�������û����������½

+extern void rtk_set_UserInfo(const char* user, const char* pwd);

+

+//�����豸ID��½

+extern void rtk_set_DeviceID(const char* device_id);

+

+//�����ƶ�վMTK��NMEA����(GGA/RMC/VTG/GSA/GSV/GST)

+extern void rtk_rove_addnmea(const unsigned char * pBuff, const int iBuffLen);

+

+//�����ƶ�վMTK�Ĺ۲���

+extern void rtk_rove_addrawmess(GnssData_ext* data);

+

+//�����ƶ�վMTK��ԭʼ������֡

+extern int  rtk_rove_addrawnav(GnssNavigationMessage * msg);

+

+//rtk��������Ϣ

+extern void rtk_result_cb(rtk_out_result pRtk);

+

+//rtk��Nmea���Ľ��(GGA/RMC/VTG/GSA/GSV/GST)

+extern void rtk_result_nmea_cb(rtk_out_result_nmea pNmea);

+

+//rtk�Ĵ�ӡ��Ϣ,������Ϊ��

+extern void rtk_config_log(rtk_out_debuginfo pLog);

+

+//rtk��������,��������

+extern void rtk_config_post(rtk_out_postdata pOut);

+

+//��վ ��������ݣ�������״̬(�������SDK״̬��)

+extern void rtk_base_sdkstatus(rtk_out_basesdkstatus pBaseStatus);

+

+//rtk�����Ƿ�ر�ijϵͳ

+//bSys------1(GPS)  2(GLO)  3(GAL)   4(QZS)   5(BD2)  6(BD3)

+//bLock-----l(Lock) 0:(unLock)

+extern void rtk_config_lockout(const unsigned char bSys, const unsigned char bLock);

+

+//��ȡRTK�汾�����20�ֽڣ�

+extern void rtk_version(char * strVer);

+

+//rtk�Ƿ��������

+//0:����������Ĭ��״̬��

+//1:�������ߣ�rtk�ӿڲ��ٽ����������룬����sdk���������ͽ������ݣ�ֹͣ������

+//2:���뵥�㶨λ״̬��rtk�ӿڽ��������������������sdkֹͣ����

+extern void rtk_gotosleep(const unsigned char bMode);

+

+//��ȡ��ǰ���õ�DeviceID�����128�ֽڣ�

+extern void rtk_get_DeviceID(char* device_id);

+

+//���÷�����IP��ַ�ӿ�

+//server_ip:��������ַ

+extern void rtk_setServerIP(const char* server_ip);

+

+//����RTK�Ľ�����Ҫ��͵�����ȣ�Ĭ��24

+extern void rtk_setCN0(const unsigned char bCN0);

+

+//����RTK״̬��ӿڣ��������SDK��״̬��+RTK״̬�룬RTK״̬�����¶���)

+//���������ԭʼ�۲�����Ƶ�ʸ���RTK״̬�룬״̬��ύ����֣�����ԭʼ����������ÿ�����һ��״̬���������ߺ������

+//4001:��ԭʼ��������(����3�뼰����)

+//4002:��NMEA��������(����3�뼰����)

+//4003:���������������

+//4004:PVTδ��λ

+//4005:�����ź���(����Ⱦ�ֵ <30)

+//4006:�����ź�һ��(����Ⱦ�ֵ30~35)

+//4007:�����źź�(����Ⱦ�ֵ35~40)

+//4008:�����ź�ǿ(����Ⱦ�ֵ >40)

+extern void rtk_status_update(rtk_out_status pRtkStatus);

+

+

+#ifdef __cplusplus

+}

+#endif

+

+

+#endif /* _RTK_FUN_H_ */

diff --git a/IC_src/mtk/lib/liblynq-system-own/include/lynq-system-own.h b/IC_src/mtk/lib/liblynq-system-own/include/lynq-system-own.h
new file mode 100644
index 0000000..0e5ff80
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-system-own/include/lynq-system-own.h
@@ -0,0 +1,17 @@
+#ifndef LYNQ_SYSTEM_OWN

+#define LYNQ_SYSTEM_OWN

+typedef void (*LYNQ_Lpm_Handler_T) ( int lpm_edge);

+int LYNQ_Lpm_Init(LYNQ_Lpm_Handler_T lynq_lpm_handler);

+int LYNQ_Lpm_Deinit();

+int LYNQ_Autosleep_Enable(int enable);

+int LYNQ_SLP_WakeLock_Lock(const char *name);

+int LYNQ_SLP_WakeLock_Unlock(const char *name);

+void LYNQ_Power_Mode(char *power_mode);

+void LYNQ_Power_Down(int mode);

+int LYNQ_Adc_Show(int adc_num);

+void lynq_lpm_handler(int lpm_edge);

+LYNQ_Lpm_Handler_T LYNQ_Lpm_Handler=NULL;

+int last_state=0;

+#endif

+

+

diff --git a/IC_src/mtk/lib/liblynq-system-own/makefile b/IC_src/mtk/lib/liblynq-system-own/makefile
new file mode 100644
index 0000000..97a234e
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-system-own/makefile
@@ -0,0 +1,57 @@
+SHELL = /bin/sh
+RM = rm -f
+
+LOCAL_CFLAGS := -Wall \
+                -std=gnu++14 \
+                -g -Os \
+                -flto \
+                -fPIC \
+                -fpermissive \
+
+$(warning ################# RITA ROOT: $(ROOT),includedir:$(includedir))
+LOCAL_PATH   = .
+
+LOCAL_C_INCLUDES = \
+  -I. \
+  -I$(LOCAL_PATH)/include \
+
+LOCAL_LIBS := \
+	-L. \
+  	-ldl \
+
+
+SOURCES = $(wildcard *.c wildcard *.h src/*.c)
+
+EXECUTABLE = liblynq-system-own.so
+
+OBJECTS=$(SOURCES:.c=.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 : %.c
+	$(CC) $(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)
diff --git a/IC_src/mtk/lib/liblynq-system-own/power_mode_own.sh b/IC_src/mtk/lib/liblynq-system-own/power_mode_own.sh
new file mode 100644
index 0000000..188cc03
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-system-own/power_mode_own.sh
@@ -0,0 +1,51 @@
+#!/bin/sh
+
+case "$1" in
+	"flight")
+		echo "Sys flight mode" >/dev/console
+		killall -9 lynq-function-test
+        echo 11 | emdlogger_ctrl  ##set log status
+		sleep 1	                 
+        mdlogctlstop              ##stop modem log
+        echo mem > /sys/power/autosleep  ##set autosleep modem
+        /usr/bin/telephony &				##initialize Ril function.
+        sleep 5
+        sh/usr/bin/demoscript/DSDS/set_default_sim_all_except_data.sh 0			##switch sim card 0
+        echo "RIL_REQUEST_RADIO_POWER 0" > dev/udp/127.0.0.1/8000					##turn off radio off sim card 0
+        sh/usr/bin/demoscript/DSDS/set_default_sim_all_except_data.sh 1				##switch sim card 1
+        echo "RIL_REQUEST_RADIO_POWER 0" >/dev/udp/127.0.0.1/8000				##turn off radio off sim card 1
+	;;
+
+	"standby")
+		echo "Sys standby mode" >/dev/console
+		killall -9 lynq-function-test
+		echo 7 | emdlogger_ctrl
+		/usr/bin/telephony &
+		sleep 5
+		sh /usr/bin/demoscript/Network_API/SetPrefferredNetworkType.sh 11
+		sh /usr/bin/demoscript/DSDS/set_default_sim_all_except_data.sh 1
+		echo "RIL_REQUEST_SCREEN_STATE 0" > /dev/udp/127.0.0.1/8000
+		sh /usr/bin/demoscript/DSDS/set_default_sim_all_except_data.sh 0
+		echo "RIL_REQUEST_SCREEN_STATE 0" > /dev/udp/127.0.0.1/8000
+		echo mem > /sys/power/autosleep
+	;;
+
+	"talking")
+		echo "Sys standby mode" >/dev/console
+		killall -9 lynq-function-test
+		echo 7 | emdlogger_ctrl
+		/usr/bin/telephony &
+		sleep 5
+		sh /usr/bin/demoscript/Network_API/SetPrefferredNetworkType.sh 2
+		sh /usr/bin/demoscript/DSDS/set_default_sim_all_except_data.sh 1
+		echo "RIL_REQUEST_SCREEN_STATE 0" > /dev/udp/127.0.0.1/8000
+		sh /usr/bin/demoscript/DSDS/set_default_sim_all_except_data.sh 0
+		echo "RIL_REQUEST_SCREEN_STATE 0" > /dev/udp/127.0.0.1/8000
+		sh /usr/bin/demoscript/CC_API/dialACall.sh <number>
+		echo mem > /sys/power/autosleep
+	;;
+
+	*)
+		echo $0 'power          - start system'
+		;;
+esac
\ No newline at end of file
diff --git a/IC_src/mtk/lib/liblynq-system-own/src/lynq-system-own.c b/IC_src/mtk/lib/liblynq-system-own/src/lynq-system-own.c
new file mode 100644
index 0000000..0c5334a
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-system-own/src/lynq-system-own.c
@@ -0,0 +1,114 @@
+#include <stdio.h>

+#include <string.h>

+#include <stdlib.h>

+#include <stdbool.h>

+#include <unistd.h>

+#include <time.h>

+#include <lynq-system-own.h>

+

+void lynq_lpm_handler(int lpm_edge)

+{

+	FILE * fp = NULL;

+	char buft[32] = {0};

+	char * cmd="cat /sys/devices/platform/10005000.pinctrl/mt_gpio | grep 000: | cut -b 8";

+	//printf("[%s][%d]cmd=[%s]\n",__FUNCTION__,__LINE__,cmd);	

+

+	fp = popen (cmd, "r");

+	if (fp) {

+		if (fgets(buft, sizeof(buft), fp) != NULL) {		

+			//printf("[%s][%d]%s\n",__FUNCTION__,__LINE__,buft);					

+			strtok(buft, "\n");

+			

+		}

+		pclose(fp);

+	}

+	//printf("[%s][%d]last_state %d\n",__FUNCTION__,__LINE__,last_state);

+	if(atoi(buft)!=last_state){

+		last_state=atoi(buft);

+		lpm_edge=atoi(buft);

+		printf("[%s][%d]lpm_edge=%d\n",__FUNCTION__,__LINE__,lpm_edge);

+	}

+}

+

+int LYNQ_Lpm_Init (LYNQ_Lpm_Handler_T lynq_lpm_handler)

+{

+	LYNQ_Lpm_Handler=lynq_lpm_handler;

+	return 0;

+}

+int LYNQ_Lpm_Deinit (void)

+{

+	LYNQ_Lpm_Handler=NULL;

+	return 0;

+}

+

+void suspendOperatingSystem()

+{

+	system("killall -9 lynq-function-test");

+	system("echo 7 | emdlogger_ctrl");

+	system("/usr/bin/telephony &");

+	system("sleep 5");

+	system("sh /usr/bin/demoscript/DSDS/set_default_sim_all_except_data.sh 0");

+	system("sh /usr/bin/demoscript/Network_API/RadioOn.sh 0");

+	system("sh /usr/bin/demoscript/DSDS/set_default_sim_all_except_data.sh 1");

+	system("sh /usr/bin/demoscript/Network_API/RadioOn.sh 0");

+	system("echo mem > /sys/power/autosleep");

+}

+

+int LYNQ_Autosleep_Enable(int enable)

+{

+	if(enable){

+		suspendOperatingSystem();

+	}

+	return 0;

+}

+

+int LYNQ_SLP_WakeLock_Lock(const char *name)

+{

+    char gyCmd[64] = {0};

+	sprintf(gyCmd,"echo %s > /sys/power/wake_lock",name);

+	system(gyCmd);

+}

+

+int LYNQ_SLP_WakeLock_Unlock(const char *name)

+{

+    char gyCmd[64] = {0};

+	sprintf(gyCmd,"echo %s > /sys/power/wake_unlock",name);

+	system(gyCmd);	

+}

+

+void LYNQ_Power_Mode(char *power_mode)

+{

+    char gyCmd[64] = {0};

+	sprintf(gyCmd,"sh /etc/powerscript/power_mode_own %s",power_mode);

+	system(gyCmd);

+}

+

+void LYNQ_Power_Down(int mode)

+{

+	if(mode){

+		system("reboot");

+	}else{

+		system("init 0");

+	}

+}

+

+int LYNQ_Adc_Show(int adc_num)

+{

+	FILE * fp = NULL;

+	char buft[32] = {0};

+	char * cmd="cat /sys/bus/iio/devices/iio:device0/in_voltage0_BATADC_input";

+	//printf("[%s][%d]cmd=[%s]\n",__FUNCTION__,__LINE__,cmd);	

+

+	fp = popen (cmd, "r");

+	if (fp) {

+		if (fgets(buft, sizeof(buft), fp) != NULL) {		

+			//printf("[%s][%d]%s\n",__FUNCTION__,__LINE__,buft);					

+			strtok(buft, "\n");

+			

+		}

+		pclose(fp);

+	}

+	return atoi(buft);

+}

+

+

diff --git a/IC_src/mtk/lib/liblynq-thermal/include/liblynq-thermal/lynq_get_thermal.h b/IC_src/mtk/lib/liblynq-thermal/include/liblynq-thermal/lynq_get_thermal.h
new file mode 100755
index 0000000..87bb23d
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-thermal/include/liblynq-thermal/lynq_get_thermal.h
@@ -0,0 +1,44 @@
+#ifndef __LYNQ_GET_THERMAL_H__

+#define __LYNQ_GET_THERMAL_H__

+

+#define LYNQ_THM_PATH 256

+

+#define TYPE_PATH_PRE "/sys/class/thermal"

+

+#define LYNQ_THM_OK 0

+#define LYNQ_THM_OPEN_ERROR -1

+#define LYNQ_THM_READ_ERROR -2

+#define LYNQ_THM_ACCESS_ERROR -3

+#define LYNQ_THM_ZONE_ERROR -4

+

+#define LYNQ_THM_ZONE_KEY "thermal_zone"

+#define LYNQ_THM_COOLER_KEY "cooling_device"

+

+typedef enum {

+    soc_max=0,

+    cpu0,

+    cpu1,

+    cpu2,

+    cpu3,

+    gpu0,

+    gpu1,

+    dramc,

+    mmsys,

+    md_5g,

+    md_4g,

+    md_3g,

+    soc_dram_ntc,

+    pa_5g,

+    pa_4g,

+    rf_ntc,

+    pmic,

+    pmic_vcore,

+    pmic_vpro,

+    pmic_vgpu=19,

+} ZONE_NUM;

+

+char* lynq_read_version();

+int read_sys_info(char *sys_path, char *out_buf, int out_buf_len);

+int lynq_get_zone_tmp(ZONE_NUM num, int *temp);

+

+#endif  //__LYNQ_GET_THERMAL_H__
\ No newline at end of file
diff --git a/IC_src/mtk/lib/liblynq-thermal/makefile b/IC_src/mtk/lib/liblynq-thermal/makefile
new file mode 100755
index 0000000..bae164e
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-thermal/makefile
@@ -0,0 +1,85 @@
+SHELL = /bin/sh
+RM = rm -f
+
+LOCAL_CFLAGS := -Wall \
+                -std=gnu++14 \
+                -g -Os \
+                -flto \
+                -fPIC \
+                -fpermissive \
+
+$(warning ################# C2K support: $(RAT_CONFIG_C2K_SUPPORT))
+ifeq ($(strip $(RAT_CONFIG_C2K_SUPPORT)), yes)
+    LOCAL_CFLAGS += -DC2K_SUPPORT
+
+endif
+
+ifeq ($(strip $(MTK_MULTI_SIM_SUPPORT)), dsds)
+    LOCAL_CFLAGS += -DANDROID_SIM_COUNT_2 \
+                     -DANDROID_MULTI_SIM \
+                     -DMODE_DSDS
+endif
+
+ifeq ($(strip $(MTK_MULTI_SIM_SUPPORT)), dsss)
+    LOCAL_CFLAGS += -DMODE_DSSS
+endif
+
+$(warning ################# TARGET_PLATFORM: $(TARGET_PLATFORM))
+ifeq ($(strip $(TARGET_PLATFORM)), mt2731)
+$(warning ################# TARGET_PLATFORM_MT2731)
+    LOCAL_CFLAGS += -DTARGET_PLATFORM_MT2731 \
+                    -DMD_93_SUPPORT
+else ifeq ($(strip $(TARGET_PLATFORM)), mt2635)
+$(warning ################# TARGET_PLATFORM_MT2635)
+    LOCAL_CFLAGS += -DTARGET_PLATFORM_MT2635 \
+                    -DMD_90_SUPPORT
+endif
+
+$(warning ################# RITA ROOT: $(ROOT),includedir:$(includedir))
+LOCAL_PATH   = .
+
+LOCAL_C_INCLUDES = \
+  -I. \
+  -I$(LOCAL_PATH)/include \
+
+
+LOCAL_LIBS := \
+    -L. \
+    -ldl \
+    -lpthread \
+
+SOURCES = $(wildcard *.c wildcard *.h src/*.c)
+
+EXECUTABLE = liblynq-thermal.so
+
+OBJECTS=$(SOURCES:.c=.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 : %.c
+	$(CC) $(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)
diff --git a/IC_src/mtk/lib/liblynq-thermal/src/lynq_get_thermal.c b/IC_src/mtk/lib/liblynq-thermal/src/lynq_get_thermal.c
new file mode 100755
index 0000000..dad9076
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-thermal/src/lynq_get_thermal.c
@@ -0,0 +1,74 @@
+#include <sys/types.h>

+#include <dirent.h>

+#include <unistd.h>

+#include <stdio.h>

+#include <string.h>

+#include <fcntl.h>

+#include <stdlib.h>

+#include <unistd.h>

+#include "liblynq-thermal/lynq_get_thermal.h"

+

+

+char* lynq_read_version()

+{

+    return "THERMAL-V1.0";

+}

+

+int read_sys_info(char *sys_path, char *out_buf, int out_buf_len)

+{

+    int fd, ret;

+    char buf[LYNQ_THM_PATH] = "";

+

+    if (NULL == out_buf)

+        return LYNQ_THM_ZONE_ERROR;

+

+    if ((access(sys_path, F_OK)) == -1)

+        return LYNQ_THM_ACCESS_ERROR;

+

+    fd = open(sys_path, O_RDONLY);

+

+    if (fd < 0)

+    {

+        printf("[%s-%d] open error!!!\n", __FUNCTION__, __LINE__);

+        return LYNQ_THM_OPEN_ERROR;

+    }

+

+    ret = read(fd, buf, sizeof(buf));

+

+

+    if(ret<0){

+        close(fd);

+        printf("[%s-%d] read error!!!\n", __FUNCTION__, __LINE__);

+        return LYNQ_THM_READ_ERROR;

+    }

+    memcpy(out_buf, buf, out_buf_len);

+    close(fd);

+

+    return LYNQ_THM_OK;

+}

+

+int lynq_get_zone_tmp(ZONE_NUM num, int *temp)

+{

+    char tz_path[LYNQ_THM_PATH] = "";

+    char buf[LYNQ_THM_PATH] = "";

+

+    if(num < 0 || num > 19)

+    {

+        printf("[%s-%d] no such device,please reinput!!\n", __FUNCTION__, __LINE__);

+        return  LYNQ_THM_ZONE_ERROR;

+    }

+

+    if(NULL == temp)

+        return LYNQ_THM_ZONE_ERROR;

+    

+    sprintf(tz_path, "%s/%s%d/temp", TYPE_PATH_PRE, LYNQ_THM_ZONE_KEY, num);

+

+    int ret = read_sys_info(tz_path, buf, LYNQ_THM_PATH);

+    if(!ret)

+    {

+        if(strlen(buf))

+            *temp = atoi(buf);

+    }

+

+    return ret;

+}

diff --git a/IC_src/mtk/lib/liblynq-wifi6/include/libwifi6.h b/IC_src/mtk/lib/liblynq-wifi6/include/libwifi6.h
new file mode 100755
index 0000000..53006b8
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-wifi6/include/libwifi6.h
@@ -0,0 +1,272 @@
+/**@File libwifi6.h
+*  @Brief :about function test
+*  @details :
+*  @Author : qs.xiong
+*  @Date : 2022-3-14
+*  @Version : V1.0
+*  @copy ritght : Copyright (c) MobileTek
+*/
+#ifndef __LIBWIFI6_H__
+#define __LIBWIFI6_H__
+
+typedef enum {
+    LYNQ_WIFI_BANDWIDTH_HT10 = 0, // not support in ap mode
+    LYNQ_WIFI_BANDWIDTH_HT20,
+    LYNQ_WIFI_BANDWIDTH_HT40,    // not support in ap mode
+    LYNQ_WIFI_BANDWIDTH_HT80,
+}lynq_wifi_bandwidth_type_m;
+
+typedef enum {
+    LYNQ_WIFI_AUTH_OPEN = 0,
+    LYNQ_WIFI_AUTH_WEP,            // not support WEP
+    LYNQ_WIFI_AUTH_WPA_PSK,
+    LYNQ_WIFI_AUTH_WPA2_PSK,
+    LYNQ_WIFI_AUTH_WPA2_WPA3_PSK,
+    LYNQ_WIFI_AUTH_WPA3_PSK,
+}lynq_wifi_auth_s;
+
+typedef enum {
+    LYNQ_WIFI_2G_band = 1,
+    LYNQ_WIFI_5G_band,
+    LYNQ_WIFI_2_and_5G_band,  //not support
+}lynq_wifi_band_m;
+
+typedef enum {
+    LYNQ_WIFI_AP_STATUS_DISABLE = 0,   
+    LYNQ_WIFI_AP_STATUS_ENABLE,        //ap is running status
+}lynq_wifi_ap_run_status_s;
+
+typedef enum {
+    LYNQ_WIFI_STA_STATUS_DISABLE = 0,
+    LYNQ_WIFI_STA_STATUS_ENABLE,       //sta is running status
+}lynq_wifi_sta_run_status_s;
+
+typedef enum {
+    LYNQ_WIFI_INTERFACE_0 = 0,      //sta
+    LYNQ_WIFI_INTERFACE_1,         //ap
+}lynq_wifi_index_e;
+
+typedef enum {
+    LYNQ_WIFI_STATUS_DISCONNECT = 0,
+    LYNQ_WIFI_STATUS_CONNECT,
+    LYNQ_WIFI_SERVICE_ABNORMAL,
+}lynq_wifi_ap_status_s;
+
+typedef struct ap_info
+{
+    char ap_ip[32];
+    char ap_mac[32];
+    char ap_ssid[64];
+    char psw[64];                      //password 
+    lynq_wifi_auth_s auth;
+    lynq_wifi_band_m band;
+}ap_info_s;
+
+typedef struct device_info
+{
+    char sta_ip[32];
+    char sta_mac[32];
+    char hostname[32];
+    lynq_wifi_ap_status_s status;
+}device_info_s;                
+
+typedef struct scan_info
+{
+    char mac[32];
+    char ssid[64];
+    lynq_wifi_band_m band;
+    lynq_wifi_auth_s auth;
+    int rssi;
+}scan_info_s;
+
+typedef struct ap_detail_info
+{
+    struct ap_info base_info;            // base_info : base info of strcut ap_info 
+    lynq_wifi_ap_run_status_s status;     // status:is not running 1:is running
+    int rssi;                         //[0~199]
+}ap_detail_info_s;
+
+typedef struct saved_ap_info
+{
+    struct ap_info base_info;
+}saved_ap_info_s;
+
+
+// insmod drive and start service of wifi
+int lynq_wifi_enable(void);
+//rmmod drive
+int lynq_wifi_disable(void);
+//set ssid of ap
+int lynq_wifi_ap_ssid_set(lynq_wifi_index_e idx,char *ap_ssid);
+//get ap of ssid
+int lynq_wifi_ap_ssid_get(lynq_wifi_index_e idx,char *ap_ssid);
+
+//set frquency for ap
+int lynq_wifi_ap_frequency_set(lynq_wifi_index_e idx,int lynq_wifi_frequency);
+//get freuency of ap
+int lynq_wifi_ap_frequency_get(lynq_wifi_index_e idx,int *lynq_wifi_frequency);
+
+//set bandwidth for ap
+int lynq_wifi_ap_bandwidth_set(lynq_wifi_index_e idx,lynq_wifi_bandwidth_type_m bandwidth);
+//get thr bandwidth of ap
+int lynq_wifi_ap_bandwidth_get(lynq_wifi_index_e idx,lynq_wifi_bandwidth_type_m *bandwidth);
+
+//set channel for ap
+int lynq_wifi_ap_channel_set( lynq_wifi_index_e idx,int channel);
+//get channel of ap 
+int lynq_wifi_ap_channel_get( lynq_wifi_index_e idx,int* channel);
+
+//set auth for ap
+int lynq_wifi_ap_auth_set(lynq_wifi_index_e idx, lynq_wifi_auth_s auth);
+//get ap auth
+int lynq_wifi_ap_auth_get(lynq_wifi_index_e idx, lynq_wifi_auth_s *auth);
+
+//start ap
+int lynq_wifi_ap_start(lynq_wifi_index_e idx);
+//stop ap
+int lynq_wifi_ap_stop(lynq_wifi_index_e idx);
+//restart ap
+int lynq_wifi_ap_restart(lynq_wifi_index_e idx);
+
+//hide ssid
+int lynq_wifi_ap_hide_ssid(lynq_wifi_index_e idx);
+//unhide ssid
+int lynq_wifi_ap_unhide_ssid(lynq_wifi_index_e idx);
+
+//set the password for ap
+int lynq_ap_password_set(lynq_wifi_index_e idx, char *password);
+//get the ap password
+int lynq_ap_password_get(lynq_wifi_index_e idx, char *password);
+
+//set the password to connet to dest_ap
+int lynq_sta_ssid_password_set(lynq_wifi_index_e idx, ap_info_s *ap, char *password);
+int lynq_sta_ssid_password_get(lynq_wifi_index_e idx, ap_info_s *ap, char *password);
+
+//get the ssid of sta
+int lynq_wifi_get_sta_ssid(lynq_wifi_index_e idx,char *sta_ssid);
+//get availble device info such as:ssid mac band rssi status auth
+int lynq_wifi_get_sta_available_ap(lynq_wifi_index_e idx,ap_detail_info_s *info);  
+
+
+
+//get the sta connect ap auth
+int lynq_wifi_get_sta_auth(lynq_wifi_index_e idx, lynq_wifi_auth_s* auth);    //auth 0:OPEN 1:WEP 2:WPA-PSK 3:WPA2-PSK
+
+//sta start connect to dest_ap
+int lynq_wifi_sta_connect(lynq_wifi_index_e idx, char *ssid, lynq_wifi_auth_s auth, char *psw);
+int lynq_wifi_sta_connect_timeout(lynq_wifi_index_e idx, char *ssid, lynq_wifi_auth_s auth, char *psw, int timeout);
+//disconnect 
+int lynq_wifi_sta_disconnect(lynq_wifi_index_e idx,char *ssid);
+int lynq_wifi_sta_disconnect_ap(lynq_wifi_index_e idx,char *ssid);
+
+//start sta mode;enable sta
+int lynq_wifi_sta_start(lynq_wifi_index_e idx);
+int lynq_wifi_sta_start_auto(lynq_wifi_index_e idx);
+//stop sta:disable sta
+int lynq_wifi_sta_stop(lynq_wifi_index_e idx);
+
+//Get all device info linked ap
+int lynq_get_ap_device_list(lynq_wifi_index_e idx, ap_info_s **ap, device_info_s ** list,int * len);        //list info:mac ip hostname status  len:device len
+//Get scan_result info
+int lynq_get_scan_list(lynq_wifi_index_e idx, scan_info_s ** list,int * len);                    //list info:mac ssid band auth rssi    len:scan_info len
+int lynq_sta_forget_ap(lynq_wifi_index_e idx, char *ssid,lynq_wifi_auth_s auth);
+int lynq_get_sta_saved_ap(lynq_wifi_index_e idx,saved_ap_info_s ** list,int * len);      //len: length of saved_ap_info
+
+//start scan availbale ap active
+int lynq_wifi_sta_start_scan(lynq_wifi_index_e idx);
+
+//add for STA auto connect
+int lynq_wifi_sta_stop_net(lynq_wifi_index_e idx,int networkid);
+/*
+ * event usage:
+ * first declare a funcion like AP_CALLBACK_FUNC_PTR to recv messge from wifi lib
+ * call lynq_reg_ap_event_callback to register whih private data pointer and the callback fuction pointer declared before
+ * when envent comes the last registered callback function will been called
+ */
+
+typedef void(*AP_CALLBACK_FUNC_PTR)(void *priv, lynq_wifi_ap_status_s status);
+int lynq_reg_ap_event_callback(void *priv, AP_CALLBACK_FUNC_PTR cb);
+int lynq_unreg_ap_event_callback(void *priv);
+
+typedef enum {
+    LYNQ_WIFI_STA_STATUS_DISCONNECT = 0,
+    LYNQ_WIFI_STA_STATUS_CONNECT,
+    LYNQ_WIFI_STA_STATUS_SCAN_RESULT,    //finish sta scan 
+    LYNQ_WIFI_STA_STATUS_CONNECT_FAIL,
+    LYNQ_WIFI_STA_SERVICE_ABNORMAL,
+    LYNQ_WIFI_STATUS_EGNORE,
+}lynq_wifi_sta_status_s;
+typedef enum
+{
+    LYNQ_TIME_OUT = 0,
+    LYNQ_UNSPECIFIED_REASON,
+    LYNQ_AUTHENTICATION_NO_LONGER_VALID,
+    LYNQ_PSW_ERROR,
+    LYNQ_AUTH_ERROR,
+    LYNQ_AP_UNABLE_HANDLE,
+    LYNQ_NOT_FIND_AP,
+    LYNQ_WAIT_CONNECT_ACTIVE,
+}error_number_s;
+
+typedef void(*STA_CALLBACK_FUNC_PTR)(void *priv, lynq_wifi_sta_status_s status, error_number_s number);
+int lynq_reg_sta_event_callback(void * priv, STA_CALLBACK_FUNC_PTR cb);
+int lynq_unreg_sta_event_callback(void * priv);
+typedef void(*STA_AUTO_CALLBACK_FUNC_PTR)(void *priv, lynq_wifi_sta_status_s status, error_number_s number,int networkid);
+int lynq_reg_sta_auto_event_callback(void * priv, STA_AUTO_CALLBACK_FUNC_PTR cb);
+int lynq_unreg_sta_auto_event_callback(void * priv);
+
+//get current ap status
+int lynq_get_ap_status(lynq_wifi_index_e idx, lynq_wifi_ap_run_status_s * ap_status);
+//get curent sta status
+int lynq_get_sta_status(lynq_wifi_index_e idx, lynq_wifi_sta_run_status_s * sta_status);
+
+//set the country code 
+int lynq_get_country_code(lynq_wifi_index_e idx, char *country_code);
+//get current country code
+int lynq_set_country_code(lynq_wifi_index_e idx, char *country_code);
+
+//get wlan0/ap0 ip or mac
+int lynq_get_interface_ip(lynq_wifi_index_e idx,char *ip);
+int lynq_get_interface_mac(lynq_wifi_index_e idx,char *mac);   
+
+
+//get current connect ap mac rssi band
+int lynq_get_connect_ap_mac(lynq_wifi_index_e idx,char *mac);
+int lynq_get_connect_ap_rssi(lynq_wifi_index_e idx,int * rssi);
+int lynq_get_connect_ap_band(lynq_wifi_index_e idx,lynq_wifi_band_m * band);
+int lynq_get_connect_ap_ip(lynq_wifi_index_e idx,char *ip);
+int lynq_get_sta_connected_dns(lynq_wifi_index_e idx,char *dns);
+/*****add limit of connected ap device number 2022.10.12 by qs.xiong
+ *
+ *sta_number:
+ *      ap max be connected no more than 15
+ *      so sta_number : [1-15] 
+ */
+int lynq_ap_connect_num(int sta_number);
+
+/****add acs contrl api*****************
+ *
+ *idx:
+ *    1 is ap and only 1 is legal in this api
+ *acs_mode:
+ *       2 is open acs at 2.4GHz
+ *       5 is open acs at 5GHz
+ *       didnt ssuport 2.4G&5G  together
+ * add by qs.xiong 20221012*************/
+int lynq_enable_acs(lynq_wifi_index_e idx,int acs_mode);
+
+//you.chen add for tv-box start
+/**
+ * @brief enableGBW, repeat call will fail before disableGBW
+ * @param mac of tv-box
+ * @return
+ */
+int enableGBW(const char* mac);
+/**
+ * @brief disableGBW
+ * @return
+ */
+int disableGBW();
+//you.chen add for tv-box end
+
+#endif
diff --git a/IC_src/mtk/lib/liblynq-wifi6/libwifi6.c b/IC_src/mtk/lib/liblynq-wifi6/libwifi6.c
new file mode 100755
index 0000000..60c4224
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-wifi6/libwifi6.c
@@ -0,0 +1,5221 @@
+/**@File lib_wifi6.c
+*  @Brief :about function test
+*  @details :
+*  @Author : you.chen
+*  @Date : 2022-4-6
+*  @Version : V1.0
+*  @copy ritght : Copyright (c) MobileTek
+*/
+#include <log/log.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+#include "libwifi6.h"
+#include <wpa_ctrl.h>
+#include <string.h>
+#include <time.h>
+#include <pthread.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <ifaddrs.h>
+#include "log/log.h"
+#include <sys/time.h>
+#include <asm/errno.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+#undef LOG_TAG
+#define LOG_TAG "LYNQ_WIFI"
+#define MAX_CMD 128
+#define MAX_RET 4096
+#define MODE_LEN 10
+#define CTRL_STA 0
+#define CTRL_AP 1
+#define AP_NETWORK_0 0
+#define STA_MAX_SAVED_AP_NUM 50
+#define MAC_LEN 17
+
+pthread_t g_ap_watcher_pid = 0;
+volatile int g_ap_watcher_stop_flag = 0;
+volatile int g_ap_watcher_started_flag = 0;
+
+pthread_t g_ap_tmp_watcher_pid = 0;
+volatile int g_ap_tmp_watcher_stop_flag = 0;
+
+pthread_t g_sta_watcher_pid = 0;
+volatile int g_sta_watcher_stop_flag = 0;
+volatile int g_sta_scan_finish_flag = 1;
+volatile int g_sta_watcher_started_flag = 0;
+volatile int g_sta_conncet_status_flag = 0;
+volatile int g_sta_fake_scan_finish_flag = 0;
+
+pthread_t g_sta_auto_watcher_pid = 0;
+volatile int g_sta_auto_watcher_stop_flag = 0;
+volatile int g_sta_auto_scan_finish_flag = 1;
+volatile int g_sta_auto_watcher_started_flag = 0;
+void * g_ap_callback_priv = NULL;
+AP_CALLBACK_FUNC_PTR g_ap_callback_func = NULL;
+void * g_sta_callback_priv = NULL;
+STA_CALLBACK_FUNC_PTR g_sta_callback_func = NULL;
+void * g_sta_auto_callback_priv = NULL;
+STA_AUTO_CALLBACK_FUNC_PTR g_sta_auto_callback_func = NULL;
+
+
+//const char * CTRL_PATH="/var/run/wpa_supplicant";
+const char * CTRL_PATH[2] = {"/var/run/wpa_supplicant/wlan0", "/var/run/wpa_supplicant/ap0"};
+//const char * CTRL_PATH[2] = {"/var/run/wpa_supplicant/wlan0", "/var/run/wpa_supplicant/wlan0"};
+const char * cmd_list_networks = "LIST_NETWORKS";
+const char * cmd_save_config = "SAVE_CONFIG";
+const char * cmd_disconnect = "DISCONNECT";
+const char * cmd_remove_all = "REMOVE_NETWORK all";
+const char * state_scan_result = "CTRL-EVENT-SCAN-RESULTS";
+const char * STATE_COMPLETED = "COMPLETED";
+const char * STATE_SCANNING = "SCANNING";
+const char * STATE_DISCONNECTED = "DISCONNECTED";
+
+const char * cmd_ping = "PING";
+const char * rsp_pong = "PONG";
+const int SLEEP_TIME_ON_IDLE = 100 * 1000; // usecond
+const int MAX_IDLE_COUNT = 600; // 60s
+
+const char * start_wg870_service_script = "/etc/wg870/scripts/start_wg870_service.sh";
+const char * get_interface_name_script = "/etc/wg870/scripts/get_interface_name.sh";
+const char * start_stop_sta_script = "/etc/wg870/scripts/start_stop_sta.sh";
+const char * start_stop_ap_script = "/etc/wg870/scripts/start_stop_ap.sh";
+const char * sta_status_change_script = "/etc/wg870/scripts/sta_status_change.sh";
+
+static char s_ap_iterface_name[64] = {0};
+
+struct local_wpa_ctrl{
+    struct wpa_ctrl *ctrl;
+    pthread_mutex_t mutex;
+};
+
+volatile int g_history_disconnect_valid_num = 0;
+int g_history_disconnect_net[128];
+
+static pthread_mutex_t s_check_wpa_ctrl_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t s_sta_callback_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t s_ap_callback_mutex = PTHREAD_MUTEX_INITIALIZER;
+// add for auto connect
+static pthread_mutex_t s_sta_auto_callback_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static struct local_wpa_ctrl * g_lynq_wpa_ctrl[2] = {0};
+
+//you.chen add for tv-box start
+volatile int g_gbw_enabled = 0;
+char * g_gbw_mac = NULL;
+pthread_t g_gbw_watcher_pid = 0;
+static int startGBW();
+static int stopGBW();
+//you.chen add for tv-box end
+
+typedef struct __curr_status_info {
+    ap_info_s *ap;
+    char * state;
+    int net_no;
+}curr_status_info;
+
+typedef enum {
+    INNER_STA_STATUS_INIT = 0,
+    INNER_STA_STATUS_CONNECTING,
+    INNER_STA_STATUS_ASSOCIATING,
+    INNER_STA_STATUS_ASSOCIATED,
+    INNER_STA_STATUS_CONNECTED,
+    INNER_STA_STATUS_DISCONNECTING,
+    INNER_STA_STATUS_DISCONNECTED,
+    INNER_STA_STATUS_CANCEL,
+}inner_sta_status_s;
+
+static pthread_cond_t s_global_check_cond = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t s_global_check_mutex = PTHREAD_MUTEX_INITIALIZER;
+volatile inner_sta_status_s s_sta_status = INNER_STA_STATUS_INIT;
+static error_number_s s_sta_error_number = -1;
+static char s_sta_current_connecting_ssid[64] = {0};
+static struct timespec s_sta_connect_timeout;
+const int MAX_CONNNECT_TIME = 15; // second
+pthread_t g_global_watcher_pid = 0;
+static int s_service_invoke_timeout_cnt=0;
+const int FAKE_MAX_INT_VALUE = 99999;
+
+static void print_disconnect_list()
+{
+    int i;
+    for( i = 0; i < g_history_disconnect_valid_num; i++ )
+    {
+        RLOGD(" list of g_history_disconnect_valid_num is  %d histroy_list[%d]:%d --------- %d",g_history_disconnect_valid_num,i,g_history_disconnect_net[i],__LINE__);
+    }
+
+    return;
+}
+
+// idex  ----> history_disconnect_list[x]  index
+static int removeElement(int idex)
+{
+    RLOGD("into removeElement");
+    if( index < 0 )
+    {
+        RLOGD("WIFI [removeElement] input idex < 0,idex is %d: ",idex);
+        return -1;
+    }
+    RLOGD("%s line: %d  g_history_disconnect_net[%d]: %d  end g_history_disconnect_net[%d]:%d",__func__,__LINE__,idex,g_history_disconnect_net[idex],g_history_disconnect_valid_num-1, g_history_disconnect_net[g_history_disconnect_valid_num-1]);
+    g_history_disconnect_net[idex] = g_history_disconnect_net[g_history_disconnect_valid_num-1];    //g_history_disconnect_vaild_num  -1 for get last index
+    g_history_disconnect_valid_num --;
+    RLOGD("end removeElement");
+    return 0;
+}
+static int check_history_disconenct_ap_list(int val)
+{
+    print_disconnect_list();
+    RLOGD("WIFI[check_history_disconenct_ap_list]into check_history_disconenct_ap_list && input val is %d g_history_disconnect_valid_num is %d line",val,g_history_disconnect_valid_num,__LINE__);
+    int i;
+    for( i = 0; i < g_history_disconnect_valid_num; i++)
+    {
+        if( val == g_history_disconnect_net[i] )
+        {
+             RLOGD("[wifi]-----input val is %d,g_history_disconnect_net[%d]:%d",val,i,g_history_disconnect_net[i]);
+             RLOGD("end check_history_disconenct_ap_list && return network index");
+             return i;
+        }
+    }
+    RLOGD("end check_history_disconenct_ap_list && return fail,didn't need remove networkid %d from list  g_history_disconnect_valid_num is %d line %d",val,g_history_disconnect_valid_num,__LINE__);
+    return -1;
+}
+
+
+static void lynq_sta_removeElement(int net_no)
+{
+    int ret;
+
+    ret = check_history_disconenct_ap_list(net_no);
+    if( ret == -1 )
+    {
+        RLOGD("curr_net_no not in history_disconenct_lsit,return 0 %s %d",__func__,__LINE__);
+        return;
+    }else
+    {
+        ret = removeElement(ret);
+        if( ret == 0 )
+        {
+            RLOGD("removeElement pass %s %d",__func__,__LINE__);
+            return;
+        }
+    }
+
+    return;
+}
+
+static void notify_service_invoke_fail(int error)
+{
+    struct local_wpa_ctrl *lynq_wpa_ctrl = NULL;
+    pthread_mutex_lock(&s_global_check_mutex);
+    if (error == -2) //timeout
+    {
+        s_service_invoke_timeout_cnt++;
+        if (s_service_invoke_timeout_cnt > 10)
+        {
+            pthread_cond_signal(&s_global_check_cond);
+        }
+    }
+    else if (error == -1)
+    {
+        // check if can connect wpa service
+        lynq_wpa_ctrl = wpa_ctrl_open(CTRL_PATH[0]);
+        if (lynq_wpa_ctrl == NULL)
+        {
+            s_service_invoke_timeout_cnt = FAKE_MAX_INT_VALUE;
+            pthread_cond_signal(&s_global_check_cond);
+        }
+        wpa_ctrl_close(lynq_wpa_ctrl);
+        lynq_wpa_ctrl = wpa_ctrl_open(CTRL_PATH[1]);
+        if (lynq_wpa_ctrl == NULL)
+        {
+            s_service_invoke_timeout_cnt = FAKE_MAX_INT_VALUE;
+            pthread_cond_signal(&s_global_check_cond);
+        }
+        wpa_ctrl_close(lynq_wpa_ctrl);
+    }
+
+    pthread_mutex_unlock(&s_global_check_mutex);
+}
+
+static int system_call_v(const char * fmt, ...)
+{
+    char str_cmd[256] = {0};
+    va_list args;
+    va_start(args, fmt);
+    vsprintf(str_cmd, fmt, args);
+    va_end(args);
+    printf("system call----------%s\n", str_cmd);
+    return system(str_cmd);
+}
+
+static int exec_cmd(const char *str_cmd, char * str_cmd_ret, size_t max_len);
+
+static const char * inner_get_ap_interface_name()
+{
+    char * p;
+    char cmd[128]={0};
+
+    sprintf(cmd, "%s %d", get_interface_name_script, LYNQ_WIFI_INTERFACE_1);
+    if (0 != exec_cmd(cmd, s_ap_iterface_name, sizeof(s_ap_iterface_name)) || s_ap_iterface_name[0] == '\0')
+    {
+        memset(s_ap_iterface_name, 0, sizeof (s_ap_iterface_name));
+        return NULL;
+    }
+    p = strchr(s_ap_iterface_name, ' ');
+    if (NULL != p)
+    {
+        *p = '\0';
+    }
+    p = strchr(s_ap_iterface_name, '\n');
+    if (NULL != p)
+    {
+        *p = '\0';
+    }
+    if (s_ap_iterface_name[0] == '\0')
+    {
+        return NULL;
+    }
+
+    return s_ap_iterface_name;
+}
+
+static void check_tether_and_notify()
+{
+    RLOGD("check_tether_and_notify called");
+    if (inner_get_ap_interface_name() == NULL || 0 == system_call_v("ifconfig | grep %s", s_ap_iterface_name))
+    {
+        return;
+    }
+    pthread_mutex_lock(&s_global_check_mutex);
+    s_service_invoke_timeout_cnt = FAKE_MAX_INT_VALUE;
+    pthread_cond_signal(&s_global_check_cond);
+    pthread_mutex_unlock(&s_global_check_mutex);
+}
+
+static int local_wpa_ctrl_request(struct local_wpa_ctrl *ctrl, const char *cmd, size_t cmd_len,
+                            char *reply, size_t *reply_len,
+                                  void (*msg_cb)(char *msg, size_t len))
+{
+    int ret;
+    if (ctrl->ctrl == NULL) {
+        RLOGE("local_wpa_ctrl_request ctrl is null\n");
+        return -1;
+    }
+    pthread_mutex_lock(&ctrl->mutex);
+    ret = wpa_ctrl_request(ctrl->ctrl, cmd, cmd_len, reply, reply_len, msg_cb);
+    pthread_mutex_unlock(&ctrl->mutex);
+    if (ret != 0)
+    {
+        notify_service_invoke_fail(ret);
+    }
+    return ret;
+}
+
+static struct local_wpa_ctrl * inner_get_wpa_ctrl(int index) {
+    int repeat_cnt;
+    struct local_wpa_ctrl *lynq_wpa_ctrl = NULL;
+    pthread_mutex_lock(&s_check_wpa_ctrl_mutex);
+    RLOGD("inner_get_wpa_ctrl\n");
+    for (repeat_cnt = 0; repeat_cnt < 5 && NULL == g_lynq_wpa_ctrl[index]; repeat_cnt++) {
+        pthread_mutex_unlock(&s_check_wpa_ctrl_mutex);
+//        printf("wait enable finish\n");
+        usleep(500 * 1000);
+        pthread_mutex_lock(&s_check_wpa_ctrl_mutex);
+    }
+    if (NULL == g_lynq_wpa_ctrl[index]) {
+        RLOGE("NULL == g_lynq_wpa_ctrl[index]");
+        goto out_addr;
+    }
+    if (NULL == g_lynq_wpa_ctrl[index]->ctrl) {
+        g_lynq_wpa_ctrl[index]->ctrl = wpa_ctrl_open(CTRL_PATH[index]);
+        if (NULL == g_lynq_wpa_ctrl[index]->ctrl) {
+            RLOGE("wpa_ctrl_open fail\n");
+            goto out_addr;
+        }
+        pthread_mutex_init(&g_lynq_wpa_ctrl[index]->mutex, NULL);
+    }
+    lynq_wpa_ctrl = g_lynq_wpa_ctrl[index];
+out_addr:
+    pthread_mutex_unlock(&s_check_wpa_ctrl_mutex);
+    return lynq_wpa_ctrl;
+}
+
+#define PRINT_AND_RETURN_VALUE(str,value) \
+{\
+    perror((str));\
+    return (value);\
+}
+
+#define CHECK_IDX(idx, type) do { \
+        if ( (idx == LYNQ_WIFI_INTERFACE_0 && type != CTRL_STA) || (idx == LYNQ_WIFI_INTERFACE_1 && type != CTRL_AP) \
+                || idx < LYNQ_WIFI_INTERFACE_0 || idx > LYNQ_WIFI_INTERFACE_1 ) { \
+            RLOGE("not support create [%s] on interface [%d]\n", (type == CTRL_STA ? "station" : "ap"), idx); \
+            return -1; \
+        } \
+    }while (0)
+
+#define CHECK_WPA_CTRL(index) int ret = 0;\
+    size_t reply_len = MAX_RET; \
+    char cmd_reply[MAX_RET]={0}; \
+    struct local_wpa_ctrl *lynq_wpa_ctrl = NULL; \
+    do{ \
+        lynq_wpa_ctrl = inner_get_wpa_ctrl(index); \
+        if (NULL == lynq_wpa_ctrl) return -1; \
+    }while(0)
+
+#define DO_REQUEST(cmd_str) do { \
+        reply_len = MAX_RET;\
+        cmd_reply[0] = '\0'; \
+        RLOGD("to call [%s]\n", cmd_str);  \
+        ret = local_wpa_ctrl_request(lynq_wpa_ctrl, cmd_str, strlen(cmd_str), cmd_reply, &reply_len, NULL); \
+        if (ret != 0) { \
+            RLOGE("call "#cmd_str" fail %d\n", ret); \
+            return ret; \
+        } \
+        cmd_reply[reply_len+1] = '\0'; \
+        RLOGD("cmd replay [ %s ]\n", cmd_reply); \
+    }while(0)
+
+#define DO_OK_FAIL_REQUEST(cmd_str) do { \
+        DO_REQUEST(cmd_str); \
+        if (reply_len >=4 && memcmp(cmd_reply, "FAIL", 4) == 0 ) {\
+            RLOGE("cmd "#cmd_str" return FAIL\n"); \
+            return -1; \
+        } else if (reply_len >=2 && memcmp(cmd_reply, "OK", 2) != 0) { \
+            RLOGE("cmd "#cmd_str" return not OK|FAIL\n"); \
+            return -1; \
+        } \
+    }while (0)
+
+
+static int check_connection(struct wpa_ctrl * wpa_ctrl)
+{
+    size_t reply_len = MAX_RET;
+    char cmd_reply[MAX_RET]={0};
+    int ret;
+
+    RLOGD("check_connection [%p]", wpa_ctrl);
+    ret = wpa_ctrl_request(wpa_ctrl, cmd_ping, strlen(cmd_ping), cmd_reply, &reply_len, NULL);
+
+    if (ret != 0 || reply_len < 4 || memcmp(cmd_reply, rsp_pong, 4) != 0)
+    {
+        RLOGE("check_connection error: ctrl [%p], ret [%d], reply_len [%d], rsp [%s]", wpa_ctrl, ret, reply_len, cmd_reply);
+        if (ret != 0)
+        {
+            notify_service_invoke_fail(ret);
+        }
+        return -1;
+    }
+
+    return 0;
+}
+
+/**
+ * @brief check_pending_msg
+ * @param lynq_wpa_ctrl
+ * @return 1 has msg, 0 no msg, -1 error
+ */
+static int check_pending_msg(struct wpa_ctrl ** pp_lynq_wpa_ctrl, int type, int* idle_count, int *started_flag)
+{
+    int ret;
+
+    if (*pp_lynq_wpa_ctrl == NULL) // need connect
+    {
+        *pp_lynq_wpa_ctrl = wpa_ctrl_open(CTRL_PATH[type]); //@todo temp change
+        if (*pp_lynq_wpa_ctrl == NULL)
+        {
+            usleep(SLEEP_TIME_ON_IDLE);
+            return -1;
+        }
+
+        ret = wpa_ctrl_attach(*pp_lynq_wpa_ctrl);
+        if (ret == 0) // attach success
+        {
+            *started_flag = 1;
+        }
+        else
+        {
+            RLOGE("[wifi error]sta watch thread wpa_ctrl_attach fail");
+            wpa_ctrl_close(*pp_lynq_wpa_ctrl);
+            *pp_lynq_wpa_ctrl = NULL;
+            *idle_count = 0;
+            notify_service_invoke_fail(-2);
+            usleep(SLEEP_TIME_ON_IDLE);
+            return -1;
+        }
+    }
+
+    ret = wpa_ctrl_pending(*pp_lynq_wpa_ctrl);
+    if ( ret == 0) // no pending messages
+    {
+        usleep(SLEEP_TIME_ON_IDLE);
+        *idle_count += 1;
+        if (*idle_count > MAX_IDLE_COUNT)
+        {
+            if (check_connection(*pp_lynq_wpa_ctrl) != 0)
+            {
+                wpa_ctrl_detach(*pp_lynq_wpa_ctrl);
+                wpa_ctrl_close(*pp_lynq_wpa_ctrl);
+                *pp_lynq_wpa_ctrl = NULL;
+                *idle_count = 0;
+                return -1;
+            }
+            *idle_count = 0;
+        }
+        return 0;
+    }
+    else if ( ret == -1) // on error
+    {
+        RLOGE("[wifi error]sta wpa_ctrl_pending");
+        wpa_ctrl_detach(*pp_lynq_wpa_ctrl);
+        wpa_ctrl_close(*pp_lynq_wpa_ctrl);
+        *pp_lynq_wpa_ctrl = NULL;
+        *idle_count = 0;
+        notify_service_invoke_fail(ret);
+        return -1;
+    }
+
+    *idle_count = 0;
+    return 1;
+}
+
+static inline void inner_notify_ap_msg(lynq_wifi_ap_status_s status)
+{
+    pthread_mutex_lock(&s_ap_callback_mutex);
+    if (g_ap_callback_func != NULL)
+        g_ap_callback_func(g_ap_callback_priv, status);
+    pthread_mutex_unlock(&s_ap_callback_mutex);
+}
+
+static void APWatcherThreadProc() {
+    size_t len = MAX_RET;
+    char msg_notify[MAX_RET];
+    int idle_count = 0;
+    char *ptr = NULL;
+    char mac[32] = {0};
+    char cmd[256] = {0};
+
+    struct wpa_ctrl *lynq_wpa_ctrl = NULL;
+    g_ap_watcher_stop_flag = 0;
+
+    while (g_ap_watcher_stop_flag == 0)
+    {
+        if (check_pending_msg(&lynq_wpa_ctrl, CTRL_AP, &idle_count, &g_ap_watcher_started_flag) != 1)
+        {
+            if (g_ap_callback_func != NULL && idle_count == MAX_IDLE_COUNT - 100 )
+            {
+                check_tether_and_notify();
+            }
+
+            continue;
+        }
+
+        memset(msg_notify, 0, MAX_RET);
+        len = MAX_RET;
+        if (!wpa_ctrl_recv(lynq_wpa_ctrl, msg_notify, &len))
+        {
+            msg_notify[len+1] = '\0';
+            RLOGD("APWatcherThreadProc ap------> %s\n", msg_notify);
+            //you.chen change for tv-box start
+            if (strstr(msg_notify, "AP-STA-DISCONNECTED") != NULL)
+            {
+                inner_notify_ap_msg(LYNQ_WIFI_STATUS_DISCONNECT);
+                ptr = strstr(msg_notify, "AP-STA-DISCONNECTED");
+                if( ptr != NULL)
+                {
+                    ptr += strlen("AP-STA-DISCONNECTED ");
+                    memcpy(mac,ptr,17);
+                    sprintf(cmd,"cat /run/wg870/ap0.lease | grep \"%s\" | awk '{print \"dhcp_release ap0 \"$3\" \"$2\}' | sh",mac);
+                    RLOGD("%s %d cmd is %s",__func__,__LINE__,cmd);
+                    system(cmd);
+                }
+
+                if (g_gbw_enabled == 1 && g_gbw_mac != NULL)
+                {
+                    RLOGD("disconect %d, %s ,%s\n", g_gbw_enabled, g_gbw_mac, strstr(msg_notify, (const char*)g_gbw_mac));
+                    if (strstr(msg_notify, (const char*)g_gbw_mac) != NULL)
+                    {
+                        stopGBW();
+                    }
+                }
+            }
+            else if (strstr(msg_notify, "AP-STA-CONNECTED") != NULL)
+            {
+                inner_notify_ap_msg(LYNQ_WIFI_STATUS_CONNECT);
+                if (g_gbw_enabled == 1 && g_gbw_mac != NULL)
+                {
+                    RLOGD("conect %d, %s ,%s\n", g_gbw_enabled, g_gbw_mac, strstr(msg_notify, (const char*)g_gbw_mac));
+                    if (strstr(msg_notify, (const char*)g_gbw_mac) != NULL)
+                    {
+                        startGBW();
+                    }
+                }
+            }
+            else if ( strstr(msg_notify, "Failed to start AP functionality") != NULL )
+            {
+                RLOGD("APWatcherThreadProc ap------> service error");
+                inner_notify_ap_msg(LYNQ_WIFI_SERVICE_ABNORMAL);
+            }
+            else
+            {
+                RLOGD("APWatcherThreadProc ap------> going on check next msg");
+            }
+            //you.chen add for tv-box end
+        } // end if (!wpa_ctrl_recv(lynq_wpa_ctrl, msg_notify, &len))
+    } // end while (g_ap_watcher_stop_flag == 0)
+    if (lynq_wpa_ctrl != NULL)
+    {
+        wpa_ctrl_detach(lynq_wpa_ctrl);
+        wpa_ctrl_close(lynq_wpa_ctrl);
+    }
+}
+
+static void inner_check_connect_error(const char * event_msg, lynq_wifi_sta_status_s state, error_number_s error_num)
+{
+    char * p;
+    const char * try_associat_flag = "Trying to associate";
+    const char * associated_flag = "Associated with ";
+
+    pthread_mutex_lock(&s_global_check_mutex);
+    if (s_sta_status < INNER_STA_STATUS_CONNECTING || s_sta_status >= INNER_STA_STATUS_CONNECTED) //not in connecting stage, egnore
+    {
+        pthread_mutex_unlock(&s_global_check_mutex);
+        return;
+    }
+
+    // youchen@2023-10-17 add for "not notify connect fail directly" begin
+    if (state == LYNQ_WIFI_STA_STATUS_CONNECT_FAIL)
+    {
+        s_sta_error_number = error_num;
+        s_sta_status = INNER_STA_STATUS_DISCONNECTED;
+        RLOGD("inner_check_connect_error line: %d, curr state %d, %d %d ------",__LINE__, state, s_sta_status, s_sta_error_number);
+        pthread_cond_signal(&s_global_check_cond);
+        pthread_mutex_unlock(&s_global_check_mutex);
+        return;
+    }
+    // youchen@2023-10-17 add for "not notify connect fail directly" end
+
+    if (state == LYNQ_WIFI_STATUS_EGNORE)
+    {
+        if (strstr(event_msg, try_associat_flag) != NULL && strstr(event_msg, s_sta_current_connecting_ssid) != NULL) //associating request ssid
+        {
+            s_sta_status = INNER_STA_STATUS_ASSOCIATING;
+        }
+        else if (s_sta_status == INNER_STA_STATUS_ASSOCIATING && (p=strstr(event_msg, associated_flag)) != NULL)
+        {
+            s_sta_status = INNER_STA_STATUS_ASSOCIATED;
+        }
+    }
+    else if (state == LYNQ_WIFI_STA_STATUS_DISCONNECT)
+    {
+        s_sta_error_number = error_num;
+        if (s_sta_status >= INNER_STA_STATUS_ASSOCIATING && strstr(event_msg, "CTRL-EVENT-SSID-TEMP-DISABLED") != NULL && error_num != LYNQ_WAIT_CONNECT_ACTIVE)
+        {
+            s_sta_status = INNER_STA_STATUS_DISCONNECTED;
+            RLOGD("inner_check_connect_error line: %d, curr state %d, %d %d ------",__LINE__, state, s_sta_status, s_sta_error_number);
+            pthread_cond_signal(&s_global_check_cond);
+        }
+    }
+    else if (state == LYNQ_WIFI_STA_STATUS_CONNECT)
+    {
+        s_sta_status = INNER_STA_STATUS_CONNECTED;
+        RLOGD("inner_check_connect_error line: %d, curr state %d, %d %d ------",__LINE__, state, s_sta_status, s_sta_error_number);
+        pthread_cond_signal(&s_global_check_cond);
+    }
+    pthread_mutex_unlock(&s_global_check_mutex);
+}
+
+static int lynq_split(char * str, int len, char delimiter, char * results[]);
+static inline char inner_convert_char(char in);
+static inline void inner_copy_ssid(char * out_ssid, const char * ssid,  size_t out_ssid_len);
+static int lynq_get_network_number_list(lynq_wifi_index_e idx, int ap_sta, int net_no_list[], char * ssid);
+
+
+
+/*
+just tmp add for fix sta connect ap fail check ap connect info
+return 0 --->Current no sta device connect this AP
+*/
+static int lynq_connected_ap_sta_status() {
+
+    FILE *fp;
+    size_t i = 0;
+    int ret;
+    char lynq_cmd_ret[MAX_RET]={0};
+
+    if((fp=popen("wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=ap0 list_sta","r"))==NULL)
+    {
+        perror("popen error!");
+        return -1;
+    }
+    if((fread(lynq_cmd_ret,sizeof(lynq_cmd_ret),1,fp))<0)
+    {
+        perror("fread fail!");
+        ret=pclose(fp);
+        if(ret == -1)
+            perror("close file faild");
+        return -1;
+    }
+    if( strlen(lynq_cmd_ret) < MAC_LEN)
+    {
+        RLOGD("---Current no sta device connect this AP %s  %d\n", lynq_cmd_ret,strlen(lynq_cmd_ret));
+        ret=pclose(fp);
+        if(ret==-1)
+        {
+            perror("close file faild");
+        }
+        return 0;
+    }else{
+        ret=pclose(fp);
+        if(ret==-1)
+        {
+            perror("close file faild");
+        }
+        RLOGD("---Current has sta device connect this AP--- %s\n", lynq_cmd_ret);
+        return 1;
+     }
+}
+
+/*
+    just tmp add for fix sta connect ap fail; check fw status
+    return 1 ----> fw status error; need wl down/up
+*/
+static int check_current_fw_status() {
+
+    FILE *fp;
+    FILE *fp1;
+    size_t i = 0;
+    int ret;
+    char lynq_cmd_ret_2g[MAX_RET]={0};
+    char lynq_cmd_ret_5g[MAX_RET]={0};
+
+    const char * fw_status = "0x0096";    //0x0096 is normal fw status
+
+    if((fp=popen("wl shmem  0x15ee a","r"))==NULL)
+    {
+        perror("popen error!");
+        return -1;
+    }
+    if((fread(lynq_cmd_ret_5g,sizeof(lynq_cmd_ret_2g),1,fp))<0)
+    {
+        perror("fread fail!");
+        if(pclose(fp) == -1)
+            perror("close fp file faild");
+        return -1;
+    }
+
+    if((fp1=popen("wl shmem  0x15ee b","r"))==NULL)
+    {
+        perror("popen error!");
+        if(pclose(fp) == -1)
+            perror("clsoe fp file faild");
+        return -1;
+    }
+    if((fread(lynq_cmd_ret_2g,sizeof(lynq_cmd_ret_5g),1,fp1))<0)
+    {
+        perror("fread fail!");
+        if(pclose(fp1) == -1)
+            perror("clsoe fp1 file faild");
+        if(pclose(fp) == -1)
+            perror("clsoe fp file faild");
+        return -1;
+    }
+
+    if ( strncmp(fw_status,lynq_cmd_ret_2g,6) == 0 || strncmp(fw_status,lynq_cmd_ret_5g,6) == 0 )
+    {
+        ret=pclose(fp);
+        if(ret==-1)
+        {
+            perror("close fp file faild");
+        }
+        ret=pclose(fp1);
+        if(ret==-1)
+        {
+            perror("close fp1 file faild");
+        }
+        return 0;
+    }else
+    {
+        ret=pclose(fp);
+        if(ret==-1)
+        {
+           perror("close file faild");
+        }
+        if(pclose(fp1) == -1)
+        {
+            perror("clsoe file fp1 faild");
+        }
+        RLOGD("current fw status --error--");
+        return 1;
+    }
+}
+
+/*
+eg: wl counters info
+sh-3.2# wl counters
+counters_version 30
+datalen 1648
+Slice_index: 0
+reinitreason_counts: 0(0) 1(0) 2(3) 3(0) 4(0) 5(0) 6(0) 7(0) 8(0) 9(0) 10(0) 11(0) 12(0) 13(0) 14(2) 15(0) 16(0) 17(0) 18(0) 19(0) 20(0) 21(0) 22(0) 23(0) 24(0) 25(0) 26(0) 27(0) 28(0) 29(0) 30(0) 31(0) 32(0) 33(0) 34(0) 35(0) 36(0) 37(0) 38(0) 39(0) 40(0) 41(0) 42(0) 43(0) 44(0) 45(0) 46(0) 47(0) 48(0) 49(0) 50(0) 51(0) 52(0) 53(0) 54(0)
+reinit 0 reset 2 pciereset 0 cfgrestore 0 dma_hang 0 ampdu_wds 0
+
+check reinit status
+return 0 ===> fw did wl reinit cmd
+*/
+static int check_current_reinit_info()
+{
+    FILE *fp;
+    int ret;
+    char lynq_cmd_ret[MAX_RET]={0};
+    char * dest;
+    char destid[3]={0};
+    if((fp=popen("wl counters","r"))==NULL)
+    {
+        perror("popen error!");
+        return -1;
+    }
+    if((fread(lynq_cmd_ret,sizeof(lynq_cmd_ret),1,fp))<0)
+    {
+        perror("fread fail!");
+        if(pclose(fp) == -1)
+        {
+           perror("close fp file faild");
+        }
+        return -1;
+    }
+    dest = strstr(lynq_cmd_ret,"reinit ");
+    if(dest != NULL)
+    {
+        dest +=strlen("reinit ");
+        RLOGD("current get dest str is %s",dest);
+        memcpy(destid,dest,2);
+        ret = atoi(destid);
+        RLOGD("get current wl counters cmd return counts is %d",ret);
+        if( ret != 0 )
+        {
+            RLOGD("current fw did run cmd wl reinit");
+            if( pclose(fp) == -1 )
+            {
+                perror("close fp file faild");
+            }
+            return 0;
+        }
+    }
+    if( pclose(fp) == -1 )
+    {
+       perror("close fp file faild");
+    }
+    RLOGD("current fw didn't run cmd wl reinit,dest ptr is NULL");
+    return -1;
+}
+
+static void APTmpWatcherThreadProc() {
+
+    int i = 0;
+    int delytime = 300;
+    g_ap_tmp_watcher_stop_flag = 0;
+
+    RLOGD("APTmpWatcherThreadProc ----> ThreadProc start");
+    while(1)
+    {
+        sleep(1);
+        i++;
+        if ( (i % 30) == 0 )
+        {
+            if ( check_current_reinit_info() == 0 )
+            {
+                system("wl reset_cnts");
+                system("wl down");
+                system("wl up");
+                RLOGD("APTmpWatcherThreadProc:check fw did reinit cmd,do down/up reset");
+            }
+        }
+        if ( (i % 10) == 0 )
+        {
+            if( lynq_connected_ap_sta_status() == 0 )      //0 --->no sta device connect this ap
+            {
+                if(check_current_fw_status() == 1)        //1 --->current fw status not 0x0096
+                {
+                    system("wl down");
+                    system("wl up");
+                }
+            }
+        }
+        if ( i == delytime )
+        {
+            i = 0;
+        }
+        if( g_ap_tmp_watcher_stop_flag == 1 )       //quit proc
+        {
+           RLOGD("APTmpWatcherThreadProc ----- > ap closed or wifi disabled");
+           return;
+        }
+
+    }
+
+}
+
+static int lynq_wifi_sta_stop_network(lynq_wifi_index_e idx,int networkid)
+{
+    char LYNQ_DISABLE_CMD[128]={0};
+    
+    CHECK_IDX(idx, CTRL_STA);
+    CHECK_WPA_CTRL(CTRL_STA);
+    
+    sprintf(LYNQ_DISABLE_CMD,"DISABLE_NETWORK %d",networkid);
+    RLOGD("LYNQ_DISABLE_CMD is:%s\n",LYNQ_DISABLE_CMD);
+    DO_OK_FAIL_REQUEST(LYNQ_DISABLE_CMD);
+
+    return 0;
+
+}
+
+static int lynq_wifi_sta_enable_network(lynq_wifi_index_e idx,int networkid)
+{
+    char LYNQ_ENABLE_CMD[128]={0};
+
+    CHECK_IDX(idx, CTRL_STA);
+    CHECK_WPA_CTRL(CTRL_STA);
+
+
+    sprintf(LYNQ_ENABLE_CMD,"ENABLE_NETWORK %d",networkid);
+    RLOGD("LYNQ_ENABLE_CMD is:%s\n",LYNQ_ENABLE_CMD);
+    DO_OK_FAIL_REQUEST(LYNQ_ENABLE_CMD);
+
+    return 0;
+
+}
+
+static int lynq_tmp_enable_network(lynq_wifi_index_e idx,int net_no_list[],int len)
+{
+
+    int index,networkid;
+
+    for ( index = 0; index < len ;index++)
+    {
+        networkid = net_no_list[index];
+        if( lynq_wifi_sta_enable_network(idx,networkid) != 0 )
+        {
+            RLOGE("[wifi]lynq_tmp_enable_network  id is %d fail",networkid);
+        }
+        RLOGD("[wifi]lynq_tmp_enable_network  id is %d",networkid);
+     }
+    return 0;
+
+}
+
+
+/*
+    dis_net_list   user disconnect list
+*/
+static void lynq_two_arr_merge(int dis_net_list[],int valid_num,int out[],int * outlen)
+{
+    RLOGD("enter %s %d",__func__,__LINE__);
+    print_disconnect_list();
+    int count,ncount,index;
+    int flag = 0;
+    int merge_index = 0;
+    int net_no_list[128];
+
+    for(ncount = 0;ncount < valid_num; ncount++ )
+    {
+        RLOGD("input history disconenct_list[%d] %d %d",ncount,dis_net_list[ncount],__LINE__);
+    }
+
+    index =lynq_get_network_number_list(0, 0, net_no_list,NULL);
+    for( count = 0; count < index; count++)
+    {
+        for(ncount = 0; ncount < valid_num; ncount++)
+        {
+            RLOGD(" %s dis_net_list[%d]->%d %d",__func__,ncount,dis_net_list[ncount],__LINE__);
+            if(net_no_list[count] == dis_net_list[ncount])
+            {
+                RLOGD("[wifi]this is history disconnect idx ----> %d %d",net_no_list[count],__LINE__);
+                flag = 1;
+                break;
+            }
+        }
+        if( flag != 1 )
+        {
+            out[merge_index] = net_no_list[count];
+            RLOGD("out[%d]: %d    net_no_list[%d]: %d %d",merge_index,out[merge_index],count,net_no_list[count],__LINE__);
+            merge_index ++;
+        }
+        flag = 0;
+    }
+    * outlen =merge_index;
+    RLOGD("[wifi]lynq_two_arr_merge get len is -----> %d",* outlen);
+    return;
+}
+
+void get_state_error(const char* modify, lynq_wifi_sta_status_s* state, error_number_s* error)
+{
+    char *pReason;
+    char *wpanetid;
+    char destid[3] = {0};
+    int tmpdisid = -1;
+    *error = LYNQ_WAIT_CONNECT_ACTIVE;
+    if (strstr(modify, "CTRL-EVENT-SCAN-RESULTS") != NULL)
+    {
+        *state = LYNQ_WIFI_STA_STATUS_SCAN_RESULT;
+        RLOGD("CTRL-EVENT-SCAN-RESULTS state:%d,error:%d\n",*state,*error);
+        return;
+    }
+
+    if (strstr(modify, "Trying to associate") != NULL)
+    {
+        RLOGD("Current sta is Trying to associate");
+        *state = LYNQ_WIFI_STATUS_EGNORE;
+        g_sta_conncet_status_flag = 1;
+	return;
+    }
+
+    if (strstr(modify, "CTRL-EVENT-CONNECTED") != NULL)
+    {
+        *state = LYNQ_WIFI_STA_STATUS_CONNECT;
+        RLOGD("CTRL-EVENT-CONNECTED state:%d,error:%d",*state,*error);
+        g_sta_conncet_status_flag = 0;
+        return;
+    }
+
+    if (strstr(modify,"CTRL-EVENT-AUTH-REJECT") != NULL)
+    {
+        *error = LYNQ_PSW_ERROR;
+        *state = LYNQ_WIFI_STA_STATUS_CONNECT_FAIL;
+        RLOGD("CTRL-EVENT-AUTH-REJECT state:%d,error:%d\n",*state,*error);
+        g_sta_conncet_status_flag = 0;
+        return;
+    }
+    if (strstr(modify, "CTRL-EVENT-SSID-TEMP-DISABLED") != NULL)
+    {
+        *state = LYNQ_WIFI_STA_STATUS_DISCONNECT;
+        wpanetid = strstr(modify,"id=");
+        if ( wpanetid != NULL )
+        {
+            wpanetid +=strlen("id=");
+            memcpy(destid,wpanetid,2);
+            tmpdisid = atoi(destid);
+
+        }
+        pReason = strstr(modify, "reason=");
+        if (pReason != NULL)
+        {
+            pReason += strlen("reason=");
+            if (memcmp(pReason, "CONN_FAILED", 11) == 0)
+            {
+                *error = LYNQ_TIME_OUT;
+            }
+            else if (memcmp(pReason, "WRONG_KEY", 9) == 0)
+            {
+                *error = LYNQ_PSW_ERROR;
+                *state = LYNQ_WIFI_STA_STATUS_CONNECT_FAIL;
+                // tmp fix sta autoconnect connect and disconnect
+                // you.chen@2023-10-17 only disable network during autoconnect
+                if(tmpdisid != -1 && s_sta_status == INNER_STA_STATUS_INIT && lynq_wifi_sta_stop_network(0,tmpdisid) != 0)
+                {
+                    RLOGE("stop wlan0 network %d fail",tmpdisid);
+                }
+            }
+            else 
+            {
+                *error = LYNQ_UNSPECIFIED_REASON;
+            }
+        }
+        else
+        {
+            *error = LYNQ_UNSPECIFIED_REASON;
+        }
+        RLOGD("CTRL-EVENT-SSID-TEMP-DISABLED state:%d,error:%d,tmpnetid:%d",*state,*error,tmpdisid);
+        g_sta_conncet_status_flag = 0;
+        return;
+
+    }
+
+    if (strstr(modify, "CTRL-EVENT-NETWORK-NOT-FOUND") != NULL)
+    {
+        *error = LYNQ_NOT_FIND_AP;
+        *state = LYNQ_WIFI_STA_STATUS_DISCONNECT;
+        RLOGD("CTRL-EVENT-NETWORK-NOT-FOUND state:%d,error:%d\n",*state,*error);
+        g_sta_conncet_status_flag = 0;
+        return;
+    }
+
+
+    if (strstr(modify, "CTRL-EVENT-ASSOC-REJECT") != NULL)
+    {
+        RLOGD("FIND CTRL EVENT : CTRL-EVENT-ASSOC-REJECT\n");
+        pReason = strstr(modify, "status_code=");
+        if (pReason != NULL)
+        {
+            pReason += strlen("status_code=");
+            if (memcmp(pReason, "17", 2) == 0)
+            {
+                *error = LYNQ_AP_UNABLE_HANDLE;
+            }
+            else if (memcmp(pReason, "1",1) == 0)
+            {
+                *error = LYNQ_UNSPECIFIED_REASON;
+            }
+            else
+            {
+                *error = LYNQ_UNSPECIFIED_REASON;
+            }
+
+             *state = LYNQ_WIFI_STA_STATUS_DISCONNECT;
+             RLOGD("CTRL-EVENT-ASSOC-REJECT BUT NOT STATUS_CODE NOT 1 or 17 state:%d,error:%d\n",*state,*error);
+             g_sta_conncet_status_flag = 0;
+             return;
+        }
+        else
+        {
+            RLOGD("FIND CTRL EVENT : CTRL-EVENT-ASSOC-REJECT BUT NOT FOUND STATUS_CODE\n");
+            *error = LYNQ_UNSPECIFIED_REASON;
+            *state = LYNQ_WIFI_STA_STATUS_DISCONNECT;
+            RLOGD("CTRL-EVENT-ASSOC-REJECT state:%d,error:%d\n",*state,*error);
+            return;
+        }
+    }
+
+    if (strstr(modify, "CTRL-EVENT-SAE-UNKNOWN-PASSWORD-IDENTIFIER") != NULL)
+    {
+        RLOGD("FIND CTRL EVENT : CTRL-EVENT-SAE-UNKNOWN-PASSWORD-IDENTIFIER\n");
+        *error = LYNQ_AUTHENTICATION_NO_LONGER_VALID;
+        *state = LYNQ_WIFI_STA_STATUS_DISCONNECT;
+        RLOGD("CTRL-EVENT-SAE-UNKNOWN-PASSWORD-IDENTIFIER state:%d,error:%d\n",*state,*error);
+        return;
+    }
+
+    if (strstr(modify, "CTRL-EVENT-DISCONNECTED") != NULL)
+    {
+        RLOGD("FIND CTRL EVENT : CTRL-EVENT-DISCONNECTED\n");
+        *error = LYNQ_WAIT_CONNECT_ACTIVE;
+        *state = LYNQ_WIFI_STA_STATUS_DISCONNECT;
+        RLOGD("CTRL-EVENT-DISCONNECTED state:%d,error:%d\n",*state,*error);
+        return;
+    }
+
+    // add by qs.xiong 20231026   tmp fix sta association request to the driver failed
+    if (strstr(modify, "Association request to the driver failed") != NULL)
+    {
+        RLOGD("Association request to the driver failed --- recover");
+        system("wl down");
+        system("wl up");
+        *error = LYNQ_UNSPECIFIED_REASON;
+        *state = LYNQ_WIFI_STA_STATUS_DISCONNECT;
+        RLOGD("CTRL-EVENT-DISCONNECTED state:%d,error:%d\n",*state,*error);
+        return;
+    }
+    // add by qs.xiong 20231026   tmp fix sta association request to the driver failed end
+
+
+    RLOGD("EVENT : %s\n", modify);
+    *error = LYNQ_UNSPECIFIED_REASON;
+    *state = LYNQ_WIFI_STATUS_EGNORE;
+    RLOGD("LAST : STA state:%d,error:%d\n",*state,*error);
+    return;
+
+}
+
+void get_state_error_networkid(const char* modify, lynq_wifi_sta_status_s* state, error_number_s* error,int *networkid)
+{
+    char *pReason;
+    char *wpanetid;
+    char destid[3];
+    *error = LYNQ_WAIT_CONNECT_ACTIVE;
+    *networkid = -1;
+    if (strstr(modify, "CTRL-EVENT-SCAN-RESULTS") != NULL)
+    {
+        *state = LYNQ_WIFI_STA_STATUS_SCAN_RESULT;
+        RLOGD("CTRL-EVENT-SCAN-RESULTS state:%d,error:%d,,networkid:%d\n",*state,*error,*networkid);
+        return;
+    }
+    if (strstr(modify, "CTRL-EVENT-CONNECTED") != NULL)
+    {
+        RLOGD("[xiong]:wpanetid = strstrmodify;\n");
+        wpanetid = strstr(modify,"id=");
+        if ( wpanetid != NULL )
+        {
+            wpanetid +=strlen("id=");
+            RLOGD("[xiong]:memcpy(destid,wpanetid,0\n");
+            if (memcpy(destid,wpanetid,2) != NULL)
+            {
+                 RLOGD("[xiong]:memcpy(destid,wpanetid,1\n");
+                *networkid = atoi(destid);
+                RLOGD("get networkid is %d\n",*networkid);
+            }
+             RLOGD("[xiong]:memcpy(destid,wpanetid,2\n");
+        }
+        *state = LYNQ_WIFI_STA_STATUS_CONNECT;
+        RLOGD("CTRL-EVENT-CONNECTED state:%d,error:%d,networkid:%d\n",*state,*error,*networkid);
+        return;
+    }
+    if (strstr(modify, "CTRL-EVENT-SSID-TEMP-DISABLED") != NULL)
+    {
+        wpanetid = strstr(modify,"id=");
+        if ( wpanetid != NULL )
+        {
+            wpanetid +=strlen("id=");
+            if (memcpy(destid,wpanetid,2) != NULL)
+            {
+                *networkid = atoi(destid);
+                RLOGD("get networkid is %d\n",*networkid);
+            }
+        }
+        pReason = strstr(modify, "reason=");
+        if (pReason != NULL)
+        {
+            pReason += strlen("reason=");
+            if (memcmp(pReason, "CONN_FAILED", 11) == 0)
+            {
+                *error = LYNQ_TIME_OUT;
+            }
+            else if (memcmp(pReason, "WRONG_KEY", 9) == 0)
+            {
+                *error = LYNQ_PSW_ERROR;
+            }
+            else 
+            {
+                *error = LYNQ_UNSPECIFIED_REASON;
+            }
+            *state = LYNQ_WIFI_STA_STATUS_CONNECT_FAIL;
+            RLOGD("CTRL-EVENT-SSID-TEMP-DISABLED state:%d,error:%d,networkid:%d\n",*state,*error,*networkid);
+            return;
+        }
+        else
+        {
+            *error = LYNQ_UNSPECIFIED_REASON;
+            *state = LYNQ_WIFI_STA_STATUS_CONNECT_FAIL;
+            return;
+        }
+    }
+    if (strstr(modify, "CTRL-EVENT-ASSOC-REJECT") != NULL)
+    {
+        wpanetid = strstr(modify,"id=");
+        if ( wpanetid != NULL )
+        {
+            wpanetid +=strlen("id=");
+            if (memcpy(destid,wpanetid,2) != NULL)
+            {
+                *networkid = atoi(destid);
+                RLOGD("get networkid is %d\n",*networkid);
+            }
+        }
+        RLOGD("FIND CTRL EVENT : CTRL-EVENT-ASSOC-REJECT\n");
+        pReason = strstr(modify, "status_code=");
+        if (pReason != NULL)
+        {
+            pReason += strlen("status_code=");
+            if (memcmp(pReason, "17", 2) == 0)
+            {
+                *error = LYNQ_AP_UNABLE_HANDLE;
+            }
+            else if (memcmp(pReason, "1",1) == 0)
+            {
+                *error = LYNQ_UNSPECIFIED_REASON;
+            }
+            else
+            {
+                *error = LYNQ_UNSPECIFIED_REASON;
+            }
+             *state = LYNQ_WIFI_STA_STATUS_DISCONNECT;
+             RLOGD("CTRL-EVENT-ASSOC-REJECT BUT NOT STATUS_CODE NOT 1 or 17 state:%d,error:%d,networkid:%d\n",*state,*error,*networkid);
+             return;
+        }
+        else
+        {
+            RLOGD("FIND CTRL EVENT : CTRL-EVENT-ASSOC-REJECT BUT NOT FOUND STATUS_CODE\n");
+            *error = LYNQ_UNSPECIFIED_REASON;
+            *state = LYNQ_WIFI_STA_STATUS_DISCONNECT;
+            RLOGD("CTRL-EVENT-ASSOC-REJECT state:%d,error:%d,networkid:%d\n",*state,*error,*networkid);
+            return;
+        }
+    }
+    if (strstr(modify, "CTRL-EVENT-SAE-UNKNOWN-PASSWORD-IDENTIFIER") != NULL)
+    {
+        RLOGD("FIND CTRL EVENT : CTRL-EVENT-SAE-UNKNOWN-PASSWORD-IDENTIFIER\n");
+        *error = LYNQ_AUTHENTICATION_NO_LONGER_VALID;
+        *state = LYNQ_WIFI_STA_STATUS_DISCONNECT;
+        RLOGD("CTRL-EVENT-SAE-UNKNOWN-PASSWORD-IDENTIFIER state:%d,error:%d,networkid:%d\n",*state,*error,*networkid);
+        return;
+    }
+    if (strstr(modify, "CTRL-EVENT-DISCONNECTED") != NULL)
+    {
+        RLOGD("FIND CTRL EVENT : CTRL-EVENT-DISCONNECTED\n");
+        *error = LYNQ_WAIT_CONNECT_ACTIVE;
+        *state = LYNQ_WIFI_STA_STATUS_DISCONNECT;
+        RLOGD("CTRL-EVENT-DISCONNECTED state:%d,error:%d,networkid:%d\n",*state,*error,*networkid);
+        return;
+    }
+    RLOGD("EVENT : %s\n", modify);
+    *error = LYNQ_UNSPECIFIED_REASON;
+    *state = LYNQ_WIFI_STATUS_EGNORE;
+    RLOGD("LAST : STA state:%d,error:%d,network:%d\n",*state,*error,*networkid);
+    return;
+}
+static void notify_connect_status(lynq_wifi_sta_status_s state, error_number_s error)
+{
+    pthread_mutex_lock(&s_sta_callback_mutex);
+    if (g_sta_callback_func != NULL && state != LYNQ_WIFI_STATUS_EGNORE)
+    {
+        RLOGD("STAWatcherThreadProc callback begin ------> %d %d\n", state, error);
+        g_sta_callback_func(g_sta_callback_priv, state, error);
+        RLOGD("STAWatcherThreadProc callback end ------> %d %d\n", state, error);
+    }
+    pthread_mutex_unlock(&s_sta_callback_mutex);
+}
+static void notify_auto_connect_status(lynq_wifi_sta_status_s state, error_number_s error,int networkid)
+{
+    pthread_mutex_lock(&s_sta_callback_mutex);
+    if (g_sta_callback_func != NULL && state != LYNQ_WIFI_STATUS_EGNORE)
+    {
+        RLOGD("STAWatcherThreadProc callback begin ------> %d %d %d\n", state, error,networkid);
+        g_sta_auto_callback_func(g_sta_auto_callback_priv, state, error,networkid);
+        RLOGD("STAAutoWatcherThreadProc callback end ------> %d %d %d\n", state, error,networkid);
+    }
+    pthread_mutex_unlock(&s_sta_callback_mutex);
+}
+
+static void STAWatcherThreadProc() {
+    size_t len = MAX_RET;
+    char msg_notify[MAX_RET];
+    error_number_s error;
+    lynq_wifi_sta_status_s state, last_state = -1;
+    int idle_count = 0;
+
+    struct wpa_ctrl *lynq_wpa_ctrl = NULL;
+    g_sta_watcher_stop_flag = 0;
+
+    RLOGD("STAWatcherThreadProc thread started ------");
+    while (g_sta_watcher_stop_flag == 0)
+    {
+        if (check_pending_msg(&lynq_wpa_ctrl, CTRL_STA, &idle_count, &g_sta_watcher_started_flag) != 1)
+        {
+            continue;
+        }
+
+        memset(msg_notify, 0, MAX_RET);
+        len = MAX_RET;
+        if (!wpa_ctrl_recv(lynq_wpa_ctrl, msg_notify, &len))
+        {
+            msg_notify[len+1] = '\0';
+            RLOGD("STAWatcherThreadProc sta ------> %s\n", msg_notify);
+            if (strstr(msg_notify, state_scan_result) != NULL)
+            {
+                g_sta_scan_finish_flag = 1;
+            }
+
+            if (g_sta_callback_func == NULL)
+            {
+                continue;
+            }
+            get_state_error(msg_notify,&state,&error);
+            // youchen@2023-10-17 add for "not notify connect fail directly" begin
+            if (state == LYNQ_WIFI_STA_STATUS_CONNECT_FAIL)
+            {
+                notify_connect_status(LYNQ_WIFI_STA_STATUS_DISCONNECT, error);
+            }
+            else if (state == LYNQ_WIFI_STA_STATUS_SCAN_RESULT &&
+                     s_sta_status != INNER_STA_STATUS_INIT && g_sta_conncet_status_flag != 0)
+            {
+                RLOGD("donot report scan result during in call connect manual");
+            }
+            else
+            {
+                notify_connect_status(state, error);
+            }
+            // youchen@2023-10-17 add for "not notify connect fail directly" end
+
+            if (state != LYNQ_WIFI_STA_STATUS_SCAN_RESULT)
+            {
+                inner_check_connect_error(msg_notify, state, error);
+                if (last_state != state)
+                {
+                    if (state == LYNQ_WIFI_STA_STATUS_CONNECT)
+                    {
+                        system_call_v("%s %s", sta_status_change_script, "connect");
+                    }
+                    else if (state == LYNQ_WIFI_STA_STATUS_DISCONNECT)
+                    {
+                        system_call_v("%s %s", sta_status_change_script, "disconnect");
+                    }
+                }
+
+                last_state = state;
+                if (g_sta_fake_scan_finish_flag == 1)
+                {
+                    g_sta_fake_scan_finish_flag = 0;
+                    notify_connect_status(LYNQ_WIFI_STA_STATUS_SCAN_RESULT, 0);
+                }
+            }
+        }
+    }
+    if (lynq_wpa_ctrl != NULL)
+    {
+        wpa_ctrl_detach(lynq_wpa_ctrl);
+        wpa_ctrl_close(lynq_wpa_ctrl);
+    }
+}
+static void STAAutoWatcherThreadProc() {
+    size_t len = MAX_RET;
+    char msg_notify[MAX_RET];
+    error_number_s error;
+    lynq_wifi_sta_status_s state;
+    int idle_count = 0;
+    int networkid;
+    struct wpa_ctrl *lynq_wpa_ctrl = NULL;
+    g_sta_auto_watcher_stop_flag = 0;
+    RLOGD("STAAutoWatcherThreadProc thread started ------");
+    while (g_sta_auto_watcher_stop_flag == 0)
+    {
+        if (check_pending_msg(&lynq_wpa_ctrl, CTRL_STA, &idle_count, &g_sta_auto_watcher_started_flag) != 1)
+        {
+            continue;
+        }
+        memset(msg_notify, 0, MAX_RET);
+        len = MAX_RET;
+        if (!wpa_ctrl_recv(lynq_wpa_ctrl, msg_notify, &len))
+        {
+            msg_notify[len+1] = '\0';
+            RLOGD("STAAutoWatcherThreadProc sta ------> %s\n", msg_notify);
+            if (strstr(msg_notify, state_scan_result) != NULL)
+            {
+                g_sta_auto_scan_finish_flag = 1;
+            }
+            if (g_sta_auto_callback_func == NULL)
+            {
+                continue;
+            }
+            get_state_error_networkid(msg_notify,&state,&error,&networkid); // add net state error network function
+            notify_auto_connect_status(state, error,networkid);
+        }
+    }
+    if (lynq_wpa_ctrl != NULL)
+    {
+        wpa_ctrl_detach(lynq_wpa_ctrl);
+        wpa_ctrl_close(lynq_wpa_ctrl);
+    }
+}
+
+// this thread will not exit when lynq_wifi_disable called,to avoid dead lock,take care
+static void GlobalWatcherThreadProc()
+{
+    int ret, connect_timeout, service_abnormal;
+    error_number_s error_num = -1;
+    inner_sta_status_s sta_status;
+    scan_info_s *scan_list = NULL;
+    int i, scan_len=0;
+    char connecting_ssid[64];
+    struct timeval now;
+
+    RLOGD("GlobalWatcherThreadProc start to run");
+
+    while (1)
+    {
+        pthread_mutex_lock(&s_global_check_mutex);
+        pthread_cond_wait(&s_global_check_cond,&s_global_check_mutex);
+        if (s_sta_status == INNER_STA_STATUS_CONNECTED)
+        {
+            pthread_mutex_unlock(&s_global_check_mutex);
+            usleep(50*1000);
+            notify_connect_status(LYNQ_WIFI_STA_STATUS_CONNECT, 0);
+            continue;
+        }
+
+        connect_timeout = 0;
+        service_abnormal = 0;
+        if (s_sta_status >= INNER_STA_STATUS_CONNECTING && s_sta_status < INNER_STA_STATUS_CONNECTED)
+        {
+            while (1)
+            {
+                ret = pthread_cond_timedwait(&s_global_check_cond, &s_global_check_mutex, &s_sta_connect_timeout);
+                if (ret == ETIME)
+                {
+                    connect_timeout = 1;
+                }
+                else if (ret != 0)
+                {
+                    gettimeofday(&now,NULL);
+                    if (now.tv_sec < s_sta_connect_timeout.tv_sec) //time not arrive
+                    {
+                        usleep(SLEEP_TIME_ON_IDLE);
+                        continue;
+                    }
+                    connect_timeout = 1;
+                }
+                sta_status = s_sta_status;
+                error_num = s_sta_error_number;
+                s_sta_status = INNER_STA_STATUS_INIT;
+                strcpy(connecting_ssid, s_sta_current_connecting_ssid);
+                memset(&s_sta_connect_timeout, 0, sizeof (s_sta_connect_timeout));
+                memset(&s_sta_current_connecting_ssid, 0, sizeof (s_sta_current_connecting_ssid));
+                break;
+            }
+        }
+        if (s_service_invoke_timeout_cnt > 10)
+        {
+            service_abnormal = 1;
+            s_service_invoke_timeout_cnt = 0;
+        }
+        pthread_mutex_unlock(&s_global_check_mutex);
+
+        if (service_abnormal == 1)
+        {
+            sleep(1);
+            RLOGE("wpa service is abnormal info app to exit");
+            notify_connect_status(LYNQ_WIFI_STA_SERVICE_ABNORMAL, -1);
+
+            inner_notify_ap_msg(LYNQ_WIFI_SERVICE_ABNORMAL);
+
+            sleep(FAKE_MAX_INT_VALUE); // wait process to exit
+        }
+
+        if (sta_status == INNER_STA_STATUS_CANCEL)
+        {
+            continue;
+        }
+        else if (sta_status == INNER_STA_STATUS_CONNECTED)
+        {
+            notify_connect_status(LYNQ_WIFI_STA_STATUS_CONNECT, 0);
+        }
+        else if (connect_timeout == 0 && error_num == LYNQ_NOT_FIND_AP) // not found ap maybe mismatch auth
+        {
+            if (0 == lynq_get_scan_list(0, &scan_list, &scan_len) && NULL != scan_list) // if not found, but scan result exist, maybe auth error
+            {
+                for(i=0; i < scan_len;i++)
+                {
+                    if (strcmp(scan_list[i].ssid, connecting_ssid) == 0)
+                    {
+                        error_num = LYNQ_AUTH_ERROR;
+                        break;
+                    }
+                }
+                free(scan_list);
+            }
+            notify_connect_status(LYNQ_WIFI_STA_STATUS_CONNECT_FAIL, error_num);
+        }
+        else if (connect_timeout == 0)
+        {
+            notify_connect_status(LYNQ_WIFI_STA_STATUS_CONNECT_FAIL, error_num);
+        }
+        else // wait timeout
+        {
+            if (0 != lynq_get_sta_status(LYNQ_WIFI_INTERFACE_0, &sta_status)) // get status fail
+            {
+                ; // wpa service abnormal
+            }
+            else if (sta_status == LYNQ_WIFI_STA_STATUS_ENABLE) // connect ok
+            {
+                RLOGD("GlobalWatcherThreadProc notify connected");
+                notify_connect_status(LYNQ_WIFI_STA_STATUS_CONNECT, 0);
+            }
+            else
+            {
+                RLOGD("GlobalWatcherThreadProc notify timeout");
+                notify_connect_status(LYNQ_WIFI_STA_STATUS_CONNECT_FAIL, LYNQ_TIME_OUT);
+            }
+        }
+    } // while (1)
+}
+
+int lynq_wifi_enable(void)
+{
+    int ret = 0;
+    int i;
+    RLOGD("enter lynq_wifi_enable");
+    pthread_mutex_lock(&s_check_wpa_ctrl_mutex);
+
+    if (g_lynq_wpa_ctrl[0] != NULL && g_lynq_wpa_ctrl[1] != NULL)
+    {
+        goto out_enable;
+    }
+
+    ret = system(start_wg870_service_script);
+    if (ret != 0)
+    {
+        //printf("service state %d\n", ret);
+        RLOGE("[wifi error]service state %d",ret);
+        ret = -1;
+        goto out_enable;
+    }
+
+    if (g_global_watcher_pid == 0 ) // this thread will not exit when lynq_wifi_disable called,to avoid dead lock,take care
+    {
+        ret=pthread_create(&g_global_watcher_pid,NULL,GlobalWatcherThreadProc,NULL);
+        if(ret<0)
+        {
+            RLOGE("[wifi error]creat GlobalWatcherThreadProc fail");
+            ret = -1;
+            goto out_enable;
+        }
+    }
+
+    g_lynq_wpa_ctrl[0] = malloc(sizeof (struct local_wpa_ctrl));
+    g_lynq_wpa_ctrl[1] = malloc(sizeof (struct local_wpa_ctrl));
+    memset(g_lynq_wpa_ctrl[0], 0 , sizeof(struct local_wpa_ctrl));
+    memset(g_lynq_wpa_ctrl[1], 0 , sizeof(struct local_wpa_ctrl));
+out_enable:
+    pthread_mutex_unlock(&s_check_wpa_ctrl_mutex);
+    return ret;
+}
+
+int lynq_wifi_disable(void)
+{
+    RLOGD("enter lynq_wifi_disable");
+    pthread_mutex_lock(&s_check_wpa_ctrl_mutex);
+    g_ap_watcher_stop_flag = 1;
+    g_sta_watcher_stop_flag = 1;
+    g_sta_auto_watcher_stop_flag = 1;
+/*  g_ap_tmp_watcher_stop_flag = 1;
+    if (g_ap_watcher_pid != 0)
+        pthread_join(g_ap_watcher_pid, NULL);
+*/
+    if (g_sta_watcher_pid != 0)
+        pthread_join(g_sta_watcher_pid, NULL);
+    if (g_sta_auto_watcher_pid != 0)
+        pthread_join(g_sta_auto_watcher_pid, NULL);
+    if (g_lynq_wpa_ctrl[0] != NULL)
+        wpa_ctrl_close(g_lynq_wpa_ctrl[0]);
+    if (g_lynq_wpa_ctrl[1] != NULL)
+        wpa_ctrl_close(g_lynq_wpa_ctrl[1]);
+    if (g_ap_tmp_watcher_pid != 0)
+        pthread_join(g_ap_tmp_watcher_pid, NULL);
+    g_ap_watcher_pid = 0;
+    g_sta_watcher_pid = 0;
+    g_sta_auto_watcher_pid = 0;
+//    g_ap_tmp_watcher_pid = 0;
+    g_lynq_wpa_ctrl[0] = NULL;
+    g_lynq_wpa_ctrl[1] = NULL;
+    g_history_disconnect_valid_num = 0;   //clean history_disconenct_list info
+    system("systemctl stop wg870_drv_insmod.service");
+    pthread_mutex_unlock(&s_check_wpa_ctrl_mutex);
+    return 0;
+}
+
+static inline char inner_convert_char(char in)
+{
+    if (in >= '0' && in <= '9')
+    {
+        return in - '0';
+    }
+    else if (in >= 'a' && in <= 'f')
+    {
+        return in - 'a' + 10;
+    }
+    else if (in >= 'A' && in <= 'F')
+    {
+        return in - 'A' + 10;
+    }
+    else
+    {
+        return '\xff';
+    }
+}
+
+static inline void inner_copy_ssid(char * out_ssid, const char * ssid,  size_t out_ssid_len)
+{
+    char *p;
+    size_t pos = 0;
+    if (NULL == out_ssid)
+        return;
+    //printf("input ssid=[%s]\n", ssid);
+    memset(out_ssid, 0, out_ssid_len);
+    if (NULL == ssid)
+        return;
+    p = strchr(ssid, '\\');
+    if (NULL == p)
+    {
+        strncpy(out_ssid, ssid, out_ssid_len);
+        //printf(" first %s\n", out_ssid);
+    }
+    else
+    {
+        pos = p - ssid;
+        memcpy(out_ssid, ssid, pos);
+        //printf("pos %lu -- %s\n", pos, out_ssid);
+        for(; pos < out_ssid_len; pos ++)
+        {
+            if (p[0] == '\0')
+            {
+                //printf(" out %s\n", out_ssid);
+                return;
+            }
+            else if (p[0] != '\\')
+            {
+                out_ssid[pos] = p[0];
+                p += 1;
+            }
+            else if (p[1] == 'x' || p[1] == 'X')
+            {
+                out_ssid[pos] = inner_convert_char(p[2]) << 4 | inner_convert_char(p[3]);
+                p += 4;
+            }
+            else if (p[1] == '\\')
+            {
+                out_ssid[pos] = '\\';
+                p += 2;
+            }
+            else if (p[1] == 't')
+            {
+                out_ssid[pos] = '\t';
+                p += 2;
+            }
+            else if (p[1] == 'r')
+            {
+                out_ssid[pos] = '\r';
+                p += 2;
+            }
+            else if (p[1] == 'n')
+            {
+                out_ssid[pos] = '\n';
+                p += 2;
+            }
+            else
+            {
+                out_ssid[pos] = p[1];
+                p += 2;
+            }//todo find a better way to convert?
+        }
+    }
+    //printf(" out %s\n", out_ssid);
+}
+
+static int inner_get_param(int interface, int net_no, char* param_name, char * out_put) {
+    int i, ssid_len;
+    char lynq_cmd_get[128]={0};
+    RLOGD("enter inner_get_param");
+    if (out_put == NULL)
+    {
+        RLOGE("output ptr is null");
+        return -1;
+    }
+    if (param_name == NULL)
+    {
+        RLOGE("param ptr is null");
+        return -1;
+    }
+    if (param_name[0] == '\0')
+    {
+        RLOGE("param is empty");
+        return -1;
+    }
+
+    sprintf(lynq_cmd_get, "GET_NETWORK %d %s", net_no, param_name);
+
+    CHECK_WPA_CTRL(interface);
+
+    DO_REQUEST(lynq_cmd_get);
+
+    if (memcmp(cmd_reply, "FAIL", 4) == 0)
+    {
+        RLOGE("wpa_supplicant return cmd_reply is FAIL");
+        return -1;
+    }
+
+//    printf("reply len %d, %08x\n", reply_len, (int)out_put);
+    if (strcmp(param_name, "ssid") == 0)
+    {
+        if (cmd_reply[0] == '\"')
+	{
+            ssid_len = reply_len - 1;
+            memcpy(out_put, cmd_reply + 1, ssid_len);
+            if (out_put[ssid_len-1] == '\"')
+            {
+                out_put[ssid_len-1] = '\0';
+            }
+            else
+            {
+                out_put[ssid_len] = '\0';
+            }
+        }
+        else
+	{
+            ssid_len = reply_len / 2;
+            for(i=0; i<ssid_len; i++)
+            {
+                out_put[i] = inner_convert_char(cmd_reply[i*2]) << 4 | inner_convert_char(cmd_reply[i*2 + 1]);
+            }
+            out_put[ssid_len] = '\0';
+        }
+    }
+    else
+    {
+        memcpy(out_put, cmd_reply, reply_len + 1);
+    }
+    return 0;
+}
+
+static int lynq_split(char * str, int len, char delimiter, char * results[]) {
+    int ret = 0;
+    char * end = str + len - 1;
+    results[ret++] = str;
+    while(str < end)
+    {
+        if (*str == delimiter)
+	{
+            *str++ = '\0';
+            results[ret++] = str;
+            continue;
+        }
+        str++;
+    }
+    if (*str == delimiter)
+    {
+        *str = '\0';
+    }
+
+    results[ret] = NULL;
+
+    return ret;
+}
+/*
+ *add func to get conencted STA device ip from dnsmasq ap0.lease
+ *return 0 means get ip success
+ */
+static int inner_get_ip_by_mac_lease(const char * mac, char * ip,int ip_len)
+{
+    char * p;
+    int ret;
+    char cmd[256]={0};
+    if (NULL == mac || NULL == ip)
+        return -1;
+    memset(ip, 0, ip_len);
+    sprintf(cmd, "cat /run/wg870/ap0.lease | grep \"%s\" | awk '{print $3}'", mac);
+    ret = exec_cmd(cmd, ip, ip_len);
+    if( ret == 0 )
+    {
+        p = strchr(ip, '\n');
+        if (NULL != p)
+        {
+            *p = '\0';
+            RLOGD("inner_get_ip_by_mac_lease %s function return is:%d", ip,ret);
+            return ret;
+        }else
+        {
+            ret = -1;
+        }
+    }
+    RLOGD("%s %d function return is:%d",__func__,__LINE__,ret);
+    return ret;
+
+}
+
+static int inner_get_ip_by_mac(const char * mac, char * ip, int ip_len)
+{
+    char * p;
+    int ret = 0;
+    char cmd[256]={0};
+    if (NULL == mac || NULL == ip)
+        return -1;
+    memset(ip, 0, ip_len);
+    sprintf(cmd, "ip n s | grep \"lladdr\" | grep \"%s\" | awk '{print $1}' | grep -v \":\" | head -1", mac);
+    ret = exec_cmd(cmd, ip, ip_len);
+    p = strchr(ip, '\n');
+    if (NULL != p)
+    {
+        *p = '\0';
+    }else
+    {
+	ret = inner_get_ip_by_mac_lease(mac,ip,ip_len);
+    }
+    RLOGD("inner_get_ip_by_mac %s\n", ip);
+    return ret;
+}
+
+static int inner_get_hostname_by_ip(char *ip, char *hostname) {
+    struct in_addr addr ={0};
+    struct hostent *ht;
+    char cmd[64] = {0};
+    char * p;
+    int ret;
+
+    if (ip == NULL || *ip == '\0' || hostname == NULL)
+    {
+        RLOGE("ip == NULL or hostname == NULL");
+	return -1;
+    }
+
+    *hostname = '\0';
+    if (inet_aton(ip, &addr) == 0)
+    {
+        printf("---inet_aton fail\n");
+        return -1;
+    }
+
+    ht = gethostbyaddr(&addr, sizeof(struct in_addr), AF_INET);
+
+    if (ht == NULL)
+    {
+        hostname[0] = '\0';
+        sprintf(cmd, "grep -F '%s' /run/wg870/ap0.lease | awk '{print $4}' | tail -1", ip);
+        ret = exec_cmd(cmd, hostname, 32);
+        if (ret == 0)
+        {
+            p = strchr(hostname, '\n');
+            if (p != NULL)
+            {
+                *p = '\0';
+            }
+            return 0;
+        }
+        hostname[0] = '\0';
+        RLOGE("---gethostbyaddr fail\n");
+        herror(NULL);
+        return -1;
+    }
+
+    strcpy(hostname, ht->h_name);
+
+    return 0;
+}
+
+static int lynq_get_network_number_list(lynq_wifi_index_e idx, int ap_sta, int net_no_list[], char * ssid)
+{
+    int count, index, words_count;
+    char * split_lines[128]= {0};
+    char * split_words[128] = {0};
+    char local_ssid[128] = {0};
+    const char *lynq_wifi_list_networks = "LIST_NETWORKS";
+    RLOGD("[lynq_get_network_number_list] enter lynq_get_network_number_list api");
+
+    CHECK_WPA_CTRL(ap_sta);
+
+    DO_REQUEST(lynq_wifi_list_networks);
+
+    count = lynq_split(cmd_reply, reply_len, '\n', split_lines);
+
+    //@todo check ssid field to compatible
+
+    ret = 0;
+    for(index=1; index < count; index++)
+    {
+        words_count = lynq_split(split_lines[index], strlen(split_lines[index]), '\t', split_words);
+        if (words_count > 2)
+	{
+            inner_copy_ssid(local_ssid, split_words[1], sizeof (local_ssid));
+            if (ssid == NULL || strcmp(local_ssid, ssid) == 0)
+	    {
+                net_no_list[ret++] = atoi(split_words[0]);
+            }
+        }
+    }
+    RLOGD("[lynq_get_network_number_list] lynq_get_network_number_list return ok");
+    return ret;
+}
+
+static int lynq_add_network(int ap_sta) {
+    size_t i=0;
+    CHECK_WPA_CTRL(ap_sta);
+    const char *lynq_wifi_add_network = "ADD_NETWORK";
+
+    RLOGD("[lynq_add_network] enter lynq_add_network");
+    DO_REQUEST(lynq_wifi_add_network);
+    if (memcmp(cmd_reply, "FAIL", 4) == 0)
+    {
+        RLOGE("[wifi error]lynq_add_network  cmd_reply FAIL");
+        return -1;
+    }
+
+    for(i=0;i<reply_len;i++)
+    {
+        if(cmd_reply[i] == '\n')
+	{
+            cmd_reply[i] = '\0';
+            break;
+        }
+    }
+    return atoi(cmd_reply);
+}
+
+static int lynq_check_network_number(lynq_wifi_index_e idx, int ap_sta, int net_no)
+{
+    int count, index;
+    int net_no_list[128];
+
+    RLOGD("[lynq_check_network_number] enter lynq_check_network_number api");
+    count = lynq_get_network_number_list(idx, ap_sta, net_no_list, NULL);
+    for (index=0; index < count; index++)
+    {
+        if (net_no_list[index] == net_no)
+	{
+            return 0;
+        }
+    }
+
+    if (count >= 1)
+        index = net_no_list[count - 1];
+    else
+        index = -1;
+
+    while (index < net_no )
+    {
+        index = lynq_add_network(ap_sta);
+        if (index >= net_no)
+	{ // required network no created
+            RLOGD("required network no created\n");;
+            return 0;
+        }
+        else if( index < 0)
+	{
+            RLOGE("[lynq_check_network_number] add network fail");
+            return -1;
+        }
+    }
+
+    if (index < 0)
+    {
+        RLOGE("[lynq_check_network_number] network index < 0");
+	return -1;
+    }
+    RLOGD("[lynq_check_network_number] work finished &state is ok");
+    return 0;
+}
+
+static lynq_wifi_band_m convert_band_from_freq(int freq) { //@todo
+    if (freq > 5000 && freq < 6000)
+    {
+        return LYNQ_WIFI_5G_band;
+    }
+    else if (freq > 2000 && freq <  3000)
+    {
+        return LYNQ_WIFI_2G_band;
+    }
+    return LYNQ_WIFI_2_and_5G_band;
+}
+
+static lynq_wifi_auth_s convert_auth_from_key_mgmt(char * key_mgmt) {
+    if (key_mgmt != NULL)
+    {
+        if (memcmp( key_mgmt, "NONE", 4) == 0)
+	{
+            return LYNQ_WIFI_AUTH_OPEN;
+        }
+        else if (memcmp( key_mgmt, "WEP", 3) == 0)
+	{
+            return LYNQ_WIFI_AUTH_WEP;
+        }
+        else if (memcmp( key_mgmt, "WPA-PSK", 7) == 0)
+	{
+            return LYNQ_WIFI_AUTH_WPA_PSK;
+        }
+        else if (memcmp( key_mgmt, "WPA2-PSK", 8) == 0)
+	{
+            return LYNQ_WIFI_AUTH_WPA2_PSK;
+        }
+    }
+
+    return -1;
+}
+
+static lynq_wifi_auth_s convert_max_auth_from_flag(char * flag) {
+    if (flag != NULL)
+    {
+        if ( strstr(flag,"WPA2-PSK+SAE-CCMP") != NULL || strstr(flag, "SHA256") != NULL || strstr(flag,"WPA2-SAE") != NULL || ( strstr(flag,"SAE-H2E") != NULL &&  strstr(flag,"WPS") == NULL ) )
+        {
+            return LYNQ_WIFI_AUTH_WPA3_PSK;
+        }else if ( strstr( flag,"SAE-CCMP") != NULL || strstr(flag,"SAE-H2E") != NULL )
+        {
+            return LYNQ_WIFI_AUTH_WPA2_WPA3_PSK;
+        }else if (strstr( flag, "WPA2-PSK") != NULL)
+        {
+            return LYNQ_WIFI_AUTH_WPA2_PSK;
+        }
+        else if (strstr( flag, "WPA-PSK") != NULL)
+        {
+            return LYNQ_WIFI_AUTH_WPA_PSK;
+        }
+        else if (strstr( flag, "WEP") != NULL)
+        {
+            return LYNQ_WIFI_AUTH_WEP;
+        }
+        else if (strstr( flag, "NONE") != NULL)
+        {
+            return LYNQ_WIFI_AUTH_OPEN;
+        }
+        else if (strcmp( flag, "[ESS]") == 0 || strcmp( flag,"[WPS][ESS]") == 0)
+        {
+            return LYNQ_WIFI_AUTH_OPEN;
+        }
+        else
+        {
+            RLOGD("convert_max_auth_from_flag not-found auth mode");
+        }
+    }
+
+    return -1;
+}
+
+static lynq_wifi_bandwidth_type_m convert_bandwidth_from_bw(int bw) {
+    switch (bw) {
+    case 10:
+        return LYNQ_WIFI_BANDWIDTH_HT10;
+        break;
+    case 20:
+        return LYNQ_WIFI_BANDWIDTH_HT20;
+        break;
+    case 40:
+        return LYNQ_WIFI_BANDWIDTH_HT40;
+        break;
+    case 80:
+        return LYNQ_WIFI_BANDWIDTH_HT80;
+        break;
+    default:
+        break;
+    }
+
+    return -1;
+}
+
+static int inner_get_network_auth(int interface, int net_no, lynq_wifi_auth_s *auth);
+static int inner_get_status_info(int interface, curr_status_info *curr_state) {
+    int i, count;
+    char *p;
+    const char *lynq_status_cmd = "STATUS";
+    const char * FLAG_SSID = "ssid=";
+    const char * FLAG_SBSID = "bssid=";
+    const char * FLAG_KEY_MGMT = "key_mgmt=";
+    const char * FLAG_FREQ = "freq=";
+    const char * FLAG_STATE = "wpa_state=";
+    const char * FLAG_ID = "id=";
+    const char * FLAG_IPADDR = "ip_address=";
+    char *split_lines[128] = {0};
+
+    CHECK_WPA_CTRL(interface);
+
+    if (curr_state == NULL)
+    {
+        RLOGE("[wifi error][inner_get_status_info]curr_state is NULL");
+        return -1;
+    }
+
+    DO_REQUEST(lynq_status_cmd);
+
+    count = lynq_split(cmd_reply, reply_len, '\n', split_lines);
+
+    curr_state->net_no = -1;
+    ret = -1;
+    for(i=0; i < count; i++)
+    {
+        if (curr_state->ap != NULL)
+        {
+            p = strstr(split_lines[i], FLAG_SBSID);
+            if (p != NULL)
+            {
+                strncpy(curr_state->ap->ap_mac, p + strlen(FLAG_SBSID), sizeof(curr_state->ap->ap_mac));
+                ret = 0;
+                continue;
+            }
+            p = strstr(split_lines[i], FLAG_SSID);
+            if (p != NULL)
+            {
+                inner_copy_ssid(curr_state->ap->ap_ssid, p + strlen(FLAG_SSID), sizeof (curr_state->ap->ap_ssid));
+                ret = 0;
+                continue;
+            }
+            p = strstr(split_lines[i], FLAG_KEY_MGMT);
+            if (p != NULL)
+            {
+                curr_state->ap->auth = convert_auth_from_key_mgmt(p + strlen(FLAG_KEY_MGMT));
+                RLOGD("inner_get_status_info: key_mgmt %d, -- %s\n", curr_state->ap->auth, p);
+                ret = 0;
+                continue;
+            }
+            p = strstr(split_lines[i], FLAG_FREQ);
+            if (p != NULL)
+            {
+                curr_state->ap->band = convert_band_from_freq(atoi( p + strlen(FLAG_FREQ)));
+                ret = 0;
+                continue;
+            }
+            p = strstr(split_lines[i], FLAG_IPADDR);
+            if (p != NULL)
+            {
+                strncpy(curr_state->ap->ap_ip, p + strlen(FLAG_IPADDR), sizeof(curr_state->ap->ap_ip));
+                ret = 0;
+                continue;
+            }
+        } // end  if (ap != NULL)
+        if (curr_state->state != NULL)
+        {
+            p = strstr(split_lines[i], FLAG_STATE);
+            if (p != NULL)
+            {
+                strcpy(curr_state->state, p + strlen(FLAG_STATE));
+                ret = 0;
+                continue;
+            }
+
+        } //end else if (state != NULL)
+        if ((p = strstr(split_lines[i], FLAG_ID)) == split_lines[i])
+        {
+            ret = 0;
+            curr_state->net_no = atoi(p + strlen(FLAG_ID));
+            RLOGD("inner_get_status_info:net_no %d, -- %s\n", curr_state->net_no, p);
+        }
+    }
+
+    if (ret == 0 && curr_state->ap != NULL && curr_state->net_no >= 0) // auth may not right when add wpa3
+    {
+        inner_get_network_auth(interface, curr_state->net_no, &curr_state->ap->auth);
+    }
+
+    return ret;
+}
+
+int lynq_wifi_ap_ssid_set(lynq_wifi_index_e idx,char *ap_ssid)
+{
+    RLOGD("enter lynq_wifi_ap_ssid_set");
+    char lynq_wifi_ssid_cmd[80]={0};
+
+    if (ap_ssid == NULL)
+    {
+        RLOGE("Input ap_ssid is NULL");
+        return -1;
+    }
+    else
+    {
+        RLOGD("[lynq_wifi_ap_ssid_set]idx:%d ap_ssid : %s\n", idx, ap_ssid);
+    }
+
+    if (lynq_check_network_number(idx, CTRL_AP, AP_NETWORK_0) != 0)
+    {
+        RLOGE("Do check ap network_number fail");
+        return -1;
+    }
+
+    CHECK_IDX(idx, CTRL_AP);
+
+    CHECK_WPA_CTRL(CTRL_AP);
+
+    sprintf(lynq_wifi_ssid_cmd,"SET_NETWORK %d ssid \"%s\"", AP_NETWORK_0, ap_ssid);
+
+    DO_OK_FAIL_REQUEST(lynq_wifi_ssid_cmd);
+    DO_OK_FAIL_REQUEST(cmd_save_config);
+
+    RLOGD("[lynq_wifi_ap_ssid_set] set ssid succeed %d",__LINE__);
+    return 0;
+
+}
+
+int lynq_wifi_ap_ssid_get(lynq_wifi_index_e idx, char* ap_ssid)
+{
+    RLOGD("enter lynq_wifi_ap_ssid_get");
+    CHECK_IDX(idx, CTRL_AP);
+    return inner_get_param(CTRL_AP, AP_NETWORK_0, "ssid", ap_ssid);
+}
+
+/*****
+ *frequency  <------>channel
+ *
+ *frequency   1    2    3    4    5    6    7    8    9   10   11   12   13   36   40   44   48   149  153  157  161  165
+ *
+ *
+ *channel     2412,2417,2422,2427,2532,2437,2442,2447,2452,2457,2462,2467,2472,5180,5200,5220,5240,5745,5765,5785,5805,5825
+ *
+ *
+ * */ 
+static int lynq_check_set_frequency(int input_frequency){
+    int legitimate_frequency[]={2412,2417,2422,2427,2432,2437,2442,2447,2452,2457,2462,2467,2472,5180,5200,5220,5240,5745,5765,5785,5805,5825};
+    int i;
+    int arr_len = sizeof(legitimate_frequency) / sizeof(int);
+
+    for(i = 0; i < arr_len; i++)
+    {
+        if(input_frequency == legitimate_frequency[i])
+            break;
+    }
+
+    if(i == arr_len)
+    {
+        RLOGE("[lynq_check_set_frequency]input frequency is --->%d,please check it\n", input_frequency);
+        return -1;
+    }
+
+    return 0;
+}
+
+static int lynq_check_frequencyby_country_code(int input_frequency)
+{
+    char str_cnc[]="CN";
+    char str_dest[20]="";
+
+    if( lynq_get_country_code(1,str_dest) != 0 )
+    {
+        RLOGE("get country_code error\n");
+	return -1;
+    }
+    if( strncmp(str_dest,str_cnc,2) != 0 )
+    {
+        return 0;
+    }else if( 2473 < input_frequency && input_frequency < 5744)
+    {
+        RLOGE("input frequency is bad\n");
+	return -1;
+    } 
+    return 0;
+}
+int lynq_wifi_ap_frequency_set(lynq_wifi_index_e idx,int lynq_wifi_frequency)
+{
+    int check;
+    char lynq_wifi_frequency_cmd[128]={0};
+    char lynq_cmd_mode[128]={0};
+    char lynq_cmd_slect[128]={0};
+    RLOGD("enter %s %d input frequency:%d",__func__,__LINE__,lynq_wifi_frequency);
+    //@do check input frequency
+    check = lynq_check_set_frequency(lynq_wifi_frequency);
+    if(check != 0)
+    {
+        RLOGE("do check frequency error");
+        return -1;
+    }
+    check = lynq_check_frequencyby_country_code(lynq_wifi_frequency);
+    if(check != 0)
+    {
+        RLOGE("do check frequency error");
+        return -1;
+    }
+
+    if (lynq_check_network_number(idx, CTRL_AP, AP_NETWORK_0) != 0)
+    {
+        RLOGE("[set ap frequecny][lynq_check_network_number] error");
+        return -1;
+    }
+
+    CHECK_IDX(idx, CTRL_AP);
+
+    CHECK_WPA_CTRL(CTRL_AP);
+
+    sprintf(lynq_wifi_frequency_cmd,"SET_NETWORK %d frequency %d", AP_NETWORK_0, lynq_wifi_frequency);
+    sprintf(lynq_cmd_mode, "SET_NETWORK %d mode 2", AP_NETWORK_0);
+    sprintf(lynq_cmd_slect, "SELECT_NETWORK %d", AP_NETWORK_0);
+
+    DO_OK_FAIL_REQUEST(cmd_disconnect);
+    DO_OK_FAIL_REQUEST(lynq_wifi_frequency_cmd);
+    DO_OK_FAIL_REQUEST(lynq_cmd_mode);
+    DO_OK_FAIL_REQUEST(cmd_save_config);
+
+    return 0;
+}
+
+int lynq_wifi_ap_frequency_get(lynq_wifi_index_e idx,int *lynq_wifi_frequency)
+{
+    char lynq_frequency_str[MAX_RET] = {0};
+    RLOGD("enter lynq_wifi_ap_frequency_get and input idx is %d",idx);
+    CHECK_IDX(idx, CTRL_AP);
+
+    if (inner_get_param(CTRL_AP, AP_NETWORK_0, "frequency", lynq_frequency_str) != 0)
+    {
+        RLOGE("[wifi error][lynq_wifi_ap_frequency_get]get frequency from device fail");
+        return -1;
+    }
+    *lynq_wifi_frequency = atoi(lynq_frequency_str);
+
+    return 0;
+}
+
+int lynq_wifi_ap_bandwidth_set(lynq_wifi_index_e idx,lynq_wifi_bandwidth_type_m bandwidth)
+{
+    RLOGD("enter lynq_wifi_ap_bandwidth_set");
+    CHECK_IDX(idx, CTRL_AP);
+    switch(bandwidth){
+        case LYNQ_WIFI_BANDWIDTH_HT10:
+	{
+            RLOGE("bandwith  [%d] not support now\n", bandwidth);
+	    return -1;
+	}
+        case LYNQ_WIFI_BANDWIDTH_HT20:
+        {
+            char lynq_cmd_bandwith[MAX_CMD]="wl chanspec 6";
+            system("wl down");
+            if (system(lynq_cmd_bandwith) != 0 )
+	    {
+                RLOGE("lynq_wifi_ap_bandwidth_set erro");
+                return -1;
+            }
+            system("wl up");
+            break;
+        }
+        case LYNQ_WIFI_BANDWIDTH_HT40:
+        {
+            char lynq_cmd_bandwith[MAX_CMD]="wl chanspec 149/40";
+            sprintf(lynq_cmd_bandwith, "wl chanspec ");
+            system("wl down");
+            if (system(lynq_cmd_bandwith) != 0 )
+	    {
+                RLOGE("lynq_wifi_ap_bandwidth_set erro");
+                return -1;
+            }
+            system("wl up");
+            break;
+        }
+        case LYNQ_WIFI_BANDWIDTH_HT80:
+        {
+            char lynq_cmd_bandwith[MAX_CMD]="wl chanspec 149/80";
+            system("wl down");
+            if (system(lynq_cmd_bandwith) != 0 )
+	    {
+                RLOGE("lynq_wifi_ap_bandwidth_set erro");
+                return -1;
+            }
+            system("wl up");
+            break;
+        }				
+        default:
+        {
+            RLOGE("auth type [%d] not support now\n", bandwidth);
+            return -1;
+        }
+    }
+
+
+    return 0;
+}
+
+int lynq_wifi_ap_bandwidth_get(lynq_wifi_index_e idx,lynq_wifi_bandwidth_type_m* bandwidth)
+{
+    int count = 0;
+    int index = 0;
+    char *split_words[128] = {0};
+    const char *lynq_chanspec_cmd = "DRIVER chanspec\n";
+    RLOGD("enter lynq_wifi_ap_bandwidth_get");
+    CHECK_IDX(idx, CTRL_AP);
+
+    CHECK_WPA_CTRL(CTRL_AP);
+
+    DO_REQUEST(lynq_chanspec_cmd);
+
+    count = lynq_split(cmd_reply, reply_len, ' ', split_words);
+    for(;index < count; index++) {
+        if (strncmp(split_words[index], "bw", 2) != 0) {
+            continue;
+        }
+
+        index++;
+        if (index >= count) {
+            return -1;
+        }
+
+        RLOGD("bw %s\n", split_words[index]);
+        *bandwidth = convert_bandwidth_from_bw(atoi(split_words[index]));
+        return 0;
+    }
+    RLOGE("[wifi error]lynq_wifi_ap_bandwidth_get");
+    return -1;
+}
+
+int lynq_wifi_ap_channel_set( lynq_wifi_index_e idx,int channel)
+{
+    char lynq_cmd_channel[MAX_CMD]={0};
+    RLOGD("enter lynq_wifi_ap_channel_set and input channel is %d",channel);
+    CHECK_IDX(idx, CTRL_AP);
+
+    sprintf(lynq_cmd_channel, "wl channel %d", channel);
+
+    if (lynq_check_network_number(idx, CTRL_AP, AP_NETWORK_0) != 0) 
+    {
+        return -1;
+    }
+
+    system("wl down");
+    if (system(lynq_cmd_channel) != 0 ){
+        RLOGE("lynq_wifi_ap_channel_set erro");
+        return -1;
+    }
+    system("wl up");
+    return 0;
+}
+
+int lynq_wifi_ap_channel_get( lynq_wifi_index_e idx,int* channel)
+{
+    int count = 0;
+    int index = 0;
+    char *split_words[128] = {0};
+    char lynq_chanspec_cmd[]="DRIVER chanspec\n";
+    RLOGD("enter lynq_wifi_ap_channel_get");
+    CHECK_IDX(idx, CTRL_AP);
+
+    CHECK_WPA_CTRL(CTRL_AP);
+
+    DO_REQUEST(lynq_chanspec_cmd);
+
+    count = lynq_split(cmd_reply, reply_len, ' ', split_words);
+    for(;index < count; index++) 
+    {
+        RLOGD("[lynq_wifi_ap_channel_get]---- %s\n",split_words[index]);
+        if (strncmp(split_words[index], "channel", 2) != 0) {
+            continue;
+        }
+
+        index++;
+        if (index >= count) 
+	{
+            return -1;
+        }
+
+        *channel = atoi(split_words[index]);
+        return 0;
+    }
+    RLOGE("[lynq_wifi_ap_channel_get] function fail");
+    return -1;
+}
+
+
+int lynq_wifi_ap_auth_set(lynq_wifi_index_e idx, lynq_wifi_auth_s auth)
+{
+    char ssid[MAX_CMD] = {0};
+    int freq = 0;
+    char lynq_auth_cmd[64]={0};
+    char lynq_auth_alg_cmd[64]={0};
+    char lynq_psk_cmd[64]={0};
+    char lynq_pairwise_cmd[64]={0};
+    char lynq_ieee80211_cmd[64]={0};
+    RLOGD("enter lynq_wifi_ap_auth_set and input idx is:%d,auth is:%d",idx,auth);
+    lynq_wifi_auth_s org_auth;
+    CHECK_IDX(idx, CTRL_AP);
+
+    CHECK_WPA_CTRL(CTRL_AP);
+
+    if (lynq_check_network_number(idx, CTRL_AP, AP_NETWORK_0) != AP_NETWORK_0) 
+    {
+        RLOGE("[wifi error][lynq_wifi_ap_auth_set] check network fail\n");
+        return -1;
+    }
+
+    if (0 == lynq_wifi_ap_auth_get(idx, &org_auth) && org_auth != -1) {
+        if (org_auth == auth) {
+            RLOGD("org_auth --- is %d\n",org_auth);
+            return 0;
+        }
+        else {
+            if (0 != lynq_wifi_ap_ssid_get(idx, ssid)) {
+                ssid[0] = '\0';
+            }
+            lynq_wifi_ap_frequency_get(idx, &freq);
+
+            DO_OK_FAIL_REQUEST(cmd_disconnect);
+            DO_OK_FAIL_REQUEST(cmd_remove_all);
+            if (ssid[0] != '\0') {
+                lynq_wifi_ap_ssid_set(idx, ssid);
+            }
+            if (freq != 0) {
+                lynq_wifi_ap_frequency_set(idx, freq);
+            }
+        }
+    }
+
+    switch(auth){
+	case LYNQ_WIFI_AUTH_OPEN:
+        {
+            RLOGD("auth == is LYNQ_WIFI_AUTH_OPEN\n");
+            sprintf(lynq_auth_cmd,"SET_NETWORK %d key_mgmt NONE", AP_NETWORK_0);
+            sprintf(lynq_pairwise_cmd,"SET_NETWORK %d pairwise NONE", AP_NETWORK_0);
+            DO_OK_FAIL_REQUEST(lynq_auth_cmd);
+	    break;
+	}
+        case LYNQ_WIFI_AUTH_WEP:
+        {
+            RLOGD("auth == is LYNQ_WIFI_AUTH_WEP\n");
+            sprintf(lynq_auth_cmd,"SET_NETWORK %d key_mgmt NONE", AP_NETWORK_0);
+            sprintf(lynq_pairwise_cmd,"SET_NETWORK %d pairwise NONE", AP_NETWORK_0);
+            sprintf(lynq_auth_alg_cmd,"SET_NETWORK %d auth_alg  SHARED", AP_NETWORK_0);
+
+            DO_OK_FAIL_REQUEST(lynq_auth_cmd);
+            DO_OK_FAIL_REQUEST(lynq_auth_alg_cmd);
+            break;
+        }
+	case LYNQ_WIFI_AUTH_WPA_PSK:
+        {
+            sprintf(lynq_auth_cmd,"SET_NETWORK %d proto WPA", AP_NETWORK_0);
+            sprintf(lynq_psk_cmd,"SET_NETWORK %d key_mgmt WPA-PSK", AP_NETWORK_0);
+            sprintf(lynq_pairwise_cmd,"SET_NETWORK %d pairwise CCMP", AP_NETWORK_0);
+
+            DO_OK_FAIL_REQUEST(lynq_auth_cmd);
+            DO_OK_FAIL_REQUEST(lynq_psk_cmd);
+            DO_OK_FAIL_REQUEST(lynq_pairwise_cmd);
+            break;
+
+	}
+        case LYNQ_WIFI_AUTH_WPA2_PSK:
+	{
+            if (auth == LYNQ_WIFI_AUTH_WPA_PSK)
+	    {
+                sprintf(lynq_auth_cmd,"SET_NETWORK %d proto WPA", AP_NETWORK_0);
+                sprintf(lynq_psk_cmd,"SET_NETWORK %d key_mgmt WPA-PSK", AP_NETWORK_0);
+            }
+            else if (auth == LYNQ_WIFI_AUTH_WPA2_PSK)
+	    {
+                sprintf(lynq_auth_cmd,"SET_NETWORK %d proto RSN", AP_NETWORK_0);
+                sprintf(lynq_psk_cmd,"SET_NETWORK %d key_mgmt WPA-PSK", AP_NETWORK_0);
+            }
+//            sprintf(lynq_auth_cmd,"SET_NETWORK %d proto WPA2", AP_NETWORK_0);
+//            sprintf(lynq_psk_cmd,"SET_NETWORK %d key_mgmt WPA-PSK", AP_NETWORK_0);
+            sprintf(lynq_pairwise_cmd,"SET_NETWORK %d pairwise CCMP", AP_NETWORK_0);
+
+            DO_OK_FAIL_REQUEST(lynq_auth_cmd);
+            DO_OK_FAIL_REQUEST(lynq_psk_cmd);
+            DO_OK_FAIL_REQUEST(lynq_pairwise_cmd);
+	    break;
+	}		
+        case LYNQ_WIFI_AUTH_WPA2_WPA3_PSK:
+	{
+            sprintf(lynq_auth_cmd,"SET_NETWORK %d proto WPA2", AP_NETWORK_0);
+            sprintf(lynq_ieee80211_cmd,"SET_NETWORK %d ieee80211w 1", AP_NETWORK_0);
+            sprintf(lynq_psk_cmd,"SET_NETWORK %d key_mgmt WPA-PSK SAE", AP_NETWORK_0);
+            sprintf(lynq_pairwise_cmd,"SET_NETWORK %d pairwise CCMP", AP_NETWORK_0);
+
+            DO_OK_FAIL_REQUEST(lynq_auth_cmd);
+            DO_OK_FAIL_REQUEST(lynq_ieee80211_cmd);
+            DO_OK_FAIL_REQUEST(lynq_psk_cmd);
+            DO_OK_FAIL_REQUEST(lynq_pairwise_cmd);
+	    break;
+	}		
+        case LYNQ_WIFI_AUTH_WPA3_PSK:
+	{
+            sprintf(lynq_auth_cmd,"SET_NETWORK %d proto WPA2", AP_NETWORK_0);
+            sprintf(lynq_ieee80211_cmd,"SET_NETWORK %d ieee80211w 2", AP_NETWORK_0);
+            sprintf(lynq_psk_cmd,"SET_NETWORK %d key_mgmt SAE", AP_NETWORK_0);
+            sprintf(lynq_pairwise_cmd,"SET_NETWORK %d pairwise CCMP", AP_NETWORK_0);
+
+            DO_OK_FAIL_REQUEST(lynq_auth_cmd);
+            DO_OK_FAIL_REQUEST(lynq_ieee80211_cmd);
+            DO_OK_FAIL_REQUEST(lynq_psk_cmd);
+            DO_OK_FAIL_REQUEST(lynq_pairwise_cmd);
+	    break;
+	}		
+	default:
+        {
+            RLOGE("auth type [%d] not support now\n", auth);
+            return -1;
+        }
+    }
+    DO_OK_FAIL_REQUEST(cmd_save_config);
+
+    return 0;
+}
+
+int lynq_wifi_ap_auth_get(lynq_wifi_index_e idx, lynq_wifi_auth_s *auth)
+{
+    char lynq_auth_str[MAX_RET] = {0};
+    char lynq_auth_alg_str[MAX_RET] = {0};
+    char lynq_proto_str[MAX_RET] = {0};
+    RLOGD("enter lynq_wifi_ap_auth_get");
+    CHECK_IDX(idx, CTRL_AP);
+
+    if (inner_get_param(CTRL_AP, AP_NETWORK_0, "key_mgmt", lynq_auth_str) != 0)
+    {
+        RLOGE("[wifi error][lynq_wifi_ap_auth_get] check network fail");
+        return -1;
+    }
+
+    if (memcmp( lynq_auth_str, "NONE", 4) == 0)
+    {
+        if (inner_get_param(CTRL_AP, AP_NETWORK_0, "auth_alg", lynq_auth_alg_str) != 0)
+	{
+            RLOGD("---auth is OPEN\n");
+            *auth = LYNQ_WIFI_AUTH_OPEN;
+            return 0;
+        }
+        else if (memcmp(lynq_auth_alg_str, "SHARED", 6) == 0)
+	{
+            RLOGD("---auth is WEP\n");
+            *auth = LYNQ_WIFI_AUTH_WEP;
+            return 0;
+        }
+        else
+	{
+            RLOGD("---auth is OPEN\n");
+            *auth = LYNQ_WIFI_AUTH_OPEN;
+            return 0;
+        }
+    }
+    else if(strcmp( lynq_auth_str, "WPA-PSK") == 0 )
+    {
+        if (inner_get_param(CTRL_AP, AP_NETWORK_0, "proto", lynq_proto_str) != 0)
+	{
+            RLOGE("---auth is -1\n");
+            *auth = -1;
+        }
+        else if (memcmp(lynq_proto_str, "RSN", 3) == 0)
+	{
+            RLOGD("---auth WPA2_PSK\n");
+            *auth = LYNQ_WIFI_AUTH_WPA2_PSK;
+            return 0;
+        }
+        else
+	{
+            RLOGD("---auth WPA_PSK\n");
+            *auth = LYNQ_WIFI_AUTH_WPA_PSK;
+	    return 0;
+        }
+    }
+    
+    if (inner_get_param(CTRL_AP, AP_NETWORK_0, "ieee80211w", lynq_auth_str) != 0)
+    {
+        RLOGE("[wifi error][lynq_wifi_ap_auth_get] check network auth ieee80211w fail");
+        return -1;
+    }
+    
+    if (memcmp(lynq_auth_str,"1",1) == 0 )
+    {
+	RLOGD("auth : LYNQ_WIFI_AUTH_WPA2_WPA3_PSK\n");
+        *auth = LYNQ_WIFI_AUTH_WPA2_WPA3_PSK;
+        return 0;
+    }else if (memcmp(lynq_auth_str,"2",1) == 0 )
+    {
+	RLOGD("auth : LYNQ_WIFI_AUTH_WPA3_PSK\n");
+        *auth = LYNQ_WIFI_AUTH_WPA3_PSK;
+        return 0;
+    }
+    else
+    {
+	RLOGE("---auth -- -1\n");
+        *auth = -1;
+    }
+
+    return 0;
+}
+
+static int inner_check_ap_connected(lynq_wifi_index_e idx, int retry_count)
+{
+    char status[64];
+    char LYNQ_WIFI_CMD[32]={0};
+    curr_status_info curr_state;
+
+    CHECK_WPA_CTRL(CTRL_AP);
+
+    memset(status, 0, sizeof (status));
+
+    curr_state.ap = NULL;
+    curr_state.state = status;
+
+    printf("inner_check_ap_connected %d\n", retry_count);
+    usleep(250*1000);
+    if (0 == inner_get_status_info(idx, &curr_state))
+    {
+        if ((strcmp(status, STATE_SCANNING) == 0)|| (strcmp(status, STATE_COMPLETED) == 0))
+        {
+            return 0;
+        }
+        else if (retry_count == 8) //not ok in 2s, do reconnect
+        {
+            DO_REQUEST("RECONNECT");
+            return inner_check_ap_connected(idx, retry_count+1);
+        }
+        else if (retry_count > 20)
+        {
+            printf("retry 10 time\n");
+            return -1;
+        }
+        else
+        {
+            if (strcmp(status, STATE_DISCONNECTED) == 0)
+            {
+                sprintf(LYNQ_WIFI_CMD,"SELECT_NETWORK %d",AP_NETWORK_0);
+                DO_REQUEST(LYNQ_WIFI_CMD);
+            }
+            return inner_check_ap_connected(idx, retry_count+1);
+        }
+    }
+    return -1;
+}
+
+int lynq_wifi_ap_start(lynq_wifi_index_e idx)
+{
+    RLOGD("enter %s %d",__func__,__LINE__);
+    char LYNQ_WIFI_CMD[128]={0};
+
+    CHECK_IDX(idx, CTRL_AP);
+    CHECK_WPA_CTRL(CTRL_AP);
+
+    if (inner_get_ap_interface_name() == NULL)
+    {
+        RLOGE("lynq_wifi_ap_start get ap name fail");
+        return -1;
+    }
+
+
+    sprintf(LYNQ_WIFI_CMD,"SELECT_NETWORK %d",AP_NETWORK_0);
+    DO_OK_FAIL_REQUEST(LYNQ_WIFI_CMD);
+
+    ret = system_call_v("%s %s", start_stop_ap_script, "start");
+    if (ret != 0)
+    {
+        RLOGE("lynq_wifi_ap_start excute script fail");
+        return -1;
+    }
+
+    if (inner_check_ap_connected(idx, 0) != 0)
+    {
+        return -1;
+    }
+
+    check_tether_and_notify();
+/*
+    if (g_ap_tmp_watcher_pid == 0)
+    {
+        if(pthread_create(&g_ap_tmp_watcher_pid,NULL,APTmpWatcherThreadProc,NULL) < 0)
+        {
+            g_ap_tmp_watcher_pid = 0;
+            RLOGE("[wifi error]create APTmpWatcherThreadProc fail");
+            return -1;
+        }
+        RLOGD("[lynq_wifi_ap_start] creat APTmpWatcherThreadProc ok");
+    }
+*/
+    RLOGD("end %s %d",__func__,__LINE__);
+    return 0;
+}
+
+int lynq_wifi_ap_restart(lynq_wifi_index_e idx)
+{
+    return lynq_wifi_ap_stop(idx) == 0 ? lynq_wifi_ap_start(idx)  : -1;
+}
+
+int lynq_wifi_ap_stop(lynq_wifi_index_e idx)
+{
+    RLOGD("enter %s %d",__func__,__LINE__);
+    char LYNQ_WIFI_CMD[128]={0};
+
+    CHECK_IDX(idx, CTRL_AP);
+
+    CHECK_WPA_CTRL(CTRL_AP);
+
+    sprintf(LYNQ_WIFI_CMD,"DISABLE_NETWORK %d",AP_NETWORK_0);
+
+    DO_OK_FAIL_REQUEST(LYNQ_WIFI_CMD);
+
+
+    ret = system_call_v("%s %s", start_stop_ap_script, "stop");
+    if (ret != 0)
+    {
+        RLOGE("lynq_wifi_ap_start excute script fail");
+        return -1;
+    }
+/*
+    g_ap_tmp_watcher_stop_flag = 1;
+    if (g_ap_tmp_watcher_pid != 0)
+        pthread_join(g_ap_tmp_watcher_pid, NULL);
+    g_ap_tmp_watcher_pid = 0;
+*/
+    RLOGD("end %s %d",__func__,__LINE__);
+    return 0;
+}
+
+int lynq_wifi_ap_hide_ssid(lynq_wifi_index_e idx)
+{
+    char lynq_disable_cmd[128] = {0};
+    char lynq_select_cmd[128] = {0};
+    const char *lynq_hide_cmd = "SET HIDE_SSID 1";
+    RLOGD("enter lynq_wifi_ap_hide_ssid");
+    CHECK_IDX(idx, CTRL_AP);
+
+    CHECK_WPA_CTRL(CTRL_AP);
+    sprintf(lynq_disable_cmd,"DISABLE_NETWORK %d", AP_NETWORK_0);
+    sprintf(lynq_select_cmd,"SELECT_NETWORK %d", AP_NETWORK_0);
+
+    DO_OK_FAIL_REQUEST(lynq_disable_cmd);
+    DO_OK_FAIL_REQUEST(lynq_hide_cmd);
+    DO_OK_FAIL_REQUEST(lynq_select_cmd);
+
+    return 0;
+}
+
+int lynq_wifi_ap_unhide_ssid(lynq_wifi_index_e idx)
+{
+    char lynq_disable_cmd[128] = {0};
+    char lynq_select_cmd[128] = {0};
+    const char *lynq_unhide_cmd = "SET HIDE_SSID 0";
+    RLOGD("enter lynq_wifi_ap_unhide_ssid");
+    CHECK_IDX(idx, CTRL_AP);
+
+    CHECK_WPA_CTRL(CTRL_AP);
+
+    sprintf(lynq_disable_cmd,"DISABLE_NETWORK %d", AP_NETWORK_0);
+    sprintf(lynq_select_cmd,"SELECT_NETWORK %d", AP_NETWORK_0);
+
+    DO_OK_FAIL_REQUEST(lynq_disable_cmd);
+    DO_OK_FAIL_REQUEST(lynq_unhide_cmd);
+    DO_OK_FAIL_REQUEST(lynq_select_cmd);
+
+    return 0;
+}
+
+int lynq_ap_password_set(lynq_wifi_index_e idx,char *password)
+{
+    int pass_len;
+    char lynq_tmp_cmd[MAX_CMD] = {0};
+    char lynq_wpa2_wpa3[64] = {0};
+    char lynq_wep_tx_keyidx_cmd[MAX_CMD] = {0};
+    RLOGD("enter lynq_ap_password_set");
+    if( password == NULL )
+    {
+        RLOGE("[lynq_ap_password_set]input password is NULL");
+        return -1;
+    }
+    pass_len=strlen(password);
+    lynq_wifi_auth_s auth = -1;
+    if(pass_len < 8 || pass_len >= 64)
+    {
+        RLOGE("[lynq_ap_password_set]input password len not in rage");
+        return -1;
+    }
+
+    CHECK_IDX(idx, CTRL_AP);
+
+    if (0 != lynq_wifi_ap_auth_get(idx, &auth))
+    {
+        RLOGE("[lynq_ap_password_set] get ap auth info error\n");
+        return -1;
+    }
+    else if (auth == LYNQ_WIFI_AUTH_OPEN)
+    {
+        RLOGD("ap auth :LYNQ_WIFI_AUTH_OPEN\n");
+        return 0;
+    }
+
+    CHECK_WPA_CTRL(CTRL_AP);
+
+    if (auth == LYNQ_WIFI_AUTH_WEP)
+    {
+        RLOGD("[lynq_ap_password_set]ap auth : LYNQ_WIFI_AUTH_WEP\n");
+        sprintf(lynq_tmp_cmd,"SET_NETWORK %d wep_key0 \"%s\"",AP_NETWORK_0, password);
+        sprintf(lynq_wep_tx_keyidx_cmd,"SET_NETWORK %d wep_tx_keyidx 0",AP_NETWORK_0);
+        DO_OK_FAIL_REQUEST(lynq_tmp_cmd);
+        DO_OK_FAIL_REQUEST(lynq_wep_tx_keyidx_cmd);
+    }
+    else if (auth == LYNQ_WIFI_AUTH_WPA_PSK || auth == LYNQ_WIFI_AUTH_WPA2_PSK)
+    {
+        RLOGD("[lynq_ap_password_set]ap auth :LYNQ_WIFI_AUTH_WPA_PSK  LYNQ_WIFI_AUTH_WPA2_PSK\n");
+        sprintf(lynq_tmp_cmd,"SET_NETWORK %d psk \"%s\"",AP_NETWORK_0, password);
+        DO_OK_FAIL_REQUEST(lynq_tmp_cmd);
+    }
+    else if (auth == LYNQ_WIFI_AUTH_WPA2_WPA3_PSK || auth == LYNQ_WIFI_AUTH_WPA3_PSK)
+    {
+        
+        RLOGD("[lynq_ap_password_set]ap auth :LYNQ_WIFI_AUTH_WPA2_WPA3  LYNQ_WIFI_AUTH_WPA3_PSK\n");
+        sprintf(lynq_tmp_cmd,"SET_NETWORK %d psk \"%s\"",AP_NETWORK_0, password);
+        sprintf(lynq_wpa2_wpa3,"SET_NETWORK %d sae_password \"%s\"",AP_NETWORK_0, password);
+        DO_OK_FAIL_REQUEST(lynq_tmp_cmd);
+        DO_OK_FAIL_REQUEST(lynq_wpa2_wpa3);
+
+    }
+    else
+    {   
+        RLOGD("[lynq_ap_password_set]ap auth :get ap auth error\n");
+        return -1;
+    }
+
+    DO_OK_FAIL_REQUEST(cmd_save_config);
+
+    return 0;
+}
+
+int lynq_ap_password_get(lynq_wifi_index_e idx, char *password)
+{
+    FILE * fp;
+    int len, ret;
+    int count, index;
+    char *split_lines[128] = {0};
+    char *buff, *p;
+    RLOGD("enter lynq_ap_password_get");
+
+    CHECK_IDX(idx, CTRL_AP);
+
+    fp = fopen("/data/wifi/wg870/wpa_supplicant_ap.conf", "rb");
+//    fp = fopen("/data/wifi/wg870/wpa_supplicant.conf", "rb");
+    if (NULL == fp)
+    {
+        RLOGE("open file fail\n");
+        return  -1;
+    }
+
+    buff = alloca(MAX_RET);
+    fseek(fp, 0, SEEK_SET);
+    len = fread(buff, 1, MAX_RET, fp);
+    fclose(fp);
+
+    for(index=0; index < len; index ++)
+    {
+        if (memcmp(buff + index, "network={", 9) != 0)
+	{
+            continue;
+        }
+         p = buff + index + 9;
+         for (; index < len; index ++ )
+	 {
+             if (buff[index] != '}')
+	     {
+                 continue;
+             }
+             buff[index] = '\0';
+             break;
+         }
+         len = buff + index - p;
+    }
+
+    count = lynq_split(p, len, '\n', split_lines);
+
+    ret = -1;
+    for(index=0; index < count; index++)
+    {
+        p = strstr(split_lines[index], "psk=");
+        if (p != NULL)
+	{
+            p += 4;
+            if (*p == '\"')
+	    {
+                p++;
+            }
+        }
+        else if (NULL != (p = strstr(split_lines[index], "wep_key0=")))
+	{
+            p += 9;
+            if (*p == '\"')
+	    {
+                p++;
+            }
+        }
+        else
+	{
+            continue;
+        }
+
+        strcpy(password, p);
+
+        while(*password != '\0')
+	{
+            if (*password == '\"')
+	    {
+                *password = '\0';
+                break;
+            }
+            password++;
+        }
+        ret = 0;
+        break;
+    } //end for(index=0; index < count; index++)
+
+    return ret;
+}
+
+static int inner_get_network_auth(int interface, int net_no, lynq_wifi_auth_s *auth) {
+    char lynq_auth_str[MAX_RET] = {0};
+    char lynq_proto_str[MAX_RET] = {0};
+
+    if (inner_get_param(interface, net_no, "key_mgmt", lynq_auth_str) != 0)
+    {
+        return -1;
+    }
+
+    *auth = convert_auth_from_key_mgmt(lynq_auth_str);
+
+    if (*auth == LYNQ_WIFI_AUTH_WPA_PSK)
+    {
+        if (inner_get_param(interface, net_no, "proto", lynq_proto_str) == 0)
+        {
+            if (strcmp(lynq_proto_str, "RSN") == 0)
+            {
+                *auth = LYNQ_WIFI_AUTH_WPA2_PSK;
+                return 0;
+            }
+            else if (strcmp(lynq_proto_str, "WPA") == 0) // need compare when wpa3 supported
+            {
+                return 0;
+            }
+        }
+    }
+    else if (*auth == LYNQ_WIFI_AUTH_OPEN || *auth == LYNQ_WIFI_AUTH_WEP)
+    {
+        return 0;
+    }
+
+    if (inner_get_param(interface, net_no,"ieee80211w",lynq_auth_str) !=0)
+    {
+        RLOGE("check ieee80211w error\n");
+        return -1;
+    }
+    if ( strncmp(lynq_auth_str,"1",1) == 0 )
+    {
+
+        *auth = LYNQ_WIFI_AUTH_WPA2_WPA3_PSK;
+        return 0;
+    }else if( strncmp(lynq_auth_str,"2",1) == 0 )
+    {
+
+        *auth = LYNQ_WIFI_AUTH_WPA3_PSK;
+        return 0;
+    }else
+    {
+        RLOGE("check ieee80211w error, not 1 or 2\n");
+        *auth = -1;
+        return -1;
+    }
+    return 0;
+}
+
+int lynq_sta_ssid_password_set(lynq_wifi_index_e idx, ap_info_s *ap, char *password)
+{
+    RLOGD("enter lynq_sta_ssid_password_set");
+    int pass_len, net_no, count, index;
+    char lynq_tmp_cmd[300]={0};
+    int net_no_list[128];
+    lynq_wifi_auth_s net_auth;
+    pass_len=strlen(password);
+    if(pass_len < 8 || pass_len >= 64)
+    {
+        RLOGE("[lynq_sta_ssid_password_set]input psw error");
+        return -1;
+    }
+
+    CHECK_IDX(idx, CTRL_STA);
+
+    net_no = -1;
+    count = lynq_get_network_number_list(idx, CTRL_STA, net_no_list, ap->ap_ssid);
+
+    for (index=0; index < count; index++)
+    {
+        net_auth = -1;
+        if (0 == inner_get_network_auth(CTRL_STA, net_no_list[index], &net_auth) && net_auth == ap->auth)
+	{
+            net_no = net_no_list[index];
+            break;
+        }
+    }
+
+    if (net_no < 0)
+    {
+        return -1;
+    }
+
+    CHECK_WPA_CTRL(CTRL_STA);
+
+    sprintf(lynq_tmp_cmd,"SET_NETWORK %d psk \"%s\"",net_no, password);
+
+    DO_OK_FAIL_REQUEST(lynq_tmp_cmd);
+    DO_OK_FAIL_REQUEST(cmd_save_config);
+
+    return 0;
+}
+
+/**
+*   buff  data
+*   buff_len  size of buff
+*   idx  sta
+*   *ap   ap info for find ssid && password
+*   password  return password
+* 
+*/
+static int lynq_sta_ssid_password_auth_get(char * buff,int buff_len,lynq_wifi_index_e idx, ap_info_s *ap,char *password) { // @todo
+
+    int ret, network_len, i, ssid_len,curr_auth;
+    int count, index,org_index;
+    char *split_lines[128] = {0};
+    char *p, *ssid, *ssid_end_flag,*ptr;
+    char tmp_ssid[128]={0};
+    char tmp_auth[24]={0};
+
+    org_index = 0;
+    network_len = 0;
+    p = NULL;
+
+    CHECK_IDX(idx, CTRL_STA);
+
+    while(1){
+        network_len = 0;
+        p == NULL;
+        for(; org_index < buff_len; org_index ++)
+        {
+            for(; org_index < buff_len; org_index ++)
+            {
+                if (memcmp(buff + org_index, "network={", 9) != 0)
+                {
+                    continue;
+                }
+                p = buff + org_index + 9;
+
+                for (; org_index < buff_len; org_index ++ )
+                {
+                    if (buff[org_index] != '}')
+                    {
+                        continue;
+                    }
+                    buff[org_index] = '\0';
+                    break;
+                }
+                network_len = buff + org_index - p;
+                break;
+            }
+
+            if (p == NULL)
+            {
+                RLOGD("not find dest info %s(),line %dERROR",__func__,__LINE__);
+                return -1;
+            }
+
+            ssid = strstr(p, "ssid=");
+            if (ssid != NULL) {
+                ssid += strlen("ssid=");
+                if (ssid[0] == '\"')
+                {
+                    if (memcmp(ssid + 1, ap->ap_ssid, strlen(ap->ap_ssid)) == 0 && ssid[strlen(ap->ap_ssid) + 1] == '\"')
+                    {
+                        break;
+                    }
+                }
+                else
+                {
+                    ssid_end_flag = strstr(ssid, "\n");
+                    if (ssid_end_flag != NULL)
+                    {
+                        ssid_len = (ssid_end_flag - ssid) / 2;
+                        for(i=0; i<ssid_len; i++)
+                        {
+                            tmp_ssid[i] = inner_convert_char(ssid[i*2]) << 4 | inner_convert_char(ssid[i*2 + 1]);
+                        }
+                        if (memcmp(tmp_ssid, ap->ap_ssid, ssid_len) == 0)
+                        {
+                            break;
+                        }
+                    }
+                }
+            }
+
+        }
+
+        if (org_index >= buff_len || NULL == p || network_len <= 0)
+        {
+
+            if (buff != NULL)
+            RLOGD("not find dest ssid %s(),line %dERROR",__func__,__LINE__);
+            return -1;
+        }
+
+        count = lynq_split(p, network_len, '\n', split_lines);
+        ret = -1;
+        for( index=0; index < count; index++ )
+        {
+            p = strstr(split_lines[index], "key_mgmt=");
+            if(p != NULL)
+            {
+                p += 9;
+                if(memcmp(p,"SAE",3) == 0)
+                {
+                    curr_auth = 5;
+                }else if(memcmp(p,"WPA-PSK SAE",11) == 0)
+                {
+                     curr_auth = 4;
+                }else if(memcmp(p,"WPA-PSK",7) == 0 )
+                {
+                      curr_auth = 3;
+                }else if(memcmp(p,"NONE",4) == 0 )
+                {
+                      curr_auth = 0;
+                }else{
+                        curr_auth = 1;
+                    }
+                if( curr_auth < 1 || curr_auth > 6)
+                {
+                    ret = -1;
+                }
+                break;
+            }
+        }
+        if( curr_auth == 0)
+        {
+            return 0;
+        }else if(curr_auth == ap->auth || ap->auth <= 3 && curr_auth <= 3 && curr_auth != -1 )
+        {
+            for(index=0; index < count; index++)
+            {
+                /*get psw info*/
+
+                p = strstr(split_lines[index], "psk=");
+                if (p != NULL)
+                {
+                    p += 4;
+                    if (*p == '\"')
+                    {
+                        p++;
+                    }
+                }
+                else if (NULL != (p = strstr(split_lines[index], "wep_key0=")))
+                {
+                    p += 9;
+                    if (*p == '\"')
+                    {
+                        p++;
+                    }
+                }
+                else
+                {
+                    continue;
+                }
+
+                if (*p == '\"')
+                    p++;
+                strncpy(password, p, 64);
+                p = password;
+                while(password - p < 64 && *password != '\0')
+                {
+                    if (*password == '\"')
+                    {
+                        *password = '\0';
+                        ret = 0;
+                        break;
+                    }
+                    password++;
+                }
+                break;
+            }
+            break;
+        }
+    }
+
+    return ret;
+}
+
+
+
+int lynq_sta_ssid_password_get(lynq_wifi_index_e idx, ap_info_s *ap, char *password) { // @todo
+
+    FILE * fp;
+    int len, ret;
+    char *info_buff;
+    RLOGD("enter lynq_sta_ssid_password_get");
+
+    info_buff = NULL;
+    CHECK_IDX(idx, CTRL_STA);
+
+    if (NULL == password)
+    {
+        RLOGE("bad param\n");
+        return -1;
+    }
+
+    fp = fopen("/data/wifi/wg870/wpa_supplicant.conf", "rb");
+    if (NULL == fp)
+    {
+        RLOGE("[lynq_sta_ssid_password_get] open file fail\n");
+        return  -1;
+    }
+
+    fseek(fp, 0, SEEK_END);
+    len = ftell(fp);
+    info_buff = malloc(len + 1);
+
+    if (info_buff == NULL)
+    {
+        RLOGE("[lynq_sta_ssid_password_get] malloc memory [%d] fail\n", len);
+        return  -1;
+    }
+
+    fseek(fp, 0, SEEK_SET);
+    len = fread(info_buff, 1, len, fp);
+    fclose(fp);
+
+
+    ret= lynq_sta_ssid_password_auth_get(info_buff,len,0, ap,password);
+
+    if(ret == 0)
+    {
+        RLOGD("lynq_sta_ssid_password_auth_get pass return ssid :%s psw is %s",ap->ap_ssid,password);
+        free(info_buff);
+        return 0;
+    }
+    else{
+        free(info_buff);
+        return -1;
+    }
+
+}
+
+
+static int inner_set_sta_ssid(int net_no, char *sta_ssid)
+{
+    char lynq_wifi_ssid_cmd[80]={0};
+
+    if (sta_ssid == NULL)
+    {
+        RLOGE("sta_ssid is null\n");
+        return -1;
+    }
+
+    CHECK_WPA_CTRL(CTRL_STA);
+
+    sprintf(lynq_wifi_ssid_cmd,"SET_NETWORK %d ssid \"%s\"", net_no, sta_ssid);
+
+    DO_OK_FAIL_REQUEST(lynq_wifi_ssid_cmd);
+//    DO_OK_FAIL_REQUEST(cmd_save_config);
+
+    return 0;
+
+}
+
+static int inner_sta_start_stop(int net_no, int start_flag, int save)
+{
+    char lynq_disable_cmd[128]={0};
+    char lynq_select_cmd[128]={0};
+
+    CHECK_WPA_CTRL(CTRL_STA);
+
+    if (save != 0)
+    {
+        if (start_flag != 0)
+        {
+            sprintf(lynq_select_cmd,"ENABLE_NETWORK %d", net_no);
+            DO_OK_FAIL_REQUEST(lynq_select_cmd);
+        }
+        else
+        {
+            sprintf(lynq_select_cmd,"DISABLE_NETWORK %d", net_no);
+            DO_OK_FAIL_REQUEST(lynq_select_cmd);
+        }
+        DO_OK_FAIL_REQUEST(cmd_save_config);
+    }
+
+    if (start_flag == 0)
+    {
+        sprintf(lynq_disable_cmd,"DISCONNECT");
+        DO_OK_FAIL_REQUEST(lynq_disable_cmd);
+    }
+    else
+    {
+        sprintf(lynq_select_cmd,"SELECT_NETWORK %d", net_no);
+        DO_OK_FAIL_REQUEST(lynq_select_cmd);
+    }
+
+    return 0;
+}
+
+int lynq_wifi_get_sta_ssid(lynq_wifi_index_e idx, char* sta_ssid)
+{
+    RLOGD("enter lynq_sta_ssid_password_set");
+    CHECK_IDX(idx, CTRL_STA);
+
+    curr_status_info curr_state;
+    ap_info_s ap_info;
+    curr_state.ap = &ap_info;
+    curr_state.state = NULL;
+
+    if (0 == inner_get_status_info(CTRL_STA, &curr_state))
+    {
+        strncpy(sta_ssid, ap_info.ap_ssid, sizeof (ap_info.ap_ssid));
+        return 0;
+    }
+
+    return -1;
+}
+
+int lynq_wifi_get_sta_available_ap(lynq_wifi_index_e idx, ap_detail_info_s *info)
+{
+    RLOGD("[wifi] ---ernter lynq_wifi_get_sta_available_ap");
+    scan_info_s *scan_list = NULL;
+    saved_ap_info_s *save_list = NULL;
+    int scan_len=0;
+    int save_len=0;
+    int best_index = -1;
+    int best_scan_index = -1;
+    int best_rssi = 0;
+    int i, j, ret;
+
+    ret = -1;
+
+    CHECK_IDX(idx, CTRL_STA);
+    if (info == NULL)
+    {
+        return -1;
+    }
+
+    curr_status_info curr_state;
+    ap_info_s ap_info;
+    char status[64];
+
+    memset(&ap_info, 0, sizeof (ap_info));
+    memset(status, 0, sizeof (status));
+
+    curr_state.ap = &ap_info;
+    curr_state.state = status;
+
+    if (0 == inner_get_status_info(CTRL_STA, &curr_state) && curr_state.net_no >= 0)
+    {
+        memcpy(&info->base_info, &ap_info, sizeof (ap_info_s));
+        if (strcmp(status, STATE_COMPLETED) == 0)
+        {
+            info->status = LYNQ_WIFI_AP_STATUS_ENABLE;
+            RLOGD("[wifi] ---lynq_wifi_get_sta_available_ap status --> LYNQ_WIFI_AP_STATUS_ENABLE");
+        }
+        else
+        {
+            info->status = LYNQ_WIFI_AP_STATUS_DISABLE;
+            RLOGD("[wifi] ---lynq_wifi_get_sta_available_ap status --> LYNQ_WIFI_AP_STATUS_DISABLE");
+        }
+        lynq_get_connect_ap_ip(idx, info->base_info.ap_ip);
+        lynq_get_connect_ap_rssi(idx, &info->rssi);
+        lynq_sta_ssid_password_get(idx, & info->base_info, info->base_info.psw);
+        RLOGD("[wifi] ---ent --lynq_wifi_get_sta_available_ap");
+        return 0;
+    }
+
+    lynq_wifi_sta_start_scan(idx);
+    sleep(2);
+    if (0 != lynq_get_scan_list(0, &scan_list, &scan_len))
+    {
+        if (NULL != scan_list)
+        {
+            free(scan_list);
+        }
+        return -1;
+    }
+
+    if (0 != lynq_get_sta_saved_ap(0, &save_list, &save_len))
+    {
+        if (NULL != scan_list)
+        {
+            free(scan_list);
+        }
+        if (NULL != save_list)
+        {
+            free(save_list);
+        }
+        return -1;
+    }
+
+    for (i=0; i < save_len; i++)
+    {
+        for (j=0; j < scan_len; j++)
+	{
+            if (strcmp(save_list[i].base_info.ap_ssid, scan_list[j].ssid) == 0 //@todo not finished
+                    && save_list[i].base_info.auth == scan_list[j].auth)
+	    {
+                if (best_rssi == 0)
+		{
+                    best_index = i;
+                    best_rssi = scan_list[j].rssi;
+                }
+                else if (best_rssi > scan_list[j].rssi)
+		{
+                    best_index = i;
+                    best_scan_index = j;
+                    best_rssi = scan_list[j].rssi;
+                }
+                strncpy(save_list[i].base_info.ap_mac, scan_list[j].mac, sizeof (save_list[i].base_info.ap_mac));
+                break;
+            }
+        }
+    }
+
+    if (best_index >= 0)
+    {
+        memcpy(&info->base_info, &save_list[best_index].base_info, sizeof (ap_info_s));
+        inner_get_ip_by_mac( info->base_info.ap_mac, info->base_info.ap_ip, sizeof (info->base_info.ap_ip));
+        info->status = LYNQ_WIFI_AP_STATUS_DISABLE;
+        RLOGD("[wifi] ---lynq_wifi_get_sta_available_ap status ---> LYNQ_WIFI_AP_STATUS_ENABLE");
+        info->rssi = best_rssi;
+        ret = 0;
+    }
+
+    if (NULL != scan_list)
+    {
+        free(scan_list);
+    }
+    if (NULL != save_list)
+    {
+        free(save_list);
+    }
+
+    RLOGD("[wifi] ---end -lynq_wifi_get_sta_available_ap");
+    return ret;
+}
+
+static int inner_set_sta_auth_psw(int net_no, lynq_wifi_auth_s auth, char *password)
+{
+    char lynq_auth_cmd[128]={0};
+    char lynq_ket_mgmt_cmd[64]={0};
+    char lynq_pairwise_cmd[64]={0};
+    char lynq_psk_cmd[64]={0};
+
+    CHECK_WPA_CTRL(CTRL_STA);
+
+    switch(auth)
+    {
+        case LYNQ_WIFI_AUTH_OPEN:
+        {
+            sprintf(lynq_auth_cmd,"SET_NETWORK %d key_mgmt NONE", net_no);
+
+            DO_OK_FAIL_REQUEST(lynq_auth_cmd);
+//          DO_OK_FAIL_REQUEST(cmd_save_config);
+            break;
+        }
+        case LYNQ_WIFI_AUTH_WPA_PSK:
+        case LYNQ_WIFI_AUTH_WPA2_PSK:
+	{
+            if (auth == LYNQ_WIFI_AUTH_WPA_PSK)
+	    {
+                sprintf(lynq_auth_cmd,"SET_NETWORK %d proto WPA", net_no);
+            }
+            else if (auth == LYNQ_WIFI_AUTH_WPA2_PSK)
+	    {
+                sprintf(lynq_auth_cmd,"SET_NETWORK %d proto RSN", net_no);
+            }
+            sprintf(lynq_ket_mgmt_cmd,"SET_NETWORK %d key_mgmt WPA-PSK", net_no);
+            sprintf(lynq_pairwise_cmd,"SET_NETWORK %d pairwise CCMP", net_no);
+
+            DO_OK_FAIL_REQUEST(lynq_auth_cmd);
+            DO_OK_FAIL_REQUEST(lynq_ket_mgmt_cmd);
+            DO_OK_FAIL_REQUEST(lynq_pairwise_cmd);
+
+            if (password != NULL)
+	    {
+                sprintf(lynq_psk_cmd, "SET_NETWORK %d psk \"%s\"", net_no, password);
+                DO_OK_FAIL_REQUEST(lynq_psk_cmd);
+                sprintf(lynq_pairwise_cmd,"SET_NETWORK %d pairwise CCMP", net_no);
+            }
+
+//            DO_OK_FAIL_REQUEST(cmd_save_config);
+            break;
+        }	
+	case LYNQ_WIFI_AUTH_WPA2_WPA3_PSK:
+	{
+            sprintf(lynq_auth_cmd,"SET_NETWORK %d ieee80211w 1",net_no);
+            sprintf(lynq_ket_mgmt_cmd,"SET_NETWORK %d key_mgmt SAE WPA-PSK",net_no);
+            sprintf(lynq_pairwise_cmd,"SET_NETWORK %d pairwise CCMP", net_no);
+            sprintf(lynq_psk_cmd, "SET_NETWORK %d psk \"%s\"", net_no, password);
+            
+	    DO_OK_FAIL_REQUEST(lynq_auth_cmd);
+            DO_OK_FAIL_REQUEST(lynq_ket_mgmt_cmd);
+            DO_OK_FAIL_REQUEST(lynq_pairwise_cmd);
+            DO_OK_FAIL_REQUEST(lynq_psk_cmd);
+
+	    break;
+	}
+	case LYNQ_WIFI_AUTH_WPA3_PSK:
+	{
+            sprintf(lynq_auth_cmd,"SET_NETWORK %d ieee80211w 2",net_no);
+            sprintf(lynq_ket_mgmt_cmd,"SET_NETWORK %d key_mgmt SAE",net_no);
+            sprintf(lynq_pairwise_cmd,"SET_NETWORK %d pairwise CCMP", net_no);
+            sprintf(lynq_psk_cmd, "SET_NETWORK %d psk \"%s\"", net_no, password);
+            
+            DO_OK_FAIL_REQUEST(lynq_auth_cmd);
+            DO_OK_FAIL_REQUEST(lynq_ket_mgmt_cmd);
+            DO_OK_FAIL_REQUEST(lynq_pairwise_cmd);
+            DO_OK_FAIL_REQUEST(lynq_psk_cmd);
+
+	    break;
+	}
+	default:
+            return -1;
+    }
+
+    return 0;
+}
+
+static int inner_get_curr_net_no(int interface) {
+    curr_status_info curr_state;
+    curr_state.ap = NULL;
+    curr_state.state = NULL;
+
+    if (0 != inner_get_status_info(interface, &curr_state))
+    {
+        return -1;
+    }
+
+    return curr_state.net_no;
+}
+
+int lynq_wifi_get_sta_auth(lynq_wifi_index_e idx, lynq_wifi_auth_s *auth)
+{
+    int net_no;
+    CHECK_IDX(idx, CTRL_STA);
+
+    net_no = inner_get_curr_net_no(CTRL_STA);
+
+    if (net_no < 0)
+    {
+        return -1;
+    }
+
+    return inner_get_network_auth(CTRL_STA, net_no, auth);
+}
+
+int lynq_wifi_sta_connect_timeout(lynq_wifi_index_e idx, char *ssid, lynq_wifi_auth_s auth, char *psw, int timeout)
+{
+    int count, net_no, index;
+    int net_no_list[128];
+    char rm_net_cmd[128];
+    lynq_wifi_auth_s net_auth;
+    curr_status_info curr_state;
+    ap_info_s ap_info;
+    char status[64];
+
+    if (ssid == NULL || *ssid == '\0')
+    {
+        RLOGE("bad ssid\n");
+        return -1;
+    }
+
+    if (LYNQ_WIFI_AUTH_OPEN != auth)
+    {
+        if (psw == NULL || strlen(psw) < 8 || strlen(psw) >= 64)
+        {
+            RLOGE("bad password\n");
+            return -1;
+        }
+    }
+
+
+    pthread_mutex_lock(&s_global_check_mutex);
+    if (s_sta_status != INNER_STA_STATUS_INIT)
+    {
+        s_sta_status = INNER_STA_STATUS_CANCEL;
+        pthread_cond_signal(&s_global_check_cond);
+    }
+    pthread_mutex_unlock(&s_global_check_mutex);
+
+    CHECK_IDX(idx, CTRL_STA);
+    CHECK_WPA_CTRL(CTRL_STA);
+
+    net_no = -1;
+    memset(&ap_info, 0, sizeof (ap_info));
+    memset(status, 0, sizeof (status));
+
+    curr_state.ap = &ap_info;
+    curr_state.state = status;
+
+    if (0 == inner_get_status_info(CTRL_STA, &curr_state) && curr_state.net_no >= 0)
+    {
+        if (strcmp(status, STATE_COMPLETED) == 0 && strcmp(ap_info.ap_ssid, ssid) ==0 && ap_info.auth == auth)
+        {
+            net_no = curr_state.net_no;
+            if (0 == lynq_sta_ssid_password_get(idx, &ap_info, ap_info.psw)
+                    && strcmp(ap_info.psw, psw) == 0)
+            {
+                RLOGD("already connected\n");
+
+                pthread_mutex_lock(&s_global_check_mutex);
+                s_sta_status = INNER_STA_STATUS_CONNECTED;
+                lynq_sta_removeElement(net_no);
+                pthread_cond_signal(&s_global_check_cond);
+                pthread_mutex_unlock(&s_global_check_mutex);
+                return 0;
+            }
+        }
+    }
+
+    if (net_no == -1)
+    {
+        count = lynq_get_network_number_list(idx, CTRL_STA, net_no_list, ssid);
+
+        for (index=0; index < count; index++)
+        {
+            net_auth = -1;
+            if (0 == inner_get_network_auth(CTRL_STA, net_no_list[index], &net_auth) && net_auth == auth)
+            {
+                net_no = net_no_list[index];
+                break;
+            }
+        }
+
+        if (net_no < 0)
+        {
+            count = lynq_get_network_number_list(idx, CTRL_STA, net_no_list, NULL);
+            for ( index = 0; index < (count - STA_MAX_SAVED_AP_NUM + 1 ) ;index++)       //+1 is for add new network
+            {
+                sprintf(rm_net_cmd,"REMOVE_NETWORK %d",net_no_list[index]);
+                RLOGD("call cmd rm_net_cmd: %s;index is %d\n",rm_net_cmd,index);
+                DO_OK_FAIL_REQUEST(rm_net_cmd);
+            }
+            net_no = lynq_add_network(CTRL_STA);
+            if (net_no == -1)
+            {
+                return -1;
+            }
+
+            RLOGD("net no is %d\n", net_no);
+            if (0 != inner_set_sta_ssid(net_no, ssid))
+            {
+                return -1;
+            }
+        }
+    }
+
+    if (0 != inner_set_sta_auth_psw(net_no, auth, psw))
+    {
+        return -1;
+    }
+
+
+    DO_OK_FAIL_REQUEST(cmd_disconnect);
+    system("echo \"\" > /tmp/wlan0_dhcpcd_router");
+    usleep(200*1000);
+
+    pthread_mutex_lock(&s_global_check_mutex);
+    lynq_sta_removeElement(net_no);
+    pthread_mutex_unlock(&s_global_check_mutex);
+
+    ret = inner_sta_start_stop(net_no, 1, 1);
+
+    pthread_mutex_lock(&s_global_check_mutex);
+    s_sta_status = INNER_STA_STATUS_CONNECTING;
+    g_sta_conncet_status_flag = 1;
+    strcpy(s_sta_current_connecting_ssid, ssid);
+    struct timeval now;
+    gettimeofday(&now,NULL);
+    s_sta_connect_timeout.tv_sec = now.tv_sec + timeout;
+    s_sta_connect_timeout.tv_nsec = now.tv_usec*1000;
+    pthread_cond_signal(&s_global_check_cond);
+    pthread_mutex_unlock(&s_global_check_mutex);
+    return ret;
+}
+
+int lynq_wifi_sta_connect(lynq_wifi_index_e idx, char *ssid, lynq_wifi_auth_s auth, char *psw)
+{
+    return lynq_wifi_sta_connect_timeout(idx, ssid, auth, psw, MAX_CONNNECT_TIME);
+}
+
+int lynq_wifi_sta_disconnect(lynq_wifi_index_e idx, char *ssid)
+{
+    ap_info_s ap;
+    curr_status_info curr_state;
+    ap.ap_ssid[0] = '\0';
+
+    if (ssid == NULL || *ssid == '\0')
+    {
+        RLOGE("input ssid is NULL\n");
+        return -1;
+    }
+
+    CHECK_IDX(idx, CTRL_STA);
+
+    curr_state.ap = &ap;
+    curr_state.state = NULL;
+
+    if (inner_get_status_info(CTRL_STA, &curr_state) != 0)
+    {
+        return 0;
+    }
+
+    if (strcmp(ap.ap_ssid, ssid) != 0)
+    {
+        return 0;
+    }
+
+    pthread_mutex_lock(&s_global_check_mutex);
+    s_sta_status = INNER_STA_STATUS_DISCONNECTING;
+    pthread_mutex_unlock(&s_global_check_mutex);
+    return inner_sta_start_stop(curr_state.net_no, 0, 0);
+}
+
+int lynq_wifi_sta_disconnect_ap(lynq_wifi_index_e idx, char *ssid)
+{
+    int i,check_history_idx_flag;
+    ap_info_s ap;
+    curr_status_info curr_state;
+    ap.ap_ssid[0] = '\0';
+    check_history_idx_flag = 0;
+
+    if (ssid == NULL || *ssid == '\0')
+    {
+        RLOGE("input ssid is NULL\n");
+        return -1;
+    }
+
+    CHECK_IDX(idx, CTRL_STA);
+
+
+    curr_state.ap = &ap;
+    curr_state.state = NULL;
+
+    if (inner_get_status_info(CTRL_STA, &curr_state) != 0)
+    {
+        return 0;
+    }
+
+    if (strcmp(ap.ap_ssid, ssid) != 0)
+    {
+        return 0;
+    }
+
+    pthread_mutex_lock(&s_global_check_mutex);
+    s_sta_status = INNER_STA_STATUS_DISCONNECTING;
+    RLOGD("WIFI[lynq_wifi_sta_disconnect_ap]g_history_disconnect_valid_num is %d",g_history_disconnect_valid_num);
+    for( i = 0; i< g_history_disconnect_valid_num ; i++)
+    {
+        RLOGD("WIFI[lynq_wifi_sta_disconnect_ap]g_history_disconnect_net[%d] is %d,current disconnet network is %d",i,g_history_disconnect_net[i],curr_state.net_no);
+        if( g_history_disconnect_net[i] == curr_state.net_no)
+        {
+            RLOGD("current disconenct ap idx is %d && last aready into g_history_disconenct_net",curr_state.net_no);
+            check_history_idx_flag = 1;
+            break;
+        }
+    }
+    if ( check_history_idx_flag == 0)
+    {
+        RLOGD("current need add ap idx is %d ,g_history_disconnect_valid_num is %d line %d",curr_state.net_no,g_history_disconnect_valid_num,__LINE__);
+        g_history_disconnect_net[g_history_disconnect_valid_num] = curr_state.net_no;
+        g_history_disconnect_valid_num++;
+    }
+    RLOGD("%s %d",__func__,__LINE__);
+    print_disconnect_list();
+    pthread_mutex_unlock(&s_global_check_mutex);
+    return lynq_wifi_sta_stop_network(idx, curr_state.net_no);
+
+}
+
+
+int lynq_wifi_sta_start(lynq_wifi_index_e idx)
+{
+    RLOGD("enter %s %d func",__func__,__LINE__);
+    const char *lynq_enable_sta_cmd = "wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=wlan0 enable_net all";
+    const char *lynq_reconnect_cmd = "wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=wlan0 reconnect";
+
+    CHECK_IDX(idx, CTRL_STA);
+    CHECK_WPA_CTRL(CTRL_STA);
+
+    ret = system_call_v("%s %s", start_stop_sta_script, "start");
+    if (ret != 0)
+    {
+        RLOGE("lynq_wifi_sta_start excute script fail %s %d",__func__,__LINE__);
+        return -1;
+    }
+
+    system(lynq_enable_sta_cmd);
+    system(lynq_reconnect_cmd);
+    pthread_mutex_lock(&s_global_check_mutex);
+    g_history_disconnect_valid_num = 0;   //clean history_disconenct_list info
+    s_sta_status = INNER_STA_STATUS_INIT;
+    pthread_mutex_unlock(&s_global_check_mutex);
+    RLOGD("end %s %d func",__func__,__LINE__);
+    return 0;
+}
+
+static int inner_get_status_info_state (int interface, char *state) {
+    curr_status_info curr_state;
+    curr_state.ap = NULL;
+    curr_state.state = state;
+    return inner_get_status_info(interface, &curr_state);
+}
+
+int lynq_wifi_sta_start_auto(lynq_wifi_index_e idx)
+{
+
+    RLOGD("[wifi]enter lynq_wifi_sta_start_auto start");
+    int tmp_open_idx[128];
+    int len;
+
+    pthread_mutex_lock(&s_global_check_mutex);
+    s_sta_status = INNER_STA_STATUS_INIT;
+    lynq_two_arr_merge(g_history_disconnect_net,g_history_disconnect_valid_num,tmp_open_idx,&len);
+    pthread_mutex_unlock(&s_global_check_mutex);
+    if(lynq_tmp_enable_network(idx,tmp_open_idx,len) != 0 )
+    {
+        RLOGD("[wifi]lynq_tmp_enable_network error");
+    }
+
+    RLOGD("[wifi]enter lynq_wifi_sta_start_auto end");
+    return 0;
+}
+
+
+int lynq_wifi_sta_stop(lynq_wifi_index_e idx)
+{
+    RLOGD("enter %s %d",__func__,__LINE__);
+    int i=0;
+    char state[MAX_CMD];
+
+    CHECK_IDX(idx, CTRL_STA);
+    CHECK_WPA_CTRL(CTRL_STA);
+
+    DO_OK_FAIL_REQUEST(cmd_disconnect);
+    DO_OK_FAIL_REQUEST(cmd_save_config);
+
+    ret = system_call_v("%s %s", start_stop_sta_script, "stop");
+    if (ret != 0)
+    {
+        RLOGE("lynq_wifi_sta_stop excute script fail %s %d",__func__,__LINE__);
+        return -1;
+    }
+
+    for (i=0; i < 30; i++) // to check if sta is realy stoped
+    {
+        if (inner_get_status_info_state(idx, state) != 0)
+        {
+            break;
+        }
+
+        if (memcmp(state, STATE_DISCONNECTED, strlen (STATE_DISCONNECTED)) == 0)
+        {
+            break;
+        }
+        RLOGD("lynq_wifi_sta_stop curr state %s %s %d", state,__func__,__LINE__);
+        usleep(SLEEP_TIME_ON_IDLE);
+    }
+    pthread_mutex_lock(&s_global_check_mutex);
+    g_history_disconnect_valid_num = 0;   //clean history_disconenct_list info
+    pthread_mutex_unlock(&s_global_check_mutex);
+    RLOGD("end %s %d",__func__,__LINE__);
+    return 0;
+//    return system("connmanctl disable wifi");
+}
+int lynq_wifi_sta_stop_net(lynq_wifi_index_e idx,int networkid)
+{
+    char LYNQ_DISABLE_CMD[128]={0};
+    CHECK_IDX(idx, CTRL_STA);
+    CHECK_WPA_CTRL(CTRL_STA);
+    sprintf(LYNQ_DISABLE_CMD,"DISABLE_NETWORK %d",networkid);
+    RLOGD("LYNQ_DISABLE_CMD is:%d\n",LYNQ_DISABLE_CMD);
+    DO_OK_FAIL_REQUEST(LYNQ_DISABLE_CMD);
+    return 0;
+}
+
+//static int inner_get_sta_info(lynq_wifi_index_e idx, const char * bssid, device_info_s *dev) {
+//    int i, count;
+//    char *p;
+//    const char * FLAG_SSID = "ssid=";
+//    const char * FLAG_SBSID = "bssid=";
+//    const char * FLAG_KEY_MGMT = "key_mgmt=";
+//    const char * FLAG_FREQ = "freq=";
+//    char lynq_sta_cmd[MAX_CMD];
+//    char *split_lines[128] = {0};
+
+//    CHECK_WPA_CTRL(CTRL_AP);
+
+//    sprintf(lynq_sta_cmd, "STA %s", bssid);
+
+//    DO_REQUEST(lynq_sta_cmd);
+
+//    count = lynq_split(cmd_reply, reply_len, '\n', split_lines);
+
+//    for(i=0; i < count; i++) {
+//        p = strstr(split_lines[i], FLAG_SSID);
+//        if (p != NULL) {
+//            strcpy(ap->ap_ssid, p + strlen(FLAG_SSID));
+//            continue;
+//        }
+//    }
+
+//    lynq_get_interface_ip(idx, ap->ap_ip);
+//    lynq_ap_password_set(idx, ap->psw);
+
+//    return 0;
+//}
+
+static int inner_get_status_info_ap (int interface, ap_info_s *ap) {
+    curr_status_info curr_state;
+    curr_state.ap = ap;
+    curr_state.state = NULL;
+    return inner_get_status_info(interface, &curr_state);
+}
+
+int lynq_get_ap_device_list(lynq_wifi_index_e idx, ap_info_s **ap, device_info_s ** list,int * len)
+{
+    RLOGD("[wifi]-----enter lynq_get_ap_device_list");
+    int index, line_count;
+    device_info_s *dev_info;
+    const char *lynq_first_sta_cmd = "STA-FIRST";
+    char lynq_next_sta_cmd[MAX_CMD];
+    char *bssid[1024] = {0};
+    char *split_lines[128] = {0};
+
+    CHECK_IDX(idx, CTRL_AP);
+
+    CHECK_WPA_CTRL(CTRL_AP);
+
+    //    ap_info_s * tmp_ap;
+    //    device_info_s * tmp_list;
+    if (ap == NULL || list == NULL || len == NULL)
+    {
+        RLOGE("bad input param");
+        return -1;
+    }
+
+    //    ap = &tmp_ap;
+    //    list = &tmp_list;
+    *ap = malloc(sizeof (ap_info_s));
+    memset(*ap, 0, sizeof (ap_info_s));
+
+    if (inner_get_status_info_ap (CTRL_AP, *ap) != 0 || (*ap)->ap_ssid[0] == '\0')
+    {
+        RLOGE("inner_get_status_info_ap !=0 or ap_ssid is empty\n");
+        return -1;
+    }
+
+    lynq_get_interface_ip(idx, (*ap)->ap_ip);
+    lynq_ap_password_get(idx, (*ap)->psw);
+
+    DO_REQUEST(lynq_first_sta_cmd);
+
+    index = 0;
+    while (reply_len > 0)
+    {
+        if (memcmp(cmd_reply, "FAIL", 4) == 0)
+        {
+            break;
+        }
+        line_count = lynq_split(cmd_reply, reply_len, '\n', split_lines);
+        bssid[index] = malloc(strlen(split_lines[0]) + 1);
+        strcpy(bssid[index], split_lines[0]);
+        index++;
+        sprintf(lynq_next_sta_cmd, "STA-NEXT %s", split_lines[0]);
+        reply_len = MAX_RET;
+        cmd_reply[0] = '\0';
+        ret = local_wpa_ctrl_request(lynq_wpa_ctrl, lynq_next_sta_cmd, strlen(lynq_next_sta_cmd), cmd_reply, &reply_len, NULL);
+        if (ret != 0 || memcmp(cmd_reply, "FAIL", 4) == 0)
+        {
+            RLOGD("run %s fail \n", lynq_next_sta_cmd);
+            break;
+        }
+    }
+
+    *len = index;
+
+    *list = malloc(sizeof(device_info_s) * (*len));
+    for (index=0; index < *len; index++)
+    {
+        dev_info = &(*list)[index];
+        memset(dev_info, 0, sizeof(device_info_s));
+        strncpy(dev_info->sta_mac, bssid[index], sizeof (dev_info->sta_mac));
+        inner_get_ip_by_mac(dev_info->sta_mac, dev_info->sta_ip, sizeof (dev_info->sta_ip));
+        inner_get_hostname_by_ip(dev_info->sta_ip, dev_info->hostname);
+        dev_info->status = LYNQ_WIFI_STATUS_CONNECT;
+        free(bssid[index]);
+    }
+    RLOGD("[wifi]-----end lynq_get_ap_device_list");
+    return 0;
+}
+
+int lynq_get_scan_list(lynq_wifi_index_e idx, scan_info_s ** list,int * len)
+{
+    int i, count, index, count_words;
+    const char *lynq_scan_result_cmd = "SCAN_RESULTS";
+    char *split_lines[128] = {0};
+    char *split_words[128] = {0};
+    scan_info_s * p;
+
+    if (list == NULL || len == NULL)
+    {
+        return -1;
+    }
+
+    for (i =0; i < 50 && g_sta_scan_finish_flag == 0; i++)
+    {
+        usleep(100 * 1000);
+    }
+
+    CHECK_IDX(idx, CTRL_STA);
+
+    CHECK_WPA_CTRL(CTRL_STA);
+
+    DO_REQUEST(lynq_scan_result_cmd);
+
+    count = lynq_split(cmd_reply, reply_len, '\n', split_lines);
+    *len = count - 1;
+    *list = malloc(sizeof (scan_info_s) * *len);
+
+    count_words = lynq_split(split_lines[0], strlen(split_lines[0]), '/', split_words); //@todo get with header
+    for (index=0; index <count_words; index++)
+    {
+        RLOGD("----header: %s\n", split_words[index]);
+    }
+
+    for(index = 1;index < count; index++)
+    {
+        RLOGD("---- %s\n",split_lines[index]);
+        memset(split_words, 0 , sizeof (split_words));
+        count_words = lynq_split(split_lines[index], strlen(split_lines[index]), '\t', split_words);
+        if (count_words < 4)
+            continue;
+        RLOGD("count: %d, %s\n", count_words, split_words[0]);
+        //bssid / frequency / signal level / flags / ssid
+        p = (*list) + index - 1;
+        strcpy(p->mac, split_words[0]);
+        p->band = convert_band_from_freq(atoi(split_words[1]));
+        p->rssi = -1 * atoi( split_words[2]);
+        p->auth = convert_max_auth_from_flag(split_words[3]);
+        if (count_words == 4) // ssid hided
+        {
+            p->ssid[0] = '\0';
+        }
+        else
+        {
+            inner_copy_ssid(p->ssid, split_words[4], sizeof (p->ssid));
+        }
+    }
+
+    return 0;
+}
+
+int lynq_sta_forget_ap(lynq_wifi_index_e idx, char *ssid, lynq_wifi_auth_s auth)
+{
+    int count, net_no, index;
+    int net_no_list[128];
+    lynq_wifi_auth_s net_auth;
+
+    char lynq_remove_cmd[MAX_CMD];
+
+    if (ssid == NULL || *ssid == '\0')
+    {
+        RLOGD("bad ssid\n");
+        return -1;
+    }
+
+    CHECK_IDX(idx, CTRL_STA);
+
+    CHECK_WPA_CTRL(CTRL_STA);
+
+    net_no = -1;
+    count = lynq_get_network_number_list(idx, CTRL_STA, net_no_list, ssid);
+
+    for (index=0; index < count; index++)
+    {
+        net_auth = -1;
+        if (0 == inner_get_network_auth(CTRL_STA, net_no_list[index], &net_auth) && net_auth == auth)
+	{
+            net_no = net_no_list[index];
+            break;
+        }
+    }
+
+    if (net_no < 0)
+    {
+        return 0;
+    }
+
+    sprintf(lynq_remove_cmd, "REMOVE_NETWORK %d", net_no);
+
+    DO_OK_FAIL_REQUEST(lynq_remove_cmd);
+
+    RLOGD("WIFI[lynq_sta_forget_ap][check_history_disconenct_ap_list] input net_no is %d",net_no);
+
+    pthread_mutex_lock(&s_global_check_mutex);
+    lynq_sta_removeElement(net_no);
+    pthread_mutex_unlock(&s_global_check_mutex);
+
+    RLOGD("%s %d",__func__,__LINE__);
+    print_disconnect_list();
+    DO_OK_FAIL_REQUEST(cmd_save_config);
+
+    return 0;
+}
+
+int lynq_get_sta_saved_ap(lynq_wifi_index_e idx, saved_ap_info_s ** list, int * len)
+{
+    int count, index;
+    int net_no_list[128];
+    char freq[16];
+    RLOGD("enter lynq_get_sta_saved_ap api\n");
+    if (list == NULL || len == NULL)
+    {
+        RLOGE("bad param,please check!");
+        return -1;
+    }
+
+    CHECK_IDX(idx, CTRL_STA);
+
+//    CHECK_WPA_CTRL(CTRL_STA);
+
+    count = lynq_get_network_number_list(idx, CTRL_STA, net_no_list, NULL);
+    RLOGD("[lynq_get_sta_saved_ap]count is %d\n", count);
+
+    if (count < 0)
+    {
+        RLOGE("list network fail");
+        return count;
+    }
+    else if (count == 0)
+    {
+        *list = NULL;
+        *len = 0;
+        return 0;
+    }
+
+    *list = malloc(sizeof (saved_ap_info_s) * count);
+    memset(*list, 0, sizeof (saved_ap_info_s) * count);
+    *len = count;
+
+    for (index=0; index < count; index++)
+    {
+        inner_get_param(CTRL_STA, net_no_list[index], "ssid", (*list)[index].base_info.ap_ssid);
+        inner_get_param(CTRL_STA, net_no_list[index], "bssid", (*list)[index].base_info.ap_mac);
+        inner_get_network_auth(CTRL_STA, net_no_list[index], &(*list)[index].base_info.auth);
+        if (inner_get_param(CTRL_STA, net_no_list[index], "frequency", freq) == 0)
+        {
+            (*list)[index].base_info.band = convert_band_from_freq(atoi(freq));
+        }
+        else
+        {
+            (*list)[index].base_info.band = -1;
+        }
+        RLOGD("[lynq_get_sta_saved_ap][inner_get_param]to get psw");
+        lynq_sta_ssid_password_get(idx, & (*list)[index].base_info, (*list)[index].base_info.psw);
+    }
+    RLOGD("[lynq_get_sta_saved_ap] return ok");
+    return 0;
+}
+
+int lynq_wifi_sta_start_scan(lynq_wifi_index_e idx)
+{
+    if ( s_sta_status == INNER_STA_STATUS_INIT && g_sta_conncet_status_flag != 0 )
+    {
+        RLOGD("current sta is autoconnecting dest ap,fake scan result");
+        g_sta_fake_scan_finish_flag = 1;
+        return 0;
+    }
+    else if (g_sta_conncet_status_flag != 0)
+    {
+        RLOGD("current sta is connecting dest ap, don't scan");
+        return 1;
+    }
+
+    const char *clean_last_re ="wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=wlan0 bss_flush";
+    const char *lynq_scan_cmd = "SCAN";
+
+    CHECK_IDX(idx, CTRL_STA);
+
+    CHECK_WPA_CTRL(CTRL_STA);
+
+    if (g_sta_scan_finish_flag == 1 && s_sta_status == INNER_STA_STATUS_INIT) // temp add
+    {
+        RLOGD("tmp clear scanlist");
+        system(clean_last_re);
+    }
+    g_sta_scan_finish_flag = 0;
+    DO_REQUEST(lynq_scan_cmd);
+    if (reply_len >=9 && memcmp(cmd_reply, "FAIL-BUSY", 9) == 0 )
+    {
+        return 0;
+    } else if (reply_len >=2 && memcmp(cmd_reply, "OK", 2) != 0)
+    {
+        g_sta_scan_finish_flag = 1;
+        return -1;
+    }
+
+    return 0;
+}
+
+int lynq_reg_ap_event_callback(void * priv, AP_CALLBACK_FUNC_PTR cb) {
+    if (cb == NULL) 
+    {
+        RLOGE("lynq_reg_ap_event_callback ptr is NULL,plese check!\n");
+        return -1;
+    }
+
+    pthread_mutex_lock(&s_ap_callback_mutex);
+    g_ap_callback_priv = priv;
+    g_ap_callback_func = cb;
+    pthread_mutex_unlock(&s_ap_callback_mutex);
+
+    pthread_mutex_lock(&s_check_wpa_ctrl_mutex);
+    if (g_ap_watcher_pid == 0 )
+    {
+        if(pthread_create(&g_ap_watcher_pid,NULL,APWatcherThreadProc,NULL) < 0)
+        {
+            g_ap_watcher_pid = 0;
+            pthread_mutex_unlock(&s_check_wpa_ctrl_mutex);
+            RLOGE("[wifi error]creat APWatcherThreadProc fail");
+            return -1;
+        }
+    }
+
+    pthread_mutex_unlock(&s_check_wpa_ctrl_mutex);
+    RLOGD("creat APWatcherTheradProc succeed");
+
+    return 0;
+}
+
+int lynq_unreg_ap_event_callback(void * priv) {
+    RLOGD("enter %s %d",__func__,__LINE__);
+    pthread_mutex_lock(&s_ap_callback_mutex);
+    if (g_ap_callback_priv == priv)
+    {
+        g_ap_callback_func = NULL;
+        g_ap_callback_priv = NULL;
+        pthread_mutex_unlock(&s_ap_callback_mutex);
+	RLOGD("unreg ap callback pass %s %d",__func__,__LINE__);
+        return 0;
+    }
+    pthread_mutex_unlock(&s_ap_callback_mutex);
+    RLOGE("unreg ap callback fail %s %d",__func__,__LINE__);
+    return -1;
+}
+
+int lynq_reg_sta_event_callback(void * priv, STA_CALLBACK_FUNC_PTR cb){
+    if (cb == NULL) 
+    {
+        RLOGE("lynq_reg_sta_event_callback ptr is NULL,plese check!\n");
+        return -1;
+    }
+
+    pthread_mutex_lock(&s_sta_callback_mutex);
+    g_sta_callback_priv = priv;
+    g_sta_callback_func = cb;
+    pthread_mutex_unlock(&s_sta_callback_mutex);
+
+    pthread_mutex_lock(&s_check_wpa_ctrl_mutex);
+    if (g_sta_watcher_pid == 0 ) {
+        if(pthread_create(&g_sta_watcher_pid,NULL,STAWatcherThreadProc,NULL) < 0)
+        {
+            g_sta_watcher_pid = 0;
+            pthread_mutex_unlock(&s_check_wpa_ctrl_mutex);
+            RLOGE("[wifi error]creat STAWatcherThreadProc fail");
+            return -1;
+        }
+    }
+
+    pthread_mutex_unlock(&s_check_wpa_ctrl_mutex);
+    RLOGD("creat STAWatcherTheradProc succeed");
+    return 0;
+}
+
+int lynq_unreg_sta_event_callback(void * priv) {
+    RLOGD("enter %s %d",__func__,__LINE__);
+    pthread_mutex_lock(&s_sta_callback_mutex);
+    if (g_sta_callback_priv == priv)
+    {
+        g_sta_callback_func = NULL;
+        g_sta_callback_priv = NULL;
+        pthread_mutex_unlock(&s_sta_callback_mutex);
+        RLOGD("unreg sta callback pass  %s %d",__func__,__LINE__);
+        return 0;
+    }
+    pthread_mutex_unlock(&s_sta_callback_mutex);
+    RLOGE("unreg sta callback fail  %s %d",__func__,__LINE__);
+    return -1;
+}
+
+int lynq_reg_sta_auto_event_callback(void * priv, STA_AUTO_CALLBACK_FUNC_PTR cb){
+    if (cb == NULL) 
+    {
+        RLOGE("lynq_reg_sta_auto_event_callback ptr is NULL,plese check!\n");
+        return -1;
+    }
+    pthread_mutex_lock(&s_sta_auto_callback_mutex);
+    g_sta_auto_callback_priv = priv;
+    g_sta_auto_callback_func = cb;
+    pthread_mutex_unlock(&s_sta_auto_callback_mutex);
+    pthread_mutex_lock(&s_check_wpa_ctrl_mutex);
+    if (g_sta_auto_watcher_pid == 0 ) {
+        if(pthread_create(&g_sta_auto_watcher_pid,NULL,STAAutoWatcherThreadProc,NULL) < 0)  //create STAAutoWatcherThreadProc
+        {
+            g_sta_auto_watcher_pid = 0;
+            pthread_mutex_unlock(&s_check_wpa_ctrl_mutex);
+            RLOGE("[wifi error]creat STAWatcherThreadProc fail");
+            return -1;
+        }
+    }
+    pthread_mutex_unlock(&s_check_wpa_ctrl_mutex);
+    RLOGD("creat STAWatcherTheradProc succeed");
+    return 0;
+}
+int lynq_unreg_sta_auto_event_callback(void * priv) {
+    pthread_mutex_lock(&s_sta_auto_callback_mutex);
+    if (g_sta_auto_callback_priv == priv)
+    {  
+        g_sta_auto_watcher_stop_flag = 1;
+        if (g_sta_auto_watcher_pid != 0)
+        {
+            pthread_join(g_sta_auto_watcher_pid, NULL);
+        }
+    g_sta_auto_watcher_pid = 0;
+        g_sta_auto_callback_func = NULL;
+        g_sta_auto_callback_priv = NULL;
+        pthread_mutex_unlock(&s_sta_auto_callback_mutex);
+        return 0;
+    }
+    pthread_mutex_unlock(&s_sta_auto_callback_mutex);
+    return -1;
+}
+int lynq_get_ap_status(lynq_wifi_index_e idx, lynq_wifi_ap_run_status_s * ap_status)
+{
+    char state[MAX_CMD];
+    RLOGD("enter lynq_get_ap_status\n");
+    CHECK_IDX(idx, CTRL_AP);
+
+    if (inner_get_status_info_state(CTRL_AP, state) != 0)
+    {
+        *ap_status = LYNQ_WIFI_AP_STATUS_DISABLE;
+        return 0;
+    }
+
+    if (memcmp(state, STATE_COMPLETED, strlen (STATE_COMPLETED)) == 0)
+    {
+        *ap_status = LYNQ_WIFI_AP_STATUS_ENABLE;
+    }
+    else
+    {
+        *ap_status = LYNQ_WIFI_AP_STATUS_DISABLE;
+    }
+
+    return 0;
+}
+
+int lynq_get_sta_status(lynq_wifi_index_e idx, lynq_wifi_sta_run_status_s * sta_status) {
+    char state[MAX_CMD];
+    RLOGD("enter lynq_get_sta_status\n");
+    CHECK_IDX(idx, CTRL_STA);
+
+    if (inner_get_status_info_state(CTRL_STA, state) != 0)
+    {
+        *sta_status = LYNQ_WIFI_STA_STATUS_DISABLE;
+        return 0;
+    }
+
+    if (memcmp(state, STATE_COMPLETED, strlen (STATE_COMPLETED)) == 0)
+    {
+        *sta_status = LYNQ_WIFI_STA_STATUS_ENABLE;
+    }
+    else
+    {
+        *sta_status = LYNQ_WIFI_STA_STATUS_DISABLE;
+    }
+
+    return 0;
+}
+
+int lynq_get_country_code(lynq_wifi_index_e idx, char * country_code) {
+//    CHECK_IDX(idx, CTRL_AP);
+//    int ret = 0;
+//    size_t reply_len = MAX_RET;
+//    char cmd_reply[MAX_RET]={0};
+//    const char * cmd_str = "GET country";
+//    struct wpa_ctrl *s_lynq_wpa_ctrl = NULL;
+//    do{
+//        if (NULL == s_lynq_wpa_ctrl) {
+//            s_lynq_wpa_ctrl = wpa_ctrl_open("/var/run/wpa_wlan0_cmd");
+//            if (NULL == s_lynq_wpa_ctrl ) {
+//                printf("wpa_ctrl_open fail\n");
+//                return -1;
+//            }
+//        }
+//    }while(0);
+
+//    do {
+//        reply_len = MAX_RET;
+//        cmd_reply[0] = '\0';
+//        printf("to call [%s]\n", cmd_str);
+//        ret = local_wpa_ctrl_request(s_lynq_wpa_ctrl, cmd_str, strlen(cmd_str), cmd_reply, &reply_len, NULL);
+//        if (ret != 0) {
+//            RLOGE("call ##cmd_str fail %d\n", ret);
+//            return ret;
+//        }
+//        cmd_reply[reply_len+1] = '\0';
+//        RLOGD("cmd replay [ %s ]\n", cmd_reply);
+//    }while(0);
+
+    FILE *fp;
+    size_t i = 0;
+    char lynq_cmd_ret[MAX_RET]={0};
+
+//    CHECK_IDX(idx, CTRL_AP);
+
+    if((fp=popen("wl country","r"))==NULL)
+    {
+        perror("popen error!");
+        return -1;
+    }
+    if((fread(lynq_cmd_ret,sizeof(lynq_cmd_ret),1,fp))<0)
+    {
+        perror("fread fail!");
+        return -1;
+    }
+
+    for(i=0; i < strlen(lynq_cmd_ret); i++)
+    {
+        if (lynq_cmd_ret[i] == ' ')
+	{
+            lynq_cmd_ret[i] = '\0';
+            break;
+        }
+    }
+
+    strcpy(country_code,lynq_cmd_ret);
+    RLOGD("---country code %s\n", country_code);
+
+    int ret=pclose(fp);
+    if(ret==-1)
+    {
+        perror("close file faild");
+    }
+
+    return 0;
+}
+
+
+static int check_and_init_uci_config(char * country_code)
+{
+    FILE * fp;
+    int is_different = 0;
+    const char * check_uci_cmd ="uci show | grep lynq_wifi_country_code";
+    const char * create_uci_cmd ="uci set lynq_uci.lynq_wifi_country_code='lynq_wifi_country_code'";
+    const char * commit_uci_cmd ="uci commit";
+    char set_country_cmd[MAX_CMD];
+    char lynq_cmd_ret[MAX_CMD]={0};
+
+    sprintf(set_country_cmd, "uci set lynq_uci.lynq_wifi_country_code.code='%s'",country_code);
+
+    if (0 != system(check_uci_cmd))
+    {
+        if (0 != system(create_uci_cmd))
+        {
+            RLOGE("creat_uci_cmd fail");
+            return -1;
+        }
+        is_different = 1;
+    }
+
+    if((fp=popen("uci get lynq_uci.lynq_wifi_country_code.code","r"))==NULL)
+    {
+        RLOGE("popen error!");
+        return -1;
+    }
+
+    if((fread(lynq_cmd_ret,sizeof(lynq_cmd_ret),1,fp))<0 )
+    {
+        RLOGE("fread fail!");
+        fclose(fp);
+        return -1;
+    }
+
+    if ( strncmp(lynq_cmd_ret,country_code,2) != 0 )
+    {
+	RLOGE("get country code for uci %s,input cpuntry code is:%s\n",lynq_cmd_ret,country_code);
+        is_different = 1;
+    }
+
+    fclose(fp);
+
+    if (is_different)
+    {
+        if ( 0 != system(set_country_cmd))
+        {
+            RLOGE("set_country_cmd fail");
+            return -1;
+        }
+        if (0 != system(commit_uci_cmd))
+        {
+            RLOGE("commmit fail");
+        }
+    }
+
+    return is_different;
+}
+
+int lynq_set_country_code(lynq_wifi_index_e idx, char * country_code) {
+    char check_current_code[10];
+    const char * support_country[] = {"CN", "EU"};
+
+    int ret,is_different, i, cc_count;
+
+    if (country_code == NULL || country_code[0] == '\0')
+    {
+        RLOGE("bad country code\n");
+        return -1;
+    }
+
+    cc_count = sizeof (support_country) / sizeof (char*);
+    for(i=0; i < cc_count; i++)
+    {
+        if (strcmp(support_country[i], country_code) == 0)
+        {
+            break;
+        }
+    }
+
+    if (i >= cc_count)
+    {
+        RLOGE("unspported country code %s\n", country_code);
+        return -1;
+    }
+
+    is_different = check_and_init_uci_config(country_code);
+    if( is_different < 0 )
+    {
+        RLOGE("init set uci fail\n");
+        return -1;
+    }
+
+    ret = lynq_get_country_code(idx,check_current_code);
+    if( ret == 0 && (is_different == 1 || strcmp(check_current_code, country_code) != 0))
+    {
+        ret = lynq_wifi_disable();
+        if(ret != 0 )
+        {
+            RLOGE("berfore set country,find bcmdhd insmod,remod fail\n");
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+int lynq_get_connect_ap_mac(lynq_wifi_index_e idx,char *mac)
+{
+    RLOGD("enter lynq_get_connect_ap_mac\n");
+    if (mac == NULL) 
+    {
+        RLOGE("input ptr is NULL,please check\n");
+        return -1;
+    }
+
+    CHECK_IDX(idx, CTRL_STA);
+    ap_info_s ap;
+    ap.ap_mac[0] = '\0';
+
+    if (inner_get_status_info_ap(CTRL_STA, &ap) != 0)
+    {
+        return -1;
+    }
+    strcpy(mac, ap.ap_mac);
+
+    return 0;
+}
+
+int lynq_get_interface_ip(lynq_wifi_index_e idx, char *ip)
+{
+    RLOGD("enter lynq_get_interface_ip\n");
+    struct ifaddrs *ifaddr_header, *ifaddr;
+    struct in_addr * ifa;
+    const char * ifaName = "wlan0";
+    if (ip == NULL)
+    {
+       RLOGE("[lynq_get_interface_ip]input erro,input is NULL ptr,please check\n");
+       return -1;
+    }
+
+    if (idx == 1)
+    {
+       ifaName = inner_get_ap_interface_name();
+       if (ifaName == NULL)
+       {
+           RLOGE("[lynq_get_interface_ip] ap name get fail");
+           return -1;
+       }
+    }
+    else if (idx != 0)
+    {
+       return -1;
+    }
+
+    if (getifaddrs(&ifaddr_header) == -1)
+    {
+       perror("getifaddrs");
+       return -1;
+       //exit(EXIT_FAILURE);
+    }
+
+
+    for (ifaddr = ifaddr_header; ifaddr != NULL; ifaddr = ifaddr->ifa_next)
+    {
+        if (ifaddr->ifa_addr == NULL)
+           continue;
+        if((strcmp(ifaddr->ifa_name,ifaName)==0))
+        {
+            if (ifaddr->ifa_addr->sa_family==AF_INET) // check it is IP4
+            {
+               // is a valid IP4 Address
+               ifa=&((struct sockaddr_in *)ifaddr->ifa_addr)->sin_addr;
+               inet_ntop(AF_INET, ifa, ip, INET_ADDRSTRLEN);
+               RLOGD("[lynq_get_interface_ip]:%s IP Address %s/n", ifaddr->ifa_name, ip);
+               freeifaddrs(ifaddr_header);
+               RLOGD("ip %s\n", ip);
+               return 0;
+            }
+        }
+    }
+    freeifaddrs(ifaddr_header);
+    RLOGE("[lynq_get_interface_ip] can't find interface | other erro\n");
+    return -1;
+}
+
+int lynq_get_interface_mac(lynq_wifi_index_e idx,char *mac)
+{
+    RLOGD("enter lynq_get_interface_mac\n");
+    int count;
+    size_t i;
+    int WIFI_INTERFACE_MAC_LEN = 17;
+    char *split_words[128] = {0};
+    const char *lynq_get_mac_cmd = "DRIVER MACADDR";
+
+    CHECK_WPA_CTRL(idx);
+
+    DO_REQUEST(lynq_get_mac_cmd);
+
+    if (memcmp(cmd_reply, "FAIL", 4) == 0)
+    {
+        RLOGE("[lynq_get_interface_mac]do request cmd --DRIVER MACADDR-- reply FAIL\n");
+        return -1;
+    }
+
+    count = lynq_split(cmd_reply, reply_len, '=', split_words);
+
+    if (count < 2)
+    {
+        return -1;
+    }
+
+    for (i=0; i < strlen(split_words[1]); i++ )
+    {
+        if (split_words[1][i] != ' ')
+	{
+            break;
+        }
+    }
+
+    strncpy(mac, split_words[1] + i, WIFI_INTERFACE_MAC_LEN);
+
+    return 0;
+}
+
+int lynq_get_connect_ap_rssi(lynq_wifi_index_e idx,int * rssi)
+{
+//    int count;
+//    char *split_words[128] = {0};
+//    const char *lynq_get_rssi_cmd = "DRIVER RSSI";
+
+//    if (rssi == NULL) {
+//        return -1;
+//    }
+
+//    CHECK_IDX(idx, CTRL_STA);
+
+//    CHECK_WPA_CTRL(CTRL_STA);
+
+//    DO_REQUEST(lynq_get_rssi_cmd);
+
+//    if (memcmp(cmd_reply, "FAIL", 4) == 0) {
+//        return -1;
+//    }
+
+//    count = lynq_split(cmd_reply, reply_len, ' ', split_words);
+
+//    if (count < 2) {
+//        return -1;
+//    }
+
+//    *rssi = atoi(split_words[1]) * -1;
+
+    char lynq_cmd_ret[MAX_RET]={0};
+
+/*******change other cmd to get rssi*******
+ *
+ *wl rssi ---> wl -i wlan0 rssi
+ *
+ ***** change by qs.xiong 20221011*******/
+    if (0 !=  exec_cmd("wl -i wlan0 rssi", lynq_cmd_ret, MAX_RET))
+    {
+        RLOGE("[lynq_get_connect_ap_rssi] exec cmd [ wl -i wlan0 rssi ] fail");
+        return -1;
+    }
+    *rssi = atoi(lynq_cmd_ret) * -1;
+/****** if got rssi is 0,means sta didn't connected any device****/
+    if(*rssi == 0)
+    {
+        RLOGE("[lynq_get_connect_ap_rssi]sta didn't connected any ap device,please check connection\n");
+        return -1;
+    }
+
+    return 0;
+}
+
+int lynq_get_connect_ap_band(lynq_wifi_index_e idx, lynq_wifi_band_m * band)
+{
+    RLOGD("enter lynq_get_connect_ap_band\n");
+    if (band == NULL)
+    {
+        return -1;
+    }
+
+    CHECK_IDX(idx, CTRL_STA);
+    ap_info_s ap;
+    ap.band = -1;
+
+    if (inner_get_status_info_ap(CTRL_STA, &ap) != 0)
+    {
+        return -1;
+    }
+    *band = ap.band;
+
+    return 0;
+}
+
+int lynq_get_connect_ap_ip(lynq_wifi_index_e idx, char *ip)
+{
+    int ret;
+    char *p;
+    char bssid[1024] = {0};
+
+    if (ip == NULL)
+    {
+        RLOGE("[lynq_get_connect_ap_ip]invalid param ptr ip,input ptr is NULL\n");
+        return -1;
+    }
+
+    CHECK_IDX(idx, CTRL_STA);
+
+    if (lynq_get_connect_ap_mac(idx, bssid) != 0)
+    {
+        return -1;
+    }
+
+    ip[0] = '\0';
+    ret = inner_get_ip_by_mac(bssid, ip, 32); //better input by user
+    if (ret != 0)
+    {
+        RLOGE("[lynq_get_connect_ap_ip] inner_get_ip_by_mac return fail");
+    }
+
+    if (ip[0] == '\0' || strchr(ip, ':') != NULL) //temp change, not ok
+    {
+        ip[0] = '\0';
+        ret = exec_cmd("grep \"new_router\" /tmp/wlan0_dhcpcd_router | awk '{print $2}'| tail -1", ip, 32);
+        if (ret != 0)
+        {
+            ip[0] = '\0';
+            return 0;
+        }
+        else
+        {
+            p = strchr(ip, '\n');
+            if (p != NULL)
+            {
+                *p = '\0';
+            }
+        }
+    }
+    return 0;
+}
+
+int lynq_get_sta_connected_dns(lynq_wifi_index_e idx, char *dns)
+{
+    RLOGD("[wifi]--enter--lynq_get_sta_connected_dns");
+    return lynq_get_connect_ap_ip(idx,dns); //> not 100 % get dns info
+}
+
+int lynq_ap_connect_num(int sta_number)
+{
+    char lynq_limit_cmd[32]={0};
+    int ret;
+    if((sta_number < 1 ) && (sta_number > 15))
+    {
+        RLOGE("sta_number: not in range\n",sta_number);
+        return -1;
+    }
+    sprintf(lynq_limit_cmd,"wl maxassoc  %d", sta_number);
+    ret = system(lynq_limit_cmd);
+    if(ret != 0)
+    {
+        RLOGE("cmd of limit ap devices number error\n");
+    }
+    return 0;
+}
+
+int lynq_enable_acs(lynq_wifi_index_e idx,int acs_mode)
+{
+
+    char lynq_wifi_acs_cmd[128]={0};
+    char lynq_cmd_mode[128]={0};
+    char lynq_cmd_slect[128]={0};
+
+    if((acs_mode != 2) && (acs_mode != 5))
+    {
+        PRINT_AND_RETURN_VALUE("set acs_mode is error",-1);
+    }
+
+    if (lynq_check_network_number(idx, CTRL_AP, AP_NETWORK_0) != 0)
+    {
+        return -1;
+    }
+
+    CHECK_IDX(idx, CTRL_AP);
+
+    CHECK_WPA_CTRL(CTRL_AP);
+
+    sprintf(lynq_wifi_acs_cmd,"SET_NETWORK %d frequency %d", AP_NETWORK_0, acs_mode);
+    sprintf(lynq_cmd_mode, "SET_NETWORK %d mode 2", AP_NETWORK_0);
+    sprintf(lynq_cmd_slect, "SELECT_NETWORK %d", AP_NETWORK_0);
+
+    DO_OK_FAIL_REQUEST(cmd_disconnect);
+    DO_OK_FAIL_REQUEST(lynq_wifi_acs_cmd);
+    DO_OK_FAIL_REQUEST(lynq_cmd_mode);
+    DO_OK_FAIL_REQUEST(cmd_save_config);
+    DO_OK_FAIL_REQUEST(lynq_cmd_slect);
+
+    return 0;
+}
+//you.chen add for tv-box start
+static int exec_cmd(const char *str_cmd, char * str_cmd_ret, size_t max_len) {
+    FILE *fp;
+    //printf("to exec cmd:%s\n", str_cmd);
+    if((fp=popen(str_cmd,"r"))==NULL)
+    {
+        perror("popen error!");
+        return -1;
+    }
+    if((fread(str_cmd_ret,max_len,1,fp))<0)
+    {
+        perror("fread fail!");
+        fclose(fp);
+        return -1;
+    }
+    fclose(fp);
+    return 0;
+}
+
+static int get_netmask_length(const char* mask)
+{
+    int masklen=0, i=0;
+    int netmask=0;
+
+    if(mask == NULL)
+    {
+        return 0;
+    }
+
+    struct in_addr ip_addr;
+    if( inet_aton(mask, &ip_addr) )
+    {
+        netmask = ntohl(ip_addr.s_addr);
+    }else
+    {
+        netmask = 0;
+        return 0;
+    }
+
+    while(0 == (netmask & 0x01) && i<32)
+    {
+        i++;
+        netmask = netmask>>1;
+    }
+    masklen = 32-i;
+    return masklen;
+}
+
+static int get_tether_route_str(char *str_cmd_ret, size_t max_len) {
+    int mask_len;
+    char *p;
+    char tmp[64] = {0};
+    sprintf(tmp, "ifconfig %s | grep Mask", s_ap_iterface_name);
+    if (exec_cmd(tmp, str_cmd_ret, max_len) != 0)
+        return -1;
+    p = strstr(str_cmd_ret, "Mask:");
+    if (p == NULL)
+        return -1;
+    mask_len = get_netmask_length(p + 5);
+    if (mask_len == 0)
+        return -1;
+    p = strstr(str_cmd_ret, "inet addr:");
+    if (p == NULL)
+        return -1;
+    strcpy(tmp, p + 10);
+    p = strstr(tmp, " ");
+    if (p != NULL)
+        *p = '\0';
+    sprintf(str_cmd_ret, "%s/%d", tmp, mask_len);
+    return 0;
+}
+
+static void GBWWatchThreadProc() {
+    int i,n, nloop, nmax, ncheckcount, nidlecount;
+    unsigned long long lastAP1Bytes, lastAP2Bytes, currAP1Bytes, currAP2Bytes;
+    unsigned int lastAP1Drop,lastAP2Drop, currAP1Drop, currAP2Drop;
+    unsigned int setAP1Speed, setAP2Speed, lastAP1Speed, lastAP2Speed, currAP1Speed, currAP2Speed,currSetAP1Speed;
+    char *results[16] = {0};
+    char str_cmd[256] = {0};
+    char str_cmd_ret[128] = {0};
+    char dest_ip[32] = {0};
+    lastAP1Bytes = lastAP2Bytes = 0;
+    lastAP1Drop = lastAP2Drop = 0;
+    lastAP1Speed = lastAP2Speed = 0;
+    setAP1Speed = 50;
+    setAP2Speed = 80;
+    nloop = 0;
+    nmax = 6;
+    ncheckcount = nidlecount = 0;
+
+    if (inner_get_ap_interface_name() == NULL)
+    {
+        RLOGE("------gbw thread run\n");
+        return;
+    }
+
+    RLOGD("------gbw thread run\n");
+    sprintf(str_cmd, "ip neigh | grep %s | awk '{print $1}'", g_gbw_mac);
+    while (dest_ip[0] == '\0') {
+        sleep(1);
+        str_cmd_ret[0] = '\0';
+        exec_cmd(str_cmd, str_cmd_ret, sizeof (str_cmd_ret));
+        for(n = 0; n < (int)sizeof(str_cmd_ret) && str_cmd_ret[n] != '\0'; n++) {
+            if (str_cmd_ret[n] == '\n'){
+                str_cmd_ret[n] = '\0';
+                break;
+            }
+        }
+        if (str_cmd_ret[0] != '\0')
+        {
+            strcpy(dest_ip, str_cmd_ret);
+        }
+    }
+
+    system_call_v("tc qdisc del dev %s root > /dev/null 2>&1", s_ap_iterface_name);
+    system_call_v("tc qdisc add dev %s root handle 1: htb r2q 1", s_ap_iterface_name);
+    system_call_v("tc class add dev %s parent 1:  classid 1:1  htb rate 50Mbit ceil 70Mbit prio 2 quantum 3000", s_ap_iterface_name);
+    if (get_tether_route_str(str_cmd_ret, sizeof (str_cmd_ret)) != 0)
+    {
+        RLOGD("not get tether info\n");
+        return;
+    }
+    system_call_v("tc filter add dev %s parent 1: protocol ip prio 16 u32 match ip dst %s flowid 1:1", s_ap_iterface_name, str_cmd_ret);
+    system_call_v("tc class add dev %s parent 1:  classid 1:2  htb rate 80Mbit ceil 100Mbit prio 0 quantum 3000000", s_ap_iterface_name);
+    system_call_v("tc filter add dev %s parent 1: protocol ip prio 1 u32 match ip dst %s flowid 1:2", s_ap_iterface_name, dest_ip);
+
+    while (1) {
+        sleep(1);
+        memset(str_cmd, 0, sizeof(str_cmd));
+        memset(str_cmd_ret, 0, sizeof(str_cmd_ret));
+        sprintf(str_cmd, "tc -s class show dev %s classid 1:1 | grep Sent", s_ap_iterface_name);
+        if (0 != exec_cmd(str_cmd, str_cmd_ret, sizeof (str_cmd_ret)))
+            continue;
+        //printf("ap1 --- %s\n", str_cmd);
+        n = lynq_split(str_cmd_ret, strlen(str_cmd_ret), ' ', results);
+        if (n > 9) {
+            if (strcmp(results[1], "Sent") == 0) {
+                currAP1Bytes = atoll(results[2]);
+            }
+            if (strcmp(results[6], "(dropped") == 0) {
+                currAP1Drop = atoi(results[7]);
+            }
+        }
+
+        memset(str_cmd, 0, sizeof(str_cmd));
+        memset(str_cmd_ret, 0, sizeof(str_cmd_ret));
+        sprintf(str_cmd, "tc -s class show dev %s classid 1:2 | grep Sent", s_ap_iterface_name);
+        if (0 != exec_cmd(str_cmd, str_cmd_ret, sizeof (str_cmd_ret)))
+            continue;
+        //printf("ap2 --- %s\n", str_cmd);
+        n = lynq_split(str_cmd_ret, strlen(str_cmd_ret), ' ', results);
+        if (n > 9) {
+            if (strcmp(results[1], "Sent") == 0) {
+                currAP2Bytes = atoll(results[2]);
+            }
+            if (strcmp(results[6], "(dropped") == 0) {
+                currAP2Drop = atoi(results[7]);
+            }
+        }
+
+        //printf("ap1 %llu- %u, ap2 %llu-%u\n", currAP1Bytes, currAP1Drop, currAP2Bytes, currAP2Drop);
+        if (currAP1Bytes < lastAP1Bytes || currAP2Bytes < lastAP2Bytes) {
+            lastAP1Bytes = currAP1Bytes;
+            lastAP2Bytes = currAP2Bytes;
+            continue;
+        }
+
+        currAP1Speed = (currAP1Bytes - lastAP1Bytes) / 128 / 1024;
+        currAP2Speed = (currAP2Bytes - lastAP2Bytes) / 128 / 1024;
+        //printf("ap1 speed %d mb, ap2 speed %d mb\n", currAP1Speed, currAP2Speed);
+        lastAP1Speed = currAP1Speed;
+        lastAP2Speed = currAP2Speed;
+        lastAP1Bytes = currAP1Bytes;
+        lastAP2Bytes = currAP2Bytes;
+
+        currSetAP1Speed = setAP1Speed;
+        if ((currAP2Speed < 30 && currAP2Speed > 5) && currAP1Speed > 5) {
+            ncheckcount++;
+            if (ncheckcount > 3) {
+                ncheckcount = 0;
+                currSetAP1Speed = 5;
+            }
+        }
+        else {
+            ncheckcount = 0;
+            if (currAP1Speed < 5)
+                nidlecount++;
+            else
+                nidlecount = 0;
+
+        }
+
+        if (nidlecount > 60 ){
+            currSetAP1Speed = 50;
+        }
+
+        if (currSetAP1Speed != setAP1Speed) {
+            setAP1Speed = currSetAP1Speed;
+            system_call_v(str_cmd, "tc class replace dev %s parent 1:  classid 1:1  htb rate %dMbit ceil %dMbit prio 2 quantum 3000",
+                         s_ap_iterface_name, setAP1Speed, (int)(setAP1Speed*1.4));
+        }
+    }
+}
+
+int enableGBW(const char* mac) {
+    int i,len;
+    char get_ipaddr_cmd[128]={0};
+    ap_info_s *ap;
+    device_info_s * list;
+
+    if (mac == NULL || g_gbw_enabled == 1)
+        return -1;
+    len = strlen(mac);
+    g_gbw_mac = malloc(len + 1);
+    for(i=0;i<len;i++) {
+        if (mac[i] >= 'A' && mac[i] <= 'Z')
+        {
+            g_gbw_mac[i] = 'a' + (mac[i] - 'A');
+        }
+        else
+            g_gbw_mac[i] = mac[i];
+    }
+    g_gbw_mac[i] = '\0';
+    g_gbw_enabled = 1;
+
+    sprintf(get_ipaddr_cmd, "ip neigh | grep %s", g_gbw_mac);
+    if (system(get_ipaddr_cmd) == 0) {
+        //startGBW();
+        if ( 0 ==lynq_get_ap_device_list(1, &ap, &list,&len) ) {
+            for (i=0;i<len;i++) {
+                //printf("--mac:%s, name:%s\n",list[i].sta_mac, list[i].hostname);
+                if (strcmp(g_gbw_mac, list[i].sta_mac) == 0)
+                    startGBW();
+            }
+            free(ap);
+            free(list);
+        }
+    }
+    return 0;
+}
+
+int disableGBW() {
+    stopGBW();
+    free(g_gbw_mac);
+    g_gbw_mac = NULL;
+    g_gbw_enabled = 1;
+    return 0;
+}
+
+static int startGBW() {
+    if (g_gbw_watcher_pid != 0) {
+        stopGBW();
+    }
+    pthread_create(&g_gbw_watcher_pid,NULL,GBWWatchThreadProc,NULL);
+}
+
+static int stopGBW() {
+    void* retval;
+    char cmd[64] = {0};
+    pthread_cancel(g_gbw_watcher_pid);
+    pthread_join(g_gbw_watcher_pid, &retval);
+    g_gbw_watcher_pid = 0;
+    sprintf(cmd, "%s %d", get_interface_name_script, LYNQ_WIFI_INTERFACE_1);
+    if (s_ap_iterface_name[0] != '\0')
+    {
+        sprintf(cmd, "tc qdisc del dev %s root", s_ap_iterface_name);
+        system(cmd);
+    }
+}
+//you.chen add for tv-box end
diff --git a/IC_src/mtk/lib/liblynq-wifi6/makefile b/IC_src/mtk/lib/liblynq-wifi6/makefile
new file mode 100755
index 0000000..e7a3ca8
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-wifi6/makefile
@@ -0,0 +1,63 @@
+SHELL = /bin/sh
+RM = rm -f
+
+LOCAL_CFLAGS := -Wall \
+                -Os \
+                -flto \
+                -fpermissive \
+
+CFLAGS += -fPIC -O2 $(INCLUDE) -D_LARGEFILE64_SOURCE
+
+$(warning ################# rock ROOT: $(ROOT),includedir:$(includedir))
+LOCAL_PATH   = .
+
+LOCAL_C_INCLUDES = \
+  -I. \
+  -I./include \
+  -I$(LOCAL_PATH)/include \
+  -I$(ROOT)$(includedir)/glib-2.0 \
+  -I$(ROOT)$(libdir)/glib-2.0/include \
+
+
+
+LOCAL_LIBS := \
+    -L. \
+    -L./lib \
+    -llog \
+    -lpthread \
+    -lwpa_client
+
+SOURCES = $(wildcard *.c wildcard *.h )
+
+EXECUTABLE = liblynq-wifi6.so
+
+OBJECTS=$(SOURCES:.c=.o)
+
+
+.PHONY: build clean install pack_rootfs 
+
+all: build
+$(EXECUTABLE): $(OBJECTS)
+	$(CXX) -shared -Wl,--no-undefined $(OBJECTS) $(LOCAL_LIBS) $(CFLAGS) $(LOCAL_CFLAGS) $(LOCAL_C_INCLUDES) -o $@
+
+%.o : %.c
+	$(CC) $(LOCAL_C_INCLUDES) $(CFLAGS) $(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)
diff --git a/IC_src/mtk/lib/liblynq-wifi6/scripts/get_interface_name.sh b/IC_src/mtk/lib/liblynq-wifi6/scripts/get_interface_name.sh
new file mode 100755
index 0000000..4dc8717
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-wifi6/scripts/get_interface_name.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+if [ "$1" == "0" ]; then
+	echo "wlan0"
+elif [ "$1" == "1" ]; then
+	echo "ap0"
+else
+	exit 1
+fi
+
diff --git a/IC_src/mtk/lib/liblynq-wifi6/scripts/sta_status_change.sh b/IC_src/mtk/lib/liblynq-wifi6/scripts/sta_status_change.sh
new file mode 100755
index 0000000..829303e
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-wifi6/scripts/sta_status_change.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+
diff --git a/IC_src/mtk/lib/liblynq-wifi6/scripts/start_stop_ap.sh b/IC_src/mtk/lib/liblynq-wifi6/scripts/start_stop_ap.sh
new file mode 100755
index 0000000..441a0ee
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-wifi6/scripts/start_stop_ap.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+if [ "$1" == "start" ]; then
+	ifconfig ap0 192.168.15.1 netmask 255.255.255.240
+
+	if [ $? != 0 ]; then
+		exit 1
+	fi
+	mkdir -p /run/wg870/dnsmasq.d
+	conf_file="/run/wg870/dnsmasq.conf"
+	echo "port=0" > $conf_file
+	echo "interface=ap0" >> $conf_file
+	echo "listen-address=192.168.15.1" >> $conf_file
+	echo "bind-interfaces"  >> $conf_file
+	echo "localise-queries" >> $conf_file
+        echo "no-ping" >> $conf_file
+        echo "dhcp-authoritative" >> $conf_file
+	echo "dhcp-range=192.168.15.2,192.168.15.14,255.255.255.240,1h"  >> $conf_file
+	echo "dhcp-option=3,192.168.15.1"  >> $conf_file
+	echo "dhcp-option=6,192.168.15.1,114.114.114.114"  >> $conf_file
+	echo "dhcp-range=192.168.15.2,192.168.15.14,255.255.255.240,1h"  >> $conf_file
+	echo "dhcp-leasefile=/run/wg870/ap0.lease" >> $conf_file
+	ps -eo "%p %a" | grep "/usr/bin/dnsmasq -x /run/wg870/dnsmasq.pid" | grep -v grep 
+	if [ $? != 0 ]; then
+		/usr/bin/dnsmasq -x /run/wg870/dnsmasq.pid -7 /run/wg870/dnsmasq.d --local-service -C $conf_file -r /run/wg870 --dhcp-broadcast
+	fi
+
+elif [ "$1" == "stop" ]; then
+	ps -eo "%p %a" | grep "/usr/bin/dnsmasq -x /run/wg870/dnsmasq.pid" | grep -v grep | awk '{print "kill "$1}' | sh
+	ifconfig ap0 down
+	if [ $? != 0 ]; then
+		exit 1
+	fi
+else
+	exit 2
+fi
+
+exit 0
diff --git a/IC_src/mtk/lib/liblynq-wifi6/scripts/start_stop_sta.sh b/IC_src/mtk/lib/liblynq-wifi6/scripts/start_stop_sta.sh
new file mode 100755
index 0000000..25ab126
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-wifi6/scripts/start_stop_sta.sh
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+if [ "$1" == "start" ]; then
+        ifconfig wlan0 up
+        if [ $? != 0 ]; then
+                exit 1
+        fi
+		ps -eo "%p %a" | grep "dhcpcd wlan0" | grep -v grep
+		if [ $? != 0 ];	then
+			echo "" > /tmp/wlan0_dhcpcd_router
+			mkdir -p /run/wg870/
+			hook_script="/run/wg870/wlan0_dhcpcd_run_hooks.sh"
+			echo "#!/bin/sh" > $hook_script
+			echo "if [ \"\$reason\" == \"BOUND\" -o \"\$reason\" == \"RENEW\" -o \"\$reason\" == \"REBIND\" ]; then" >> $hook_script
+			echo "    if [ \"\$new_routers\" != \"\" ]; then" >> $hook_script
+			echo "        for x in \$new_routers; do" >> $hook_script
+			echo "            echo \"new_router \$x\" > /tmp/wlan0_dhcpcd_router" >> $hook_script
+			echo "            ping -c2 \$x &" >> $hook_script
+			echo "        done" >> $hook_script
+			echo "    fi" >> $hook_script
+			echo "fi" >> $hook_script
+			chmod +x $hook_script
+			dhcpcd wlan0 -t 0 -o domain_name_servers --noipv4ll -4 -B -G -c $hook_script &
+		fi
+elif [ "$1" == "stop" ]; then
+        ps -eo "%p %a" | grep "dhcpcd wlan0" | grep -v grep | awk '{print "kill "$1}' | sh
+        ifconfig wlan0 0.0.0.0
+        if [ $? != 0 ]; then
+                exit 1
+        fi
+else
+        exit 2
+fi
+
+exit 0
diff --git a/IC_src/mtk/lib/liblynq-wifi6/scripts/start_wg870_service.sh b/IC_src/mtk/lib/liblynq-wifi6/scripts/start_wg870_service.sh
new file mode 100755
index 0000000..27aaf10
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-wifi6/scripts/start_wg870_service.sh
@@ -0,0 +1,68 @@
+#!/bin/sh
+for ((i=0; i < 10; i++)); do
+        state=`systemctl is-active wg870_drv_insmod.service`
+        if [ "$state" == "active" ]; then
+                break
+        elif [ "$state" != "activating" ]; then
+                echo "to start now"
+                systemctl start wg870_drv_insmod.service
+        fi
+        usleep 100000
+done
+
+if [ "$state" != "active" ]; then
+        exit 1
+fi
+
+state=`wpa_cli -iwpa_wlan0_cmd -p/var/run/ ping`
+if  [ "$state" != "PONG" ]; then
+    for ((i=0; i < 50; i++)); do
+        usleep 100000
+        state=`wpa_cli -iwpa_wlan0_cmd -p/var/run/ ping`
+        echo "$state"
+        if [ "$state" == "PONG" ]; then
+            service_started=1
+            break
+        fi
+    done
+else
+        service_started=1
+fi
+
+if [ "$service_started" != "1" ];then
+        exit 1
+fi
+
+state=`wpa_cli -iwpa_wlan0_cmd -p/var/run/ interface | grep -vE "Available|p2p-dev" | grep wlan0`
+if [ $? != 0 ]; then
+        state=`wpa_cli -iwpa_wlan0_cmd -p/var/run/ interface_add wlan0 /data/wifi/wg870/wpa_supplicant.conf nl80211`
+        if [ "$state" != "OK" ]; then
+                exit 2
+        fi
+		wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=wlan0 disconnect
+fi
+
+state=`wpa_cli -iwpa_wlan0_cmd -p/var/run/ interface | grep -vE "Available|p2p-dev" | grep ap0`
+if [ $? != 0 ]; then
+		wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=wlan0 DRIVER interface_create ap0
+        state=`wpa_cli -iwpa_wlan0_cmd -p/var/run/ interface_add ap0 /data/wifi/wg870/wpa_supplicant_ap.conf nl80211`
+
+        if [ "$state" != "OK" ]; then
+                exit 3
+        fi
+        ifconfig ap0 down
+fi
+
+
+state=`wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=wlan0 log_level INFO`
+if [ "$state" != "OK" ]; then
+        state=`wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=wlan0 log_level INFO`
+
+        if [ "$state" != "OK" ]; then
+                echo "change wpa_cli log_level to INFO FAIL"
+        fi
+fi
+
+
+exit 0
+
diff --git a/IC_src/mtk/lib/liblynq-wifi6/scripts_connman/get_interface_name.sh b/IC_src/mtk/lib/liblynq-wifi6/scripts_connman/get_interface_name.sh
new file mode 100755
index 0000000..61b44d9
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-wifi6/scripts_connman/get_interface_name.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+if [ "$1" == "0" ]; then
+	echo "wlan0"
+elif [ "$1" == "1" ]; then
+	echo "tether"
+else
+	exit 1
+fi
+
diff --git a/IC_src/mtk/lib/liblynq-wifi6/scripts_connman/sta_status_change.sh b/IC_src/mtk/lib/liblynq-wifi6/scripts_connman/sta_status_change.sh
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-wifi6/scripts_connman/sta_status_change.sh
diff --git a/IC_src/mtk/lib/liblynq-wifi6/scripts_connman/start_stop_ap.sh b/IC_src/mtk/lib/liblynq-wifi6/scripts_connman/start_stop_ap.sh
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-wifi6/scripts_connman/start_stop_ap.sh
diff --git a/IC_src/mtk/lib/liblynq-wifi6/scripts_connman/start_stop_sta.sh b/IC_src/mtk/lib/liblynq-wifi6/scripts_connman/start_stop_sta.sh
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-wifi6/scripts_connman/start_stop_sta.sh
diff --git a/IC_src/mtk/lib/liblynq-wifi6/scripts_connman/start_wg870_service.sh b/IC_src/mtk/lib/liblynq-wifi6/scripts_connman/start_wg870_service.sh
new file mode 100755
index 0000000..303a075
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-wifi6/scripts_connman/start_wg870_service.sh
@@ -0,0 +1,76 @@
+#!/bin/sh
+
+for ((i=0; i < 10; i++)); do
+	state=`systemctl is-active wg870_drv_insmod.service`
+	if [ "$state" == "active" ]; then
+		break	
+	elif [ "$state" != "activating" ]; then
+
+		systemctl start wg870_drv_insmod.service
+	fi
+	usleep 100000 
+done
+
+if [ "$state" != "active" ]; then
+	exit 1
+fi
+
+for ((i=0; i < 10; i++)); do
+	connmanctl technologies | grep -q "/net/connman/technology/wifi"
+	if [ $? == 0 ]; then
+		connman_started=1
+		break
+	fi
+done
+
+if [ "$connman_started" == ""]; then
+	exit 2
+fi
+
+ifconfig | grep -q wlan0
+
+if [ $? != 0 ]; then
+	connmanctl enable wifi
+
+	for ((i=0; i < 5; i++)); do
+		usleep 100000 
+		ifconfig | grep -q wlan0
+		if [ $? == 0 ]; then
+			wlan0_started=1
+			wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=wlan0 disconnect
+			break
+		fi
+	done
+else
+	wlan0_started=1
+fi
+
+
+if [ "$wlan0_started" == ""]; then
+    exit 3
+fi
+
+ifconfig | grep -q ap0
+
+if [ $? != 0 ]; then
+	wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=wlan0 DRIVER interface_create ap0
+	connmanctl tether wifi on lynq 1qaz@WSX#$%^
+
+	for ((i=0; i < 5; i++)); do
+		usleep 100000 
+		ifconfig | grep -q ap0
+		if [ $? == 0 ]; then
+			ap0_started=1
+			wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=ap0 disconnect
+			break
+		fi
+	done
+else
+	ap0_started=1
+fi
+
+
+if [ "$ap0_started" == ""]; then
+    exit 4
+fi
+
diff --git a/IC_src/mtk/lib/liblynq_logdata_handle/LICENSE b/IC_src/mtk/lib/liblynq_logdata_handle/LICENSE
new file mode 100644
index 0000000..77f59ed
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq_logdata_handle/LICENSE
@@ -0,0 +1,31 @@
+Copyright Statement:
+
+This software/firmware and related documentation ("MediaTek Software") are
+protected under relevant copyright laws. The information contained herein is
+confidential and proprietary to MediaTek Inc. and/or its licensors. Without
+the prior written permission of MediaTek inc. and/or its licensors, any
+reproduction, modification, use or disclosure of MediaTek Software, and
+information contained herein, in whole or in part, shall be strictly
+prohibited.
+
+MediaTek Inc. (C) 2015. All rights reserved.
+
+BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ON AN "AS-IS" BASIS ONLY. MEDIATEK 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 MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
+RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK 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 MEDIATEK
+SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
+RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
+ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
+RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
+MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
diff --git a/IC_src/mtk/lib/liblynq_logdata_handle/include/lynq_deal_logrotate.h b/IC_src/mtk/lib/liblynq_logdata_handle/include/lynq_deal_logrotate.h
new file mode 100644
index 0000000..e2de89c
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq_logdata_handle/include/lynq_deal_logrotate.h
@@ -0,0 +1,30 @@
+#ifndef __LYNQ_DEAL_LOGROTATE_H__

+#define __LYNQ_DEAL_LOGROTATE_H__

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+

+typedef enum

+{

+	SYSLOG_1 = 1,

+	SYSLOG_2,

+	SYSLOG_3,

+	SYSLOG_4,

+	SYSLOG_5,

+	SYSLOG_MAX

+}SYSLOG_PATH;

+

+

+int lynq_read_logdata(int fd,unsigned char* dest, unsigned int start, unsigned int size);

+int lynq_get_syslog_path(SYSLOG_PATH syslog_path,char *file_path);

+int lynq_get_mculog_path(char *file_path);

+int lynq_get_current_mtklog_path(char *file_path);

+int lynq_get_current_syslog_path(char *file_path);

+int lynq_get_current_mculog_path(char *file_path);

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif //__LYNQ_DEAL_LOGROTATE_H__
\ No newline at end of file
diff --git a/IC_src/mtk/lib/liblynq_logdata_handle/include/lynq_logdata_handle.h b/IC_src/mtk/lib/liblynq_logdata_handle/include/lynq_logdata_handle.h
new file mode 100644
index 0000000..9aa2c57
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq_logdata_handle/include/lynq_logdata_handle.h
@@ -0,0 +1,21 @@
+#ifndef __LYNQ_LOGDATA_HANDLE__H_

+#define __LYNQ_LOGDATA_HANDLE__H_

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+

+typedef enum

+{

+	MD_LOG = 0,

+	AP_LOG,

+	MCU_LOG,

+	LOG_MD_MAX

+}MODULE;

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif //__LYNQ_LOG_SERVER__H_
\ No newline at end of file
diff --git a/IC_src/mtk/lib/liblynq_logdata_handle/makefile b/IC_src/mtk/lib/liblynq_logdata_handle/makefile
new file mode 100755
index 0000000..8cce434
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq_logdata_handle/makefile
@@ -0,0 +1,91 @@
+SHELL = /bin/sh
+RM = rm -f
+
+LOCAL_CFLAGS := -Wall \
+                -std=gnu++14 \
+                -g -Os \
+                -flto \
+                -fPIC \
+                -fpermissive \
+
+$(warning ################# C2K support: $(RAT_CONFIG_C2K_SUPPORT))
+ifeq ($(strip $(RAT_CONFIG_C2K_SUPPORT)), yes)
+    LOCAL_CFLAGS += -DC2K_SUPPORT
+
+endif
+
+ifeq ($(strip $(MTK_MULTI_SIM_SUPPORT)), dsds)
+    LOCAL_CFLAGS += -DANDROID_SIM_COUNT_2 \
+                     -DANDROID_MULTI_SIM \
+                     -DMODE_DSDS
+endif
+
+ifeq ($(strip $(MTK_MULTI_SIM_SUPPORT)), dsss)
+    LOCAL_CFLAGS += -DMODE_DSSS
+endif
+
+$(warning ################# TARGET_PLATFORM: $(TARGET_PLATFORM))
+ifeq ($(strip $(TARGET_PLATFORM)), mt2731)
+#$(warning #################add for debug $(ROOT), $(includedir))
+$(warning ################# TARGET_PLATFORM_MT2731)
+    LOCAL_CFLAGS += -DTARGET_PLATFORM_MT2731 \
+                    -DMD_93_SUPPORT
+else ifeq ($(strip $(TARGET_PLATFORM)), mt2635)
+$(warning ################# TARGET_PLATFORM_MT2635)
+    LOCAL_CFLAGS += -DTARGET_PLATFORM_MT2635 \
+                    -DMD_90_SUPPORT
+endif
+
+$(warning ################# RITA ROOT: $(ROOT),includedir:$(includedir))
+LOCAL_PATH   = .
+
+LOCAL_C_INCLUDES = \
+  -I. \
+  -I$(ROOT)$(includedir)/logger \
+  -I$(LOCAL_PATH)/include \
+  -I$(ROOT)$(includedir)/liblog \
+
+
+LOCAL_LIBS := \
+    -L. \
+    -ldl \
+    -lpthread \
+    -llynq-log \
+    -llog \
+
+SOURCES = $(wildcard *.c wildcard *.h src/*.c)
+
+EXECUTABLE =  liblynq-logdata-handle.so
+
+OBJECTS=$(SOURCES:.c=.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 : %.c
+	$(CC) $(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)
+
diff --git a/IC_src/mtk/lib/liblynq_logdata_handle/src/lynq_deal_logrotate.c b/IC_src/mtk/lib/liblynq_logdata_handle/src/lynq_deal_logrotate.c
new file mode 100755
index 0000000..12e0c77
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq_logdata_handle/src/lynq_deal_logrotate.c
@@ -0,0 +1,176 @@
+#include <stdio.h>

+#include <stdlib.h>

+#include <string.h>

+#include <sys/types.h>

+#include<sys/stat.h>

+#include<fcntl.h>

+#include <unistd.h>

+#include <errno.h>

+

+#include "lynq_deal_logrotate.h"

+

+//lt add @2021.7.28 for get file data

+int lynq_read_logdata(int fd,unsigned char* dest, unsigned int start, unsigned int size)

+{ 

+    int ret,err;

+	

+    if (lseek(fd, start, SEEK_SET) < 0) {

+        err = errno;

+        printf("mtk_device_wrap_seek read block err\n");

+    }

+

+    do {

+

+        ret = read(fd, dest, size);

+

+        if (ret == 0) {

+            break;

+        } else if (ret < 0) {

+            if (errno == EINTR) {

+                continue;

+            }

+            err = -errno;

+            printf("Error reading metadata file\n");

+

+            close(fd);

+

+            return err;

+        }

+        size -= ret;

+        dest += ret;

+    } while(size > 0);

+

+    close(fd);

+    return ret;    

+   

+}

+

+//lt add @2021.7.28 for get syslog file path

+int lynq_get_syslog_path(SYSLOG_PATH syslog_path,char *file_path) //

+{

+	char syslog_file_path[64] = {0};

+	int fd;

+	int ret = 0;

+ 	switch(syslog_path)

+	{

+		case SYSLOG_1:

+			 sprintf(syslog_file_path,"/var/log/syslog.log.1.gz");

+			break;

+		case SYSLOG_2:

+			sprintf(syslog_file_path,"/var/log/syslog.log.2.gz");

+			break;

+		case SYSLOG_3:

+			sprintf(syslog_file_path,"/var/log/syslog.log.3.gz");

+			break;

+		case SYSLOG_4:

+			sprintf(syslog_file_path,"/var/log/syslog.log.4.gz");

+			break;

+		case SYSLOG_5:

+			sprintf(syslog_file_path,"/var/log/syslog.log.5.gz");

+			break;

+		default :

+			ret = -1;

+			break;

+	 }

+	

+	if(ret == 0)

+	{

+		fd = open(syslog_file_path,O_RDONLY);

+		ret = fd;

+		close(fd);

+	}

+	

+	if(ret >= 0)

+	{

+		memcpy(file_path,syslog_file_path,sizeof(syslog_file_path));

+	}

+	return ret;

+}

+

+//lt add @2021.7.28 for get mculog file path

+int lynq_get_mculog_path(char *file_path)

+{

+	char mculog_file_path[64] = {0};

+	int fd;

+	int ret = 0;

+ 	sprintf(mculog_file_path,"/var/log/mculog.log.1.gz");

+

+	fd = open(mculog_file_path,O_RDONLY);

+	ret = fd;

+	close(fd);

+	

+	if(ret >= 0)

+	{

+		memcpy(file_path,mculog_file_path,sizeof(mculog_file_path));

+	}

+	

+	return ret;

+}

+

+//lt add @2021.7.28 for get current mtklog file path

+int lynq_get_current_mtklog_path(char *file_path)

+{

+	char mtklog_file_path[64] = {0};

+	int fd;

+	int ret = 0;

+	

+	system("tar -zcvf /var/log/mtklog.tar.gz /var/log/mtklog");

+//	system("echo -n "" > /var/log/mtklog");

+ 	sprintf(mtklog_file_path,"/var/log/mtklog.tar.gz");

+

+	fd = open(mtklog_file_path,O_RDONLY);

+	ret = fd;

+	close(fd);

+	

+	if(ret >= 0)

+	{

+		memcpy(file_path,mtklog_file_path,sizeof(mtklog_file_path));

+	}

+	return ret;

+}

+

+

+//lt add @2021.7.28 for get current syslog file path

+int lynq_get_current_syslog_path(char *file_path)

+{

+	char syslog_file_path[64] = {0};

+	int fd;

+	int ret = 0;

+	

+	system("tar -zcvf /var/log/syslog.tar.gz /var/log/syslog.log");

+	system("echo -n "" > /var/log/syslog.log");

+ 	sprintf(syslog_file_path,"/var/log/syslog.tar.gz");

+

+	fd = open(syslog_file_path,O_RDONLY);

+	ret = fd;

+	close(fd);

+	

+	if(ret >= 0)

+	{

+		memcpy(file_path,syslog_file_path,sizeof(syslog_file_path));

+	}

+	return ret;

+}

+

+

+//lt add @2021.7.28 for get current mculog file path

+int lynq_get_current_mculog_path(char *file_path)

+{

+	char mculog_file_path[64] = {0};

+	int fd;

+	int ret = 0;

+	

+	system("tar -zcvf /var/log/mculog.tar.gz /var/log/mculog.log");

+	system("echo -n "" > /var/log/mculog.log");

+ 	sprintf(mculog_file_path,"/var/log/mculog.tar.gz");

+

+	fd = open(mculog_file_path,O_RDONLY);

+	ret = fd;

+	close(fd);

+	

+	if(ret >= 0)

+	{

+		memcpy(file_path,mculog_file_path,sizeof(mculog_file_path));

+	}

+	return ret;

+}
\ No newline at end of file
diff --git a/IC_src/mtk/lib/libpoweralarm/LICENSE b/IC_src/mtk/lib/libpoweralarm/LICENSE
new file mode 100644
index 0000000..77f59ed
--- /dev/null
+++ b/IC_src/mtk/lib/libpoweralarm/LICENSE
@@ -0,0 +1,31 @@
+Copyright Statement:
+
+This software/firmware and related documentation ("MediaTek Software") are
+protected under relevant copyright laws. The information contained herein is
+confidential and proprietary to MediaTek Inc. and/or its licensors. Without
+the prior written permission of MediaTek inc. and/or its licensors, any
+reproduction, modification, use or disclosure of MediaTek Software, and
+information contained herein, in whole or in part, shall be strictly
+prohibited.
+
+MediaTek Inc. (C) 2015. All rights reserved.
+
+BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ON AN "AS-IS" BASIS ONLY. MEDIATEK 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 MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
+RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK 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 MEDIATEK
+SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
+RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
+ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
+RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
+MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
diff --git a/IC_src/mtk/lib/libpoweralarm/format_change.c b/IC_src/mtk/lib/libpoweralarm/format_change.c
new file mode 100644
index 0000000..8d3e3b1
--- /dev/null
+++ b/IC_src/mtk/lib/libpoweralarm/format_change.c
@@ -0,0 +1,133 @@
+#include"format_change.h"
+#include<log/log.h>
+
+
+/*****************************************************************************
+*   Prototype    : format_change
+*   Description  : convert the incoming fixed format string into the corresponding alarm seconds
+*   Input        : char *buffer ;  input format : 2022-04-23-15-30-00 ( Mon-Day-Hour-Min-Sec ) Or  1200 ( seconds )              
+*   Output       : None
+*   Return Value : -1: match error ; >0: set to wake up the devices after seconds
+*
+*****************************************************************************/
+ssize_t format_change(char *buffer)
+{
+    time_t rawtime;
+    time_t alarm_tamp;
+    struct tm *info = NULL;
+    struct tm *set_alarm = NULL;
+    char *time_buff = NULL;
+
+    char ebuff[256];
+    regex_t reg_alm,reg_sec;
+    char *pattern_setalm = "^20[0-9][0-9]-[01]?[1-9]-[0-3]?[0-9]-[0-2]?[0-9]-[0-5]?[0-9]-[0-5]?[0-9]$";//regular expression 1 ,  in order that match alarm time string eg:Mon-Day-Hour-Min-Sec 
+    char *pattern_setsec = "^[1-9][0-9]*$";//regular expression 2 ,  in order that match seconds 
+    int cflags = REG_EXTENDED | REG_ICASE | REG_NOSUB;//POSIX extend,not care up and low letters,not store result
+
+    int ret;
+    ssize_t sec;
+
+    ret = regcomp(&reg_alm,pattern_setalm,cflags);  //匹配规则1:\d\d\d\d\d-\d\d-\d\d-\d\d-\d\d-\d\d
+    if(ret) // judge error code : 0 symbolize success ; other value symbolizes fail 
+    {
+        regerror(ret,&reg_alm,ebuff,256);
+        ALOGI(ebuff);
+        regfree(&reg_alm);  //free mattch pattern
+        regfree(&reg_sec);
+        return -1;
+    }
+
+    ret = regcomp(&reg_sec,pattern_setsec,cflags); //匹配规则2:^\d\d*$
+    if(ret)// judge error code : 0 symbolize success ; other value symbolizes fail 
+    {
+        regerror(ret,&reg_sec,ebuff,256);
+        ALOGI(ebuff);
+        regfree(&reg_alm);  //free mattch pattern
+        regfree(&reg_sec);
+        return -1;
+    }
+
+    time(&rawtime);  //获取自1970年到现在一共过去了几秒,赋值给rawtime
+
+    info =localtime(&rawtime); //转换为UTC时间
+
+    bool leap_flag = (bool)(((info->tm_year%4==0)&&(info->tm_year%100!=0)) || (info->tm_year%400 == 0));  //判断当前是否为闰年
+    int day_array[13] = {0,31, leap_flag?29:28,31,30,31,30,31,31,30,31,30,31};   //设置每个月的天数
+
+    if((ret = regexec(&reg_alm,buffer,0,NULL,0)) == 0)   //Retrieve the incoming buffer string according to matching rule 1
+    {
+        set_alarm = (struct tm *)malloc(sizeof(struct tm));
+        memset(set_alarm,0,sizeof(struct tm));
+        memcpy(set_alarm,info,sizeof(struct tm));  //拷贝当前时间信息
+
+        ret = sscanf(buffer,"%d-%d-%d-%d-%d-%d",&(set_alarm->tm_year),&(set_alarm->tm_mon),&(set_alarm->tm_mday),&(set_alarm->tm_hour),&(set_alarm->tm_min),&(set_alarm->tm_sec));//read data form formatted string
+        
+        if(ret == -1)  //sscanf no mattch
+        {
+            ALOGI("sscanf error code -1\n");
+            free(set_alarm);
+            return -1;
+        }
+        else if(ret == 6) //Success mattch 
+        {
+            if((set_alarm->tm_hour > 23) || (set_alarm->tm_hour < 0)) //judge hour 
+            {
+                ALOGI("hour error\n");
+                ret = -1;
+            }
+            if((set_alarm->tm_mon > 12) || (set_alarm->tm_mon < 1))  //judge month
+            {
+                ALOGI("mon error\n");
+                ret = -1;
+            }
+            if((set_alarm->tm_mday > day_array[set_alarm->tm_mon]) || (set_alarm->tm_mday < 1)) //judge day
+            {
+                ALOGI("day error\n");
+                ret = -1;
+            }
+            if(ret == -1) //Error setting alarm time
+            {
+                free(set_alarm);
+                return -1;
+            }
+
+            set_alarm->tm_mon -= 1; 
+            sprintf(ebuff,"set alarm is %s\n",asctime(set_alarm)); //print log
+            ALOGI(ebuff);
+            alarm_tamp = mktime(set_alarm); //struct tm transform struct time_t
+            time(&rawtime); 
+            //printf("tamp: %ld\n",alarm_tamp);
+            sec = alarm_tamp - rawtime; //set second
+            free(set_alarm);
+
+            if(sec <= 0) //the current alarm time is less than the current system time
+            { 
+                ALOGI("sec <= 0 setalarm error\n");
+                return -1;
+            }
+        }
+        else //sscanf mattch fail
+        {
+            ALOGI("sscanf error other\n");
+            free(set_alarm);
+            return -1;
+        }
+    }
+    else if ((ret = regexec(&reg_sec,buffer,0,NULL,0)) == 0) //Retrieve the incoming buffer string according to matching rule 2
+    {
+        sec = (ssize_t)atoi(buffer); //string convert ssize_t
+    }
+    else //matching rule 1 and 2 all fail
+    {
+        regerror(ret,&reg_sec,ebuff,256); //free memony
+        ALOGI(ebuff);
+        regfree(&reg_alm); 
+        regfree(&reg_sec);
+        return -1;
+    }
+
+    regfree(&reg_alm);
+    regfree(&reg_sec);
+    
+    return sec;
+}
diff --git a/IC_src/mtk/lib/libpoweralarm/format_change.h b/IC_src/mtk/lib/libpoweralarm/format_change.h
new file mode 100644
index 0000000..e84c985
--- /dev/null
+++ b/IC_src/mtk/lib/libpoweralarm/format_change.h
@@ -0,0 +1,15 @@
+#ifndef _FORMAT_CHANGE_H_
+#define _FORMAT_CHANGE_H_
+
+#include<stdio.h>
+#include<stdlib.h>
+#include<regex.h>
+#include<stdbool.h>
+#include<time.h>
+#include<string.h>
+
+
+ssize_t format_change(char *buffer);
+
+
+#endif
diff --git a/IC_src/mtk/lib/libpoweralarm/include/lynq_alarm.h b/IC_src/mtk/lib/libpoweralarm/include/lynq_alarm.h
new file mode 100644
index 0000000..b72e0f0
--- /dev/null
+++ b/IC_src/mtk/lib/libpoweralarm/include/lynq_alarm.h
@@ -0,0 +1,27 @@
+#ifndef _LYNQ_ALARM_H_
+#define _LYNQ_ALARM_H_
+
+
+#include<stdio.h>
+#include<stdlib.h>
+#include<regex.h>
+#include<stdbool.h>
+#include<time.h>
+#include<string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+ssize_t wakealarm(char *buffer);
+
+ssize_t poweralarm(char *buffer);
+
+int cancel_wakealarm(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/IC_src/mtk/lib/libpoweralarm/libpoweralarm.c b/IC_src/mtk/lib/libpoweralarm/libpoweralarm.c
new file mode 100755
index 0000000..aeb3933
--- /dev/null
+++ b/IC_src/mtk/lib/libpoweralarm/libpoweralarm.c
@@ -0,0 +1,124 @@
+#include<stdio.h>
+#include<stdlib.h>
+#include<unistd.h>
+#include<stdbool.h>
+#include<log/log.h>
+#include"./include/lynq_alarm.h"
+#include"format_change.h"
+
+#define LOG_TAG "libpoweralarm" 
+#define RTCFILE_POWERALARM "/sys/class/rtc/rtc0/poweralarm"
+
+#define RTCFILE_WAKEALARM "/sys/class/rtc/rtc0/wakealarm"
+
+
+/*****************************************************************************
+* 
+*   Prototype    : poweralarm
+*   Description  : set shutdown wake-up alarm clock 
+*   Input        : char *buffer ;  input format : 04-23-15-30-00 ( Mon-Day-Hour-Min-Sec ) Or  1200 ( seconds )              
+*   Output       : None
+*   Return Value : -1: error ; >0: set to wake up the devices after seconds
+*
+*****************************************************************************/
+
+ssize_t poweralarm(char *buffer)
+{
+    ssize_t sec;
+    char *time_buff = NULL;
+
+    sec = format_change(buffer); //computing seconds for shutdown alarm
+    if(sec < 60)
+    {
+        ALOGI("No Mattch\n");
+        return -1;
+    }
+    
+    time_buff = (char*)malloc(100);
+    bzero(time_buff,100);
+
+    sprintf(time_buff,"echo +%ld > %s",sec,RTCFILE_POWERALARM); //write formatted data into time_buff
+    system(time_buff);
+    ALOGI(time_buff);
+
+    free(time_buff);
+
+    return sec; // wake-up devices after sec seconds
+}
+
+
+/*****************************************************************************
+*   Prototype    : wakealarm
+*   Description  : set the wake-up alarm clock in low power mode
+*   Input        : char *buffer ;  input format : 04-23-15-30-00 ( Mon-Day-Hour-Min-Sec ) Or  1200 ( seconds )
+*   Output       : None
+*   Return Value : -1: error ; >0: set to wake up the devices after seconds
+*
+*****************************************************************************/
+ssize_t wakealarm(char *buffer)
+{
+    ssize_t sec;
+    char *time_buff = NULL;
+    int ret;
+    sec = format_change(buffer); //computing seconds for lowpower alarm
+    if(sec < 60)
+    {
+        ALOGI("No Mattch\n");
+        return -1;
+    }
+    ret = system("echo +0 > /sys/class/rtc/rtc0/wakealarm");
+    RLOGD("close wakealarm ret= %d\n", ret);
+    time_buff = (char*)malloc(100);
+    bzero(time_buff,100);
+
+    sprintf(time_buff,"echo +%ld > %s",sec,RTCFILE_WAKEALARM); //write formatted data into time_buff
+    system(time_buff);
+    ALOGI(time_buff);
+
+    free(time_buff);
+
+    return sec; // wake-up devices after sec seconds
+}
+
+
+/*****************************************************************************
+*   Prototype    : cancel wakealarm
+*   Description  : cancel the wake-up alarm clock in low power mode
+*   Input        : void
+*   Output       : int
+*   Return Value : -1: error ; 0: cannel wakealarm success
+*
+*****************************************************************************/
+
+int cancel_wakealarm(void)
+{
+    int ret;
+    ret = system("echo +0 > /sys/class/rtc/rtc0/wakealarm");
+    ret = system("echo +315360000 > /sys/class/rtc/rtc0/wakealarm");
+    RLOGD("close wakealarm ret= %d\n", ret);
+    return ret;
+
+}
+
+/*****************************************************************************
+*   Prototype    : check wake up by rtc
+*   Description  : check weather AP is waked up by RTC
+*   Input        : void
+*   Output       : int
+*   Return Value : 1: AP is waked up by rtc ; 0: AP is not waked up by rtc
+*
+*****************************************************************************/
+
+int check_wakeupbydtr(void)
+{
+    FILE *fp;
+    char buf[4];
+    int ret;
+    fp = popen("cat /proc/driver/rtc_wakeup","r");
+    fgets(buf, sizeof(buf), fp);
+    RLOGD("buf=%s\n", buf);
+    ret=atoi(buf);
+    pclose(fp);
+    return ret;
+
+}
diff --git a/IC_src/mtk/lib/libpoweralarm/makefile b/IC_src/mtk/lib/libpoweralarm/makefile
new file mode 100644
index 0000000..3cdf04f
--- /dev/null
+++ b/IC_src/mtk/lib/libpoweralarm/makefile
@@ -0,0 +1,69 @@
+SHELL = /bin/sh
+RM = rm -f
+
+LOCAL_CFLAGS := -Wall \
+                -std=gnu++14 \
+                -g -Os \
+                -flto \
+                -DRIL_SHLIB \
+                -DATCI_PARSE \
+                -fPIC \
+                -DKEEP_ALIVE \
+                -DECALL_SUPPORT \
+               
+
+
+
+$(warning ################# libautosuspend ROOT: $(ROOT),includedir:$(includedir))
+LOCAL_PATH   = .
+
+LOCAL_C_INCLUDES = \
+  -I. \
+  -I$(ROOT)$(includedir)/logger \
+  -I$(ROOT)$(includedir)/liblog \
+
+
+LOCAL_LIBS := \
+    -L. \
+    -ldl \
+    -lstdc++ \
+    -llog \
+    -lcutils \
+    -lutils \
+    -lbinder \
+    -lpthread \
+    -llynq-log \
+
+
+SOURCES = $(wildcard *.c)
+
+EXECUTABLE = libpoweralarm.so
+
+OBJECTS=$(SOURCES:.c=.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 : %.c
+	$(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