Add basic change for v1453

Change-Id: I9497a61bbc3717f66413794a4e7dee0347c0bc33
diff --git a/mbtk/mbtk_at/src/factory/mbtk_adc.c b/mbtk/mbtk_at/src/factory/mbtk_adc.c
new file mode 100755
index 0000000..9f0913c
--- /dev/null
+++ b/mbtk/mbtk_at/src/factory/mbtk_adc.c
@@ -0,0 +1,195 @@
+/**
+ *   \file mbtk_adc.c
+ *   \brief A Documented file.
+ *
+ *  Detailed description
+ *   \Author:  js.wang <js.wang@mobiletek.cn>
+ *   \Version: 1.0.0
+ *   \Date: 2022-04-22
+ */
+#include <fcntl.h>
+#include <stdint.h>
+#include <limits.h>
+#include <termios.h>
+#include <stdarg.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <sys/statfs.h>
+#include <sys/types.h>
+#include <stdio.h>
+// #include "mbtk_log.h"
+//#include "mbtk_type.h"
+#include "mbtk_adc.h"
+
+#define ADC_DEVICE_802 "/sys/devices/soc.0/d4000000.apb/pxa2xx-i2c.2/i2c-2/2-0030/pm802-bat/adc"
+#define ADC_DEVICE_803 "/sys/kernel/debug/adc"
+#define ADC_DEVICE_PMIC802 "/sys/devices/platform/asr-adc/pm80x_adc"
+#define ADC_DEVICE_AUX "/sys/devices/platform/asr-adc/aux_adc"
+
+void mbtk_log(int level, const char *format, ...);
+
+#define LOG_DEBUG_LEVEL 5
+#define LOG(fmt, args...) mbtk_log(LOG_DEBUG_LEVEL, fmt, ##args)
+
+int mbtk_adc_close(void)
+{
+    int ret = 0;
+    int fd = 0;
+    char adc = '3';
+    //system("echo 3 > /sys/kernel/debug/adc");
+    if(!access(ADC_DEVICE_803, R_OK))
+    {
+        //LOGI("DEV:%s", ADC_DEVICE_803);
+        fd = open(ADC_DEVICE_803, O_RDWR|O_CREAT|O_TRUNC, 0644);
+    }
+    else
+    {
+        LOG("No found ADC devices.");
+        return -1;
+    }
+
+    if(fd < 0) {
+        LOG("[%s]  file open error\n", __FUNCTION__);
+        return -2;
+    }
+    ret = write(fd, &adc, 1);
+    if (ret < 0) {
+        LOG("%s: error writing to file!\n", __FUNCTION__);
+        close(fd);
+        return -2;
+    }
+    close(fd);
+    return 0;
+}
+
+int mbtk_adc_get(mbtk_adc_enum channle)
+{
+    int ret = 0;
+    int fd = 0;
+    char adc_buf[24] = {0};
+    char *adc_value = NULL;
+    char adc =(channle == MBTK_ADC0 ? '0' : (channle == MBTK_ADC1 ? '1' : '2'));
+
+#if defined(MBTK_PROJECT_L508_X6)
+    switch(channle)
+    {
+        case MBTK_ADC0:
+        case MBTK_ADC1:
+        {
+            if(!access(ADC_DEVICE_PMIC802, R_OK))
+            {
+                LOG("[adc] DEV:%s", ADC_DEVICE_PMIC802);
+                fd = open(ADC_DEVICE_PMIC802, O_RDWR|O_CREAT|O_TRUNC, 0644);
+            }
+            else
+            {
+                LOG("No found ADC devices.");
+                return -1;
+            }
+            break;
+        }
+        case MBTK_ADC2:
+        {
+            if(!access(ADC_DEVICE_AUX, R_OK))
+            {
+                LOG("[adc] DEV:%s", ADC_DEVICE_AUX);
+                fd = open(ADC_DEVICE_AUX, O_RDWR|O_CREAT|O_TRUNC, 0644);
+            }
+            else
+            {
+                LOG("No found ADC devices.");
+                return -1;
+            }
+            break;
+        }
+        default:
+        {
+            LOG("channle is error.");
+            return -1;
+        }
+    }
+#elif defined(MBTK_PROJECT_T108)
+    if(!access(ADC_DEVICE_AUX, R_OK))
+    {
+        LOG("[adc] DEV:%s", ADC_DEVICE_AUX);
+        fd = open(ADC_DEVICE_AUX, O_RDWR|O_CREAT|O_TRUNC, 0644);
+    }
+    else
+    {
+        LOG("No found ADC devices.");
+        return -1;
+    }
+#else
+#if 0
+    if(!access(ADC_DEVICE_802, R_OK)) {
+        //LOGI("DEV:%s", ADC_DEVICE_802);
+        fd = open(ADC_DEVICE_802, O_RDWR|O_CREAT|O_TRUNC, 0644);
+    } else {
+        if(!access(ADC_DEVICE_803, R_OK)) {
+            //LOGI("DEV:%s", ADC_DEVICE_803);
+            fd = open(ADC_DEVICE_803, O_RDWR|O_CREAT|O_TRUNC, 0644);
+        } else {
+            LOGE("No found ADC devices.");
+            return -1;
+        }
+    }
+#endif
+    if(!access(ADC_DEVICE_PMIC802, R_OK))
+    {
+            //LOGI("DEV:%s", ADC_DEVICE_803);
+            fd = open(ADC_DEVICE_PMIC802, O_RDWR|O_CREAT|O_TRUNC, 0644);
+    }
+    else
+    {
+            LOG("No found ADC devices.");
+            return -1;
+    }
+#endif
+
+    if(fd < 0) {
+        LOG("[%s]  file open error\n", __FUNCTION__);
+        return -2;
+    }
+    ret = write(fd, &adc, 1);
+    if (ret < 0) {
+        LOG("%s: error writing to file!\n", __FUNCTION__);
+        close(fd);
+        return -2;
+    }
+    ret = read(fd, adc_buf, 24);
+    if (ret < 0) {
+        LOG("%s: error writing to file!\n", __FUNCTION__);
+        close(fd);
+        return -2;
+    }else{
+        //LOGI("%s %d adc:%s\n", __FUNCTION__, __LINE__, adc_buf);
+        adc_value = strstr(adc_buf, "channel");
+    }
+    close(fd);
+    if(adc_value)
+    {
+        //LOGI("%s adc: %s\n", __FUNCTION__, adc_value);
+    }
+    else
+        return -2;
+
+    return atoi(&adc_value[9]);
+}
+
+int mbtk_at_adc(int value)
+{
+    if(0 != value && 1 != value && 2 != value){
+        return -1;
+    }
+
+#if (defined(MBTK_PROJECT_L508_X6) || defined(MBTK_PROJECT_T108))
+    //NULL
+#else
+    if(value == 2)
+    {
+        return mbtk_adc_close();
+    }
+#endif
+
+    return mbtk_adc_get((mbtk_adc_enum)value);
+}
\ No newline at end of file
diff --git a/mbtk/mbtk_at/src/factory/mbtk_audio.c b/mbtk/mbtk_at/src/factory/mbtk_audio.c
new file mode 100755
index 0000000..10ff992
--- /dev/null
+++ b/mbtk/mbtk_at/src/factory/mbtk_audio.c
@@ -0,0 +1,86 @@
+//#include "mbtk_audio2.h"
+//#include "mbtk_audio_ubus.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "telutl.h"
+#include "mbtk_at.h"
+
+#define AUD_DEMO_WAV "/user_data/demo.wav"
+
+typedef enum {
+    MBTK_AUDIO_SAMPLE_RATE_8000 = 0,
+    MBTK_AUDIO_SAMPLE_RATE_16000
+} mbtk_audio_sample_rate_enum;
+
+
+int mbtk_at_loopback(int type)
+{
+    LOG("mbtk_at_loopback() : type - %d", type);
+    if(0 == type) // Stop
+    {
+        if(MBTK_FUNC(mbtk_audio_loopback_stop)()) {
+            return -1;
+        }
+
+        MBTK_FUNC(mbtk_audio_ubus_deinit)();
+    }
+    else // Start
+    {
+        MBTK_FUNC(mbtk_audio_ubus_init)();
+
+        MBTK_FUNC(mbtk_audio_mode_set)(0);
+        MBTK_FUNC(mbtk_audio_loopback_start)(2);
+    }
+
+    return 0;
+}
+
+int mbtk_at_play(const char *args)
+{
+    int ret = 0;
+    if(MBTK_FUNC(mbtk_audio_wav_init)()) {
+        LOG("mbtk_audio_wav_init() fail.");
+        return -1;
+    }
+
+    if(MBTK_FUNC(mbtk_audio_wav_play_start)(AUD_DEMO_WAV)) {
+        LOG("mbtk_audio_wav_play_start() fail.");
+        ret = -1;
+        goto exit;
+    }
+
+    sleep(5);
+
+exit:
+    if(MBTK_FUNC(mbtk_audio_wav_deinit)()) {
+        LOG("mbtk_audio_wav_deinit() fail.");
+        return -1;
+    }
+
+    return ret;
+}
+
+int mbtk_at_rec(const char *args)
+{
+    int ret = 0;
+    if(MBTK_FUNC(mbtk_audio_wav_init)()) {
+        LOG("mbtk_audio_wav_init() fail.");
+        return -1;
+    }
+
+    if(MBTK_FUNC(mbtk_audio_wav_recorder_start)(AUD_DEMO_WAV, MBTK_AUDIO_SAMPLE_RATE_8000)) {
+        LOG("mbtk_audio_wav_recorder_start() fail.");
+        ret = -1;
+        goto exit;
+    }
+
+    sleep(5);
+
+exit:
+    if(MBTK_FUNC(mbtk_audio_wav_deinit)()) {
+        LOG("mbtk_audio_wav_deinit() fail.");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/mbtk/mbtk_at/src/factory/mbtk_gpio.c b/mbtk/mbtk_at/src/factory/mbtk_gpio.c
new file mode 100755
index 0000000..df94926
--- /dev/null
+++ b/mbtk/mbtk_at/src/factory/mbtk_gpio.c
@@ -0,0 +1,2006 @@
+/**
+ *   \file gpio-test.c
+ *   \brief A Documented file.
+ *
+ *  Detailed description
+ *   \Author:  Sniper <js.wang@mobiletek.cn>
+ *   \Version: 1.0.0
+ *   \Date: 2022-04-26
+ */
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <limits.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <sys/mount.h>
+#include <sys/mman.h>
+#include <ctype.h>
+#include <stdbool.h>
+#include <cutils/properties.h>
+#include "mbtk_gpio_def.h"
+#include "gpio-define.h"
+
+#ifndef TRUE
+#define TRUE   1   /* Boolean true value. */
+#endif
+
+#ifndef FALSE
+#define FALSE  0   /* Boolean false value. */
+#endif
+
+#define gpio_log(...)     if(gpio_debug)printf(__VA_ARGS__)
+#define HWMAP_DEVICE "/dev/hwmap"
+#define PAGE_OFFS_BITS(pgsz) ((unsigned int)(pgsz)-1)
+#define PAGE_MASK_BITS(pgsz) (~PAGE_OFFS_BITS(pgsz))
+#define STR_MAX_LEN 220
+typedef enum {
+    MBTK_ADC0 = 0,  /* ADC 0 */
+    MBTK_ADC1       /* ADC 1 */
+} mbtk_adc_enum;
+
+static int gpio_debug = 0;
+#define DEBUG_GPIO_TEST 1
+
+/**/
+#define GPIO_MAX_CURRENT     (7<<10)  //设置GPIO最大输出电流
+#define GPIO_STRONG_PULLUP   (1<<3)   //设置GPIO强上拉
+#define GPIO_PULLUP_ENABLE   ((1<<15)|(1<<14)) //GPIO上拉
+#define GPIO_PULLDOWN_ENABLE ((1<<15)|1<<13) //GPIO下拉
+
+#define MBTK_GPIO_OUTPUT 1
+#define MBTK_GPIO_INPUT  0
+
+#if (defined(MBTK_PROJECT_L508_X6) || defined(MBTK_PROJECT_T108))
+struct gpio_register_function gpio_func_register[128] = {
+    {GPIO_FUNC_GPIO_00, 0},
+    {GPIO_FUNC_GPIO_01, 0},
+    {GPIO_FUNC_GPIO_02, 0},
+    {GPIO_FUNC_GPIO_03, 0},
+    {GPIO_FUNC_GPIO_04, 0},
+    {GPIO_FUNC_GPIO_05, 0},
+    {GPIO_FUNC_GPIO_06, 0},
+    {GPIO_FUNC_GPIO_07, 0},
+    {GPIO_FUNC_GPIO_08, 0},
+    {GPIO_FUNC_GPIO_09, 0},
+    {GPIO_FUNC_GPIO_10, 0},
+    {GPIO_FUNC_GPIO_11, 0},
+    {GPIO_FUNC_GPIO_12, 0},
+    {GPIO_FUNC_GPIO_13, 0},
+    {GPIO_FUNC_GPIO_14, 0},
+    {GPIO_FUNC_GPIO_15, 0},
+    {GPIO_FUNC_GPIO_16, 0},
+    {GPIO_FUNC_GPIO_17, 0},
+    {GPIO_FUNC_GPIO_18, 0},
+    {GPIO_FUNC_GPIO_19, 0},
+    {GPIO_FUNC_GPIO_20, 0},
+    {GPIO_FUNC_GPIO_21, 0},
+    {GPIO_FUNC_GPIO_22, 0},
+    {GPIO_FUNC_GPIO_23, 0},
+    {GPIO_FUNC_GPIO_24, 0},
+    {GPIO_FUNC_GPIO_25, 0},
+    {GPIO_FUNC_GPIO_26, 0},
+    {GPIO_FUNC_GPIO_27, 0},
+    {GPIO_FUNC_GPIO_28, 0},
+    {GPIO_FUNC_GPIO_29, 0},
+    {GPIO_FUNC_GPIO_30, 0},
+    {GPIO_FUNC_GPIO_31, 0},
+    {GPIO_FUNC_GPIO_32, 0},
+    {GPIO_FUNC_GPIO_33, 0},
+    {GPIO_FUNC_GPIO_34, 0},
+    {GPIO_FUNC_GPIO_35, 0},
+    {GPIO_FUNC_GPIO_36, 0},
+	{GPIO_FUNC_GPIO_37, 0}, // GPIO_37
+    {GPIO_FUNC_GPIO_38, 0}, // GPIO_38
+    {GPIO_FUNC_GPIO_39, 0}, // GPIO_39
+    {GPIO_FUNC_GPIO_40, 0}, // GPIO_40
+    {GPIO_FUNC_GPIO_41, 0},  //GPIO_41
+    {GPIO_FUNC_GPIO_42, 0},  //GPIO_42
+    {GPIO_FUNC_GPIO_43, 0},  //GPIO_43
+    {GPIO_FUNC_GPIO_44,0},	//GPIO_44
+	{GPIO_FUNC_GPIO_45,0},	//GPIO_45
+	{GPIO_FUNC_GPIO_46,0},		//GPIO_46
+	{GPIO_FUNC_GPIO_47,0},		//GPIO_47
+    {GPIO_FUNC_SDIO_DAT3, 1}, //GPIO_48
+    {GPIO_FUNC_GPIO_49, 0},
+    {GPIO_FUNC_GPIO_50, 0},
+    {GPIO_FUNC_GPIO_51, 0},
+    {GPIO_FUNC_GPIO_52, 0},
+    {GPIO_FUNC_GPIO_53, 0},
+    {GPIO_FUNC_GPIO_54, 0},
+    {GPIO_FUNC_SDIO_DAT2, 1}, //GPIO_55
+    {GPIO_FUNC_SDIO_DAT1, 1}, //GPIO_56
+    {GPIO_FUNC_SDIO_DAT0, 1}, //GPIO_57
+    {GPIO_FUNC_SDIO_CMD, 1},  //GPIO_58
+    {GPIO_FUNC_SDIO_CLK, 1},  //GPIO_59
+    {GPIO_FUNC_GPIO_60, 0},
+    {0,0},{0,0},{0,0},{0,0},
+    {0,0},{0,0},
+    {GPIO_FUNC_DVL_0, 1},//GPIO_67
+    {GPIO_FUNC_DVL_1, 1},//GPIO_68
+    {GPIO_FUNC_GPIO_69, 0},
+    {GPIO_FUNC_GPIO_70, 0},
+    {GPIO_FUNC_QSPI_DAT3, 1}, //GPIO_71
+    {GPIO_FUNC_QSPI_DAT2, 1}, //GPIO_72
+    {GPIO_FUNC_QSPI_DAT1, 1}, //GPIO_73
+    {GPIO_FUNC_QSPI_DAT0, 1}, //GPIO_74
+    {GPIO_FUNC_QSPI_CLK, 1},  //GPIO_75
+    {GPIO_FUNC_QSPI_CS1, 1},  //GPIO_76
+    {GPIO_FUNC_GPIO_77, 0},
+    {GPIO_FUNC_GPIO_78, 0},
+    {GPIO_FUNC_GPIO_79, 0},
+    {GPIO_FUNC_GPIO_80, 0},
+    {GPIO_FUNC_USIM_UCLK, 1},//GPIO_81
+    {GPIO_FUNC_USIM_UIO, 1},//GPIO_82
+    {GPIO_FUNC_USIM_URSTn, 1},//GPIO_83
+
+    {GPIO_FUNC_MMC1_DAT3,5},			//GPIO_84
+	{GPIO_FUNC_MMC1_DAT2,5},			//GPIO_85
+	{GPIO_FUNC_MMC1_DAT1,5},			//GPIO_86
+	{GPIO_FUNC_MMC1_DAT0,5},			//GPIO_87
+    {GPIO_FUNC_MMC1_CMD,5},			//GPIO_88
+	{GPIO_FUNC_MMC1_CLK,5},			//GPIO_89
+	{GPIO_FUNC_MMC1_CD,1},						//GPIO_90
+	{0,0},
+    {0,0},{0,0},{0,0},{0,0},
+    {0,0},{0,0},{0,0},
+    {GPIO_FUNC_USB_ID, 1},//GPIO_99
+    {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},
+    {GPIO_FUNC_PRI_TDI, 1},         //GPIO_117
+    {GPIO_FUNC_PRI_TMS, 1},         //GPIO_118
+    {GPIO_FUNC_PRI_TCK, 1},         //GPIO_119
+    {GPIO_FUNC_PRI_TDO, 1},         //GPIO_120
+    {GPIO_FUNC_QSPI_VMODE_GPIO, 1}, //GPIO_121
+    {GPIO_FUNC_VBUS_DRV, 1},        //GPIO_122
+    {GPIO_FUNC_CLK_REQ, 1},         //GPIO_123
+    {0,0},
+    {GPIO_FUNC_VCXO_REQ, 1},        //GPIO_125
+	{0,0},							//GPIO_126
+    {GPIO_FUNC_VCXO_OUT, 1},        //GPIO_127
+    {0,0},
+};
+
+#else
+struct gpio_register_function gpio_func_register[128] = {
+    {GPIO_FUNC_GPIO_00, 0},
+    {GPIO_FUNC_GPIO_01, 0},
+    {GPIO_FUNC_GPIO_02, 0},
+    {GPIO_FUNC_GPIO_03, 0},
+    {GPIO_FUNC_GPIO_04, 0},
+    {GPIO_FUNC_GPIO_05, 0},
+    {GPIO_FUNC_GPIO_06, 0},
+    {GPIO_FUNC_GPIO_07, 0},
+    {GPIO_FUNC_GPIO_08, 0},
+    {GPIO_FUNC_GPIO_09, 0},
+    {GPIO_FUNC_GPIO_10, 0},
+    {GPIO_FUNC_GPIO_11, 0},
+    {GPIO_FUNC_GPIO_12, 0},
+    {GPIO_FUNC_GPIO_13, 0},
+    {GPIO_FUNC_GPIO_14, 0},
+    {GPIO_FUNC_GPIO_15, 0},
+    {GPIO_FUNC_GPIO_16, 0},
+    {GPIO_FUNC_GPIO_17, 0},
+    {GPIO_FUNC_GPIO_18, 0},
+    {GPIO_FUNC_GPIO_19, 0},
+    {GPIO_FUNC_GPIO_20, 0},
+    {GPIO_FUNC_GPIO_21, 0},
+    {GPIO_FUNC_GPIO_22, 0},
+    {GPIO_FUNC_GPIO_23, 0},
+    {GPIO_FUNC_GPIO_24, 0},
+    {GPIO_FUNC_GPIO_25, 0},
+    {GPIO_FUNC_GPIO_26, 0},
+    {GPIO_FUNC_GPIO_27, 0},
+    {GPIO_FUNC_GPIO_28, 0},
+    {GPIO_FUNC_GPIO_29, 0},
+    {GPIO_FUNC_GPIO_30, 0},
+    {GPIO_FUNC_GPIO_31, 0},
+    {GPIO_FUNC_GPIO_32, 0},
+    {GPIO_FUNC_GPIO_33, 0},
+    {GPIO_FUNC_GPIO_34, 0},
+    {GPIO_FUNC_GPIO_35, 0},
+    {GPIO_FUNC_GPIO_36,   0},
+    {GPIO_FUNC_MMC1_DAT3, 5}, // GPIO_37
+    {GPIO_FUNC_MMC1_DAT2, 5}, // GPIO_38
+    {GPIO_FUNC_MMC1_DAT1, 5}, // GPIO_39
+    {GPIO_FUNC_MMC1_DAT0, 5}, // GPIO_40
+    {GPIO_FUNC_MMC1_CMD, 5},  //GPIO_41
+    {GPIO_FUNC_MMC1_CLK, 5},  //GPIO_42
+    {GPIO_FUNC_MMC1_CD , 1},  //GPIO_43
+    {0,0},{0,0},{0,0},{0,0},
+    {GPIO_FUNC_SDIO_DAT3, 1}, //GPIO_48
+    {GPIO_FUNC_GPIO_49, 0},
+    {GPIO_FUNC_GPIO_50, 0},
+    {GPIO_FUNC_GPIO_51, 0},
+    {GPIO_FUNC_GPIO_52, 0},
+    {GPIO_FUNC_GPIO_53, 0},
+    {GPIO_FUNC_GPIO_54, 0},
+    {GPIO_FUNC_SDIO_DAT2, 1}, //GPIO_55
+    {GPIO_FUNC_SDIO_DAT1, 1}, //GPIO_56
+    {GPIO_FUNC_SDIO_DAT0, 1}, //GPIO_57
+    {GPIO_FUNC_SDIO_CMD, 1},  //GPIO_58
+    {GPIO_FUNC_SDIO_CLK, 1},  //GPIO_59
+    {GPIO_FUNC_GPIO_60, 0},
+    {0,0},{0,0},{0,0},{0,0},
+    {0,0},{0,0},
+    {GPIO_FUNC_DVL_0, 1},//GPIO_67
+    {GPIO_FUNC_DVL_1, 1},//GPIO_68
+    {GPIO_FUNC_GPIO_69, 0},
+    {GPIO_FUNC_GPIO_70, 0},
+    {GPIO_FUNC_QSPI_DAT3, 1}, //GPIO_71
+    {GPIO_FUNC_QSPI_DAT2, 1}, //GPIO_72
+    {GPIO_FUNC_QSPI_DAT1, 1}, //GPIO_73
+    {GPIO_FUNC_QSPI_DAT0, 1}, //GPIO_74
+    {GPIO_FUNC_QSPI_CLK, 1},  //GPIO_75
+    {GPIO_FUNC_QSPI_CS1, 1},  //GPIO_76
+    {GPIO_FUNC_GPIO_77, 0},
+    {GPIO_FUNC_GPIO_78, 0},
+    {GPIO_FUNC_GPIO_79, 0},
+    {GPIO_FUNC_GPIO_80, 0},
+    {GPIO_FUNC_USIM_UCLK, 1},//GPIO_81
+    {GPIO_FUNC_USIM_UIO, 1},//GPIO_82
+    {GPIO_FUNC_USIM_URSTn, 1},//GPIO_83
+    {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},
+    {GPIO_FUNC_USB_ID, 1},//GPIO_99
+    {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},
+    {GPIO_FUNC_PRI_TDI, 1},         //GPIO_117
+    {GPIO_FUNC_PRI_TMS, 1},         //GPIO_118
+    {GPIO_FUNC_PRI_TCK, 1},         //GPIO_119
+    {GPIO_FUNC_PRI_TDO, 1},         //GPIO_120
+    {GPIO_FUNC_QSPI_VMODE_GPIO, 1}, //GPIO_121
+    {GPIO_FUNC_VBUS_DRV, 1},        //GPIO_122
+    {GPIO_FUNC_CLK_REQ, 1},         //GPIO_123
+    {0,0},
+    {GPIO_FUNC_VCXO_REQ, 1},        //GPIO_125
+    {GPIO_FUNC_VCXO_OUT, 1},        //GPIO_126
+    {0,0},
+};
+
+#endif
+
+static int mbtk_gpio_adc(channel)
+{
+    int ret = 0;
+
+    ret =  mbtk_adc_get(channel);
+#if DEBUG_GPIO_TEST
+    printf("ADC_%d_value =%d\n", channel, ret);
+#endif
+    if(ret >= 500 ){	//TODO: 各项目高电平标准?
+        ret = 1;
+    }
+    else if (ret>=0 && ret<=480){
+        ret = 0;
+    }
+    else{
+        ret = -1;
+    }
+    return ret;
+}
+
+
+static int hwacc_register(int rw, unsigned int addr, unsigned int *data)
+{
+	int fid;
+	unsigned int pagesize, len, len_aligned;
+	unsigned int addr_aligned;
+	volatile unsigned int *pa;
+	void *vpa;
+
+	len = pagesize = sysconf(_SC_PAGESIZE);
+	if((fid = open(HWMAP_DEVICE, O_RDWR)) < 0)
+	{
+		printf("Failed to open %s\n", HWMAP_DEVICE);
+		exit(-1);
+	}
+
+	// Align the length so the mapped area is page-aligned and contains the requested area
+	addr_aligned = addr & PAGE_MASK_BITS(pagesize);
+	len_aligned =((addr + len - addr_aligned) + pagesize - 1) & PAGE_MASK_BITS(pagesize);
+
+	/* Notes on flags: MAP_PRIVATE results in copy on write; MAP_SHARED allows normal write */
+	/*   MAP_SHARED required O_RDWR in open above, otherwise mmap fails with errno=EACCES   */
+	/* Notes on prot:  PROT_WRITE allows read and write; PROT_READ allows read only         */
+	/* Notes on off: an unsigned 32-bit value, should be aligned to page size according to mmap manpage */
+	if((vpa = mmap(0, len_aligned, PROT_READ|PROT_WRITE, MAP_SHARED, fid, addr_aligned)) == MAP_FAILED)
+	{
+		printf("mmap failed (%d)\n", errno);
+	}
+	else
+	{
+		pa = (volatile unsigned int *)((unsigned char *)vpa + (addr & PAGE_OFFS_BITS(pagesize)));
+		if(rw == 0)
+		{
+			*data = *pa;
+			gpio_log("Value read from 0x%.8x via MVA=0x%p is 0x%.8x\n", addr, pa, *data);
+		}
+		else if(rw == 1)
+		{
+			*pa = *data;
+			gpio_log("Value %.8x written to 0x%.8x via MVA=0x%p\n", *data, addr, pa);
+#if defined(HWACC_DEBUG)
+			{
+				unsigned int val;
+				val = *pa;
+				printf("Value read from 0x%.8x via MVA=0x%p is 0x%.8x\n", addr, pa, val);
+			}
+#endif
+		}
+		munmap(vpa, len);
+	}
+
+	close(fid);
+	return 0;
+}
+/*
+设置GPIO 模式:第一步读GPIO22默认function
+root@OpenWrt:/# hwacc r 0xd401e134
+Option = r Addr = d401e134
+Value read from 0xd401e134 via MVA=0x0xb6fc3134 is 0x0000d040   //默认GPIO功能
+Bit0~bit2值对应上面表格各function,0代表GPIO功能
+ */
+static int gpio_register_read(int reg)
+{
+    int ret = -1;
+#if 0
+    FILE * fp;
+    // "/bin/hwacc r 0xd401e134";
+    char command[36] = {0};
+    char buffer[1024];
+    int i = 0;
+
+    sprintf(command, "/bin/hwacc r 0x%x", reg);
+    fp = popen(command, "r");
+    while(1)
+    {
+        if( fgets (buffer, sizeof(buffer), fp)!=NULL ) {
+            buffer[strlen(buffer) - 1] = 0;
+            // gpio_log("out [%d]: %s\n", strlen(buffer), buffer);
+        }else{
+            break;
+        }
+        i = strstr_n(buffer, "is");
+        if(i)
+        {
+            ret = str_to_hex(&buffer[i + 2]);
+            gpio_log("read 0x%x value:%s, %x\n", reg, &buffer[i + 2], ret);
+        }
+    }
+    pclose(fp);
+#else
+#ifndef MBTK_PROJECT_PN1803
+    usleep(50);
+#endif
+    hwacc_register(0, reg, &ret);
+#ifndef MBTK_PROJECT_PN1803
+    usleep(50);
+#endif
+#endif
+    return ret;
+}
+/*
+设置输入输出状态,设置PDR寄存器GPIO22为output
+root@OpenWrt:/# hwacc w 0xD401900c 0x00c03800
+Option = w Addr = d401900c Data=00c03800
+Value 00c03800 written to 0xd401900c via MVA=0x0xb6f9f00c
+ */
+static void gpio_register_write(int reg, int value)
+{
+#if 0
+    FILE * fp;
+    //  "/bin/hwacc w 0xD401900c 0x00c03800"
+    char command[36] = {0};
+    char buffer[1024];
+
+    sprintf(command, "/bin/hwacc w 0x%x 0x%x", reg, value);
+    gpio_log("command: %s\n", command);
+    fp = popen(command, "r");
+    while(1)
+    {
+        if( fgets (buffer, sizeof(buffer), fp)!=NULL ) {
+            gpio_log("%s\n", buffer);
+        }else{
+            break;
+        }
+    }
+    pclose(fp);
+
+#else
+#ifndef MBTK_PROJECT_PN1803
+    usleep(50);
+#endif
+    hwacc_register(1, reg, &value);
+#ifndef MBTK_PROJECT_PN1803
+    usleep(50);
+#endif
+#endif
+}
+/*
+AF SEL<p>This field is used for alternate function selection for a pin.
+It selects between the eight possible alternate functions for the pin.
+Alternate function 0 is always the reset case.
+
+<p>0x0 = Alternate function 0 (primary function at reset)
+<p>0x1 = Alternate function 1
+<p>0x2 = Alternate function 2
+<p>0x3 = Alternate function 3
+<p>0x4 = Alternate function 4
+<p>0x5 = Alternate function 5
+<p>0x6 = Alternate function 6
+<p>0x7 = Alternate function 7
+ */
+static int gpio_register_set_func_0(int port)
+{
+    int ret;
+    struct gpio_register_function *reg = NULL;
+    if(port > 128)
+        return -1;
+    reg = &gpio_func_register[port];
+    if(0 == reg->reg)
+        return -1;
+    ret = gpio_register_read(reg->reg);
+    if((ret & 0x7) != reg->func_gpio)
+    {
+        //printf("Gpio set func [%d] [0x%x]!\n", reg->func_gpio, (ret & 0xfffffff8) | reg->func_gpio);
+        gpio_register_write(reg->reg, (ret & 0xfffffff8) | reg->func_gpio);
+    }
+    return 0;
+}
+/*
+设置GPIO  方向
+读取输入输出状态,读PDR寄存器:0x0c
+root@OpenWrt:/# hwacc r 0xD401900c
+Option = r Addr = d401900c
+Value read from 0xd401900c via MVA=0x0xb6f3900c is 0x00803800  //bit22为0,代表Input
+ */
+static void gpio_register_set_direction(int port, int dir)
+{
+    int ret;
+    int reg = 0xD4019000;
+
+    if(port > (32 - 1))
+        reg = 0xD4019004;
+    if(port > (32 * 2 - 1))
+        reg = 0xD4019008;
+    if(port > (32 * 3 - 1))
+        reg = 0xD4019100;
+
+    reg += 0x0c;
+    port = port % 0x20;
+    ret = gpio_register_read(reg);
+    //printf("[Direction] reg_value=%x\n", ret);
+    // 设置 输出 0 && 1
+    if(!(ret & (0x1 << port)) && dir)
+    {
+        gpio_register_write(reg, ret | (0x1 << port));  //set the gpio bit
+        //printf("[Direction out] reg_value=%x\n",  gpio_register_read(reg));
+    }
+    // 设置 输入 1 && 0
+    if((ret & (0x1 << port)) && !dir)
+    {
+#if 1
+        gpio_register_write(reg, ret & (~(0x1 << port)));  //clear the gpio bit,mbtk_tanggaoyou
+#else
+	     gpio_register_write(reg, ret | !(0x1 << port)); //这是错误配置,实际没有任何作用,还是原来的值
+#endif
+        //printf("[Direction in] reg_value=%x\n",  gpio_register_read(reg));
+    }
+}
+/*
+设置GPIO 输出电平
+
+读取电平状态,先读PLR寄存器:0x00
+root@OpenWrt:/# hwacc r 0xD4019000
+Option = r Addr = d4019000
+Value read from 0xd4019000 via MVA=0x0xb6f1c000 is 0x81e82a30
+对应下面具体BIT
+1000 0001 1110 1000 0010 1010 0011 0000   BIT22默认电平高
+
+设置输出高:设置PSR寄存器:0x18(只写寄存器)
+root@OpenWrt:/# hwacc w 0xD4019018 0x400000
+Option = w Addr = d4019018 Data=00400000
+Value 00400000 written to 0xd4019018 via MVA=0x0xb6f56018 //bit22写1,输出高
+
+设置输出低:设置PCR寄存器:0x24
+root@OpenWrt:/# hwacc w 0xD4019024 0x400000
+Option = w Addr = d4019024 Data=00400000
+Value 00400000 written to 0xd4019024 via MVA=0x0xb6faa024   //Bit22写1,GPIO22输出低
+
+ */
+static void gpio_register_set_value(int port, int value)
+{
+    int ret;
+    int reg = 0xD4019000;
+
+    if(port > (32 - 1))
+        reg = 0xD4019004;
+    if(port > (32 * 2 - 1))
+        reg = 0xD4019008;
+    if(port > (32 * 3 - 1))
+        reg = 0xD4019100;
+
+    if(value)
+    {
+        reg += 0x18;
+    }
+    else
+        reg += 0x24;
+
+    port = port % 0x20;
+    ret = gpio_register_read(reg);
+    //printf("[Value] reg_value=%x\n", gpio_register_read(0xD4019004));
+    // 设置 高电平 0 && 1
+    if(value)
+    {
+        gpio_register_write(reg, ret | (0x1 << port));
+        //printf("[Value high] reg_value=%x\n", gpio_register_read(0xD4019004));
+        return;
+    }
+    // 设置 低电平 1 && 0
+    if(!(ret & (0x1 << port)) && !value)
+    {
+        gpio_register_write(reg, ret | (0x1 << port));
+        //printf("[Value low] reg_value=%x\n", gpio_register_read(0xD4019004));
+    }
+}
+/*
+读取电平状态,先读PLR寄存器:0x00
+root@OpenWrt:/# hwacc r 0xD4019000
+Option = r Addr = d4019000
+Value read from 0xd4019000 via MVA=0x0xb6f1c000 is 0x81e82a30
+对应下面具体BIT
+1000 0001 1110 1000 0010 1010 0011 0000   BIT22默认电平高
+ */
+static int gpio_register_get_value(int port)
+{
+    int ret = -1;
+    int reg = 0xD4019000;
+
+    if(port > (32 - 1))
+        reg = 0xD4019004;
+    if(port > (32 * 2 - 1))
+        reg = 0xD4019008;
+    if(port > (32 * 3 - 1))
+        reg = 0xD4019100;
+    port = port % 0x20;
+    ret = gpio_register_read(reg);
+    if(ret & (0x1 << port))
+    {
+        return 1;
+    }
+    return 0;
+}
+
+void gpio_debug_set(int enable)
+{
+    gpio_debug = enable;
+}
+
+
+
+#if defined(MBTK_PROJECT_PN1803)
+int gpio_register_test_out(int port, int value)
+{
+    int ret;
+    int i;
+    int valueh = 0;
+    int valuel = 1;
+
+    //printf("Gpio port [%d] test start!\n", port);
+    ret = gpio_register_set_func_0(port);           //设功能为GPIO
+    if(ret){
+        printf("gpio_port can't support!\n");
+        return -1;
+    }
+    gpio_register_set_direction(port, 1);           //设方向为输出
+    ret = gpio_register_get_value(port);
+    //printf("gpio default value is : %d.\n", ret);
+
+
+    //[High]
+    for(i = 0; i <= 10; i++){
+        gpio_register_set_value(port, 1);
+        usleep(50);
+        valueh = gpio_register_get_value(port);
+        //printf("set high? %d\n",valueh);
+        if(1 == valueh){
+            break;
+        }
+    }
+    //usleep(10000);
+    for(i = 0; i <= 35; i++){
+        ret = mbtk_gpio_adc(0);
+        usleep(3000);
+        if(1 == ret){
+            break;
+        }
+    }
+    if(1 != ret){
+        ret=-1;
+        goto exit;
+    }
+    printf("******gpio should is high: %d.******\n", ret);
+
+
+    //[Low]
+     usleep(200);
+     for(i = 0; i <= 10; i++){
+        gpio_register_set_value(port, 0);               //输出低
+        usleep(50);
+        valuel = gpio_register_get_value(port);
+        //printf("set low? %d\n",valuel);
+        if(0 == valuel){
+            break;
+        }
+    }
+    //usleep(10000);
+    for(i = 0; i <= 35; i++){
+        ret = mbtk_gpio_adc(0);
+        usleep(3000);
+        if(0 == ret){
+            break;
+        }
+    }
+    printf("******gpio should is low: %d.******\n", ret);
+    if(0 != ret){
+        ret=-1;
+        goto exit;
+    }
+
+exit:
+    //gpio_register_set_direction(port, 0);  //设方向为输入
+    return ret;
+}
+
+int mbtk_at_gpio(bool gnss_support, void* arg)
+{
+    int test_gpio[] = {
+     56, 55, 58, 57, 48, 59, 12, 20, 5, 43, 21,
+     49, 50, 27, 28, 26, 25, 16, 17, 15, 126, 125,
+      4,  0, 3, 18, 7, 6, 1, 2, /*54,*/ 19, 13,
+     32, 31, 23, 24, 22, /*122,*/ 33, 35, 36, 34, 14,
+     99,/* 53,*/ 37, 38, 39, 40, 41, 42};
+
+    int i, j, ret, total, n = 0;
+    int *fail_io = (int *)arg;
+    total = (sizeof(test_gpio)/sizeof(int));
+    //printf("Start test gpio total: %d\n", total);
+
+    /* [1 all gpio set to low] */
+    for(j = 0; j < 6 ; j++){
+        for(i = 0; i < total; i++){
+            gpio_register_set_func_0(test_gpio[i]);
+            gpio_register_set_direction(test_gpio[i], 1);
+            gpio_register_set_value(test_gpio[i], 0);
+        }
+      //usleep(10000);
+      for(i = 0; i <= 35; i++){
+          ret = mbtk_gpio_adc(0);
+          usleep(3000);
+          if(0 == ret){
+              break;
+          }
+      }
+      printf("pre set ADC: %d, times: %d\n",ret, j);
+      if(0 == ret){
+          break;
+      }
+    }
+	if(0 != ret){
+		printf("Fail, please retest");
+		return -1;
+	}
+
+
+    /* [2 GPIOTEST] */
+    for(i = 0; i < total; i++){
+        ret = gpio_register_test_out(test_gpio[i], 0);
+        if(-1 == ret){
+            printf("!!!!!!!!!!!!gpio [%d] test failed!!!!!!!!!!!!\n", test_gpio[i]);
+            fail_io[n] = test_gpio[i];
+            n++;
+        }else{
+            //printf("############gpio [%d] test success############\n", test_gpio[i]);
+        }
+    }
+    mbtk_adc_close();
+    return n;
+}
+
+#elif defined(MBTK_PROJECT_L508)
+
+
+#define READ_GPIO_NUM 22
+
+#define DEBUG_GPIO_TEST 1
+
+mbtk_gpio_test_pin_and_gpio *p_test_gpio =NULL;
+mbtk_gpio_test_pin_and_gpio *p_gnss_gpio = NULL;
+int test_gpio_group_total_pin = 0;
+int gnss_gpio_group_total_pin = 0;
+
+int gpio_test_set_group_pin_to_low(mbtk_gpio_test_pin_and_gpio *p_pin_group_array, int total_num)
+{
+    int i;
+    int gpio_num = 0;
+    int ret = 0;
+
+    if(p_pin_group_array == NULL)
+       return -1;
+
+	for(i=0; i < total_num; i++)
+	{
+       gpio_num = p_pin_group_array[i].gpio_num;
+	   ret += gpio_register_set_func_0(gpio_num);
+	   gpio_register_set_direction(gpio_num, MBTK_GPIO_OUTPUT);
+	   gpio_register_set_value(gpio_num, 0);
+	}
+	return ret;
+}
+
+
+int gpio_test_init(void)
+{
+	int i,j,ret;
+    int gpio_num = 0;
+
+
+
+
+	system("i2cset -y -f 2 0x31 0x12 0x46");
+	system("echo 53 > /sys/class/gpio/export");  //gnss uart rx
+	system("echo out > /sys/class/gpio/gpio53/direction");
+	system("echo 54 > /sys/class/gpio/export");//gnss uart tx
+	system("echo out > /sys/class/gpio/gpio54/direction");
+	system("echo 22 > /sys/class/gpio/export");//check pin
+
+	gpio_register_set_func_0(READ_GPIO_NUM);
+	gpio_register_set_direction(READ_GPIO_NUM, 1);	//输出
+
+	usleep(500);
+/*
+     GPIO22默认是上拉,如果改成GPIO输入模式,其PIN脚电压是高电平,必须改成下拉后GPIO22才处于低电平状态,否则测试PIN拉低失败
+*/
+	gpio_register_set_direction(READ_GPIO_NUM, MBTK_GPIO_INPUT);	//设置输入模式
+	gpio_register_write(GPIO_FUNC_GPIO_22,0xb040);  //PULL DOWN
+
+
+    gpio_test_set_group_pin_to_low(p_gnss_gpio,gnss_gpio_group_total_pin); //set all gnss reserver pin to low
+
+
+	/* [1 all gpio set to low] */
+    for(j = 0; j < 6 ; j++){
+         gpio_test_set_group_pin_to_low(p_test_gpio,test_gpio_group_total_pin);
+
+		for(i = 0; i <= 5; i++){
+			ret = gpio_register_get_value(READ_GPIO_NUM);
+			if(0 == ret){
+				break;
+			}
+			usleep(3000);
+		}
+
+		if(0 == ret){
+			break;
+		}
+	}
+
+	if(0 != ret){
+		printf("[GPIOTEST]set all low Fail, please retest\n");
+		return -1;
+	}
+	printf("[GPIOTEST]pre set SUCCESS\n");
+	return 0;
+}
+
+int gpio_test(void* arg,int index,mbtk_gpio_test_pin_and_gpio *p_pin_group_array,int total)
+{
+	int ret,i;
+	int *fail_io = (int *)arg;
+	int failed_num = index;
+	int gpio_num = 0;
+	int pin_num = 0;
+    bool falied_flag = FALSE;
+
+	for(i = 0; i < total; i++){
+        gpio_num = p_pin_group_array[i].gpio_num;
+		pin_num = p_pin_group_array[i].pin_num;
+		falied_flag = FALSE;
+
+#if DEBUG_GPIO_TEST
+		ret = gpio_register_get_value(gpio_num);
+		printf("[GPIOTEST]pin_num%d default value= %d\n", pin_num, ret);
+#endif
+
+		//set high
+		gpio_register_set_value(gpio_num, 1);
+
+#if DEBUG_GPIO_TEST
+		ret = gpio_register_get_value(gpio_num);
+		printf("[GPIOTEST]pin_num%d set high= %d\n", pin_num, ret);
+#endif
+		//get
+		ret = gpio_register_get_value(READ_GPIO_NUM);
+		if(1 != ret){
+            printf("[GPIOTEST]pin%d test high failed\n", pin_num);
+            falied_flag = TRUE;
+        }else{
+            printf("[GPIOTEST]pin[%d] test high success\n", pin_num);
+        }
+
+		//set low
+	    gpio_register_set_value(gpio_num, 0);
+#if DEBUG_GPIO_TEST
+		ret = gpio_register_get_value(gpio_num);
+		printf("[GPIOTEST]pin_num%d set low= %d\n", pin_num, ret);
+#endif
+		//get
+		ret = gpio_register_get_value(READ_GPIO_NUM);
+		if(0 != ret){
+            printf("[GPIOTEST]pin_num%d test low failed\n", pin_num);
+			falied_flag = TRUE;
+
+        }else{
+            printf("[GPIOTEST]pin_num%d test low success\n", pin_num);
+        }
+
+		if(falied_flag)
+		{
+            fail_io[failed_num] = p_pin_group_array[i].pin_num;
+#if DEBUG_GPIO_TEST
+		 printf("[GPIOTEST]NO.%d pin_num%d failed %d\n",i,pin_num, failed_num);
+#endif
+			failed_num++;
+		}
+	}
+	return failed_num;
+}
+
+
+int mbtk_at_gpio(bool gnss_support,void* arg)
+{
+	int n = 0;
+	mbtk_gpio_test_pin_and_gpio test_gpio[] =
+	{
+		//{GPIO , PIN}
+		{0,100}, //RMII_RX-DV
+		{1,101}, //RMII_RXD0
+		{2,102},//RMII_RXD1
+		{3,103},//RMII_CLK
+		{6,104},//RMII_TXD0
+		{7,105},//RMII_TXD1
+		{15,106},//RMII_TX_EN
+		{16,109},//RMII_MDC
+		{17,110},//RMII_MDIO
+		{18,107},//RMII_INT
+		{99,16},//USB_ID
+		{34,9}, //SPI0_CS
+		{36,8},//SPI0_TXD
+		{35,7},//SPI0_RXD
+		{33,6},//SPI0_CLK
+		{14,51}, //NET_LIGHT
+		{13,49}, //STATUS LED
+		{12,50},//WAKE_IN
+		{49,55}, //I2C SCL
+		{50,56}, //I2C SDA
+		{19,53}, //USIM_DET
+		{43,48}, //SD_DET
+		{118,52}, //WAKE OUT
+		{120,54}, //FLIGHT MODE
+
+
+		{20,45}, //NORMAL GPIO
+		{59,122},  //SDIO_CLK
+		{56,117}, //SDIO_DATA1
+		{55,118},//SDIO_DATA2
+		{58,119},//SDIO_CMD
+		{48,120},//SDIO_DATA3
+		{57,121},//SDIO_DATA0
+		{5,84}, //NORMAL GPIO
+		{4,30},//NORMAL GPIO
+		{21,28}, //NORMAL GPIO
+		{23,69}, //UART_RING
+		{24,70}, //UART_DCD
+		{27,73}, //PCM_OUT
+		{28,74}, //PCM_IN
+		{26,75}, //PCM_SYNC
+		{25,76}, //PCM_CLK
+
+		{126,112},//NORMAL GPIO or pwm3
+		{117,123},	//PWM
+		{125,116}, //CLK_REQ
+
+		//{54,114}, //debug uart2, no need be tested
+		//{53,115}, //debug uart2, no need be tested
+
+	};
+
+	mbtk_gpio_test_pin_and_gpio GNSS_test_gpio[] = {
+		{54,114}, //GPS UTXD, UART1_TXD,L508LAN+L508CN(D)+L508EN+L508LEN+L508TLCN NOT CONNECTED
+		{53,115}, //GPS URXD,UART1-RXD,L508LAN+L508CN(D)+L508EN+L508LEN+L508TLCN NOT CONNECTED
+		{32,66}, //PIN66,host wake GPS, RTS, L508TLCN_V2+L508LEN_V2+L508EN_V2 NOT CONNECTED
+		{31,67}, //PIN67,GPS wake Host,CTS, L508TLCN_V2+L508LEN_V2+L508EN_V2 NOT CONNECTED
+		{123,42},//GPS_EN, L508TLCN_V2+L508LEN_V2+L508EN_V2 NOT CONNECTED
+		{122,35},  //32K OUT, L508TLCN_V2+L508LEN_V2+L508EN_V2 not connected
+	};
+	p_gnss_gpio = GNSS_test_gpio;
+	gnss_gpio_group_total_pin = (sizeof(GNSS_test_gpio)/sizeof(GNSS_test_gpio[0]));
+
+    p_test_gpio = test_gpio;
+	test_gpio_group_total_pin = (sizeof(test_gpio)/sizeof(test_gpio[0]));
+
+   if(!gnss_support)
+       n = test_gpio_group_total_pin+gnss_gpio_group_total_pin;
+    else
+       n = test_gpio_group_total_pin;
+
+	printf("[init] L508 XX GPIOTEST v1.3 total pin=%d\n",n);
+
+	n = gpio_test_init();
+	if(-1 == n)
+	{
+		goto gpiotest_finished;
+	}
+    n = 0;
+
+	n = gpio_test(arg,0,p_test_gpio,test_gpio_group_total_pin);
+
+   //if the module has gnss chip, don't test the gnss's pins
+    if(!gnss_support)
+	{
+    	n = gpio_test(arg,n,p_gnss_gpio,gnss_gpio_group_total_pin);
+	}
+
+gpiotest_finished:
+	system("echo 53 > /sys/class/gpio/unexport"); //unexport gnss uart rx
+	system("echo 54 > /sys/class/gpio/unexport");//unexportgnss uart tx
+	system("echo 22 > /sys/class/gpio/unexport");//unexportcheck pin
+
+	printf("\n[GPIOTEST] Finished %d!!\n\n",n);
+	return n;
+}
+
+
+
+#elif defined(MBTK_PROJECT_L509)
+//测低
+static uint16 mbtk_gpio_test_all_low(mbtk_gpio_paired_info_struct *pin_array, uint16 MAX_pin_num)
+{
+    uint16 index = 0;
+    uint16 OUT_pin, Read_pin;
+    uint32 read_high_value;
+    uint32 read_low_value;
+    uint16 fail_num = 0;
+    //int res;
+
+    printf("[GPIOTEST][run test all pin low]\n");
+
+    for(index = 0; index < MAX_pin_num; index++){
+       OUT_pin = pin_array[index].output_gpio;
+       Read_pin = pin_array[index].input_gpio;
+
+       //输出低
+       gpio_register_set_direction(OUT_pin, 1);
+       gpio_register_set_value(OUT_pin, 0);
+
+       //输入脚设为输入
+       gpio_register_set_direction(Read_pin,0);
+   }
+
+    for(index = 0; index < MAX_pin_num; index++){
+        OUT_pin = pin_array[index].output_gpio;
+        Read_pin = pin_array[index].input_gpio;
+        read_low_value = gpio_register_get_value(Read_pin);
+
+        //结果检测
+        if(read_low_value != 0){
+           printf("[GPIOTEST][!Low Failed!]: GPIO%d PIN%d\n", Read_pin, pin_array[index].input_pin);
+           pin_array[index].mbtk_gpio_test_result = 1;
+           fail_num ++;
+        }
+#if DEBUG_GPIO_TEST
+        else{
+			printf("[GPIOTEST][-Low Success-]: GPIO%d \n", Read_pin);
+        }
+#endif
+    }
+    return fail_num;
+}
+
+
+//测高
+static uint16 mbtk_gpio_test_pin_high(mbtk_gpio_paired_info_struct *pin_array, uint16 MAX_pin_num)
+{
+    uint16 index = 0;
+    uint16 OUT_pin, Read_pin;
+    uint32 read_high_value;
+    uint32 read_low_value;
+    uint16 fail_num = 0;
+    int i = 0;
+
+    printf("[GPIOTEST][run test pin high]\n");
+
+    for(index = 0; index < MAX_pin_num; index++){
+        OUT_pin = pin_array[index].output_gpio;
+        Read_pin = pin_array[index].input_gpio;
+
+        //设高
+        gpio_register_set_direction(OUT_pin,1);
+        gpio_register_set_direction(Read_pin,0);
+        gpio_register_set_value(OUT_pin, 1);
+        usleep(10000);
+        read_high_value = gpio_register_get_value(Read_pin);
+#if DEBUG_GPIO_TEST
+        printf("[GPIOTEST][test_high]: PIN%d: get value =%d \n", pin_array[index].input_pin, read_high_value);
+#endif
+
+        //设高后重新设低
+        usleep(10000);
+        gpio_register_set_value(OUT_pin, 0);
+        usleep(10000);
+        for(i = 0; i < 10; i++){
+            read_low_value = gpio_register_get_value(Read_pin);
+            if(0 == read_low_value){
+                break;
+            }
+            usleep(20000);
+        }
+#if DEBUG_GPIO_TEST
+		printf("[GPIOTEST][test_low]: PIN%d: get value =%d  \n", pin_array[index].input_pin, read_low_value);
+#endif
+		if(read_high_value != 1 || read_low_value != 0){
+			printf("[GPIOTEST][!High Failed!]: Gpio%d PIN%d\n", Read_pin,pin_array[index].input_pin);
+			pin_array[index].mbtk_gpio_test_result = 2;
+			fail_num ++;
+        }
+#if DEBUG_GPIO_TEST
+        else{
+            printf("[GPIOTEST][-High Success-]: Gpio%d \n", Read_pin);
+		}
+#endif
+    }
+	return fail_num;
+}
+
+
+static void gpio_test_init_test_gpio_mode(mbtk_gpio_paired_info_struct pin_array[], int MAX_pin_num)
+{
+	int index = 0;
+	int OUT_pin, Read_pin;
+
+	printf("[GPIOTEST] L509 GPIOTEST v2.2 --init\n");
+
+	gpio_register_set_func_0(125);
+	gpio_register_set_direction(125, 1);
+	gpio_register_set_value(125, 1);			//RS2299开关的使能脚
+
+	system("i2cset -y -f 2 0x31 0x12 0x46");	//使能0x12地址的VLDO, 某组GPIO的供电
+
+	gpio_register_write(GPIO_FUNC_GPIO_53, 0xb040);  //GPIO53 DTR set PULL DOWN
+
+	for(index = 0; index < MAX_pin_num; index++){
+		OUT_pin = pin_array[index].output_gpio;
+		Read_pin = pin_array[index].input_gpio;
+		pin_array[index].mbtk_gpio_test_result = 0;	 //init as passed
+		gpio_register_set_func_0(OUT_pin);
+		gpio_register_set_func_0(Read_pin);
+		gpio_register_set_value(OUT_pin, 0);
+	}
+
+#if DEBUG_GPIO_TEST
+	printf("[GPIOTEST]gpio_test_init_test_gpio_mode FINISH\n");
+#endif
+
+}
+
+
+int mbtk_at_gpio(bool gnss_support, void* arg)
+{
+	int i, num;
+	int *fail_io = (int *)arg;
+	/*OPEN SWITCH */
+	uint16 test_fail_count = 0;
+	uint16 test_MAX_pin_num = 0;
+	char buf[STR_MAX_LEN];
+	//uint16 str_len = 0;
+	uint16 temp_len =0;
+	uint16 Out_pin;
+	uint16 in_pin;
+	//uint16 fail_print_num = 0;
+
+	mbtk_gpio_paired_info_struct  test_pin_array[] ={
+        //output_pin, output_gpio,    input_gpio, input_pin,    test_result
+        {122, 16,	 	   17,  121,         0},		/* RGMII/RMII_MD_CLK	<---SW RS2299--->		RGMII/RMII_MD_IO	*/
+
+        {78,  7,           2,   73, 	     0},		/* RGMII/RMII_TX_1		<---SW RS2299--->		RGMII/RMII_RXD1		*/
+        {77,  6,           1,   76,          0}, 	    /* RGMII/RMII_TXD0		<---SW RS2299--->		RGMII/RMII_RXD0		*/
+        {81,  15,          3,   75, 	     0},		/* RGMII/RMII_TX_EN		<---SW RS2299--->		RGMII/RMII_CLK		*/
+        {74,  0,           18,  120,	     0},		/* RGMII/RMII_RX_DV		<---SW RS2299--->		RGMII/RMII_INT		*/
+
+        {1,   117,         120, 2,	         0}, 	    /* WAKEUP_IN			<---SW RS2299--->		AP_READY			*/
+        {4,   118,         19,  13,	         0},		/* FLIGHTMODE			<---SW RS2299--->		USIM_CD				*/
+        {5,   123,         126, 6,           0},		/* NET_MODE				<---SW RS2299--->		NET_STATUS			*/
+        {23,  43,          23,  62, 	     0},		/* MMC1_CD				<---SW RS2299--->		UART_RI				*/
+
+        {79,  4,           5,   82, 	     0},		/* RGMII_RX_2			<---SW RS2299--->		RGMII_RX_3			*/
+        {80,  13,          14,  84, 	     0},		/* RGMII_TX_2			<---SW RS2299--->		RGMII_TX_3			*/
+        {129, 48,          55,  130,	     0},		/* WLAN_DAT3			<---SW RS2299--->		WLAN_DAT2			*/
+        {131, 56,          57,  132,	     0},		/* WLAN_DAT1			<---SW RS2299--->		WLAN_DAT0			*/
+
+        {24,  28,          27,  25,          0},		/* PCM_IN				<---SW RS2299--->		PCM_OUT				*/
+        {26,  26,          25,  27, 	     0},		/* PCM_SYNC				<---SW RS2299--->		PCM_CLK				*/
+        {37,  34,          33,  40, 	     0}, 	    /* SPI_CS				<---SW RS2299--->		SPI_CLK				*/
+        {38,  36,          35,  39, 	     0},		/* SPI_DOUT				<---SW RS2299--->		SPI_DIN				*/
+
+        {133, 59,          58,  134,	     0},		/* WLAN_CLK/PCIE_RSTN	<---SW RS2299--->		WLAN_CMD/PCIE_WK	*/
+        {135, 21,          99,  139,	     0},		/* WLAN_WAKE_HOST		<---SW RS2299--->		USB_ID				*/
+        {119, 20,          22,  136,	     0}, 	    /* RGMII/RMII_RST_N		<---SW RS2299--->		WLAN_EN				*/
+        {83,  12,          122, 118,	     0},        /* RGMII_CLK_TX			<---SW RS2299--->		WLAN_SLP_CLK		*/
+
+        {41,  49,          50,  42, 	     0},		/* I2C_SCL				<---SW RS2299--->		I2C_SDA				*/
+        {143, 10,          11,  144,	     0},		/* GRFC1				<---SW RS2299--->		GRFC2				*/
+        {64,  32,          31,  65, 	     0},		/* UART_CTS				<---SW RS2299--->		UART_RTS			*/
+        {63,  54,          53,  66, 	     0},        /* UART_DCD				<---SW RS2299--->		UART_DTR			*/
+    };
+
+
+	/* [1]初始化待测GPIO */
+	test_MAX_pin_num = sizeof(test_pin_array) / sizeof(test_pin_array[0]);
+    if(gnss_support){    //TODO: When the hardware does not have GNSS, do not test GPIO53, 54
+                          //bad implement, need modify
+        test_MAX_pin_num = test_MAX_pin_num - 1;
+    }
+	gpio_test_init_test_gpio_mode(test_pin_array, test_MAX_pin_num);
+
+
+	/* [2]测试过程 */
+	test_fail_count = mbtk_gpio_test_all_low(test_pin_array, test_MAX_pin_num);
+
+	if(!test_fail_count){ //set all pin to low success
+		printf("[GPIOTEST]set all pin to low: success\n");
+		test_fail_count = mbtk_gpio_test_pin_high(&test_pin_array, test_MAX_pin_num);
+	}
+	else{
+		printf("[GPIOTEST]set all pin low: failed num=%d!!!\n", test_fail_count);
+	}
+
+
+	//memset(buf,0,STR_MAX_LEN);
+	/* [3]测试结果检测与上报 */
+	if(test_fail_count ){
+		//printf( "GPIOTEST Fail %02d PINs:\n", test_fail_count*2);
+		sprintf(buf, "GPIOTEST Fail %02d PINs:", test_fail_count * 2);
+		temp_len = strlen(buf);
+
+		num = 0;
+		for(i = 0; i < test_MAX_pin_num; i++){
+			if(test_pin_array[i].mbtk_gpio_test_result){
+				Out_pin = test_pin_array[i].output_pin;
+				in_pin = test_pin_array[i].input_pin;
+				fail_io[num++] = Out_pin;
+				fail_io[num++] = in_pin;
+			}
+		}
+	}
+
+	else{
+		printf(buf, "ALL GPIO TEST PASS\r\n");
+	}
+
+    printf("\n[GPIOTEST] Finished !!\n\n");
+	return  test_fail_count * 2;
+}
+
+
+#elif defined(MBTK_PROJECT_L508_X6)
+int gpio_register_test_out_0(int port)
+{
+    int ret;
+    int i;
+    int valueh = 0;
+    int valuel = 1;
+
+    //printf("Gpio port [%d] test start!\n", port);
+    ret = gpio_register_set_func_0(port);           //设功能为GPIO
+    if(ret){
+        printf("gpio_port can't support!\n");
+        return -1;
+    }
+    gpio_register_set_direction(port, 1);           //设方向为输出
+    //ret = gpio_register_get_value(port);
+    //printf("gpio default value is : %d.\n", ret);
+
+
+    //[High]
+    for(i = 0; i <= 10; i++){
+        gpio_register_set_value(port, 1);
+        usleep(50);
+        valueh = gpio_register_get_value(port);
+        //printf("set high? %d\n",valueh);
+        if(1 == valueh){
+            break;
+        }
+    }
+    usleep(5000);
+    for(i = 0; i <= 10; i++){
+        ret = mbtk_gpio_adc(0);
+        usleep(3000);
+        if(1 == ret){
+            break;
+        }
+    }
+	//printf("******gpio should is high: %d.******\n", ret);
+    if(1 != ret){
+        ret=-1;
+        goto exit;
+    }
+
+
+
+    //[Low]
+     usleep(200);
+     for(i = 0; i <= 10; i++){
+        gpio_register_set_value(port, 0);               //输出低
+        usleep(50);
+        valuel = gpio_register_get_value(port);
+        //printf("set low? %d\n",valuel);
+        if(0 == valuel){
+            break;
+        }
+    }
+    usleep(5000);
+    for(i = 0; i <= 10; i++){
+        ret = mbtk_gpio_adc(0);
+        usleep(3000);
+        if(0 == ret){
+            break;
+        }
+    }
+    printf("******gpio should is low: %d.******\n", ret);
+    if(0 != ret){
+        ret=-1;
+        goto exit;
+    }
+
+exit:
+	gpio_register_set_value(port, 0);
+    //gpio_register_set_direction(port, 0);  //设方向为输入
+    return ret;
+}
+
+int gpio_register_test_out_1(int port)
+{
+    int ret;
+    int i;
+    int valueh = 0;
+    int valuel = 1;
+
+    //printf("Gpio port [%d] test start!\n", port);
+    ret = gpio_register_set_func_0(port);           //设功能为GPIO
+    if(ret){
+        printf("gpio_port can't support!\n");
+        return -1;
+    }
+    gpio_register_set_direction(port, 1);           //设方向为输出
+    //ret = gpio_register_get_value(port);
+    //printf("gpio default value is : %d.\n", ret);
+
+
+    //[High]
+    for(i = 0; i <= 10; i++){
+        gpio_register_set_value(port, 1);
+        usleep(50);
+        valueh = gpio_register_get_value(port);
+        //printf("set high? %d\n",valueh);
+        if(1 == valueh){
+            break;
+        }
+    }
+    usleep(5000);
+    for(i = 0; i <= 10; i++){
+        ret = mbtk_gpio_adc(1);
+        usleep(3000);
+        if(1 == ret){
+            break;
+        }
+    }
+    if(1 != ret){
+        ret=-1;
+        goto exit;
+    }
+    //printf("******gpio should is high: %d.******\n", ret);
+
+
+    //[Low]
+     usleep(200);
+     for(i = 0; i <= 10; i++){
+        gpio_register_set_value(port, 0);               //输出低
+        usleep(50);
+        valuel = gpio_register_get_value(port);
+        //printf("set low? %d\n",valuel);
+        if(0 == valuel){
+            break;
+        }
+    }
+    usleep(10000);
+    for(i = 0; i <= 10; i++){
+        ret = mbtk_gpio_adc(1);
+        usleep(3000);
+        if(0 == ret){
+            break;
+        }
+    }
+    //printf("******gpio should is low: %d.******\n", ret);
+    if(0 != ret){
+        ret=-1;
+        goto exit;
+    }
+
+exit:
+    gpio_register_set_value(port, 0);
+    //error: no need set direction in gpio_register_set_direction(port, 0);
+    return ret;
+}
+
+
+int gpio_register_test_out_2(int port_in, int port_out)
+{
+    int ret_in;
+	int ret_out;
+    int i;
+    int valueh = 0;
+    int valuel = 1;
+
+    //printf("Gpio port [%d] test start!\n", port_out);
+    ret_in = gpio_register_set_func_0(port_in);           //设功能为GPIO
+	ret_out = gpio_register_set_func_0(port_out);
+    if((ret_in+ret_out)){
+        printf("gpio_port can't support!\n");
+        return -1;
+    }
+    gpio_register_set_direction(port_out, 1);           //设方向为输出
+	gpio_register_set_direction(port_in, 0);           //设方向为输入
+    //ret_in = gpio_register_get_value(port_in);
+    //printf("gpio default value is : %d.\n", ret_in);
+
+
+    //[High]
+    for(i = 0; i <= 10; i++){
+        gpio_register_set_value(port_out, 1);
+        usleep(50);
+        valueh = gpio_register_get_value(port_out);
+        //printf("set high? %d\n",valueh);
+        if(1 == valueh){
+            break;
+        }
+    }
+
+	usleep(5000);
+    for(i = 0; i <= 10; i++){
+       ret_in = gpio_register_get_value(port_in);
+        usleep(3000);
+        if(1 == ret_in){
+            break;
+        }
+    }
+    if(1 != ret_in){
+        ret_in=-1;
+		printf("get high failed! \n");
+        goto exit;
+    }
+    //printf("******gpio should is high: %d.******\n", ret_in);
+
+
+    //[Low]
+     usleep(200);
+     for(i = 0; i <= 10; i++){
+        gpio_register_set_value(port_out, 0);               //输出低
+        usleep(50);
+        valuel = gpio_register_get_value(port_out);
+        //printf("set low? %d\n",valuel);
+        if(0 == valuel){
+            break;
+        }
+    }
+
+	usleep(5000);
+    for(i = 0; i <= 10; i++){
+        ret_in = gpio_register_get_value(port_in);
+        usleep(3000);
+        if(0 == ret_in){
+            break;
+        }
+    }
+    //printf("******gpio should is low: %d.******\n", ret_in);
+    if(0 != ret_in){
+        ret_in=-1;
+		printf("get low failed! \n");
+        goto exit;
+    }
+
+exit:
+    gpio_register_set_value(port_out, 0);
+    //gpio_register_set_direction(port_out, 0);
+    return ret_in;
+}
+
+
+static int gpio_test_init_test_gpio_mode(void )
+{
+	const int test_gpio_1[] = {
+		40, 33, 34, 39, 99, 10, 11, 88, 87, 86, 85, 84, 89,
+		56, 55, 58, 57, 48, 59, 10, 90, 20, 53, 19, 46, 127,
+		49, 50, 32, 31, 6, 7
+	};
+
+	const int test_gpio_0[] = {
+		8, 27, 28, 26, 25, 15, 1, 3, 0,
+		37, 38,35, 36, 42, 41, 21, 22, 24, 23,
+		54, 125, 18, 13, 14, 17, 16, 5, 4, 2, 12,
+		43, 44, 45, 47, 117, 119
+	};
+    int i, j, ret_0, ret_1, total_1, total_0, n = 0;
+    total_0 = (sizeof(test_gpio_0)/sizeof(int));
+    total_1 = (sizeof(test_gpio_1)/sizeof(int));
+
+	//system("at at+gpsinit=0");
+	system("i2cset -y -f 2 0x32 0x0d 0x00");
+	system("i2cset -y -f 2 0x31 0x18 0x8f");
+	usleep(10000);
+
+       //printf("[init]gpio_test_init_test_gpio_mode FINISH\n");
+		/* [1 all gpio set to low] */
+    for(j = 0; j < 6 ; j++){
+        for(i = 0; i < total_0; i++){
+            gpio_register_set_func_0(test_gpio_0[i]);
+            gpio_register_set_direction(test_gpio_0[i], 1);
+            gpio_register_set_value(test_gpio_0[i], 0);
+        }
+        for(i = 0; i < total_1; i++){
+            gpio_register_set_func_0(test_gpio_1[i]);
+            gpio_register_set_direction(test_gpio_1[i], 1);
+            gpio_register_set_value(test_gpio_1[i], 0);
+        }
+
+        usleep(50000);
+        for(i = 0; i <= 10; i++){
+            ret_0 = mbtk_gpio_adc(0);
+            usleep(3000);
+            ret_1 = mbtk_gpio_adc(1);
+
+            if(ret_0 ==0  && ret_1 == 0){
+                break;
+            }
+        }
+        printf("pre set ADC0: %d, ADC1: %d, times: %d\n", ret_0, ret_1, j);
+        if(ret_0 ==0  && ret_1 == 0){
+            break;
+        }
+    }
+	if(!(ret_0 ==0  && ret_1 == 0)){
+
+		printf("Fail, please retest");
+		return -1;
+	}
+	gpio_register_set_value(119, 1);
+	gpio_register_set_value(117, 1);
+    return 0;
+}
+
+int mbtk_at_gpio(bool gnss_support, void* arg)
+{
+	const int test_gpio_0[] = {
+		35, 93,
+		36, 94,
+		42, 97,
+		41, 98,
+		21, 100,
+		22, 101,
+		24, 102,
+		23, 103,
+		54, 107,
+		125, 108,
+		18, 109,
+		13, 114,
+		14, 115,
+		17, 116,
+		16, 117,
+		5, 119,
+		4, 127,
+		2, 120,
+		12, 126,
+		0, 90,
+		27, 73,
+		28, 74,
+		26, 75,
+		25, 76,
+		15, 86,
+		1, 88,
+		3, 89,
+		37, 91,
+		38, 92,
+		8, 72
+	};
+
+    const int test_gpio_1[] = {
+		40,	6,
+		33, 7,
+		34, 8,
+		39, 9,
+		99, 16,
+		56, 27,
+		58, 29,
+		55, 28,
+		57, 30,
+		48, 31,
+		59, 32,
+		20, 49,
+		53, 50,
+		19, 51,
+		49, 55,
+		50, 56,
+		32, 66,
+		31, 67,
+		6, 68,
+		11, 83,
+		10, 84,
+		7, 69,
+		90, 48,
+		46, 52,
+		127, 54,
+		88, 21,
+		87, 22,
+		86, 23,
+		85, 24,
+		84, 25,
+		89, 26,
+	};
+
+	const int test_gpio_2[] = {		//GPS组
+		43, 53,
+		47, 95,
+		45, 71,
+		44, 70,
+	};
+
+    int i, j, ret_0, ret_1, ret_2, total_1, total_0, total_2, n = 0;
+    int *fail_io = (int *)arg;
+    total_0 = (sizeof(test_gpio_0)/sizeof(int));	//GPIO+PIN
+    total_1 = (sizeof(test_gpio_1)/sizeof(int));
+	total_2 = (sizeof(test_gpio_2)/sizeof(int));
+	if(gnss_support == 1){
+		total_2 = total_2 - 4;
+	}
+    printf("L508-X6 Start test gpio V1.1\n");
+    /* [1 all gpio Init] */
+    gpio_test_init_test_gpio_mode();
+
+
+    /* [2 GPIOTEST] */
+	//Test 0
+	for(i = 0; i < total_0; i=i+2){
+        ret_0 = gpio_register_test_out_0(test_gpio_0[i]);
+        if(-1 == ret_0){
+            printf("!!!!!!!!!!!!gpio [%d] test failed!!!!!!!!!!!!\n", test_gpio_0[i]);
+            fail_io[n] = test_gpio_0[i+1];
+            n++;
+        }else{
+            //printf("############gpio [%d] test success############\n", test_gpio_0[i]);
+        }
+    }
+
+	//Test 1
+    for(i = 0; i < total_1; i=i+2){
+        ret_1 = gpio_register_test_out_1(test_gpio_1[i]);
+        if(-1 == ret_1){
+            printf("!!!!!!!!!!!!gpio [%d] test failed!!!!!!!!!!!!\n", test_gpio_1[i]);
+            fail_io[n] = test_gpio_1[i+1];
+            n++;
+        }else{
+            //printf("############gpio [%d] test success############\n", test_gpio_1[i]);
+        }
+    }
+
+	//Test 2
+    for(i = 0; i < total_2; i=i+4){
+        ret_2 = gpio_register_test_out_2(test_gpio_2[i], test_gpio_2[i+2]);
+        if(-1 == ret_2){
+            printf("!!!!!!!!!!!!gpio [%d] test failed!!!!!!!!!!!!\n", test_gpio_2[i+2]);
+            fail_io[n] = test_gpio_2[i+3];
+            n++;
+        }else{
+            //printf("############gpio [%d] test success############\n", test_gpio_2[i+2]);
+        }
+    }
+
+    mbtk_adc_close();
+    return n;
+}
+
+#elif 0//(MBTK_PROJECT_T108)
+int gpio_register_test_out(int port, int value)
+{
+    int ret;
+    int i;
+    int valueh = 0;
+    int valuel = 1;
+
+    //printf("Gpio port [%d] test start!\n", port);
+    ret = gpio_register_set_func_0(port);           //设功能为GPIO
+    if(ret){
+        printf("gpio_port can't support!\n");
+        return -1;
+    }
+    gpio_register_set_direction(port, 1);           //设方向为输出
+    //ret = gpio_register_get_value(port);
+    //printf("gpio default value is: %d\n", ret);
+
+
+    //[High]
+    for(i = 0; i <= 9; i++){
+        gpio_register_set_value(port, 1);
+        usleep(50);
+        //valueh = gpio_register_get_value(port);
+        //printf("set high? %d\n", valueh);
+        if(1 == valueh){
+            break;
+        }
+    }
+
+    for(i = 0; i <= 35; i++){
+        ret = gpio_register_get_value(118);
+        if(1 == ret){
+            break;
+        }
+		usleep(3000);
+    }
+	printf("******gpio should is high: %d.******\n", ret);
+    if(1 != ret){
+        ret=-1;
+        goto exit;
+    }
+
+    //[Low]
+	usleep(200);
+	for(i = 0; i <= 9; i++){
+		gpio_register_set_value(port, 0);               //输出低
+		usleep(50);
+		//valuel = gpio_register_get_value(port);
+		//printf("set low? %d\n", valuel);
+		if(0 == valuel){
+			break;
+		}
+	}
+
+    for(i = 0; i <= 35; i++){
+        ret = gpio_register_get_value(118);
+        if(0 == ret){
+            break;
+        }
+        usleep(3000);
+    }
+    //printf("******gpio should is low: %d.******\n", ret);
+    if(0 != ret){
+        ret=-1;
+        goto exit;
+    }
+
+exit:
+	gpio_register_set_value(port, 0);
+    gpio_register_set_direction(port, 0);  //设方向为输入
+    return ret;
+}
+
+int gpio_test_init_test_gpio_mode(void)
+{
+    const int test_gpio[] = {
+		99,
+		117,
+		21,22,23,24,44,41,120,
+		8,127,46,59,58,57,56,55,48,19,34,33,35,36,49,
+		50,25,28,26,122,20,10,11,
+		39,40,37,38,
+		51,52,31,32,
+	};
+
+    int i, j, ret, total, n = 0;
+    total = (sizeof(test_gpio)/sizeof(int));
+    printf("[init]gpio_test_init_test_gpio_mode BEGIN\n");
+
+	/* [1 all gpio set to low] */
+	gpio_register_set_func_0(118);
+	gpio_register_set_direction(118, 0);
+	system("echo in  > /sys/class/gpio/gpio118/direction");
+
+    for(j = 0; j < 6 ; j++){
+        for(i = 0; i < total; i++){
+            gpio_register_set_func_0(test_gpio[i]);
+            gpio_register_set_direction(test_gpio[i], 1);
+            gpio_register_set_value(test_gpio[i], 0);
+			//ret = gpio_register_get_value(test_gpio[i]);
+			//printf("[init]get gpio%d=%d\n", test_gpio[i], ret);
+        }
+
+		for(i = 0; i <= 35; i++){
+		  ret = gpio_register_get_value(118);
+		  printf("[init]get gpi118=%d\n", ret);
+		  usleep(3000);
+		  if(0 == (ret)){
+			  break;
+		  }
+		}
+
+		printf("pre set ADC: %d, times: %d\n",(ret), j);
+		if(0 == (ret)){
+		  break;
+		}
+    }
+	if(0 != (ret)){
+		printf("!!!Set all low FAIL, please retest\n");
+		return -1;
+	}
+	return 0;
+}
+
+int mbtk_at_gpio(bool gnss_support, void* arg)
+{
+
+    const int test_gpio[] = {
+	  //GPIO	PIN		GPIO	PIN		GPIO	PIN		GPIO	PIN
+		99,		170,	117,	59,		21,		61,		22,		62,
+		23,		144,	24,		147,	44,		5,		41,		159,
+		120,	143,	8,		171,	127,	160,	46,		149,
+		59,		19,		58,		18,		57,		20,		56,		21,
+		55,		22,		48,		23,		19,		3,		34,		79,
+		33,		80,		35,		78,		36,		77,		49,		43,
+		50,		42,		25,		67,		28,		66,		26,		65,
+		122,	169,	20,		152,	10,		74,		11,		73,
+		39,		166,	40,		164,	37,		165,	38,		163,
+		51,		58,		52,		60,		31,		57,		32,		56,
+	};
+
+    int i, n = 0, ret, total;
+    int *fail_io = (int *)arg;
+	int try_count = 0;
+    total = (sizeof(test_gpio)/sizeof(int));
+	printf("T108 Start test gpio V1.0, total gpio=%d\n", (total/2));
+
+	for(try_count; try_count < 4; try_count++){
+	    n = 0;
+	    /* [1 all gpio Init] */
+	    gpio_test_init_test_gpio_mode();
+
+	    /* [2 GPIOTEST] */
+		for(i = 0; i < total; i = i + 2){
+	        ret = gpio_register_test_out(test_gpio[i], 0);
+	        if(-1 == ret){
+				n++;
+	            printf("!!!!!!!!!!!!gpio [%d] test failed!!!!!!!!!!!!\n", test_gpio[i]);
+				if(try_count != 3){
+					printf(" ---TEST FAILED! RETRY!--- \n");
+        			usleep(5000);
+					break;
+				}
+	            fail_io[n - 1] = test_gpio[i+1];
+	        }else{
+	            //printf("############gpio [%d] test success############\n", test_gpio[i]);
+	        }
+	    }
+	    if(0 == n){
+	    	break;
+		}
+    }
+    return n;
+}
+
+
+#elif (MBTK_PROJECT_T108)
+static int gpio_test(int port)
+{
+    int ret;
+    int i;
+    int valueh = 0;
+    int valuel = 1;
+
+    //printf("Gpio port [%d] test start!\n", port);
+    ret = gpio_register_set_func_0(port);
+    if(ret){
+        printf("gpio_port can't support!\n");
+        return -1;
+    }
+    gpio_register_set_direction(port, 1);
+    //ret = gpio_register_get_value(port);
+    //printf("gpio default value is: %d\n", ret);
+
+
+    //[High]
+    for(i = 0; i <= 5; i++){
+        gpio_register_set_value(port, 1);
+        usleep(50);
+        //valueh = gpio_register_get_value(port);
+        //printf("set high? %d\n", valueh);
+        if(1 == valueh){
+            break;
+        }
+    }
+
+    for(i = 0; i <= 5; i++){
+        ret = gpio_register_get_value(118);
+        if(1 == ret){
+
+            break;
+        }
+		usleep(3000);
+    }
+    //printf("count=%d \n", i);
+  	//printf("******gpio should is high: %d.******\n", ret);
+    if(1 != ret){
+        ret=-1;
+        goto exit;
+    }
+
+    //[Low]
+	usleep(200);
+	for(i = 0; i <= 9; i++){
+		gpio_register_set_value(port, 0);
+		usleep(50);
+		//valuel = gpio_register_get_value(port);
+		//printf("set low? %d\n", valuel);
+		if(0 == valuel){
+			break;
+		}
+	}
+
+    for(i = 0; i <= 5; i++){
+        ret = gpio_register_get_value(118);
+        if(0 == ret){
+
+            break;
+        }
+        usleep(3000);
+    }
+    //printf("count=%d \n", i);
+    //printf("******gpio should is low: %d.******\n", ret);
+    if(0 != ret){
+        ret=-1;
+        goto exit;
+    }
+
+exit:
+    gpio_register_set_value(port, 0);
+    gpio_register_set_direction(port, 0);
+    return ret;
+
+}
+
+static int gpio_test_init_test_gpio_mode(void)
+{
+	const int test_gpio[] = {
+      99,8,117,21,22,23,24,41,120,19,123,
+      58,59,57,56,55,48,125,127,36,35,34,
+      33,54,47,53,46,50,49,11,10,26,28,25,
+      27,32,31,51,52,39,40,37,38,
+      44,45
+	};
+
+    int i, j, ret, total, n = 0;
+    total = (sizeof(test_gpio)/sizeof(int));
+    //printf("[init]gpio_test_init_test_gpio_mode BEGIN\n");
+
+	/* [1 all gpio set to low] */
+	gpio_register_set_func_0(118);
+	gpio_register_set_direction(118, 0);
+
+    for(j = 0; j < 5 ; j++){
+        for(i = 0; i < total; i++){
+            gpio_register_set_func_0(test_gpio[i]);
+            gpio_register_set_direction(test_gpio[i], 1);
+            gpio_register_set_value(test_gpio[i], 0);
+			//ret = gpio_register_get_value(test_gpio[i]);
+			//printf("[init]get gpio%d=%d\n", test_gpio[i], ret);
+        }
+
+
+		for(i = 0; i <= 10; i++){
+		  ret = gpio_register_get_value(118);
+		  //printf("[init]get gpi118=%d\n", ret);
+		  usleep(3000);
+		  if(0 == (ret)){
+			  break;
+		  }
+		}
+
+		//printf("pre set 118: %d, times: %d\n",(ret), j);
+		if(0 == (ret)){
+		  break;
+		}
+    }
+	if(0 != (ret)){
+		printf("!!!Set all low FAIL, please retest\n");
+		return -1;
+	}
+	return 0;
+}
+
+int mbtk_at_gpio(bool gnss_support, void* arg)
+{
+    const int test_gpio[] = {
+	//GPIO	PIN		GPIO	PIN		GPIO	PIN		GPIO	PIN
+	99,		170,	8,		171,	117,	59,		21,		61,
+	22,		62,		23,		144,	24,		147,	41,		159,
+	120,	143,	19,		3,		123,	5,		58,		18,
+	59,		19,		57,		20,		56,		21,		55,		22,
+	48,		23,		125,	149,	127,	160,	36,		77,
+	35,		78,		34,		79,		33,		80,		54,		163,
+	#if 0	//Hard Ware ERROR!
+	47,		164,
+	46,		166,
+	#endif
+	53,		165,	50,		42,		49,		43,		11,		73,
+	10,		74,		26,		65,		28,		66,		25,		67,
+	27,		68,		32,		56,		31,		57,		51,		58,
+	52,		60,		39,		192,	40,		193,	37,		194,
+	38,		195,
+	#if 0	//undefine GNSS
+	44,		161,
+	45,		151,
+	#endif
+	};
+
+    int i, n = 0, ret, total;
+    int *fail_io = (int *)arg;
+    int try_count;
+    total = (sizeof(test_gpio)/sizeof(int));
+	printf("T108 V2 Start test gpio V0.8, total gpio=%d\n", (total/2));
+
+    for(try_count = 0; try_count < 4; try_count++){
+        n = 0;
+        /* [1 all gpio Init] */
+        gpio_test_init_test_gpio_mode();
+
+        /* [2 GPIOTEST] */
+    	for(i = 0; i < total; i = i + 2){
+            ret = gpio_test(test_gpio[i]);
+            if(-1 == ret){
+				n++;
+				printf("!!!!!!!!!!!!gpio [%d] test failed!!!!!!!!!!!!\n", test_gpio[i]);
+				if(try_count != 3){
+					printf(" ---TEST FAILED! RETRY!--- \n");
+        			usleep(5000);
+					break;
+				}
+                fail_io[n - 1] = test_gpio[i + 1];
+            }else{
+                //printf("############gpio [%d] test success############\n", test_gpio[i]);
+            }
+        }
+        if(0 == n){
+			printf(" ---ALL PASS---\n");
+            break;
+        }
+    }
+    return n;
+}
+
+
+#else
+int mbtk_at_gpio(bool gnss_support, void* arg)
+{
+    return -1;
+}
+
+#endif
+
diff --git a/mbtk/mbtk_at/src/factory/mbtk_power.c b/mbtk/mbtk_at/src/factory/mbtk_power.c
new file mode 100755
index 0000000..f823bf8
--- /dev/null
+++ b/mbtk/mbtk_at/src/factory/mbtk_power.c
@@ -0,0 +1,703 @@
+#if 1
+#include <fcntl.h>
+#include <stdint.h>
+#include <libubox/blobmsg_json.h>
+#include <libubus.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <pthread.h>
+#include <sys/epoll.h>
+
+/****************************DEFINE***************************************/
+#define MBTK_POWER_RESULT_FAIL -1
+
+#define MBTK_POWER_CLOSE_FAIL -1
+#define MBTK_POWER_CLOSE_SUCCESS 0
+
+#define GNSS_SOCK_PATH "/tmp/mbtk_gnss_sock"
+void mbtk_log(int level, const char *format, ...);
+
+#define LOG_DEBUG_LEVEL 5
+#define LOG(fmt, args...) mbtk_log(LOG_DEBUG_LEVEL, fmt, ##args)
+#define LOGE LOG
+
+typedef enum{
+    MBTK_POWER_RESULT_SUCCESS = 0,
+    MBTK_POWER_RESULT_GNSS_TIMEOUT,
+    MBTK_POWER_RESULT_GNSS_CLOSE_FAIL,
+    MBTK_POWER_RESULT_NO_SLEEP_NODE,
+    MBTK_POWER_RESULT_UKNOWN_ERROR
+}mbtk_power_result_type;
+
+
+static int sock_listen_fd = -1;
+
+typedef enum {
+    GNSS_CMD_INIT = 0,
+    GNSS_CMD_DEINIT,
+    GNSS_CMD_SETTING,
+    GNSS_CMD_DL
+} gnss_cmd_enum;
+
+
+/****************************DEFINE***************************************/
+
+/****************************VARIABLE***************************************/
+const struct blobmsg_policy mbtk_power_cb_policy1[] = {
+    [0] = {
+        .name = "event",
+        .type = BLOBMSG_TYPE_INT32,
+    },
+};
+/****************************VARIABLE***************************************/
+
+/****************************FUNC***************************************/
+static void mbtk_power_gnss_callback(struct ubus_request *req, int type, struct blob_attr *msg)
+{
+    UNUSED(type);
+
+    struct blob_attr *tb[1];
+    struct blob_attr *cur;
+    unsigned int event;
+    int *ubus_gnss_result = (int *)req->priv;
+    int rc;
+
+    /*parsing blob to be accessed easily with tb array - parse "1" argument*/
+    rc = blobmsg_parse(mbtk_power_cb_policy1, 1, tb, blob_data(msg), blob_len(msg));
+    if (rc < 0)
+    {
+        LOGE("[MBTK_POWER] blobmsg_parse fail.");
+        //printf("blobmsg_parse fail\n");
+        *ubus_gnss_result = MBTK_POWER_CLOSE_FAIL;
+        return;
+    }
+
+    /*parse first parameter*/
+    cur = tb[0];
+    if (!cur)
+    {
+        LOGE("[MBTK_POWER] missing parameter.");
+        //printf("missing parameter\n");
+        *ubus_gnss_result = MBTK_POWER_CLOSE_FAIL;
+        return;
+    }
+
+    event = blobmsg_get_u32(cur);
+    LOGE("[MBTK_POWER] get event = [%d].", event);
+    //printf("get event = [%d].\n", event);
+
+#if 1
+    if(event != 0)
+#else
+    if(event != 7)
+#endif
+    {
+        *ubus_gnss_result = MBTK_POWER_CLOSE_FAIL;
+    }
+
+    return ;
+}
+
+static int mbtk_power_ubus_uloop_init(struct ubus_context **ctx)
+{
+    int ret = -1;
+    if(ctx == NULL)
+    {
+        LOGE("[MBTK_POWER] ctx is NULL");
+        return MBTK_POWER_RESULT_FAIL;
+    }
+
+    ret = uloop_init();
+    if(ret != 0)
+    {
+        LOGE("[MBTK_POWER] uloop_init fail.ret = [%d]", ret);
+        return MBTK_POWER_RESULT_FAIL;
+    }
+
+    if(*ctx != NULL)
+    {
+        LOGE("[MBTK_POWER] mbtk_gnss_ctx not NULL.");
+        return MBTK_POWER_RESULT_FAIL;
+    }
+
+    *ctx = ubus_connect(NULL);
+    if( !(*ctx) )
+    {
+        LOGE("[MBTK_POWER] ubus_connect fail.");
+        return MBTK_POWER_RESULT_FAIL;
+    }
+
+    ubus_add_uloop(*ctx);
+
+    return MBTK_POWER_RESULT_SUCCESS;
+}
+
+static int mbtk_power_ubus_uloop_deinit(struct ubus_context *ctx)
+{
+    if(ctx != NULL)
+    {
+        ubus_free(ctx);
+        ctx = NULL;
+    }
+
+    uloop_done();
+
+    return MBTK_POWER_RESULT_SUCCESS;
+}
+
+static int mbtk_power_invoke_reply_data_cb(const char *service, const char *method, struct blob_attr *msg,
+                         ubus_data_handler_t cb, void *cb_param, int timeout, struct ubus_context *ctx)
+{
+	int rc = -1;
+	uint32_t id;
+	struct ubus_request req;
+
+	/* Look up the target object id by the object path */
+    rc = ubus_lookup_id(ctx, service, &id);
+	if(rc)
+    {
+        LOGE("[MBTK_POWER] ubus_lookup_id fail.rc = [%d]", rc);
+		return MBTK_POWER_RESULT_FAIL;
+    }
+
+	rc = ubus_invoke(ctx, id, method, msg, cb, cb_param, timeout);
+    if(rc)
+    {
+        LOGE("[MBTK_POWER] ubus_invoke fail.rc = [%d]", rc);
+		return MBTK_POWER_RESULT_FAIL;
+    }
+	return MBTK_POWER_RESULT_SUCCESS;
+}
+
+                 //mbtk wyq for AT+MGPSC add start
+
+#if 0//#ifndef MBTK_GNSS_FACTORY_TEST_MODE
+                 if(strncasecmp((char const *)line, "AT+MGPSC=", strlen("AT+MGPSC=")) == 0)
+                 {
+                     int mode,ret = 0;
+                     (void)sscanf((const char *)line, "%*[^0-9]%d", &mode);
+                     if(mode == 1 || mode == 5)
+                     {
+                         if(modem_if.echo_mode == MODEM_ECHO_MODE)
+                         {
+                             writen(ppp_uart2_fd, line, 10);
+                         }
+
+                         ret = mbtk_GPS_process(GNSS_CMD_INIT, &mode);
+
+                         if(-1 == ret)
+                         {
+                             const char RESP_BUFF[] = "\r\n+GPS: gps server timeout.\r\n\r\nERROR\r\n";
+                             writen(ppp_uart2_fd, RESP_BUFF, sizeof(RESP_BUFF) - 1);
+                         }
+                         else
+                         {
+                             const char RESP_BUFF[] = "\r\n+GPS: gps init success\r\n";
+                             writen(ppp_uart2_fd, RESP_BUFF, sizeof(RESP_BUFF) - 1);
+                         }
+                         continue;
+                     }
+                 }
+#endif
+                 //mbtk wyq for AT+MGPSC add end
+
+ static int mbtk_GPS_process(gnss_cmd_enum cmd, void *arg)
+ {
+     if(sock_listen_fd < 0) {
+         sock_listen_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
+         if(sock_listen_fd < 0)
+         {
+             LOGE("[MBTK_POWER]socket() fail[%d].", errno);
+             return -1;
+         }
+
+         struct sockaddr_un cli_addr;
+         memset(&cli_addr, 0, sizeof(cli_addr));
+         cli_addr.sun_family = AF_LOCAL;
+         strcpy(cli_addr.sun_path, GNSS_SOCK_PATH);
+         if(connect(sock_listen_fd, (struct sockaddr *)&cli_addr, sizeof(cli_addr)))
+         {
+             LOGE("[MBTK_POWER]connect() fail[%d].", errno);
+             close(sock_listen_fd);
+             sock_listen_fd = -1;
+             return -1;
+         }
+     }
+
+     char buff[100] = {0};
+     if(cmd == GNSS_CMD_INIT) {
+         if(arg) {
+             sprintf(buff, "gnss_init:%d", *(int*)arg);
+         } else {
+             return -1;
+         }
+     } else if(cmd == GNSS_CMD_DEINIT) {
+         sprintf(buff, "gnss_deinit");
+     } else if(cmd == GNSS_CMD_SETTING) {
+         sprintf(buff, "gnss_setting:%s", arg);
+     } else if(cmd == GNSS_CMD_DL) {
+         sprintf(buff, "gnss_dl:%s", arg);
+     } else {
+         LOGE("[MBTK_POWER]Unknown cmd.");
+         return -1;
+     }
+
+     write(sock_listen_fd, buff, strlen(buff));
+
+     int len = 0;
+     while(1) {
+         memset(buff, 0, sizeof(buff));
+         len = read(sock_listen_fd, buff, sizeof(buff));
+         if(len > 0) {
+             LOGE("[MBTK_POWER]RSP : %s", buff);
+             if(cmd == GNSS_CMD_INIT) {
+                 if(strstr(buff, "gnss_init") != 0) {
+                     return 0;
+                 } else {
+                     LOGE("[MBTK_POWER]gnss_init response error.");
+                     return -1;
+                 }
+             } else if(cmd == GNSS_CMD_DEINIT) {
+                 if(strstr(buff, "gnss_deinit") != 0) {
+                     return 0;
+                 } else {
+                     LOGE("[MBTK_POWER]gnss_deinit response error.");
+                     return -1;
+                 }
+             } else if(cmd == GNSS_CMD_SETTING) {
+                 if(strstr(buff, "gnss_setting") != 0) {
+                     return 0;
+                 } else {
+                     LOGE("[MBTK_POWER]gnss_setting response error.");
+                     return -1;
+                 }
+             } else if(cmd == GNSS_CMD_DL) {
+                 if(strstr(buff, "gnss_dl") != 0) {
+                     return 0;
+                 } else {
+                     LOGE("[MBTK_POWER]gnss_dl response error.");
+                     return -1;
+                 }
+             } else {
+                 LOGE("[MBTK_POWER]Unknown response.\n");
+                 return -1;
+             }
+         } else if(len == 0) {
+             LOGE("[MBTK_POWER]RSP is null.");
+             return -1;
+         } else {
+             LOGE("[MBTK_POWER]read = %d:errno = %d", len, errno);
+         }
+     }
+ }
+
+
+ int mbtk_mgpsc_set(int arg)
+ {
+    int ret = 0;
+    int *p = 3;
+
+    if (arg == 1)
+    {
+        ret = mbtk_GPS_process(GNSS_CMD_INIT, &p);
+
+        if (-1 == ret)
+        {
+            LOGE("[MBTK_POWER] mbtk_mgpsc_set fail.");
+            return -1;
+        }
+    }
+    else
+    {
+        ret = mbtk_GPS_process(GNSS_CMD_DEINIT, NULL);
+
+        if (-1 == ret)
+        {
+            LOGE("[MBTK_POWER] mbtk_mgpsc_set fail.");
+            return -1;
+        }
+    }
+
+    return 0;
+ }
+
+
+
+static int mbtk_power_gnss_close(void)
+{
+    int ret = 0;
+
+    ret = mbtk_GPS_process(GNSS_CMD_DEINIT, NULL);
+
+    if (-1 == ret)
+    {
+        LOGE("[MBTK_POWER] mbtk_power_gnss_close fail.");
+        return MBTK_POWER_CLOSE_FAIL;
+    }
+
+    return MBTK_POWER_CLOSE_SUCCESS;
+}
+
+static int gpio_direct_set(char *value,int gpio)
+{
+    char buffer[50]= {0};
+    int file =-1;
+    int result =-1;
+
+    memset(buffer,0,50);
+    sprintf(buffer,"/sys/class/gpio/gpio%d/direction", gpio);
+    file = open(buffer, O_WRONLY);
+    if(file == -1)
+    {
+        LOGE("[MBTK_POWER] Open gpio[%d] direct fail.", gpio);
+        return MBTK_POWER_RESULT_FAIL;
+    }
+
+    result = write(file,value,strlen(value));
+    if(result != strlen(value))
+    {
+        LOGE("[MBTK_POWER] Set gpio[%d] direct fail.", gpio);
+        close(file);
+        return MBTK_POWER_RESULT_FAIL;
+    }
+    close(file);
+
+    return MBTK_POWER_RESULT_SUCCESS;
+}
+
+static int gpio_value_set(int value, int gpio)
+{
+    char buffer[50]= {0};
+    int file =-1;
+    int result =-1;
+
+    memset(buffer,0,50);
+    sprintf(buffer,"/sys/class/gpio/gpio%d/value", gpio);
+    file = open(buffer,O_WRONLY);
+    if(file == -1)
+    {
+        LOGE("[MBTK_POWER] Open gpio[%d] value fail.", gpio);
+        return MBTK_POWER_RESULT_FAIL;
+    }
+    if(value == 0) {
+        result = write(file,"0",1);
+    } else {
+        result = write(file,"1",1);
+    }
+    if(result != 1)
+    {
+        LOGE("[MBTK_POWER] Set gpio[%d] value fail.", gpio);
+        close(file);
+        return MBTK_POWER_RESULT_FAIL;
+    }
+    close(file);
+
+    return MBTK_POWER_RESULT_SUCCESS;
+}
+
+//type:0 value 0
+//type:1 value 1
+//type:2 direction "out"
+//type:3 direction "in"
+
+static int one_gpio_export(int gpio, int type)
+{
+    int index=0;
+    int file=-1;
+    int file1=-1;
+    int result =-1;
+    char pin_index_buffer[5]= {0};
+    char buffer[50]= {0};
+    int ret =0;
+
+    file = open("/sys/class/gpio/export",O_WRONLY);
+    if(file == -1)
+    {
+        LOGE("[MBTK_POWER] Open gpio export file fail.");
+        return MBTK_POWER_RESULT_FAIL;
+    }
+
+    memset(buffer,0,50);
+    sprintf(buffer,"/sys/class/gpio/gpio%d", gpio);
+    file1 = open(buffer,O_RDONLY);
+    if(file1 != -1)
+    {
+        //file is created
+        close(file1);
+    }
+    else
+    { // create gpio
+        memset(pin_index_buffer,0,5);
+        sprintf(pin_index_buffer,"%d",gpio);
+        result = write(file,pin_index_buffer,strlen(pin_index_buffer));
+        if(result < 0)
+        {
+            LOGE("[MBTK_POWER] Gpio[%d] export fail.", gpio);
+            return MBTK_POWER_RESULT_FAIL;
+        }
+    }
+
+    close(file);
+
+
+    switch(type)
+    {
+        case 0 :
+        {
+            ret = gpio_value_set(0, gpio);
+            break;
+        }
+        case 1:
+        {
+            ret = gpio_value_set(1, gpio);
+            break;
+        }
+        case 2:
+        {
+            ret = gpio_direct_set("out", gpio);
+            break;
+        }
+        case 3:
+        {
+            ret = gpio_direct_set("in", gpio);
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+
+
+    return ret;
+}
+
+/****************************FUNC***************************************/
+
+/****************************API***************************************/
+#if defined(MBTK_PROJECT_T108)
+int mbtk_system_sleep(void)
+{
+    int ubus_ret = 0;
+
+    ubus_ret = mbtk_power_gnss_close();
+    if(ubus_ret < 0)
+    {
+        LOGE("[MBTK_POWER] mbtk_power_gnss_close() fail.");
+        return MBTK_POWER_RESULT_GNSS_CLOSE_FAIL;
+    }
+
+    // echo off > /sys/devices/mbtk-dev-op.10/gps_power && echo mem > /sys/power/autosleep
+    // echo 1 > /sys/devices/asr-rfkill.0/pwr_ctrl && sleep 2 && echo 0 > /sys/devices/asr-rfkill.0/pwr_ctrl
+
+    if(!access("/sys/power/autosleep", W_OK))
+    {
+        system("echo mem > /sys/power/autosleep");
+    }
+    else
+    {
+        LOGE("[MBTK_POWER] /sys/power/autosleep can not write.");
+        //printf("/sys/power/autosleep can not write.");
+        return MBTK_POWER_RESULT_NO_SLEEP_NODE;
+    }
+
+    return MBTK_POWER_RESULT_SUCCESS;
+}
+
+#elif defined(MBTK_PROJECT_L508_X6)
+int mbtk_system_sleep(void)
+{
+    int ubus_ret = 0;
+
+    ubus_ret = mbtk_power_gnss_close();
+    if(ubus_ret < 0)
+    {
+        LOGE("[MBTK_POWER] mbtk_power_gnss_close() fail.");
+        return MBTK_POWER_RESULT_GNSS_CLOSE_FAIL;
+    }
+
+    // echo off > /sys/devices/mbtk-dev-op.10/gps_power && echo mem > /sys/power/autosleep
+    // echo 1 > /sys/devices/asr-rfkill.0/pwr_ctrl && sleep 2 && echo 0 > /sys/devices/asr-rfkill.0/pwr_ctrl
+    //close Ldo6
+    system("i2cset -y -f 2 0x31 0x18 0x0f");
+    //GPS_WAKE_HOST to GPIO
+    system("hwacc w 0xd401e198 0x1040");
+    //HOST_WAKE_GPS to GPIO
+    //system("hwacc w 0xd401e0c0 0x1040");
+    //gpio34 to GPIO
+#if 1
+    system("hwacc w 0xd401e164 0x1040");
+	system("hwacc w 0xd401e166 0x1040");
+	system("hwacc w 0xd401e1b4 0x1040");
+
+    system("hwacc w 0xd401e2ec 0xa441");
+    system("hwacc w 0xd401e2f0 0xa441");
+    system("hwacc w 0xd401e2f4 0xa441");
+    system("hwacc w 0xd401e2f8 0xa441");
+    system("hwacc w 0xd401e2fc 0xa441");
+    system("hwacc w 0xd401e300 0xa441");
+#endif
+    one_gpio_export(117, 2);
+    one_gpio_export(117, 0);
+
+    one_gpio_export(119, 2);
+    one_gpio_export(119, 0);
+
+    one_gpio_export(127, 2);
+    one_gpio_export(127, 0);
+
+    one_gpio_export(33, 2);
+    one_gpio_export(33, 0);
+
+    one_gpio_export(34, 2);
+    one_gpio_export(34, 0);
+
+    one_gpio_export(54, 2);
+    one_gpio_export(54, 0);
+
+    one_gpio_export(21, 2);
+    one_gpio_export(21, 0);
+
+    one_gpio_export(118, 2);
+    one_gpio_export(118, 0);
+
+    if(!access("/sys/power/autosleep", W_OK))
+    {
+        system("echo mem > /sys/power/autosleep");
+    }
+    else
+    {
+        LOGE("[MBTK_POWER] /sys/power/autosleep can not write.");
+        //printf("/sys/power/autosleep can not write.");
+        return MBTK_POWER_RESULT_NO_SLEEP_NODE;
+    }
+
+    return MBTK_POWER_RESULT_SUCCESS;
+}
+
+#elif defined(MBTK_PROJECT_L509)
+int mbtk_system_sleep(void)
+{
+    int ubus_ret = 0;
+
+    ubus_ret = mbtk_power_gnss_close();
+    if(ubus_ret < 0)
+    {
+        LOGE("[MBTK_POWER] mbtk_power_gnss_close() fail.");
+        return MBTK_POWER_RESULT_GNSS_CLOSE_FAIL;
+    }
+
+    // echo off > /sys/devices/mbtk-dev-op.10/gps_power && echo mem > /sys/power/autosleep
+    // echo 1 > /sys/devices/asr-rfkill.0/pwr_ctrl && sleep 2 && echo 0 > /sys/devices/asr-rfkill.0/pwr_ctrl
+
+    one_gpio_export(120, 2);
+    one_gpio_export(120, 0);
+
+    one_gpio_export(21, 2);
+    one_gpio_export(21, 0);
+
+    one_gpio_export(118, 2);
+    one_gpio_export(118, 0);
+
+    if(!access("/sys/power/autosleep", W_OK))
+    {
+        system("echo mem > /sys/power/autosleep");
+    }
+    else
+    {
+        LOGE("[MBTK_POWER] /sys/power/autosleep can not write.");
+        //printf("/sys/power/autosleep can not write.");
+        return MBTK_POWER_RESULT_NO_SLEEP_NODE;
+    }
+
+    return MBTK_POWER_RESULT_SUCCESS;
+}
+
+#elif defined(MBTK_PROJECT_L508)
+int mbtk_system_sleep(void)
+{
+    int ubus_ret = 0;
+
+    ubus_ret = mbtk_power_gnss_close();
+    if(ubus_ret < 0)
+    {
+        LOGE("[MBTK_POWER] mbtk_power_gnss_close() fail.");
+        return MBTK_POWER_RESULT_GNSS_CLOSE_FAIL;
+    }
+
+    // echo off > /sys/devices/mbtk-dev-op.10/gps_power && echo mem > /sys/power/autosleep
+    // echo 1 > /sys/devices/asr-rfkill.0/pwr_ctrl && sleep 2 && echo 0 > /sys/devices/asr-rfkill.0/pwr_ctrl
+
+    one_gpio_export(119, 2);
+    one_gpio_export(119, 0);
+
+    one_gpio_export(21, 2);
+    one_gpio_export(21, 0);
+
+    one_gpio_export(118, 2);
+    one_gpio_export(118, 0);
+
+    if(!access("/sys/power/autosleep", W_OK))
+    {
+        system("echo mem > /sys/power/autosleep");
+    }
+    else
+    {
+        LOGE("[MBTK_POWER] /sys/power/autosleep can not write.");
+        //printf("/sys/power/autosleep can not write.");
+        return MBTK_POWER_RESULT_NO_SLEEP_NODE;
+    }
+
+    return MBTK_POWER_RESULT_SUCCESS;
+}
+
+#elif defined(MBTK_PROJECT_PN1803)
+int mbtk_system_sleep(void)
+{
+    int ubus_ret = 0;
+
+    ubus_ret = mbtk_power_gnss_close();
+    if(ubus_ret < 0)
+    {
+        LOGE("[MBTK_POWER] mbtk_power_gnss_close() fail.");
+        return MBTK_POWER_RESULT_GNSS_CLOSE_FAIL;
+    }
+
+    // echo off > /sys/devices/mbtk-dev-op.10/gps_power && echo mem > /sys/power/autosleep
+    // echo 1 > /sys/devices/asr-rfkill.0/pwr_ctrl && sleep 2 && echo 0 > /sys/devices/asr-rfkill.0/pwr_ctrl
+
+    one_gpio_export(119, 2);
+    one_gpio_export(119, 0);
+
+    one_gpio_export(21, 2);
+    one_gpio_export(21, 0);
+
+    one_gpio_export(118, 2);
+    one_gpio_export(118, 0);
+
+    if(!access("/sys/power/autosleep", W_OK))
+    {
+        system("echo mem > /sys/power/autosleep");
+    }
+    else
+    {
+        LOGE("[MBTK_POWER] /sys/power/autosleep can not write.");
+        //printf("/sys/power/autosleep can not write.");
+        return MBTK_POWER_RESULT_NO_SLEEP_NODE;
+    }
+
+    return MBTK_POWER_RESULT_SUCCESS;
+}
+
+#else
+int mbtk_system_sleep(void)
+{
+    return MBTK_POWER_RESULT_SUCCESS;
+}
+#endif
+/****************************API***************************************/
+#endif
diff --git a/mbtk/mbtk_at/src/mbtk_at.c b/mbtk/mbtk_at/src/mbtk_at.c
new file mode 100755
index 0000000..3389857
--- /dev/null
+++ b/mbtk/mbtk_at/src/mbtk_at.c
@@ -0,0 +1,229 @@
+/*
+*
+*
+* Author : lb
+* Date   : 2021/11/5 10:53:49
+*
+*/
+#include "telutl.h"
+#include "mbtk_at.h"
+#include <dlfcn.h>
+#include <include/log.h>
+#include <stdarg.h>
+#include <errno.h>
+
+// See utlAtParameterOp_T
+static char *at_op_list[] = {"UNKNOWN", "EXEC", "GET", "SET", "ACTION", "TEST", NULL};
+
+
+//void* mbtk_cmd_line_ex = NULL;
+#ifdef MBTK_DATA_MODE_SUPPORT
+static mbtk_data_mode_callback_func data_mode_cb = NULL;
+static TelAtParserID mbtk_atp_index = TEL_AT_CMD_ATP_0;
+static char datamode_buff[4096];
+static int datamode_buff_len = 0;
+#endif
+
+#if 0
+mbtk_audio_exec_f mbtk_at_play = NULL;
+mbtk_audio_exec_f mbtk_at_rec = NULL;
+#endif
+
+typedef struct {
+    /*mbtk_at_func_type_enum type;*/
+    char lib_name[50];
+    void *handle;
+} mbtk_at_lib_info_t;
+
+mbtk_at_func_t *func_list = NULL;
+static mbtk_at_lib_info_t lib_list[] = {
+    {"/lib/libmbtk_lib.so", NULL},      /* MBTK_AT_FUNC_TYPE_BASIC */
+    //{"/lib/libmbtk_factory.so", NULL},  /* MBTK_AT_FUNC_TYPE_FACTORY */
+    //{"/lib/libmbtk_audio.so", NULL},    /* MBTK_AT_FUNC_TYPE_AUDIO */
+    //{"/lib/libmbtk_gnss.so", NULL},     /* MBTK_AT_FUNC_TYPE_GNSS */
+    //{"/lib/libmbtk_ecall.so", NULL},    /* MBTK_AT_FUNC_TYPE_ECALL */
+    //{"/lib/libmbtk_socket.so", NULL},   /* MBTK_AT_FUNC_TYPE_SOCKET */
+    //{"/lib/libmbtk_tcpip.so", NULL},    /* MBTK_AT_FUNC_TYPE_TCPIP */
+    //{"/lib/libmbtk_http.so", NULL},     /* MBTK_AT_FUNC_TYPE_HTTP */
+    //{"/lib/libmbtk_ftp.so", NULL}       /* MBTK_AT_FUNC_TYPE_FTP */
+};
+
+BOOL getExtValue( const utlAtParameterValue_P2c param_value_p,
+                  int index,
+                  int *value_p,
+                  int minValue,
+                  int maxValue,
+                  int DefaultValue);
+
+BOOL getExtUValue(const utlAtParameterValue_P2c param_value_p,
+                  int index,
+                  unsigned int *value_p,
+                  unsigned int minValue,
+                  unsigned int maxValue,
+                  unsigned int DefaultValue);
+
+BOOL getExtString( const utlAtParameterValue_P2c param_value_p,
+                    int index,
+                    CHAR *outString,
+                    INT16 maxStringLength,
+                    INT16 *outStringLength,
+                    CHAR *defaultString);
+
+void mbtk_log(int level, const char *format, ...)
+{
+	char *timestr;
+	char buf[1024];
+	va_list ap;
+	struct timeval log_time;
+	int length = 0;
+
+	va_start(ap, format);
+	length = vsnprintf(buf,1024,format,ap);
+	if(length > 0) {
+        __android_log_printf(LOG_ID_RADIO, level, "%s", buf);
+    }
+
+	va_end(ap);
+}
+
+char *op2str(utlAtParameterOp_T op)
+{
+    return at_op_list[op];
+}
+
+static bool str_empty(const void *str)
+{
+    if (str && strlen((char*)str) > 0)
+        return false;
+
+    return true;
+}
+
+void func_add(mbtk_at_func_type_enum type, char *name)
+{
+    if(!str_empty(name)) {
+        mbtk_at_func_t *func_ptr = (mbtk_at_func_t*)malloc(sizeof(mbtk_at_func_t));
+        if(func_ptr) {
+            memset(func_ptr, 0x0, sizeof(mbtk_at_func_t));
+            func_ptr->type = type;
+            memcpy(func_ptr->name, name, strlen(name));
+
+            func_ptr->next = func_list;
+            func_list = func_ptr;
+        }
+    }
+}
+
+mbtk_at_func_t *func_get(char *name)
+{
+    mbtk_at_func_t *func_ptr = func_list;
+    while(func_ptr) {
+        if(!strcmp(func_ptr->name, name)) {
+            return func_ptr;
+        }
+        func_ptr = func_ptr->next;
+    }
+
+    return func_ptr;
+}
+
+void mbtk_at_proc_null()
+{
+    LOG("MBTK_AT function not found in so.");
+}
+
+int mbtk_lib_init()
+{
+    #define MBTK_FUNC_INIT
+    #include "mbtk_at_func.h"
+    #undef MBTK_FUNC_INIT
+
+    set_service_log_tag("MBTK_AT");
+    mbtk_at_func_t *func_ptr = func_list;
+    while(func_ptr) {
+        if(lib_list[func_ptr->type].handle == NULL) {
+            lib_list[func_ptr->type].handle = dlopen(lib_list[func_ptr->type].lib_name , RTLD_LAZY);
+        }
+
+        if(lib_list[func_ptr->type].handle) {
+            func_ptr->func = dlsym(lib_list[func_ptr->type].handle, func_ptr->name);
+            if(func_ptr->func == NULL) {
+                LOG("%s() dlsym from %s fail.", func_ptr->name, lib_list[func_ptr->type].lib_name);
+                //return -1;
+                func_ptr->func = mbtk_at_proc_null;
+            } else {
+                LOG("%s function : %s", lib_list[func_ptr->type].lib_name, func_ptr->name);
+            }
+        } else {
+            LOG("dlopen() %s fail : %d", lib_list[func_ptr->type].lib_name, errno);
+            //return -1;
+            func_ptr->func = mbtk_at_proc_null;
+        }
+
+        func_ptr = func_ptr->next;
+    }
+    return 0;
+}
+
+#ifdef MBTK_DATA_MODE_SUPPORT
+static utlReturnCode_T mbtk_utlAtTxLineDataFunction_P(const unsigned char *octets_p, const size_t n, void *arg_p)
+{
+    if(n > 0) {
+        LOG("DATA[%d]:%s", n, octets_p);
+        LOG("ARG:%s", arg_p);
+        if(datamode_buff_len + n > 4096) {
+            utlAtParserOp(aParser_p[mbtk_atp_index], utlAT_PARSER_OP_DISABLE_BYPASS_MODE);
+            ATRESP(MAKE_AT_HANDLE(mbtk_atp_index), ATCI_RESULT_CODE_ERROR, 0, NULL);
+            return utlSUCCESS;
+        }
+
+        memcpy(datamode_buff + datamode_buff_len, octets_p, n);
+        datamode_buff_len += n;
+
+        // control-z(0x1a)
+        if(datamode_buff[datamode_buff_len - 1] == 0x1a) {
+            utlAtParserOp(aParser_p[mbtk_atp_index], utlAT_PARSER_OP_DISABLE_BYPASS_MODE);
+            datamode_buff[datamode_buff_len - 1] = '\0';
+            datamode_buff_len--;
+
+            ATRESP(MAKE_AT_HANDLE(mbtk_atp_index), ATCI_RESULT_CODE_OK, 0, datamode_buff);
+            //ATRESP(MAKE_AT_HANDLE(mbtk_atp_index), ATCI_RESULT_CODE_OK, 0, "OK");
+
+            if(data_mode_cb) {
+                data_mode_cb(datamode_buff, datamode_buff_len);
+                data_mode_cb = NULL;
+            }
+        }
+    }
+
+    return utlSUCCESS;
+}
+
+utlReturnCode_T mbtk_data_mode_enter(TelAtParserID atp_index, mbtk_data_mode_callback_func cb)
+{
+    data_mode_cb = cb;
+    utlReturnCode_T result = utlAtParserOp(aParser_p[atp_index], utlAT_PARSER_OP_ENABLE_BYPASS_MODE);
+    if (result != utlSUCCESS)
+    {
+    	LOG("(utlAT_PARSER_OP_ENABLE_BYPASS_MODE)Enter data mode fail[%d].", result);
+    	result = ATRESP(MAKE_AT_HANDLE(atp_index), ATCI_RESULT_CODE_ERROR, 0, NULL);
+    } else {
+        result = utlAtParserOp(aParser_p[atp_index], utlAT_PARSER_OP_SET_TX_LINE_DATA_HANDLER, mbtk_utlAtTxLineDataFunction_P);
+        if (result == utlSUCCESS)
+        {
+            // ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, "\r\n>>\r\n");
+            LOG("Enter data mode success.");
+            mbtk_atp_index = atp_index;
+            memset(datamode_buff, 0x0, 4096);
+            datamode_buff_len = 0;
+
+            result = ATRESP(MAKE_AT_HANDLE(atp_index), ATCI_RESULT_CODE_OK, 0, ">>");
+        } else {
+            LOG("(utlAT_PARSER_OP_SET_TX_LINE_DATA_HANDLER)Enter data mode fail[%d].", result);
+            result = ATRESP(MAKE_AT_HANDLE(atp_index), ATCI_RESULT_CODE_ERROR, 0, NULL);
+        }
+    }
+
+    return result;
+}
+#endif
\ No newline at end of file
diff --git a/mbtk/mbtk_at/src/mbtk_at_basic.c b/mbtk/mbtk_at/src/mbtk_at_basic.c
new file mode 100755
index 0000000..55638ef
--- /dev/null
+++ b/mbtk/mbtk_at/src/mbtk_at_basic.c
@@ -0,0 +1,2322 @@
+/*
+* MBTK Basic AT Process.
+*
+* Author : lb
+* Date   : 2021/11/5 10:14:32
+*
+*/
+#include "mbtk_at.h"
+#include "mbtk_device_info.h"
+#include "mbtk/mbtk_type.h"
+#include "mbtk/mbtk_device.h"
+#include <dlfcn.h>
+
+//#include <sys/statfs.h>
+#include <sys/vfs.h>
+#include <errno.h>
+#include <linux/magic.h>
+#include <time.h>
+#include <sys/time.h>
+#include <signal.h>
+#include <pthread.h>
+#include <time.h>
+#include <sys/time.h>
+#include <cutils/properties.h>
+#include "configwrapper.h"
+#include<linux/msg.h>
+
+//#include "gps.h"
+#include "atcmdsvr_ubus.h"
+
+#define MAX_GPIO_TEST_NUM 60
+
+typedef int (*mbtk_dev_info_read_func)(mbtk_device_info_item_enum, void *, int);
+
+#define MBTK_LIB_PATH "/lib/libmbtk_lib.so"
+const struct blobmsg_policy gps_user_cb_policy1[] = {
+    [0] = {
+        .name = "event",
+        .type = BLOBMSG_TYPE_INT32,
+    },
+};
+
+bool mbtk_urc_enable = TRUE;
+
+int mbtk_at_loopback(int type);
+int mbtk_at_play(const char *args);
+int mbtk_at_rec(const char *args);
+
+typedef struct
+{
+    int gpio;
+    bool busy;
+    bool state;
+} mbtk_gpio_state_t;
+
+static bool gpio_test_usable = true;
+
+static mbtk_gpio_state_t gpio_pins[] =
+{
+    {22, FALSE, FALSE},     // IN
+    {33,FALSE,FALSE},
+    {35,FALSE,FALSE},
+    {36,FALSE,FALSE},
+    {34,FALSE,FALSE},
+    {21,FALSE,FALSE},
+    {4,FALSE,FALSE},
+    {123,FALSE,FALSE},
+    {20,FALSE,FALSE},
+    {43,FALSE,FALSE},
+    {13,FALSE,FALSE},
+//    {12,FALSE,FALSE},
+    {14,FALSE,FALSE},
+    {118,FALSE,FALSE},
+//    {19,FALSE,FALSE},
+    {120,FALSE,FALSE},
+    {49,FALSE,FALSE},
+    {50,FALSE,FALSE},
+    {32,FALSE,FALSE},
+    {31,FALSE,FALSE},
+    {51,FALSE,FALSE},
+//    {23,FALSE,FALSE},
+    {24,FALSE,FALSE},
+    {52,FALSE,FALSE},
+    {27,FALSE,FALSE},
+    {28,FALSE,FALSE},
+    {26,FALSE,FALSE},
+    {25,FALSE,FALSE},
+    {5,FALSE,FALSE},
+    {0,FALSE,FALSE},
+    {1,FALSE,FALSE},
+    {2,FALSE,FALSE},
+    {3,FALSE,FALSE},
+    {6,FALSE,FALSE},
+    {7,FALSE,FALSE},
+    {15,FALSE,FALSE},
+    {18,FALSE,FALSE},
+    {16,FALSE,FALSE},
+    {17,FALSE,FALSE},
+    {54,FALSE,FALSE},
+    {53,FALSE,FALSE},
+    {48,FALSE,FALSE},
+    {55,FALSE,FALSE},
+    {58,FALSE,FALSE},
+    {57,FALSE,FALSE},
+    {29,FALSE,FALSE},
+    {30,FALSE,FALSE},
+    {99,FALSE,FALSE},
+    {126,FALSE,FALSE},
+    {125,FALSE,FALSE},
+    {56,FALSE,FALSE},
+    {59,FALSE,FALSE},
+    {117,FALSE,FALSE},
+//    {122,FALSE,FALSE}
+};
+
+int gpio_register_auto_test_out(int *result);
+
+#define MBTK_GPIO_NUM (sizeof(gpio_pins)/sizeof(mbtk_gpio_state_t))
+
+static bool dev_info_inited = FALSE;
+static mbtk_device_info_basic_t info_basic;
+static mbtk_device_info_modem_t info_modem;
+
+static int dev_info_get()
+{
+    if(dev_info_inited) {
+        return 0;
+    }
+    void *handle = dlopen(MBTK_LIB_PATH , RTLD_LAZY);
+    if(handle == NULL)
+    {
+        DBGMSG(MBTK_AT, "dlopen() %s fail : %d", MBTK_LIB_PATH, errno);
+        return -1;
+    }
+
+    mbtk_dev_info_read_func dev_info_read = (mbtk_dev_info_read_func)dlsym(handle, "mbtk_dev_info_read");
+    if(dev_info_read == NULL)
+    {
+        DBGMSG(MBTK_AT, "dlsym(mbtk_dev_info_read) fail : %d", errno);
+        return -1;
+    }
+
+    memset(&info_basic, 0, sizeof(mbtk_device_info_basic_t));
+    memset(&info_modem, 0, sizeof(mbtk_device_info_modem_t));
+
+    // mbtk_dev_info_read()
+    int result = dev_info_read(MBTK_DEVICE_INFO_ITEM_BASIC, &info_basic, sizeof(mbtk_device_info_basic_t));
+    if(result) {
+        DBGMSG(MBTK_AT, "mbtk_dev_info_read(BASIC) fail.");
+        return -1;
+    }
+
+    result = dev_info_read(MBTK_DEVICE_INFO_ITEM_MODEM, &info_modem, sizeof(mbtk_device_info_modem_t));
+    if(result) {
+        DBGMSG(MBTK_AT, "mbtk_dev_info_read(MODEM) fail.");
+        return -1;
+    }
+
+    dev_info_inited = TRUE;
+    return 0;
+}
+
+static char* band_area_2_str(mbtk_modem_band_area_enum band_area)
+{
+    switch(band_area) {
+        case MBTK_MODEM_BAND_AREA_CN:
+            return "CN";
+        case MBTK_MODEM_BAND_AREA_EU:
+            return "EU";
+        case MBTK_MODEM_BAND_AREA_SA:
+            return "SA";
+        default:
+            return "DEF";
+    }
+}
+
+static int gpio_export(void)
+{
+    int index=0;
+    int file=-1;
+    int result =-1;
+    char pin_index_buffer[5]= {0};
+
+    for(index = 0; index < MBTK_GPIO_NUM; index++)
+    {
+        file = open("/sys/class/gpio/export",O_WRONLY);
+        if(file == -1)
+        {
+            LOG("Open gpio export file fail.");
+            return -1;
+        }
+
+        memset(pin_index_buffer,0,5);
+        sprintf(pin_index_buffer,"%d",gpio_pins[index].gpio);
+        result = write(file,pin_index_buffer,strlen(pin_index_buffer));
+        if(result < 0)
+        {
+            LOG("Gpio[%d] export fail.", gpio_pins[index].gpio);
+            gpio_pins[index].busy = TRUE;
+        }
+        close(file);
+    }
+
+    return 0;
+}
+
+static int gpio_unexport(void)
+{
+    int index=0;
+    int file=-1;
+    int result =-1;
+    char pin_index_buffer[5]= {0};
+
+    for(index = 0; index < MBTK_GPIO_NUM; index++)
+    {
+        if(!gpio_pins[index].busy)
+        {
+            file = open("/sys/class/gpio/unexport",O_WRONLY);
+            if(file == -1)
+            {
+                LOG("Open gpio unexport file fail.");
+                return -1;
+            }
+
+            memset(pin_index_buffer,0,5);
+            sprintf(pin_index_buffer,"%d",gpio_pins[index].gpio);
+            result=write(file,pin_index_buffer,strlen(pin_index_buffer));
+            if(result < 0)
+            {
+                close(file);
+                LOG("Gpio[%d] unexport fail.",gpio_pins[index].gpio);
+                return -1;
+            }
+            close(file);
+        }
+    }
+
+    return 0;
+}
+
+static int gpio_direct_set(char *value,int gpio)
+{
+    char buffer[50]= {0};
+    int file =-1;
+    int result =-1;
+
+    memset(buffer,0,50);
+    sprintf(buffer,"/sys/class/gpio/gpio%d/direction", gpio);
+    file = open(buffer, O_WRONLY);
+    if(file == -1)
+    {
+        LOG("Open gpio[%d] direct fail.", gpio);
+        return -1;
+    }
+
+    result = write(file,value,strlen(value));
+    if(result != strlen(value))
+    {
+        LOG("Set gpio[%d] direct fail.", gpio);
+        close(file);
+        return -1;
+    }
+    close(file);
+
+    return 0;
+}
+
+static int gpio_value_get(int gpio)
+{
+    char buffer[50];
+    char path[10];
+    int file =-1;
+    int result =-1;
+    int value;
+
+    memset(path,0,50);
+    memset(buffer,0,10);
+    sprintf(path,"/sys/class/gpio/gpio%d/value", gpio);
+    file = open(path,O_RDONLY);
+    if(file == -1)
+    {
+        LOG("Open gpio[%d] fail.", gpio);
+        return -1;
+    }
+    result = read(file,buffer,5);
+    if(result <= 0)
+    {
+        LOG("Get gpio[%d] value fail", gpio);
+        close(file);
+        return -1;
+    }
+    close(file);
+    value = atoi(buffer);
+    return value;
+}
+
+static int gpio_value_set(int value, int gpio)
+{
+    char buffer[50]= {0};
+    int file =-1;
+    int result =-1;
+
+    memset(buffer,0,50);
+    sprintf(buffer,"/sys/class/gpio/gpio%d/value", gpio);
+    file = open(buffer,O_WRONLY);
+    if(file == -1)
+    {
+        LOG("Open gpio[%d] value fail.", gpio);
+        return -1;
+    }
+    if(value == 0) {
+        result = write(file,"0",1);
+    } else {
+        result = write(file,"1",1);
+    }
+    if(result != 1)
+    {
+        LOG("Set gpio[%d] value fail.", gpio);
+        close(file);
+        return -1;
+    }
+    close(file);
+
+    return 0;
+}
+
+//type:0 value 0
+//type:1 value 1
+//type:2 direction "out"
+//type:3 direction "in"
+
+static int one_gpio_export(int gpio, int type)
+{
+    int index=0;
+    int file=-1;
+    int file1=-1;
+    int result =-1;
+    char pin_index_buffer[5]= {0};
+    char buffer[50]= {0};
+    int ret =0;
+
+    file = open("/sys/class/gpio/export",O_WRONLY);
+    if(file == -1)
+    {
+        LOG("Open gpio export file fail.");
+        return -1;
+    }
+
+    memset(buffer,0,50);
+    sprintf(buffer,"/sys/class/gpio/gpio%d", gpio);
+    file1 = open(buffer,O_RDONLY);
+    if(file1 != -1)
+    {
+        //file is created
+    }
+    else{ // create gpio
+        memset(pin_index_buffer,0,5);
+        sprintf(pin_index_buffer,"%d",gpio);
+        result = write(file,pin_index_buffer,strlen(pin_index_buffer));
+        if(result < 0)
+        {
+            ATRESP(IND_REQ_HANDLE , ATCI_RESULT_CODE_NULL, 0, "Gpio export fail");
+            LOG("Gpio[%d] export fail.", gpio);
+            return -1;
+        }
+    }
+
+    close(file);
+
+
+    switch(type)
+    {
+        case 0 :
+        {
+            ret = gpio_value_set(0, gpio);
+            break;
+        }
+        case 1:
+        {
+            ret = gpio_value_set(1, gpio);
+            break;
+        }
+        case 2:
+        {
+            ret = gpio_direct_set("out", gpio);
+            break;
+        }
+        case 3:
+        {
+            ret = gpio_direct_set("in", gpio);
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+
+
+    return ret;
+}
+
+
+static int gpio_test(void)
+{
+    int index = 0;
+    int fail_count = 0;
+    gpio_export();
+
+    gpio_direct_set("in", gpio_pins[0].gpio);
+    //set all gpio low level start
+    for(index = 1; index < MBTK_GPIO_NUM; index++)
+    {
+        if(!gpio_pins[index].busy)
+        {
+            gpio_direct_set("out", gpio_pins[index].gpio);
+            gpio_value_set(0, gpio_pins[index].gpio);
+        }
+    }
+
+    if(gpio_value_get(gpio_pins[0].gpio) != 0)
+    {
+        LOG("gpio_test set all gpio level[%d] fail", gpio_pins[0].gpio);
+        gpio_unexport();
+        return -1;
+    }
+    //set all gpio low level end
+
+#if 1
+    for(index = 1; index < MBTK_GPIO_NUM; index++)
+    {
+        if(!gpio_pins[index].busy)
+        {
+            gpio_value_set(1, gpio_pins[index].gpio);
+            if(gpio_value_get(gpio_pins[index].gpio) == 1 && gpio_value_get(gpio_pins[0].gpio) == 1)
+            {
+                gpio_pins[index].state = TRUE;
+            }
+            else
+            {
+                LOG("gpio[%d] input not match output level [1]", gpio_pins[index].gpio);
+                gpio_pins[index].state = FALSE;
+                fail_count++;
+                continue;
+            }
+        }
+    }
+
+    if(fail_count > 0) {
+        gpio_unexport();
+        return fail_count;
+    }
+
+    for(index = 1; index < MBTK_GPIO_NUM; index++)
+    {
+        if(!gpio_pins[index].busy)
+        {
+            gpio_value_set(0, gpio_pins[index].gpio);
+            if(gpio_value_get(gpio_pins[index].gpio) == 0 && gpio_value_get(gpio_pins[0].gpio) == 0)
+            {
+                gpio_pins[index].state = TRUE;
+            }
+            else
+            {
+                LOG("gpio[%d] input not match output level [0]", gpio_pins[index].gpio);
+                gpio_pins[index].state = FALSE;
+                fail_count++;
+                continue;
+            }
+        }
+    }
+
+    gpio_unexport();
+#endif
+    return fail_count;
+}
+
+static int gpio_test2(void)
+{
+    int index=0;
+    int value=0;
+    int fail_count = 0;
+    //export all test gpio
+    gpio_export();
+
+
+    //set main control gpio in
+    gpio_direct_set("in", gpio_pins[0].gpio);
+    for(index = 1; index < MBTK_GPIO_NUM; index++)
+    {
+        gpio_direct_set("out",gpio_pins[index].gpio);
+        gpio_value_set(1, gpio_pins[index].gpio);
+    }
+
+    if(gpio_value_get(gpio_pins[0].gpio) != 1)
+    {
+        LOG("gpio_test set all gpio level[%d] fail", gpio_pins[0].gpio);
+        gpio_unexport();
+        return -1;
+    }
+
+    //set all gpio value as 0
+    for(index = 1; index < MBTK_GPIO_NUM; index++)
+    {
+        gpio_value_set(0, gpio_pins[index].gpio);
+    }
+
+    //set gpio direct in except main control gpio
+    for(index = 1; index < MBTK_GPIO_NUM; index++)
+    {
+        gpio_direct_set("in",gpio_pins[index].gpio);
+    }
+
+    //set main control gpio out
+    gpio_direct_set("out",gpio_pins[0].gpio);
+    gpio_value_set(1,gpio_pins[0].gpio);
+    for(index = 1; index < MBTK_GPIO_NUM; index++)
+    {
+        value = -1;
+        value=gpio_value_get(gpio_pins[index].gpio);
+        if(1==value)
+        {
+            gpio_pins[index].state = TRUE;
+        }
+        else
+        {
+            LOG("gpio[%d] input not match output level [0]", gpio_pins[index].gpio);
+            gpio_pins[index].state = FALSE;
+            fail_count++;
+            continue;
+        }
+    }
+    //unexport gpio
+    gpio_unexport();
+
+    return fail_count;
+//set main
+}
+
+
+uint64 partion_space_get(const char *path)
+{
+    unsigned long long totle = 0;
+    unsigned long long blocksize = 0;
+    struct statfs diskInfo;
+
+    if(path == NULL){
+        return 0;
+    }
+    memset(&diskInfo, 0, sizeof(diskInfo));
+
+    if(statfs(path, &diskInfo)){
+        LOG("statfs() fail - %d.", errno);
+        return 0;
+    }
+    blocksize = diskInfo.f_bsize;
+    LOG("path=%s [totle=%lld MB] :f_type= %lld, f_bsize=%lld, f_blocks=%lld, f_bfree=%lld, f_bavail%lld\n", path,totle,
+	diskInfo.f_type, diskInfo.f_bsize,diskInfo.f_blocks,diskInfo.f_bfree, diskInfo.f_bavail);
+
+    // MSDOS_SUPER_MAGIC     0x4d44
+    if((diskInfo.f_type & 0x0ffff) == MSDOS_SUPER_MAGIC) {
+        totle = (diskInfo.f_blocks * blocksize) >> 20;
+        return totle;
+    } else {
+        LOG("Unknow fs type : %x", diskInfo.f_type);
+        return 0;
+    }
+}
+
+static unsigned int shell_at_handle;
+static void shell_cb_func(char *buf,int buf_size)
+{
+    if(buf && buf_size > 0)
+    {
+        char resp_buf[MBTK_AT_RESP_LEN_MAX] = {0};
+        snprintf(resp_buf, MBTK_AT_RESP_LEN_MAX, "+MSHELL: %d\r\n%s\r\n",
+                 buf_size, buf);
+        //MBTK_FUNC(log_hex)("+MSHELL", buf, buf_size);
+        ATRESP(shell_at_handle, ATCI_RESULT_CODE_NULL, 0, resp_buf);
+    }
+}
+
+int metis_strptime(char *str_time)
+{
+    struct tm stm;
+    char dateTime[30];
+    struct timeval tv;
+    if( strptime(str_time, "%Y-%m-%d %H:%M:%S",&stm) != NULL)
+    {
+        printf("success\n");
+    }
+    else{
+        printf("error\n");
+        return -1;
+    }
+
+//    printf("设置系统时间前的时间是:\n");
+//    system("date");
+    time_t _t = mktime(&stm);
+//    stime(&_t);
+    tv.tv_sec = _t;
+//    tv.tv_usec = USEC(pnew_time_packet->transmit_timestamp.fine);
+    settimeofday(&tv, NULL);
+
+    printf("设置系统时间HOU的时间是:\n");
+//    system("date");
+
+    return 0;
+}
+
+extern int mbtk_time_type;
+
+#if 0
+static void gpio_timer_alrm_func(int signo)
+{
+    LOG("TIMEOUT : %d", signo);
+    if(SIGALRM == signo) {
+        gpio_test_usable = true;
+        LOG("gpio_test_usable has reset to true.");
+    }
+}
+#else
+static void* gpio_thread_func(void *arg)
+{
+    sleep(1);
+    gpio_test_usable = true;
+    LOG("gpio_test_usable has reset to true.");
+    return NULL;
+}
+#endif
+#ifdef MBTK_DATA_MODE_SUPPORT
+static void data_mode_callback_cb(const char *data, int data_len)
+{
+    LOG("DATA - %d:%s", data_len, data);
+}
+#endif
+
+utlReturnCode_T MBTK_AT_MTEST_PROCESS(const utlAtParameterOp_T op,
+                                      const char *command_name_p,
+                                      const utlAtParameterValue_P2c parameter_values_p,
+                                      const size_t num_parameters,
+                                      const char *info_text_p,
+                                      unsigned int *xid_p,
+                                      void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlSUCCESS;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int At_handle = MAKE_AT_HANDLE(sAtp_index);
+    char resp_buf[MBTK_AT_RESP_LEN_MAX] = {0};
+    unsigned int svc_id = 0;
+    *xid_p = At_handle;
+
+    const static int arg2_len_max = 10;
+    static int arg1 = 0;
+    static char arg2[MBTK_AT_RESP_LEN_MAX];
+
+    LOG("MBTK_AT_MTEST_PROCESS enter with command_op [%s]", op2str(op));
+
+    switch(op)
+    {
+        case TEL_EXT_GET_CMD :
+        {
+            sprintf(resp_buf, "%s : %d,\"%s\"\r\n", command_name_p, arg1, arg2);
+            ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);
+            break;
+        }
+        case TEL_EXT_SET_CMD :
+        {
+            if(!getExtValue(parameter_values_p, 0, &arg1, 0, 1, 0))
+            {
+                ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+
+            int len = 0;
+            memset(arg2, 0x0, MBTK_AT_RESP_LEN_MAX);
+            if(!getExtString(parameter_values_p, 1, arg2, arg2_len_max, &len, "test"))
+            {
+                ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+
+            ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+            break;
+        }
+        case TEL_EXT_ACTION_CMD :
+        {
+            // ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, "ACTION_OK");
+#ifdef MBTK_DATA_MODE_SUPPORT
+            ret = mbtk_data_mode_enter(sAtp_index, data_mode_callback_cb);
+#else
+			ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, "ACTION_OK");
+#endif
+            break;
+        }
+
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+
+}
+
+
+utlReturnCode_T MBTK_AT_MINFO_PROCESS(const utlAtParameterOp_T op,
+                                       const char *command_name_p,
+                                       const utlAtParameterValue_P2c parameter_values_p,
+                                       const size_t num_parameters,
+                                       const char *info_text_p,
+                                       unsigned int *xid_p,
+                                       void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int at_handle = MAKE_AT_HANDLE(sAtp_index);
+    *xid_p = at_handle;
+
+    LOG("%s enter with command_op [%s]", command_name_p, op2str(op));
+
+    switch(op)
+    {
+        case TEL_EXT_ACTION_CMD :
+        {
+            char resp_buf[MBTK_AT_RESP_LEN_MAX] = {0};
+            if(!dev_info_get()) {
+                snprintf(resp_buf, MBTK_AT_RESP_LEN_MAX,
+                    "Revision:%s\r\n"
+                    "Custom_Model:%s\r\n"
+                    "Module_Type:%s\r\n",
+                    strlen(info_basic.revision_out) > 0 ? info_basic.revision_out: "Unknown",
+                    strlen(info_basic.project_cust) > 0 ? info_basic.project_cust: "Unknown",
+                    band_area_2_str(info_modem.band_area));
+            } else {
+                snprintf(resp_buf, MBTK_AT_RESP_LEN_MAX,
+                    "Revision:%s\r\n"
+                    "Custom_Model:%s\r\n"
+                    "Module_Type:%s\r\n",
+                    "Unknown", "Unknown", "Unknown");
+            }
+            ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+}
+
+utlReturnCode_T MBTK_AT_SYSTIME_PROCESS(const utlAtParameterOp_T op,
+                                      const char *command_name_p,
+                                      const utlAtParameterValue_P2c parameter_values_p,
+                                      const size_t num_parameters,
+                                      const char *info_text_p,
+                                      unsigned int *xid_p,
+                                      void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlSUCCESS;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int At_handle = MAKE_AT_HANDLE(sAtp_index);
+    char resp_buf[MBTK_AT_RESP_LEN_MAX] = {0};
+    unsigned int svc_id = 0;
+    *xid_p = At_handle;
+
+    const static int arg2_len_max = 10;
+    static int arg1 = 0;
+
+    printf("MBTK_AT_SYSTIME_PROCESS enter with command_op [%s]", op2str(op));
+
+    switch(op)
+    {
+        case TEL_EXT_GET_CMD :
+        {
+            char time_type[10] = {0};
+            property_get("persist.mbtk.time_type", time_type, "0");
+            mbtk_time_type = atoi(time_type);
+            sprintf(resp_buf, "%s: %d\r\n", command_name_p, mbtk_time_type);
+            ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);
+            break;
+        }
+        case TEL_EXT_SET_CMD :
+        {
+            if(!getExtValue(parameter_values_p, 0, &arg1, 0, 2, 0))
+            {
+                ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+
+            if(num_parameters > 1) {
+    		    const static int cmd_len_max = MBTK_AT_RESP_LEN_MAX;
+                static char time_str[MBTK_AT_RESP_LEN_MAX];
+                int len = 0;
+                memset(time_str, 0x0, MBTK_AT_RESP_LEN_MAX);
+                if(!getExtString(parameter_values_p, 1, time_str, cmd_len_max, &len, ""))
+                {
+                    ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                    LOG("Get CMD Fail.");
+                    break;
+                }
+
+                if(strlen(time_str) > 0)
+                {
+                    ret = metis_strptime(time_str);
+                }
+            }
+
+            mbtk_time_type = arg1;
+            char type_str[10] = {0};
+            sprintf(type_str, "%d", mbtk_time_type);
+            property_set("persist.mbtk.time_type", type_str);
+            if(ret < 0)
+            {
+                ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+            }
+            else
+            {
+                ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+            }
+
+			break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+    return ret;
+}
+
+utlReturnCode_T MBTK_AT_MTESTF_PROCESS(const utlAtParameterOp_T op,
+                                       const char *command_name_p,
+                                       const utlAtParameterValue_P2c parameter_values_p,
+                                       const size_t num_parameters,
+                                       const char *info_text_p,
+                                       unsigned int *xid_p,
+                                       void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlSUCCESS;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int At_handle = MAKE_AT_HANDLE(sAtp_index);
+    char resp_buf[MBTK_AT_RESP_LEN_MAX] = {0};
+    unsigned int svc_id = 0;
+    *xid_p = At_handle;
+
+    const static int arg2_len_max = 10;
+    static int arg1 = 0;
+    static char arg2[MBTK_AT_RESP_LEN_MAX];
+
+    LOG("MBTK_AT_MTESTF_PROCESS enter with command_op [%s]", op2str(op));
+
+    switch(op)
+    {
+        case TEL_EXT_GET_CMD :
+        {
+            sprintf(resp_buf, "%s : %d,\"%s\"\r\n", command_name_p, arg1, arg2);
+            ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);
+            break;
+        }
+        case TEL_EXT_SET_CMD :
+        {
+            if(!getExtValue(parameter_values_p, 0, &arg1, 0, 1, 0))
+            {
+                ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+
+            int len = 0;
+            memset(arg2, 0x0, MBTK_AT_RESP_LEN_MAX);
+            if(!getExtString(parameter_values_p, 1, arg2, arg2_len_max, &len, "test"))
+            {
+                ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+
+            ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+            break;
+        }
+        case TEL_EXT_TEST_CMD :
+        {
+            ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, "+MTESTF=(0,1),\"\"");
+            break;
+        }
+        case TEL_EXT_ACTION_CMD :
+        {
+            ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, "ACTION_OK");
+            break;
+        }
+
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+
+}
+
+
+utlReturnCode_T MBTK_AT_MSHELL_PROCESS(const utlAtParameterOp_T op,
+                                       const char *command_name_p,
+                                       const utlAtParameterValue_P2c parameter_values_p,
+                                       const size_t num_parameters,
+                                       const char *info_text_p,
+                                       unsigned int *xid_p,
+                                       void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    shell_at_handle = MAKE_AT_HANDLE(sAtp_index);
+    *xid_p = shell_at_handle;
+
+    LOG("MBTK_AT_MSHELL_PROCESS enter with command_op [%s]", op2str(op));
+
+    switch(op)
+    {
+        case TEL_EXT_SET_CMD :
+        {
+            const static int cmd_len_max = MBTK_AT_RESP_LEN_MAX;
+            static char cmd[MBTK_AT_RESP_LEN_MAX];
+            int len = 0;
+            memset(cmd, 0x0, MBTK_AT_RESP_LEN_MAX);
+            if(!getExtString(parameter_values_p, 0, cmd, cmd_len_max, &len, ""))
+            {
+                ret = ATRESP(shell_at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                LOG("Get CMD Fail.");
+                break;
+            }
+
+            //if(strlen(cmd) > 0 && mbtk_cmd_line_ex(cmd, shell_cb_func))
+            if(strlen(cmd) > 0 && MBTK_FUNC(mbtk_cmd_line_ex)(cmd, shell_cb_func))
+            {
+                ret = ATRESP(shell_at_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+            }
+            else
+            {
+                LOG("CMD length error.");
+                break;
+            }
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+
+}
+
+utlReturnCode_T MBTK_AT_ISLKVRSCAN_PROCESS(const utlAtParameterOp_T op,
+        const char *command_name_p,
+        const utlAtParameterValue_P2c parameter_values_p,
+        const size_t num_parameters,
+        const char *info_text_p,
+        unsigned int *xid_p,
+        void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int at_handle = MAKE_AT_HANDLE(sAtp_index);
+    *xid_p = at_handle;
+
+    LOG("MBTK_AT_ISLKVRSCAN_PROCESS enter with command_op [%s]", op2str(op));
+
+#ifndef MBTK_BUILD_TIME
+#define MBTK_BUILD_TIME "Unknown"
+#endif
+
+    switch(op)
+    {
+        case TEL_EXT_ACTION_CMD :
+        {
+            char resp_buf[MBTK_AT_RESP_LEN_MAX] = {0};
+            if(!dev_info_get()) {
+                snprintf(resp_buf, MBTK_AT_RESP_LEN_MAX, "Version: %s\r\nBuild time: %s\r\n",
+                     strlen(info_basic.revision_out) > 0 ? info_basic.revision_out: "Unknown",
+                     strlen(info_basic.build_time) > 0 ? info_basic.build_time: "Unknown");
+            } else {
+                snprintf(resp_buf, MBTK_AT_RESP_LEN_MAX, "Version: %s\r\nBuild time: %s\r\n",
+                     "Unknown", "Unknown");
+            }
+            ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+
+}
+
+utlReturnCode_T MBTK_AT_SDTEST_PROCESS(const utlAtParameterOp_T op,
+                                       const char *command_name_p,
+                                       const utlAtParameterValue_P2c parameter_values_p,
+                                       const size_t num_parameters,
+                                       const char *info_text_p,
+                                       unsigned int *xid_p,
+                                       void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int at_handle = MAKE_AT_HANDLE(sAtp_index);
+    *xid_p = at_handle;
+
+    LOG("%s enter with command_op [%s]", command_name_p, op2str(op));
+
+    switch(op)
+    {
+        case TEL_EXT_ACTION_CMD :
+        {
+            // SDVOLUME:xxxMB
+            // OK
+            // /mnt/mmcblk0p1
+            #if (defined(MBTK_PROJECT_L508_X6) || defined(MBTK_PROJECT_T108) || defined(MBTK_PROJECT_L509) || defined(MBTK_PROJECT_L508))
+            int i =0 ;
+            uint64 size = 0;
+            for(i = 0; i < 3; i++)
+            {
+                if(i == 0)
+                {
+                    size = partion_space_get("/sdcard");
+                }
+                else if(i == 1)
+                {
+                    size = partion_space_get("/system/etc/www/webdav/sdcard");
+                }
+                else
+                {
+                    system("mkfs.vfat -F 32 /dev/mmcblk0");
+                    system("mount -t vfat /dev/mmcblk0 /mnt");
+                    size = partion_space_get("/mnt");
+                }
+
+                if(size > 0)
+                {
+                    LOG("[SDTEST] i = %d, size = %d", i, size);
+                    break;
+                }
+
+                size = 0;
+            }
+            #else
+            uint64 size = partion_space_get("/mnt/mmcblk0p1");
+            #endif
+            char resp_buf[MBTK_AT_RESP_LEN_MAX] = {0};
+            if(size > 0) {
+                snprintf(resp_buf, MBTK_AT_RESP_LEN_MAX, "SDVOLUME:%lldMB\r\n", size);
+            } else {
+                snprintf(resp_buf, MBTK_AT_RESP_LEN_MAX, "SDVOLUME:0MB\r\n");
+            }
+            ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+}
+
+
+utlReturnCode_T MBTK_AT_SPKTEST_PROCESS(const utlAtParameterOp_T op,
+                                        const char *command_name_p,
+                                        const utlAtParameterValue_P2c parameter_values_p,
+                                        const size_t num_parameters,
+                                        const char *info_text_p,
+                                        unsigned int *xid_p,
+                                        void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int at_handle = MAKE_AT_HANDLE(sAtp_index);
+    *xid_p = at_handle;
+
+    LOG("MBTK_AT_SPKTEST_PROCESS enter with command_op [%s]", op2str(op));
+
+    switch(op)
+    {
+        case TEL_EXT_ACTION_CMD :
+        {
+            // SDVOLUME:MB
+            // OK
+            char resp_buf[MBTK_AT_RESP_LEN_MAX] = {0};
+
+            mbtk_at_play(NULL);
+
+            snprintf(resp_buf, MBTK_AT_RESP_LEN_MAX, "Audio spk test.\r\nBuild time: %s\r\n",
+                     MBTK_BUILD_TIME);
+            ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);
+
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+}
+
+utlReturnCode_T MBTK_AT_MICTEST_PROCESS(const utlAtParameterOp_T op,
+                                        const char *command_name_p,
+                                        const utlAtParameterValue_P2c parameter_values_p,
+                                        const size_t num_parameters,
+                                        const char *info_text_p,
+                                        unsigned int *xid_p,
+                                        void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int at_handle = MAKE_AT_HANDLE(sAtp_index);
+    *xid_p = at_handle;
+
+    LOG("MBTK_AT_MICTEST_PROCESS enter with command_op [%s]", op2str(op));
+
+    switch(op)
+    {
+        case TEL_EXT_ACTION_CMD :
+        {
+            // SDVOLUME:MB
+            // OK
+            char resp_buf[MBTK_AT_RESP_LEN_MAX] = {0};
+
+            mbtk_at_rec(NULL);
+            snprintf(resp_buf, MBTK_AT_RESP_LEN_MAX, "Audio record test.\r\nBuild time: %s\r\n",
+                     MBTK_BUILD_TIME);
+            ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+}
+
+utlReturnCode_T MBTK_AT_REVTEST_PROCESS(const utlAtParameterOp_T op,
+                                        const char *command_name_p,
+                                        const utlAtParameterValue_P2c parameter_values_p,
+                                        const size_t num_parameters,
+                                        const char *info_text_p,
+                                        unsigned int *xid_p,
+                                        void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int at_handle = MAKE_AT_HANDLE(sAtp_index);
+    *xid_p = at_handle;
+    char resp_buf[MBTK_AT_RESP_LEN_MAX] = {0};
+    int arg1 = 0;
+
+    static bool loopback_running = FALSE;
+
+    LOG("MBTK_AT_REVTEST_PROCESS enter with command_op [%s]", op2str(op));
+
+    switch(op)
+    {
+        case TEL_EXT_GET_CMD :
+        {
+            sprintf(resp_buf, "%s : %d\r\n", command_name_p, arg1);
+            ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);
+            break;
+        }
+        case TEL_EXT_SET_CMD :
+        {
+            if(!getExtValue(parameter_values_p, 0, &arg1, 0, 1, 0))
+            {
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+            #if (defined(MBTK_PROJECT_L508_X6) || defined(MBTK_PROJECT_T108))
+            if(arg1 == 1)
+            {
+                system("ubus call audio_if loopback_enable '{\"param0\":1}'");
+            }
+            else
+            {
+                system("ubus call audio_if loopback_disable");
+            }
+            #else
+            LOG("MBTK_AT_REVTEST_PROCESS arg1 [%d]", arg1);
+            mbtk_at_loopback(arg1);
+            //sprintf(resp_buf, "%s : ,\"%s\"\r\n", command_name_p, "TEL_EXT_SET_CMD");
+            #endif
+            ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+            break;
+        }
+        case TEL_EXT_ACTION_CMD :
+        {
+            if(!loopback_running) {
+                #if (defined(MBTK_PROJECT_L508_X6) || defined(MBTK_PROJECT_T108))
+                system("ubus call audio_if loopback_enable '{\"param0\":1}'");
+                #else
+                mbtk_at_loopback(1);
+                #endif
+                loopback_running = TRUE;
+            } else {
+                #if (defined(MBTK_PROJECT_L508_X6) || defined(MBTK_PROJECT_T108))
+                system("ubus call audio_if loopback_disable");
+                #else
+                mbtk_at_loopback(0);
+                #endif
+                loopback_running = FALSE;
+            }
+            //snprintf(resp_buf, MBTK_AT_RESP_LEN_MAX, "Audio loopback test.\r\nBuild time: %s\r\n",
+            //         MBTK_BUILD_TIME);
+            ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+}
+
+utlReturnCode_T MBTK_AT_GPIOTEST_PROCESS(const utlAtParameterOp_T op,
+        const char *command_name_p,
+        const utlAtParameterValue_P2c parameter_values_p,
+        const size_t num_parameters,
+        const char *info_text_p,
+        unsigned int *xid_p,
+        void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int at_handle = MAKE_AT_HANDLE(sAtp_index);
+    int gnss_support = 0;
+    *xid_p = at_handle;
+
+    LOG("MBTK_AT_GPIOTEST_PROCESS enter with command_op [%s]", op2str(op));
+
+    switch(op)
+    {
+        case TEL_EXT_SET_CMD :
+        {
+            if(!getExtValue(parameter_values_p, 0, &gnss_support, 0, 1, 0))
+            {
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+        }
+        case TEL_EXT_ACTION_CMD :
+        {
+            if(gpio_test_usable) {
+                gpio_test_usable = false;
+            } else { // GPIO test is busy.
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_SUPPRESS, 0, NULL);
+                break;
+            }
+
+#if 1
+			int test_result[MAX_GPIO_TEST_NUM];
+			memset(test_result,0,sizeof(test_result));
+            int result = mbtk_at_gpio((bool)gnss_support, test_result);
+            if(result < 0)
+            {
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, "GPIO TEST FAIL\r\n");
+            }
+            else if(result == 0) {
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, "ALL GPIO TEST PASS\r\n");
+            }
+            else
+            {
+                char resp_buf[MBTK_AT_RESP_LEN_MAX] = {0};
+                int index;
+                sprintf(resp_buf, "GPIOTEST Fail %02d PINs:", result);
+                for(index = 0; index < result &&index < MAX_GPIO_TEST_NUM; index++)
+                {
+                    sprintf(resp_buf + strlen(resp_buf), "%03d,", test_result[index]);
+                }
+                resp_buf[strlen(resp_buf) - 1] = '\r';
+                resp_buf[strlen(resp_buf)] = '\n';
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);
+            }
+#else
+            int fail_count = gpio_test();
+            if(fail_count < 0) {
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, "GPIO TEST FAIL\r\n");
+            } else if(fail_count == 0){
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, "ALL GPIO TEST PASS\r\n");
+            } else {
+                char resp_buf[MBTK_AT_RESP_LEN_MAX] = {0};
+                int index;
+                sprintf(resp_buf, "GPIOTEST Fail %02d PINs:", fail_count);
+                for(index = 0; index < MBTK_GPIO_NUM; index++)
+                {
+                    if(!gpio_pins[index].state) {
+                        sprintf(resp_buf + strlen(resp_buf), "%03d,", gpio_pins[index].gpio);
+                    }
+                }
+                resp_buf[strlen(resp_buf) - 1] = '\r';
+                resp_buf[strlen(resp_buf)] = '\n';
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);
+            }
+#endif
+
+            // Set gpio_test_usable to true after 1s.
+#if 0
+            signal(SIGALRM, gpio_timer_alrm_func);
+            struct itimerval val;
+            // Only time
+            val.it_interval.tv_sec  = 0;
+            val.it_interval.tv_usec = 0;
+            // Time
+            val.it_value.tv_sec  = 1;
+            val.it_value.tv_usec = 0;
+            if (setitimer(ITIMER_REAL, &val, NULL) == -1)
+            {
+                LOG("setitimer fail.[errno - %d]",errno);
+            }
+#else
+            pthread_t gpio_thread_id;
+            if (pthread_create(&gpio_thread_id, NULL, gpio_thread_func, NULL) != 0)
+            {
+                LOG("%s errno: %d (%s)",__func__, errno, strerror(errno));
+            }
+#endif
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+}
+
+utlReturnCode_T MBTK_AT_ADCGETV_PROCESS(const utlAtParameterOp_T op,
+                                        const char *command_name_p,
+                                        const utlAtParameterValue_P2c parameter_values_p,
+                                        const size_t num_parameters,
+                                        const char *info_text_p,
+                                        unsigned int *xid_p,
+                                        void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int at_handle = MAKE_AT_HANDLE(sAtp_index);
+    char resp_buf[MBTK_AT_RESP_LEN_MAX] = {0};
+    int arg1 = 0;
+    *xid_p = at_handle;
+
+    LOG("MBTK_AT_ADCGETV_PROCESS enter with command_op [%s]", op2str(op));
+
+    switch(op)
+    {
+        case TEL_EXT_ACTION_CMD :
+        {
+            // SDVOLUME:MB
+            // OK
+            snprintf(resp_buf, MBTK_AT_RESP_LEN_MAX, "ADC Version: %s\r\nBuild time: %s\r\n",
+                     MBTK_DEVICES_REVISION, MBTK_BUILD_TIME);
+            ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);
+            break;
+        }
+        case TEL_EXT_SET_CMD :
+        {
+            int adc_ret;
+            if(!getExtValue(parameter_values_p, 0, &arg1, 0, 2, 0))
+            {
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+            adc_ret = mbtk_at_adc(arg1);
+            LOG("MBTK_AT_ADC_PROCESS adc [%d]", adc_ret);
+            sprintf(resp_buf, "%s:%d,%d\r\n", command_name_p, arg1, adc_ret);
+            ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+}
+
+utlReturnCode_T MBTK_AT_RGMIITEST_PROCESS(const utlAtParameterOp_T op,
+                                        const char *command_name_p,
+                                        const utlAtParameterValue_P2c parameter_values_p,
+                                        const size_t num_parameters,
+                                        const char *info_text_p,
+                                        unsigned int *xid_p,
+                                        void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int at_handle = MAKE_AT_HANDLE(sAtp_index);
+    *xid_p = at_handle;
+
+    LOG("MBTK_AT_RGMIITEST_PROCESS enter with command_op [%s]", op2str(op));
+
+    switch(op)
+    {
+        case TEL_EXT_ACTION_CMD :
+        {
+            #if defined(MBTK_PROJECT_T108)
+            int result = -1;
+            int rgmii_test_num = 0;
+            char buf[50] = {0};
+            static char rgmii_flag = 0;
+            //mbtk_mdio("eth0", 0, 0x9800, 0xc834);
+            //mbtk_mdio("eth0", 0,  0x0, 0xa000);
+            for(rgmii_test_num = 0; rgmii_test_num < 3; rgmii_test_num++)
+            {
+                if(!rgmii_flag)
+                {
+                    system("/bin/mbtk_mdio eth0 0x9800 0xc834");
+                    system("/bin/mbtk_mdio eth0 0x0 0xa000");
+                }
+                result = mbtk_rgmii_loopback();
+                if(result < 0)
+                {
+                    //
+                }
+                else
+                {
+                    memcpy(buf, "+RGMIITEST: phy loopback ok", strlen("+RGMIITEST: phy loopback ok"));
+                    ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, buf);
+                    rgmii_flag = 1;
+                    break;
+                }
+            }
+
+            if(result < 0)
+            {
+                memcpy(buf, "+RGMIITEST: phy loopback fail", strlen("+RGMIITEST: phy loopback fail"));
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, buf);
+            }
+            break;
+            #endif
+        }
+        default:
+        {
+            ret = ATRESP( at_handle, ATCI_RESULT_CODE_CME_ERROR, CME_OPERATION_NOT_SUPPORTED, NULL);
+            break;
+        }
+    }
+
+    return ret;
+}
+
+utlReturnCode_T MBTK_AT_MGPSC_PROCESS(const utlAtParameterOp_T op,
+                                        const char *command_name_p,
+                                        const utlAtParameterValue_P2c parameter_values_p,
+                                        const size_t num_parameters,
+                                        const char *info_text_p,
+                                        unsigned int *xid_p,
+                                        void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int at_handle = MAKE_AT_HANDLE(sAtp_index);
+    char resp_buf[MBTK_AT_RESP_LEN_MAX] = {0};
+    int arg1 = 0;
+    *xid_p = at_handle;
+
+    LOG("MBTK_AT_MGPSC_PROCESS enter with command_op [%s]", op2str(op));
+
+    switch(op)
+    {
+        case TEL_EXT_SET_CMD :
+        {
+            int gnss_ret;
+            if(!getExtValue(parameter_values_p, 0, &arg1, 0, 11, 0))
+            {
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+#if 1
+            if (arg1 == 5 || arg1 == 1 || arg1 ==0)
+            {
+                if (1 == arg1)
+                {
+                    gnss_ret = mbtk_mgpsc_set(arg1);
+                    if (gnss_ret < 0)
+                    {
+                        ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, "+GPS: init fail.\r\n");
+                    }
+                    else
+                    {
+                        ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, "+GPS: init success.\r\n");
+                    }
+                }
+                else if (arg1 == 5)
+                {
+                    ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+                }
+                else
+                {
+                    gnss_ret = mbtk_mgpsc_set(arg1);
+                    if (gnss_ret < 0)
+                    {
+                        ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, "+GPS: deinit fail.\r\n");
+                    }
+                    else
+                    {
+                        ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, "+GPS: deinit success.\r\n");
+                    }                }
+            }
+            else
+            {
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+#else
+            if(1 == arg1 || 11 == arg1 || 10 == arg1 || 9 == arg1)
+                gnss_ret = MBTK_FUNC(mbtk_at_gnss)(arg1, at_gnss_handler_function);
+            else if (6 == arg1)
+                gnss_ret = at_gnss_firmware_update();
+            else
+                gnss_ret = MBTK_FUNC(mbtk_at_gnss)(arg1, NULL);
+
+            LOG("%s gnss [%d]", __FUNCTION__, gnss_ret);
+            sprintf(resp_buf, "%s:%d,%d\r\n", command_name_p, arg1, gnss_ret);
+            ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);
+#endif
+
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+}
+
+utlReturnCode_T MBTK_AT_CGNETLED_PROCESS(const utlAtParameterOp_T op,
+                                        const char *command_name_p,
+                                        const utlAtParameterValue_P2c parameter_values_p,
+                                        const size_t num_parameters,
+                                        const char *info_text_p,
+                                        unsigned int *xid_p,
+                                        void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int at_handle = MAKE_AT_HANDLE(sAtp_index);
+    *xid_p = at_handle;
+
+    LOG("MBTK_AT_CGNETLED_PROCESS enter with command_op [%s]", op2str(op));
+    switch(op)
+    {
+        case TEL_EXT_SET_CMD :
+        {
+            int led_switch;
+            if(!getExtValue(parameter_values_p, 0, &led_switch, 0, 1, 0))
+            {
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+
+            if(led_switch == 0 || led_switch == 1) {
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+            }
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+}
+
+utlReturnCode_T MBTK_AT_SYSSLEEP_PROCESS(const utlAtParameterOp_T op,
+                                        const char *command_name_p,
+                                        const utlAtParameterValue_P2c parameter_values_p,
+                                        const size_t num_parameters,
+                                        const char *info_text_p,
+                                        unsigned int *xid_p,
+                                        void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int at_handle = MAKE_AT_HANDLE(sAtp_index);
+    *xid_p = at_handle;
+
+    TelAtParserID origParserId = *(TelAtParserID *)arg_p;
+
+    LOG("MBTK_AT_SYSSLEEP_PROCESS enter with command_op [%s]", op2str(op));
+    switch(op)
+    {
+        case TEL_EXT_SET_CMD:
+        case TEL_EXT_ACTION_CMD:
+        {
+            // [ -e /sys/class/devfreq/devfreq-ddr/polling_interval ] && {
+            //    echo 50 > /sys/class/devfreq/devfreq-ddr/polling_interval
+            // }
+
+            // [ -e /sys/power/autosleep ] && {
+            //    echo booting 8000000000 > /sys/power/wake_lock
+            //    echo mem > /sys/power/autosleep
+            // }
+
+            //close GPS set gpio 21/118: out / 0
+            int result = -1;
+            result = mbtk_system_sleep();
+            if(result != 0)
+            {
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+            }
+            else
+            {
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+            }
+#if 0
+            int ubus_ret = 0;
+            ubus_ret = invoke_reply_data_cb(origParserId, "gps", "gnss_deinit", NULL, (ubus_data_handler_t *)gps_usr_callback_hdl, &at_handle, 4000);
+            if(ubus_ret < 0)
+            {
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_SUPPRESS, 0, "BUSY");
+                break;
+            }
+            else if(ubus_ret > 0)
+            {
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+#ifdef MBTK_PROJECT_L508
+            system("echo 0 > /sys/class/gpio/gpio119/value");
+#else
+#ifdef MBTK_PROJECT_PN1803
+            system("echo 0 > /sys/class/gpio/gpio119/value");
+#else
+#ifdef MBTK_PROJECT_L509
+            system("echo 0 > /sys/class/gpio/gpio120/value");
+#endif
+#endif
+#endif
+
+#ifdef MBTK_PROJECT_L508_X6
+            //close Ldo6
+            system("i2cset -y -f 2 0x31 0x18 0x0f");
+            //GPS_WAKE_HOST to GPIO
+            system("hwacc w 0xd401e198 0x1040");
+            //HOST_WAKE_GPS to GPIO
+            //system("hwacc w 0xd401e0c0 0x1040");
+            //gpio34 to GPIO
+            #if 1
+            system("hwacc w 0xd401e164 0x1040");
+			system("hwacc w 0xd401e166 0x1040");
+			system("hwacc w 0xd401e1b4 0x1040");
+
+            system("hwacc w 0xd401e2ec 0xa441");
+            system("hwacc w 0xd401e2f0 0xa441");
+            system("hwacc w 0xd401e2f4 0xa441");
+            system("hwacc w 0xd401e2f8 0xa441");
+            system("hwacc w 0xd401e2fc 0xa441");
+            system("hwacc w 0xd401e300 0xa441");
+
+            if(one_gpio_export(117, 2))
+            {
+                LOG("GPIO SET ERROR.");
+            }
+            if(one_gpio_export(117, 0))
+            {
+                LOG("GPIO SET ERROR.");
+            }
+			if(one_gpio_export(119, 2))
+            {
+                LOG("GPIO SET ERROR.");
+            }
+            if(one_gpio_export(119, 0))
+            {
+                LOG("GPIO SET ERROR.");
+            }
+
+
+            if(one_gpio_export(127, 2))
+            {
+                LOG("GPIO SET ERROR.");
+            }
+            if(one_gpio_export(127, 0))
+            {
+                LOG("GPIO SET ERROR.");
+            }
+			 if(one_gpio_export(34, 2))
+            {
+                LOG("GPIO SET ERROR.");
+            }
+            if(one_gpio_export(34, 0))
+            {
+                LOG("GPIO SET ERROR.");
+            }
+			 if(one_gpio_export(33, 2))
+            {
+                LOG("GPIO SET ERROR.");
+            }
+            if(one_gpio_export(33, 0))
+            {
+                LOG("GPIO SET ERROR.");
+            }
+		    if(one_gpio_export(54, 2))
+            {
+                LOG("GPIO SET ERROR.");
+            }
+            if(one_gpio_export(54, 0))
+            {
+                LOG("GPIO SET ERROR.");
+            }
+
+            #endif
+#endif
+
+#ifdef MBTK_PROJECT_T108
+
+#else
+            if(one_gpio_export(21, 2))
+            {
+                LOG("GPIO SET ERROR.");
+            }
+            if(one_gpio_export(21, 0))
+            {
+                LOG("GPIO SET ERROR.");
+            }
+            if(one_gpio_export(118, 2))
+            {
+                LOG("GPIO SET ERROR.");
+            }
+            if(one_gpio_export(118, 0))
+            {
+                LOG("GPIO SET ERROR.");
+            }
+#endif
+            // echo off > /sys/devices/mbtk-dev-op.10/gps_power && echo mem > /sys/power/autosleep
+            // echo 1 > /sys/devices/asr-rfkill.0/pwr_ctrl && sleep 2 && echo 0 > /sys/devices/asr-rfkill.0/pwr_ctrl
+
+            if(!access("/sys/power/autosleep", W_OK))
+                system("echo mem > /sys/power/autosleep");
+            else
+                LOG("/sys/power/autosleep can not write.");
+            ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+#endif
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+}
+
+static int port_config(mbtk_port_type_enum type, mbtk_port_mode_enum mode) {
+
+    char type_buff[32] = {0};
+    char mode_buff[32] = {0};
+    switch(type)
+    {
+        case MBTK_PORT_TYPE_UART1:
+            strcpy(type_buff, "persist.mbtk.dev_ttyS1");
+            break;
+        case MBTK_PORT_TYPE_USB1:
+            strcpy(type_buff, "persist.mbtk.dev_ttyGS0");
+            break;
+        case MBTK_PORT_TYPE_USB2:
+            strcpy(type_buff, "persist.mbtk.dev_ttymodem0");
+            break;
+        default:
+            return -1;
+    }
+    switch(mode)
+    {
+        case MBTK_PORT_MODE_AT:
+            strcpy(mode_buff, "at");
+            break;
+        case MBTK_PORT_MODE_ADB:
+            strcpy(mode_buff, "adb");
+            break;
+        case MBTK_PORT_MODE_CUSTOM:
+            strcpy(mode_buff, "custom");
+            break;
+        default:
+            return -1;
+    }
+    return property_set(type_buff, mode_buff);
+}
+
+utlReturnCode_T MBTK_AT_MPORTCFG_PROCESS(const utlAtParameterOp_T op,
+                                        const char *command_name_p,
+                                        const utlAtParameterValue_P2c parameter_values_p,
+                                        const size_t num_parameters,
+                                        const char *info_text_p,
+                                        unsigned int *xid_p,
+                                        void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int at_handle = MAKE_AT_HANDLE(sAtp_index);
+    *xid_p = at_handle;
+    char resp_buf[1024] = {0};
+
+    LOG("MBTK_AT_MPORTCFG_PROCESS enter with command_op [%s]", op2str(op));
+    switch(op)
+    {
+        case TEL_EXT_SET_CMD:
+		{
+            int arg;
+            if(!getExtValue(parameter_values_p, 0, &arg, 0, 2, 0))
+            {
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+            mbtk_port_type_enum type = (mbtk_port_type_enum)arg;
+            if(!getExtValue(parameter_values_p, 1, &arg, 0, 2, 0))
+            {
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+            mbtk_port_mode_enum mode = (mbtk_port_mode_enum)arg;
+
+            if(port_config(type, mode)) {
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+            } else {
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+            }
+
+            break;
+		}
+        case TEL_EXT_GET_CMD :
+        {
+            int len = 0;
+            char port_config[32] = {0};
+            property_get("persist.mbtk.dev_ttyS1", port_config, "at");
+            if(!strcmp(port_config, "adb")) {
+                len += sprintf(resp_buf + len, "%s : %d,%d\r\n", command_name_p, MBTK_PORT_TYPE_UART1, MBTK_PORT_MODE_ADB);
+            } else if(!strcmp(port_config, "custom")) {
+                len += sprintf(resp_buf + len, "%s : %d,%d\r\n", command_name_p, MBTK_PORT_TYPE_UART1, MBTK_PORT_MODE_CUSTOM);
+            } else {
+                len += sprintf(resp_buf + len, "%s : %d,%d\r\n", command_name_p, MBTK_PORT_TYPE_UART1, MBTK_PORT_MODE_AT);
+            }
+
+            memset(port_config, 0, 32);
+            property_get("persist.mbtk.dev_ttyGS0", port_config, "at");
+            if(!strcmp(port_config, "adb")) {
+                len += sprintf(resp_buf + len, "%s : %d,%d\r\n", command_name_p, MBTK_PORT_TYPE_USB1, MBTK_PORT_MODE_ADB);
+            } else if(!strcmp(port_config, "custom")) {
+                len += sprintf(resp_buf + len, "%s : %d,%d\r\n", command_name_p, MBTK_PORT_TYPE_USB1, MBTK_PORT_MODE_CUSTOM);
+            } else {
+                len += sprintf(resp_buf + len, "%s : %d,%d\r\n", command_name_p, MBTK_PORT_TYPE_USB1, MBTK_PORT_MODE_AT);
+            }
+
+            memset(port_config, 0, 32);
+            property_get("persist.mbtk.dev_ttymodem0", port_config, "at");
+            if(!strcmp(port_config, "adb")) {
+                len += sprintf(resp_buf + len, "%s : %d,%d\r\n", command_name_p, MBTK_PORT_TYPE_USB2, MBTK_PORT_MODE_ADB);
+            } else if(!strcmp(port_config, "custom")) {
+                len += sprintf(resp_buf + len, "%s : %d,%d\r\n", command_name_p, MBTK_PORT_TYPE_USB2, MBTK_PORT_MODE_CUSTOM);
+            } else {
+                len += sprintf(resp_buf + len, "%s : %d,%d\r\n", command_name_p, MBTK_PORT_TYPE_USB2, MBTK_PORT_MODE_AT);
+            }
+
+            ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+}
+
+utlReturnCode_T MBTK_AT_MURCECHO_PROCESS(const utlAtParameterOp_T op,
+                                        const char *command_name_p,
+                                        const utlAtParameterValue_P2c parameter_values_p,
+                                        const size_t num_parameters,
+                                        const char *info_text_p,
+                                        unsigned int *xid_p,
+                                        void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int At_handle = MAKE_AT_HANDLE(sAtp_index);
+    *xid_p = At_handle;
+    char resp_buf[MBTK_AT_RESP_LEN_MAX] = {0};
+
+    static int arg1 = 0;
+
+    LOG("MBTK_AT_MTEST_PROCESS enter with command_op [%s]", op2str(op));
+
+    switch(op)
+    {
+        case TEL_EXT_GET_CMD :
+        {
+            sprintf(resp_buf, "%s : %d\r\n", command_name_p, mbtk_urc_enable);
+            ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);
+            break;
+        }
+        case TEL_EXT_SET_CMD :
+        {
+            if(!getExtValue(parameter_values_p, 0, &arg1, 0, 1, 0))
+            {
+                ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+
+            mbtk_urc_enable = (bool)arg1;
+
+            ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+}
+
+RETURNCODE_T  MBTK_AT_READVER_PROCESS(            const utlAtParameterOp_T        op,
+        const char                      *command_name_p,
+        const utlAtParameterValue_P2c   parameter_values_p,
+        const size_t                    num_parameters,
+        const char                      *info_text_p,
+        unsigned int                    *xid_p,
+        void                            *arg_p)
+{
+
+    UNUSEDPARAM(command_name_p);
+	UNUSEDPARAM(parameter_values_p);
+	UNUSEDPARAM(num_parameters);
+	UNUSEDPARAM(info_text_p);
+
+    /*
+     *  Put parser index into the variable
+     */
+        RETURNCODE_T      rc = INITIAL_RETURN_CODE;
+        CiReturnCode          ret = CIRC_FAIL;
+        UINT32                atHandle = MAKE_AT_HANDLE(* (TelAtParserID *) arg_p);
+
+        *xid_p = atHandle;
+    //  DBGMSG("%s: atHandle = %d.\n", __FUNCTION__, atHandle);
+
+    /*
+     * process operation
+     */
+    switch ( op )
+    {
+        case TEL_EXT_ACTION_CMD: /* AT*READVER */
+            {
+                char tmpBuf[512];
+#if 0
+                sprintf(tmpBuf, "*READVER: \r\nrelease_version:%s\r\nrelease_time:%s\r\n", SYSTEM_RELEASE_NAME, SYSTEM_RELEASE_CREATION_DATE);
+#else
+                {
+                    char rel_version[128] = {0};
+                    char sdk[64] = {0};
+                    char rel_date[64] = {0};
+                    char dsp_version[128]={0};
+                    char dsp_date[64]={0};
+                    char rf_version[128] = {0};
+                    int num = 0;
+
+                    char internalRevisionId[400 + 1] = {0};
+                    char buildTimeStr[100 + 1] = {0};
+
+                    //GetDspFWVersionAndDate(dsp_version1,dsp_date1);
+                    //p_string = GetRFBinFWVersion();
+                    //p_string2 = GetRFBinFWDate();
+                    property_get("dev.cp.rel.revision", rel_version, "NULL");
+                    property_get("dev.cp.dsp.revision", dsp_version, "NULL");
+                    property_get("dev.cp.rf.revision", rf_version, "NULL");
+		            property_get("dev.cp.rel.time", rel_date, "NULL");
+                    property_get("dev.cp.dsp.time", dsp_date, "NULL");
+
+                    #if 1
+                    if(strncmp(rel_version, "NULL", strlen("NULL")) != 0)
+                    {
+                        char *p1 = NULL;
+                        p1 = strstr(rel_version, "SDK");
+                        if(p1 != NULL)
+                        {
+                            memcpy(sdk, p1, strlen(p1));
+                            p1 = strstr(sdk, "_");
+                            if(p1 != NULL)
+                            {
+                                *p1 = '\0';
+                            }
+                        }
+                        else
+                        {
+                            strcpy(sdk, "NULL");
+                        }
+                    }
+                    else
+                    {
+                        strcpy(sdk, "NULL");
+                    }
+                    #endif
+
+                    sprintf(tmpBuf, "*READVER: \r\nRelease_Version: %s (SDK %s)\r\nRelease_Time: %s\r\n(DSP: %s %s)\r\n(RF: %s %s)\r\n(HW: %s by %s)\r\n",
+                        rel_version,sdk,rel_date,
+                        dsp_version,dsp_date,
+                        rf_version,"NULL",
+                        "NULL","NULL");
+                }
+#endif
+                ret = ATRESP( atHandle, ATCI_RESULT_CODE_OK, 0, tmpBuf);
+                break;
+            }
+
+
+        default:
+                ret = ATRESP( atHandle, ATCI_RESULT_CODE_CME_ERROR, CME_OPERATION_NOT_SUPPORTED, NULL );
+            break;
+    }
+
+
+    rc = HANDLE_RETURN_VALUE(ret);
+    return(rc);
+}
+
+utlReturnCode_T MBTK_AT_CGDRT_PROCESS(const utlAtParameterOp_T op,
+                                        const char *command_name_p,
+                                        const utlAtParameterValue_P2c parameter_values_p,
+                                        const size_t num_parameters,
+                                        const char *info_text_p,
+                                        unsigned int *xid_p,
+                                        void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int At_handle = MAKE_AT_HANDLE(sAtp_index);
+    *xid_p = At_handle;
+    char resp_buf[MBTK_AT_RESP_LEN_MAX] = {0};
+
+    static int mode = 0;
+    static int cert = 0;
+
+    LOG("MBTK_AT_MTEST_PROCESS enter with command_op [%s]", op2str(op));
+
+    switch(op)
+    {
+        case TEL_EXT_GET_CMD :
+        {
+            ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);
+            break;
+        }
+        case TEL_EXT_SET_CMD :
+        {
+            if(!getExtValue(parameter_values_p, 0, &mode, 0, 139, 0))
+            {
+                ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+
+            if(!getExtValue(parameter_values_p, 1, &cert, 0, 1, 0))
+            {
+                ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+
+
+             if(cert)  //out
+             {
+                 ret = one_gpio_export(mode, 2);
+             }
+             else   //in
+             {
+                 ret = one_gpio_export(mode, 3);
+             }
+
+
+             if(ret)
+             {
+                 ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+             }
+             else
+             {
+                 ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+             }
+
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+}
+
+utlReturnCode_T MBTK_AT_CGSETV_PROCESS(const utlAtParameterOp_T op,
+                                        const char *command_name_p,
+                                        const utlAtParameterValue_P2c parameter_values_p,
+                                        const size_t num_parameters,
+                                        const char *info_text_p,
+                                        unsigned int *xid_p,
+                                        void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int At_handle = MAKE_AT_HANDLE(sAtp_index);
+    *xid_p = At_handle;
+    char resp_buf[MBTK_AT_RESP_LEN_MAX] = {0};
+
+    static int mode = 0;
+    static int cert = 0;
+
+    LOG("MBTK_AT_MTEST_PROCESS enter with command_op [%s]", op2str(op));
+
+    switch(op)
+    {
+        case TEL_EXT_SET_CMD :
+        {
+            if(!getExtValue(parameter_values_p, 0, &mode, 0, 139, 0))
+            {
+                ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+
+            if(!getExtValue(parameter_values_p, 1, &cert, 0, 1, 0))
+            {
+                ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+
+             if(cert) //hight
+             {
+                 ret = one_gpio_export(mode, 1);
+             }
+             else   //low
+             {
+                 ret = one_gpio_export(mode, 0);
+             }
+
+
+             if(ret)
+             {
+                 ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+             }
+             else
+             {
+                 ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+             }
+
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+}
+
+
+utlReturnCode_T MBTK_AT_MDUMP_PROCESS(const utlAtParameterOp_T op,
+                                        const char *command_name_p,
+                                        const utlAtParameterValue_P2c parameter_values_p,
+                                        const size_t num_parameters,
+                                        const char *info_text_p,
+                                        unsigned int *xid_p,
+                                        void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int at_handle = MAKE_AT_HANDLE(sAtp_index);
+    char resp_buf[MBTK_AT_RESP_LEN_MAX] = {0};
+    int arg1 = 0;
+    *xid_p = at_handle;
+
+    LOG("MBTK_AT_MDUMP_PROCESS enter with command_op [%s]", op2str(op));
+
+    switch(op)
+    {
+        case TEL_EXT_GET_CMD :
+        {
+            char dump[10];
+            memset(dump, 0, 10);
+            property_get("persist.mbtk.dump", dump, "0");
+            snprintf(resp_buf, MBTK_AT_RESP_LEN_MAX, "+MDUMP: %d\r\n", atoi(dump));
+            ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);
+            break;
+        }
+        case TEL_EXT_SET_CMD :
+        {
+            int adc_ret;
+            if(!getExtValue(parameter_values_p, 0, &arg1, 0, 1, 0))
+            {
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+            char dump[10];
+            memset(dump, 0, 10);
+            if(arg1 == 1) {
+                memcpy(dump, "1", 1);
+            } else {
+                memcpy(dump, "0", 1);
+            }
+            if(property_set("persist.mbtk.dump", dump))
+            {
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+            } else {
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+            }
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+}
+
+
diff --git a/mbtk/mbtk_at/src/mbtk_at_ftp.c b/mbtk/mbtk_at/src/mbtk_at_ftp.c
new file mode 100755
index 0000000..8b38c7d
--- /dev/null
+++ b/mbtk/mbtk_at/src/mbtk_at_ftp.c
@@ -0,0 +1,976 @@
+#include "mbtk_at.h"
+//#include <sys/statfs.h>
+#include <sys/vfs.h>
+#include <errno.h>
+#include <linux/magic.h>
+#include <time.h>
+#include <sys/time.h>
+#include <signal.h>
+#include <pthread.h>
+#include <time.h>
+#include <sys/time.h>
+#include <cutils/properties.h>
+#include "configwrapper.h"
+#include<linux/msg.h>
+
+#include "atcmdsvr_ubus.h"
+
+//mbtk_ftp
+struct my_msg   //消息队列结构体
+{
+	long int my_msg_type;
+    char *ptr;
+}mbtk_at_msg;
+
+void mbtk_at_printf()
+{
+	int msgid;
+	mbtk_at_msg.my_msg_type=3;
+	msgid=msgget(12,0666|IPC_CREAT);
+    MBTK_FUNC(mbtk_at_msgid)(&msgid);
+    //char read_buf[MAXMSG];
+	while(1)
+	{
+	    msgrcv(msgid,&mbtk_at_msg,4,mbtk_at_msg.my_msg_type,0);
+       	if(strncmp(mbtk_at_msg.ptr,"end",3)==0)
+		    break;
+        ATRESP(IND_REQ_HANDLE , ATCI_RESULT_CODE_NULL, 0, mbtk_at_msg.ptr);
+        free(mbtk_at_msg.ptr);
+        mbtk_at_msg.ptr=NULL;
+	}
+	msgctl(msgid,IPC_RMID,0);
+}
+
+utlReturnCode_T MBTK_AT_CFTPPORT_PROCESS(const utlAtParameterOp_T op,
+                                        const char *command_name_p,
+                                        const utlAtParameterValue_P2c parameter_values_p,
+                                        const size_t num_parameters,
+                                        const char *info_text_p,
+                                        unsigned int *xid_p,
+                                        void *arg_p)
+
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int At_handle = MAKE_AT_HANDLE(sAtp_index);
+    *xid_p = At_handle;
+    char resp_buf[MBTK_AT_RESP_LEN_MAX] = {0};
+
+    static int arg1 = 0;
+
+    LOG("MBTK_AT_MTEST_PROCESS enter with command_op [%s]", op2str(op));
+
+    switch(op)
+    {
+        case TEL_EXT_GET_CMD :
+        {
+            MBTK_FUNC(mbtk_at_get_ftp_info)(0,&arg1, NULL, NULL, NULL, NULL, NULL, NULL);
+            sprintf(resp_buf, "+CFTPPORT: <%d>\r\n", arg1);
+            ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);
+            break;
+        }
+        case TEL_EXT_SET_CMD :
+        {
+            if(!getExtValue(parameter_values_p, 0, &arg1, 1, 65535, 21))
+            {
+                ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+
+            MBTK_FUNC(mbtk_at_ftp)(0,arg1, NULL, NULL, NULL, NULL, NULL, NULL);
+
+            ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+}
+
+utlReturnCode_T MBTK_AT_CFTPUN_PROCESS(const utlAtParameterOp_T op,
+                                        const char *command_name_p,
+                                        const utlAtParameterValue_P2c parameter_values_p,
+                                        const size_t num_parameters,
+                                        const char *info_text_p,
+                                        unsigned int *xid_p,
+                                        void *arg_p)
+
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int At_handle = MAKE_AT_HANDLE(sAtp_index);
+    *xid_p = At_handle;
+    char resp_buf[MBTK_AT_RESP_LEN_MAX] = {0};
+
+    LOG("MBTK_AT_MTEST_PROCESS enter with command_op [%s]", op2str(op));
+
+    switch(op)
+    {
+        case TEL_EXT_GET_CMD :
+        {
+            static char name[MBTK_AT_FTP_NAME_LEN_MAX];
+            MBTK_FUNC(mbtk_at_get_ftp_info)(3,NULL, NULL, NULL, name, NULL, NULL, NULL);
+            sprintf(resp_buf, "+CFTPUN: \"<%s>\"\r\n",name);
+            ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);
+            break;
+        }
+        case TEL_EXT_SET_CMD :
+        {
+            const static int name_len_max = MBTK_AT_FTP_NAME_LEN_MAX;
+            static char name[MBTK_AT_FTP_NAME_LEN_MAX];
+            int len = 0;
+            memset(name, 0x0, MBTK_AT_FTP_NAME_LEN_MAX);
+            if(!getExtString(parameter_values_p, 0, name, name_len_max, &len, ""))
+            {
+                ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                LOG("Get FTP NAME Fail.");
+                break;
+            }
+
+            MBTK_FUNC(mbtk_at_ftp)(3,NULL, NULL, NULL, name, NULL, NULL, NULL);
+
+            ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+}
+
+utlReturnCode_T MBTK_AT_CFTPPW_PROCESS(const utlAtParameterOp_T op,
+                                        const char *command_name_p,
+                                        const utlAtParameterValue_P2c parameter_values_p,
+                                        const size_t num_parameters,
+                                        const char *info_text_p,
+                                        unsigned int *xid_p,
+                                        void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int At_handle = MAKE_AT_HANDLE(sAtp_index);
+    *xid_p = At_handle;
+    char resp_buf[MBTK_AT_RESP_LEN_MAX] = {0};
+
+    LOG("MBTK_AT_MTEST_PROCESS enter with command_op [%s]", op2str(op));
+
+    switch(op)
+    {
+        case TEL_EXT_GET_CMD :
+        {
+            static char pass[MBTK_AT_FTP_PASS_LEN_MAX];
+            MBTK_FUNC(mbtk_at_get_ftp_info)(2,NULL, NULL, pass, NULL, NULL, NULL, NULL);
+            sprintf(resp_buf, "+CFTPPW: \"<%s>\"\r\n",pass);
+            ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);
+            break;
+        }
+        case TEL_EXT_SET_CMD :
+        {
+            const static int pass_len_max = MBTK_AT_FTP_PASS_LEN_MAX;
+            static char pass[MBTK_AT_FTP_PASS_LEN_MAX];
+            int len = 0;
+            memset(pass, 0x0, MBTK_AT_FTP_PASS_LEN_MAX);
+            if(!getExtString(parameter_values_p, 0, pass, pass_len_max, &len, ""))
+            {
+                ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                LOG("Get FTP PASS Fail.");
+                break;
+            }
+
+            MBTK_FUNC(mbtk_at_ftp)(2,NULL, NULL, pass, NULL, NULL, NULL, NULL);
+
+            ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+}
+
+utlReturnCode_T MBTK_AT_CFTPTLS_PROCESS(const utlAtParameterOp_T op,
+                                        const char *command_name_p,
+                                        const utlAtParameterValue_P2c parameter_values_p,
+                                        const size_t num_parameters,
+                                        const char *info_text_p,
+                                        unsigned int *xid_p,
+                                        void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int At_handle = MAKE_AT_HANDLE(sAtp_index);
+    *xid_p = At_handle;
+    char resp_buf[MBTK_AT_RESP_LEN_MAX] = {0};
+
+    static int mode = 0;
+    static int cert = 0;
+
+    LOG("MBTK_AT_MTEST_PROCESS enter with command_op [%s]", op2str(op));
+
+    switch(op)
+    {
+        case TEL_EXT_GET_CMD :
+        {
+            MBTK_FUNC(mbtk_at_get_ftp_info)(4,NULL, NULL, NULL, NULL, &mode, NULL, &cert);
+            sprintf(resp_buf, "+CFTPTLS: <%d>,<%d>\r\n", mode, cert);
+            ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);
+            break;
+        }
+        case TEL_EXT_SET_CMD :
+        {
+            if(!getExtValue(parameter_values_p, 0, &mode, 0, 2, 0))
+            {
+                ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+
+            if(!getExtValue(parameter_values_p, 1, &cert, 0, 1, 0))
+            {
+                ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+
+            MBTK_FUNC(mbtk_at_ftp)(4,NULL, NULL, NULL, NULL, mode, NULL, cert);
+
+            ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+}
+
+utlReturnCode_T MBTK_AT_CFTPSERV_PROCESS(const utlAtParameterOp_T op,
+                                        const char *command_name_p,
+                                        const utlAtParameterValue_P2c parameter_values_p,
+                                        const size_t num_parameters,
+                                        const char *info_text_p,
+                                        unsigned int *xid_p,
+                                        void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int At_handle = MAKE_AT_HANDLE(sAtp_index);
+    *xid_p = At_handle;
+    char resp_buf[MBTK_AT_RESP_LEN_MAX] = {0};
+
+    LOG("MBTK_AT_MTEST_PROCESS enter with command_op [%s]", op2str(op));
+
+    switch(op)
+    {
+        case TEL_EXT_GET_CMD :
+        {
+            static char addr[MBTK_AT_FTP_ADDR_LEN_MAX];
+            MBTK_FUNC(mbtk_at_get_ftp_info)(1,NULL, addr, NULL, NULL, NULL, NULL, NULL);
+            sprintf(resp_buf, "+CFTPSERV: %s", addr);
+            ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);
+            break;
+        }
+        case TEL_EXT_SET_CMD :
+        {
+            const static int addr_len_max = MBTK_AT_FTP_ADDR_LEN_MAX;
+            static char addr[MBTK_AT_FTP_ADDR_LEN_MAX];
+            int len = 0;
+            memset(addr, 0x0, MBTK_AT_FTP_ADDR_LEN_MAX);
+            if(!getExtString(parameter_values_p, 0, addr, addr_len_max, &len, ""))
+            {
+                ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                LOG("Get FTP ADDR Fail.");
+                break;
+            }
+
+            MBTK_FUNC(mbtk_at_ftp)(1,NULL, addr, NULL, NULL, NULL, NULL, NULL);
+
+            ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+}
+
+utlReturnCode_T MBTK_AT_CFTPTYPE_PROCESS(const utlAtParameterOp_T op,
+                                        const char *command_name_p,
+                                        const utlAtParameterValue_P2c parameter_values_p,
+                                        const size_t num_parameters,
+                                        const char *info_text_p,
+                                        unsigned int *xid_p,
+                                        void *arg_p)
+
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int At_handle = MAKE_AT_HANDLE(sAtp_index);
+    *xid_p = At_handle;
+    char resp_buf[MBTK_AT_RESP_LEN_MAX] = {0};
+
+    LOG("MBTK_AT_MTEST_PROCESS enter with command_op [%s]", op2str(op));
+
+    switch(op)
+    {
+        case TEL_EXT_GET_CMD :
+        {
+            int mbtk_ftp_type = -1;
+            static char ftp_type;
+            MBTK_FUNC(mbtk_at_get_ftp_info)(5,NULL, NULL, NULL, NULL, NULL, &mbtk_ftp_type, NULL);
+            if(mbtk_ftp_type == 0)
+                ftp_type='A';
+            else if(mbtk_ftp_type == 1)
+                ftp_type='I';
+            else
+            {
+                ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, resp_buf);
+                break;
+            }
+            sprintf(resp_buf, "+CFTPTYPE:\"%c\"",ftp_type);
+            ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);
+            break;
+        }
+        case TEL_EXT_SET_CMD :
+        {
+            static char ftp_type[2];
+            int addr_len_max = 2;
+            int len = 0;
+            int mbtk_ftp_type = -1;
+            if(!getExtString(parameter_values_p, 0, ftp_type, addr_len_max, &len, ""))
+            {
+                ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                LOG("Get FTP PASS Fail.");
+                break;
+            }
+            //FTP_DATA_TYPE_I = 2 FTP_DATA_TYPE_A = 0
+            if(strstr(ftp_type,"A") != NULL)
+                mbtk_ftp_type = 0;
+            else if(strstr(ftp_type,"I") != NULL)
+                mbtk_ftp_type = 2;
+            else
+            {
+                ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                LOG("Get FTP PASS Fail.");
+                break;
+            }
+            MBTK_FUNC(mbtk_at_ftp)(5,NULL, NULL, NULL, NULL, NULL, mbtk_ftp_type, NULL);
+
+            ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+}
+
+utlReturnCode_T MBTK_AT_CFTPMKD_PROCESS(const utlAtParameterOp_T op,
+                                        const char *command_name_p,
+                                        const utlAtParameterValue_P2c parameter_values_p,
+                                        const size_t num_parameters,
+                                        const char *info_text_p,
+                                        unsigned int *xid_p,
+                                        void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int At_handle = MAKE_AT_HANDLE(sAtp_index);
+    *xid_p = At_handle;
+    char resp_buf[MBTK_AT_RESP_LEN_MAX] = {0};
+
+    LOG("MBTK_AT_MTEST_PROCESS enter with command_op [%s]", op2str(op));
+
+    pthread_t mbtk_at_thread_ID;      //定义线程id
+    pthread_create(&mbtk_at_thread_ID, NULL, &mbtk_at_printf, NULL);
+    pthread_detach(mbtk_at_thread_ID);	//设置线程结束收
+
+    switch(op)
+    {
+        case TEL_EXT_GET_CMD :
+        {
+            static char remote_size[MBTK_AT_FTP_DIR_LEN_MAX+1];
+            memset(remote_size, 0x0, MBTK_AT_FTP_DIR_LEN_MAX+1);
+
+            MBTK_FUNC(mbtk_at_get_ftp_data_info)(remote_size,NULL,NULL,NULL,NULL);
+
+            sprintf(resp_buf, "+CFTPLIST: \"%s\"\r\n",remote_size);
+            ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);
+            break;
+        }
+        case TEL_EXT_SET_CMD :
+        {
+            static char dir[MBTK_AT_FTP_DIR_LEN_MAX];
+            int dir_len_max = MBTK_AT_FTP_DIR_LEN_MAX;
+            int len = 0;
+            memset(dir, 0x0, MBTK_AT_FTP_DIR_LEN_MAX);
+            if(!getExtString(parameter_values_p, 0, dir, dir_len_max, &len, ""))
+            {
+                ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                LOG("Get FTP MKDIR Fail.");
+                break;
+            }
+            ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+            MBTK_FUNC(mbtk_at_ftp_mkrmdel)(0,dir);
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+}
+
+utlReturnCode_T MBTK_AT_CFTPRMD_PROCESS(const utlAtParameterOp_T op,
+                                        const char *command_name_p,
+                                        const utlAtParameterValue_P2c parameter_values_p,
+                                        const size_t num_parameters,
+                                        const char *info_text_p,
+                                        unsigned int *xid_p,
+                                        void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int At_handle = MAKE_AT_HANDLE(sAtp_index);
+    *xid_p = At_handle;
+    char resp_buf[MBTK_AT_RESP_LEN_MAX] = {0};
+
+    LOG("MBTK_AT_MTEST_PROCESS enter with command_op [%s]", op2str(op));
+
+    pthread_t mbtk_at_thread_ID;      //定义线程id
+    pthread_create(&mbtk_at_thread_ID, NULL, &mbtk_at_printf, NULL);
+    pthread_detach(mbtk_at_thread_ID);	//设置线程结束收
+
+    switch(op)
+    {
+        case TEL_EXT_GET_CMD :
+        {
+            static char remote_size[MBTK_AT_FTP_DIR_LEN_MAX+1];
+            memset(remote_size, 0x0, MBTK_AT_FTP_DIR_LEN_MAX+1);
+
+            MBTK_FUNC(mbtk_at_get_ftp_data_info)(remote_size,NULL,NULL,NULL,NULL);
+
+            sprintf(resp_buf, "+CFTPMKD: \"%s\"\r\n",remote_size);
+            ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);
+            break;
+        }
+        case TEL_EXT_SET_CMD :
+        {
+            static char dir[MBTK_AT_FTP_DIR_LEN_MAX];
+            int dir_len_max = MBTK_AT_FTP_DIR_LEN_MAX;
+            int len = 0;
+            memset(dir, 0x0, MBTK_AT_FTP_DIR_LEN_MAX);
+            if(!getExtString(parameter_values_p, 0, dir, dir_len_max, &len, ""))
+            {
+                ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                LOG("Get FTP RMDIR Fail.");
+                break;
+            }
+            ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+            MBTK_FUNC(mbtk_at_ftp_mkrmdel)(1,dir);
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+}
+
+utlReturnCode_T MBTK_AT_CFTPDEL_PROCESS(const utlAtParameterOp_T op,
+                                        const char *command_name_p,
+                                        const utlAtParameterValue_P2c parameter_values_p,
+                                        const size_t num_parameters,
+                                        const char *info_text_p,
+                                        unsigned int *xid_p,
+                                        void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int At_handle = MAKE_AT_HANDLE(sAtp_index);
+    *xid_p = At_handle;
+    char resp_buf[MBTK_AT_RESP_LEN_MAX] = {0};
+
+    LOG("MBTK_AT_MTEST_PROCESS enter with command_op [%s]", op2str(op));
+
+    pthread_t mbtk_at_thread_ID;      //定义线程id
+    pthread_create(&mbtk_at_thread_ID, NULL, &mbtk_at_printf, NULL);
+    pthread_detach(mbtk_at_thread_ID);	//设置线程结束收
+
+    switch(op)
+    {
+        case TEL_EXT_GET_CMD :
+        {
+            static char remote_size[MBTK_AT_FTP_DIR_LEN_MAX+1];
+            memset(remote_size, 0x0, MBTK_AT_FTP_DIR_LEN_MAX+1);
+
+            MBTK_FUNC(mbtk_at_get_ftp_data_info)(remote_size,NULL,NULL,NULL,NULL);
+
+            sprintf(resp_buf, "+CFTPDELE: \"%s\"\r\n",remote_size);
+            ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);
+            break;
+        }
+        case TEL_EXT_SET_CMD :
+        {
+            static char dir[MBTK_AT_FTP_DIR_LEN_MAX];
+            int dir_len_max = MBTK_AT_FTP_DIR_LEN_MAX;
+            int len = 0;
+            memset(dir, 0x0, MBTK_AT_FTP_DIR_LEN_MAX);
+            if(!getExtString(parameter_values_p, 0, dir, dir_len_max, &len, ""))
+            {
+                ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                LOG("Get FTP DEL FILE Fail.");
+                break;
+            }
+            ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+            MBTK_FUNC(mbtk_at_ftp_mkrmdel)(2,dir);
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+}
+
+utlReturnCode_T MBTK_AT_CFTPPUTFILE_PROCESS(const utlAtParameterOp_T op,
+                                        const char *command_name_p,
+                                        const utlAtParameterValue_P2c parameter_values_p,
+                                        const size_t num_parameters,
+                                        const char *info_text_p,
+                                        unsigned int *xid_p,
+                                        void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int At_handle = MAKE_AT_HANDLE(sAtp_index);
+    *xid_p = At_handle;
+    char resp_buf[MBTK_AT_RESP_LEN_MAX] = {0};
+
+    LOG("MBTK_AT_MTEST_PROCESS enter with command_op [%s]", op2str(op));
+
+    pthread_t mbtk_at_thread_ID;      //定义线程id
+    pthread_create(&mbtk_at_thread_ID, NULL, &mbtk_at_printf, NULL);
+    pthread_detach(mbtk_at_thread_ID);	//设置线程结束收
+
+    switch(op)
+    {
+        case TEL_EXT_GET_CMD :
+        {
+            int rest_size = -1;
+            static char remote_size[MBTK_AT_FTP_DIR_LEN_MAX+1];
+            static char local_path[MBTK_AT_FTP_DIR_LEN_MAX+1];
+            memset(remote_size, 0x0, MBTK_AT_FTP_DIR_LEN_MAX+1);
+            memset(local_path, 0x0, MBTK_AT_FTP_DIR_LEN_MAX+1);
+
+            MBTK_FUNC(mbtk_at_get_ftp_data_info)(remote_size,local_path,&rest_size,NULL,NULL);
+
+            sprintf(resp_buf, "+CFTPPUTFILE: \"%s\", \"%s\",<%d>\r\n",remote_size,local_path,rest_size);
+            ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);
+            break;
+        }
+        case TEL_EXT_SET_CMD :
+        {
+            int rest_size;
+            static char remote_path[MBTK_AT_FTP_DIR_LEN_MAX+1];
+            static char local_path[MBTK_AT_FTP_DIR_LEN_MAX+1];
+            int dir_len_max = MBTK_AT_FTP_DIR_LEN_MAX;
+            int len = 0;
+            memset(remote_path, 0x0, MBTK_AT_FTP_DIR_LEN_MAX+1);
+            memset(local_path, 0x0, MBTK_AT_FTP_DIR_LEN_MAX+1);
+            if(!getExtString(parameter_values_p, 0, remote_path, dir_len_max, &len, ""))
+            {
+                ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                LOG("Get FTP DEL FILE Fail.");
+                break;
+            }
+            if(!getExtString(parameter_values_p, 1, local_path, dir_len_max, &len, ""))
+            {
+                ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                LOG("Get FTP DEL FILE Fail.");
+                break;
+            }
+            if(!getExtValue(parameter_values_p, 2, &rest_size, 0, 2147483647, 0))
+            {
+                ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+            ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+            MBTK_FUNC(mbtk_at_ftp_upload)(remote_path,local_path,0,rest_size);
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+}
+
+utlReturnCode_T MBTK_AT_CFTPPUT_PROCESS(const utlAtParameterOp_T op,
+                                        const char *command_name_p,
+                                        const utlAtParameterValue_P2c parameter_values_p,
+                                        const size_t num_parameters,
+                                        const char *info_text_p,
+                                        unsigned int *xid_p,
+                                        void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int At_handle = MAKE_AT_HANDLE(sAtp_index);
+    *xid_p = At_handle;
+    char resp_buf[MBTK_AT_RESP_LEN_MAX] = {0};
+
+    LOG("MBTK_AT_MTEST_PROCESS enter with command_op [%s]", op2str(op));
+
+    pthread_t mbtk_at_thread_ID;      //定义线程id
+    pthread_create(&mbtk_at_thread_ID, NULL, &mbtk_at_printf, NULL);
+    pthread_detach(mbtk_at_thread_ID);	//设置线程结束收
+
+    switch(op)
+    {
+        case TEL_EXT_GET_CMD :
+        {
+            int rest_size = -1;
+            int put_len = -1;
+            static char remote_size[MBTK_AT_FTP_DIR_LEN_MAX+1];
+            memset(remote_size, 0x0, MBTK_AT_FTP_DIR_LEN_MAX+1);
+
+            MBTK_FUNC(mbtk_at_get_ftp_data_info)(remote_size,NULL,&rest_size,NULL,&put_len);
+
+            sprintf(resp_buf, "+CFTPPUT: \"%s\",<%d>,<%d>\r\n",remote_size,rest_size,put_len);
+            ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);
+            break;
+
+        }
+        case TEL_EXT_SET_CMD :
+        {
+            static char remote_path[MBTK_AT_FTP_DIR_LEN_MAX];
+            int dir_len_max = MBTK_AT_FTP_DIR_LEN_MAX;
+            int len = 0;
+            int rest_size;
+            int put_len;
+            memset(remote_path, 0x0, MBTK_AT_FTP_DIR_LEN_MAX);
+            if(!getExtString(parameter_values_p, 0, remote_path, dir_len_max, &len, ""))
+            {
+                ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                LOG("Get FTP DEL FILE Fail.");
+                break;
+            }
+            if(!getExtValue(parameter_values_p, 1, &rest_size, 0, 2147483647, 0))
+            {
+                ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+            if(!getExtValue(parameter_values_p, 2, &put_len, 1, 1500, 0))
+            {
+                ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+            ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+            MBTK_FUNC(mbtk_at_ftp_upload)(remote_path,NULL,put_len,rest_size);
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+}
+
+utlReturnCode_T MBTK_AT_CFTPGETFILE_PROCESS(const utlAtParameterOp_T op,
+                                        const char *command_name_p,
+                                        const utlAtParameterValue_P2c parameter_values_p,
+                                        const size_t num_parameters,
+                                        const char *info_text_p,
+                                        unsigned int *xid_p,
+                                        void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int At_handle = MAKE_AT_HANDLE(sAtp_index);
+    *xid_p = At_handle;
+    char resp_buf[MBTK_AT_RESP_LEN_MAX] = {0};
+
+    LOG("MBTK_AT_MTEST_PROCESS enter with command_op [%s]", op2str(op));
+
+    pthread_t mbtk_at_thread_ID;      //定义线程id
+    pthread_create(&mbtk_at_thread_ID, NULL, &mbtk_at_printf, NULL);
+    pthread_detach(mbtk_at_thread_ID);	//设置线程结束收
+
+    switch(op)
+    {
+        case TEL_EXT_GET_CMD :
+        {
+            int rest_size = -1;
+            int read_size = -1;
+            static char remote_size[MBTK_AT_FTP_DIR_LEN_MAX+1];
+            static char local_path[MBTK_AT_FTP_DIR_LEN_MAX+1];
+            memset(remote_size, 0x0, MBTK_AT_FTP_DIR_LEN_MAX+1);
+            memset(local_path, 0x0, MBTK_AT_FTP_DIR_LEN_MAX+1);
+
+            MBTK_FUNC(mbtk_at_get_ftp_data_info)(remote_size,local_path,&rest_size,&read_size,NULL);
+
+            sprintf(resp_buf, "+CFTPGETFILE: \"%s\", \"%s\",<%d>, <%d>\r\n",remote_size,local_path,rest_size,read_size);
+            ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);
+            break;
+        }
+        case TEL_EXT_SET_CMD :
+        {
+            static char remote_path[MBTK_AT_FTP_DIR_LEN_MAX+1];
+            static char local_path[MBTK_AT_FTP_DIR_LEN_MAX+1];
+            int dir_len_max = MBTK_AT_FTP_DIR_LEN_MAX;
+            int len = 0;
+            int rest_size;
+            int read_size;
+            memset(remote_path, 0x0, MBTK_AT_FTP_DIR_LEN_MAX+1);
+            memset(local_path, 0x0, MBTK_AT_FTP_DIR_LEN_MAX+1);
+            if(!getExtString(parameter_values_p, 0, remote_path, dir_len_max, &len, ""))
+            {
+                ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                LOG("Get FTP DEL FILE Fail.");
+                break;
+            }
+            if(!getExtString(parameter_values_p, 1, local_path, dir_len_max, &len, ""))
+            {
+                ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                LOG("Get FTP DEL FILE Fail.");
+                break;
+            }
+            if(!getExtValue(parameter_values_p, 2, &rest_size, 0, 2147483647, 0))
+            {
+                ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+            if(!getExtValue(parameter_values_p, 3, &read_size, 0, 524288, 0))
+            {
+                ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+            ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+            MBTK_FUNC(mbtk_at_ftp_download)(remote_path,local_path,0,rest_size,read_size);
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+
+}
+
+utlReturnCode_T MBTK_AT_CFTPGET_PROCESS(const utlAtParameterOp_T op,
+                                        const char *command_name_p,
+                                        const utlAtParameterValue_P2c parameter_values_p,
+                                        const size_t num_parameters,
+                                        const char *info_text_p,
+                                        unsigned int *xid_p,
+                                        void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int At_handle = MAKE_AT_HANDLE(sAtp_index);
+    *xid_p = At_handle;
+    char resp_buf[MBTK_AT_RESP_LEN_MAX] = {0};
+
+    LOG("MBTK_AT_MTEST_PROCESS enter with command_op [%s]", op2str(op));
+
+    pthread_t mbtk_at_thread_ID;      //定义线程id
+    pthread_create(&mbtk_at_thread_ID, NULL, &mbtk_at_printf, NULL);
+    pthread_detach(mbtk_at_thread_ID);	//设置线程结束收
+
+    switch(op)
+    {
+        case TEL_EXT_GET_CMD :
+        {
+            int rest_size = -1;
+            static char remote_size[MBTK_AT_FTP_DIR_LEN_MAX+1];
+            memset(remote_size, 0x0, MBTK_AT_FTP_DIR_LEN_MAX+1);
+
+            MBTK_FUNC(mbtk_at_get_ftp_data_info)(remote_size,NULL,&rest_size,NULL,NULL);
+
+            sprintf(resp_buf, "+CFTPGET: \"%s\",<%d>\r\n",remote_size,rest_size);
+            ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);
+            break;
+        }
+        case TEL_EXT_SET_CMD :
+        {
+            static char remote_path[MBTK_AT_FTP_DIR_LEN_MAX+1];
+            int dir_len_max = MBTK_AT_FTP_DIR_LEN_MAX;
+            int len = 0;
+            int rest_size;
+            int read_size;
+            memset(remote_path, 0x0, MBTK_AT_FTP_DIR_LEN_MAX+1);
+            if(!getExtString(parameter_values_p, 0, remote_path, dir_len_max, &len, ""))
+            {
+                ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                LOG("Get FTP DEL FILE Fail.");
+                break;
+            }
+            if(!getExtValue(parameter_values_p, 1, &rest_size, 0, 2147483647, 0))
+            {
+                ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+            if(!getExtValue(parameter_values_p, 2, &read_size, 0, 524288, 0))
+            {
+                ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+            ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+            MBTK_FUNC(mbtk_at_ftp_download)(remote_path,NULL,1,rest_size,read_size);
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+
+}
+
+utlReturnCode_T MBTK_AT_CFTPLIST_PROCESS(const utlAtParameterOp_T op,
+                                        const char *command_name_p,
+                                        const utlAtParameterValue_P2c parameter_values_p,
+                                        const size_t num_parameters,
+                                        const char *info_text_p,
+                                        unsigned int *xid_p,
+                                        void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int At_handle = MAKE_AT_HANDLE(sAtp_index);
+    *xid_p = At_handle;
+    char resp_buf[MBTK_AT_RESP_LEN_MAX] = {0};
+
+    LOG("MBTK_AT_MTEST_PROCESS enter with command_op [%s]", op2str(op));
+
+    pthread_t mbtk_at_thread_ID;      //定义线程id
+    pthread_create(&mbtk_at_thread_ID, NULL, &mbtk_at_printf, NULL);
+    pthread_detach(mbtk_at_thread_ID);	//设置线程结束收尸
+
+    switch(op)
+    {
+        case TEL_EXT_GET_CMD :
+        {
+            int rest_size = -1;
+            static char remote_size[MBTK_AT_FTP_DIR_LEN_MAX+1];
+            memset(remote_size, 0x0, MBTK_AT_FTP_DIR_LEN_MAX+1);
+
+            MBTK_FUNC(mbtk_at_get_ftp_data_info)(remote_size,NULL,NULL,NULL,NULL);
+
+            sprintf(resp_buf, "+CFTPLIST: \"%s\"\r\n",remote_size);
+            ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);
+            break;
+
+        }
+        case TEL_EXT_SET_CMD :
+        {
+            static char dir[MBTK_AT_FTP_DIR_LEN_MAX+1];
+            int dir_len_max = MBTK_AT_FTP_DIR_LEN_MAX;
+            int len = 0;
+            memset(dir, 0x0, MBTK_AT_FTP_DIR_LEN_MAX+1);
+            if(!getExtString(parameter_values_p, 0, dir, dir_len_max, &len, ""))
+            {
+                ret = ATRESP(At_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                LOG("Get FTP RMDIR Fail.");
+                break;
+            }
+            ret = ATRESP(At_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+            MBTK_FUNC(mbtk_at_ftp_list)(dir);
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+}
+
diff --git a/mbtk/mbtk_at/src/mbtk_at_http.c b/mbtk/mbtk_at/src/mbtk_at_http.c
new file mode 100755
index 0000000..aee2bb9
--- /dev/null
+++ b/mbtk/mbtk_at/src/mbtk_at_http.c
@@ -0,0 +1,1246 @@
+#include "mbtk_at.h"
+//#include <sys/statfs.h>
+#include <sys/vfs.h>
+#include <errno.h>
+#include <linux/magic.h>
+#include <time.h>
+#include <sys/time.h>
+#include <signal.h>
+#include <pthread.h>
+#include <time.h>
+#include <sys/time.h>
+#include <cutils/properties.h>
+#include "configwrapper.h"
+#include<linux/msg.h>
+
+#include "atcmdsvr_ubus.h"
+
+
+int http_handle = -1;
+int http_session = -1;
+int http_type = 0;
+int file_fd = -1;
+
+#define MODEM_FACTORY_TEST_TERM_DEVICE "/dev/ttyGS0"
+
+typedef struct mbtk_http_header {
+    char name[30];
+    char *value;
+} mbtk_http_header_t;
+
+mbtk_http_header_t req_h[30] ={0};
+
+
+
+typedef enum {
+    MBTK_HTTP_DATA_NON = 0,
+    MBTK_HTTP_DATA_HEADER,
+    MBTK_HTTP_DATA_CONTENT,
+    MBTK_HTTP_DATA_COMPLETE
+} mbtk_http_data_type_enum;
+
+typedef enum {
+    MBTK_HTTP_DATA_EFS_BUF = 0,  
+    MBTK_HTTP_DATA_EFS_SIZE,
+    MBTK_HTTP_DATA_EFS_BUF_SIZE
+} mbtk_http_data_file_type_enum;
+
+
+typedef enum {
+    HTTP_VERSION_1_0 = 0,
+    HTTP_VERSION_1_1,
+    HTTP_VERSION_2,
+    HTTP_VERSION_3
+} mbtk_http_version_enum;
+
+typedef enum {
+    HTTP_OPTION_HEAD = 0,
+    HTTP_OPTION_GET,
+    HTTP_OPTION_POST,
+    HTTP_OPTION_PUT,
+    HTTP_OPTION_DELETE,
+    HTTP_OPTION_OPTIONS,
+    HTTP_OPTION_TRACE,
+    HTTP_OPTION_CONNECT,
+    HTTP_OPTION_LINK,
+    HTTP_OPTION_UNLINK
+} mbtk_http_option_enum;
+
+typedef enum {
+    HTTP_TYPE_URC = 0,
+	HTTP_TYPE_EFS
+} mbtk_http_type_enum;
+
+typedef enum {
+    HTTP_SESSION_STATE_NON = 0,
+    HTTP_SESSION_STATE_CONN,
+    HTTP_SESSION_STATE_WRITE_HEADER,
+    HTTP_SESSION_STATE_WRITE_CONTENT,
+    HTTP_SESSION_STATE_WRITE_END,
+    HTTP_SESSION_STATE_READ_HEADER,
+    HTTP_SESSION_STATE_READ_CONTENT,
+    HTTP_SESSION_STATE_READ_END
+} http_session_state_e;
+
+typedef struct {
+    int header_cnt;
+    mbtk_http_header_t *req_h[30];
+
+    int content_len;    // Post content lenght
+    int content_len_send; // Post content lenght for send.
+    char *content;
+} mbtk_http_session_req_t;
+
+typedef struct {
+    int state_code;
+    mbtk_http_version_enum version;
+
+    int content_length;
+    bool is_chunked;
+    int header_cnt;
+    mbtk_http_header_t *rsp_h[30];
+} mbtk_http_session_rsp_t;
+
+typedef struct mbtk_http_session{
+    int handle_id;
+    int id;
+    int sock_fd;
+    int file_fd;
+    http_session_state_e state;
+    char host[50 + 1];
+    mbtk_http_option_enum option;
+    mbtk_http_type_enum type;
+    mbtk_http_version_enum version;
+    char uri[205 + 1];
+    int port;
+    bool is_ssl;
+
+    mbtk_http_session_req_t req;
+    mbtk_http_session_rsp_t rsp;
+} mbtk_http_session_t;
+
+
+#define   CS8	0000060
+#define  B115200  0010002
+
+#define DATABITS	CS8
+#define BAUD		B115200
+#define STOPBITS	0
+#define PARITYON	0
+#define PARITY		0
+#define FILTER_INFO_NUM 12
+#define CRTSCTS	  020000000000	/* flow control */
+#define VERASE 2
+#define VEOF 4
+#define VMIN 6
+#define VEOL 11
+#define IGNPAR	0000004
+#define CREAD	0000200
+#define CLOCAL	0004000
+
+#define	TCSANOW		0
+
+typedef unsigned char	cc_t;
+typedef unsigned int	speed_t;
+typedef unsigned int	tcflag_t;
+
+/* tcflush() and TCFLSH use these */
+#define	TCIFLUSH	0
+#define	TCOFLUSH	1
+#define	TCIOFLUSH	2
+
+
+#define NCCS 19
+struct termios {
+	tcflag_t c_iflag;		/* input mode flags */
+	tcflag_t c_oflag;		/* output mode flags */
+	tcflag_t c_cflag;		/* control mode flags */
+	tcflag_t c_lflag;		/* local mode flags */
+	cc_t c_line;			/* line discipline */
+	cc_t c_cc[NCCS];		/* control characters */
+};
+
+
+
+int mbtk_http_port_fd = -1;
+
+static int mbtk_http_open_device(int *fd_ptr, const char *file_path, int flag, int tty)
+{
+
+	int fd = -1;
+
+	if((fd = open(file_path, flag)) < 0)
+	{
+        LOG("Open %s fail.", file_path);
+		return -1;
+	}
+
+     LOG("Open %s success.", file_path);
+	if (tty) {
+		/* set newtio */
+		struct termios newtio;
+		memset(&newtio, 0, sizeof(newtio));
+		//(void)fcntl(fd, F_SETFL, 0);
+#ifdef UART2_AT
+		/* no flow control for uart by default */
+		newtio.c_cflag = BAUD | DATABITS | STOPBITS | PARITYON | PARITY | CLOCAL | CREAD;
+#else
+		newtio.c_cflag = BAUD | CRTSCTS | DATABITS | STOPBITS | PARITYON | PARITY | CLOCAL | CREAD;
+#endif
+		newtio.c_iflag = IGNPAR;
+                //newtio.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
+		newtio.c_oflag = 0;
+		newtio.c_lflag = 0;    /* disable ECHO, ICANON, etc... */
+
+		newtio.c_cc[VERASE]   = 0x8;      /* del */
+		newtio.c_cc[VEOF]     = 4;      /* Ctrl-d */
+		newtio.c_cc[VMIN]     = 1;      /* blocking read until 1 character arrives */
+		newtio.c_cc[VEOL]     = 0xD;      /* '\0' */
+
+		tcflush(fd, TCIFLUSH);
+		tcsetattr(fd, TCSANOW, &newtio);
+	}
+
+	*fd_ptr = fd;
+    return 0;
+}
+
+
+int mbtk_http_open_port(void)
+{
+    if(mbtk_http_port_fd < 0)
+    {
+        return mbtk_http_open_device(&mbtk_http_port_fd, MODEM_FACTORY_TEST_TERM_DEVICE, O_RDWR | O_NONBLOCK | O_NOCTTY, 0);
+    }
+    return 0;
+}
+
+void mbtk_http_close_port(void)
+{
+    if(mbtk_http_port_fd >= 0)
+    {
+        tcflush(mbtk_http_port_fd, TCIOFLUSH);
+        close(mbtk_http_port_fd);
+        mbtk_http_port_fd = -1;
+    }
+
+}
+
+int mbtk_http_write_data(void *data,int data_len)
+{
+    int ret = write(mbtk_http_port_fd, data, data_len);
+    if(ret < 0)
+    {
+        LOG("gnss_factory_test_port_fd write fail");
+        return -1;
+    }
+
+    return 0;
+}
+
+static void http_data_cb_func(
+    int session_id, mbtk_http_data_type_enum type,
+    void *data,int data_len)
+{
+	LOG("2type:%d,data_len:%d,data:%s ",type, data_len, data);
+
+    if(http_type)
+    {
+        if(type == MBTK_HTTP_DATA_HEADER) {
+
+        } else if(type == MBTK_HTTP_DATA_CONTENT){
+
+            if(file_fd >= 0)
+            {
+                int write_len = write(file_fd, data, data_len);
+                if(write_len < data_len) {
+                    LOG("write() fail.");
+                    // return -1;
+                }
+            }
+        } else {
+            LOG(">>>>>Complete<<<<<\n");
+        }
+    }
+    else
+    {
+        char buf[50]={0};
+        sprintf(buf, "$HTTPRECV: DATA,%d",data_len);
+        mbtk_http_write_data("\r\n", strlen("\r\n"));
+        mbtk_http_write_data(buf, strlen(buf));
+        mbtk_http_write_data("\r\n", strlen("\r\n"));
+
+        if(type == MBTK_HTTP_DATA_HEADER) {
+
+            mbtk_http_write_data(data, data_len);
+
+            LOG("Header(%d):%s\n",data_len,(char*)data);
+    	
+        } else if(type == MBTK_HTTP_DATA_CONTENT) {
+            mbtk_http_write_data(data, data_len);
+
+        } else {
+            LOG(">>>>>Complete<<<<<\n");
+        }
+
+    }
+
+}
+
+static void http_data_file_cb_func(mbtk_http_data_file_type_enum type,void *data,int data_len)
+{
+    if(type == MBTK_HTTP_DATA_EFS_BUF) {   //read file data
+
+        char buf[50]={0};
+        sprintf(buf, "$HTTPRECV: DATA,%d",data_len);
+        mbtk_http_write_data("\r\n", strlen("\r\n"));
+        mbtk_http_write_data(buf, strlen(buf));
+        mbtk_http_write_data("\r\n", strlen("\r\n"));
+       
+        mbtk_http_write_data(data, data_len);
+        LOG("Header(%d):%s\n",data_len,(char*)data);
+	
+    } else if(type == MBTK_HTTP_DATA_EFS_SIZE) {   //read file size
+
+        char buf[50]={0};
+        sprintf(buf, "$HTTPREAD:%d",data_len);
+        ATRESP(IND_REQ_HANDLE , ATCI_RESULT_CODE_NULL, 0, buf);
+
+        LOG("mbtk data_len(%d)\n",data_len);
+    } else {
+        LOG(">>>>>Complete<<<<<\n");
+    }
+}	
+
+static int http_header_value_get(mbtk_http_header_t *header,char *header_str,int header_str_len)
+{
+    if(header == NULL || header->value == NULL
+        || header_str == NULL)
+        return 0;
+
+    int len = 0;
+    len = snprintf(header_str,header_str_len,"%s: %s",
+            header->name, header->value);
+
+    return len;
+}
+
+
+int mbtk_http_get_file_size(char *file_name)
+{
+    int ret;
+    int fd = -1;
+    struct stat file_stat;
+
+    LOG("mbtk_http_get_file_size() start\n");
+
+    fd = open(file_name, O_RDONLY);
+    if (fd == -1) {
+        printf("Open file %s failed\n", file_name);
+        return -1;
+    }
+    ret = fstat(fd, &file_stat);
+    if (ret == -1) {
+        printf("Get file %s stat failed\n", file_name);
+        close(fd);
+        return -1;
+    }
+    close(fd);
+    LOG("mbtk_http_get_file_size() end\n");
+    return file_stat.st_size;
+}
+
+
+int mbtk_http_read_file_data1(mbtk_http_data_file_type_enum type,int offset)
+{
+
+    if(type) //1 read file size
+    {
+        int size = mbtk_http_get_file_size("/http_test.txt");
+
+        http_data_file_cb_func(MBTK_HTTP_DATA_EFS_SIZE, NULL, size);
+    }else	//read file data
+    {
+        char buf[1024+1] = {0};
+        int ret = 0;
+
+        int fd = open("/http_test.txt", O_RDONLY);
+        if (fd == -1) {
+            printf("Open file %s failed\n", "/http_test.txt");
+            return -1;
+        }
+
+        if(offset)
+        {
+            lseek(fd, offset, SEEK_SET);
+        }
+//            usleep(500000);
+        int index = 0;
+        while(1)
+        {
+            memset(buf,0, sizeof(buf));
+            ret = read(fd, buf, 1024);
+            printf("ret = %d , ", ret);
+            usleep(100000);
+            LOG("mbtk, read file:%s\n", buf);
+            if(ret <= 0)
+                break;
+
+            http_data_file_cb_func(MBTK_HTTP_DATA_EFS_BUF, buf, ret);
+            index++;
+        }
+        close(fd);
+        printf("%d\n", index);
+
+        LOG("read()end  index;:%d, ret:%d",index,ret);
+    }
+
+    return 0;
+}
+
+
+
+utlReturnCode_T MBTK_AT_HTTPOPEN_PROCESS(const utlAtParameterOp_T op,
+                                       const char *command_name_p,
+                                       const utlAtParameterValue_P2c parameter_values_p,
+                                       const size_t num_parameters,
+                                       const char *info_text_p,
+                                       unsigned int *xid_p,
+                                       void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int at_handle = MAKE_AT_HANDLE(sAtp_index);
+    *xid_p = at_handle;
+
+    LOG("%s enter with command_op [%s]", command_name_p, op2str(op));
+
+    switch(op)
+    {
+        case TEL_EXT_ACTION_CMD :
+        {
+            if(http_handle >= 0)
+            {
+				LOG("http is open");
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, NULL);  
+                break;
+            }
+
+            if(mbtk_http_open_port())
+            {
+                LOG("http open device port fail\n");
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);  
+                break;
+            }
+            
+            http_handle = MBTK_FUNC(mbtk_http_handle_get)(TRUE, http_data_cb_func);
+
+			if(http_handle < 0)
+			{
+			    LOG("mbtk_http_handle_get() fail.");
+			    ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+			}else{
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+            }
+
+            break;
+        }
+		case TEL_EXT_GET_CMD :
+		{
+			char resp_buf[50] ={0};
+			if(http_handle < 0)
+			{
+				sprintf(resp_buf, "$HTTPOPEN:%d", 0);
+				ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);	
+			}else{
+
+				sprintf(resp_buf, "$HTTPOPEN:%d", 1);
+				ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);	
+			};
+
+			break;
+
+		}
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+}
+
+
+
+utlReturnCode_T MBTK_AT_HTTPCLOSE_PROCESS(const utlAtParameterOp_T op,
+                                       const char *command_name_p,
+                                       const utlAtParameterValue_P2c parameter_values_p,
+                                       const size_t num_parameters,
+                                       const char *info_text_p,
+                                       unsigned int *xid_p,
+                                       void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int at_handle = MAKE_AT_HANDLE(sAtp_index);
+    *xid_p = at_handle;
+
+    LOG("%s enter with command_op [%s]", command_name_p, op2str(op));
+
+    switch(op)
+    {
+        case TEL_EXT_ACTION_CMD :
+        {
+            int i = 0;
+            if(http_handle < 0)
+            {
+				LOG("http close handle is < 0");
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);  
+                break;
+            }
+
+            mbtk_http_close_port();
+            for(i = 0; i < 30; i++)
+            {
+                if(req_h[i].value)
+                {
+                    free(req_h[i].value);
+                    req_h[i].value = NULL;
+                }
+            }
+
+            ret = MBTK_FUNC(mbtk_http_handle_free)(http_handle);
+
+			if(ret )
+			{
+			    LOG("mbtk_http_handle_free() fail.");
+			    ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+			}else{
+                http_handle = -1;
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+            }
+            break;
+        }
+		case TEL_EXT_GET_CMD :
+		{
+			char resp_buf[50] ={0};
+			if(http_handle >= 0)
+			{
+				sprintf(resp_buf, "$HTTPCLOSE:%d", 1);
+				ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);	
+			}else{
+
+				sprintf(resp_buf, "$HTTPCLOSE:%d", 0);
+				ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);	
+			};
+
+			break;
+
+		}
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+}
+
+//$HTTPPARA="",(0-65535),(0-1), (0-1)
+utlReturnCode_T MBTK_AT_HTTPPARA_PROCESS(const utlAtParameterOp_T op,
+                                       const char *command_name_p,
+                                       const utlAtParameterValue_P2c parameter_values_p,
+                                       const size_t num_parameters,
+                                       const char *info_text_p,
+                                       unsigned int *xid_p,
+                                       void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int at_handle = MAKE_AT_HANDLE(sAtp_index);
+    *xid_p = at_handle;
+
+    LOG("%s enter with command_op [%s]", command_name_p, op2str(op));
+
+    switch(op)
+    {
+        case TEL_EXT_SET_CMD :
+        {
+            const static int cmd_len_max = MBTK_AT_RESP_LEN_MAX;
+            static char cmd[MBTK_AT_RESP_LEN_MAX] ={0};
+            char url[255] ={0};
+            char resp_buf[100] = {0};
+            bool ingnore_cert = TRUE;
+ 
+            int arg3 = 0, port = 0, is_ssl = 0;
+            int len = 0;
+            if(!getExtString(parameter_values_p, 0, cmd, cmd_len_max, &len, ""))
+            {
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+
+            if(!getExtValue(parameter_values_p, 1, &port, 0, 65535, 0))
+            {
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+
+			if(!getExtValue(parameter_values_p, 2, &is_ssl, 0, 2, 0))
+            {
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+
+			if(!getExtValue(parameter_values_p, 3, &arg3, 0, 2, 0))
+            {
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+
+            if(is_ssl)
+            {
+                if(!memcmp(cmd,"https://",8))
+                {
+                    sprintf(url, "%s:%d", cmd, port);
+                }
+                else if(!memcmp(cmd,"http://",7))
+                {
+                    ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);  
+                    break;
+                }
+                else
+                {
+                    sprintf(url, "https://%s:%d", cmd, port);
+                }
+            }
+            else
+            {
+                sprintf(url, "%s:%d", cmd, port);
+            }
+
+			 if(http_handle < 0)
+            {
+				LOG("http is not  open");
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);  
+                break;
+            }
+
+            http_session = MBTK_FUNC(mbtk_http_session_create)(http_handle,1,1);
+			if(http_session < 0)
+			{
+			    LOG("mbtk_http_handle_get() fail.");
+			    ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+			}
+            else
+            {
+				ret = MBTK_FUNC(mbtk_http_session_url_set)(http_handle,http_session,url);
+				if(ret )
+				{
+				    ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+				}
+                else
+                {
+                    if(arg3)
+                        ingnore_cert = FALSE;
+                    
+                    if(!ingnore_cert)
+                    {
+                        ret = MBTK_FUNC(mbtk_http_session_ingnore_cert_set)(http_handle,http_session,ingnore_cert);
+                        if(ret)
+                        {
+                            LOG("mbtk_http_session_ingnore_cert_set() fail.");
+                            ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                            break;
+                        }
+                    }
+                    
+                    ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+		        }
+            }
+
+            break;
+        }
+		case TEL_EXT_GET_CMD :
+		{
+			char resp_buf[1024] ={0};
+			const mbtk_http_session_t* session = MBTK_FUNC(mbtk_http_session_get)(http_handle, http_session);
+			if(session != NULL)
+			{
+				sprintf(resp_buf, "Host:\"%s\"\r\nURI:\"%s\"\r\nport:%d\r\nCert:%d",\
+					 session->host,session->uri, session->port,session->is_ssl);
+			}
+
+			ATRESP(IND_REQ_HANDLE , ATCI_RESULT_CODE_NULL, 0, resp_buf);
+			ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+			break;
+		}
+		case TEL_EXT_TEST_CMD :
+		{
+			char resp_buf[50] ={0};
+			memcpy(resp_buf, "$HTTPPARA=\"\",(0-65535),(0-1), (0-1)", strlen("$HTTPPARA=\"\",(0-65535),(0-1), (0-1)"));
+
+			ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);
+			break;
+
+		}
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+}		
+
+utlReturnCode_T MBTK_AT_HTTPSEND_PROCESS(const utlAtParameterOp_T op,
+                                       const char *command_name_p,
+                                       const utlAtParameterValue_P2c parameter_values_p,
+                                       const size_t num_parameters,
+                                       const char *info_text_p,
+                                       unsigned int *xid_p,
+                                       void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int at_handle = MAKE_AT_HANDLE(sAtp_index);
+    *xid_p = at_handle;
+
+    LOG("%s enter with command_op [%s]", command_name_p, op2str(op));
+
+    switch(op)
+    {
+        case TEL_EXT_ACTION_CMD :
+        {
+            printf("MBTK HTTP Version 1.1");
+            char resp_buf[150] ={0};
+
+			if(http_handle < 0)
+			{
+			    printf("mbtk_http_handle_get() fail.");
+			    ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+			}else{
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+            }
+
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+}
+
+
+
+utlReturnCode_T MBTK_AT_HTTPRQH_PROCESS(const utlAtParameterOp_T op,
+                                       const char *command_name_p,
+                                       const utlAtParameterValue_P2c parameter_values_p,
+                                       const size_t num_parameters,
+                                       const char *info_text_p,
+                                       unsigned int *xid_p,
+                                       void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int at_handle = MAKE_AT_HANDLE(sAtp_index);
+    *xid_p = at_handle;
+
+    LOG("%s 11111111111111enter with command_op [%s]", command_name_p, op2str(op));
+
+    switch(op)
+    {
+        case TEL_EXT_SET_CMD :
+        {
+            const static int rqh_head_len_max = MBTK_AT_RESP_LEN_MAX;
+            static char rqh_head[MBTK_AT_RESP_LEN_MAX];
+            char rqh_buf[100] = {0};
+            char buf_test[100] ={0};
+            char *p = buf_test;
+            int len = 0;
+            memset(rqh_head, 0x0, MBTK_AT_RESP_LEN_MAX);
+            if(!getExtString(parameter_values_p, 0, rqh_head, rqh_head_len_max, &len, ""))
+            {
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, "MBTK_AT_HTTPRQH_PROCESS1");
+                LOG("Get CMD Fail.");
+                break;
+            }
+            else{
+                memcpy(buf_test,rqh_head, strlen(rqh_head) );
+            }
+
+            len = 0;
+            if(!getExtString(parameter_values_p, 1, rqh_buf, rqh_head_len_max, &len, ""))
+            {
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, "MBTK_AT_HTTPRQH_PROCESS1_buf");
+                LOG("Get CMD Fail.");
+                break;
+            }
+
+			 if(http_handle < 0)
+            {
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, NULL);  
+                break;
+            }
+
+            ret = MBTK_FUNC(mbtk_http_session_head_add)(http_handle,  http_session, rqh_head, rqh_buf);
+    
+			if(ret)
+			{
+			    LOG("mbtk_http_handle_get() fail.");
+			    ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+			}else{
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+                
+                int i = 0;
+                for(i = 0; i < 30; i++)
+                {
+                    if( !strcmp(req_h[i].name, rqh_head) )
+                    {
+                        if(req_h[i].value)
+                        {
+                            free(req_h[i].value);
+                        }
+                
+                        req_h[i].value = (char*)malloc(strlen(rqh_buf) + 1);
+                        if(req_h[i].value == NULL)
+                        {
+                            return -1;
+                        }
+                        memset(req_h[i].value, 0x0, strlen(rqh_buf) + 1);
+                        memcpy(req_h[i].value, rqh_buf, strlen(rqh_buf));
+                
+                    }
+                }
+                
+                for(i = 0; i < 30; i++)
+                {
+                    if(req_h[i].value == NULL)
+                    {
+                        break;
+                    }
+                }
+                
+                memcpy(req_h[i].name, rqh_head, strlen(rqh_head));
+                req_h[i].value = (char*)malloc(strlen(rqh_buf) + 1);
+                if(req_h[i].value == NULL)
+                {
+                //    return -1;
+                    break;
+                }
+                memset(req_h[i].value, 0x0, strlen(rqh_buf) + 1);
+                memcpy(req_h[i].value, rqh_buf, strlen(rqh_buf));
+
+            }
+
+            break;
+        }
+        case TEL_EXT_GET_CMD :
+        {
+            char resp_buf[1024] ={0};
+            int index = 0;
+            int len = 0;
+            int i = 0;
+
+            for(i = 0; i < 30; i++)
+            {
+                if(req_h[i].value == NULL)
+                {
+                    break;
+                }
+
+                sprintf(resp_buf, "%s:%s\n", req_h[i].name, req_h[i].value);
+                ATRESP(IND_REQ_HANDLE , ATCI_RESULT_CODE_NULL, 0, resp_buf);
+                memset(resp_buf, 0, sizeof(resp_buf));
+            }
+
+			if(i == 0)
+			{
+				ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, "$HTTPRQH: \"\"");
+			}
+			else
+			{
+				ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+			}
+			
+			break;
+		}
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+}
+
+
+utlReturnCode_T MBTK_AT_HTTPACTION_PROCESS(const utlAtParameterOp_T op,
+                                        const char *command_name_p,
+                                        const utlAtParameterValue_P2c parameter_values_p,
+                                        const size_t num_parameters,
+                                        const char *info_text_p,
+                                        unsigned int *xid_p,
+                                        void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int at_handle = MAKE_AT_HANDLE(sAtp_index);
+    char resp_buf[MBTK_AT_RESP_LEN_MAX] = {0};
+    int arg1 = 0;
+    int type = 0;
+    *xid_p = at_handle;
+
+    LOG("%s enter with command_op [%s]", __FUNCTION__, op2str(op));
+
+    switch(op)
+    {
+        case TEL_EXT_TEST_CMD :
+        {
+            char resp_buf[50] ={0};
+            memcpy(resp_buf, "$HTTPACTION: (0-3) ", strlen("$HTTPACTION: (0-3) "));
+
+            ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);
+            break;
+        }
+        case TEL_EXT_SET_CMD :
+        {
+            int gnss_ret;
+
+            if(!getExtValue(parameter_values_p, 0, &arg1, 0, 3, 0))
+            {
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+
+            if(arg1 == 0){ type = 1;}
+            else if(arg1== 2){type = 0; }
+            else if(arg1== 3){type = 2; }
+            else{
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+
+            ret = MBTK_FUNC(mbtk_http_session_option_reset)(http_handle,http_session,type);
+            if(ret)
+            {
+                LOG("mbtk_http_handle_get() fail.");
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+            }
+            else
+            {
+
+                if(http_type)
+                {
+                    file_fd = open("/http_test.txt", O_WRONLY|O_TRUNC|O_CREAT|O_APPEND, 0666);
+                    if(file_fd < 0) 
+                    {
+                        LOG("mbtk_http_session_type_set fail");
+                        ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                        break;
+                    }
+                }
+
+                ret = MBTK_FUNC(mbtk_http_session_start)(http_handle, http_session);
+                if(ret)
+                {
+                    ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                }else{
+                    ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+                }
+
+                if(file_fd >= 0)
+                {
+                    if(close(file_fd))
+                    {
+                        LOG("close() fail file_fd:%d",file_fd);
+                    }
+                    file_fd = -1;
+                }
+
+//                mbtk_http_close_port();
+            }
+
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+}
+
+
+utlReturnCode_T MBTK_AT_HTTPTYPE_PROCESS(const utlAtParameterOp_T op,
+const char *command_name_p,
+const utlAtParameterValue_P2c parameter_values_p,
+const size_t num_parameters,
+const char *info_text_p,
+unsigned int *xid_p,
+void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int at_handle = MAKE_AT_HANDLE(sAtp_index);
+    char resp_buf[MBTK_AT_RESP_LEN_MAX] = {0};
+    int arg1 = 0;
+    *xid_p = at_handle;
+
+    LOG("%s enter with command_op [%s]", __FUNCTION__, op2str(op));
+
+    switch(op)
+    {
+    	case TEL_EXT_TEST_CMD :
+    	{
+			ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, "$HTTPTYPE: (0-1)");
+			break;
+
+		}
+        case TEL_EXT_GET_CMD :
+        {
+           	char resp_buf[50] ={0};
+			const mbtk_http_session_t* session = MBTK_FUNC(mbtk_http_session_get)(http_handle, http_session);
+			if(session != NULL)
+			{
+				sprintf(resp_buf, "$HTTPTYPE:%d",session->type);
+			}
+            ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);
+            break;
+        }
+        case TEL_EXT_SET_CMD :
+        {
+            int gnss_ret;
+
+            if(!getExtValue(parameter_values_p, 0, &arg1, 0, 1, 0))
+            {
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+
+            http_type = arg1;
+            ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+
+        }
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+}
+
+//$HTTPDATAEX: (0-500) ,"" 
+utlReturnCode_T MBTK_AT_HTTPDATAEX_PROCESS(const utlAtParameterOp_T op,
+const char *command_name_p,
+const utlAtParameterValue_P2c parameter_values_p,
+const size_t num_parameters,
+const char *info_text_p,
+unsigned int *xid_p,
+void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int at_handle = MAKE_AT_HANDLE(sAtp_index);
+    char resp_buf[MBTK_AT_RESP_LEN_MAX] = {0};
+    int arg1 = 0, arg2 = 0;
+    *xid_p = at_handle;
+
+    LOG("%s enter with command_op [%s]", __FUNCTION__, op2str(op));
+
+    switch(op)
+    {
+        case TEL_EXT_TEST_CMD :
+        {
+            char resp_buf[50] ={0};
+			memcpy(resp_buf, "$HTTPDATAEX: (0-500) ,\"\"",strlen("$HTTPDATAEX: (0-500) ,\"\""));
+			ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, resp_buf);
+			break;
+        }
+        case TEL_EXT_SET_CMD :
+        {
+            int gnss_ret;
+
+			const static int cmd_len_max = MBTK_AT_RESP_LEN_MAX;
+            static char cmd[MBTK_AT_RESP_LEN_MAX];
+            int len = 0;
+			
+            if(!getExtValue(parameter_values_p, 0, &arg1, 0, 501, 0))
+            {
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+
+			memset(cmd, 0x0, MBTK_AT_RESP_LEN_MAX);
+            if(!getExtString(parameter_values_p, 1, cmd, cmd_len_max, &len, ""))
+            {
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                LOG("Get CMD Fail.");
+                break;
+            }
+
+			ret = MBTK_FUNC(mbtk_http_session_option_reset)(http_handle,http_session,2);
+			if(ret)
+			{
+				LOG("mbtk_http_session_option_reset fail");
+				ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+
+			}
+			else
+			{
+
+				ret = MBTK_FUNC(mbtk_http_session_content_set)(http_handle,http_session,cmd,arg1);
+				if(ret)
+				{
+					sprintf(resp_buf, "mbtk_http_session_content_set fail,arg1:%d, len:%d, cmd:%s\r\n", arg1,len, cmd);
+					LOG(resp_buf);
+				    ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+				}
+				else
+				{
+	                ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+	            }
+			}
+
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+}
+
+
+//$HTTPREAD: (0-1),(0-512000) 
+utlReturnCode_T MBTK_AT_HTTPREAD_PROCESS(const utlAtParameterOp_T op,
+const char *command_name_p,
+const utlAtParameterValue_P2c parameter_values_p,
+const size_t num_parameters,
+const char *info_text_p,
+unsigned int *xid_p,
+void *arg_p)
+{
+    UNUSEDPARAM(command_name_p);
+    UNUSEDPARAM(num_parameters);
+    UNUSEDPARAM(info_text_p);
+
+    utlReturnCode_T ret = utlFAILED;
+    TelAtParserID sAtp_index = *(TelAtParserID *)arg_p;
+    unsigned int at_handle = MAKE_AT_HANDLE(sAtp_index);
+    char resp_buf[MBTK_AT_RESP_LEN_MAX] = {0};
+    int arg1 = 0, arg2 = 0;
+    *xid_p = at_handle;
+
+    LOG("%s enter with command_op [%s]", __FUNCTION__, op2str(op));
+
+    switch(op)
+    {
+        case TEL_EXT_TEST_CMD :
+        {
+            ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, "$HTTPREAD: (0-1),(0-512000) ");
+            break;
+        }
+		case TEL_EXT_GET_CMD:
+		{
+			ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+			break;
+		}
+        case TEL_EXT_SET_CMD :
+        {
+            int gnss_ret;
+
+            if(!getExtValue(parameter_values_p, 0, &arg1, 0, 2, 0))
+            {
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+
+			if(!getExtValue(parameter_values_p, 1, &arg2, 0, 512001, 0))
+            {
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+
+//            char buf[100] ={0};
+//            sprintf(buf, "arg1:%d, arg2%d\n", arg1, arg2);
+
+//            ATRESP(IND_REQ_HANDLE , ATCI_RESULT_CODE_NULL, 0, buf);
+
+            
+            if(arg1 == 0)   // read data
+            {
+                if(arg2 < 1)
+                    arg2 = 0;
+                    
+            }
+            else if(arg1 == 1){    // read file size
+                arg2 = 0;
+            }
+            else{
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+                break;
+            }
+
+            ret = mbtk_http_read_file_data1(arg1,arg2);
+            if(ret)
+            {
+                LOG("mbtk_http_read_file_data fail");
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_ERROR, 0, NULL);
+            }else{
+                ret = ATRESP(at_handle, ATCI_RESULT_CODE_OK, 0, NULL);
+            }
+
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+
+    return ret;
+}
+
+
+
diff --git a/mbtk/mbtk_at/src/mbtk_at_tcpip.c b/mbtk/mbtk_at/src/mbtk_at_tcpip.c
new file mode 100755
index 0000000..5e0499c
--- /dev/null
+++ b/mbtk/mbtk_at/src/mbtk_at_tcpip.c
Binary files differ
diff --git a/mbtk/mbtk_at/src/mbtk_rgmii_loopback.c b/mbtk/mbtk_at/src/mbtk_rgmii_loopback.c
new file mode 100755
index 0000000..c127cbe
--- /dev/null
+++ b/mbtk/mbtk_at/src/mbtk_rgmii_loopback.c
@@ -0,0 +1,269 @@
+#if 1//MBTK_RGMII_TEST
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>// close()
+#include <string.h>// strcpy, memset(), and memcpy()
+#include <netdb.h> // struct addrinfo
+#include <sys/types.h>  // needed for socket(), uint8_t, uint16_t, uint32_t
+#include <sys/socket.h>  // needed for socket()
+#include <netinet/in.h> // IPPROTO_ICMP, INET_ADDRSTRLEN
+#include <netinet/ip.h>// struct ip and IP_MAXPACKET (which is 65535)
+#include <netinet/ip_icmp.h> // struct icmp, ICMP_ECHO
+#include <arpa/inet.h> // inet_pton() and inet_ntop()
+#include <sys/ioctl.h> // macro ioctl is defined
+//#include <bits/ioctls.h>  // defines values for argument "request" of ioctl.
+#include <net/if.h> // struct ifreq
+#include <linux/if_ether.h> // ETH_P_IP = 0x0800, ETH_P_IPV6 = 0x86DD
+#include <linux/if_packet.h> // struct sockaddr_ll (see man 7 packet)
+//#include <net/ethernet.h>
+#include <errno.h> // errno, perror()
+
+#include <linux/mii.h>
+#include <linux/sockios.h>
+#include <linux/types.h>
+
+#include "mbtk_at.h"
+
+#define ETH_P_DEAN 0x8874 //自定义的以太网协议type
+
+//mdio eth0 1          	读取phy寄存器1的数值
+//mdio eth0 0 0x1120      将0x1120写入 phy寄存器1
+#define reteck(ret)     \
+        if(ret < 0){    \
+            LOG("[RGMIITEST]%s : line: %d", __func__, __LINE__);   \
+            goto lab;   \
+        }
+
+#if 0
+#define help() \
+    printf("mdio:\n");                  \
+    printf("read operation: mdio reg_addr\n");          \
+    printf("write operation: mdio reg_addr value\n");    \
+    printf("For example:\n");            \
+    printf("mdio eth0 1\n");             \
+    printf("mdio eth0 0 0x12\n\n");      \
+    exit(0);
+#endif
+
+int sockfd;
+
+//net_name:网卡名字,mode:get 1/set 0,reg_addr: 寄存器地址,value:值
+int mbtk_mdio(char* net_name,int mode, uint16_t reg_addr, uint16_t value)
+{
+    if(net_name == NULL)
+    {
+        return -1;
+    }
+
+    struct mii_ioctl_data *mii = NULL;
+    struct ifreq ifr;
+    int ret;
+
+    memset(&ifr, 0, sizeof(ifr));
+    strncpy(ifr.ifr_name, net_name, IFNAMSIZ - 1);
+
+    sockfd = socket(PF_LOCAL, SOCK_DGRAM, 0);
+    reteck(sockfd);
+
+    //get phy address in smi bus
+    ret = ioctl(sockfd, SIOCGMIIPHY, &ifr);
+    reteck(ret);
+
+    mii = (struct mii_ioctl_data*)&ifr.ifr_data;
+
+    if(mode == 1)
+    {
+
+        mii->reg_num = reg_addr;
+
+        ret = ioctl(sockfd, SIOCGMIIREG, &ifr);
+        reteck(ret);
+
+        LOG("[RGMIITEST]read phy addr: 0x%x  reg: 0x%x   value : 0x%x\n", mii->phy_id, mii->reg_num, mii->val_out);
+
+        if (mii->reg_num == 0x1)
+        {
+            LOG("[RGMIITEST]Link Status\n");
+
+            if(mii->val_out& 0x0004)
+            {
+                LOG("[RGMIITEST]link is up\n");
+            }
+            else
+            {
+                LOG("[RGMIITEST]link is down\n");
+            }
+        }
+    }
+    else if(mode == 0)
+    {
+
+        mii->reg_num    = reg_addr;
+        mii->val_in     = value;
+
+        ret = ioctl(sockfd, SIOCSMIIREG, &ifr);
+        reteck(ret);
+
+        LOG("[RGMIITEST]write phy addr: 0x%x  reg: 0x%x  value : 0x%x\n", mii->phy_id, mii->reg_num, mii->val_in);
+    }
+
+    close(sockfd);
+    return 0;
+    lab:
+    close(sockfd);
+    return -1;
+}
+ 
+int mbtk_rgmii_loopback(void)
+{
+    int i, datalen, frame_length, sd, bytes;
+    char *interface = "eth0";
+    uint8_t data[100];
+    uint8_t src_mac[6];
+    uint8_t dst_mac[6];
+    uint8_t ether_frame[100] = {0};
+    struct sockaddr_ll device;
+    struct ifreq ifr;
+    int recvlen=0;
+    uint8_t buffer[100] = {0};
+    int loopback_state=0;
+    int ret = -1;
+
+    // Submit request for a socket descriptor to look up interface.
+    if ((sd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0)
+    {
+        LOG("[RGMIITEST]socket() failed to get socket descriptor for using ioctl()");
+        return -1;
+    }
+
+    // Use ioctl() to look up interface name and get its MAC address.
+    memset(&ifr, 0, sizeof(ifr));
+    snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", interface);
+    if (ioctl(sd, SIOCGIFHWADDR, &ifr) < 0)
+    {
+        close(sd);
+        LOG("[RGMIITEST]ioctl() failed to get source MAC address ");
+        return -1;
+    }
+    close(sd);
+ 
+    // Copy source MAC address.
+    memcpy(src_mac, ifr.ifr_hwaddr.sa_data, 6);
+ 
+    // Report source MAC address to stdout.
+    LOG("[RGMIITEST]MAC address for interface %s is %02x:%02x:%02x:%02x:%02x:%02x", interface, \
+                            src_mac[0], src_mac[1], src_mac[2], src_mac[3], src_mac[4], src_mac[5]);
+ 
+    // Find interface index from interface name and store index in
+    // struct sockaddr_ll device, which will be used as an argument of sendto().
+    memset(&device, 0, sizeof(device));
+    if ((device.sll_ifindex = if_nametoindex(interface)) == 0)
+    {
+        LOG("[RGMIITEST]if_nametoindex() failed to obtain interface index ");
+        return -1;
+    }
+    LOG("[RGMIITEST]Index for interface %s is %i", interface, device.sll_ifindex);
+ 
+    // Set destination MAC address: you need to fill these out
+    dst_mac[0] = 0x72; //设置目的网卡地址
+    dst_mac[1] = 0x40;
+    dst_mac[2] = 0xB8;
+	dst_mac[3] = 0xF7;
+    dst_mac[4] = 0x5A;
+    dst_mac[5] = 0x64;
+ 
+    // Fill out sockaddr_ll.
+    device.sll_family = AF_PACKET;
+    memcpy(device.sll_addr, src_mac, 6);
+    device.sll_halen = htons(6);
+ 
+    // 发送的data,长度可以任意,但是抓包时看到最小数据长度为46,这是以太网协议规定以太网帧数
+    //据域部分最小为46字节,不足的自动补零处理
+ 
+    datalen = 12;
+    data[0] = 'h';
+    data[1] = 'e';
+    data[2] = 'l';
+    data[3] = 'l';
+    data[4] = 'o';
+    data[5] = ' ';
+    data[6] = 'w';
+    data[7] = 'o';
+    data[8] = 'r';
+    data[9] = 'l';
+    data[10] = 'd';
+    data[11] = '!';
+ 
+    // Fill out ethernet frame header.
+    frame_length = 6 + 6 + 2 + datalen;
+    // Destination and Source MAC addresses
+    memcpy(ether_frame, dst_mac, 6);
+    memcpy(ether_frame + 6, src_mac, 6);
+ 
+    ether_frame[12] = ETH_P_DEAN / 256;
+    ether_frame[13] = ETH_P_DEAN % 256;
+
+    // data
+    memcpy(ether_frame + 14, data, datalen);
+    // Submit request for a raw socket descriptor.
+    if ((sd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0)
+    { //创建正真发送的socket
+        LOG("[RGMIITEST]socket() failed ");
+		return -1;
+    }
+
+    //set recv timeout
+    struct timeval tv;
+    tv.tv_sec = 3;
+    tv.tv_usec = 0;
+    ret = setsockopt( sd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv) );
+    if(ret != 0)
+    {
+        LOG("[RGMIITEST]setsockopt is fail ret = [%d]", ret);
+    }
+
+    // Send ethernet frame to socket.
+    if ((bytes = sendto(sd, ether_frame, frame_length, 0, (struct sockaddr *)&device,
+        sizeof(device))) <= 0)
+    {
+        close(sd);
+        LOG("[RGMIITEST]sendto() failed");
+        return -1;
+    }
+	LOG("[RGMIITEST]IP_MAXPACKET = %d", IP_MAXPACKET, bytes);
+    LOG("[RGMIITEST]sendlen = %d sendto data:", bytes);
+    LOG("[RGMIITEST]%s", ether_frame);
+
+    recvlen = recvfrom(sd,buffer,sizeof(buffer),0,NULL,NULL);
+    if(recvlen < 0)
+    {
+        if(errno == EWOULDBLOCK)
+        {
+            LOG("[RGMIITEST] recv timeout");
+        }
+        close(sd);
+        return -1;
+    }
+	LOG("[RGMIITEST]recvlen = %d recvfrom data:\n", recvlen);
+    LOG("[RGMIITEST]%s", buffer);
+ 
+    for(i=0; i<recvlen; i++) {
+        if(bytes>recvlen)
+        {
+            loopback_state=-1;
+            break;
+        }
+        else if(ether_frame[i]!=buffer[i])
+        {
+            loopback_state=-1;
+			LOG("[RGMIITEST]ether_frame[%d]:%02x buffer[%d]:%02x", i, ether_frame[i], i, buffer[i]);
+            break;
+        }
+    }
+    
+    // Close socket descriptor.
+    close(sd);
+    return loopback_state;
+}
+
+#endif
\ No newline at end of file