[Feature]add MT2731_MP2_MR2_SVN388 baseline version

Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em.cpp
new file mode 100644
index 0000000..7e9609f
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em.cpp
@@ -0,0 +1,734 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include "em/em.h"
+
+#include <vendor-ril/telephony/ril.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <cutils/jstring.h>
+#include <log/log.h>
+#include <unistd.h>
+#include <math.h>
+#include  "common.h"
+
+#if EM_MODE_SUPPORT
+
+#undef LOG_TAG
+#define LOG_TAG "EM_ENTRY"
+
+#define NUM_ITEMS(a)     (sizeof (a) / sizeof (a)[0])
+em_arry_t lte_info[] = {
+    //{"4G ERRC Misc Info",0,NULL,1,1},
+    //{"4G LTE Support Band",0,NULL,1,1},
+    //{"4G Active Intra-RAT Meas (LTE)",0,NULL,1,1},
+    //{"4G Active Inter-RAT Meas (UMTS)",0,NULL,1,1},
+    //{"4G Active Inter-RAT Meas (GSM)",0,NULL,1,1},
+    //{"4G SIB Receive Status",0,NULL,1,1},
+    //{"4G CSG Autonomous Search",0,NULL,1,1},
+    //{"4G Config Info",0,NULL,1,1},
+    //{"ESM",0,NULL,1,1},
+    //{"EMM",0,NULL,1,1},
+    //{"MMDC",0,NULL,1,1},
+    {"EL1",0,NULL,1,1},
+    //{"Timer Information",0,NULL,1,1},
+    //{"TDD TAS",0,NULL,1,1},
+    //{"GSM TAS",0,NULL,1,1},
+    //{"WCDMA TAS",0,NULL,1,1},
+    //{"LTE TAS",0,NULL,1,1},
+};
+em_arry_t ims_setting[] = {
+    {"get",0,NULL,0,0},
+    {"set",0,NULL,0,0},
+};
+em_arry_t ims_common[] = {
+    {"operator_code",2,ims_setting,0,0},
+    {"sms_support",2,ims_setting,0,0},
+    {"voice_support",2,ims_setting,0,0}
+};
+em_arry_t ims_call[] = {
+    {"UA_call_codec_order1",2,ims_setting,0,0},
+    {"UA_call_codec_order2",2,ims_setting,0,0},
+    {"UA_call_codec_order3",2,ims_setting,0,0},
+    {"silence_dropcall_threshold",2,ims_setting,0,0},
+    {"jbm_load_params_enable",2,ims_setting,0,0},
+    {"jbm_prebuf_len",2,ims_setting,0,0},
+};
+em_arry_t ims_registration[] = {
+    {"emergency_reg_retain_timer",2,ims_setting,0,0},
+    {"UA_reg_auth_password",2,ims_setting,0,0},
+    {"UA_reg_auth_name",2,ims_setting,0,0},
+    {"VoLTE_Setting_SIP_TCP_On_Demand",2,ims_setting,0,0},
+};
+em_arry_t ims[] = {
+    {"Common",NUM_ITEMS(ims_common),ims_common,1,1},
+    {"Call",NUM_ITEMS(ims_call),ims_call,1,1},
+    {"Registration",NUM_ITEMS(ims_registration),ims_registration,1,1},
+};
+em_arry_t gprs[] = {
+    {"ATTACH",0,NULL,1,1},
+    {"DETACH",0,NULL,1,1},
+    {"ATTACH_CONTINUE",0,NULL,1,1},
+    {"DETACH_CONTINUE",0,NULL,1,1},
+    {"SELECT_ATTACH_TYPE_1",0,NULL,1,1},
+    {"SELECT_ATTACH_TYPE_0",0,NULL,1,1},
+};
+em_arry_t networkselection[] = {
+    {"GSM/WCDMA (WCDMA preferred)",0,NULL,1,1},
+    {"GSM only",0,NULL,1,1},
+    {"WCDMA only",0,NULL,1,1},
+    {"GSM/WCDMA (auto)",0,NULL,1,1},
+    {"LTE only",0,NULL,1,1},
+    {"4G/3G/2G(auto)",0,NULL,1,1},
+    {"4G/3G",0,NULL,1,1},
+};
+em_arry_t modem_cta[] = {
+    {"Integrity Check",0,NULL,1,1},
+    {"RLC TL1",0,NULL,1,1},
+    {"K1297",0,NULL,1,1},
+    {"SN Conflict",0,NULL,1,1},
+    {"CF query",0,NULL,1,1},
+    {"DLMN lock",0,NULL,1,1},
+    {"Measurement open",0,NULL,1,1},
+    {"Disable DPA",0,NULL,1,1},
+    {"Intra CMR",0,NULL,1,1},
+};
+em_arry_t modem_fta[] = {
+    {"ANITE",0,NULL,1,1},
+    {"CRTUG",0,NULL,1,1},
+    {"CRTUW",0,NULL,1,1},
+    {"ANRITSU",0,NULL,1,1},
+    {"CMW500",0,NULL,1,1},
+};
+em_arry_t modem_C2K_Test_MODEM[] = {
+    { "NONE", 0, NULL, 1, 1 },
+    { "SPIRENT", 0,NULL, 1, 1 },
+};
+em_arry_t modemtest[] = {
+    {"NONE",0,NULL,1,1},
+    {"CTA",NUM_ITEMS(modem_cta),modem_cta,1,1},
+    {"FTA",NUM_ITEMS(modem_fta),modem_fta,1,1},
+    {"IOT",0,NULL,1,1},
+    {"OPERATOR",0,NULL,1,1},
+    {"FACTORY",0,NULL,1,1},
+    {"CDMA Test Mode", NUM_ITEMS(modem_C2K_Test_MODEM),modem_C2K_Test_MODEM,1,1},
+};
+em_arry_t hspa[] = {
+    {"QUERY",0,NULL,1,1},
+};
+em_arry_t cfu[] = {
+    {"Default",0,NULL,1,1},
+    {"Always query",0,NULL,1,1},
+    {"Always not query",0,NULL,1,1},
+};
+em_arry_t bandmode[] = {
+    {"getcurrentband",0,NULL,1,1},
+    {"setBand(eg: 1.1=1 add band, 1.1=0 remove band) or getSupportBand",0,NULL,1,1},
+};
+em_arry_t networkinfo[] = {
+    {"RR Cell Sel",0,NULL,1,1},
+    {"RR Ch Dscr",0,NULL,1,1},
+    {"RR Ctrl chan",0,NULL,1,1},
+    {"RR RACH Ctrl",0,NULL,1,1},
+    {"RR LAI Info",0,NULL,1,1},
+    {"RR Radio Link",0,NULL,1,1},
+    {"RR Meas Rep",0,NULL,1,1},
+    {"RR Ca List",0,NULL,1,1},
+    {"RR Control Msg",0,NULL,1,1},
+    {"RR SI2Q Info",0,NULL,1,1},
+    {"RR MI Info",0,NULL,1,1},
+    {"RR BLK Info",0,NULL,1,1},
+    {"RR TBF Info",0,NULL,1,1},
+    {"RR GPRS Gen",0,NULL,1,1},
+    {"SMEmInfo",0,NULL,1,1},
+    {"3GMmEmInfo",0,NULL,1,1},
+    {"GmmEmInfo",0,NULL,1,1},
+#if 1
+    {"3GTcmMmiEmInfo",0,NULL,1,1},
+    {"3GGeneralStatusInd",0,NULL,1,1},
+    {"xGCsceEMNeighCellSStatusInd",0,NULL,1,1},
+    {"3GCsceEMServCellSStatusInd",0,NULL,1,1},
+    {"3GCsceEmInfoMultiPlmn",0,NULL,1,1},
+    {"3GMemeEmPeriodicBlerReportInd",0,NULL,1,1},
+    {"3GUrrUmtsSrncId",0,NULL,1,1},
+    {"3GMemeEmInfoHServCellInd",0,NULL,1,1},
+#endif
+#if 1//fdd
+    {"3GMemeEmInfoUmtsCellStatus",0,NULL,1,1},
+    {"3GSlceEmPsDataRateStatusInd",0,NULL,1,1},
+#endif
+#if 0//tdd
+    {"3GHandoverSequenceIndStuct",0,NULL,1,1},
+    {"3GUl2EmAdmPoolStatusIndStruct",0,NULL,1,1},
+    {"3GUl2EmPsDataRateStatusIndStruct",0,NULL,1,1},
+    {"3GUl2EmHsdschReconfigStatusIndStruct",0,NULL,1,1},
+    {"3GUl2EmUrlcEventStatusIndStruct",0,NULL,1,1},
+    {"3G Ul2EmPeriodicBlerReportInd",0,NULL,1,1},
+#endif
+#if 0 //lte
+    {"3G speech codec",0,NULL,1,1},//lte
+    {"Security Configuration",0,NULL,1,1},//lte
+#endif
+};
+
+em_arry_t antenna_setmodes_4g[] {
+    {"RX1&RX2", 0, NULL, 1, 1},
+    {"RX1", 0, NULL, 1, 1},
+    {"RX2", 0, NULL, 1, 1},
+};
+
+em_arry_t antenna_setmodes_3g[] {
+    {"RX1", 0, NULL, 1, 1},
+    {"RX2", 0, NULL, 1, 1},
+    {"RX1&RX2", 0, NULL, 1, 1},
+    {"Resume default setting", 0, NULL, 1, 1},
+};
+
+em_arry_t antenna_setmodes_c2k[] {
+    {"Resume default setting", 0, NULL, 1, 1},
+    {"RX1", 0, NULL, 1, 1},
+    {"RX2", 0, NULL, 1, 1},
+    {"RX1&RX2", 0, NULL, 1, 1},
+};
+
+em_arry_t antenna_4Gmode[] = {
+    {"getmode",0,NULL,1,1},
+    {"setmode",NUM_ITEMS(antenna_setmodes_4g),antenna_setmodes_4g,1,1},
+};
+
+em_arry_t antenna_3Gmode[] = {
+    {"getmode",0,NULL,1,1},
+    {"setmode",NUM_ITEMS(antenna_setmodes_3g),antenna_setmodes_3g,1,1},
+};
+
+em_arry_t antenna_c2kmode[] = {
+    {"getmode",0,NULL,1,1},
+    {"setmode",NUM_ITEMS(antenna_setmodes_c2k),antenna_setmodes_c2k,1,1},
+};
+
+em_arry_t antennatest[] = {
+    {"4G",NUM_ITEMS(antenna_4Gmode),antenna_4Gmode,1,1},
+    {"3G",NUM_ITEMS(antenna_3Gmode),antenna_3Gmode,1,1},
+    {"CDMA",NUM_ITEMS(antenna_c2kmode),antenna_c2kmode,1,1},
+};
+
+em_arry_t time_reg[] = {
+    { "disable", 0,NULL, 1, 1 },
+    { "enable", 0, NULL, 1, 1 },
+};
+
+em_arry_t c2k_modem_setting[] {
+        {"TIME REG",NUM_ITEMS(time_reg),time_reg,1,1},
+};
+
+em_arry_t rfdesense_setting[] = {
+    {"start",0,NULL,0,0},
+    {"set",0,NULL,0,0},
+//    {"set_check_Limit",0,NULL,0,0},
+//    {"get_check_Limit",0,NULL,0,0},
+};
+
+em_arry_t set_get[] = {
+        {"get",0,NULL,0,0},
+        {"set",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_gsm_band[] = {
+        {"GSM 850",0,NULL,0,0},
+        {"P-GSM 900",0,NULL,0,0},
+        {"E-GSM 900",0,NULL,0,0},
+        {"R-GSM 900",0,NULL,0,0},
+        {"DCS 1800",0,NULL,0,0},
+        {"PCS 1900",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_gsm_pattern[] = {
+        {"RFTOOL_NB_TX_RANDOM_WITH_TSC",0,NULL,0,0},
+        {"RFTOOL_NB_TX_ALL_ONES_WITHOUT_TSC",0,NULL,0,0},
+        {"RFTOOL_AB_TX_RANDOM_WITH_SYNC_SEQ",0,NULL,0,0},
+        {"RFTOOL_CONT_TX_ALL_ZEROS",0,NULL,0,0},
+        {"RFTOOL_CONT_TX_ALL_ONES",0,NULL,0,0},
+        {"RFTOOL_CONT_TX_ALTERNATE_BITS",0,NULL,0,0},
+        {"RFTOOL_CONT_TX_PSEUDO_RANDOM",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_gsm_sub[] = {
+        {"Band",NUM_ITEMS(rfdesense_gsm_band),rfdesense_gsm_band,0,0},
+        {"Channel(ARFCN)",NUM_ITEMS(set_get),set_get,0,0},
+        {"Power Level",NUM_ITEMS(set_get),set_get,0,0},
+        {"AFC",NUM_ITEMS(set_get),set_get,0,0},
+        {"TSC",NUM_ITEMS(set_get),set_get,0,0},
+        {"PATTERN",NUM_ITEMS(rfdesense_gsm_pattern),rfdesense_gsm_pattern,0,0},
+};
+
+em_arry_t rfdesense_gsm[] = {
+        {"start",0,NULL,0,0},
+        {"Parameters_set",NUM_ITEMS(rfdesense_gsm_sub),rfdesense_gsm_sub,0,0},
+        {"show default",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_tdscdma_band[] = {
+        {"Band A",0,NULL,0,0},
+        {"Band F",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_tdscdma_sub[] = {
+        {"Band",NUM_ITEMS(rfdesense_tdscdma_band),rfdesense_tdscdma_band,0,0},
+        {"Channel(ARFCN)",NUM_ITEMS(set_get),set_get,0,0},
+        {"Power Level(dBm)",NUM_ITEMS(set_get),set_get,0,0},
+};
+
+em_arry_t rfdesense_tdscdma[] = {
+        {"start",0,NULL,0,0},
+        {"Parameters_set",NUM_ITEMS(rfdesense_tdscdma_sub),rfdesense_tdscdma_sub,0,0},
+        {"show default",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_wcdma_band[] = {
+        {"Band 1",0,NULL,0,0},
+        {"Band 2",0,NULL,0,0},
+        {"Band 3",0,NULL,0,0},
+        {"Band 4",0,NULL,0,0},
+        {"Band 5",0,NULL,0,0},
+        {"Band 6",0,NULL,0,0},
+        {"Band 7",0,NULL,0,0},
+        {"Band 8",0,NULL,0,0},
+        {"Band 9",0,NULL,0,0},
+        {"Band 10",0,NULL,0,0},
+        {"Band 11",0,NULL,0,0},
+        {"Band 12",0,NULL,0,0},
+        {"Band 13",0,NULL,0,0},
+        {"Band 14",0,NULL,0,0},
+        {"Band 19",0,NULL,0,0},
+        {"Band 20",0,NULL,0,0},
+        {"Band 21",0,NULL,0,0},
+        {"Band 22",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_wcdma_sub[] = {
+        {"Band",NUM_ITEMS(rfdesense_wcdma_band),rfdesense_wcdma_band,0,0},
+        {"Channel(ARFCN)",NUM_ITEMS(set_get),set_get,0,0},
+        {"Power Level(dBm)",NUM_ITEMS(set_get),set_get,0,0},
+};
+
+em_arry_t rfdesense_wcdma[] {
+        {"start",0,NULL,0,0},
+        {"Parameters_set",NUM_ITEMS(rfdesense_wcdma_sub),rfdesense_wcdma_sub,0,0},
+        {"show default",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_lte_mode[] = {
+        {"single tone",0,NULL,0,0},
+        {"modulation signal",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_fdd_band[] = {
+        {"1",0,NULL,0,0},
+        {"2",0,NULL,0,0},
+        {"3",0,NULL,0,0},
+        {"4",0,NULL,0,0},
+        {"5",0,NULL,0,0},
+        {"6",0,NULL,0,0},
+        {"7",0,NULL,0,0},
+        {"8",0,NULL,0,0},
+        {"9",0,NULL,0,0},
+        {"10",0,NULL,0,0},
+        {"11",0,NULL,0,0},
+        {"12",0,NULL,0,0},
+        {"13",0,NULL,0,0},
+        {"14",0,NULL,0,0},
+        {"15",0,NULL,0,0},
+        {"16",0,NULL,0,0},
+        {"17",0,NULL,0,0},
+        {"18",0,NULL,0,0},
+        {"19",0,NULL,0,0},
+        {"20",0,NULL,0,0},
+        {"21",0,NULL,0,0},
+        {"22",0,NULL,0,0},
+        {"23",0,NULL,0,0},
+        {"24",0,NULL,0,0},
+        {"25",0,NULL,0,0},
+        {"26",0,NULL,0,0},
+        {"27",0,NULL,0,0},
+        {"28",0,NULL,0,0},
+        {"29",0,NULL,0,0},
+        {"30",0,NULL,0,0},
+        {"31",0,NULL,0,0},
+        {"66",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_lte_bandwidth[] = {
+        {"1.4M",0,NULL,0,0},
+        {"3M",0,NULL,0,0},
+        {"5M",0,NULL,0,0},
+        {"10M",0,NULL,0,0},
+        {"15M",0,NULL,0,0},
+        {"20M",0,NULL,0,0},
+};
+
+em_arry_t  rfdesense_lte_mcs[] = {
+        {"QPSK",0,NULL,0,0},
+        {"16QAM",0,NULL,0,0},
+        {"64QAM",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_fdd_sub[] = {
+        {"mode",NUM_ITEMS(rfdesense_lte_mode),rfdesense_lte_mode,0,0},
+        {"band",NUM_ITEMS(rfdesense_fdd_band),rfdesense_fdd_band,0,0},
+        {"UL Bandwidth",NUM_ITEMS(rfdesense_lte_bandwidth),rfdesense_lte_bandwidth,0,0},
+        {"UL Freq(100kHz)",NUM_ITEMS(set_get),set_get,0,0},
+        {"VRB Start(0-99)",NUM_ITEMS(set_get),set_get,0,0},
+        {"VRB Length(1-100)",NUM_ITEMS(set_get),set_get,0,0},
+        {"MCS",NUM_ITEMS(rfdesense_lte_mcs),rfdesense_lte_mcs,0,0},
+        {"Power Level(dbm)(-50_23)",NUM_ITEMS(set_get),set_get,0,0},
+};
+
+em_arry_t rfdesense_lte_fdd[] = {
+        {"start",0,NULL,0,0},
+        {"Parameters_set",NUM_ITEMS(rfdesense_fdd_sub),rfdesense_fdd_sub,0,0},
+        {"show default",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_tdd_band[] = {
+        {"33",0,NULL,0,0},
+        {"34",0,NULL,0,0},
+        {"35",0,NULL,0,0},
+        {"36",0,NULL,0,0},
+        {"37",0,NULL,0,0},
+        {"38",0,NULL,0,0},
+        {"39",0,NULL,0,0},
+        {"40",0,NULL,0,0},
+        {"41",0,NULL,0,0},
+        {"42",0,NULL,0,0},
+        {"43",0,NULL,0,0},
+        {"44",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_tdd_config[] = {
+        {"0",0,NULL,0,0},
+        {"1",0,NULL,0,0},
+        {"2",0,NULL,0,0},
+        {"3",0,NULL,0,0},
+        {"4",0,NULL,0,0},
+        {"5",0,NULL,0,0},
+        {"6",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_tdd_special[] = {
+        {"0",0,NULL,0,0},
+        {"1",0,NULL,0,0},
+        {"2",0,NULL,0,0},
+        {"3",0,NULL,0,0},
+        {"4",0,NULL,0,0},
+        {"5",0,NULL,0,0},
+        {"6",0,NULL,0,0},
+        {"7",0,NULL,0,0},
+        {"8",0,NULL,0,0},
+        {"9",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_tdd_sub[] = {
+        {"mode",NUM_ITEMS(rfdesense_lte_mode),rfdesense_lte_mode,0,0},
+        {"band",NUM_ITEMS(rfdesense_tdd_band),rfdesense_tdd_band,0,0},
+        {"UL Bandwidth",NUM_ITEMS(rfdesense_lte_bandwidth),rfdesense_lte_bandwidth,0,0},
+        {"UL Freq(100kHz)",NUM_ITEMS(set_get),set_get,0,0},
+        {"TDD Config Index",NUM_ITEMS(rfdesense_tdd_config),rfdesense_tdd_config,0,0},
+        {"TDD Special SF Config Index",NUM_ITEMS(rfdesense_tdd_special),rfdesense_tdd_special,0,0},
+        {"VRB Start(0-99)",NUM_ITEMS(set_get),set_get,0,0},
+        {"VRB Length(1-100)",NUM_ITEMS(set_get),set_get,0,0},
+        {"MCS",NUM_ITEMS(rfdesense_lte_mcs),rfdesense_lte_mcs,0,0},
+        {"Power Level(dbm)(-50_23)",NUM_ITEMS(set_get),set_get,0,0},
+};
+
+em_arry_t rfdesense_lte_tdd[] = {
+        {"start",0,NULL,0,0},
+        {"Parameters_set",NUM_ITEMS(rfdesense_tdd_sub),rfdesense_tdd_sub,0,0},
+        {"show default",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_cdma_band[] = {
+        {"Band 0",0,NULL,0,0},
+        {"Band 1",0,NULL,0,0},
+        {"Band 2",0,NULL,0,0},
+        {"Band 3",0,NULL,0,0},
+        {"Band 4",0,NULL,0,0},
+        {"Band 5",0,NULL,0,0},
+        {"Band 6",0,NULL,0,0},
+        {"Band 7",0,NULL,0,0},
+        {"Band 8",0,NULL,0,0},
+        {"Band 9",0,NULL,0,0},
+        {"Band 10",0,NULL,0,0},
+        {"Band 11",0,NULL,0,0},
+        {"Band 12",0,NULL,0,0},
+        {"Band 13",0,NULL,0,0},
+        {"Band 14",0,NULL,0,0},
+        {"Band 15",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_cdma_modulation[] = {
+        {"1X",0,NULL,0,0},
+        {"EVDO",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_cdma_sub[] = {
+        {"Band",NUM_ITEMS(rfdesense_cdma_band),rfdesense_cdma_band,0,0},
+        {"modulation",NUM_ITEMS(rfdesense_cdma_modulation),rfdesense_cdma_modulation,0,0},
+        {"Channel(ARFCN)",NUM_ITEMS(set_get),set_get,0,0},
+        {"Power Level(dBm)",NUM_ITEMS(set_get),set_get,0,0},
+};
+
+em_arry_t rfdesense_cdma[] = {
+        {"start",0,NULL,0,0},
+        {"Parameters_set",NUM_ITEMS(rfdesense_cdma_sub),rfdesense_cdma_sub,0,0},
+        {"show default",0,NULL,0,0},
+};
+
+em_arry_t sub_tx_test[] = {
+    { "GSM", NUM_ITEMS(rfdesense_gsm),rfdesense_gsm, 1, 1 },
+    { "TDSCDMA", NUM_ITEMS(rfdesense_tdscdma), rfdesense_tdscdma, 1, 1 },
+    { "WCDMA", NUM_ITEMS(rfdesense_wcdma), rfdesense_wcdma, 1, 1 },
+    { "LTE(FDD)", NUM_ITEMS(rfdesense_lte_fdd), rfdesense_lte_fdd, 1, 1 },
+    { "LTE(TDD)", NUM_ITEMS(rfdesense_lte_tdd), rfdesense_lte_tdd, 1, 1 },
+#ifdef C2K_SUPPORT
+    { "CDMA(EVDO)", NUM_ITEMS(rfdesense_cdma), rfdesense_cdma, 1, 1 },
+    { "CDMA(1x)", NUM_ITEMS(rfdesense_cdma), rfdesense_cdma, 1, 1 },
+#endif/*C2K_SUPPORT*/
+};
+
+em_arry_t desense_test[] {
+        {"Tx Test",NUM_ITEMS(sub_tx_test),sub_tx_test,1,1},
+};
+
+em_arry_t no_support[] {
+        {"NO SUPPORT",0,NULL,0,0},
+};
+
+em_arry_t emmain[] = {
+    {"CDMA modem setting",NUM_ITEMS(c2k_modem_setting),c2k_modem_setting,0,0},
+    {"RF Desense Test ",NUM_ITEMS(desense_test),desense_test,0,0},
+    {"Modem Test",NUM_ITEMS(modemtest),modemtest,0,0},
+    {"HSPA",NUM_ITEMS(hspa),hspa,0,0},
+    {"CFU",NUM_ITEMS(cfu),cfu,0,0},
+    {"Antenna Test",NUM_ITEMS(antennatest),antennatest,0,0},
+    {"Band Mode",NUM_ITEMS(bandmode),bandmode,0,0},
+    {"IMS",NUM_ITEMS(ims),ims,0,0},
+    //{"Network Info",NUM_ITEMS(networkinfo),networkinfo,0,0},
+    {"Network Info",NUM_ITEMS(no_support),no_support,0,0},
+    {"LTE",NUM_ITEMS(lte_info),lte_info,0,0},
+    //{"GPRS Attach",NUM_ITEMS(gprs),gprs,0,0}, // replace data allow script
+    //{"NetworkSelection",NUM_ITEMS(networkselection),networkselection,0,0}, // repplace with script
+};
+typedef enum {
+    C2K_MODEM_SETTING = 0,
+    RF_DESENSE_TEST,
+    MODEM_TEST_ITEM,
+    HSPA_ITEM,
+    CFU_ITEM,
+    ANTENNATEST_ITEM,
+    BANDMODE_ITEM,
+    IMS_ITEM,
+    NO_SUPPORT,
+    //NETWORKINFO_ITEM,
+    LTE_ITEM,
+}EM_MAIN_ITEM;
+em_arry_t em = {"Telephony",NUM_ITEMS(emmain),emmain,0,0};
+int em_main(int len, int *item, int multilen, char *value[]) {
+    int testclass = item[0];
+    RLOGD("em_main testclase %d", testclass);
+    switch (testclass) {
+    case C2K_MODEM_SETTING:
+        emC2kModemSettingStart(len - 1, multilen, &item[1]);
+        break;
+    case RF_DESENSE_TEST:
+        emRfDesenseStart(len - 1, &item[1], multilen, value);
+        break;
+    case MODEM_TEST_ITEM:
+        emModemtestStart(len - 1, multilen, &item[1]);
+        break;
+    case HSPA_ITEM:
+        emHspaStart(len - 1, &item[1]);
+        break;
+    case CFU_ITEM:
+        emCfuStart(len - 1, &item[1]);
+        break;
+    case ANTENNATEST_ITEM:
+        emAntennaTestStart(len - 1, &item[1],(value != NULL ? value[0] : NULL));
+        break;
+    case BANDMODE_ITEM:
+        emBandmodeStart(len - 1, &item[1], multilen, value);
+        break;
+    case IMS_ITEM:
+        emImsStart(len - 1, &item[1], (value != NULL ? value[0] : NULL));
+        break;
+//    case NETWORKINFO_ITEM:
+//        emNwInfoStart(len - 1, multilen, &item[1]);
+//        break;
+    case LTE_ITEM:
+        //lte_em_start(len - 1, multilen, &item[1]);
+        em_el1_start(len - 1, multilen, &item[1]);
+        break;
+    case NO_SUPPORT:
+        android::emResultNotify("don't support\n");
+        break;
+    default:
+        break;
+    }
+    return 0;
+}
+
+int em_start(int argc, char *argv[], RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    RLOGD("em_start called");
+    int i = 0;
+    em_arry_t *em_test = &em;
+    em_arry_t *em_sub = NULL;
+    RLOGD("Welcome to EM %s",em_test->name);
+    char output[2048] = {0};
+    int len = 0;
+
+    if(argc < 2){
+        for(i = 0; i < em_test->subcnt; i++){
+            sprintf(output+len,"%d:%s\n",i+1,em_test->subarray[i].name);
+            len = strlen(output);
+        }
+        RLOGD("%s",output);
+        android::emResultNotify(output);
+        return 0;
+    }
+    int itemlevel = 0;
+    int select_argvi[32] = {0};
+    int current_argvi = -1;
+    for(itemlevel = 1; itemlevel < argc; itemlevel++){
+        select_argvi[itemlevel-1] = atoi(argv[itemlevel]) - 1;
+        current_argvi = select_argvi[itemlevel-1];
+        if (em_test->subcnt < current_argvi + 1) {
+            sprintf(output, "the select index %d is out of bounds, please reselect.\nfail\n",current_argvi + 1);
+            android::emResultNotify(output);
+            return -1;
+        }
+        if(em_test->subarray[current_argvi].subarray == NULL){
+            for(i = 0 ; i < (argc - itemlevel - 1); i++){
+                select_argvi[itemlevel + i] = atoi(argv[itemlevel+1+i]) - 1;
+            }
+            RLOGD("em_test->subarray[%d].name: %s",current_argvi, em_test->subarray[current_argvi].name);
+            if(strncmp(em_test->subarray[current_argvi].name,"set",3) == 0){
+                em_main(itemlevel,&select_argvi[0],(argc - itemlevel - 1),&argv[itemlevel+1]);
+            }
+            else{
+                RLOGD("item level %d",itemlevel);
+                em_main(itemlevel,&select_argvi[0],(argc - itemlevel - 1),NULL);
+            }
+            //android::emResultNotify("done\n");
+            break;
+        }else{
+            RLOGD("em_sub[%d].name: %s, itemlevel: %d, argc: %d ",current_argvi, (em_test->subarray[current_argvi].name), itemlevel, argc);
+            em_sub = &em_test->subarray[current_argvi];
+            if(itemlevel == (argc - 1)){
+                memset(output,0,2048);
+                len = 0;
+
+                for(i = 0; i < em_sub->subcnt; i++){
+                    //RLOGD("%d:%s",i+1,em_sub->subarray[i].name);
+                    sprintf(output+len,"%d:%s\n",i+1,em_sub->subarray[i].name);
+                    len = strlen(output);
+                }
+                RLOGD("%s",output);
+                android::emResultNotify(output);
+            }
+            em_test = em_sub;
+        }
+    }
+    return 0;
+}
+
+extern void ARspRequestWithArg(int request, const char* arg, RIL_SOCKET_ID soc_id);
+
+void emSendATCommand(const char *cmd, int soc_id)
+{
+    ARspRequestWithArg(RIL_REQUEST_OEM_HOOK_RAW, cmd, (RIL_SOCKET_ID)soc_id);
+}
+
+void emEnableRadio(bool isEnable, int soc_id) {
+    //check main phone
+    ARspRequestWithArg(RIL_REQUEST_RADIO_POWER, (isEnable ? "1" : "0"), (RIL_SOCKET_ID)soc_id);
+}
+
+std::vector<std::string> getCdmaCmdArr(std::vector<std::string> cmdArray) {
+#ifndef MD_93_SUPPORT
+    return cmdArray;
+#else
+    std::vector<std::string> cmdArrayNew(2);
+    cmdArrayNew[0] = cmdArray[0];
+    cmdArrayNew[1] = cmdArray[1];
+    return cmdArrayNew;
+#endif /*MD_93_SUPPORT*/
+}
+
+int emResultNotifyWithDone(std::string str) {
+    std::string tmp = str + std::string("\ndone\n");
+    android::emResultNotify(tmp.c_str());
+    return 0;
+}
+
+int emResultNotifyEx(std::string str) {
+    std::string tmp = str + std::string("\n");
+    android::emResultNotify(tmp.c_str());
+    return 0;
+}
+
+int em_result_only_msg(std::string str) {
+    std::string tmp = str + std::string("\nonly_em_message\n");
+    android::emResultNotify(tmp.c_str());
+    return 0;
+}
+
+int em_result_notify_fail(std::string str) {
+    std::string tmp = "fail, " + str;
+    emResultNotifyWithDone(tmp);
+    return 0;
+}
+
+int em_result_notify_ok(std::string str) {
+    std::string tmp = "OK, " + str;
+    emResultNotifyWithDone(tmp);
+    return 0;
+}
+
+int em_result_notify_error(std::string str) {
+    std::string tmp = "error, " + str;
+    emResultNotifyWithDone(tmp);
+    return 0;
+}
+#endif
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em.h
new file mode 100644
index 0000000..44e3e13
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em.h
@@ -0,0 +1,149 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#ifndef __RIL_EM_API__
+#define __RIL_EM_API__
+
+#include  <vendor-ril/telephony/ril.h>
+#include <string>
+#include <vector>
+
+#include  "common.h"
+
+typedef struct em_arry_{
+    char *name;  /* main test name. */
+    int subcnt;
+    struct em_arry_ *subarray; 	  /* Function to call to do the job. */
+    int unsol;
+    int reply;
+} em_arry_t;
+extern em_arry_t lte_info[];
+extern em_arry_t ims_setting[];
+extern em_arry_t ims_common[];
+extern em_arry_t ims_call[] ;
+extern em_arry_t ims_registration[];
+extern em_arry_t ims[];
+extern em_arry_t gprs[];
+extern em_arry_t networkselection[];
+extern em_arry_t modem_cta[];
+extern em_arry_t modem_fta[];
+extern em_arry_t modem_C2K_Test_MODEM[];
+extern em_arry_t modemtest[];
+extern em_arry_t hspa[];
+extern em_arry_t cfu[];
+extern em_arry_t bandmode[];
+extern em_arry_t networkinfo[];
+extern em_arry_t antenna_4Gmode[];
+extern em_arry_t antenna_3Gmode[];
+extern em_arry_t antennatest[];
+extern em_arry_t time_reg[];
+extern em_arry_t c2k_modem_setting[];
+extern em_arry_t set_get[];
+extern em_arry_t rfdesense_gsm_band[];
+extern em_arry_t rfdesense_gsm_pattern[];
+extern em_arry_t rfdesense_gsm_sub[];
+extern em_arry_t rfdesense_gsm[];
+extern em_arry_t rfdesense_tdscdma_band[];
+extern em_arry_t rfdesense_tdscdma_sub[];
+extern em_arry_t rfdesense_tdscdma[];
+extern em_arry_t rfdesense_wcdma_band[];
+extern em_arry_t rfdesense_wcdma_sub[];
+extern em_arry_t rfdesense_wcdma[];
+extern em_arry_t rfdesense_lte_mode[];
+extern em_arry_t rfdesense_fdd_band[] ;
+extern em_arry_t rfdesense_lte_bandwidth[];
+extern em_arry_t  rfdesense_lte_mcs[];
+extern em_arry_t rfdesense_fdd_sub[];
+extern em_arry_t rfdesense_lte_fdd[];
+extern em_arry_t rfdesense_tdd_band[];
+extern em_arry_t rfdesense_tdd_config[];
+extern em_arry_t rfdesense_tdd_special[];
+extern em_arry_t rfdesense_tdd_sub[];
+extern em_arry_t rfdesense_lte_tdd[];
+extern em_arry_t rfdesense_cdma_band[];
+extern em_arry_t rfdesense_cdma_modulation[];
+extern em_arry_t rfdesense_cdma_sub[];
+extern em_arry_t rfdesense_cdma[];
+extern em_arry_t sub_tx_test[];
+extern em_arry_t desense_test[];
+extern em_arry_t emmain[];
+
+#define RET_STRING_IMS_SUCCESS "IMS test success\ndone\n"
+#define RET_STRING_IMS_FAIL "IMS test fail\ndone\n"
+#define RET_STRING_GPRS_SUCCESS "GPRS test success\ndone\n"
+#define RET_STRING_GPRS_FAIL "GPRS test fail\ndone\n"
+#define RET_STRING_NWSELECTION_SUCCESS "Network Selection success\ndone\n"
+#define RET_STRING_NWSELECTION_FAIL "Network Selection fail\ndone\n"
+#define RET_STRING_MODEMTEST_SUCCESS "Modem test success\ndone\n"
+#define RET_STRING_MODEMTEST_FAIL "Modem test fail\ndone\n"
+#define RET_STRING_HSPA_SUCCESS "HSPA test success\ndone\n"
+#define RET_STRING_HSPA_FAIL "HSPA test fail\ndone\n"
+#define RET_STRING_LTE_SUCCESS "LTE success\ndone\n"
+#define RET_STRING_LTE_FAIL "LTE fail\ndone\n"
+#define RET_STRING_CFU_SUCCESS "CFU success\ndone\n"
+#define RET_STRING_CFU_FAIL "CFU fail\ndone\n"
+#define RET_STRING_BANDMODE_SUCCESS "Bandmode success\ndone\n"
+#define RET_STRING_BANDMODE_FAIL "Bandmode fail\ndone\n"
+#define RET_STRING_NWINFO_SUCCESS "NetworkInfo success\ndone\n"
+#define RET_STRING_NWINFO_FAIL "NetworkInfo fail\ndone\n"
+#define RET_STRING_ANTENNATEST_SUCCESS "Antenna test success\ndone\n"
+#define RET_STRING_ANTENNATEST_FAIL "Antenna test fail\ndone\n"
+#define RET_STRING_C2K_MODEM_SETTING_SUCCESS "c2k modem setting success\ndone\n";
+#define RET_STRING_C2K_MODEM_SETTING_FAIL "c2k modem setting fail\ndone\n";
+
+int emImsStart(int argc, int *item,char *value);
+int emGprsStart(int argc, int *item,char *value);
+int emNetworkSelectionStart(int argc,int selectpos);
+int emModemtestStart(int argc, int multicnt,int *item);
+int emHspaStart(int argc, int *item);
+int lte_em_start(int argc, int multicnt,int *item);
+int em_el1_start(int argc, int multicnt,int *item);
+int emCfuStart(int argc, int *item);
+int emBandmodeStart(int len,int *item,int multilen,char *value[]);
+int emNwInfoStart(int argc, int multicnt,int *item);
+int emAntennaTestStart(int argc, int *item,char *value);
+int emC2kModemSettingStart(int argc, int multicnt,int *item);
+int emRfDesenseStart(int len,int *item,int multilen,char *value[]);
+
+std::vector<std::string> getCdmaCmdArr(std::vector<std::string> cmdArray);
+int em_result_notify_fail(std::string str);
+int em_result_notify_ok(std::string str);
+int em_result_notify_error(std::string str);
+int emResultNotifyWithDone(std::string str);
+int emResultNotifyEx(std::string str);
+int em_result_only_msg(std::string str);
+void emSendATCommand(const char *cmd, int soc_id);
+void emEnableRadio(bool isEnable, int soc_id);
+int em_start(int argc, char *argv[], RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+#endif
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_EL1.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_EL1.cpp
new file mode 100644
index 0000000..73e8a1a
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_EL1.cpp
@@ -0,0 +1,198 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include <vendor-ril/telephony/ril.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <cutils/jstring.h>
+#include <log/log.h>
+#include <unistd.h>
+#include <math.h>
+#include "em/em_el1_public_struct.h"
+#include  "common.h"
+#include "em/em.h"
+#include "Radio_capability_switch_util.h"
+
+#if EM_MODE_SUPPORT
+
+#undef LOG_TAG
+#define LOG_TAG "EM_EL1"
+
+static int mItemCount = 0;
+static int mFlag = 0;// at cmd flag
+static int mCurrentFlag = 0; // at cmd handle flag
+
+static const int MSG_NW_INFO = 1;
+static const int MSG_NW_INFO_OPEN = 4;
+static const int MSG_NW_INFO_CLOSE = 5;
+
+static void sendATCommand(const char *cmd,int msg)
+{
+    mCurrentFlag = msg;
+    emSendATCommand(cmd, get_default_sim_all_except_data());
+    return ;
+}
+
+static char hex2char(unsigned int hex) {
+    if (hex >= '0' && hex <= '9') {
+        return hex - '0';
+    }
+    if (hex >= 'A' && hex <= 'F') {
+        return 0xA + hex - 'A';
+    }
+    if (hex >= 'a' && hex <= 'f') {
+        return 0xA + hex - 'a';
+    }
+    return 0;
+}
+
+static void hex2char(char *input, int input_len, char *buf, int buf_size) {
+    RLOGD("hex2char, input_len: %d, buf_size: %d", input_len, buf_size);
+    memset(buf, 0, buf_size);
+    //respose data lack of 8 byte, corresponding to header
+    //ref_count(1)+lp_reserved(1)+ msg_len(2) + em_info(4)
+    if (input_len < (buf_size-8) * 2) { // should not happen
+        buf_size = input_len / 2;
+    }
+    for (int i = 0; i < buf_size; i++) {
+        buf[i+8] = (hex2char(input[i * 2]) << 4) + hex2char(input[i * 2 + 1]);
+    }
+
+}
+
+static void el1_at_cmd_handle(char*response, int responselen) {
+    switch (mCurrentFlag) {
+        case MSG_NW_INFO:
+            if ((responselen > 0) && (response != NULL)) {
+                RLOGD("el1_at_cmd_handle response %s\n",response);
+                //mFlag = FLAG_OFFSET_BIT;
+            }
+            else {
+                RLOGD("send fail ");
+            }
+            break;
+        case MSG_NW_INFO_OPEN:
+        case MSG_NW_INFO_CLOSE:
+            break;
+        default:
+            break;
+    }
+}
+
+static void el1_parse(char *output,char * input){
+    em_el1_status_ind_struct buf;
+    hex2char(input, strlen(input), (char *)&buf, sizeof(em_el1_status_ind_struct));
+    snprintf(output, 8192,
+            "[Cell Info]\n"
+            "  band: %u,%u,%u,%u\n"
+            "  DL_BW: %u,%u,%u,%u\n"
+            "  UL_BW: %u,%u,%u,%u\n"
+            "  TM: %u,%u,%u,%u\n"
+            "  PCI: %d,%d,%d,%d\n"
+            "  EARFCN: %u,%u,%u,%u\n"
+            "[DL]\n"
+            "  dl_rssi: (%d,%d),(%d,%d),(%d,%d),(%d,%d)\n"
+            "  dl_rsrp: (%d,%d),(%d,%d),(%d,%d),(%d,%d)\n"
+            "  dl_rsrq: (%d,%d),(%d,%d),(%d,%d),(%d,%d)\n"
+            "  dl_sinr: (%d,%d),(%d,%d),(%d,%d),(%d,%d)\n"
+            "  rsrp: %d,%d,%d,%d\n"
+            "  rsrq: %d,%d,%d,%d\n"
+            "  sinr: %d,%d,%d,%d\n"
+            "  rsSNR: %d,%d,%d,%d\n"
+            "  tm: %d,%d,%d,%d\n"
+            "  rsrp_l1_rxpath_sum_dBm: %d,%d,%d,%d\n"
+            "  rsrq_l1_rxpath_sum_dB: %d,%d,%d,%d\n"
+            "  snr_l1_rxpath_sum_dB: %d,%d,%d,%d\n",
+        buf.cell_info[0].band, buf.cell_info[1].band,buf.cell_info[2].band,buf.cell_info[3].band,
+        buf.cell_info[0].dl_bw, buf.cell_info[1].dl_bw,buf.cell_info[2].dl_bw,buf.cell_info[3].dl_bw,
+        buf.cell_info[0].ul_bw, buf.cell_info[1].ul_bw,buf.cell_info[2].ul_bw,buf.cell_info[3].ul_bw,
+        buf.cell_info[0].tm, buf.cell_info[1].tm,buf.cell_info[2].tm,buf.cell_info[3].tm,
+        buf.cell_info[0].pci, buf.cell_info[1].pci,buf.cell_info[2].pci,buf.cell_info[3].pci,
+        buf.cell_info[0].earfcn, buf.cell_info[1].earfcn,buf.cell_info[2].earfcn,buf.cell_info[3].earfcn,
+        buf.dl_info[0].dl_rssi[0],buf.dl_info[0].dl_rssi[1],buf.dl_info[1].dl_rssi[0],buf.dl_info[1].dl_rssi[1],
+        buf.dl_info[2].dl_rssi[0],buf.dl_info[2].dl_rssi[1],buf.dl_info[3].dl_rssi[0],buf.dl_info[3].dl_rssi[1],
+        buf.dl_info[0].dl_rsrp[0],buf.dl_info[0].dl_rsrp[1],buf.dl_info[1].dl_rsrp[0],buf.dl_info[1].dl_rsrp[1],
+        buf.dl_info[2].dl_rsrp[0],buf.dl_info[2].dl_rsrp[1],buf.dl_info[3].dl_rsrp[0],buf.dl_info[3].dl_rsrp[1],
+        buf.dl_info[0].dl_rsrq[0],buf.dl_info[0].dl_rsrq[1],buf.dl_info[1].dl_rsrq[0],buf.dl_info[1].dl_rsrq[1],
+        buf.dl_info[2].dl_rsrq[0],buf.dl_info[2].dl_rsrq[1],buf.dl_info[3].dl_rsrq[0],buf.dl_info[3].dl_rsrq[1],
+        buf.dl_info[0].dl_sinr[0],buf.dl_info[0].dl_sinr[1],buf.dl_info[1].dl_sinr[0],buf.dl_info[1].dl_sinr[1],
+        buf.dl_info[2].dl_sinr[0],buf.dl_info[2].dl_sinr[1],buf.dl_info[3].dl_sinr[0],buf.dl_info[3].dl_sinr[1],
+        buf.dl_info[0].rsrp, buf.dl_info[1].rsrp, buf.dl_info[2].rsrp, buf.dl_info[3].rsrp,
+        buf.dl_info[0].rsrq, buf.dl_info[1].rsrq, buf.dl_info[2].rsrq, buf.dl_info[3].rsrq,
+        buf.dl_info[0].sinr, buf.dl_info[1].sinr, buf.dl_info[2].sinr, buf.dl_info[3].sinr,
+        buf.dl_info[0].rsSNR, buf.dl_info[1].rsSNR, buf.dl_info[2].rsSNR, buf.dl_info[3].rsSNR,
+        buf.dl_info[0].tm, buf.dl_info[1].tm, buf.dl_info[2].tm, buf.dl_info[3].tm,
+        buf.dl_info[0].rsrp_l1_rxpath_sum_dBm, buf.dl_info[1].rsrp_l1_rxpath_sum_dBm, buf.dl_info[2].rsrp_l1_rxpath_sum_dBm, buf.dl_info[3].rsrp_l1_rxpath_sum_dBm,
+        buf.dl_info[0].rsrq_l1_rxpath_sum_dB, buf.dl_info[1].rsrq_l1_rxpath_sum_dB, buf.dl_info[2].rsrq_l1_rxpath_sum_dB, buf.dl_info[3].rsrq_l1_rxpath_sum_dB,
+        buf.dl_info[0].snr_l1_rxpath_sum_dB, buf.dl_info[1].snr_l1_rxpath_sum_dB, buf.dl_info[2].snr_l1_rxpath_sum_dB, buf.dl_info[3].snr_l1_rxpath_sum_dB
+        );
+}
+
+static void  el1_urc_handle(int type, char *data){
+    RLOGD("el1_urc_handle type %d data %s\n",type,data);
+    if(type == EM_EL1_INFO) {
+        char outbuf[8192] = {0};
+        el1_parse(outbuf,data);
+        android::emResultNotify(outbuf);
+        android::emResultNotify(RET_STRING_LTE_SUCCESS);
+        android::unregisterNetwork();
+        char atcommand[32] = {0};
+        sprintf(atcommand,"AT+EINFO=%d,%d,1",mFlag,EM_EL1_INFO);
+        sendATCommand(atcommand, MSG_NW_INFO_CLOSE);
+    }
+}
+
+int em_el1_start(int argc, int multicnt,int *item)
+{
+    RLOGD("em_el1_start called");
+    if(argc < 1)
+    {
+        RLOGD("em_el1_start: please select page to show info");
+        android::emResultNotify(RET_STRING_LTE_FAIL);
+        return -1;
+    }
+    mItemCount = multicnt + 1;
+    RLOGD("mItemCount: %d, item[%d]: %d", mItemCount, multicnt, item[multicnt]);
+    android::registerForNetworkInfo(el1_urc_handle);
+    android::registerForATcmdResponse(el1_at_cmd_handle);
+    //sendATCommand("AT+EINFO?",MSG_NW_INFO);
+    mFlag = 8;
+    char atcommand[32] = {0};
+    sprintf(atcommand,"AT+EINFO=%d,%d,0",mFlag,EM_EL1_INFO);
+    sendATCommand(atcommand, MSG_NW_INFO_OPEN);
+    return (0);
+}
+#endif
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_antennatest.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_antennatest.cpp
new file mode 100644
index 0000000..87c8380
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_antennatest.cpp
@@ -0,0 +1,355 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include <vendor-ril/telephony/ril.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <cutils/jstring.h>
+#include <log/log.h>
+#include <unistd.h>
+#include <math.h>
+#include <vector>
+#include <string>
+#include <stdexcept>
+#include  "common.h"
+#include "em/em.h"
+#include "ModemCategory.h"
+#include "Radio_capability_switch_util.h"
+#include "../util/utils.h"
+
+#if EM_MODE_SUPPORT
+
+#undef LOG_TAG
+#define LOG_TAG "EM_ANTENNA"
+
+static const int MSG_QUERY_ANTENNA_MODE = 1;
+static const int MSG_SET_ANTENNA_MODE = 2;
+static const int MSG_QUERY_ANTENNA_MODE_C2K = 4;
+static const int MSG_QUERY_ANTENNA_EGMC_4G = 5;
+static const int MSG_SET_ANTENNA_EGMC_4G = 6;
+static const int MSG_INIT_ANTENNA_EGMC_4G = 7;
+static const int MODE_INDEX_BASE_3G = 10;
+static const int MODE_EPCM_VALID = 0xFF;
+static const int CELL_2RX_LENGTH = 2;
+static const int CELL_4RX_LENGTH = 4;
+
+int mCurrentEmantennaFlag = 0;
+bool fgAntennaRead = true;
+static int fgget = -1;
+static int fgset = -1;
+int mAntennaMode = 0;
+char antennaretstring[128] = {0};
+
+static const std::vector<std::string> antenna_modes_4g {
+    "RX1&RX2",
+    "RX1",
+    "RX2"
+};
+
+static const std::vector<std::string> antenna_modes_3g {
+    "Please select a mode:",
+    "RX1",
+    "RX2",
+    "RX1&RX2",
+    "Resume default setting"
+};
+
+static const std::vector<std::string> antenna_modes_c2k_mode {
+    "Resume default setting",
+    "RX1",
+    "RX2",
+    "RX1&RX2"
+};
+
+static void  sendATCommand(const char *cmd,int msg)
+{
+    mCurrentEmantennaFlag = msg;
+    emSendATCommand(cmd, Radio_capability_switch_util::get_main_capability_phone_id());
+    return ;
+}
+static void queryCurrentMode() {
+    char cmd_str[32] = {0};
+    sprintf(cmd_str,"%s","AT+ERXPATH?");
+    sendATCommand(cmd_str, MSG_QUERY_ANTENNA_MODE);
+}
+
+void queryCurrentCdmaMode() {
+    if (utils::is93Modem()) {
+        sendATCommand("AT+ERXTESTMODE?", MSG_QUERY_ANTENNA_MODE_C2K);
+    } else {
+        android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
+        RLOGD("don't support");
+    }
+}
+
+static void setMode(int mode) {
+    char cmd_str[32] = {0};
+    sprintf(cmd_str,"%s%d","AT+ERXPATH=",mode);
+    sendATCommand(cmd_str, MSG_SET_ANTENNA_MODE);
+}
+
+static void setCdmaMode(int mode) {
+    std::string str("AT+ERXTESTMODE=");
+    str.append(std::to_string(mode));
+    if (utils::is93Modem()) {
+        sendATCommand(str.c_str(), MSG_SET_ANTENNA_MODE);
+    } else {
+        android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
+        RLOGD("don't support");
+    }
+}
+
+static void parseCurrentMode(char* data) {
+    RLOGD("parseCurrentMode(%d):%s",fgget, data);
+    std::vector<std::string> out;
+    utils::tokenize(string(data), "\n", out);
+    std::string str;
+    str.clear();
+    if(fgget == 0 || fgget == 1) {
+        for(auto i: out) {
+            if(i.find("+ERXPATH:") != std::string::npos) {
+                try {
+                    int mode = std::stoi(i.substr(std::string("+ERXPATH:").size()));
+                    if (mode < 0 || (mode >= antenna_modes_4g.size()
+                            && mode >= MODE_INDEX_BASE_3G + mode >= antenna_modes_4g.size()
+                            &&  mode != MODE_EPCM_VALID)) {
+                        android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
+                        RLOGD("Modem returned invalid mode(%d): %s",mode, data);
+                        return ;
+                    } else {
+                        if (mode == MODE_EPCM_VALID) {
+                            android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
+                        } else if (mode >= MODE_INDEX_BASE_3G) {
+                            if(ModemCategory::getModemType() != ModemCategory::MODEM_TD) {
+                                int pos = mode - MODE_INDEX_BASE_3G + 1;
+                                RLOGD("parseCurrent3GMode is: %d", pos);
+                                str.append("3G:");
+                                str.append(antenna_modes_3g[pos]);
+                                str.append(" ");
+                            }
+                        } else {
+                            if (ModemCategory::isLteSupport()) {
+                                RLOGD("parseCurrentLteMode is: %d", mode);
+                                str.append("4G:");
+                                str.append(antenna_modes_4g[mode]);
+                                str.append(" ");
+                            }
+                        }
+                    }
+                    str.append("\ndone\n");
+                } catch (const out_of_range &e) {
+                    android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
+                    RLOGD("out of range: %s", e.what());
+                    return;
+                } catch (const invalid_argument &e) {
+                    android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
+                    RLOGD("invalid argument: %s", e.what());
+                    return;
+                }
+            }
+        }
+        android::emResultNotify(str.c_str());
+    } else if (fgget == 2) {
+        for(auto i: out) {
+            if(i.find("+ERXTESTMODE:") != std::string::npos) {
+                try {
+                    int mode = std::stoi(i.substr(std::string("+ERXTESTMODE:").size()));
+                    if (mode < 0 || mode >= antenna_modes_c2k_mode.size()) {
+                        android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
+                        RLOGD("Modem returned invalid mode(%d): %s",mode, data);
+                        return;
+                    } else {
+                        RLOGD("parseCurrentC2KMode is: %d", mode);
+                        str.append("CDMA:");
+                        str.append(antenna_modes_c2k_mode[mode]);
+                        str.append(" ");
+                    }
+                    str.append("\ndone\n");
+                } catch (const out_of_range &e) {
+                    android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
+                    RLOGD("out of range: %s", e.what());
+                    return;
+                } catch (const invalid_argument &e) {
+                    android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
+                    RLOGD("invalid argument: %s", e.what());
+                    return;
+                }
+            }
+        }
+        android::emResultNotify(str.c_str());
+    } else {
+        RLOGE("error choose!!!");
+        android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
+    }
+    return;
+}
+
+
+static void emAntennaAtCmdHandle(char*response, int responselen) {
+    switch (mCurrentEmantennaFlag) {
+    case MSG_QUERY_ANTENNA_MODE:
+    case MSG_QUERY_ANTENNA_MODE_C2K:
+        //parse antenna mode.
+        if ((responselen > 0) && (response != NULL)) {
+            RLOGD("Get mode %s", response);
+            parseCurrentMode(response);
+        } else {
+            RLOGD("Query antenna mode failed.");
+            sprintf(antennaretstring, "%s%s", ("Query antenna mode failed."),
+            RET_STRING_ANTENNATEST_FAIL);
+            android::emResultNotify(antennaretstring);
+        }
+        android::unregisterNetwork();
+        break;
+    case MSG_SET_ANTENNA_MODE:
+        memset(antennaretstring, 0, sizeof(antennaretstring));
+        if ((responselen > 0) && (response != NULL)) {
+            RLOGD("Set successful.");
+            sprintf(antennaretstring, "%s\n%s", ("Set successful."),
+                    RET_STRING_ANTENNATEST_SUCCESS);
+        } else {
+            RLOGD("Set failed.");
+            sprintf(antennaretstring, "%s\n%s", ("Set failed."),
+                    RET_STRING_ANTENNATEST_FAIL);
+        }
+        android::unregisterNetwork();
+        android::emResultNotify(antennaretstring);
+        break;
+    default:
+        RLOGD("error(%d)", mCurrentEmantennaFlag);
+        break;
+    }
+}
+
+
+//create thread to send command
+static void * emAntennaTestThread(void* arg)
+{
+    if(fgAntennaRead){
+        if(fgget == 0) { //4G
+            if (ModemCategory::isLteSupport()) {
+                queryCurrentMode();
+            } else {
+                android::emResultNotify("Antenna test don't support for 4G \ndone\n");
+            }
+        } else if (fgget == 1){ //3G
+            if (ModemCategory::getModemType() == ModemCategory::MODEM_TD) {
+                android::emResultNotify("Antenna test don't support for 3G \ndone\n");
+            } else {
+                queryCurrentMode();
+            }
+        } else if (fgget == 2) { //C2K
+            if(ModemCategory::isCdma()) {
+                queryCurrentCdmaMode();
+            } else {
+                android::emResultNotify("Antenna test don't support for C2K \ndone\n");
+            }
+        } else {
+            android::emResultNotify("Antenna test index error \ndone\n");
+        }
+
+    }else{
+        if(fgset == 0) { //4G
+            if (ModemCategory::isLteSupport()) {
+                setMode(mAntennaMode);
+            } else {
+                android::emResultNotify("Antenna test don't support for 4G \ndone\n");
+            }
+        } else if (fgset == 1){ //3G
+            if (ModemCategory::getModemType() == ModemCategory::MODEM_TD) {
+                android::emResultNotify("Antenna test don't support for 3G \ndone\n");
+            } else {
+                setMode(mAntennaMode);
+            }
+        } else if (fgset == 2) { //C2K
+            if(ModemCategory::isCdma()) {
+                setCdmaMode(mAntennaMode);
+            } else {
+                android::emResultNotify("Antenna test don't support for C2K \ndone\n");
+            }
+        } else {
+            android::emResultNotify("Antenna test index error \ndone\n");
+        }
+    }
+    pthread_exit(0);
+}
+
+int emAntennaTestStart(int argc, int *item,char *value)
+{
+    RLOGD("emAntennaTestStart called");
+    if(argc < 2){
+        RLOGD("please select AntennaTest get or set :");
+        return -1;
+    }
+    mCurrentEmantennaFlag = 0;
+    int classid = item[0];
+    int operatorid = item[1];
+    if((item[0] != 0 ) && (item[0] != 1) && (item[0] != 2)){ // 0 4G 1 3G
+        RLOGD("emAntennaTestStart: invalid parameter %d, operatorid: %d",item[0], operatorid);
+        android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
+        return -1;
+    }
+    switch(operatorid){
+        case 0://get
+        {
+            fgAntennaRead = true;
+            fgget = classid;
+            break;
+        }
+        case 1://set
+        {
+            printf("argc: %d, fgset: %d\n", argc, classid);
+            printf("itme[2]: %d\n", item[2]);
+            fgset = classid;
+            if(classid == 0){ // 4G
+               mAntennaMode = item[2];
+            } else if(classid == 1) { //3G
+                mAntennaMode = item[2]+ MODE_INDEX_BASE_3G;
+            } else if (classid == 2) { //C2K
+                mAntennaMode = item[2];
+            } else { // other
+                RLOGW("error classid");
+                android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
+            }
+            fgAntennaRead = false;
+            break;
+        }
+    }
+    android::registerForATcmdResponse(emAntennaAtCmdHandle);
+    pthread_t emantenna_thread;
+    pthread_create(&emantenna_thread,NULL, emAntennaTestThread, NULL);
+    return (0);
+}
+#endif
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_bandmode.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_bandmode.cpp
new file mode 100644
index 0000000..8b33c18
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_bandmode.cpp
@@ -0,0 +1,833 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include <pthread.h>
+#include <vendor-ril/telephony/ril.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <cutils/jstring.h>
+#include <log/log.h>
+#include <unistd.h>
+#include <math.h>
+#include <string>
+#include <vector>
+#include <stdint.h>
+#include "ModemCategory.h"
+#include  "common.h"
+#include "em/em.h"
+#include "Radio_capability_switch_util.h"
+#include "../util/utils.h"
+#include "MtkRadioAccessFamily.h"
+
+#if EM_MODE_SUPPORT
+
+#undef LOG_TAG
+#define LOG_TAG "EM_BANDMODE"
+
+static const int WCDMA = 1;
+static const int TDSCDMA = 2;
+
+static const int INDEX_GSM_BAND = 0;
+static const int INDEX_UMTS_BAND = 1;
+static const int INDEX_LTE_FDD_BAND = 2;
+static const int INDEX_LTE_TDD_BAND = 3;
+static const int INDEX_LTE_BAND_96 = 4;
+static const int INDEX_LTE_BAND_128 = 5;
+static const int INDEX_LTE_BAND_160 = 6;
+static const int INDEX_LTE_BAND_192 = 7;
+static const int INDEX_LTE_BAND_224 = 8;
+static const int INDEX_LTE_BAND_256 = 9;
+static const int INDEX_CDMA_BAND = 10;
+static const int INDEX_BAND_MAX = 11;
+static const int BAND_SET_INVALID = 1000;
+static int mSimType = -1;
+
+/** GSM mode bit. */
+static const int GSM_EGSM900_BIT = 1;
+static const int GSM_DCS1800_BIT = 3;
+static const int GSM_PCS1900_BIT = 4;
+static const int GSM_GSM850_BIT = 7;
+static const std::vector<int> GSM_BAND_BIT{GSM_EGSM900_BIT,GSM_DCS1800_BIT,GSM_PCS1900_BIT,GSM_GSM850_BIT};
+
+/** Event or message id. */
+static const int EVENT_QUERY_SUPPORTED = 100;
+static const int EVENT_QUERY_CURRENT = 101;
+static const int EVENT_SET_GSM = 110;
+
+static const int EVENT_SET_FAIL = 1;
+static const int EVENT_RESET = 2;
+
+static const std::uint32_t GSM_MAX_VALUE = UINT8_MAX; //255
+static const std::uint32_t UMTS_MAX_VALUE = UINT16_MAX; //65535;
+static const std::uint32_t LTE_MAX_VALUE = UINT32_MAX;//4294967295
+
+/** AT Command. */
+static const std::string QUERY_SUPPORT_COMMAND = "AT+EPBSE=?";
+static const std::string QUERY_CURRENT_COMMAND = "AT+EPBSE?";
+static const std::string SET_COMMAND = "AT+EPBSE=";
+static const std::string SAME_COMMAND = "+EPBSE:";
+
+
+static const int EVENT_QUERY_CURRENT_CDMA = 103;
+static const int EVENT_SET_CDMA = 111;
+
+static const std::string QUERY_CURRENT_COMMAND_CDMA = "AT+ECBANDCFG?";
+static const std::string SET_COMMAND_CDMA = "AT+ECBANDCFG=";
+static const std::string SAME_COMMAND_CDMA = "+ECBANDCFG:";
+
+static pthread_mutex_t s_band_Mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t s_band_Cond = PTHREAD_COND_INITIALIZER;
+#define BLOCK_LOCK() pthread_mutex_lock(&s_band_Mutex)
+#define BLOCK_UNLOCK() pthread_mutex_unlock(&s_band_Mutex)
+#define BLOCK_WAIT() pthread_cond_wait(&s_band_Cond, &s_band_Mutex)
+#define BLOCK_WAKEUP() pthread_cond_broadcast(&s_band_Cond)
+
+bool mIsLteExtend = false;
+int mCurrentEmbandmodeFlag = 0;
+std::vector<long> gsmValues(INDEX_BAND_MAX);
+long cdmaValues = 0;
+
+struct BandModeMap{
+    std::string mName;
+    int mIndex;
+    int mBit;
+    bool mEnable;
+    bool mCheck;
+    BandModeMap(std::string name, int index, int bit ,bool enable, bool check)
+    : mName(name), mIndex(index), mBit(bit), mEnable(enable), mCheck(check) {
+
+    }
+    BandModeMap(BandModeMap&& other): mName(std::move(other.mName)),
+            mIndex(std::move(other.mIndex)),
+            mBit(std::move(other.mBit)),
+            mEnable(std::move(other.mEnable)),
+            mCheck(std::move(other.mCheck)) {
+
+    }
+    BandModeMap& operator=(const BandModeMap& other) = default;
+};
+
+static std::vector<BandModeMap> mModeArray;
+static std::vector<BandModeMap> mCdmaModeArray;
+static const std::vector<std::string> band_mode_gsm { "EGSM900", "DCS1800",
+        "PCS1900", "GSM850" };
+
+static const std::vector<std::string> band_mode_wcdma { "WCDMA-IMT-2000",
+        "WCDMA-PCS-1900", "WCDMA-DCS-1800", "WCDMA-AWS-1700", "WCDMA-CLR-850",
+        "WCDMA-800", "WCDMA-IMT-E-2600", "WCDMA-GSM-900", "WCDMA-1800",
+        "WCDMA-1700" };
+
+static const std::vector<std::string> band_mode_tdscdma { "TD_SCDMA Band A",
+        "TD_SCDMA Band B", "TD_SCDMA Band C", "TD_SCDMA Band D",
+        "TD_SCDMA Band E", "TD_SCDMA Band F" };
+
+static const std::vector<std::string> band_mode_lte_fdd { "Band 1", "Band 2",
+        "Band 3", "Band 4", "Band 5", "Band 6", "Band 7", "Band 8", "Band 9",
+        "Band 10", "Band 11", "Band 12", "Band 13", "Band 14", "Band 15",
+        "Band 16", "Band 17", "Band 18", "Band 19", "Band 20", "Band 21",
+        "Band 22", "Band 23", "Band 24", "Band 25", "Band 26", "Band 27",
+        "Band 28", "Band 29", "Band 30", "Band 31", "Band 32" };
+
+static const std::vector<std::string> band_mode_lte_tdd { "Band 33", "Band 34",
+        "Band 35", "Band 36", "Band 37", "Band 38", "Band 39", "Band 40",
+        "Band 41", "Band 42", "Band 43", "Band 44" };
+
+static const std::vector<std::string> band_mode_lte_96 { "Band 65", "Band 66",
+        "Band 67", "Band 68", "Band 69", "Band 70", "Band 71", "Band 72",
+        "Band 73", "Band 74", "Band 75", "Band 76", "Band 77", "Band 78",
+        "Band 79", "Band 80", "Band 81", "Band 82", "Band 83", "Band 84",
+        "Band 85", "Band 86", "Band 87", "Band 88", "Band 89", "Band 90",
+        "Band 91", "Band 92", "Band 93", "Band 94", "Band 95", "Band 96" };
+
+static const std::vector<std::string> band_mode_lte_128 { "Band 97", "Band 98",
+        "Band 99", "Band 100", "Band 101", "Band 102", "Band 103", "Band 104",
+        "Band 105", "Band 106", "Band 107", "Band 108", "Band 109", "Band 110",
+        "Band 111", "Band 112", "Band 113", "Band 114", "Band 115", "Band 116",
+        "Band 117", "Band 118", "Band 119", "Band 120", "Band 121", "Band 122",
+        "Band 123", "Band 124", "Band 125", "Band 126", "Band 127", "Band 128" };
+
+static const std::vector<std::string> band_mode_lte_160 { "Band 129",
+        "Band 130", "Band 131", "Band 132", "Band 133", "Band 134", "Band 135",
+        "Band 136", "Band 137", "Band 138", "Band 139", "Band 140", "Band 141",
+        "Band 142", "Band 143", "Band 144", "Band 145", "Band 146", "Band 147",
+        "Band 148", "Band 149", "Band 150", "Band 151", "Band 152", "Band 153",
+        "Band 154", "Band 155", "Band 156", "Band 157", "Band 158", "Band 159",
+        "Band 160" };
+
+static const std::vector<std::string> band_mode_lte_192 { "Band 161",
+        "Band 162", "Band 163", "Band 164", "Band 165", "Band 166", "Band 167",
+        "Band 168", "Band 169", "Band 170", "Band 171", "Band 172", "Band 173",
+        "Band 174", "Band 175", "Band 176", "Band 177", "Band 178", "Band 179",
+        "Band 180", "Band 181", "Band 182", "Band 183", "Band 184", "Band 185",
+        "Band 186", "Band 187", "Band 188", "Band 189", "Band 190", "Band 191",
+        "Band 192" };
+
+static const std::vector<std::string> band_mode_lte_224 { "Band 193",
+        "Band 194", "Band 195", "Band 196", "Band 197", "Band 198", "Band 199",
+        "Band 200", "Band 201", "Band 202", "Band 203", "Band 204", "Band 205",
+        "Band 206", "Band 207", "Band 208", "Band 209", "Band 210", "Band 211",
+        "Band 212", "Band 213", "Band 214", "Band 215", "Band 216", "Band 217",
+        "Band 218", "Band 219", "Band 220", "Band 221", "Band 222", "Band 223",
+        "Band 224" };
+
+static const std::vector<std::string> band_mode_lte_256 { "Band 225",
+        "Band 226", "Band 227", "Band 228", "Band 229", "Band 230", "Band 231",
+        "Band 232", "Band 233", "Band 234", "Band 235", "Band 236", "Band 237",
+        "Band 238", "Band 239", "Band 240", "Band 241", "Band 242", "Band 243",
+        "Band 244", "Band 245", "Band 246", "Band 247", "Band 248", "Band 249",
+        "Band 250", "Band 251", "Band 252", "Band 253", "Band 254", "Band 255",
+        "Band 256" };
+
+static const std::vector<std::string> band_mode_cdma {
+        "Band 0(North American Celluar Band)",
+        "Band 1(North American PCS band)", "Band 2(TACS band)",
+        "Band 3(JTACS band)", "Band 4(Korean PCS band)", "Band 5(NMT-450 Band)",
+        "Band 6(IMT-2000 band)", "Band 7(North American 700Mhz Celluar Band)",
+        "Band 8(1800-MHz Band)", "Band 9(900-MHz Band)",
+        "Band 10(Secondary 800 MHz Band)", "Band 11(400 MHz European PAMR Band",
+        "Band 12(800 MHz PAMR Band)",
+        "Band 13(2.5 GHz IMT-2000 Extension Band)",
+        "Band 14(US PCS 1.9GHz Band)", "Band 15(AWS Band)" };
+
+int fgset = false;
+int count = -1;
+std::vector<std::string> choose_vals;
+
+static void sendATCommand(const char *cmd,int msg)
+{
+    BLOCK_LOCK();
+    mCurrentEmbandmodeFlag = msg;
+    emSendATCommand(cmd,mSimType);
+    RLOGD("sendATCommand: wait start");
+    BLOCK_WAIT();
+    RLOGD("sendATCommand: wait end");
+    BLOCK_UNLOCK();
+    return ;
+}
+
+static void setCurrentMode(std::vector<long> values) {
+    for (auto& m : mModeArray) {
+        if ((values[m.mIndex] & (1L << m.mBit)) == 0) {
+            m.mCheck = false;
+        } else {
+            if (m.mEnable) {
+                m.mCheck = true;
+            }
+        }
+        //RLOGD("setCurrentMode labels: %s, enable: %d, check: %d", m.mName.c_str(), m.mEnable, m.mCheck);
+    }
+}
+
+static void setSupportedMode(std::vector<long> values) {
+    for (auto& m : mModeArray) {
+        if ((values[m.mIndex] & (1L << m.mBit)) == 0) {
+            m.mEnable = false;
+        } else {
+            m.mEnable = true;
+        }
+        //RLOGD("setSupportedMode labels: %s, enable: %d", m.mName.c_str(), m.mEnable);
+    }
+}
+
+static void setCurrentModeCdma(const long value) {
+    RLOGD("setCurrentModeCdma: %ld", value);
+    for (auto& m : mCdmaModeArray) {
+        if ((value & (1L << m.mBit)) == 0) {
+            m.mCheck = false;
+        } else {
+            if (m.mEnable) {
+                m.mCheck = true;
+            }
+        }
+        RLOGD("setCurrentModeCdma labels: %s, enable: %d, check: %d", m.mName.c_str(), m.mEnable, m.mCheck);
+    }
+
+}
+
+static void setSupportedModeCdma(const long value) {
+    RLOGD("setSupportedModeCdma: %ld", value);
+    for (auto& m : mCdmaModeArray) {
+        if ((value & (1L << m.mBit)) == 0) {
+            m.mEnable = false;
+        } else {
+            m.mEnable = true;
+        }
+        RLOGD("setSupportedModeCdma labels: %s, enable: %d", m.mName.c_str(), m.mEnable);
+    }
+}
+
+static void showBandModeCdma(char* response, int msg) {
+    std::vector<std::string> out;
+    utils::tokenize(string(response), "\n", out);
+    for(auto i: out) {
+        if(i.find(SAME_COMMAND_CDMA) != std::string::npos) {
+            std::string splitString = i.substr(std::string(SAME_COMMAND_CDMA).size());
+            RLOGD("showBandModeCdma splitString: %s", splitString.c_str());
+            if (msg == EVENT_QUERY_CURRENT_CDMA) {
+                std::vector<std::string> getDigitalVal;
+                utils::tokenize(string(splitString), ",\n", getDigitalVal);
+                std::vector<long> values;
+                try {
+                    for(auto str: getDigitalVal) {
+                        if(str.empty() || str == "\n") {
+                            continue;
+                        }
+                        long v = std::stol(str, 0 ,0);
+                        values.push_back(v);
+                    }
+                } catch (const out_of_range &e) {
+                    RLOGD("out of range: %s", e.what());
+                } catch (const invalid_argument &e) {
+                    RLOGD("invalid argument: %s", e.what());
+                }
+                if(values.size() < 2) {
+                    RLOGD("showBandModeCdma size < 2");
+                    android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+                    return;
+                }
+                setSupportedModeCdma(values[0]);
+                setCurrentModeCdma(values[1]);
+            }
+        }
+    }
+}
+
+static void showBandModeGsm(char* response, int msg) {
+    std::vector<std::string> out;
+    utils::tokenize(string(response), "\n", out);
+    for(auto i: out) {
+        if(i.find(SAME_COMMAND) != std::string::npos) {
+            std::string splitString = i.substr(std::string(SAME_COMMAND).size());
+            RLOGD("showBandModeGsm splitString: %s", splitString.c_str());
+            std::vector<std::string> getDigitalVal;
+            utils::tokenize(string(splitString), ",\n", getDigitalVal);
+            if (getDigitalVal.size() > 0) {
+                std::vector<long> values;
+                for (int i = 0; i < INDEX_BAND_MAX; i++) {
+                    if (getDigitalVal.size() <= i) {
+                        values.push_back(0);
+                        continue;
+                    }
+                    try {
+                        values.push_back(std::stol(getDigitalVal[i], 0 ,0));
+                    } catch (const out_of_range &e) {
+                        values.push_back(0);
+                        RLOGD("out of range: %s", e.what());
+                    } catch (const invalid_argument &e) {
+                        values.push_back(0);
+                        RLOGD("invalid argument: %s", e.what());
+                    }
+                }
+                if (msg == EVENT_QUERY_SUPPORTED) {
+                    setSupportedMode(values);
+                    if (getDigitalVal.size() > 5) {
+                        RLOGD("The Modem support Lte extend band");
+                        mIsLteExtend = true;
+                    } else {
+                        RLOGD("The Modem not support Lte extend band");
+                        mIsLteExtend = false;
+                    }
+                } else {
+                    setCurrentMode(values);
+                }
+            } else {
+                android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+                RLOGD("getDigitalVal is null");
+            }
+        }
+    }
+}
+
+static void printGetBand(int flag) {
+    RLOGD("printGetBand(%d), fgset(%d)", flag, fgset);
+    if(fgset) {
+        return;
+    }
+    if(flag == EVENT_QUERY_CURRENT) {
+        RLOGD("printGetBand start");
+        std::string msg;
+        for (auto& i : mModeArray) {
+            if (i.mEnable && i.mCheck) {
+                if ((i.mIndex == INDEX_GSM_BAND) && (msg.find("GSM Mode:") == std::string::npos)) {
+                    msg.append("GSM Mode:\n");
+                } else if ((i.mIndex == INDEX_UMTS_BAND) && (msg.find("UMTS Mode:") == std::string::npos)) {
+                    msg.append("\nUMTS Mode:\n");
+                } else if ((i.mIndex >= INDEX_LTE_FDD_BAND) && (i.mIndex <= INDEX_LTE_BAND_256) && (msg.find("LTE Mode:") == std::string::npos)) {
+                    msg.append("\nLTE Mode:\n");
+                }
+
+                msg.append("....");
+                msg.append(i.mName);
+                msg.append("\n");
+            }
+        }
+        for (auto& i : mCdmaModeArray) {
+            if (i.mEnable && i.mCheck) {
+                if ((i.mIndex == INDEX_CDMA_BAND) && (msg.find("CDMA Mode:") == std::string::npos)) {
+                    msg.append("\nCDMA Mode: \n");
+                }
+                msg.append("....");
+                msg.append(i.mName);
+                msg.append("\n");
+            }
+        }
+        msg.append("done\n");
+        android::emResultNotify(msg.c_str());
+    }
+}
+
+static void setBandModeCdma(const long value) {
+    RLOGD("setCdmaBandMode: %d", value);
+    string msg = SET_COMMAND_CDMA + std::to_string(value);
+    sendATCommand(msg.c_str(), EVENT_SET_CDMA);
+}
+
+/**
+ * Set the selected modes.
+ *
+ * @param values the integers of mode values
+ * @return false means set failed or success
+ */
+static void setBandMode(std::vector<long> values) {
+    RLOGD("setBandMode values: %ld,%ld,%ld,%ld", values[0],values[1],values[2],values[3]);
+    if (values[0] > GSM_MAX_VALUE
+            || values[1] > UMTS_MAX_VALUE
+            || values[2] > LTE_MAX_VALUE
+            || values[3] > LTE_MAX_VALUE) {
+        android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+        RLOGD("setBandMode,just return");
+        return;
+    }
+
+    std::vector<std::string> modeString {SET_COMMAND + std::to_string(values[0]) + std::string(",") + std::to_string(values[1]), ""};
+    if (ModemCategory::isLteSupport()) {
+        modeString[0] += std::string(",") + std::to_string(values[2]) + std::string(",") + std::to_string(values[3]);
+        if (mIsLteExtend) {
+            for (int i = 4; i < INDEX_BAND_MAX - 1; i++) {
+                modeString[0] += std::string(",") + std::to_string(values[i]);
+            }
+        }
+    }
+    RLOGD("setGsmBandMode AT String: %s", modeString[0].c_str());
+    sendATCommand(modeString[0].c_str(), EVENT_SET_GSM);
+}
+
+static long getValFromBoxCdma() {
+    long value = 0;
+    for (auto& m : mCdmaModeArray) {
+        if (m.mCheck) {
+            value |= 1L << m.mBit;
+        }
+    }
+    return value;
+}
+
+/**
+ * Get the selected mode values.
+ *
+ * @return values from the selected boxes
+ */
+static std::vector<long> getValFromBox(bool judge) {
+    std::vector<long> values(INDEX_BAND_MAX,0);
+    std::vector<long> values_temp(INDEX_BAND_MAX,0);
+    for (auto& m : mModeArray) {
+        if (m.mCheck) {
+            values[m.mIndex] |= 1L << m.mBit;
+            values_temp[m.mIndex] |= 1L << m.mBit;
+        }
+    }
+
+    if (judge) {
+        // band64 to band256 belongs to lte fdd, so check null together
+        for (int i = INDEX_LTE_BAND_96; i <= INDEX_LTE_BAND_256; i++) {
+            values_temp[INDEX_LTE_FDD_BAND] = values_temp[INDEX_LTE_FDD_BAND] | values_temp[i];
+        }
+        // check FDD and TDD ,only all null is invalid
+        values_temp[INDEX_LTE_FDD_BAND] = values_temp[INDEX_LTE_FDD_BAND] | values_temp[INDEX_LTE_TDD_BAND];
+        values_temp[INDEX_LTE_TDD_BAND] = values_temp[INDEX_LTE_FDD_BAND];
+
+        // null select is not allowed.
+        if (values[0] == 0) {
+            values[0] = GSM_MAX_VALUE;
+        }
+        if (values[1] == 0) {
+            values[1] = UMTS_MAX_VALUE;
+        }
+        if (values_temp[2] == 0 && values_temp[3] == 0) {
+            values[2] = LTE_MAX_VALUE;
+            values[3] = LTE_MAX_VALUE;
+            RLOGD("lte not to null");
+        }
+    }
+    return values;
+}
+
+static void printSupportBand(int flag) {
+    RLOGD("printSupportBand, fgset(%d), count(%d), flag(%d)",fgset, count, flag);
+    if(fgset && (count == 0) && (flag == EVENT_QUERY_CURRENT)) {
+        RLOGD("printSupportBand start");
+        std::string msg;
+        for (auto& i : mModeArray) {
+            if (i.mEnable) {
+                if ((i.mIndex == INDEX_GSM_BAND) && (msg.find("GSM Mode:") == std::string::npos)) {
+                    msg.append("GSM Mode:\n");
+                } else if ((i.mIndex == INDEX_UMTS_BAND) && (msg.find("UMTS Mode:") == std::string::npos)) {
+                    msg.append("\nUMTS Mode:\n");
+                } else if ((i.mIndex >= INDEX_LTE_FDD_BAND) && (i.mIndex <= INDEX_LTE_BAND_256) && (msg.find("LTE Mode:") == std::string::npos)) {
+                    msg.append("\nLTE Mode:\n");
+                }
+
+                msg.append("....");
+                msg.append("(");
+                msg.append(std::to_string(i.mIndex));
+                msg.append(".");
+                msg.append(std::to_string(i.mBit));
+                msg.append("): ");
+                msg.append(i.mName);
+                msg.append("....");
+                msg.append(i.mCheck ? "true":"false");
+                msg.append("\n");
+            }
+        }
+        for (auto& i : mCdmaModeArray) {
+            if (i.mEnable) {
+                if ((i.mIndex == INDEX_CDMA_BAND) && (msg.find("CDMA Mode:") == std::string::npos)) {
+                    msg.append("\nCDMA Mode: \n");
+                }
+                msg.append("....");
+                msg.append("(");
+                msg.append(std::to_string(i.mIndex));
+                msg.append(".");
+                msg.append(std::to_string(i.mBit));
+                msg.append("): ");
+                msg.append(i.mName);
+                msg.append("....");
+                msg.append(i.mIndex ? "true":"false");
+                msg.append("\n");
+            }
+        }
+        msg.append("done\n");
+        android::emResultNotify(msg.c_str());
+    }
+}
+
+static void* setGsmBandMode(void* arg) {
+    setBandMode(gsmValues);
+    return NULL;
+}
+
+static void* setCdmaBandMode(void* arg) {
+    setBandModeCdma(cdmaValues);
+    return NULL;
+}
+
+static void emBandmodeAtCmdHandle(char* response, int responselen) {
+    RLOGD("emBandmodeAtCmdHandle, flag=%d, data=%s", mCurrentEmbandmodeFlag, response);
+    switch (mCurrentEmbandmodeFlag) {
+    case EVENT_QUERY_CURRENT_CDMA: {
+        if ((responselen > 0) && (response != NULL)) {
+            showBandModeCdma(response, EVENT_QUERY_CURRENT_CDMA);
+        } else {
+            android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+            RLOGD("don't support(%d)", EVENT_QUERY_CURRENT_CDMA);
+        }
+        BLOCK_WAKEUP();
+        break;
+    }
+    case EVENT_QUERY_SUPPORTED:
+    {
+        if ((responselen > 0) && (response != NULL)) {
+            showBandModeGsm(response, EVENT_QUERY_SUPPORTED);
+        } else {
+            android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+            RLOGD("don't support(%d)", EVENT_QUERY_SUPPORTED);
+        }
+        BLOCK_WAKEUP();
+        break;
+    }
+    case EVENT_QUERY_CURRENT:
+    {
+        if ((responselen > 0) && (response != NULL)) {
+            showBandModeGsm(response, EVENT_QUERY_CURRENT);
+        } else {
+            android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+            RLOGD("don't support(%d)", EVENT_QUERY_CURRENT);
+        }
+        printGetBand(EVENT_QUERY_CURRENT);
+        printSupportBand(EVENT_QUERY_CURRENT);
+        BLOCK_WAKEUP();
+        if(fgset && (count > 0)) {
+            for(auto& val : choose_vals) {
+                RLOGD("handle values: %s", val.c_str());
+                std::vector<std::string> out;
+                utils::tokenize(val, "=", out);
+                if(out.size() == 2) {
+                    std::vector<std::string> indexs;
+                    utils::tokenize(out[0], ".", indexs);
+                    if(indexs.size() == 2) {
+                        try {
+                            int index = std::stoi(indexs[0]);
+                            int bit = std::stoi(indexs[1]);
+                            bool check = std::stoi(out[1]) > 0 ? true : false;
+                            for (auto& i : mModeArray) {
+                                if((i.mIndex == index) && (i.mBit == bit)) {
+                                    i.mCheck = check;
+                                    RLOGD("set gsm band: lales=%s, index=%d, bit=%d, enable=%d, check=%d",
+                                            i.mName.c_str(),i.mIndex, i.mBit, i.mEnable, i.mCheck);
+                                }
+                            }
+                            for (auto& i : mCdmaModeArray) {
+                                if((i.mIndex == index) && (i.mBit == bit)) {
+                                    if((i.mIndex == index) && (i.mBit == bit)) {
+                                        i.mCheck = check;
+                                        RLOGD("set gsm band: lales=%s, index=%d, bit=%d, enable=%d, check=%d",
+                                                i.mName.c_str(),i.mIndex, i.mBit, i.mEnable, i.mCheck);
+                                    }
+                                }
+                            }
+                        } catch (const out_of_range &e) {
+                            RLOGD("out of range: %s", e.what());
+                        } catch (const invalid_argument &e) {
+                            RLOGD("invalid argument: %s", e.what());
+                        }
+                    }else {
+                        RLOGD("invalid parameters: %s", out[0].c_str());
+                        android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+                        return;
+                    }
+
+                } else {
+                    RLOGD("invalid parameters: %s", val.c_str());
+                    android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+                    return;
+                }
+            }
+            cdmaValues = getValFromBoxCdma();
+            gsmValues = getValFromBox(true);
+            pthread_t setBandMode_thread;
+            pthread_create(&setBandMode_thread,NULL, setGsmBandMode, NULL);
+        }
+        break;
+    }
+    case EVENT_SET_GSM:
+    {
+        BLOCK_WAKEUP();
+        if ((responselen > 0) && (response != NULL)) {
+            RLOGD("Set Gsm bandmode success: %s", response);
+            if ((mSimType == 0) && ModemCategory::isCdma() && (!utils::is90Modem())) {
+                pthread_t setBandMode_thread;
+                pthread_create(&setBandMode_thread,NULL, setCdmaBandMode, NULL);
+            } else {
+                RLOGD("don't support cdma, response");
+                android::emResultNotify(RET_STRING_BANDMODE_SUCCESS);
+            }
+        } else {
+            RLOGD("send gsm fail ");
+            android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+        }
+        break;
+    }
+    case EVENT_SET_CDMA:
+    {
+        BLOCK_WAKEUP();
+        if ((responselen > 0) && (response != NULL)) {
+            RLOGD("Set cdma bandmode success: %s", response);
+            android::emResultNotify(RET_STRING_BANDMODE_SUCCESS);
+        } else {
+            RLOGD("send cdma fail ");
+            android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+        }
+        break;
+    }
+    default:
+        break;
+    }
+}
+
+static void queryCurrentCdmaMode() {
+    if (utils::is93Modem()) {
+        //SAME_COMMAND_CDMA;
+        RLOGD("queryCurrentCdmaMode: %s", QUERY_CURRENT_COMMAND_CDMA.c_str());
+        sendATCommand(QUERY_CURRENT_COMMAND_CDMA.c_str(), EVENT_QUERY_CURRENT_CDMA);
+    } else {
+        android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+        RLOGD("don't support");
+    }
+}
+
+/**
+ * Query Modem supported band modes.
+ */
+static void querySupportMode() {
+    //SAME_COMMAND
+    RLOGD("querySupportMode AT String: %s", QUERY_SUPPORT_COMMAND.c_str());
+    sendATCommand(QUERY_SUPPORT_COMMAND.c_str(), EVENT_QUERY_SUPPORTED);
+}
+
+/**
+ * Query Modem is being used band modes.
+ */
+static void queryCurrentMode() {
+    //SAME_COMMAND
+    RLOGD("queryCurrentMode AT String: %s", QUERY_CURRENT_COMMAND.c_str());
+    sendATCommand(QUERY_CURRENT_COMMAND.c_str(), EVENT_QUERY_CURRENT);
+}
+
+static void initGsmArray() {
+    for (int i = 0; i < band_mode_gsm.size(); i++) {
+        mModeArray.emplace_back(band_mode_gsm[i], INDEX_GSM_BAND, GSM_BAND_BIT[i], false, false);
+    }
+}
+
+static void initLteArray() {
+    for (int i = 0; i < band_mode_lte_fdd.size(); i++) {
+        mModeArray.emplace_back(band_mode_lte_fdd[i], INDEX_LTE_FDD_BAND, i, false, false);
+    }
+    for (int i = 0; i < band_mode_lte_tdd.size(); i++) {
+        mModeArray.emplace_back(band_mode_lte_tdd[i], INDEX_LTE_TDD_BAND, i, false, false);
+    }
+    for (int i = 0; i < band_mode_lte_96.size(); i++) {
+        mModeArray.emplace_back(band_mode_lte_96[i], INDEX_LTE_BAND_96, i, false, false);
+    }
+    for (int i = 0; i < band_mode_lte_128.size(); i++) {
+        mModeArray.emplace_back(band_mode_lte_128[i], INDEX_LTE_BAND_128, i, false, false);
+    }
+    for (int i = 0; i < band_mode_lte_160.size(); i++) {
+        mModeArray.emplace_back(band_mode_lte_160[i], INDEX_LTE_BAND_160, i, false, false);
+    }
+    for (int i = 0; i < band_mode_lte_192.size(); i++) {
+        mModeArray.emplace_back(band_mode_lte_192[i], INDEX_LTE_BAND_192, i, false, false);
+    }
+    for (int i = 0; i < band_mode_lte_224.size(); i++) {
+        mModeArray.emplace_back(band_mode_lte_224[i], INDEX_LTE_BAND_224, i, false, false);
+    }
+    for (int i = 0; i < band_mode_lte_256.size(); i++) {
+        mModeArray.emplace_back(band_mode_lte_256[i], INDEX_LTE_BAND_256, i, false, false);
+    }
+}
+
+static void initTdscdmaArray() {
+    for (int i = 0; i < band_mode_tdscdma.size(); i++) {
+        mModeArray.emplace_back(band_mode_tdscdma[i], INDEX_UMTS_BAND, i, false, false);
+    }
+}
+
+static void initWcdmaArray() {
+    for (int i = 0; i < band_mode_wcdma.size(); i++) {
+        mModeArray.emplace_back(band_mode_wcdma[i], INDEX_UMTS_BAND, i, false, false);
+    }
+}
+
+static void initCdmaArray() {
+    for (int i = 0; i < band_mode_cdma.size(); i++) {
+        mCdmaModeArray.emplace_back(band_mode_cdma[i], INDEX_CDMA_BAND, i, false, false);
+    }
+}
+
+static void * emBandmodeThread(void* arg)
+{
+    mModeArray.clear();
+    mCdmaModeArray.clear();
+    initGsmArray();
+    int modemType = ModemCategory::getModemType();
+    if (modemType == TDSCDMA && ModemCategory::isCapabilitySim(mSimType)) {
+        initTdscdmaArray();
+        if (ModemCategory::isLteSupport()) {
+            initLteArray();
+        }
+    } else if (modemType == WCDMA && ModemCategory::isCapabilitySim(mSimType)) {
+        initWcdmaArray();
+        if (ModemCategory::isLteSupport()) {
+            initLteArray();
+        }
+    } else if (!(ModemCategory::isCapabilitySim(mSimType))) {
+        if (ModemCategory::checkViceSimCapability(mSimType, MtkRadioAccessFamily::RAF_UMTS)) {
+            initWcdmaArray();
+        }
+        if (ModemCategory::checkViceSimCapability(mSimType, MtkRadioAccessFamily::RAF_LTE)) {
+            if (ModemCategory::isLteSupport()) {
+                initLteArray();
+            }
+        }
+    }
+
+    if (mSimType == 0 && ModemCategory::isCdma() && !utils::is90Modem()) {
+        initCdmaArray();
+    }
+    if (ModemCategory::isCdma() && !utils::is90Modem() && (mSimType == 0)) {
+        queryCurrentCdmaMode();
+    }
+    querySupportMode();
+    queryCurrentMode();
+    pthread_exit(0);
+}
+
+//AT+EPBSE=gsm,umts,ltefdd,ltetdd
+int emBandmodeStart(int len,int *item,int multilen,char *value[])
+{
+    mSimType = get_default_sim_all_except_data();
+    RLOGD("emBandmodeStart called : simType:%d", mSimType);
+    //1. reset to default: select all supported bands: AT+EPBSE=255,63355
+    if(len < 1)
+    {
+        RLOGD("emBandmodeStart: please select mode to test: 0: get, 1: set ");
+        android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+        return -1;
+    }
+    if((item[0] > 1 ) || (item[0] < 0)){
+        RLOGD("emBandmodeStart: invalid parameter %d",item[0]);
+        android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+        return -1;
+    }
+    if(item[0] == 0){
+        fgset = false;
+    }else{
+        fgset = true;
+        count = multilen;
+        RLOGD("emBandmodeStart count = %d", count);
+        choose_vals.clear();
+        if(count > 0){
+            for(int i=0; i< count; i++) {
+                choose_vals.push_back(value[i]);
+            }
+        }
+    }
+    mCurrentEmbandmodeFlag = 0;
+    android::registerForATcmdResponse(emBandmodeAtCmdHandle);
+    pthread_t embandmode_thread;
+    pthread_create(&embandmode_thread,NULL, emBandmodeThread, NULL);
+    return (0);
+}
+#endif
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_c2kmodemsetting.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_c2kmodemsetting.cpp
new file mode 100644
index 0000000..e577c39
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_c2kmodemsetting.cpp
@@ -0,0 +1,134 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include <string>
+#include <vector>
+
+#include  "common.h"
+#include "em/em.h"
+#include "Radio_capability_switch_util.h"
+
+#if EM_MODE_SUPPORT
+
+#undef LOG_TAG
+#define LOG_TAG "EM_C2KMODEMSETTING"
+const int TIME_REG = 0;
+
+const static int MSG_SET_DISABLE_1X_TIME = 1;
+const static int MSG_SET_ENABLE_1X_TIME = 2;
+const static int MSG_QUERY_STATUS_1X_TIME = 3;
+
+int c2kmodemsetting_id = -1;
+//int c2kmodemsetting_option_cnt = -1;
+int c2kmodemsetting_option[8] = { 0 };
+
+int mCurrentC2KEmmodemSettingFlag = -1;
+static void sendATCommand(const char *cmd, int msg) {
+    mCurrentC2KEmmodemSettingFlag = msg;
+    emSendATCommand(cmd,Radio_capability_switch_util::get_main_capability_phone_id());
+    return;
+}
+
+static void set1XTime(int command, int msg) {
+    std::vector<std::string> cmdOri(3);
+    cmdOri[0] = "AT+ECREGTYPE=0," + std::to_string((command == 1 ? 1 : 0));
+    cmdOri[1] = "";
+    cmdOri[2] = "DESTRILD:C2K";
+    std::vector<std::string> cmds = getCdmaCmdArr(cmdOri);
+    std::string cmd;
+    for (auto s : cmds) {
+        cmd += s;
+    }
+    RLOGD("set1XTime AT command: %s", cmd);
+    sendATCommand(cmd.c_str(), msg);
+}
+
+static void emC2kModemSetingsAtCmdHandle(char*response, int responselen) {
+    switch (mCurrentC2KEmmodemSettingFlag) {
+    case MSG_SET_DISABLE_1X_TIME: {
+        if ((responselen > 0) && (response != NULL)) {
+            RLOGD("Disable_Time_REG successful");
+            emResultNotifyWithDone("Disable_Time_REG successful");
+        } else {
+            RLOGD("Disable_Time_REG failed.");
+            emResultNotifyWithDone("Disable_Time_REG failed.");
+        }
+        break;
+    }
+    case MSG_SET_ENABLE_1X_TIME: {
+        if ((responselen > 0) && (response != NULL)) {
+            RLOGD("Enable_Time_REG successful.");
+            emResultNotifyWithDone("Enable_Time_REG successful.");
+        } else {
+            RLOGD("Enable_Time_REG failed.");
+            emResultNotifyWithDone("Enable_Time_REG failed.");
+        }
+        break;
+    }
+    case MSG_QUERY_STATUS_1X_TIME:
+        break;
+    default:
+        break;
+    }
+}
+
+static void * emC2kModemSettingThread(void* arg) {
+    RLOGD("c2k Modem Setting: %d ", c2kmodemsetting_option[0]);
+    switch (c2kmodemsetting_id) {
+    case TIME_REG: {
+        set1XTime(c2kmodemsetting_option[0],
+                (c2kmodemsetting_option[0] ?
+                        MSG_SET_ENABLE_1X_TIME : MSG_SET_DISABLE_1X_TIME));
+        break;
+    }
+    default:
+        break;
+    }
+    pthread_exit(0);
+}
+
+int emC2kModemSettingStart(int argc, int multicnt, int *item) {
+    RLOGD("emC2kModemSettingStart called");
+    int idmapping[1] = { TIME_REG };
+    c2kmodemsetting_id = idmapping[item[0]];
+    c2kmodemsetting_option[0] = item[1];
+    android::registerForATcmdResponse(emC2kModemSetingsAtCmdHandle);
+    pthread_t emC2kModemSetting_thread;
+    pthread_create(&emC2kModemSetting_thread, NULL, emC2kModemSettingThread,
+            NULL);
+    return 0;
+}
+#endif /*EM_MODE_SUPPORT*/
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_cfu.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_cfu.cpp
new file mode 100644
index 0000000..7b382d8
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_cfu.cpp
@@ -0,0 +1,153 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include <vendor-ril/telephony/ril.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <cutils/jstring.h>
+#include <log/log.h>
+#include <unistd.h>
+#include <math.h>
+#include  "common.h"
+#include "em/em.h"
+#include "Radio_capability_switch_util.h"
+
+#if EM_MODE_SUPPORT
+
+#undef LOG_TAG
+#define LOG_TAG "EM_CFU"
+
+const int QUERY = 3;
+const int SET_DEFAULT = 0;
+const int SET_ON = 2;
+const int SET_OFF = 1;
+#define CFU_QUERY_CMD  "AT+ESSP?"
+#define CFU_SET_CMD  "AT+ESSP="
+int mCurrentEmcfuFlag = 0;
+int cfumode = -1;
+
+void  sendATCommand_ecfu(const char *cmd,int msg)
+{
+    mCurrentEmcfuFlag = msg;
+    emSendATCommand(cmd, Radio_capability_switch_util::get_main_capability_phone_id());
+    return ;
+}
+
+void emCfuAtCmdHandle(char*response, int responselen) {
+    switch (mCurrentEmcfuFlag) {
+        case QUERY:
+        {
+            //parse hspa mode.
+            if ((responselen > 0) && (response != NULL)) {
+                RLOGD("emCfuAtCmdHandle QUERY response: %s\n",response);
+            }
+            else {
+                RLOGD("send fail ");
+            }
+            android::unregisterNetwork();
+            android::emResultNotify(RET_STRING_CFU_SUCCESS);
+            break;
+        }
+        case SET_DEFAULT:
+        {
+            if ((responselen > 0) && (response != NULL)) {
+                RLOGD("Set default success: %s.\n",response);
+            }
+            else {
+                RLOGD("send fail ");
+            }
+            break;
+        }
+        case SET_ON:
+        {
+            if ((responselen > 0) && (response != NULL)) {
+                RLOGD("Set on success: %s.\n",response);
+            }
+            else {
+                RLOGD("send fail ");
+            }
+            break;
+        }
+        case SET_OFF:
+        {
+            if ((responselen > 0) && (response != NULL)) {
+                RLOGD("Set off success: %s.\n",response);
+            }
+            else {
+                RLOGD("send fail ");
+            }
+            break;
+        }
+        default:
+            break;
+    }
+}
+
+
+//create thread to send command
+void * emCfuThread(void* arg)
+{
+    char cmd_str[32] = {0};
+    sprintf(cmd_str,"%s%d", CFU_SET_CMD,cfumode);
+    sendATCommand_ecfu(cmd_str,cfumode);
+    sendATCommand_ecfu(CFU_QUERY_CMD,QUERY);
+    pthread_exit(0);
+}
+
+int emCfuStart(int argc, int *item)
+{
+    RLOGD("emCfuStart called");
+    if(argc < 1)
+    {
+        RLOGD("emCfuStart: please select mode to test: \
+                0: default, 1: set on 2: set off");
+        android::emResultNotify(RET_STRING_CFU_FAIL);
+        return -1;
+    }
+    if((item[0] > 2 ) || (item[0] < 0)){
+        RLOGD("emCfuStart: invalid parameter %d",item[0]);
+        android::emResultNotify(RET_STRING_CFU_FAIL);
+        return -1;
+    }
+    int cfumapping[3] = {SET_DEFAULT,SET_ON,SET_OFF};
+    mCurrentEmcfuFlag = 0;
+    cfumode = cfumapping[item[0]];
+    android::registerForATcmdResponse(emCfuAtCmdHandle);
+    pthread_t emcfu_thread;
+    pthread_create(&emcfu_thread,NULL, emCfuThread, NULL);
+    return (0);
+}
+
+#endif
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_el1_public_struct.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_el1_public_struct.h
new file mode 100644
index 0000000..1c44d29
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_el1_public_struct.h
@@ -0,0 +1,2026 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2005
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+#ifndef _EM_EL1_PUBLIC_STRUCT_H
+#define _EM_EL1_PUBLIC_STRUCT_H
+
+/* portable 8-bit unsigned integer */
+typedef unsigned char           kal_uint8;
+/* portable 8-bit signed integer */
+typedef signed char             kal_int8;
+/* portable 16-bit unsigned integer */
+typedef unsigned short int      kal_uint16;
+/* portable 16-bit signed integer */
+typedef signed short int        kal_int16;
+/* portable 32-bit unsigned integer */
+typedef unsigned int            kal_uint32;
+typedef signed int              kal_int32;
+typedef unsigned long long kal_uint64;
+typedef signed long long kal_int64;
+typedef unsigned char kal_bool;
+typedef kal_uint32 EARFCN;
+
+/* EL1 */
+#define RPT_LTE_RX_CC_MAX   4
+#define RPT_LTE_TX_CC_MAX   2
+#define LTE_MAX_DATA_BUF   30   // EL1 MDMI
+
+#define AGC_RX_ANT_NUM 2
+#define EM_OTDOA_MAX_NBR_CELL_LIST_NUM_TOTAL  3
+
+#define LOCAL_PARA_HDR \
+   kal_uint8 ref_count; \
+   kal_uint8 lp_reserved; \
+   kal_uint16 msg_len;
+
+typedef enum
+{
+    EM_RNTI_NONE                = 0,
+    EM_C_RNTI                   = 1,
+    EM_SPSC_RNTI                = 2,
+    EM_P_RNTI                   = 3,
+    EM_RA_RNTI                  = 4,
+    EM_TC_RNTI                  = 5,
+    EM_SI_RNTI                  = 6,
+    EM_TPC_PUSCH_RNTI           = 7,
+    EM_TPC_PUCCH_RNTI           = 8,
+    EM_M_RNTI                   = 9,
+    EM_RNTI_INVALID             = 255
+} em_dl_rnti_enum;
+
+typedef enum
+{
+   /*
+    * MP branches: please add "EM type id" in em_info_enum.h.
+    * Please remember to modify MD_COMMON\EM\em_info_enum.h for main TRUNK ex: LR11/LR12/UMOLY/UMOLYA
+    */
+          /* RR */
+          /* Begin of RR EM INFO Request enum */
+          RR_EM_CELL_SELECT_PARA_INFO = 0, RR_EM_INFO_BEGIN = RR_EM_CELL_SELECT_PARA_INFO,
+          RR_EM_CHANNEL_DESCR_INFO = 1,
+          RR_EM_CTRL_CHANNEL_DESCR_INFO = 2,
+          RR_EM_RACH_CTRL_PARA_INFO = 3,
+          RR_EM_LAI_INFO = 4,
+          RR_EM_RADIO_LINK_COUNTER_INFO = 5,
+          RR_EM_MEASUREMENT_REPORT_INFO = 6,
+          /* ZY : Temp solution : Cell allocation list*/
+          RR_EM_CA_LIST_INFO = 7,
+          /* RR new structure */
+          RR_EM_CONTROL_MSG_INFO = 8,
+          RR_EM_SI2Q_INFO_STRUCT_INFO = 9,
+          RR_EM_MI_INFO_STRUCT_INFO = 10,
+          RR_EM_BLK_INFO = 11,
+          RR_EM_TBF_INFO = 12,
+          RR_EM_GPRS_GENERAL_INFO = 13,
+          /* GAS MM EM INFO */
+          RRM_EM_FDD_IR_PARAMETER_STATUS_IND_STRUCT_INFO = 14,
+          RRM_EM_IR_RESELECT_STATUS_IND_STRUCT_INFO = 15,
+          RRM_EM_IR_3G_NEIGHBOR_MEAS_STATUS_IND_STRUCT_INFO = 16,
+          RRM_EM_IR_3G_NEIGHBOR_MEAS_INFO_IND_STRUCT_INFO = 17,
+          RRM_EM_IR_4G_NEIGHBOR_MEAS_STATUS_IND_STRUCT_INFO = 18,
+          RRM_EM_IR_4G_NEIGHBOR_MEAS_INFO_IND_STRUCT_INFO = 19,
+          RRM_EM_SERV_CELL_POWER_STATUS_IND_STRUCT_INFO = 20,
+          RRM_EM_IR_3G_NEIGHBOR_CELL_STATUS_IND_STRUCT_INFO = 21,
+          RRM_EM_IR_4G_NEIGHBOR_CELL_STATUS_IND_STRUCT_INFO = 22,
+          RRM_EM_TDD_IR_PARAMETER_STATUS_IND_STRUCT_INFO = 23,
+          RRM_EM_SUCCESS_RATE_KPI_INFO = 24,
+          RRM_EM_MT_T3126_TIMEOUT_INFO = 25,
+          RRM_EM_CS_RLF_INFO = 26,
+          RRM_EM_RR_STATE_INFO = 27,
+          RRM_EM_GAS_SEARCH_INFO = 28,
+          RRM_EM_DOWNLINK_SIGNALLING_COUNTER_INFO = 29,
+          RRM_EM_RACH_FAIL = 30,
+          RRM_EM_N200_EXP = 31,
+          RRM_EM_HO_FAIL = 32,
+          RRM_EM_OOS_IND = 33,
+          RR_EM_INFO_END = RR_EM_INFO_BEGIN + 49,
+
+          /*End of RR EM INFO Request enum*/
+
+          /* CC */
+          CC_EM_CHANNEL_INFO = 50,
+          CC_EM_CALL_INFO = 51,
+
+          /* SS */
+          SS_EM_INFO = 52,
+
+          /* MM */
+          MM_EM_INFO = 53,
+          /*EM ehancement for RR new structure*/
+          MMRR_EM_PLMN_INFO_STRUCT_INFO = 54,
+
+          /* UEM */
+          UEM_EM_BATTERY_INFO = 55,
+
+          /* gprs em begins */
+          GMM_EM_INFO = 56,
+       //   TCM_EM_EXT_PDP_INFO,
+       //   TCM_EM_INT_PDP_INFO,
+       //   TCM_EM_CONTEXT_INFO, //new
+       //   SNDCP_EM_INFO,
+          LLC_EM_INFO = 57,
+          /* PPP , removed because of no use*/
+          //PPP_EM_INFO,
+          SM_EM_INFO = 58,
+          EM_TCM_INFO_IND = 59,
+
+          MMRR_EM_PLMN_LIST_REQ_STRUCT_INFO = 60,
+          MMRR_EM_PLMN_LIST_CNF_STRUCT_INFO = 61,
+          MMRR_EM_PLMN_SEARCH_REQ_STRUCT_INFO = 62,
+          MMRR_EM_PLMN_SEARCH_CNF_STRUCT_INFO = 63,
+          MMRR_EM_HPLMN_LIST_INFO = 64,
+          MMRR_EM_OPLMN_LIST_INFO = 65,
+          MMRR_EM_STATIC_APPLMN_LIST_INFO = 66,
+          MMRR_EM_DYNAMIC_APPLMN_LIST_INFO = 67,
+
+           /* VT EM Display, 2007/11/30 */
+           /* VT owner comments VT EM enum is not needed in WR8 */
+           //VT_EM_CALL_STATE_INFO = 50, VT_EM_BEGIN = VT_EM_CALL_STATE_INFO,/* vt_em_call_state_choice */
+           //VT_EM_MASTER_SLAVE_STATUS_INFO,     /* vt_em_master_slave_status_choice */
+           //VT_EM_RETRANSMISSION_PROTOCOL_INFO, /* vt_em_retransmission_protocol_choice */
+           //VT_EM_INCOMING_AUDIO_CHANNEL_INFO,  /* vt_em_audio_channel_info_struct */
+           //VT_EM_OUTGOING_AUDIO_CHANNEL_INFO,  /* vt_em_audio_channel_info_struct */
+           //VT_EM_INCOMING_VIDEO_CHANNEL_INFO,  /* vt_em_video_channel_info_struct */
+           //VT_EM_OUTGOING_VIDEO_CHANNEL_INFO,  /* vt_em_video_channel_info_struct */
+           //VT_EM_ADM_MEM_MAX_USED_INFO,        /* kal_uint32 */
+           //VT_EM_STATISTIC_INFO,               /* vt_em_statistic_info_struct */
+           //VT_EM_ROUND_TRIP_DELAY_INFO,        /* kal_uint32 */
+           //VT_EM_INCOMING_XSRP_INFO,           /* vt_em_incoming_xSRP */
+           //VT_EM_OUTGOING_XSRP_INFO,           /* vt_em_outgoing_xSRP */
+           //VT_EM_END = VT_EM_OUTGOING_XSRP_INFO,
+
+          /**
+           * Gibran 20061228
+           * UAS MEME/CSCE measuremnt and cell status structure
+           */
+          MMRR_EM_PLMN_LOSS_INFO_STRUCT_INFO = 68,
+          MMRR_EM_PLMN_SEARCH_CNF_INFO_STRUCT_INFO = 69,
+          /* URR common Range 1, from enum 70 to 169.
+             it's used for both FDD and TDD */
+          FDD_EM_URR_3G_GENERAL_STATUS_IND = 70, URR_EM_INFO_BEGIN = FDD_EM_URR_3G_GENERAL_STATUS_IND,
+          /* Put 1st XXX_STATUS_IND_STRUCT_INFO in front of XXX_EM_INFO_BEGIN
+             in order to show enum_name in XXX_STATUS_IND_STRUCT_INFO not in XXX_EM_INFO_BEGIN. */
+
+          EM_SIBE_3G_SIB_IND_STRUCT_INFO = 71,
+          TDD_EM_URR_3G_GENERAL_STATUS_IND = 72,
+          FDD_EM_CSCE_SERV_CELL_IND_STRUCT_INFO = 75,
+          FDD_EM_CSCE_NEIGH_CELL_IND_STRUCT_INFO = 76,
+          FDD_EM_CSCE_R_STATUS_IND_STRUCT_INFO = 77,
+          FDD_EM_CSCE_H_STATUS_IND_STRUCT_INFO = 78,
+          FDD_EM_CSCE_APBCR_STATUS_IND_STRUCT_INFO = 79,
+          FDD_EM_CSCE_MEAS_RULE_STATUS_IND_STRUCT_INFO = 80,
+          FDD_EM_CSCE_MULTIPLE_PLMN_IND_STRUCT_INFO = 81,
+          TDD_EM_CSCE_SERV_CELL_IND_STRUCT_INFO = 82,
+          TDD_EM_CSCE_NEIGH_CELL_IND_STRUCT_INFO = 83,
+          TDD_EM_CSCE_R_STATUS_IND_STRUCT_INFO = 84,
+          TDD_EM_CSCE_H_STATUS_IND_STRUCT_INFO = 85,
+          TDD_EM_CSCE_APBCR_STATUS_IND_STRUCT_INFO = 86,
+          TDD_EM_CSCE_MEAS_RULE_STATUS_IND_STRUCT_INFO = 87,
+          TDD_EM_CSCE_MULTIPLE_PLMN_IND_STRUCT_INFO = 88,
+
+           /*SIM*/
+          EM_SIM_MONITOR_EVENT_INFO = 89,
+
+          EM_TDD_MEME_INFO_DCH_UMTS_CELL_INFO = 90, TDD_MEME_EM_INFO_BEGIN = EM_TDD_MEME_INFO_DCH_UMTS_CELL_INFO,
+          EM_TDD_MEME_INFO_DCH_GSM_CELL_INFO = 91,
+          EM_TDD_MEME_INFO_DCH_LTE_CELL_INFO = 92,
+          EM_TDD_MEME_INFO_EVENT_TYPE_1_PARAMETER_STRUCT_INFO = 93,
+          EM_TDD_MEME_INFO_EVENT_TYPE_2_PARAMETER_STRUCT_INFO = 94,
+          EM_TDD_MEME_INFO_EVENT_TYPE_3_PARAMETER_STRUCT_INFO =95,
+       //   EM_MEME_INFO_EVENT_TYPE_4_PARAMETER_STRUCT_INFO,
+       //   EM_MEME_INFO_EVENT_TYPE_5_PARAMETER_STRUCT_INFO,
+       //   EM_MEME_INFO_EVENT_TYPE_6_PARAMETER_STRUCT_INFO,
+       //   EM_MEME_INFO_DCH_H_SERVING_CELL_INFO,
+       //   EM_TDD_MEME_INFO_DCH_3G_BLER_INFO = 96,
+          EM_TDD_MEME_INFO_GSM_CELL_INFO =97, //for CMCC FT Tool
+          EM_TDD_MEME_INFO_LTE_CELL_INFO =98, //for CMCC FT Tool
+       //   EM_MEME_INFO_FACH_LTE_CELL_INFO = 100,
+          EM_TDD_MEME_INFO_REPORT_INFO = 99,
+          TDD_MEME_EM_INFO_END = TDD_MEME_EM_INFO_BEGIN + 15,
+
+          /* Call Information */
+          EM_CALL_INFO_IND = 106,
+
+          /* SIP Information */
+          EM_IMC_SIP_INFO_IND = 107,
+
+          MMRF_EM_MIPI_HW_INFO = 108,
+
+          EM_RRCE_TGPS_STATUS_IND= 110,
+          EM_SLCE_SRNCID_STATUS_IND= 111,
+
+          /* WO: 112 ~ 129 */
+          EM_WO_INFO_BEGIN = 112,
+          EM_WO_IKE_SRCPORT_INFO = EM_WO_INFO_BEGIN,
+          EM_WO_IKE_NATT_SRCPORT_INFO = 113,
+          EM_WO_IKE_DECRYPT_INFO_ADD = 114,
+          EM_WO_IKE_DECRYPT_INFO_DEL = 115,
+          EM_WO_ESP_DECRYPT_INFO_ADD = 116,
+          EM_WO_ESP_DECRYPT_INFO_DEL = 117,
+          EM_WO_DPD_INTERVAL_INFO = 118,
+          EM_WO_INFO_END = EM_WO_INFO_BEGIN + 17,
+
+          EM_UAS_3G_TDD128_HANDOVER_SEQUENCE_IND = 130,
+
+          EM_RRCE_3G4_REDIR_EVENT = 131,
+          EM_RRCE_KPI_STATUS_IND = 132,
+          TDD_EM_RRCE_CONN_STATUS_IND = 133,
+
+          /* SIM */
+          EM_SIM_APDU_INFO = 135,
+
+          EM_SLCE_PS_DATA_RATE_STATUS_IND = 140,
+          EM_RRCE_NW_PEER_MSG_INFO = 150,
+          EM_RRCE_RACH_FAIL_IND = 151,
+          EM_RRCE_MO_RLF_IND = 152,
+          EM_RRCE_3G3_HO_FAIL_IND = 153,
+          EM_RRCE_3G2_HO_FAIL_IND = 154,
+          EM_RRCE_DCH_STATE_CONFIGURATION_STATUS_IND = 155,
+          EM_RRCE_FACH_STATE_CONFIGURATION_STATUS_IND = 156,
+          EM_RRCE_CS_OVER_HSPA_STATUS_IND = 157,
+          EM_RRCE_3G_SECURITY_CONFIGURATION_INFO_IND = 158,
+          EM_RRCE_FD_CONFIGURATION_STATUS_IND = 159,
+          EM_RRCE_HSPA_CONFIG_IND = 160,   /* MOLY00100048, Jack Chu,  EM_RRCE_HSPA_CONFIG_IND == 160 */
+          EM_RRCE_RLF_IND = 161,  /* __ALPS02506878_SUPPORT__ */
+          EM_RRCE_3G_CELL_UARFCN_DL_UL_INFO_IND = 162,
+          URR_EM_INFO_END = EM_RRCE_3G_CELL_UARFCN_DL_UL_INFO_IND,
+
+          /* LBS: 163 ~ 169 */
+          EM_LBS_BEGIN = 163,
+          EM_LBS_GPS_OPEN_STATISTIC = EM_LBS_BEGIN,
+          EM_LBS_LR_STATISTIC = 164,
+          EM_LBS_AP_SETTING = 165,
+          EM_LBS_END = 169,
+
+          /* __UL1_EM_MODE__ */
+          UL1_EM_HS_DSCH_CONFIGURATION_INFO = 170, UL1_EM_INFO_BEGIN = UL1_EM_HS_DSCH_CONFIGURATION_INFO,
+          UL1_EM_EDCH_CONFIGURATION_INFO = 171,
+          UL1_EM_CPC_CONFIGURATION_INFO = 172,
+          UL1_EM_SECONDARY_HS_CONFIGURATION_STATUS_INFO = 173,
+          UL1_EM_PRIMARY_HS_DSCH_BLER_INFO = 174,
+          UL1_EM_SECONDARY_HS_DSCH_BLER_INFO = 175,
+          UL1_EM_EDCH_ACK_RATE_INFO = 176,   UL1_EM_INFO_END = UL1_EM_EDCH_ACK_RATE_INFO,  /* for backward compatibility */
+          UL1_EM_PRX_DRX_MEASUREMENT_INFO = 177,
+          /* HSDSCH info group  */
+          UL1_EM_HSPA_INFO_GROUP = 178,
+          UL1_EM_TAS_INFO = 179,
+          UL1_EM_RADIO_LINK_SYNC_STATUS = 180,
+          UL1_EM_UL1_RXD_STATUS = 181, /* already ported */
+          UL1_EM_UL1_RAS_INFO = 182,
+          UL1_EM_FS_UARFCN_INFO = 184,
+
+
+          /* __UL2_EM_MODE__ */
+          UL2_EM_ADM_POOL_STATUS_IND_STRUCT_INFO = 185, UL2_EM_INFO_BEGIN = UL2_EM_ADM_POOL_STATUS_IND_STRUCT_INFO,
+          UL2_EM_PS_DATA_RATE_STATUS_IND_STRUCT_INFO = 186,
+          UL2_EM_HSDSCH_RECONFIG_STATUS_IND_STRUCT_INFO = 187,
+          UL2_EM_URLC_EVENT_STATUS_IND_STRUCT_INFO = 188,
+          UL2_EM_3G_BLER_IND_STRUCT_INFO = 189,
+          UL2_EM_WCDMA_RLC_STATS_STRUCT_INFO = 190,
+          UL2_EM_URLC_LAYER_TPUT_INFO = 191,
+          /* UMAC new EM Arch */
+          /***HSUPA SI***/
+          UL2_EM_HSUPA_SI_IND_STRUCT_INFO = 192,
+          /***HSUPA SI***/
+
+          /* UMAC EM 2015 */
+          UL2_EM_UMAC_DCH_INFO = 193,
+          UL2_EM_UMAC_EDCH_INFO = 194,
+          UL2_EM_UMAC_HSDSCH_INFO = 195,
+          UL2_EM_URLC_ATT_RLC_STATISTICS_INFO = 196,
+          UL2_EM_URLC_ATT_RLC_RESET_INFO = 197,
+          UL2_EM_UMAC_PCH_CRC_ERR_INFO = 198,
+          UL2_EM_UMAC_PCH_INFO = 199,
+          UL2_EM_UMAC_LCHID_TRCH_MAPPING_INFO = 200,
+          UL2_EM_INFO_END = UL2_EM_UMAC_LCHID_TRCH_MAPPING_INFO,
+
+          /*ERRC_EM_MODE, here is the start of errc em info definition*/
+          ERRC_EM_MOB_MEAS_INTRARAT_INFO = 210, ERRC_EM_INFO_BEGIN = ERRC_EM_MOB_MEAS_INTRARAT_INFO,
+          ERRC_EM_MOB_MEAS_INTERRAT_UTRAN_INFO = 211,
+          ERRC_EM_MOB_MEAS_INTERRAT_GERAN_INFO = 212,
+          ERRC_EM_AUTOS_CSG_INFO = 213,
+          ERRC_EM_CARRS_EVENT_IND = 214,
+          ERRC_EM_SIB_EVENT_IND = 215,
+          ERRC_EM_MOB_EVENT_IND = 216,
+          ERRC_EM_SEC_PARAM = 217,
+          ERRC_EM_REEST_INFO = 218,
+          ERRC_EM_RECONF_INFO = 219,
+          ERRC_EM_RCM_SIM_STS_INFO = 220,
+          ERRC_EM_SYS_SIB_RX_STS_INFO = 221,
+          ERRC_EM_ERRC_STATE_IND = 222,
+          ERRC_EM_OVER_PROC_DELAY_WARNING = 223,
+          ERRC_EM_LTE_SUPPORTED_BAND_INFO = 224,
+          ERRC_EM_ERRC_KPI_INFO = 225,
+          ERRC_EM_ERRC_CONFIG_INFO = 226,
+
+          ERRC_EM_CONN_INFO = 227,
+
+          ERRC_EM_INFO_END = ERRC_EM_CONN_INFO,
+
+          /* __ESM_EM_MODE__ */
+          ESM_ESM_INFO = 228,
+          ESM_L4C_ESM_INFO = 229,
+
+          /* __EMM_EM_MODE__*/
+          EMM_EM_SEC_INFO = 230, EMM_EM_INFO_BEGIN = EMM_EM_SEC_INFO,
+          EMM_EM_PLMNSEL_INFO = 231,
+          EMM_EM_CONN_INFO = 232,
+          EMM_EM_NASMSG_INFO = 233,
+          EMM_EM_CALL_INFO = 234,
+          EMM_EM_REG_ATTACH_INFO = 235,
+          EMM_EM_REG_DETACH_INFO = 236,
+          EMM_EM_REG_TAU_INFO = 237,
+          EMM_EM_REG_COMMON_INFO = 238,
+          EMM_EM_SV_INFO = 239,
+          EMM_EM_RATBAND_INFO = 240,
+          EMM_EM_TIMERSRV_INFO = 241,
+          EMM_EM_USIMSRV_INFO = 242,
+          EMM_EM_NVMSRV_INFO = 243,
+          EMM_EM_INFO_END = EMM_EM_NVMSRV_INFO,
+
+          EMM_L4C_EMM_INFO = 244,
+
+          EM_EL2_OV_STATUS = 245,
+          EM_EL1_OV_STATUS = 246,
+          EM_QBM_STATUS = 247,
+          EM_UPCM_STATUS = 248,
+
+          /* EL1 */
+          EM_EL1_INFO = 249,
+
+          EM_CSR_STATUS_IND = 250,
+
+          RAC_EM_INFO = 251,
+
+          /* EL2 public status */
+          EM_EL2_PUB_STATUS = 252,
+
+          EMM_L4C_LAI_CHANGE_INFO = 253,
+
+          /*RATCM*/
+          RATCM_EM_23G_RAT_CHANGE_IND = 254, RATCM_EM_INFO_BEGIN = RATCM_EM_23G_RAT_CHANGE_IND,
+
+          EM_EL1_B3B39_INFO = 255,
+
+          RATCM_EM_INFO_END = RATCM_EM_INFO_BEGIN + 20,
+
+          /* L4C */
+          EM_L4C_RAT_CHANGE_IND = 275,
+
+          /* EMAC RACH */
+          EM_EMAC_RACH_TRIGGER = 276,
+          EM_EMAC_RACH_FINISH = 277,
+          EM_EMAC_MSG2_REPORT = 278,
+          EM_EMAC_MSG4_REPORT = 279,
+
+          /* EMAC 500MS */
+          EM_EMAC_OV_STATUS_500 = 280,
+
+          /* EMAC TIMER EXPIRE */
+          EM_EMAC_TIMER_EXPIRE = 281,
+
+          EM_L4C_MDMI_RAT_INFO_IND = 282,
+
+          /* EMAC CONFIG REPORT */
+          EM_EMAC_CONFIG_REPORT = 283,
+
+          /* MD EVENT INFO */
+          EM_L4C_MD_EVENT_INFO = 284,
+
+         /*EMAC RACH for Innowireless EM*/
+          EM_EMAC_RACH_SUCCESS = 285,
+          EM_EMAC_RACH_FAILURE = 286,
+
+          /* EMAC EMBMS */
+          EM_EMAC_EMBMS_REPORT = 287,
+
+          /* EMAC DL TBS REPORT */
+          EM_EMAC_DL_TBS_REPORT = 288,
+
+          /* EMM CSFB status */
+          EMM_L4C_CSFB_INFO = 289,
+
+          /* EL1 CIQ for ATT*/
+          EM_EL1_CIQ_RLF_STATUS_INFO        = 290, EM_EL1_CIQ_INFO_BEGIN = EM_EL1_CIQ_RLF_STATUS_INFO,
+          EM_EL1_CIQ_PUSCH_INFO             = 291,
+          EM_EL1_CIQ_INFO_END               = EM_EL1_CIQ_INFO_BEGIN + 10,
+
+          /* L4C EM to report ECSQ params */
+          EM_L4C_ECSQ_IND = 301,
+
+          /* IPCORE */
+          IPC_EM_UL_THROTTLE_STATUS = 326,
+
+          /*ERRC_EM_MODE, here is the start of errc em info definition of Range 2*/
+          ERRC_EM_SERV_IR_NEIGHBOR_INFO = 327, ERRC_EM_INFO_BEGIN_R2 = ERRC_EM_SERV_IR_NEIGHBOR_INFO,
+          ERRC_EM_IR_REDIR_EVENT = 328,
+          ERRC_EM_IRAT_MEAS_CFG = 329,
+          ERRC_EM_MOB_MEAS_CONFIG_INFO_IND = 330,
+          ERRC_EM_MOB_MEAS_REPORT_INFO_IND = 331,
+          ERRC_EM_MOB_MEAS_INTERRAT_C2K_INFO = 332,
+          ERRC_EM_LTE_RRC_STATE_IND = 333,
+          ERRC_EM_SERVING_INFO = 334,
+          ERRC_EM_PAGING_FAIL = 335,
+          ERRC_EM_RLF_EVENT = 336,
+          ERRC_EM_TIMER_EXPIRY_EVENT = 337,
+          ERRC_EM_HO_EVENT = 338,
+          ERRC_EM_ERRC_SYS_MIB_SIB_READEVENT_INFO = 339,
+          ERRC_EM_SRVCC_BSIC_INFO = 340,
+          ERRC_EM_MFROM_INFO = 341,
+          ERRC_EM_FEATURE_DETECTION = 342,
+          ERRC_EM_SEARCHING_STATE = 343,
+          ERRC_EM_CA_INFO = 344,
+          ERRC_EM_EUTRA_RRC_MESSAGE_S = 345,
+          ERRC_EM_EUTRA_RRC_MESSAGE_M = 346,
+          ERRC_EM_EUTRA_RRC_MESSAGE_L = 347,
+          ERRC_EM_LTE_BAND_TIME = 348,
+          ERRC_EM_REEST_BY_L2 = 349,
+          ERRC_EM_EL1_CONFIG_INFO = 350,
+          ERRC_EM_SRVCC_CELL_INFO = 351,
+          ERRC_EM_SRVCC_HO_FAIL_EVENT =352,
+          ERRC_EM_OOS_EVENT = 353,
+          ERRC_EM_CELL_BLACK_LIST_EVENT = 354,
+          ERRC_EM_INFO_END_R2 = ERRC_EM_CELL_BLACK_LIST_EVENT,
+          ERRC_EM_INFO_END_RESERVED = ERRC_EM_INFO_BEGIN_R2 + 30,
+
+          /* UPCM */
+          EM_UPCM_PS_TPUT_INFO = 358,
+
+          MM_EM_MTC_TIMER_INFO = 359,
+          MM_EM_LU_INFO = 360,
+          MM_EM_RAU_INFO = 361,
+
+          /* USIME capability */
+          USIME_EM_INFO_CAPABILITY = 362, USIME_EM_INFO_BEGIN = USIME_EM_INFO_CAPABILITY,
+          USIME_EM_INFO_END = USIME_EM_INFO_BEGIN + 30,
+
+          MM_EM_MT_CSFB_INFO = 393,
+          MM_EM_REG_REJ_INFO = 394,        // LU, Attach, RAU reject info
+          MM_EM_AUTH_REJ_INFO = 395,       // Auth reject info for MM/GMM
+          MM_EM_AS_FAIL_INFO = 396,        // AS fail info during REG proc
+
+          /* EL2 feature detection */
+          EM_EL2_FEATURE_DETECTION = 397,
+
+          MM_EM_CSFB_STATUS = 398,         // CSFB START /SUCCESSFUL /FAIL
+          MM_EM_MTCS_MTCSFB_STATUS = 399,  //MTCS MT CSFB FAILURES
+
+          /* FDD URR common Range 2, the range should be 400 ~ 599 */
+          /* FDD CSCE Range 2 */
+          FDD_CSCE_EM_INFO_BEGIN_R2 = 400, FDD_URR_EM_INFO_BEGIN_R2 = FDD_CSCE_EM_INFO_BEGIN_R2,
+          FDD_CSCE_EM_INFO_END_R2 = 449,
+          /* FDD RRCE Range 2 */
+          FDD_RRCE_EM_INFO_BEGIN_R2 = 450,
+          FDD_RRCE_EM_INFO_END_R2 = 499,
+          /* FDD MEME Range 2 */
+          EM_FDD_MEME_INFO_DCH_UMTS_CELL_INFO = 500, FDD_MEME_EM_INFO_BEGIN_R2 = EM_FDD_MEME_INFO_DCH_UMTS_CELL_INFO,
+          EM_FDD_MEME_INFO_DCH_GSM_CELL_INFO = 501,
+          EM_FDD_MEME_INFO_DCH_LTE_CELL_INFO = 502,
+          EM_FDD_MEME_INFO_DCH_H_SERVING_CELL_INFO = 503,
+          EM_FDD_MEME_INFO_DCH_3G_BLER_INFO = 504,
+          EM_FDD_MEME_INFO_FACH_LTE_CELL_INFO = 505,
+          EM_FDD_MEME_INFO_EVENT_TYPE_3_PARAMETER_INFO = 506,        // For NVIOT EM MeasCtrl E3x
+          EM_FDD_MEME_INFO_REPORT_INFO = 507,                        // For NVIOT EM MEasRpt E3x
+          FDD_MEME_EM_INFO_END_R2 = 549,
+
+          /* FDD SLCE Range 2 */
+          FDD_SLCE_EM_INFO_BEGIN_R2 = 550,
+          FDD_SLCE_EM_INFO_END_R2 = 559,
+
+          /* FDD SIBE Range 2 */
+          FDD_SIBE_EM_INFO_BEGIN_R2 = 560,
+          FDD_SIBE_EM_INFO_END_R2 = 569,
+
+          /* for other FDD URR modules, 569 ~ 599 */
+
+          FDD_URR_EM_INFO_END_R2 = 599,
+
+
+          /* VDM */
+          EM_VDM_CALL_INFO_IND = 601,
+
+          /* IMC */
+          IMC_EM_IPSEC_INFO_IND = 602, IMC_EM_INFO_BEGIN = IMC_EM_IPSEC_INFO_IND,
+          IMC_EM_IMC_INFO_IND = 603,
+          IMC_EM_BEARER_INFO_IND = 604,
+          IMC_EM_REG_INFO_IND = 605,
+          IMC_EM_SMS_INFO_IND = 606,
+          IMC_EM_CALL_INFO_IND = 607,
+          IMC_EM_CONF_INFO_IND = 608,
+          IMC_EM_SRVCC_INFO_IND = 609,
+          IMC_EM_PCSCF_INFO_IND = 610,
+          IMC_EM_MEDIA_INFO_IND = 611,
+          IMC_EM_CALL_DROP_IND = 613,
+          IMC_EM_INFO_END = IMC_EM_INFO_BEGIN + 20,
+
+          /* __EMM_EM_MODE__ Range 2, the range should be 625 ~ 629*/
+          EMM_EM_REG_EVENT_INFO = 625, EMM_EM_INFO_RANGE_2_BEGIN = EMM_EM_REG_EVENT_INFO,
+          EMM_EM_TIMER_EXPIRY_INFO = 626,
+          EMM_EM_EMM_STATE_INFO = 627,
+          EMM_EM_SEC_EVENT_INFO = 628,
+          EMM_EM_TIMERSRV_TIMER_START_INFO = 629,
+          EMM_EM_INFO_RANGE_2_END = EMM_EM_TIMERSRV_TIMER_START_INFO,
+
+          EM_SPEECH_INFO_BEGIN = 630,  EM_SPEECH_INFO_SPH_CODEC = EM_SPEECH_INFO_BEGIN,
+          EM_SPEECH_INFO_END = 649,
+
+          /* NWSEL */
+          NWSEL_EM_TIMER_INFO = 650,
+          NWSEL_EM_INFO_BEGIN = NWSEL_EM_TIMER_INFO,
+          NWSEL_EM_PLMN_LIST_REQ_INFO = 651,
+          NWSEL_EM_PLMN_LIST_CNF_INFO = 652,
+          NWSEL_EM_PLMN_SEARCH_REQ_INFO = 653,
+          NWSEL_EM_HPLMN_INFO_INFO = 654,
+          NWSEL_EM_OPLMN_INFO_INFO = 655,
+          NWSEL_EM_STATIC_APPLMN_INFO = 656,
+          NWSEL_EM_DYNAMIC_APPLMN_INFO = 657,
+          NWSEL_EM_EUTRAN_DISABLE_INFO = 658,
+          NWSEL_EM_INFO_END = NWSEL_EM_INFO_BEGIN+30,
+
+          /* Abnormal event for smart logging phase2 */
+          /* Naming format: EM_ABNORMAL_EVENT_(MOD)_(NAME) */
+          EM_ABNORMAL_EVENT_RAC_NO_SERVICE = 681,
+
+          /* LTECSR */
+          LTECSR_EM_RTP_CODEC = 682,
+          LTECSR_EM_RTP_PACKET_LOSS = 683,
+          LTECSR_EM_RTP_ONE_WAY_DELAY = 684,
+          LTECSR_EM_RTP_JITTER = 685,
+          LTECSR_EM_RTP_JITTER_BUFFER_DELAY = 686,
+          LTECSR_EM_RTP_OTA_MSG = 687,
+          LTECSR_EM_SESSION_STAT = 688,
+          LTECSR_EM_XMIT_PKT = 689,
+          LTECSR_EM_RECV_PKT = 690,
+          LTECSR_EM_XMIT_STAT = 691,
+          LTECSR_EM_RECV_STAT = 692,
+          LTECSR_EM_RTP_INFO = 693,
+          LTECSR_EM_RTCP_INFO = 694,
+          LTECSR_EM_RTP_EVENT = 695,
+
+          /* LPP 696 ~699 */
+          LPP_EM_MSG_STATUS_STATISTICS = 696,
+          LPP_EM_MSG_INFO = 697,
+          LPP_EM_INFO_END = 699,
+
+          /* TDD URR common Range 2, the range should be 700 ~ 899
+             before put TDD URR EM enum below, please make sure relative function already consider the enum range,
+             e.g. TDD_RRC_HandleEmUpdateReq() should cover enum 700 ~ 899. */
+          TDD_URR_EM_INFO_BEGIN_R2 = 700,
+          TDD_URR_EM_INFO_END_R2 = 749,
+
+          /* C2K: 750 ~ 899 */
+          EM_C2K_INFO_BEGIN = 750,
+
+          /* C2K EVDO L1 750~769 */
+          EM_EVL1_INFO_BEGIN = EM_C2K_INFO_BEGIN,
+          EM_EVL1_GENERAL_INFO = EM_EVL1_INFO_BEGIN,
+          EM_EVL1_TXAGC_POWER_INFO = 751,
+          EM_EVL1_CELL_SWITCH_INFO = 752,
+          EM_EVL1_RXAGC_INFO = 753,
+          EM_EVL1_AFC_INFO = 754,
+          EM_EVL1_MBP_SECTOR_INFO = 755,
+          EM_EVL1_FMP_FINGER_INFO = 756,
+          EM_EVL1_TIMING_TRACK_STATUS = 757,
+          EM_EVL1_SCH_STATUS = 758,
+          EM_EVL1_ACC_DATA_RATE_INFO = 759,
+          EM_EVL1_TRAFFIC_RRI_VALUE_INFO = 760,
+          EM_EVL1_FMP_SECTOR_INFO = 761,
+          EM_EVL1_SCH_PILOT_UPDATE_INFO = 762,
+          EM_EVL1_SCH_RESULT_INFO = 763,
+          EM_EVL1_INFO_END = EM_EVL1_INFO_BEGIN + 19,
+
+          /* XL1: 770 ~ 789 */
+          EM_XL1_INFO_BEGIN = 770,
+          EM_XL1_STATUS_INFO = EM_XL1_INFO_BEGIN,
+          EM_XL1_MEAS_INFO = 771,
+          EM_XL1_MAIN_RXAGC_INFO = 772,
+          EM_XL1_DIV_RXAGC_INFO = 773,
+          EM_XL1_RAKE_INFO = 774,
+          EM_XL1_CRC_INFO = 775,
+          EM_XL1_TX_PATH_INFO = 776,
+          EM_XL1_TX_AGC_INFO = 777,
+          EM_XL1_AFC_INFO = 778,
+          EM_XL1_MMAFC_INIT_FOE_INFO = 779,
+          EM_XL1_TAS_INFO = 780,
+          EM_XL1_TIMING_LOOP_INFO = 781,
+          EM_XL1_INFO_END = EM_XL1_INFO_BEGIN + 19,
+
+          /* HSC: 790 ~ 809 */
+          EM_C2K_HSC_INFO_BEGIN = 790,
+          EM_C2K_RTBA_CHANNEL_STATUS_INFO = EM_C2K_HSC_INFO_BEGIN,
+          EM_C2K_DO_SPAGE_STATE_INFO = 791,
+          EM_C2K_HSC_MPA_STATUS_INFO = 792,
+          EM_C2K_LL1A_STATE_MODE_INFO = 793,
+          EM_C2K_LL1A_STANDBY_GAP_INFO = 794,
+          EM_C2K_LL1A_ACTIVE_GAP_INFO = 795,
+          EM_C2K_HSC_INFO_END = EM_C2K_HSC_INFO_BEGIN + 19,
+
+          /* XL3: 810 ~ 824 */
+          EM_XL3_INFO_BEGIN = 810,
+          EM_XL3_CP_STATUS = EM_XL3_INFO_BEGIN,
+          EM_XL3_SLOTTED_MODE_INFO = 811,
+          EM_XL3_CP_EVENTS = 812,
+          EM_1XRTT_CALL_EVENTS = 813,
+          EM_C2K_RSVAS_INFO = 814,
+          EM_XL3_PAGING_INFO = 815,
+          EM_XL3_SET_INFO = 816,
+          EM_XL3_SYSTEM_SEARCH_INFO = 817,
+          EM_XL3_CALL_FAIL_REASON = 818,
+          EM_XL3_INFO_END = EM_XL3_INFO_BEGIN + 14,
+
+          /* EVL3: 825 ~ 839 */
+          EM_EVL3_INFO_BEGIN = 825,
+          EM_EVL3_STATE = EM_EVL3_INFO_BEGIN,
+          EM_EVL3_SERVING_CELL_INFO = 826,
+          EM_EVL3_SLOTTED_MODE_INFO = 827,
+          EM_EVL3_ACCESS_PROCEDURE_INFO = 828,
+          EM_EVL3_CP_EVENTS = 829,
+          EM_EVL3_SYSTEM_SEARCH_INFO = 830,
+          EM_EVL3_INFO_END = EM_EVL3_INFO_BEGIN + 14,
+
+          /* EVL2: 840~849 */
+          EM_EVL2_INFO_BEGIN = 840,
+          EM_EVL2_FWD_CHANNEL_INFO = EM_EVL2_INFO_BEGIN,
+          EM_EVL2_REV_TRAFFIC_INFO = 841,
+          EM_EVL2_ACCESS_STATE_INFO = 842,
+          EM_EVL2_RTM3_T2P_INFO = 843,
+          EM_EVL2_INFO_END = EM_EVL2_INFO_BEGIN + 9,
+
+          /* XL2 :850~859*/
+          EM_XL2_INFO_BEGIN = 850,
+          EM_XL2_REV_STATE  = EM_XL2_INFO_BEGIN,
+          EM_XL2_ACH_PROBE_INFO = 851,
+          EM_XL2_VOICE_RATE_INFO = 852,
+          EM_XL2_RLP_INFO = 853,
+          EM_XL2_PS_RATE_INFO = 854,
+          EM_XL2_SCH_ASSIGNED_RATE = 855,
+          EM_XL2_INFO_END = EM_XL2_INFO_BEGIN + 9,
+
+          /* C2K HLP: 860 ~ 879*/
+          EM_C2K_HLP_INFO_BEGIN = 860,
+          EM_C2K_HLP_TIMER_STATUS = EM_C2K_HLP_INFO_BEGIN,
+          EM_C2K_HLP_CAM_STATE = 861,
+          EM_C2K_HLP_NSPE_STATE = 862,
+          EM_C2K_HLP_PDN_STATUS = 863,
+          EM_C2K_HLP_PPPHA_STATUS = 864,
+          EM_C2K_HLP_PPP_STATUS = 865,
+          EM_C2K_HLP_RM_BUFQ_INFO = 866,
+          EM_C2K_HLP_UM_BUFQ_INFO = 867,
+          EM_C2K_HLP_PACKET_INFO = 868,
+          EM_C2K_HLP_ABNORMAL_EVENT_INFO = 869,
+          EM_C2K_HLP_INFO_END = EM_C2K_HLP_INFO_BEGIN + 19,
+
+          /* C2K_L4(CVAL): 880 ~ 899 */
+          EM_C2K_L4_INFO_BEGIN = 880,
+          EM_C2K_L4_RTT_RADIO_INFO = EM_C2K_L4_INFO_BEGIN,
+          EM_C2K_L4_RTT_INFO = 881,
+          EM_C2K_L4_RTT_SCH_INFO = 882,
+          EM_C2K_L4_RTT_STAT_INFO = 883,
+          EM_C2K_L4_RTT_SERVING_NEIGHBR_SET_INFO = 884,
+          EM_C2K_L4_EVDO_SERVING_INFO = 885,
+          EM_C2K_L4_EVDO_ACTIVE_SET_INFO = 886,
+          EM_C2K_L4_EVDO_CAND_SET_INFO = 887,
+          EM_C2K_L4_EVDO_NGHDR_SET_INFO = 888,
+          EM_C2K_L4_EVDO_FL_INFO = 889,
+          EM_C2K_L4_EVDO_RL_INFO = 890,
+          EM_C2K_L4_EVDO_STATE_INFO = 891,
+          EM_C2K_L4_SPRINT_XRTT_INFO = 892,
+          EM_C2K_L4_SPRINT_EVDO_INFO = 893,
+          EM_C2K_L4_INFO_END = 899,
+          EM_C2K_INFO_END = EM_C2K_L4_INFO_END,
+
+          /* GMSS: 900 ~ 919 */
+          GMSS_EM_INFO_BEGIN = 900,
+          GMSS_EM_WORLD_PHONE_INFO = GMSS_EM_INFO_BEGIN,
+          GMSS_EM_INFO_END = GMSS_EM_WORLD_PHONE_INFO+19,
+
+          /* EL1 MDMI for VzW*/
+          EM_EL1_STATUS_CSR_RPT_INFO        = 921, EM_EL1_MDMI_INFO_BEGIN = EM_EL1_STATUS_CSR_RPT_INFO,
+          EM_EL1_STATUS_SRV_MEAS_RPT_INFO   = 922,
+          EM_EL1_STATUS_PBCH_RPT_INFO       = 923,
+          EM_EL1_STATUS_PCFICH_RPT_INFO     = 924,
+          EM_EL1_STATUS_PDCCH_RPT_INFO      = 925,
+          EM_EL1_STATUS_PDSCH_RPT_INFO      = 926,
+          EM_EL1_STATUS_PHICH_RPT_INFO      = 927,
+          EM_EL1_STATUS_PMCH_RPT_INFO       = 928,
+          EM_EL1_STATUS_DCI_RPT_INFO        = 929,
+          EM_EL1_STATUS_PUCCH_RPT_INFO      = 930,
+          EM_EL1_STATUS_PUCCH_CSI_RPT_INFO  = 931,
+          EM_EL1_STATUS_PUSCH_RPT_INFO      = 932,
+          EM_EL1_STATUS_PUSCH_CSI_RPT_INFO  = 933,
+          EM_EL1_STATUS_SRS_RPT_INFO        = 934,
+          EM_EL1_STATUS_CELLTIME_RPT_INFO   = 935,
+          EM_EL1_STATUS_SR_CFG_INFO         = 936,
+          EM_EL1_STATUS_PRACH_INFO          = 937,
+          EM_EL1_STATUS_RACH_INFO           = 938,
+          EM_EL1_STATUS_PCH_INFO            = 939,
+          EM_EL1_STATUS_TA_INFO             = 940,
+          EM_EL1_STATUS_PHR_INFO            = 941,
+          EM_EL1_STATUS_DL_TPUT_INFO        = 942,
+          EM_EL1_STATUS_UL_TPUT_INFO        = 943,
+          EM_EL1_STATUS_CSR_INFO            = 944,
+          EM_EL1_MDMI_INFO_END              = EM_EL1_MDMI_INFO_BEGIN + 25,
+
+          /* EPDCP */
+          EM_EPDCP_DATA_INACTV_IND = 947,
+
+          /* GL1: 950 ~ 959 */
+          GL1_EM_TAS_INFO = 950,
+          GL1_EM_RXD_INFO = 951,
+
+          /* TDD L1 */
+          TDD_EM_L1_TAS_INFO = 960, TDD_EM_L1_INFO_BEGIN = TDD_EM_L1_TAS_INFO,
+          TDD_EM_L1_INFO_END = TDD_EM_L1_TAS_INFO + 4,
+
+          EMM_L4C_REJECT_INFO = 965,
+          EMM_L4C_TIMER_INFO = 966,
+          EMM_L4C_CALL_INFO = 967,
+
+          /*EL1*/
+          EM_EL1_STATUS_PDSCH_INFO = 970,
+
+          RAC_EM_NETWORK_TYPE_INFO = 971,
+
+          /* ERLC */
+          EM_ERLC_DATA_STALL = 972,
+
+          /* LTECSR Range 2, the range should be 975 ~ 979 */
+          LTECSR_EM_RTP_PERIODIC_RPT = 975,
+
+       /*================C2K_XCAL start====================*/
+         /* C2K XCAL related EMs, maximum 30 EMs supported. */
+         EM_C2K_XCAL_INFO_BEGIN = 980,
+         EM_C2K_XCAL_OTA_EVENT_INFO = EM_C2K_XCAL_INFO_BEGIN,
+         EM_C2K_XCAL_OTA_FDSCH_INFO = 981,
+         EM_C2K_XCAL_OTA_RDSCH_INFO = 982,
+         /* New C2K EMs should be added before  EM_C2K_XCAL_INFO_LAST, */
+         EM_C2K_XCAL_INFO_LAST = EM_C2K_XCAL_OTA_RDSCH_INFO,
+         EM_C2K_XCAL_INFO_END = EM_C2K_XCAL_INFO_BEGIN + 29,
+         /*================C2K_XCAL end====================*/
+
+          /* D2/DDM: 1016-1023 */
+          EM_DDM_INFO_BEGIN = 1016,
+          EM_DDM_W2LHO_EVENT_INFO = EM_DDM_INFO_BEGIN,
+          EM_DDM_L2WHO_EVENT_INFO = 1017,
+          EM_DDM_IP_INFO = 1020,
+          EM_DDM_LAST_ERROR_CODE_INFO = 1021,
+          EM_DDM_INFO_END = EM_DDM_INFO_BEGIN + 7, /* 1023 */
+
+   NUM_OF_EM_INFO,
+   INVALID_EM_INFO = 0x7fffffff //end tag force this enum 4 bytes, for alignment purpose. Don't remove
+   /*
+    * MP branches: please add "EM type id" in em_info_enum.h.
+    * Please remember to modify MD_COMMON\EM\em_info_enum.h for main TRUNK ex: LR11/LR12/UMOLY/UMOLYA
+    */
+} em_info_enum;
+
+typedef enum
+{
+    EM_TX_ANT_L_ANT    = 0, // L_ANT
+    EM_TX_ANT_U_ANT    = 1, // U_ANT
+    EM_TX_ANT_L_ANT_A  = 2, // L_ANT'
+    EM_TX_ANT_INVALID  = 0xFF
+} em_tx_ant_enum;
+
+
+typedef enum
+{
+    EM_TAS_VERSION_1_0     = 0,
+    EM_TAS_VERSION_2_0     = 1,
+    EM_TAS_VERSION_INVALID = 0xFF
+} em_tas_version_enum;
+
+
+typedef struct
+{
+    /* PWR info */
+    kal_int16  prach_tx_power_ave;
+    kal_int16  pucch_tx_power_ave;
+    kal_int16  pusch_tx_power_ave;
+    kal_int16  srs_tx_power_ave;
+
+    /* Tx report */
+    kal_int16  tm;
+    kal_int16  phr;
+    kal_int16  ta;
+
+    /* UL info */
+    kal_uint32 UL_Tput;
+    kal_int16  UL_Imcs;
+    kal_int16  UL_rb;
+    kal_int16  UL_block;
+    kal_int16  UL_bler;
+    kal_uint16 UL_retx_rate;
+
+   /* TAS info */
+    kal_int16   tx_ant;
+    kal_int8   UL_Mod;
+
+    /*RJIL requirement*/
+    kal_uint8   srs_bw_ave;
+    kal_int16   pucch_tx_power_ave_fmt[9]; //0:FMT1 1:FMT1A 2:FMT1B 3:FMT2 4:FMT2_extCP 5:FMT2A 6:FMT2B 7:FMT3 8:FMT1B_CS
+    kal_bool    hop_en;
+    kal_int8    puschPrb0;
+    kal_int8    puschPrb1;
+
+    /*Power scaling*/
+    kal_int16  pucch_tx_pwr;
+    kal_int16  pucch_tx_pwr_out;
+    kal_int16  pusch_tx_pwr;
+    kal_int16  pusch_tx_pwr_out;
+    kal_int16  ul_ca_pucch_tx_pwr_out;
+    kal_int16  ul_ca_pusch_tx_pwr_out;
+
+    /* TAS Info */
+    em_tx_ant_enum  tx_ant_type;
+    kal_int16       rsrp_l_ant;      // L_ANT: -255: disable, -140 ~ 18 (dBm)
+    kal_int16       rsrp_u_ant;      // U_ANT: -255: disable, -140 ~ 18 (dBm)
+    kal_int16       rsrp_l_ant_a;    // L_ANT' -255: disable, -140 ~ 18 (dBm)
+    kal_int16       tx_power;        // -50...33
+    kal_int16       el1_dat_scenario_index;
+
+    kal_uint16  ul_grant_cnt;
+    kal_uint16  cqi_req_cnt;
+    kal_int16   total_tx_power_ave;
+
+    /* PUCCH format statistics */
+    kal_uint16  pucch_f1_cnt;       // Standalone SR count
+    kal_uint16  pucch_f1a_cnt;      // Probable SR + 1 bit HARQ count
+    kal_uint16  pucch_f1b_cnt;      // Probable SR + 2 bit HARQ count
+    kal_uint16  pucch_f2_cnt;       // Standalone CSI over PUCCH count
+    kal_uint16  pucch_f2a_cnt;      // CSI + 1 bit HARQ count
+    kal_uint16  pucch_f2b_cnt;      // CSI + 2 bit HARQ count
+    kal_uint16  pucch_f2_ecp_cnt;   // CSI with extended CP
+    kal_uint16  pucch_f3_cnt;       // Format 3 count
+    kal_uint16  pucch_f1b_cs_cnt;   // Format 1b with CS count
+    kal_uint16  pucch_sr_cnt;       // Overall SR count
+
+    /* TITAN Info */
+    kal_int16   curr_fi;
+    kal_int16   curr_gi;
+    kal_int16   num_tpc_fi;
+    kal_int16   num_tpc_gi;
+    kal_int16   avg_ul_retx;
+
+    /* TAS Info */ // This is request by OPPO
+    kal_uint8   tas_status;         // TAS status: 0: disable/ 1: enable
+    kal_uint8   force_tx_ant;       // TAS force tx ant status: 0: disable/ 1: enable
+    kal_uint8   force_tx_idx;       // TAS force tx ann index: 0~7 according to antenna state
+
+    kal_int16   pcmax;
+} em_el1_ul_status_struct;
+
+typedef struct
+{
+    /* DL Qual indicator */
+    kal_int16  dl_rssi[2]; // -255: disable, -140 ~ 18 (dBm)
+    kal_int16  dl_rsrp[2]; // -255: disable, -140 ~ 18 (dBm)
+    kal_int16  dl_rsrq[2]; //
+    kal_int16  dl_sinr[2];
+    kal_int16  rsrp;
+    kal_int16  rsrq;
+    kal_int16  sinr;
+    kal_int16  rsSNR;
+
+    /* Rx report */
+    kal_int16  tm;
+    kal_int16  cqi_cw0;
+    kal_int16  cqi_cw1;
+    kal_int16  ri;
+
+    /* DL info */
+    kal_uint32 DL_Tput;
+    kal_uint32 DL_Tput_cw0;
+    kal_uint32 DL_Tput_cw1;
+    kal_int16  DL_Imcs;
+    kal_int16  DL_rb;
+    kal_int16  DL_block;
+    kal_int16  DL_bler;
+    kal_int8  DL_Mod0;
+    kal_int8  DL_Mod1;
+
+    /* MCH info */
+    kal_uint32 MCH_Tput;
+    kal_int16  MCH_block;
+    kal_int16  MCH_bler;
+
+    // PDSCH info
+    kal_uint16 pdsch_tc_rnti;
+    kal_uint16 pdsch_c_rnti;
+    kal_uint16 pdsch_sps_rnti;
+    kal_uint16 pdsch_avg_tbs;
+    kal_uint16 dl_grant_cnt;
+    kal_int8   dl_carrier_idx;
+    kal_int8   dl_mcs0;
+    kal_int8   dl_mcs1;
+    kal_int8   dl_pmi0;
+    kal_int8   dl_pmi1;  // Not used in 90 as well. Can be used to differentiate 1CW and 2CW scenario in future.
+
+    // PDCCH info
+    kal_int8   pdcch_dci;
+    kal_uint16 pdcch_agg_lv[4];
+    kal_uint16 pdcch_sps_rnti;
+    kal_uint16 pdcch_ra_rnti;
+    kal_uint16 tpc_pucch_rnti;
+    kal_uint16 tpc_pusch_rnti;
+    kal_uint16 pdcch_p_rnti;
+    kal_uint16 pdcch_si_rnti;
+
+    // For 93 KPI
+    kal_int16  kpi_DL_bler[2];
+
+    //For 91 Titan request
+    kal_int16  avg_dl_grant;
+    kal_int16  dl_sm_ratio;
+
+    /* MCH info */
+    kal_int16  MCH_sf_skip_cnt;
+
+    /* DL Qual indicator */
+    kal_int16  sir;
+
+    /* DL tb Number*/
+    kal_uint8   DL_TB;
+
+    /* rxpath_sum for RSRP/RSRQ/SNR as Mohamed' request */
+    kal_int16    rsrp_l1_rxpath_sum_dBm;     /*rx0 + rx1  RSRP dBm*/
+    kal_int16    rsrq_l1_rxpath_sum_dB;      /*rx0 + rx1  RSRQ dB*/
+    kal_int16    snr_l1_rxpath_sum_dB;       /*rx0 + rx1  SNR dB*/
+
+    // For LG
+    kal_int16  DL_bler_harq[15];
+    kal_int16  DL_rb_tb1;
+    kal_int16  DL_rb_tb2;
+
+    kal_uint8  rsrq_decimal;
+    // For AT&T
+    kal_uint16 DL_Mod_time[4];
+} em_el1_dl_status_struct;
+
+typedef struct
+{
+    /* TPC info */
+    kal_uint8 pa_mode[RPT_LTE_TX_CC_MAX];
+    kal_uint8 pa_idx[RPT_LTE_TX_CC_MAX];
+    kal_int16 pa_gain[RPT_LTE_TX_CC_MAX];
+    kal_uint8 temper_idx[RPT_LTE_TX_CC_MAX];  //temperature idx
+    kal_int16 temper_comp[RPT_LTE_TX_CC_MAX]; //temperature compensation power for PA
+    kal_int16 cmeas_rf[RPT_LTE_TX_CC_MAX];    //close loop compensation
+    kal_int16 ppa_dbm[RPT_LTE_TX_CC_MAX];     //DDPC report(antenna power)
+
+    /* RF info */
+    kal_int16 rf_gain_absolute[RPT_LTE_RX_CC_MAX][AGC_RX_ANT_NUM];
+
+    /* Power info */
+    kal_int16  mpr[RPT_LTE_TX_CC_MAX];
+    kal_int16  a_mpr[RPT_LTE_TX_CC_MAX];
+    kal_int16  p_cmax[RPT_LTE_TX_CC_MAX];
+    kal_int16 main_ant_sar[RPT_LTE_TX_CC_MAX]; // S(9,7)
+    kal_int16 div_ant_sar[RPT_LTE_TX_CC_MAX];  // S(9,7)
+
+    kal_int16 bb_gain[RPT_LTE_TX_CC_MAX];
+    kal_int16 rf_gain[RPT_LTE_TX_CC_MAX];     //PGA gain
+    kal_uint8 dc2dc_lvl[RPT_LTE_TX_CC_MAX];   //VP
+} em_el1_tpc_rf_status_struct;
+
+typedef struct
+{
+    /* DL info */
+    kal_int16  DL_block;
+    kal_int16  DL_nack_cnt;
+    kal_int16  DL_bler;
+    kal_uint8  fail_rate_ind;
+} em_el1_dl_pdsch_status_struct;
+
+typedef struct
+{
+    kal_uint16                         phyCellId;
+    kal_uint32                         earfcn;        /* [0..262143], 65535 is invalid to indicate ARFCN-ValueEUTRA-v9a0 present */
+    kal_int64                          rstd_microsec;
+}em_el1_mpc_otdoa_measured_nbr_cell_em_struct;
+
+
+typedef struct
+{
+    kal_uint8                           numMeasuredNbrCell;
+    em_el1_mpc_otdoa_measured_nbr_cell_em_struct  measuredNbrCell[EM_OTDOA_MAX_NBR_CELL_LIST_NUM_TOTAL];
+} em_el1_mpc_otdoa_struct;
+
+typedef struct
+{
+    /* cell info */
+    kal_uint8  band;
+    kal_uint8  ant_port;
+    kal_uint8  dl_bw;       // 100kHz
+    kal_uint8  ul_bw;       // 100kHz
+    kal_uint8  tdd_cfg;     // TDD: 0~6, FDD: 0xFF
+    kal_uint8  sp_cfg;      // TDD: 0~9, FDD: 0xFF
+    kal_uint8  tm;          // 0,1~9
+    kal_int8   ul_cc_idx;   //-1,0~(ul_cc_max-1)
+    kal_int16  pci;         // 0~503
+    EARFCN     earfcn;
+    EARFCN     ul_earfcn;
+    kal_uint16 dlFreq;      // 100kHz
+    kal_uint16 ulFreq;      // 100kHz
+    kal_bool   enable_64qam;
+    kal_uint8  ue_category;
+    kal_uint8  sr_period;   //ms
+    kal_uint8  main_ant_swap; // Main Antenna swap information
+    kal_uint8  rx_antenna_config;
+    kal_uint8  rx_div_status;
+    em_el1_mpc_otdoa_struct otdoa_info;
+    kal_uint8  dl_bw_rb;
+    kal_uint8  ul_bw_rb;
+    kal_uint32 dl_max_throughput;
+    kal_uint32 ul_max_throughput;
+} em_el1_cell_info_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum            em_info;
+    kal_uint8               dl_cc_count;
+    kal_uint8               ul_cc_count;
+    em_el1_cell_info_struct cell_info[RPT_LTE_RX_CC_MAX];
+    em_el1_dl_status_struct dl_info[RPT_LTE_RX_CC_MAX];
+    em_el1_ul_status_struct ul_info[RPT_LTE_TX_CC_MAX];
+    em_tas_version_enum     tas_version;
+    em_el1_tpc_rf_status_struct tpc_rf_info;
+} em_el1_status_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum            em_info;
+    em_el1_dl_pdsch_status_struct dl_info[RPT_LTE_RX_CC_MAX];
+} em_el1_status_pdsch_ind_struct;
+
+
+typedef enum
+{
+    EM_CRC_FAIL                 = 0,
+    EM_CRC_PASS                 = 1
+} em_dl_crc_enum;
+
+typedef enum
+{
+    EM_FDD                      = 0,
+    EM_TDD                      = 1
+} em_duplex_enum;
+
+typedef enum
+{
+    EM_COMMON_SPACE             = 0,
+    EM_UE_SPECIFIC_SPACE        = 1
+} em_dci_srch_space;
+
+typedef enum
+{
+    EM_PCC                      = 0,
+    EM_SCC1                     = 1,
+    EM_SCC2                     = 2
+} em_carrier_idx_enum;
+
+typedef enum
+{
+    EM_Bandwidth_1_4            = 1,
+    EM_Bandwidth_3              = 2,
+    EM_Bandwidth_5              = 3,
+    EM_Bandwidth_10             = 4,
+    EM_Bandwidth_15             = 5,
+    EM_Bandwidth_20             = 6
+} em_BandWidth_enum;
+
+typedef enum
+{
+    EM_CCE_AGG_LV1              = 0,
+    EM_CCE_AGG_LV2              = 1,
+    EM_CCE_AGG_LV4              = 2,
+    EM_CCE_AGG_LV8              = 3
+} em_cce_agg_lv_enum;
+
+typedef enum
+{
+    EM_PDCCH_FMT0               = 0,
+    EM_PDCCH_FMT1               = 1,
+    EM_PDCCH_FMT1A              = 2,
+    EM_PDCCH_FMT1B              = 3,
+    EM_PDCCH_FMT1C              = 4,
+    EM_PDCCH_FMT1D              = 5,
+    EM_PDCCH_FMT2               = 6,
+    EM_PDCCH_FMT2A              = 7,
+    EM_PDCCH_FMT2B              = 8,
+    EM_PDCCH_FMT2C              = 9,
+    EM_PDCCH_FMT2D              = 10,
+    EM_PDCCH_FMT3               = 11,
+    EM_PDCCH_FMT3A              = 12,
+    EM_PDCCH_FMT4               = 13,
+    EM_PDCCH_INVALID            = 255
+} em_pdcch_fmt_enum;
+
+typedef enum
+{
+    EM_DCI_FMT0                 = 0,
+    EM_DCI_FMT1                 = 1,
+    EM_DCI_FMT1A                = 2,
+    EM_DCI_FMT1B                = 3,
+    EM_DCI_FMT1C                = 4,
+    EM_DCI_FMT1D                = 5,
+    EM_DCI_FMT2                 = 6,
+    EM_DCI_FMT2A                = 7,
+    EM_DCI_FMT3                 = 8,
+    EM_DCI_FMT3A                = 9
+} em_dci_fmt_enum;
+
+typedef enum
+{
+    EM_dciSuc                   = 1,
+    EM_dciErr                   = 2
+} em_dci_stat_enum;
+
+typedef enum
+{
+    EM_PHICH_NACK               = 0,
+    EM_PHICH_ACK                = 1
+} em_phich_val_enum;
+
+typedef enum
+{
+    EM_PUCCH_FMT1               = 0,
+    EM_PUCCH_FMT1A              = 1,
+    EM_PUCCH_FMT1B              = 2,
+    EM_PUCCH_FMT2               = 3,
+    EM_PUCCH_FMT2A              = 4,
+    EM_PUCCH_FMT2B              = 5
+} em_pucch_fmt_enum;
+
+typedef enum
+{
+    EM_DL_TM_MODE_DISABLED      = 0,
+    EM_DL_TM_MODE_1             = 1,
+    EM_DL_TM_MODE_2             = 2,
+    EM_DL_TM_MODE_3             = 3,
+    EM_DL_TM_MODE_4             = 4,
+    EM_DL_TM_MODE_5             = 5,
+    EM_DL_TM_MODE_6             = 6,
+    EM_DL_TM_MODE_7             = 7,
+    EM_DL_TM_MODE_8             = 8,
+    EM_DL_TM_MODE_9             = 9,
+    EM_DL_TM_MODE_10            = 10,
+    EM_DL_TM_MODE_INVALID       = 255
+} em_dl_tm_mode_enum;
+
+typedef enum
+{
+    EM_mode10                   = 0,
+    EM_mode11                   = 1,
+    EM_mode20                   = 2,
+    EM_mode21                   = 3
+} em_pucch_rpt_mode_enum;
+
+typedef enum
+{
+    EM_subBandCqiFeedback       = 0,
+    EM_wideBandCqiPmiFeedback   = 1,
+    EM_riFeedback               = 2,
+    EM_widebandCqiFeedback      = 3
+} em_pucch_rpt_type_enum;
+
+typedef enum
+{
+    EM_UL_BPSK                  = 0,
+    EM_UL_QPSK                  = 1,
+    EM_UL_QAM16                 = 2,
+    EM_UL_QAM64                 = 3
+} em_pusch_mcs_enum;
+
+typedef enum
+{
+    EM_FREQ_HOP_DISABLED        = 0,
+    EM_FREQ_HOP_INTER_SF        = 1,
+    EM_FREQ_HOP_INTRA_INTER_SF  = 2,
+    EM_FREQ_HOP_INVALID         = 255
+} em_pusch_freq_hop_enum;
+
+typedef enum
+{
+    EM_semiPersistent           = 0,
+    EM_dynamic                  = 1,
+    EM_rachMsg3                 = 2
+} em_pusch_type_enum;
+
+typedef enum
+{
+    EM_modeAperiodicRm12        = 0,
+    EM_modeAperiodicRm20        = 1,
+    EM_modeAperiodicRm22        = 2,
+    EM_modeAperiodicRm30        = 3,
+    EM_modeAperiodicRm31        = 4
+} em_pusch_rpt_mode_enum;
+
+typedef enum
+{
+    EM_NoSrs                    = 0,
+    EM_UpPtsSymbol0             = 1,
+    EM_UpPtsSymbol1             = 2,
+    EM_BothUpPtsSymbols         = 3
+} em_srs_uppts_enum;
+
+typedef enum
+{
+    EM_SRS_Type0                = 0,
+    EM_SRS_Type1Dci0            = 1,
+    EM_SRS_Type1Dci1A2B2C       = 2,
+    EM_SRS_Type1Dci4            = 3
+} em_srs_trig_enum;
+
+typedef enum
+{
+    EM_CYCLE_320                = 0,
+    EM_CYCLE_640                = 1,
+    EM_CYCLE_1280               = 2,
+    EM_CYCLE_2560               = 3
+} em_paging_cyc_enum;
+
+typedef enum
+{
+    EM_fourT                    = 0,
+    EM_twoT                     = 1,
+    EM_oneT                     = 2,
+    EM_one2T                    = 3,
+    EM_one4T                    = 4,
+    EM_one8T                    = 5,
+    EM_one16T                   = 6,
+    EM_one32T                   = 7
+} em_drx_nb_enum;
+
+typedef enum
+{
+    EM_T310_STOP                = 0,
+    EM_T310_START               = 1,
+    EM_T310_EXPIRE              = 2,
+    EM_T310_INVALID             = 255
+} em_t310_status_enum;
+
+
+
+typedef enum
+{
+    EM_DL_QPSK                  = 0,
+    EM_DL_QAM16                 = 1,
+    EM_DL_QAM64                 = 2,
+    EM_DL_QAM256                = 3,
+    EM_DL_INVALID               = 255
+} em_dl_mod_enum;
+
+
+typedef struct
+{
+    kal_bool                        tbEn;
+    kal_uint8                       Imcs;
+    em_dl_mod_enum                  mcs;
+    kal_uint8                       rv;
+    kal_uint8                       ndi;
+    kal_uint8                       tbIndex;
+    kal_uint32                      tbsize;
+    kal_uint8                       dupPacket;
+    kal_bool                        harqComb;
+    //pdsch 3
+    em_dl_crc_enum                  tbCrc;
+    kal_uint16                      cbCrc;
+    kal_uint8                       cw_idx;
+    kal_uint8                       reRxNum;                        // 1~8
+    kal_uint16                      cbSizePlus;                     // 0~6168
+    kal_uint8                       numCbPlus;                      // 0~13
+    kal_uint8                       turboDecMaxIterNum;
+    kal_uint8                       turboDecIterNum;
+    kal_bool                        earlyEndAlgm;
+} em_PdschTb_struct;
+
+typedef struct
+{
+    kal_uint8                       numRBs;      //pdsch 1,2
+    kal_uint8                       numLayers;   //pdsch 2
+    kal_uint8                       numTBs;      //pdsch 2
+    kal_uint8                       harqId;      //pdsch 1,3
+    em_dl_rnti_enum                 rntiType;
+    kal_uint16                      rntiValue;
+    em_PdschTb_struct               PdschTb[2];
+} em_PdschRlt_struct;
+
+typedef struct
+{
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+    kal_uint16                      pci;
+
+    kal_uint8                       cc_idx;//pdsch 3
+    kal_uint8                       ueCat;//pdsch 3
+    kal_uint8                       tranMode;//pdsch 3
+    kal_uint8                       mimoRi;                     // num of tb
+    kal_uint8                       pmchId;                     // 0~255
+    kal_uint8                       areaId;                     // 0~255
+    em_PdschRlt_struct              PdschRlt[5];
+} el1_em_PdschRpt_struct;
+
+typedef struct
+{
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+    kal_uint16                      pci;
+    kal_uint8                       cc_idx;
+    kal_uint8                       ulDlCfg;                        // 0~6:TDD
+    //ltePhyPdcch 1
+    em_dl_rnti_enum                 rntiType[9];
+    em_cce_agg_lv_enum              cceAggLv[9];
+    kal_bool                        newDl[9];
+    em_dci_srch_space               srchSpace[9];                   // 0: common, 1: ue-specific
+    kal_uint16                      payloadSize[9];                 // pi/si/ra/c,tc,sps
+    kal_uint8                       spsType;                        // 1:rel, 2:acv, 3:cfg, 4:retx
+    //ltePhyPdcch 2
+    kal_uint8                       numDlTbs[9];                    // 0~3, number of DL TBs
+    //ltePhyPdcch 3
+    em_pdcch_fmt_enum               dciFormat[9];
+    kal_uint8                       strtCce[9];                     // 0~86
+    kal_bool                        dciStatus[9];
+} el1_em_PdcchRpt_struct;
+
+typedef struct
+{
+    //ltePhyPhich 1, 3
+    kal_bool                        phichEn;
+    em_phich_val_enum               phichRlt;
+    //ltePhyPhich 3
+    kal_uint8                       spreadCode;                     // 0~7
+    kal_uint8                       groupNum;                       // 0~31
+} em_PhichRlt_struct;
+
+typedef struct
+{
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+    kal_uint16                      pci;
+    em_carrier_idx_enum             cc_idx;
+    kal_uint8                       ulDlCfg;                        //0~6:TDD
+    em_PhichRlt_struct              phichRlt0;
+    em_PhichRlt_struct              phichRlt1;
+} el1_em_PhichRpt_struct;
+
+typedef struct
+{
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+    kal_uint16                      pci;
+    em_pdcch_fmt_enum               dciFormat[9];
+    em_pucch_fmt_enum               txFormat;
+    kal_uint8                       numAck;                         //0~2, number of Harq bits
+    kal_bool                        csiEn[RPT_LTE_RX_CC_MAX];
+    kal_uint8                       numCqi[RPT_LTE_RX_CC_MAX];
+    kal_int8                        pucchTpc[9];
+    kal_int16                       gi;
+    kal_uint8                       digitalGain;                    //0~255, PUCCH digital amplitude gain in dB
+    kal_int8                        txPower;
+    kal_int8                        ActualTxPower;
+    kal_uint8                       pathLoss;
+    kal_uint8                       startRbSlot0;                   //0~110
+    kal_uint8                       startRbSlot1;                   //0~110
+    kal_uint8                       dmrsSeqSlot0;                   //0~29
+    kal_uint8                       dmrsSeqSlot1;                   //0~29
+} em_el1_PucchRpt_struct;
+
+typedef struct
+{
+    kal_bool                        csiEn;
+    kal_uint8                       cc_idx;
+    em_dl_tm_mode_enum              csiTxMode;
+    em_pucch_rpt_mode_enum          csiRptMode;
+    em_pucch_rpt_type_enum          csiRptType;
+    //kal_uint8                       numCqi;
+    kal_uint8                       bpSize;                         //0~4
+    kal_uint8                       bpIndex;                        //0~4
+    kal_uint8                       sbNum;
+    kal_uint8                       ri;
+    kal_uint8                       cqiCw0;
+    kal_uint8                       cqiCw1;
+    kal_uint8                       wbPmi;
+} em_pucchCsiRpt_struct;
+
+typedef struct
+{
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+
+    em_pucchCsiRpt_struct           csiRpt[RPT_LTE_RX_CC_MAX];
+} em_el1_PucchCsiRpt_struct;
+
+typedef struct
+{
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+    kal_uint16                      pci;
+    em_pdcch_fmt_enum               dciFormat;                      // DCI format of the decoded PDCCH
+    kal_int8                        puschTpc;
+    em_pusch_type_enum              puschType;
+    kal_int16                       fi;
+    kal_uint8                       digitalGain;                    //0~255, PUSCH digital amplitude gain in dB
+    kal_int8                        txPower;
+    kal_int8                        ActualTxPower;
+    kal_uint8                       pathLoss;
+    kal_uint8                       rbNum;
+    em_pusch_mcs_enum               ModOrd;
+    kal_uint8                       harqId;
+    kal_uint16                      tbSize;
+    kal_uint8                       retxIndex;                      //1~8, HARQ retransmission number
+    em_pusch_freq_hop_enum          freqHop;
+    //kal_bool                        ackExists;
+    kal_uint8                       numAck;                         //0~7, length of ACK NACK bit
+    //kal_bool                        cqiExists[RPT_LTE_RX_CC_MAX];
+    kal_bool                        csiEn[RPT_LTE_RX_CC_MAX];
+    kal_uint8                       numCqi[RPT_LTE_RX_CC_MAX];      //0~66, length of CQI bit
+    //kal_bool                        riExists[RPT_LTE_RX_CC_MAX];
+    kal_uint8                       numRi[RPT_LTE_RX_CC_MAX];       //0~3, length of RI bit
+    kal_uint8                       startRbSlot0;                   //0~110
+    kal_uint8                       startRbSlot1;                   //0~110
+    kal_uint8                       dmrsSeqSlot0;                   //0~29
+    kal_uint8                       dmrsSeqSlot1;                   //0~29
+} em_el1_PuschRpt_struct;
+
+typedef struct
+{
+    kal_bool                        csiEn;
+    kal_uint8                       cc_idx;
+    em_dl_tm_mode_enum              csiTxMode;
+    em_pusch_rpt_mode_enum          csiRptMode;
+    kal_uint8                       sbNum;
+    kal_uint8                       ri;
+    kal_uint8                       wbCqiCw0;
+    kal_uint8                       wbCqiCw1;
+    kal_uint8                       sizeM;
+    kal_uint8                       snglWbPmi;
+    kal_uint8                       snglMbPmi;
+    kal_uint8                       sbCqiCw0[13];
+    kal_uint8                       sbCqiCw1[13];
+    kal_uint8                       mSbCqiCw0;
+    kal_uint8                       mSbCqiCw1;
+    kal_uint8                       sbSize;
+} em_puschCsiRpt_struct;
+
+typedef struct
+{
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+
+    em_puschCsiRpt_struct           csiRpt[RPT_LTE_RX_CC_MAX];
+} em_el1_PuschCsiRpt_struct;
+
+typedef struct
+{
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+    kal_uint16                      pci;
+    em_carrier_idx_enum             cc_idx;
+    kal_uint8                       cfi;
+} em_el1_PcfichRpt_struct;
+
+typedef struct
+{
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+    kal_uint16                      pci;
+    em_carrier_idx_enum             cc_idx;
+    kal_uint8                       pmchId;
+    kal_uint8                       areaId;
+    //kal_uint8                       numOfRB;
+    kal_uint8                       numRBs;
+    kal_uint8                       numLayers;
+    kal_uint8                       harqId;
+    kal_uint8                       rv;
+    kal_uint8                       ndi;
+    em_dl_crc_enum                  crcRlt;
+    em_dl_rnti_enum                 rntiType;
+    kal_uint8                       tbIndex;
+    kal_uint16                      tbSize;                         // bytes
+    kal_uint8                       Imcs;                           // 0~31
+    //kal_uint8                       numRBs;                         // 0~255 // TBD
+} em_el1_PmchRpt_struct;
+
+typedef struct
+{
+    kal_uint16                      strtSFN;
+    kal_uint8                       strtSubframe;
+    kal_uint32                      strtDlFrameTimeOffst;           // 0~307200, Ts units
+    kal_uint32                      strtUlFrameTimeOffst;           // 0~307200, Ts units
+    kal_uint32                      strtUlTimeAdv;                  // 0~307200, Ts units
+
+    kal_int16                       dlFrameTimeChng;                // -512~511
+    kal_int8                        ulFrameTimeChng;                //  -16~15
+    kal_int8                        timeAdvChng;                    // -128~127
+} em_el1_CellTime_struct;
+
+typedef struct
+{
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+    kal_uint16                      pci;
+    kal_int16                       rsrp;                           // -180~-30
+    kal_int16                       rsrp0;
+    kal_int16                       rsrp1;
+    kal_int16                       rsrq;                           //  -30~ 10
+    kal_int16                       rsrq0;
+    kal_int16                       rsrq1;
+    kal_int16                       rssi;                           // -110~-10
+    kal_int16                       rssi0;
+    kal_int16                       rssi1;
+    kal_int16                       sinr;                           //  -20~ 30
+    kal_int16                       sinr0;
+    kal_int16                       sinr1;
+    EARFCN                          earfcn;
+    kal_uint8                       priority;                       // 0~7, The priority of the layer that the cell resides on
+    kal_bool                        isIdleMode;
+    em_BandWidth_enum               Bandwidth;
+    em_carrier_idx_enum             CarrierType;
+} em_el1_SrvMeasRpt_struct;
+
+#if 0
+typedef struct
+{
+    kal_uint16                      sysFrameNumber;
+    kal_uint8                       subFrameNumber;
+    kal_uint8                       TranMode;
+} em_el1_TranMode_struct;
+
+typedef struct
+{
+    kal_uint16                      sysFrameNumber;
+    kal_uint8                       subFrameNumber;
+    kal_uint8                       mcs;                            // 0~31
+} em_el1_McsValue_struct;
+#endif
+
+
+typedef struct
+{
+    kal_bool                        ueSrsEn;
+    kal_bool                        cellSrsEn;
+    kal_uint8                       strtRb;
+    kal_uint8                       numRb;
+    kal_uint16                      zcRoot;                         // 1~1151
+    em_srs_uppts_enum               upPtsType;
+    //em_srs_trig_enum                srsTrigType;
+} em_srsTxParam_struct;
+
+typedef struct
+{
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+    kal_uint16                      pci;
+    em_carrier_idx_enum             carrierType;
+    em_duplex_enum                  duplexMode[RPT_LTE_RX_CC_MAX];
+    //ltePhyMeasurements 15
+    kal_int8                        srsTxPower;
+    kal_int16                       fi;
+    kal_uint8                       pathLoss;
+    kal_uint8                       srsTxBw;
+    kal_int8                        srsActualTxPower;
+    //ltePhyMeasurements 16
+    em_srs_trig_enum                srsTrigType;
+    kal_uint8                       cycShift;
+    kal_int8                        srsPwrOffst;                 // 0:p-srs,    1:a-srs
+    em_srsTxParam_struct            srsTxParam[2];                  // 0:symbol 1, 1:symbol 2
+} em_el1_SrsRpt_struct;
+
+typedef struct
+{
+    kal_uint8                       mcsIndex;
+    kal_uint8                       cqiRequest;
+    kal_uint8                       startRB[2];
+    kal_uint8                       numRB[2];
+    kal_uint8                       tbSizeIndex;
+    kal_uint8                       modType;
+    kal_bool                        freqHop;                        // 0: disable, 1: enable
+    kal_uint8                       ndi;
+    kal_uint8                       rv;
+    kal_int8                        tpcCmd;
+    kal_uint8                       dmrsCycShift;
+    kal_uint8                       timeToTx;
+} ul_grant_struct;
+
+typedef struct
+{
+    kal_uint16                      pci;
+    em_pdcch_fmt_enum               dlAssgnFmt[7];
+    kal_uint8                       numAck[7];                      // 0~2
+    kal_int8                        tpcCmd[7];
+} dl_assgn_struct;
+
+typedef struct
+{
+    em_duplex_enum                  duplexMode[RPT_LTE_RX_CC_MAX];
+
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+
+    kal_bool                        pdcchOrderVld[RPT_LTE_TX_CC_MAX];
+
+    kal_bool                        ulGrantVld[RPT_LTE_TX_CC_MAX];
+    ul_grant_struct                 ulGrantInfo[RPT_LTE_TX_CC_MAX];
+
+    kal_bool                        tpcVld;
+    em_pdcch_fmt_enum               tpcFmt[2];                      // 0: tpc-pucch, 1: tpc-pusch
+
+    kal_bool                        dlAssgnVld[RPT_LTE_RX_CC_MAX];                  // 2cc
+    dl_assgn_struct                 dlAssgnInfo[RPT_LTE_RX_CC_MAX];                 // 2/tc/spsc -rnti
+} em_el1_DciRpt_struct;
+
+typedef struct
+{
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+    //PSS result
+    kal_int16                       pssQualLev;
+    kal_uint16                      pssPeakPos;                     // 0~10000
+    kal_uint8                       pssIndex;                       // 0~2
+    //SSS result
+    kal_uint16                      pci;
+    kal_int16                       sssQualLev;
+    kal_uint16                      sssFrameBoundary;
+    kal_uint16                      sssCp;
+} em_el1_CsrRpt_struct;
+
+typedef struct
+{
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+    kal_uint16                      pci;
+    EARFCN                          earfcn;
+    kal_uint8                       dlBw;
+    kal_uint16                      payloadSize;
+    kal_uint16                      decSFN;
+    em_dl_crc_enum                  crcRlt;
+    kal_uint8                       numAnt;
+    kal_uint8                       txAntCfg;
+    kal_uint16                      sfnOffst;
+    kal_uint16                      freqOffst;                      // TBD
+    kal_uint16                      tx0Rx0Cir;                      // TBD
+} em_el1_PbchRpt_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    //lteMacKpis 7
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+    kal_uint8                       srPeriod;
+} em_el1_status_sr_cfg_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    //ltePhyPrach 1
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+    kal_int16                       rachTxPwr;
+    kal_uint16                      zadOffSeq;                      //0~837, ZadOFF Sequence Number
+    kal_uint8                       prachCfg;
+    kal_uint8                       preambleFmt;
+    em_duplex_enum                  duplexType;
+    kal_uint8                       maxTxMsg3;
+    kal_uint8                       rarWinSize;
+    kal_bool                        rachRlt;
+} em_el1_status_prach_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    //ltePhyMeasurements 5
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+    kal_uint32                      dlTputVal;
+    kal_uint32                      dlTputCw0;
+    kal_uint32                      dlTputCw1;
+} em_el1_status_dl_tput_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    //ltePhyMeasurements 6
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+    kal_uint32                      ulTputVal;
+} em_el1_status_ul_tput_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    el1_em_PdcchRpt_struct          PdcchRpt[LTE_MAX_DATA_BUF];
+    kal_uint16                      PdcchRpt_num;
+    kal_uint16                      Pdcch_num;
+} em_el1_status_pdcch_rpt_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    //ltePhyPdsch 1
+    el1_em_PdschRpt_struct          PdschRpt[LTE_MAX_DATA_BUF];
+    kal_uint16                      PdschRpt_num;
+    kal_uint16                      Pdsch_num;
+} em_el1_status_pdsch_rpt_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    //ltePhyPhich 1,3
+    el1_em_PhichRpt_struct          PhichRpt[LTE_MAX_DATA_BUF];
+    kal_uint16                      PhichRpt_num;
+} em_el1_status_phich_rpt_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    //ltePhyMeasurements 10, 11
+    em_el1_CsrRpt_struct            CsrRlt[LTE_MAX_DATA_BUF];
+    kal_uint8                       CsrRlt_num;
+} em_el1_status_csr_rpt_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    em_info;
+
+    //Carrier search information
+    EARFCN                          csr_earfcn;
+    kal_uint8                       csr_band;
+} em_el1_status_csr_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    //ltePhyMeasurements 1
+    em_el1_SrvMeasRpt_struct        SrvMeasRpt[LTE_MAX_DATA_BUF];
+    kal_int8                        SrvMeasRpt_num;
+} em_el1_status_srv_meas_rpt_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    //ltePhyPucch 1,3
+    em_el1_PucchRpt_struct          PucchRpt[LTE_MAX_DATA_BUF];
+    kal_uint8                       PucchRpt_num;
+} em_el1_status_pucch_rpt_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    //ltePhyPucch 4
+    em_el1_PucchCsiRpt_struct       PucchCsiRpt[LTE_MAX_DATA_BUF];
+    kal_uint8                       PucchCsiRpt_num;
+} em_el1_status_pucch_csi_rpt_ind_struct;
+
+
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    //ltePhyPusch 1,3
+    em_el1_PuschRpt_struct          PuschRpt[LTE_MAX_DATA_BUF];
+    kal_uint8                       PuschRpt_num;
+} em_el1_status_pusch_rpt_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    //ltePhyPusch 4
+    em_el1_PuschCsiRpt_struct       PuschCsiRpt[LTE_MAX_DATA_BUF];
+    kal_uint8                       PuschCsiRpt_num;
+} em_el1_status_pusch_csi_rpt_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    //ltePhyMeasurements 17
+    em_el1_DciRpt_struct            DciRpt[LTE_MAX_DATA_BUF];
+    kal_uint8                       DciRpt_num;
+} em_el1_status_dci_rpt_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    //ltePhyPmch 3
+    em_el1_PmchRpt_struct           PmchRpt[LTE_MAX_DATA_BUF];
+    kal_uint8                       PmchRpt_num;
+} em_el1_status_pmch_rpt_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    //ltePhyMeasurements 15, 16
+    em_el1_SrsRpt_struct            SrsRpt[LTE_MAX_DATA_BUF];
+    kal_uint8                       SrsRpt_num;
+} em_el1_status_srs_rpt_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    //ltePhyDebug 1
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+    kal_uint32                      strtDlFrmeTimeOffst;            // 0~307200, Ts units
+    kal_uint32                      strtUlFrameTimeOffst;           // 0~307200, Ts units
+    kal_uint32                      strtUlTimeAdv;                  // 0~307200, Ts units
+    kal_int16                       dlFrameTimeChng;                // -512~511
+    kal_int16                       ulFrameTimeChng;                //  -16~15
+    kal_int8                        timeAdvChng;                    // -128~127
+} em_el1_status_celltime_rpt_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    //ltePhyPcfich 3
+    em_el1_PcfichRpt_struct         PcfichRpt[LTE_MAX_DATA_BUF];
+    kal_uint8                       PcfichRpt_num;
+} em_el1_status_pcfich_rpt_ind_struct;
+
+typedef struct
+{
+    kal_uint8                       sequence;                       //    0~63, Preamble sequence index
+    kal_int8                        prachTxPower;                   // -112~23, PRACH tx power
+    kal_uint8                       duplexMode;
+} el1_em_msg1_rpt_struct;
+
+typedef struct
+{
+    kal_uint8                       mcs;
+    kal_uint8                       modType;
+    kal_uint8                       startRb;
+    kal_uint8                       numRb;
+    kal_uint8                       tbSizeIndex;
+} el1_em_msg3_rpt_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+
+    kal_bool                        msg1_valid;
+    el1_em_msg1_rpt_struct          msg1_rpt;
+    kal_bool                        msg3_valid;
+    el1_em_msg3_rpt_struct          msg3_rpt;
+} em_el1_status_rach_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    em_el1_PbchRpt_struct           PbchRpt[LTE_MAX_DATA_BUF];
+    kal_uint8                       PbchRpt_num;
+} em_el1_status_pbch_rpt_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    EARFCN                          earfcn;
+    kal_uint16                      pci;
+    em_paging_cyc_enum              pagCyc;
+    em_drx_nb_enum                  nb;
+    kal_uint16                      ueId;                           // IMSI mod 1024
+    kal_uint8                       drxFrameNumOffst;
+    kal_uint8                       drxSubframeNum;
+} em_el1_status_pch_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    //ltePhyMeasurements 7
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+    kal_int16                       ta_value;
+} em_el1_status_ta_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    //ltePhyMeasurements 8
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+    kal_int8                        phr_value;                      // -23~40
+} em_el1_status_phr_ind_struct;
+
+// CIQ
+typedef struct
+{
+    kal_bool                        wb_rpt_valid;
+    kal_uint8                       sb_rpt_num;
+    kal_uint16                      wb_cqi_dist[16];
+    kal_uint16                      sb_cqi_dist[4][16];
+    kal_uint16                      ri_dist[5];
+    kal_uint16                      pmi_dist[16];
+} el1_em_csi_rpt_struct;
+
+
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    ciq_info;
+    kal_uint32              trig_time;
+    //LT13 - E-UTRA Radio Link Sync Status
+    em_t310_status_enum             t310_status;
+} em_el1_ciq_rlf_status_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    ciq_info;
+    kal_uint32              trig_time;
+
+    //LT12 - E-UTRA PUSCH Transmission Status
+    kal_int16                       total_pwr;
+    kal_int16                       perRB_pwr;
+    kal_uint16                      count_pwr;
+    //CSI info
+    //TBD
+    el1_em_csi_rpt_struct       csi_rpt;
+} em_el1_ciq_pusch_ind_struct;
+
+
+
+
+#endif /* _EM_EL1_PUBLIC_STRUCT_H */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_hspa.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_hspa.cpp
new file mode 100644
index 0000000..3e9638a
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_hspa.cpp
@@ -0,0 +1,182 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include <vendor-ril/telephony/ril.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <cutils/jstring.h>
+#include <log/log.h>
+#include <unistd.h>
+#include <math.h>
+#include  "common.h"
+#include "em/em.h"
+#include "Radio_capability_switch_util.h"
+#include "WorldPhoneUtil.h"
+#include "../util/AtLine.h"
+#if EM_MODE_SUPPORT
+
+#undef LOG_TAG
+#define LOG_TAG "EM_HSPA"
+
+char *hspa_info_mode_array_td[] = {
+    "HSDPA off\n",
+    "HSDPA on\nHSUPA off\n",
+    "HSDPA on\nHSUPA on\n",
+    "HSDPA on\nHSUPA on\n",
+};
+
+char *hspa_info_mode_array_fd[] = {
+    "HSDPA off\n",
+    "HSDPA on\nHSUPA off\n",
+    "HSDPA on\nHSUPA on\nHSPA+ off\n",
+    "HSDPA on\nHSUPA on\nHSPA+ on\n",
+};
+
+const int EVENT_HSPA_INFO = 1;
+//const int EVENT_DC_HSPA_INFO = 2;
+const int EVENT_SET_HSPA = 3;
+#define QUERY_CMD "AT+EHSM?"
+#define SET_CMD "AT+EHSM="
+#define RESPONSE_CMD "+EHSM:"
+int mCurrentEmhspaFlag = 0;
+int hspamode = 0;
+
+void  sendATCommand_ehspa(const char *cmd,int msg)
+{
+    mCurrentEmhspaFlag = msg;
+    emSendATCommand(cmd, Radio_capability_switch_util::get_main_capability_phone_id());
+    return ;
+}
+
+void showHspa(int mode) {
+    RLOGD("showHspa, mode=%d", mode);
+    if (mode < 0 || mode >= 4) {
+        RLOGD("Modem return invalid mode: %d", mode);
+        android::emResultNotify(RET_STRING_HSPA_FAIL);
+        return;
+    }
+    if (WorldPhoneUtil::getModemType() == WorldPhoneUtil::MODEM_TD) {
+        android::emResultNotify(hspa_info_mode_array_td[mode]);
+    } else {
+        android::emResultNotify(hspa_info_mode_array_fd[mode]);
+    }
+}
+
+void parseHspaAtCmd(const char* line) {
+    if (strstr(line, RESPONSE_CMD) != NULL) {
+        AtLine* atLine = new AtLine(line, NULL);
+        int err;
+        atLine->atTokStart(&err);
+        if (err < 0) {
+            RLOGW("this is not a valid response string");
+            return;
+        }
+        int mode = atLine->atTokNextint(&err);
+        if (err < 0) {
+            RLOGW("parse rat fail");
+            return;
+        }
+        showHspa(mode);
+        delete atLine;
+    }
+}
+
+void emHspaAtCmdHandle(char*response, int responselen) {
+    switch (mCurrentEmhspaFlag) {
+        case EVENT_HSPA_INFO:
+        {
+            //parse hspa mode.
+            if ((responselen > 0) && (response != NULL)) {
+                RLOGD("EVENT_HSPA_INFO response: %s\n",response);
+                parseHspaAtCmd(response);
+            }
+            else {
+                android::emResultNotify(RET_STRING_HSPA_FAIL);
+                RLOGD("send fail ");
+            }
+            break;
+        }
+        case EVENT_SET_HSPA:
+        {
+            if ((responselen > 0) && (response != NULL)) {
+                RLOGD("EVENT_SET_HSPA success: %s.\n",response);
+            }
+            else {
+                RLOGD("send fail ");
+            }
+            break;
+        }
+        default:
+            break;
+    }
+}
+
+
+//create thread to send command
+void * emHspaThread(void* arg)
+{
+    char cmd_str[32] = {0};
+    //sprintf(cmd_str,"%s%d,0", SET_CMD,hspamode);
+    //sendATCommand_ehspa(cmd_str,EVENT_SET_HSPA);
+    sendATCommand_ehspa(QUERY_CMD,EVENT_HSPA_INFO);
+    android::unregisterNetwork();
+    //android::emResultNotify(RET_STRING_HSPA_SUCCESS);
+    pthread_exit(0);
+}
+
+int emHspaStart(int argc, int *item)
+{
+    RLOGD("emHspaStart called");
+    if(argc < 1)
+    {
+        RLOGD("emHspaStart: please select mode to test: \
+                0: off, 2: on");
+        android::emResultNotify(RET_STRING_HSPA_FAIL);
+        return -1;
+    }
+    if((item[0] > 1 ) || (item[0] < 0)){
+        RLOGD("emHspaStart: invalid parameter %d",item[0]);
+        android::emResultNotify(RET_STRING_HSPA_FAIL);
+        return -1;
+    }
+    //int modemapping[2] = {0,2};
+    mCurrentEmhspaFlag = 0;
+    //hspamode = modemapping[item[0]];
+    android::registerForATcmdResponse(emHspaAtCmdHandle);
+    pthread_t emhspa_thread;
+    pthread_create(&emhspa_thread,NULL, emHspaThread, NULL);
+    return (0);
+}
+#endif
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_ims.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_ims.cpp
new file mode 100644
index 0000000..048ffa9
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_ims.cpp
@@ -0,0 +1,167 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include <vendor-ril/telephony/ril.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <cutils/jstring.h>
+#include <log/log.h>
+#include <unistd.h>
+#include <math.h>
+#include  "common.h"
+#include "em/em.h"
+#include "Radio_capability_switch_util.h"
+
+#if EM_MODE_SUPPORT
+
+#undef LOG_TAG
+#define LOG_TAG "EM_IMS"
+
+const int MSG_QUERY = 0;
+const int MSG_SET = 1;
+int mCurrentEmimsFlag = 0;
+char mCurrentSettingLabel[32] = {0};
+char mCurrentSettingValue[32] = {0};
+bool fgImsRead = true;
+char retstring[128] = {0};
+
+void sendCommandSet(const char* name, char *value) {
+    mCurrentEmimsFlag = MSG_SET;
+    char cmd_str[64] = {0};
+    sprintf(cmd_str,"AT+ECFGSET=\"%s\",\"%s\"",name,value);
+    emSendATCommand(cmd_str, get_default_sim_all_except_data());
+}
+
+void sendCommandQuery(const char* name) {
+    mCurrentEmimsFlag = MSG_QUERY;
+    char cmd_str[64] = {0};
+    sprintf(cmd_str,"AT+ECFGGET=\"%s\"",name);
+    emSendATCommand(cmd_str,get_default_sim_all_except_data());
+}
+
+char * parseCommandResponse(char * data) {
+   RLOGD("raw data: %s",data);
+   return "";
+}
+
+void emImsAtCmdHandle(char*response, int responselen) {
+    switch (mCurrentEmimsFlag) {
+    case MSG_QUERY:
+    {
+        memset(retstring,0,sizeof(retstring));
+        if ((responselen > 0) && (response != NULL)) {
+            RLOGD("Query success for %s ", mCurrentSettingLabel);
+            RLOGD("%s",response);
+            sprintf(retstring,"%s %s",response,RET_STRING_IMS_SUCCESS);
+        }
+        else {
+            RLOGD("Query failed for %s ", mCurrentSettingLabel);
+            sprintf(retstring,"Query failed for %s %s",mCurrentSettingLabel,RET_STRING_IMS_FAIL);
+        }
+        android::unregisterNetwork();
+        android::emResultNotify(retstring);
+        break;
+    }
+    case MSG_SET:
+    {
+        memset(retstring,0,sizeof(retstring));
+        if ((responselen > 0) && (response != NULL)) {
+            sprintf(retstring,"Set %s=%s successful %s",mCurrentSettingLabel,mCurrentSettingValue,RET_STRING_IMS_SUCCESS);
+            RLOGD("Set successful.");
+        }
+        else {
+            sprintf(retstring,"Set %s=%s failed %s",mCurrentSettingLabel,mCurrentSettingValue,RET_STRING_IMS_FAIL);
+            RLOGD("Set failed.");
+        }
+        android::unregisterNetwork();
+        android::emResultNotify(retstring);
+        break;
+    }
+    default:
+        break;
+    }
+}
+
+
+//create thread to send command
+void * emImsThread(void* arg)
+{
+    if(fgImsRead){
+        sendCommandQuery(mCurrentSettingLabel);
+    }else{
+        sendCommandSet(mCurrentSettingLabel,mCurrentSettingValue);
+    }
+    pthread_exit(0);
+}
+
+int emImsStart(int argc, int *item,char *value)
+{
+    RLOGD("emImsStart called");
+     //init item[0] //common/call/xxx: item[1] property item[2] get/set
+    mCurrentEmimsFlag = 0;
+    if(argc < 3){
+        RLOGD("please select ims get or set : ims get xxx /ims set xxx xx");
+        return -1;
+    }
+    int classid = item[0];
+    int propertyid = item[1];
+    int operatorid = item[2];
+
+    em_arry_t *subarry = &(ims[classid].subarray[propertyid]);
+    RLOGD("IMS property name %s",subarry->name);
+    memset(mCurrentSettingLabel,0,sizeof(mCurrentSettingLabel));
+    switch(operatorid){
+        case 0://get
+        {
+            strncpy(mCurrentSettingLabel,subarry->name,strlen(subarry->name));
+            fgImsRead = true;
+            break;
+        }
+        case 1://set
+        {
+            strncpy(mCurrentSettingLabel,subarry->name,strlen(subarry->name));
+            strncpy(mCurrentSettingValue,value,strlen(value));
+            fgImsRead = false;
+            break;
+        }
+    }
+
+    android::registerForATcmdResponse(emImsAtCmdHandle);
+    pthread_t emimsthread;
+    pthread_create(&emimsthread,NULL, emImsThread, NULL);
+    return (0);
+}
+
+#endif
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_modemtest.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_modemtest.cpp
new file mode 100644
index 0000000..38b9497
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_modemtest.cpp
@@ -0,0 +1,464 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include <vendor-ril/telephony/ril.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <cutils/jstring.h>
+#include <log/log.h>
+#include <unistd.h>
+#include <math.h>
+#include <string>
+#include <vector>
+
+#include "Phone_utils.h"
+#include  "common.h"
+#include "em/em.h"
+#include "Radio_capability_switch_util.h"
+
+#if EM_MODE_SUPPORT
+
+#undef LOG_TAG
+#define LOG_TAG "EM_MODEMTEST"
+
+int mCurrentEmmodemtestFlag = -1; // at cmd handle flag
+
+const int MODEM_NONE = 0;
+const int MODEM_CTA = 1;
+const int MODEM_FTA = 2;
+const int MODEM_IOT = 3;
+const int MODEM_QUERY = 4;
+const int MODEM_OPERATOR = 5;
+const int MODEM_FACTORY = 6;
+const int MODEM_QUERY_CDMA = 7;
+const int MODEM_CDMA = 8;
+const int MODEM_QUERY_CLSC = 9;
+const int MODEM_CLSC = 10;
+
+int mCtaOption = 0;
+int mIotOption = 0;
+int mFtaOption = 0;
+int mOperatorOption = 0;
+int mFactoryOption = 0;
+int mCdmaOption = 0;
+
+int modem_id = -1;
+int modem_option_cnt = -1;
+int modem_option[8] = {0};
+
+static const int EVENT_QUERY_PREFERRED_TYPE_DONE = 1000;
+static const int EVENT_SET_PREFERRED_TYPE_DONE = 1001;
+static const int REBOOT_DIALOG = 2000;
+static const int NETWORK_TYPE = 3; //type 3 means GSM/WCDMA (auto mode) 0 means GSM/WCDMA (WCDMA preferred)
+
+static const int CMD_LENGTH = 6;
+static const int MODE_LENGTH = 3;
+
+//static const String PREFERENCE_GPRS = "com.mtk.GPRS";
+//static const String PREF_ATTACH_MODE = "ATTACH_MODE";
+//static const String PREF_ATTACH_MODE_SIM = "ATTACH_MODE_SIM";
+static const int ATTACH_MODE_ALWAYS = 1;
+static const int ATTACH_MODE_NOT_SPECIFY = -1;
+static const int DOCOMO_OPTION = 1 << 7;
+static const int SOFTBANK_OPTION = 1 << 8;
+//static const String PROP_TEST_CARD = "persist.sys.forcttestcard";
+//static const String PROP_TDD_TEST = "persist.sys.forcttddtest";
+
+static const int IPO_ENABLE = 1;
+static const int IPO_DISABLE = 0;
+
+static const int PCH_DATA_PREFER = 0;
+static const int PCH_CALL_PREFER = 1;
+
+static const int INDEX_SPIRENT = 1;
+static const int FLAG_UNLOCK = 0x200000;
+static const int FLAG_NOT_DETECT_CDMA_CARD = 0x100000;
+
+bool mModemFlag = false;
+int mCurrentMode = 0;
+int mCurrentCmdFlag = 0;
+
+void setCurrentTestFlag(int msg){
+    mCurrentEmmodemtestFlag = msg;
+    return ;
+}
+
+void  sendATCommand_modemtest(const char *cmd,int msg)
+{
+    setCurrentTestFlag(msg);
+    emSendATCommand(cmd, Radio_capability_switch_util::get_main_capability_phone_id());
+    return ;
+}
+
+static void sendATCommandCdma(std::string str, int message) {
+    std::vector<std::string> cmdOri(3);
+    cmdOri[0] = "AT+ECTM=" + str;
+    cmdOri[1] = "";
+    cmdOri[2] = "DESTRILD:C2K";
+    std::vector<std::string> cmds = getCdmaCmdArr(cmdOri);
+    std::string cmd;
+    for (auto s : cmds) {
+        cmd += s;
+    }
+    sendATCommand_modemtest(cmd.c_str(), message);
+    sendATCommand_modemtest("AT+RFSSYNC", -1);
+}
+
+void setCdmaOption() {
+    if (modem_option[0] == INDEX_SPIRENT) {
+        sendATCommandCdma("\"SPIRENT\"", MODEM_CDMA);
+    } else {
+        sendATCommandCdma("\"NONE\"", MODEM_CDMA);
+    }
+}
+void  sendATCommand_modemtest(const char *str,int flag,int msg)
+{
+    char cmd[32] = {0};
+    mCurrentCmdFlag = (mCurrentCmdFlag & 0xFF0000) | flag;
+    sprintf(cmd,"AT+EPCT=%s,%d",str,mCurrentCmdFlag);
+    setCurrentTestFlag(msg);
+    emSendATCommand(cmd,Radio_capability_switch_util::get_main_capability_phone_id());
+    return ;
+}
+
+int setPreferredNetworkType_modemtest(int type)
+{
+    RequestInfo *pRI_preferredNetType = creatRILInfoAndInit(RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, OTHER,
+            (RIL_SOCKET_ID)Radio_capability_switch_util::get_main_capability_phone_id());
+    android::Parcel p;
+    size_t pos =  p.dataPosition();
+    p.writeInt32(1);
+    p.writeInt32(type);
+    p.setDataPosition(pos);
+    pRI_preferredNetType->pCI->dispatchFunction(p, pRI_preferredNetType);
+    return 1;
+}
+void checkNetworkType() {
+    RLOGD("TcheckNetworkType");
+    RequestInfo *pRI_preferredNetType = creatRILInfoAndInit(RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE, OTHER,
+            (RIL_SOCKET_ID)Radio_capability_switch_util::get_main_capability_phone_id());
+    android::Parcel p;
+    pRI_preferredNetType->pCI->dispatchFunction(p, pRI_preferredNetType);
+}
+
+void handleQuery(char* data)
+{
+    if(strstr(data,"+EPCT:") != NULL){
+        char *p = strstr(data,",");
+        if(p != NULL){
+            char mode[3] = {0};
+            char flag[12] = {0};
+            strncpy(mode,p-1,1);
+            char *end = strstr(data,"OK");
+            if(end != NULL){
+                RLOGD("end %s ", end);
+                RLOGD("end len %d ", end - p -1);
+                strncpy(flag,p+1,end - p -1);
+                mCurrentCmdFlag = atoi(flag);
+            }
+            mCurrentMode = atoi(mode);
+            RLOGD("mCurrentMode %d mCurrentCmdFlag %d",mCurrentMode,mCurrentCmdFlag);
+        }
+    }
+    return;
+}
+const char *modem_test_cta_options[] = {
+    "Integrity Check",
+    "RLC TL1",
+    "K1297",
+    "SN Conflict",
+    "CF query",
+    "DLMN lock",
+    "Measurement open",
+    "Disable DPA",
+    "Intra CMR",
+};
+
+const char *modem_test_fta_options[] = {
+    "ANITE",
+    "CRTUG",
+    "CRTUW",
+    "ANRITSU",
+    "CMW500"
+};
+
+void setGprsTransferType(int type) {
+    int property = (type == PCH_DATA_PREFER ? 1 : 0);
+    RLOGD("Change persist.radio.gprs.prefer to %d" ,property);
+    //SystemProperties.set("persist.radio.gprs.prefer", property);
+    char cmd[32];
+    sprintf(cmd,"AT+EGTP=%d",type);
+    sendATCommand_modemtest(cmd,-1);
+    sprintf(cmd,"AT+EMPPCH=%d",type);
+    sendATCommand_modemtest(cmd,-1);
+    //sendATCMD
+}
+void attachOrDetachGprs() {
+    if ((mOperatorOption & DOCOMO_OPTION) != 0 || (mOperatorOption & SOFTBANK_OPTION) != 0) {
+        RLOGD("Attach GPRS for DoCoMo/Softband");
+        //SystemProperties.set("persist.radio.gprs.attach.type", "1");
+        char cmdStr[] = {"AT+EGTYPE=1,1"};
+        sendATCommand_modemtest(cmdStr,-1);
+    } else {
+        RLOGD("Dettach GPRS for DoCoMo/Softband");
+        //SystemProperties.set("persist.radio.gprs.attach.type", "0");
+        char cmdStr[] = {"AT+EGTYPE=0,1"};
+        sendATCommand_modemtest(cmdStr,-1);
+    }
+}
+void turnoffWCMAPreferred(){
+    if(mModemFlag){
+        setCurrentTestFlag(EVENT_SET_PREFERRED_TYPE_DONE);
+        setPreferredNetworkType_modemtest(NETWORK_TYPE);
+    }
+}
+int modemTestProcess(int id,int *whichButton, int ButtonCount)//from onCreate & onCreateDialog
+{
+    switch(id){
+    case REBOOT_DIALOG:
+    {
+        //hint do reboot
+        return 0;
+    }
+    case MODEM_NONE:
+    {
+        sendATCommand_modemtest("0", 0, MODEM_NONE);
+        if (mCurrentMode == MODEM_FTA) {
+            setGprsTransferType(PCH_CALL_PREFER);
+        }
+        break;
+    }
+    case MODEM_CTA:
+    {
+        mCtaOption = 0;
+        for(int i = 0; i < ButtonCount; i++){
+            mCtaOption += (1 << whichButton[i]);
+        }
+        turnoffWCMAPreferred();
+        sendATCommand_modemtest("1", mCtaOption, MODEM_CTA);
+        if (mCurrentMode == MODEM_FTA) {
+            setGprsTransferType(PCH_CALL_PREFER);
+        }
+        break;
+    }
+    case MODEM_FTA:
+    {
+        mFtaOption = 0;
+        for(int i = 0; i < ButtonCount; i++){
+            RLOGD("which button %d",whichButton[i]);
+            mFtaOption += (1 << whichButton[i]);
+        }
+        RLOGD("mFtaOption %x", mFtaOption);
+        turnoffWCMAPreferred();
+        sendATCommand_modemtest("2", mFtaOption, MODEM_FTA);
+        //enableIPO(false);
+        setGprsTransferType(PCH_DATA_PREFER);
+        break;
+    }
+    case MODEM_IOT:
+    {
+        mIotOption = 0;
+        for(int i = 0; i < ButtonCount; i++){
+            mIotOption += (1 << whichButton[i]);
+        }
+        sendATCommand_modemtest("3", mIotOption, MODEM_IOT);
+        if (mCurrentMode == MODEM_FTA) {
+            setGprsTransferType(PCH_CALL_PREFER);
+        }
+        break;
+    }
+    case MODEM_OPERATOR:
+    {
+        mOperatorOption = 0;
+        for(int i = 0; i < ButtonCount; i++){
+            mOperatorOption += (1 << whichButton[i]);
+        }
+        turnoffWCMAPreferred();
+        attachOrDetachGprs();
+        sendATCommand_modemtest("4", mOperatorOption, MODEM_OPERATOR);
+        if (mCurrentMode == MODEM_FTA) {
+            setGprsTransferType(PCH_CALL_PREFER);
+        }
+        break;
+    }
+    case MODEM_CDMA:
+        setCdmaOption();
+        break;
+    case MODEM_FACTORY:
+    {
+        turnoffWCMAPreferred();
+        sendATCommand_modemtest("5", 0, MODEM_FACTORY);
+        if (mCurrentMode == MODEM_FTA) {
+            setGprsTransferType(PCH_CALL_PREFER);
+        }
+        break;
+    }
+    }
+}
+
+const char * getToastString(int what) {
+    switch (what) {
+    case MODEM_NONE:
+        return "MODEM_NONE";
+    case MODEM_CTA:
+        return "MODEM_CTA";
+    case MODEM_FTA:
+        return "MODEM_FTA";
+    case MODEM_IOT:
+        return "MODEM_IOT";
+    case MODEM_OPERATOR:
+        return "MODEM_OPERATOR";
+    case MODEM_FACTORY:
+        return "MODEM_FACTORY";
+    case MODEM_CDMA:
+        return "MODEM_CDMA";
+    default:
+        return "";
+    }
+}
+
+void emModemtestAtCmdHandle(char*response, int responselen) {
+    switch (mCurrentEmmodemtestFlag) {
+        case MODEM_NONE:
+        case MODEM_CTA:
+        case MODEM_FTA:
+        case MODEM_IOT:
+        case MODEM_OPERATOR:
+        case MODEM_FACTORY:
+        case MODEM_CDMA:
+        {
+            if ((responselen > 0) && (response != NULL)) {
+                RLOGD("%s  AT cmd success. %s\n",getToastString(mCurrentEmmodemtestFlag),response);
+            }
+            else {
+                RLOGD("%s  AT cmd failed.\n",getToastString(mCurrentEmmodemtestFlag));
+            }
+            break;
+        }
+        case MODEM_QUERY:
+        {
+            if ((responselen > 0) && (response != NULL)) {
+                RLOGD("Query success. %s\n",response);
+                handleQuery(response);
+            }
+            else {
+                RLOGD("Query fail. ");
+            }
+            break;
+        }
+        case EVENT_QUERY_PREFERRED_TYPE_DONE:
+        {
+            if ((responselen > 0) && (response != NULL)) {
+                int type = -1;
+                //parse currect preferred type
+                type = atoi(response);
+                RLOGD("Get Preferred Type: %d ",type);
+                if (type == 0) {
+                    mModemFlag = true;
+                } else {
+                    mModemFlag = false;
+                }
+            }
+            else {
+                RLOGD("Query preferred type fail ");
+            }
+            break;
+        }
+        case EVENT_SET_PREFERRED_TYPE_DONE:
+        {
+            if ((responselen > 0) && (response != NULL)) {
+                RLOGD("Turn off WCDMA Preferred success\n");
+            }
+            else {
+                RLOGD("Turn off WCDMA Preferred Fail");
+            }
+            break;
+        }
+        default:
+            break;
+    }
+}
+
+void * emModemtestThread(void* arg)
+{
+    RLOGD("Modem Test: %s ",getToastString(modem_id));
+    modemTestProcess(modem_id,modem_option,modem_option_cnt);
+    android::unregisterNetwork();
+    android::emResultNotify(RET_STRING_MODEMTEST_SUCCESS);
+    pthread_exit(0);
+}
+
+int emModemtestStart(int argc, int multicnt,int *item)
+{
+    //item[0]: fta/cta/... item[1] count  item[2]..item[count+1] which part
+    RLOGD("emModemtestStart called");
+    if(argc < 1)
+    {
+        RLOGD("emModemtestStart: please select id to test: \
+            ");
+        android::emResultNotify(RET_STRING_MODEMTEST_FAIL);
+        return -1;
+    }
+    int idmapping[7] = {MODEM_NONE,MODEM_CTA,MODEM_FTA,MODEM_IOT,MODEM_FACTORY,MODEM_FACTORY, MODEM_CDMA};
+    modem_id = idmapping[item[0]];
+    modem_option_cnt = multicnt;
+    modem_option[0] = item[1];
+
+    for(int i = 0; i < modem_option_cnt ; i++){
+        modem_option[i+1] = item[2+i];
+    }
+    modem_option_cnt+=1;
+
+    RLOGD("emModemtestStart modem_option_cnt %d",modem_option_cnt);
+    mCtaOption = 0;
+    mIotOption = 0;
+    mFtaOption = 0;
+    mOperatorOption = 0;
+    mFactoryOption = 0;
+    mCdmaOption = 0;
+    mCurrentEmmodemtestFlag = 0;
+    android::registerForATcmdResponse(emModemtestAtCmdHandle);
+
+    if(modem_id != MODEM_CDMA) {
+        setCurrentTestFlag(EVENT_QUERY_PREFERRED_TYPE_DONE);
+        checkNetworkType();
+        sendATCommand_modemtest("AT+EPCT?",MODEM_QUERY);
+    }
+
+    pthread_t emmodemtest_thread;
+    pthread_create(&emmodemtest_thread,NULL, emModemtestThread, NULL);
+    return (0);
+}
+#endif
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/networkinfo/Content.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/networkinfo/Content.cpp
new file mode 100644
index 0000000..b351b6e
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/networkinfo/Content.cpp
@@ -0,0 +1,153 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include "Content.h"
+#include "../../util/utils.h"
+#include "../../util/ModemCategory.h"
+
+const bool Content::NEW_VALUE = true; //ChipSupport.getChip() >= ChipSupport.MTK_6735_SUPPORT;
+const bool Content::IS_MOLY = ModemCategory::isLteSupport();
+
+/* Item Index */
+constexpr int Content::CELL_INDEX;
+constexpr int Content::CHANNEL_INDEX;
+constexpr int Content::CTRL_INDEX;
+constexpr int Content::RACH_INDEX;
+constexpr int Content::LAI_INDEX;
+constexpr int Content::RADIO_INDEX;
+constexpr int Content::MEAS_INDEX;
+constexpr int Content::CA_INDEX;
+constexpr int Content::CONTROL_INDEX;
+constexpr int Content::SI2Q_INDEX;
+constexpr int Content::MI_INDEX;
+constexpr int Content::BLK_INDEX;
+constexpr int Content::TBF_INDEX;
+constexpr int Content::GPRS_INDEX;
+const int Content::SM_INFO_INDEX = IS_MOLY ? 58 : 63;
+constexpr int Content::URR_3G_GENERAL_INDEX;
+const int Content::MM_INFO_INDEX = NEW_VALUE ? 53 : 21;
+constexpr int Content::GMM_INFO_INDEX;
+const int Content::TCM_MMI_INDEX = NEW_VALUE ? 59 : 27;
+const int Content::CSCE_SERV_CELL_STATUS_INDEX = NEW_VALUE ? 75 : 47;
+const int Content::CSCE_NEIGH_CELL_STATUS_INDEX = NEW_VALUE ? 76 : 48;
+const int Content::CSCE_MULTIPLMN_INDEX = NEW_VALUE ? 81 : 52;
+const int Content::UMTS_CELL_STATUS_INDEX = NEW_VALUE ? 90 : 53;
+const int Content::PERIOD_IC_BLER_REPORT_INDEX = NEW_VALUE ? (IS_MOLY ? 97 : 99) : 62;
+const int Content::URR_UMTS_SRNC_INDEX = NEW_VALUE ? 111 : 64;
+const int Content::PSDATA_RATE_STATUS_INDEX = NEW_VALUE ? 140 : 65;
+const int Content::HSERV_CELL_INDEX = NEW_VALUE ? (IS_MOLY ? 96 : 98) : 61;
+const int Content::HANDOVER_SEQUENCE_INDEX = NEW_VALUE ? 130 : 65;
+const int Content::UL_ADM_POOL_STATUS_INDEX = NEW_VALUE ? 185 : 67;
+const int Content::UL_PSDATA_RATE_STATUS_INDEX = NEW_VALUE ? 186 : 68;
+const int Content::UL_HSDSCH_RECONFIG_STATUS_INDEX = NEW_VALUE ? 187 : 69;
+const int Content::UL_URLC_EVENT_STATUS_INDEX = NEW_VALUE ? 188 : 70;
+const int Content::UL_PERIOD_IC_BLER_REPORT_INDEX = NEW_VALUE ? 189 : 71;
+
+constexpr int Content::CDMA_INDEX_BASE;
+constexpr int Content::CDMA_1XRTT_RADIO_INDEX;
+constexpr int Content::CDMA_1XRTT_INFO_INDEX;
+constexpr int Content::CDMA_1XRTT_SCH_INFO_INDEX;
+constexpr int Content::CDMA_1XRTT_STATISTICS_INDEX;
+constexpr int Content::CDMA_1XRTT_SERVING_INDEX;
+constexpr int Content::CDMA_EVDO_SERVING_INFO_INDEX;
+constexpr int Content::CDMA_EVDO_ACTIVE_SET_INDEX;
+constexpr int Content::CDMA_EVDO_CANDICATE_SET_INDEX;
+constexpr int Content::CDMA_EVDO_NEIGHBOR_SET_INDEX;
+constexpr int Content::CDMA_EVDO_FL_INDEX;
+constexpr int Content::CDMA_EVDO_RL_INDEX;
+constexpr int Content::CDMA_EVDO_STATE_INDEX;
+constexpr int Content::CDMA_EVDO_FORCE_TX_ANT;
+
+// add for LGE
+const int Content::LLC_EM_INFO_INDEX = 57;
+constexpr int Content::UL1_EM_PRX_DRX_MEASURE_INFO_INDEX;
+const int Content::ERRC_EM_SEC_PARAM_INDEX = 217;
+const int Content::ERRC_EM_ERRC_STATE_INDEX = 222;
+const int Content::EMM_L4C_EMM_INFO_INDEX = 244;
+constexpr int Content::EL1TX_EM_TX_INFO_INDEX;
+const int Content::SLCE_VOICE_INDEX = NEW_VALUE ? (IS_MOLY ? 250 : 141) : 80;
+const int Content::SECURITY_CONFIGURATION_INDEX = NEW_VALUE ? (IS_MOLY ? 158 : 157) : 81;
+
+/* Item data size */
+const int Content::CELL_SEL_SIZE = 6;
+const int Content::CH_DSCR_SIZE = 340;
+const int Content::CTRL_CHAN_SIZE = 14;
+const int Content::RACH_CTRL_SIZE = 14;
+const int Content::LAI_INFO_SIZE = 28;
+const int Content::RADIO_LINK_SIZE = 16;
+const int Content::MEAS_REP_SIZE = 1384;
+const int Content::CAL_LIST_SIZE = 260;
+const int Content::CONTROL_MSG_SIZE = 4;
+const int Content::SI2Q_INFO_SIZE = 10;
+const int Content::MI_INFO_SIZE = 8;
+const int Content::BLK_INFO_SIZE = 80;
+const int Content::TBF_INFO_SIZE = 56;
+const int Content::GPRS_GEN_SIZE = 32;
+const int Content::URR_3G_GENERAL_SIZE = 12;
+
+// add for LGE
+const int Content::SLCE_VOICE_SIZE = 1 * 2;
+const int Content::SECURITY_CONFIGURATION_SIZE = 2 * 2;
+
+// LXO, stupid code..
+const int Content::SM_EM_INFO_SIZE = 2204 * 2;
+const int Content::M3G_MM_EMINFO_SIZE = 30 * 2;
+const int Content::GMM_EM_INFO_SIZE = 20 * 2;
+const int Content::M_3G_TCMMMI_INFO_SIZE = 7 * 2;
+const int Content::CSCE_SERV_CELL_STATUS_SIZE = 52 * 2;
+const int Content::CSCE_MULTI_PLMN_SIZE = 37 * 2;
+const int Content::UMTS_CELL_STATUS_SIZE = 772 * 2;
+const int Content::PERIOD_IC_BLER_REPORT_SIZE = 100 * 2;
+const int Content::URR_UMTS_SRNC_SIZE = 2 * 2;
+const int Content::SLCE_PS_DATA_RATE_STATUS_SIZE = 100 * 2;
+const int Content::MEME_HSERV_CELL_SIZE = 8 * 2;
+
+const int Content::HANDOVER_SEQUENCE_SIZE = 16 * 2; // alignment enabled
+const int Content::ADM_POOL_STATUS_SIZE = 32 * 2;
+const int Content::UL2_PSDATA_RATE_STATUS_SIZE = 8 * 2;
+const int Content::UL_HSDSCH_RECONFIG_STATUS_SIZE = 8 * 2;
+const int Content::URLC_EVENT_STATUS_SIZE = 18 * 2;
+const int Content::UL_PERIOD_IC_BLER_REPORT_SIZE = 100 * 2;
+
+const int Content::XGCSCE_NEIGH_CELL_STATUS_SIZE = 520 * 2;
+Content::Content() {
+    // TODO Auto-generated constructor stub
+
+}
+
+Content::~Content() {
+    // TODO Auto-generated destructor stub
+}
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/networkinfo/Content.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/networkinfo/Content.h
new file mode 100644
index 0000000..a027aec
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/networkinfo/Content.h
@@ -0,0 +1,152 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef SRC_EM_NETWORKINFO_CONTENT_H_
+#define SRC_EM_NETWORKINFO_CONTENT_H_
+
+class Content {
+public:
+    Content();
+    virtual ~Content();
+public:
+    static const bool NEW_VALUE;
+    static const bool IS_MOLY;
+
+    /* Item Index */
+    static constexpr int CELL_INDEX = 0;
+    static constexpr int CHANNEL_INDEX = 1;
+    static constexpr int CTRL_INDEX = 2;
+    static constexpr int RACH_INDEX = 3;
+    static constexpr int LAI_INDEX = 4;
+    static constexpr int RADIO_INDEX = 5;
+    static constexpr int MEAS_INDEX = 6;
+    static constexpr int CA_INDEX = 7;
+    static constexpr int CONTROL_INDEX = 8;
+    static constexpr int SI2Q_INDEX = 9;
+    static constexpr int MI_INDEX = 10;
+    static constexpr int BLK_INDEX = 11;
+    static constexpr int TBF_INDEX = 12;
+    static constexpr int GPRS_INDEX = 13;
+
+    static const int SM_INFO_INDEX;
+    static constexpr int URR_3G_GENERAL_INDEX = 70;
+    static const int MM_INFO_INDEX;
+    static constexpr int GMM_INFO_INDEX = 56;
+    static const int TCM_MMI_INDEX;
+    static const int CSCE_SERV_CELL_STATUS_INDEX;
+    static const int CSCE_NEIGH_CELL_STATUS_INDEX;
+    static const int CSCE_MULTIPLMN_INDEX;
+    static const int UMTS_CELL_STATUS_INDEX;
+    static const int PERIOD_IC_BLER_REPORT_INDEX;
+    static const int URR_UMTS_SRNC_INDEX;
+    static const int PSDATA_RATE_STATUS_INDEX;
+    static const int HSERV_CELL_INDEX;
+    static const int HANDOVER_SEQUENCE_INDEX;
+    static const int UL_ADM_POOL_STATUS_INDEX;
+    static const int UL_PSDATA_RATE_STATUS_INDEX;
+    static const int UL_HSDSCH_RECONFIG_STATUS_INDEX;
+    static const int UL_URLC_EVENT_STATUS_INDEX;
+    static const int UL_PERIOD_IC_BLER_REPORT_INDEX;
+
+    static constexpr int CDMA_INDEX_BASE = 300;
+    static constexpr int CDMA_1XRTT_RADIO_INDEX = CDMA_INDEX_BASE + 0;
+    static constexpr int CDMA_1XRTT_INFO_INDEX = CDMA_INDEX_BASE + 1;
+    static constexpr int CDMA_1XRTT_SCH_INFO_INDEX = CDMA_INDEX_BASE + 2;
+    static constexpr int CDMA_1XRTT_STATISTICS_INDEX = CDMA_INDEX_BASE + 3;
+    static constexpr int CDMA_1XRTT_SERVING_INDEX = CDMA_INDEX_BASE + 4;
+    static constexpr int CDMA_EVDO_SERVING_INFO_INDEX = CDMA_INDEX_BASE + 5;
+    static constexpr int CDMA_EVDO_ACTIVE_SET_INDEX = CDMA_INDEX_BASE + 6;
+    static constexpr int CDMA_EVDO_CANDICATE_SET_INDEX = CDMA_INDEX_BASE + 7;
+    static constexpr int CDMA_EVDO_NEIGHBOR_SET_INDEX = CDMA_INDEX_BASE + 8;
+    static constexpr int CDMA_EVDO_FL_INDEX = CDMA_INDEX_BASE + 9;
+    static constexpr int CDMA_EVDO_RL_INDEX = CDMA_INDEX_BASE + 10;
+    static constexpr int CDMA_EVDO_STATE_INDEX = CDMA_INDEX_BASE + 11;
+    static constexpr int CDMA_EVDO_FORCE_TX_ANT = CDMA_INDEX_BASE - 1;
+
+// add for LGE
+    static const int LLC_EM_INFO_INDEX;
+    static constexpr int UL1_EM_PRX_DRX_MEASURE_INFO_INDEX = 177;
+    static const int ERRC_EM_SEC_PARAM_INDEX;
+    static const int ERRC_EM_ERRC_STATE_INDEX;
+    static const int EMM_L4C_EMM_INFO_INDEX;
+    static constexpr int EL1TX_EM_TX_INFO_INDEX = 249;
+    static const int SLCE_VOICE_INDEX;
+    static const int SECURITY_CONFIGURATION_INDEX;
+
+/* Item data size */
+    static const int CELL_SEL_SIZE;
+    static const int CH_DSCR_SIZE;
+    static const int CTRL_CHAN_SIZE;
+    static const int RACH_CTRL_SIZE;
+    static const int LAI_INFO_SIZE;
+    static const int RADIO_LINK_SIZE;
+    static const int MEAS_REP_SIZE;
+    static const int CAL_LIST_SIZE;
+    static const int CONTROL_MSG_SIZE;
+    static const int SI2Q_INFO_SIZE;
+    static const int MI_INFO_SIZE;
+    static const int BLK_INFO_SIZE;
+    static const int TBF_INFO_SIZE;
+    static const int GPRS_GEN_SIZE;
+    static const int URR_3G_GENERAL_SIZE;
+
+// add for LGE
+    static const int SLCE_VOICE_SIZE;
+    static const int SECURITY_CONFIGURATION_SIZE;
+
+// LXO, stupid code..
+    static const int SM_EM_INFO_SIZE;
+    static const int M3G_MM_EMINFO_SIZE;
+    static const int GMM_EM_INFO_SIZE;
+    static const int M_3G_TCMMMI_INFO_SIZE;
+    static const int CSCE_SERV_CELL_STATUS_SIZE;
+    static const int CSCE_MULTI_PLMN_SIZE;
+    static const int UMTS_CELL_STATUS_SIZE;
+    static const int PERIOD_IC_BLER_REPORT_SIZE;
+    static const int URR_UMTS_SRNC_SIZE;
+    static const int SLCE_PS_DATA_RATE_STATUS_SIZE;
+    static const int MEME_HSERV_CELL_SIZE;
+
+    static const int HANDOVER_SEQUENCE_SIZE;
+    static const int ADM_POOL_STATUS_SIZE;
+    static const int UL2_PSDATA_RATE_STATUS_SIZE;
+    static const int UL_HSDSCH_RECONFIG_STATUS_SIZE;
+    static const int URLC_EVENT_STATUS_SIZE;
+    static const int UL_PERIOD_IC_BLER_REPORT_SIZE;
+
+    static const int XGCSCE_NEIGH_CELL_STATUS_SIZE;
+};
+
+#endif /* SRC_EM_NETWORKINFO_CONTENT_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/networkinfo/NetworkInfoUrcParser.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/networkinfo/NetworkInfoUrcParser.cpp
new file mode 100644
index 0000000..a9b3658
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/networkinfo/NetworkInfoUrcParser.cpp
@@ -0,0 +1,1737 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include <log/log.h>
+#include <stdexcept>
+#include "NetworkInfoUrcParser.h"
+#include "Content.h"
+#include "../../util/utils.h"
+#include "../../util/ModemCategory.h"
+
+#undef LOG_TAG
+#define LOG_TAG "EM_NetworkInfoUrcParser"
+
+const int NetworkInfoUrcParser::DATA_OFFSET_2 = 2;
+const int NetworkInfoUrcParser::DATA_OFFSET_4 = 4;
+const int NetworkInfoUrcParser::DATA_OFFSET_6 = 6;
+const int NetworkInfoUrcParser::DATA_OFFSET_8 = 8;
+const int NetworkInfoUrcParser::DATA_FORMAT = 16;
+const int NetworkInfoUrcParser::MAX_DATA_PER_LINE = 7;
+
+const int NetworkInfoUrcParser::TYPE_UINT8 = 0;
+const int NetworkInfoUrcParser::TYPE_UINT16 = 1;
+const int NetworkInfoUrcParser::TYPE_UINT32 = 2;
+const int NetworkInfoUrcParser::TYPE_INT8 = 3;
+const int NetworkInfoUrcParser::TYPE_INT16 = 4;
+const int NetworkInfoUrcParser::TYPE_INT32 = 5;
+const int NetworkInfoUrcParser::TYPE_LONG = 6;
+const int NetworkInfoUrcParser::TYPE_FLOAT = 7;
+const int NetworkInfoUrcParser::TYPE_ALIGNMENT = 8;
+const int NetworkInfoUrcParser::TYPE_STRING = 9;
+
+const bool NetworkInfoUrcParser::ALIGN_MENT_ENABLE = true;
+const bool NetworkInfoUrcParser::GPRS_MODE_ENABLE = true;
+const bool NetworkInfoUrcParser::AMR_SUPPORT_ENABLE = true;
+const bool NetworkInfoUrcParser::FWPNC_LAI_INFO_ENABLE = false;
+const bool NetworkInfoUrcParser::UMTS_R8 = true;
+const bool NetworkInfoUrcParser::WISDOM_EM = true;
+const bool NetworkInfoUrcParser::ADVANCED_EM = true;
+const bool NetworkInfoUrcParser::IS_MOLY = Content::IS_MOLY;
+
+const int NetworkInfoUrcParser::MODEM_FDD = 1;
+const int NetworkInfoUrcParser::MODEM_TD = 2;
+
+NetworkInfoUrcParser::NetworkInfoUrcParser() {
+    // TODO Auto-generated constructor stub
+
+}
+
+NetworkInfoUrcParser::~NetworkInfoUrcParser() {
+    // TODO Auto-generated destructor stub
+}
+
+std::string NetworkInfoUrcParser::get3GUl2EmPsDataRateStatusIndStruct() {
+    parseElement(TYPE_UINT16, "rx_mac_data_rate:");
+    parseElement(TYPE_UINT16, "rx_pdcp_data_rate:");
+    parseElement(TYPE_UINT16, "tx_mac_data_rate:");
+    parseElement(TYPE_UINT16, "tx_pdcp_data_rate:");
+    return mResult;
+}
+std::string NetworkInfoUrcParser::get3Gul2EmHsdschReconfigStatusIndStruct(){
+    for (int i = 0; i < 8; i++) {
+        parseElement(TYPE_UINT8, std::string("reconfig_info") + std::to_string(i) + std::string(":"));
+    }
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::get3GUl2EmUrlcEventStatusIndStruct(){
+    parseElement(TYPE_INT8, "rb_id:");
+    parseElement(TYPE_UINT8, "rlc_action:");
+    parseElement(TYPE_UINT8, "rb_info:--- \nis_srb:");
+    parseElement(TYPE_UINT8, "cn_domain:");
+    parseElement(TYPE_UINT8, "rlc_info:--- \nrlc_mode:");
+    parseElement(TYPE_UINT8, "direction:");
+    parseElement(TYPE_UINT16, "rlc_parameter:--- \npdu_Size:");
+    parseElement(TYPE_UINT16, "tx_window_size:");
+    parseElement(TYPE_UINT16, "rx_window_size:");
+    parseElement(TYPE_UINT8, "discard_mode:");
+    parseElement(TYPE_UINT16, "discard_value:");
+    parseElement(TYPE_UINT8, "flush_data_indicator:");
+    parseElement(TYPE_UINT8, "reset_cause:");
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::get3GUl2EmPeriodicBlerReportInd(){
+    parseElement(TYPE_UINT8, "num_trch:");
+    parseElement(TYPE_ALIGNMENT, "");
+    mResult.append("TrCHBler:--------");
+    for (int i = 0; i < 8; i++) {
+        parseElement(TYPE_UINT8, std::string("TrCHId") + std::to_string(i) + std::string(":"));
+        parseElement(TYPE_UINT32, std::string("TotalCRC") + std::to_string(i) + std::string(":"));
+        parseElement(TYPE_UINT32, std::string("BadCRC")  + std::to_string(i) + std::string(":"));
+    }
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::get3GUl2EmAdmPoolStatusIndStruct() {
+    mResult.append("[dl_adm_poll_info:-----]\n");
+    for (int i = 0; i < 4; i++) {
+        parseElement(TYPE_UINT16, std::string("max_usage_kbytes") + std::to_string(i) + std::string(":"));
+        parseElement(TYPE_UINT16, std::string("avg_usage_kbytes") + std::to_string(i) + std::string(":"));
+    }
+    mResult.append("[ul_adm_poll_info:-----]\n");
+    for (int i = 0; i < 4; i++) {
+        parseElement(TYPE_UINT16, std::string("max_usage_kbytes") + std::to_string(i) + std::string(":"));
+        parseElement(TYPE_UINT16, std::string("avg_usage_kbytes") + std::to_string(i) + std::string(":"));
+    }
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::get3GCsceEMServCellSStatusInd(bool isTdd) {
+    if (!IS_MOLY) {
+        parseElement(TYPE_UINT8, "ref_count:");
+        parseElement(TYPE_UINT16, "msg_len");
+    }
+    parseElement(TYPE_UINT8, "cell_idx: ");
+    parseElement(TYPE_UINT16, "uarfacn_DL: ");
+    parseElement(TYPE_UINT16, "psc: ");
+    parseElement(TYPE_UINT8, "is_s_criteria_satisfied: ");
+    parseElement(TYPE_INT8, "qQualmin: ");
+    parseElement(TYPE_INT8, "qRxlevmin: ");
+    parseElement(TYPE_INT32, "srxlev: ");
+    parseElement(TYPE_INT32, "spual: ");
+    parseElement(TYPE_LONG, "rscp: ");
+    if (!isTdd) {
+        parseElement(TYPE_FLOAT, "ec_no: ");
+    }
+    parseElement(TYPE_UINT16, "cycle_len: ");
+    if (!isTdd) {
+        parseElement(TYPE_UINT8, "quality_measure: ");
+    }
+    parseElement(TYPE_UINT8, "band: ");
+    parseElement(TYPE_INT32, "rssi: ");
+    parseElement(TYPE_UINT32, "cell_identity: ");
+    if (UMTS_R8) {
+        parseElement(TYPE_UINT32, "csg_id: ");
+        parseElement(TYPE_UINT8, "apbcr_priority: ");
+        parseElement(TYPE_UINT8, "sprio_search1: ");
+        parseElement(TYPE_UINT8, "sprio_search2: ");
+        parseElement(TYPE_UINT8, "threshserv_low: ");
+        if (IS_MOLY) {
+            parseElement(TYPE_UINT8, "threshserv_low2: ");
+        }
+    }
+    if (!isTdd) {
+        parseElement(TYPE_UINT8, "multi_plmn_count: ");
+        for (int i = 0; i < 6; i++) {
+            parseElement(TYPE_UINT8, std::string("multi_plmn_id[") + std::to_string(i) + std::string("].mcc: "), 3);
+            parseElement(TYPE_UINT8, std::string("multi_plmn_id[") + std::to_string(i) + std::string("].mnc: "), 3);
+        }
+
+        int lacValid = readIntegerFromByte();
+        if (lacValid != 0) {
+            parseElement(TYPE_UINT16, "lac: ");
+        } else {
+            mResult.append("lac: invalid\n");
+            mOffset += DATA_OFFSET_4;
+        }
+
+        int racValid = readIntegerFromByte();
+        if (racValid != 0) {
+            parseElement(TYPE_UINT8, "rac: ");
+        } else {
+            mResult.append("rac: invalid\n");
+            mOffset += DATA_OFFSET_2;
+        }
+
+        int uraValid = readIntegerFromByte();
+        if (uraValid != 0) {
+            parseElement(TYPE_UINT8, "num_ura_id: ");
+            for (int i = 0; i < 8; i++) {
+                int numBits = readIntegerFromByte();
+                if (numBits == 1) {
+                    parseElement(TYPE_UINT8, std::string("uraIdentity[") + std::to_string(i) + std::string("]: "));
+                    mOffset += DATA_OFFSET_2; // skip high byte
+                } else {
+                    parseElement(TYPE_UINT8, std::string("uraIdentity[") + std::to_string(i) + std::string("]: "), 2);
+                }
+            }
+        } else {
+            mResult.append("ura: invalid\n");
+        }
+    }
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::getxGCsceEMNeighCellSStatusIndStructSize(bool isTdd) {
+    if (!IS_MOLY) {
+        parseElement(TYPE_UINT8, "ref_count:");
+        parseElement(TYPE_UINT16, "msg_len");
+    }
+    parseElement(TYPE_UINT8, "neigh_cell_count:");
+    parseElement(TYPE_UINT8, "operation:");
+    std::string xgType = getValueFromByte(mRawString, mOffset, false);
+    parseElement(TYPE_UINT8, "RAT_type:");
+    parseElement(TYPE_ALIGNMENT, "");
+
+    if (xgType == std::string("1")) {
+        mResult.append("----GSM_neigh_cells----\n");
+        for (int i = 0; i < 16; i++) {
+            parseElement(TYPE_UINT8, std::string("cellidx") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_UINT16, "arfcn");
+            parseElement(TYPE_UINT8, std::string("bsic") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_UINT8, std::string("is_bsic_verified") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_UINT8, std::string("is_s_criteria_saticified") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_UINT8, std::string("freq_band") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_INT8, std::string("qRxlevmin") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_INT32, std::string("srxlev") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_INT32, std::string("rssi") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_INT8, std::string("apbcr_priority") + std::to_string(i)+ std::string(":"));
+            parseElement(TYPE_UINT8, std::string("threshx_high") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_UINT8, std::string("threshx_low") + std::to_string(i)+ std::string(":"));
+            if (IS_MOLY) {
+                parseElement(TYPE_UINT8, std::string("threshx_high2") + std::to_string(i) + std::string(":"));
+                parseElement(TYPE_UINT8, std::string("threshx_low2") + std::to_string(i) + std::string(":"));
+            }
+            parseElement(TYPE_ALIGNMENT, "");
+        }
+    } else if (xgType == std::string("2")) {
+        mResult.append("----LTE_neigh_cells----\n");
+        for (int i = 0; i < 16; i++) {
+            parseElement(TYPE_UINT16, "earfcn");
+            parseElement(TYPE_UINT16, std::string("pci") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_INT32, std::string("rsrp") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_INT32, std::string("rsrq") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_INT32, std::string("Treselection") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_INT8, std::string("apbcr_priority") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_INT16, std::string("qRxlevmin") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_INT8, std::string("qQualMinEUTRA") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_UINT8, std::string("threshx_high") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_UINT8, std::string("threshx_low") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_UINT8, std::string("threshx_high2") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_UINT8, std::string("threshx_low2") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_ALIGNMENT, "");
+        }
+    } else {
+        mResult.append("----3G_neigh_cells----\n");
+        for (int i = 0; i < 16; i++) {
+            parseElement(TYPE_UINT8, std::string("cellidx") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_UINT16, std::string("arfcn_DL"));
+            parseElement(TYPE_UINT16, std::string("psc"));
+            parseElement(TYPE_UINT8, std::string("is_s_criteria_saticified") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_INT8, std::string("qQualmin") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_INT8, std::string("qRxlevmin") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_INT32, std::string("srxlev") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_INT32, std::string("squal") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_LONG, "rscp: ");
+            parseElement(TYPE_INT32, std::string("ec_no") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_INT8, std::string("apbcr_priority") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_UINT8, std::string("threshx_high") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_UINT8, std::string("threshx_low") + std::to_string(i) + std::string(":"));
+            if (IS_MOLY) {
+                parseElement(TYPE_UINT8, std::string("threshx_high2") + std::to_string(i) + std::string(":"));
+                parseElement(TYPE_UINT8, std::string("threshx_low2") + std::to_string(i) + std::string(":"));
+            }
+            if (!isTdd) {
+                parseElement(TYPE_UINT32, std::string("cell_identity") + std::to_string(i) + std::string(":"));
+                int plmnValid = readIntegerFromByte();
+                if (plmnValid != 0) {
+                    parseElement(TYPE_UINT8, std::string("multi_plmn_count: "));
+                    for (int j = 0; j < 6; j++) {
+                        parseElement(TYPE_UINT8, std::string("multi_plmn_id[") + std::to_string(j) + std::string("].mcc: "), 3);
+                        parseElement(TYPE_UINT8, std::string("multi_plmn_id[") + std::to_string(j) + std::string("].mnc: "), 3);
+                    }
+                } else {
+                    mOffset += 37 * 2; // skip plmn data
+                }
+
+                int lacValid = readIntegerFromByte();
+                if (lacValid != 0) {
+                    parseElement(TYPE_UINT16, "lac: ");
+                } else {
+                    mResult.append("lac: invalid\n");
+                    mOffset += DATA_OFFSET_6;
+                }
+
+                int racValid = readIntegerFromByte();
+                if (racValid != 0) {
+                    parseElement(TYPE_UINT8, "rac: ");
+                } else {
+                    mResult.append("rac: invalid\n");
+                    mOffset += DATA_OFFSET_2;
+                }
+
+                int uraValid = readIntegerFromByte();
+                if (uraValid != 0) {
+                    parseElement(TYPE_UINT8, "num_ura_id: ");
+                    for (int j = 0; j < 8; j++) {
+                        int numBits = readIntegerFromByte();
+                        if (numBits == 1) {
+                            parseElement(TYPE_UINT8, std::string("uraIdentity[") + std::to_string(j) + std::string("]: "));
+                            mOffset += DATA_OFFSET_2; // skip high byte
+                        } else {
+                            parseElement(TYPE_UINT8, std::string("uraIdentity[") + std::to_string(j) + std::string("]: "), 2);
+                        }
+                    }
+                } else {
+                    mOffset += 25 * 2; // skip ura data
+                    mResult.append("ura: invalid\n");
+                }
+            }
+            parseElement(TYPE_ALIGNMENT, "");
+        }
+    }
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::getValueFrom4Byte(std::string data, int start, bool sig) {
+    if (data.length() < start + DATA_OFFSET_8) {
+        return std::string("0");
+    }
+    try {
+        std::string byte1 = data.substr(start, start + DATA_OFFSET_2);
+        std::string byte2 = data.substr(start + DATA_OFFSET_2, start + DATA_OFFSET_4);
+        std::string byte3 = data.substr(start + DATA_OFFSET_4, start + DATA_OFFSET_6);
+        std::string byte4 = data.substr(start + DATA_OFFSET_6, start + DATA_OFFSET_8);
+        std::string reverse = byte4 + byte3 + byte2 + byte1;
+        if (sig) {
+            long lg = std::stol(reverse,0, DATA_FORMAT);
+            int i = (int) lg;
+            return std::to_string(i);
+        } else {
+            return std::to_string(std::stol(reverse,0, DATA_FORMAT));
+        }
+    } catch (const std::out_of_range &e) {
+        RLOGD("out of range: %s, line: %s", e.what(), __LINE__);
+        return std::string("Error.");
+    } catch (const std::invalid_argument &e) {
+        RLOGD("invalid argument: %s, line: %s", e.what(), __LINE__);
+        return std::string("Error.");
+    }
+}
+std::string NetworkInfoUrcParser::oneBlockFrom4Byte(std::string label, std::string data, int start,bool sig, int dataLength) {
+    std::string block(label);
+    for (int i = 0; i < dataLength; i++) {
+        if (dataLength > MAX_DATA_PER_LINE && 0 == i % MAX_DATA_PER_LINE) {
+            block += std::string("\n");
+        }
+        block += getValueFrom4Byte(data, start, sig);
+        start += DATA_OFFSET_8;
+        if (i != dataLength - 1) {
+            block += std::string(", ");
+        }
+    }
+    return block + std::string("\n");
+}
+
+std::string NetworkInfoUrcParser::getValueFrom2Byte(std::string data, int start, bool sig) {
+    if (data.length() < start + DATA_OFFSET_4) {
+        return std::string("0");
+    }
+    try {
+        std::string low = data.substr(start, start + DATA_OFFSET_2);
+        std::string high = data.substr(start + DATA_OFFSET_2, start + DATA_OFFSET_4);
+        std::string reverse = high + low;
+        if (sig) {
+            int i = std::stoi(reverse,0, DATA_FORMAT);
+            int16_t s = (int16_t) i;
+            return std::to_string(s);
+        } else {
+            return std::to_string(std::stoi(reverse,0, DATA_FORMAT));
+        }
+    } catch (const std::out_of_range &e) {
+        RLOGD("out of range: %s, line: %s", e.what(), __LINE__);
+        return std::string("Error.");
+    } catch (const std::invalid_argument &e) {
+        RLOGD("invalid argument: %s, line: %s", e.what(), __LINE__);
+        return std::string("Error.");
+    }
+}
+
+std::string NetworkInfoUrcParser::oneBlockFrom2Byte(std::string label, std::string data, int start,bool sig, int dataLength) {
+    std::string block(label);
+    for (int i = 0; i < dataLength; i++) {
+        if ((dataLength > MAX_DATA_PER_LINE) && (0 == i % MAX_DATA_PER_LINE)) {
+            block += std::string("\n");
+        }
+        block += getValueFrom2Byte(data, start, sig);
+        start += DATA_OFFSET_4;
+        if (i != dataLength - 1) {
+            block += std::string(", ");
+        }
+    }
+    return block + std::string("\n");
+}
+
+std::string NetworkInfoUrcParser::getValueFromByte(std::string data, int start, bool sig) {
+    if (data.length() < start + DATA_OFFSET_2) {
+        return std::string("0");
+    }
+    try {
+        std::string sub = data.substr(start, start + DATA_OFFSET_2);
+        if (sig) {
+            int16_t s = std::stoi(sub, 0, DATA_FORMAT);
+            int8_t b = (int8_t) s;
+            return std::to_string(b); //???
+        } else {
+            return std::to_string(std::stoi(sub, 0, DATA_FORMAT));
+        }
+    } catch (const std::out_of_range &e) {
+        RLOGD("out of range: %s, line: %s", e.what(), __LINE__);
+        return std::string("Error.");
+    } catch (const std::invalid_argument &e) {
+        RLOGD("invalid argument: %s, line: %s", e.what(), __LINE__);
+        return std::string("Error.");
+    }
+}
+
+std::string NetworkInfoUrcParser::oneBlockFromByte(std::string label, std::string data, int start,bool sig, int dataLength) {
+    std::string block(label);
+    for (int i = 0; i < dataLength; i++) {
+        if (dataLength > MAX_DATA_PER_LINE && 0 == i % MAX_DATA_PER_LINE) {
+            block += "\n";
+        }
+        block.append(getValueFromByte(data, start, sig));
+        start += DATA_OFFSET_2;
+        if (i != dataLength - 1) {
+            block += std::string(", ");
+        }
+    }
+    return block + std::string("\n");
+}
+
+std::string NetworkInfoUrcParser::parseElement(int type, std::string label, int count){
+    std::string value("");
+    switch (type) {
+    case TYPE_UINT8:
+    {
+        value = oneBlockFromByte(label, mRawString, mOffset, false, count);
+        mOffset += 2 * count;
+        break;
+    }
+    case TYPE_UINT16:
+    {
+        if (ALIGN_MENT_ENABLE) {
+            mOffset = (mOffset + 3) & ~3;
+        }
+        value = oneBlockFrom2Byte(label, mRawString, mOffset, false, count);
+        mOffset += 4 * count;
+        break;
+    }
+    case TYPE_UINT32:
+    {
+        if (ALIGN_MENT_ENABLE) {
+            mOffset = (mOffset + 7) & ~7;
+        }
+        value = oneBlockFrom4Byte(label, mRawString, mOffset, false, count);
+        mOffset += 8 * count;
+        break;
+    }
+    case TYPE_INT8:
+    {
+        value = oneBlockFromByte(label, mRawString, mOffset, true, count);
+        mOffset += 2 * count;
+        break;
+    }
+    case TYPE_INT16:
+    {
+        if (ALIGN_MENT_ENABLE) {
+            mOffset = (mOffset + 3) & ~3;
+        }
+        value = oneBlockFrom2Byte(label, mRawString, mOffset, true, count);
+        mOffset += 4 * count;
+        break;
+    }
+    case TYPE_INT32:
+    {
+        if (ALIGN_MENT_ENABLE) {
+            mOffset = (mOffset + 7) & ~7;
+        }
+        value = oneBlockFrom4Byte(label, mRawString, mOffset, true, count);
+        mOffset += 8 * count;
+        break;
+    }
+    case TYPE_LONG:
+    {
+        if (ALIGN_MENT_ENABLE) {
+            mOffset = (mOffset + 7) & ~7;
+        }
+        std::string strRscp = getValueFrom4Byte(mRawString, mOffset, true);
+        long rscp = 0;
+        try {
+            rscp = std::stol(strRscp) / 4096;
+        } catch (const std::out_of_range &e) {
+            RLOGD("out of range: %s, line: %s", e.what(), __LINE__);
+        } catch (const std::invalid_argument &e) {
+            RLOGD("invalid argument: %s, line: %s", e.what(), __LINE__);
+        }
+        value = label + std::to_string(rscp) + std::string("\n");
+        mOffset += 8;
+        break;
+    }
+    case TYPE_FLOAT:
+    {
+        if (ALIGN_MENT_ENABLE) {
+            mOffset = (mOffset + 7) & ~7;
+        }
+        std::string strEcno = getValueFrom4Byte(mRawString, mOffset, true);
+        float ecno = 0;
+        try {
+            ecno = std::stof(strEcno) / 4096;
+        } catch (const std::out_of_range &e) {
+            RLOGD("out of range: %s, line: %s", e.what(), __LINE__);
+        } catch (const std::invalid_argument &e) {
+            RLOGD("invalid argument: %s, line: %s", e.what(), __LINE__);
+        }
+        value = label + std::to_string(ecno) + std::string("\n");
+        mOffset += 8;
+        break;
+    }
+    case TYPE_STRING:
+    {
+        value = label;
+        for (int i = 0; i < count; i++) {
+            std::string str = getValueFromByte(mRawString, mOffset, false);
+            mOffset += 2;
+            try {
+                short s = std::stoi(str);
+                value.push_back((char) s); //???
+            } catch (const std::out_of_range &e) {
+                RLOGD("out of range: %s, line: %s", e.what(), __LINE__);
+                break;
+            } catch (const std::invalid_argument &e) {
+                RLOGD("invalid argument: %s, line: %s", e.what(), __LINE__);
+                break;
+            }
+        }
+        value += std::string("\n");
+        break;
+    }
+    case TYPE_ALIGNMENT:
+    {
+        if (ALIGN_MENT_ENABLE) {
+            mOffset = (mOffset + 7) & ~7;
+        }
+        break;
+    }
+    default:
+        break;
+    }
+    mResult.append(value);
+    return value;
+}
+
+std::string NetworkInfoUrcParser::parseElement(int type, std::string label) {
+    return parseElement(type, label, 1);
+}
+
+std::string NetworkInfoUrcParser::getCellSelInfo() {
+    parseElement(TYPE_UINT8, "crh: ");
+    parseElement(TYPE_UINT8, "ms_txpwr: ");
+    parseElement(TYPE_UINT8, "rxlev_access_min: ");
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::getChDscrInfo() {
+    parseElement(TYPE_UINT8,  "channel_type: ");
+    parseElement(TYPE_UINT8,  "tn: ");
+    parseElement(TYPE_UINT8,  "tsc: ");
+    parseElement(TYPE_UINT8,  "hopping_flag: ");
+    parseElement(TYPE_UINT8,  "maio: ");
+    parseElement(TYPE_UINT8,  "hsn: ");
+    parseElement(TYPE_UINT8,  "num_of_carriers: ");
+    parseElement(TYPE_UINT16, "arfcn:", 64);
+    parseElement(TYPE_INT8,   "is_BCCH_arfcn_valid: ");
+    parseElement(TYPE_UINT16, "BCCH_arfcn: ");
+    parseElement(TYPE_UINT8,  "cipher_algo: ");
+    parseElement(TYPE_UINT8,  "imeisv_digit: ", 16);
+    parseElement(TYPE_UINT8,  "channel_mode: ");
+    if (AMR_SUPPORT_ENABLE) {
+        parseElement(TYPE_INT8,  "amr_valid: ");
+        parseElement(TYPE_UINT8, "mr_ver: ");
+        parseElement(TYPE_INT8,  "nscb: ");
+        parseElement(TYPE_INT8,  "icmi: ");
+        parseElement(TYPE_UINT8, "start_codec_mode: ");
+        parseElement(TYPE_UINT8, "acs: ");
+        parseElement(TYPE_UINT8, "threshold:", 3);
+        parseElement(TYPE_UINT8, "hysteresis:", 3);
+    }
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::getRACHCtrlInfo() {
+    parseElement(TYPE_UINT8, "max_retrans: ");
+    parseElement(TYPE_UINT8, "tx_integer: ");
+    parseElement(TYPE_UINT8, "cba: ");
+    parseElement(TYPE_UINT8, "re: ");
+    parseElement(TYPE_UINT8, "acc_class:", 2);
+    parseElement(TYPE_INT8,  "CB_supported: ");
+    return mResult;
+}
+
+
+std::string NetworkInfoUrcParser::getLAIInfo() {
+    parseElement(TYPE_UINT8, "mcc:", 3);
+    parseElement(TYPE_UINT8, "mnc:", 3);
+    parseElement(TYPE_UINT8, "lac:", 2);
+    parseElement(TYPE_UINT16, "cell_id: ");
+    parseElement(TYPE_UINT8, "nc_info_index: ");
+    parseElement(TYPE_UINT8, "rac: ");
+    parseElement(TYPE_UINT8, "nmo: ");
+    parseElement(TYPE_UINT8, "supported_Band: ");
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::getRadioLinkInfo() {
+    parseElement(TYPE_UINT16, "max_value: ");
+    parseElement(TYPE_INT16, "current_value: ");
+    parseElement(TYPE_UINT8, "dtx_ind: ");
+    parseElement(TYPE_UINT8, "dtx_used: ");
+    parseElement(TYPE_INT8, "is_dsf: ");
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::getMeasRepInfo() {
+    parseElement(TYPE_UINT8, "rr_state: ");
+    if (IS_MOLY) {
+        parseElement(TYPE_UINT8, "meas_mode: ");
+    }
+    parseElement(TYPE_UINT16, "serving_arfcn: ");
+    parseElement(TYPE_UINT8, "serving_bsic: ");
+    parseElement(TYPE_UINT8, "serving_current_band: ");
+    parseElement(TYPE_UINT8, "serv_gprs_supported: ");
+    parseElement(TYPE_INT16, "serv_rla_in_quarter_dbm: ");
+    if (IS_MOLY) {
+        parseElement(TYPE_UINT8, "serv_rla_reported_value: ");
+    }
+    parseElement(TYPE_INT8, "is_serv_BCCH_rla_valid: ");
+    parseElement(TYPE_INT16, "serv_BCCH_rla_in_dedi_state: ");
+    parseElement(TYPE_UINT8, "quality: ");
+    parseElement(TYPE_INT8, "gprs_pbcch_present: ");
+    parseElement(TYPE_INT8, "gprs_c31_c32_enable: ");
+    if (!IS_MOLY) {
+        parseElement(TYPE_INT16, "c31:", 32);
+    }
+    parseElement(TYPE_INT16, "c1_serv_cell: ");
+    parseElement(TYPE_INT16, "c2_serv_cell: ");
+    parseElement(TYPE_INT16, "c31_serv_cell: ");
+    parseElement(TYPE_UINT8, "num_of_carriers: ");
+    parseElement(TYPE_UINT16, "nc_arfcn:", 32);
+    parseElement(TYPE_INT16, "rla_in_quarter_dbm:", 32);
+    if (IS_MOLY) {
+        parseElement(TYPE_UINT8, "rla_in_reported_value: ", 32);
+    }
+    parseElement(TYPE_UINT8, "nc_info_status:", 32);
+    parseElement(TYPE_UINT8, "nc_bsic:", 32);
+    parseElement(TYPE_INT32, "frame_offset:", 32);
+    parseElement(TYPE_INT32, "ebit_offset:", 32);
+    parseElement(TYPE_INT16, "c1:", 32);
+    parseElement(TYPE_INT16, "c2:", 32);
+    if (IS_MOLY) {
+        parseElement(TYPE_INT16, "c31:", 32);
+    }
+    parseElement(TYPE_UINT8, "multiband_report: ");
+    parseElement(TYPE_UINT8, "timing_advance: ");
+    parseElement(TYPE_INT16, "tx_power_level: ");
+    parseElement(TYPE_INT16, "serv_rla_full_value_in_quater_dbm: ");
+    parseElement(TYPE_UINT8, "nco: ");
+    parseElement(TYPE_UINT8, "rxqual_sub: ");
+    parseElement(TYPE_UINT8, "rxqual_full: ");
+    parseElement(TYPE_INT16, "using_tx_power_in_dbm: ");
+    parseElement(TYPE_INT8, "amr_info_valid: ");
+    parseElement(TYPE_UINT8, "cmr_cmc_cmiu_cmid: ");
+    parseElement(TYPE_UINT8, "c_i: ");
+    parseElement(TYPE_UINT16, "icm: ");
+    parseElement(TYPE_UINT16, "acs: ");
+    parseElement(TYPE_INT8, "dl_dtx_used: ");
+    if (FWPNC_LAI_INFO_ENABLE) {
+        parseElement(TYPE_UINT8, "num_of_nc_lai: ");
+        mResult.append("nc_lai:\n");
+        for (int i = 0; i < 6; i++) {
+            parseElement(TYPE_UINT8, std::string("nc_lai[") + std::to_string(i) + std::string("]:\n") + std::string("mcc:"), 3);
+            parseElement(TYPE_UINT8, "mnc:", 3);
+            parseElement(TYPE_UINT8, "lac:", 2);
+            parseElement(TYPE_UINT16, "cell_id: ");
+            parseElement(TYPE_UINT8, "nc_info_index: ");
+        }
+    }
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::getCaListInfo() {
+    parseElement(TYPE_UINT8, "valid: ");
+    parseElement(TYPE_UINT8, "number_of_channels: ");
+    parseElement(TYPE_UINT16, "arfcn_list:", 64);
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::getControlMsgInfo() {
+    parseElement(TYPE_UINT8, "msg_type: ");
+    parseElement(TYPE_UINT8, "rr_cause: ");
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::getSI2QInfo() {
+    parseElement(TYPE_INT8, "present: ");
+    parseElement(TYPE_UINT8, "no_of_instance: ");
+    parseElement(TYPE_INT8, "emr_report: ");
+    parseElement(TYPE_INT8, "pemr_report: ");
+    parseElement(TYPE_INT8, "umts_parameter_exist: ");
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::getMIInfo() {
+    parseElement(TYPE_INT8, "present: ");
+    parseElement(TYPE_UINT8, "no_of_instance: ");
+    parseElement(TYPE_INT8, "emr_report: ");
+    parseElement(TYPE_INT8, "umts_parameter_exist: ");
+    return mResult;
+}
+
+
+std::string NetworkInfoUrcParser::getBLKInfo() {
+    parseElement(TYPE_UINT8, "ul_coding_scheme: ");
+    parseElement(TYPE_UINT8, "ul_cv: ");
+    parseElement(TYPE_UINT8, "ul_tlli: ");
+    parseElement(TYPE_UINT16, "ul_bsn1: ");
+    if (GPRS_MODE_ENABLE) {
+        parseElement(TYPE_UINT16, "ul_bsn2: ");
+        parseElement(TYPE_UINT8, "ul_cps: ");
+        parseElement(TYPE_UINT8, "ul_rsb: ");
+        parseElement(TYPE_UINT8, "ul_spb: ");
+    }
+    parseElement(TYPE_UINT8, "dl_c_value_in_rx_level: ");
+    parseElement(TYPE_UINT8, "dl_rxqual: ");
+    parseElement(TYPE_UINT8, "dl_sign_var: ");
+    parseElement(TYPE_UINT8, "dl_coding_scheme: ");
+    parseElement(TYPE_UINT8, "dl_fbi: ");
+    parseElement(TYPE_UINT16, "dl_bsn1: ");
+    if (GPRS_MODE_ENABLE) {
+        parseElement(TYPE_UINT16, "dl_bsn2: ");
+        parseElement(TYPE_UINT8, "dl_cps: ");
+        parseElement(TYPE_UINT8, "dl_gmsk_mean_bep_lev: ");
+        parseElement(TYPE_UINT8, "dl_8psk_mean_bep_lev: ");
+        parseElement(TYPE_UINT8, "dl_tn_mean_bep_lev:", 8);
+    }
+    parseElement(TYPE_UINT8, "dl_tn_interference_lev:", 8);
+    return mResult;
+}
+
+
+std::string NetworkInfoUrcParser::getTBFInfo() {
+    parseElement(TYPE_UINT8, "tbf_mode: ");
+    parseElement(TYPE_UINT8, "ul_tbf_status: ");
+    parseElement(TYPE_UINT8, "ul_rel_cause: ");
+    parseElement(TYPE_UINT8, "ul_ts_allocation: ");
+    parseElement(TYPE_UINT8, "ul_rlc_mode: ");
+    parseElement(TYPE_UINT8, "ul_mac_mode: ");
+    parseElement(TYPE_UINT16, "number_rlc_octect: ");
+    parseElement(TYPE_UINT8, "ul_tfi: ");
+    parseElement(TYPE_UINT8, "ul_granularity: ");
+    parseElement(TYPE_UINT8, "ul_usf: ");
+    parseElement(TYPE_UINT8, "ul_tai: ");
+    parseElement(TYPE_UINT16, "ul_tqi: ");
+    parseElement(TYPE_UINT16, "ul_window_size: ");
+    parseElement(TYPE_UINT8, "dl_tbf_status: ");
+    parseElement(TYPE_UINT8, "dl_rel_cause: ");
+    parseElement(TYPE_UINT8, "dl_ts_allocation: ");
+    parseElement(TYPE_UINT8, "dl_rlc_mode: ");
+    parseElement(TYPE_UINT8, "dl_mac_mode: ");
+    parseElement(TYPE_UINT8, "dl_tfi: ");
+    parseElement(TYPE_UINT8, "dl_tai: ");
+    parseElement(TYPE_UINT16, "dl_window_size: ");
+    if (GPRS_MODE_ENABLE) {
+        parseElement(TYPE_UINT8, "dl_out_of_memory: ");
+    }
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::getGPRSGenInfo() {
+    parseElement(TYPE_UINT32, "t3192: ");
+    parseElement(TYPE_UINT32, "t3168: ");
+    parseElement(TYPE_UINT8, "rp: ");
+    parseElement(TYPE_UINT8, "gprs_support: ");
+    parseElement(TYPE_UINT8, "egprs_support: ");
+    parseElement(TYPE_UINT8, "sgsn_r: ");
+    parseElement(TYPE_UINT8, "pfc_support: ");
+    parseElement(TYPE_UINT8, "epcr_support: ");
+    parseElement(TYPE_UINT8, "bep_period: ");
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::get3GGeneralInfo() {
+    if (getValueFromByte(mRawString, mOffset, false).compare("255") == 0) {
+        // "FF" means Invalid service_status
+        mResult.append("service_status:\n");
+        mOffset += 2;
+    } else {
+        parseElement(TYPE_UINT8, "service_status: ");
+    }
+
+    if (getValueFromByte(mRawString, mOffset, false).compare("255") == 0) {
+        // "FF" means Invalid umts_rrc_state
+        mResult.append("umts_rrc_state:\n");
+        mOffset += 2;
+    } else {
+        parseElement(TYPE_UINT8, "umts_rrc_state: ");
+    }
+
+    if (getValueFrom2Byte(mRawString, mOffset, false).compare("65535") == 0) {
+        // "FFFF" means Invalid uarfcn_DL
+        mResult.append("uarfcn_DL:\n");
+        mOffset += 4;
+    } else {
+        parseElement(TYPE_UINT16, "uarfcn_DL: ");
+    }
+
+    if (getValueFrom2Byte(mRawString, mOffset, false).compare("65535") == 0) {
+        // "FFFF" means Invalid psc
+        mResult.append("psc:\n");
+        mOffset += 4;
+    } else {
+        parseElement(TYPE_UINT16, "psc: ");
+    }
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::getSlceVoiceInfo() {
+    if (IS_MOLY) {
+        parseElement(TYPE_UINT8, "ULAMRType: ");
+        parseElement(TYPE_UINT8, "DLAMRType: ");
+    } else {
+        parseElement(TYPE_UINT8, "voice: ");
+    }
+    return mResult;
+}
+
+
+std::string NetworkInfoUrcParser::getSecurityConfigInfo() {
+    parseElement(TYPE_UINT8, "Ciphering Algorithm: ");
+    parseElement(TYPE_UINT8, "Integrity Algorithm: ");
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::get3GMmEmInfo() {
+    parseElement(TYPE_UINT8, "t3212: ");
+    parseElement(TYPE_UINT8, "ATT_flag: ");
+    parseElement(TYPE_UINT8, "MM_reject_cause: ");
+    parseElement(TYPE_UINT8, "MM_state: ");
+    parseElement(TYPE_UINT8, "MCC:", 3);
+    parseElement(TYPE_UINT8, "MNC:", 3);
+    parseElement(TYPE_UINT8, "LOC:", 2);
+    parseElement(TYPE_UINT8, "rac: ");
+    parseElement(TYPE_UINT8, "TMSI:", 4);
+    parseElement(TYPE_UINT8, "is_t3212_running:");
+    parseElement(TYPE_UINT16, "t3212_timer_value:");
+    parseElement(TYPE_UINT16, "t3212_passed_time:");
+    parseElement(TYPE_UINT8, "common_access_class: ");
+    parseElement(TYPE_UINT8, "cs_access_class: ");
+    parseElement(TYPE_UINT8, "ps_access_class: ");
+    mOffset += DATA_OFFSET_8;
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::getSmEmInfo() {
+    parseElement(TYPE_UINT8, "num_of_active_pdp_context: ");
+    parseElement(TYPE_ALIGNMENT, "");
+    for (int i = 0; i < 11; i++) {
+        mResult.append("--------------------\n");
+        mResult.append(std::string("pdp[") + std::to_string(i) + std::string("]:\n"));
+        parseElement(TYPE_UINT8, "pdp_index: ");
+        parseElement(TYPE_UINT8, "nsapi: ");
+        if (IS_MOLY) {
+            parseElement(TYPE_UINT8, "ti_value: ");
+        }
+        parseElement(TYPE_UINT8, "pdp_context_status: ");
+        if (IS_MOLY) {
+            parseElement(TYPE_UINT8, "context_type: ");
+            parseElement(TYPE_UINT8, "initiated_by: ");
+            parseElement(TYPE_UINT8, "pdp_addr_type: ");
+        }
+        parseElement(TYPE_UINT8, "ip:", 16);
+        parseElement(TYPE_UINT16, "sdu_size:");
+        parseElement(TYPE_STRING, "apn: ", 100);
+        parseElement(TYPE_UINT8, "sm_cause: ");
+        if (IS_MOLY) {
+            mOffset += 249 * 2;
+        } else {
+            mOffset += 77 * 2; // Skip the rest 77 bytes
+        }
+    }
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::getGmmEmInfo() {
+    parseElement(TYPE_UINT16, "ready_timer: ");
+    parseElement(TYPE_UINT16, "rau_timer: ");
+    parseElement(TYPE_UINT8, "ms_state: ");
+    parseElement(TYPE_INT8, "is_rau_timer_running: ");
+    parseElement(TYPE_UINT16, "rau_timer_passed_time: ");
+    parseElement(TYPE_UINT8, "attach_req_mobile_identity: ");
+    if (WISDOM_EM && ADVANCED_EM) {
+        parseElement(TYPE_UINT8, "ptmsi: ", 4);
+        parseElement(TYPE_UINT8, "attach_rej_cause: ");
+        parseElement(TYPE_UINT8, "rau_rej_cause: ");
+        parseElement(TYPE_UINT8, "gprs_update_status: ");
+        parseElement(TYPE_UINT8, "cipher_algo: ");
+        parseElement(TYPE_UINT8, "attach_type: ");
+        parseElement(TYPE_UINT8, "gmm_state: ");
+        parseElement(TYPE_UINT8, "gprs_attach_status: ");
+    }
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::get3GTcmMmiEmInfo() {
+    parseElement(TYPE_UINT8, "num_of_valid_entries: ");
+    for (int i = 0; i < 3; i++) {
+        parseElement(TYPE_UINT8, std::string("nsapi") + std::to_string(i) + std::string(":"));
+        parseElement(TYPE_UINT8, std::string("data_speed_value") + std::to_string(i) + std::string(":"));
+    }
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::get3GCsceEmInfoMultiPlmn() {
+    parseElement(TYPE_UINT8, "multi_plmn_count: ");
+    for (int i = 0; i < 6; i++) {
+        parseElement(TYPE_UINT8, std::string("mcc1_") + std::to_string(i) + std::string(":"));
+        parseElement(TYPE_UINT8, std::string("mcc2_") + std::to_string(i) + std::string(":"));
+        parseElement(TYPE_UINT8, std::string("mcc3_") + std::to_string(i) + std::string(":"));
+        parseElement(TYPE_UINT8, std::string("mnc1_") + std::to_string(i) + std::string(":"));
+        parseElement(TYPE_UINT8, std::string("mnc2_") + std::to_string(i) + std::string(":"));
+        parseElement(TYPE_UINT8, std::string("mnc3_") + std::to_string(i) + std::string(":"));
+    }
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::get3GMemeEmInfoUmtsCellStatus() {
+    parseElement(TYPE_INT8, "tx_power: ");
+    parseElement(TYPE_UINT8, "num_cells: ");
+    parseElement(TYPE_ALIGNMENT, "");
+    for (int i = 0; i < 32; i++) {
+        mResult.append("--------------------\n");
+        mResult.append(std::string("umts_cell_list[") + std::to_string(i) + std::string("]:\n"));
+        parseElement(TYPE_UINT16, "UARFCN: ");
+        parseElement(TYPE_UINT16, "PSC: ");
+        parseElement(TYPE_INT32, "RSCP: ");
+        parseElement(TYPE_INT32, "ECNO: ");
+        parseElement(TYPE_UINT8, "cell_type: ");
+        parseElement(TYPE_UINT8, "Band: ");
+        parseElement(TYPE_INT32, "RSSI: ");
+        parseElement(TYPE_UINT32, "Cell_identity: ");
+
+        int validity = readIntegerFromByte();
+        int lacValid = validity & 0x01;
+        int racValid = validity & 0x02;
+        int uraValid = validity & 0x04;
+
+        parseElement(TYPE_UINT8, "num_plmn_id: ");
+        for (int j = 0; j < 6; j++) {
+            parseElement(TYPE_UINT16, std::string("plmn_id_list[") + std::to_string(j) + std::string("].mcc: "));
+            parseElement(TYPE_UINT16, std::string("plmn_id_list[") + std::to_string(j) + std::string("].mnc: "));
+        }
+
+        if (lacValid != 0) {
+            parseElement(TYPE_UINT16, "lac: ");
+        } else {
+            mResult.append("lac: invalid\n");
+            mOffset += DATA_OFFSET_4;
+        }
+
+        if (racValid != 0) {
+            parseElement(TYPE_UINT8, "rac: ");
+        } else {
+            mResult.append("rac: invalid\n");
+            mOffset += DATA_OFFSET_2;
+        }
+
+        if (uraValid != 0) {
+            parseElement(TYPE_UINT8, "num_ura_id: ");
+            for (int j = 0; j < 8; j++) {
+                int numBits = readIntegerFromByte();
+                if (numBits == 1) {
+                    parseElement(TYPE_UINT8, std::string("uraIdentity[") + std::to_string(j) + std::string("]: "));
+                    mOffset += DATA_OFFSET_2; // skip high byte
+                } else {
+                    parseElement(TYPE_UINT8, std::string("uraIdentity[") + std::to_string(j) + std::string("]: "), 2);
+                }
+            }
+            mOffset += DATA_OFFSET_4;
+        } else {
+            mResult.append("ura: invalid\n");
+            mOffset += 27 * 2;
+        }
+    }
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::get3GMemeEmPeriodicBlerReportInd() {
+    parseElement(TYPE_UINT8, "num_trch: ");
+    for (int i = 0; i < 8; i++) {
+        parseElement(TYPE_ALIGNMENT, "");
+        parseElement(TYPE_UINT8, std::string("TrCHId") + std::to_string(i) + std::string(":"));
+        parseElement(TYPE_UINT32, std::string("TotalCRC") + std::to_string(i) + std::string(":"));
+        parseElement(TYPE_UINT32, std::string("BadCRC") + std::to_string(i) + std::string(":"));
+    }
+    return mResult;
+}
+
+
+std::string NetworkInfoUrcParser::get3GUrrUmtsSrncId() {
+    parseElement(TYPE_UINT16, "srnc: ");
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::get3GSlceEmPsDataRateStatusInd() {
+    parseElement(TYPE_UINT8, "ps_number: ");
+    parseElement(TYPE_ALIGNMENT, "");
+    for (int i = 0; i < 8; i++) {
+        parseElement(TYPE_UINT8, std::string("RAB_ID") + std::to_string(i) + std::string(":"));
+        parseElement(TYPE_INT8, std::string("RB_UD") + std::to_string(i) + std::string(":"));
+        parseElement(TYPE_UINT32, std::string("DL_rate") + std::to_string(i) + std::string(":"));
+        parseElement(TYPE_UINT32, std::string("UL_rate") + std::to_string(i) + std::string(":"));
+    }
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::get3GMemeEmInfoHServCellInd() {
+    parseElement(TYPE_UINT16, "HSDSCH_Serving_UARFCN: ");
+    parseElement(TYPE_UINT16, "HSDSCH_Serving_PSC: ");
+    parseElement(TYPE_UINT16, "EDCH_Serving_UARFCN: ");
+    parseElement(TYPE_UINT16, "EDCH_Serving_PSC: ");
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::get3GHandoverSequenceIndStuct() {
+    parseElement(TYPE_UINT8, "service_status: ");
+    parseElement(TYPE_ALIGNMENT, "");
+    parseElement(TYPE_UINT16, "[old_cell_info:-----]\nprimary_uarfcn_DL: ");
+    parseElement(TYPE_UINT16, "working_uarfcn: ");
+    parseElement(TYPE_UINT16, "physicalCellId: ");
+    parseElement(TYPE_UINT16, "[target_cell_info:-----]\nprimary_uarfcn_DL: ");
+    parseElement(TYPE_UINT16, "working_uarfcn: ");
+    parseElement(TYPE_UINT16, "physicalCellId: ");
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::getCtrlchanInfo() {
+    parseElement(TYPE_UINT8, "mscr: ");
+    parseElement(TYPE_UINT8, "att: ");
+    parseElement(TYPE_UINT8, "bs_ag_blks_res: ");
+    parseElement(TYPE_UINT8, "ccch_conf: ");
+    parseElement(TYPE_UINT8, "cbq2: ");
+    parseElement(TYPE_UINT8, "bs_pa_mfrms: ");
+    parseElement(TYPE_UINT8, "t3212: ");
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::parseInfo(int type, std::string info, int simType) {
+    RLOGD("NetworkInfo ------ Type is: %d, simtype: %d",type, simType);
+    RLOGD("NetworkInfo ------ Data is:\n");
+    RLOGD("%s\n",info.c_str());
+    RLOGD("NetworkInfo ---------------------------");
+    mRawString = info;
+    mResult = "";
+    mOffset = 0;
+
+    switch (type) {
+    case Content::CELL_INDEX:
+        return getCellSelInfo();
+    case Content::CHANNEL_INDEX:
+        return getChDscrInfo();
+    case Content::CTRL_INDEX:
+        return getCtrlchanInfo();
+    case Content::RACH_INDEX:
+        return getRACHCtrlInfo();
+    case Content::LAI_INDEX:
+        return getLAIInfo();
+    case Content::RADIO_INDEX:
+        return getRadioLinkInfo();
+    case Content::MEAS_INDEX:
+        return getMeasRepInfo();
+    case Content::CA_INDEX:
+        return getCaListInfo();
+    case Content::CONTROL_INDEX:
+        return getControlMsgInfo();
+    case Content::SI2Q_INDEX:
+        return getSI2QInfo();
+    case Content::MI_INDEX:
+        return getMIInfo();
+    case Content::BLK_INDEX:
+        return getBLKInfo();
+    case Content::TBF_INDEX:
+        return getTBFInfo();
+    case Content::GPRS_INDEX:
+        return getGPRSGenInfo();
+    case Content::URR_3G_GENERAL_INDEX:
+        return get3GGeneralInfo();
+    case Content::GMM_INFO_INDEX:
+        return getGmmEmInfo();
+    default:
+        break;
+    }
+
+    if (type == Content::SM_INFO_INDEX) {
+        return getSmEmInfo();
+    } else if (type == Content::SLCE_VOICE_INDEX) {
+        return getSlceVoiceInfo();
+    } else if (type == Content::SECURITY_CONFIGURATION_INDEX) {
+        return getSecurityConfigInfo();
+    } else if (type == Content::MM_INFO_INDEX) {
+        return get3GMmEmInfo();
+    } else if (type == Content::TCM_MMI_INDEX) {
+        return get3GTcmMmiEmInfo();
+    } else if (type == Content::CSCE_MULTIPLMN_INDEX) {
+        return get3GCsceEmInfoMultiPlmn();
+    } else if (type == Content::PERIOD_IC_BLER_REPORT_INDEX) {
+        return get3GMemeEmPeriodicBlerReportInd();
+    } else if (type == Content::URR_UMTS_SRNC_INDEX) {
+        return get3GUrrUmtsSrncId();
+    } else if (type == Content::HSERV_CELL_INDEX) {
+        return get3GMemeEmInfoHServCellInd();
+    } else if (type == Content::CSCE_NEIGH_CELL_STATUS_INDEX) {
+        return getxGCsceEMNeighCellSStatusIndStructSize(
+                ModemCategory::getModemType() == MODEM_TD);
+    } else if (type == Content::CSCE_SERV_CELL_STATUS_INDEX) {
+        return get3GCsceEMServCellSStatusInd(
+                ModemCategory::getModemType() == MODEM_TD);
+    }
+
+    if (ModemCategory::getModemType() == MODEM_FDD) {
+        if (type == Content::UMTS_CELL_STATUS_INDEX) {
+            return get3GMemeEmInfoUmtsCellStatus();
+        } else if (type == Content::PSDATA_RATE_STATUS_INDEX) {
+            return get3GSlceEmPsDataRateStatusInd();
+        }
+    } else if (ModemCategory::getModemType() == MODEM_TD) {
+        if (type == Content::HANDOVER_SEQUENCE_INDEX) {
+            return get3GHandoverSequenceIndStuct();
+        } else if (type == Content::UL_ADM_POOL_STATUS_INDEX) {
+            return get3GUl2EmAdmPoolStatusIndStruct();
+        } else if (type == Content::UL_PSDATA_RATE_STATUS_INDEX) {
+            return get3GUl2EmPsDataRateStatusIndStruct();
+        } else if (type == Content::UL_HSDSCH_RECONFIG_STATUS_INDEX) {
+            return get3Gul2EmHsdschReconfigStatusIndStruct();
+        } else if (type == Content::UL_URLC_EVENT_STATUS_INDEX) {
+            return get3GUl2EmUrlcEventStatusIndStruct();
+        } else if (type == Content::UL_PERIOD_IC_BLER_REPORT_INDEX) {
+            return get3GUl2EmPeriodicBlerReportInd();
+        }
+    }
+
+    return "";
+}
+
+int NetworkInfoUrcParser::readIntegerFromByte() {
+    if (mRawString.length() < mOffset + 2) {
+        mOffset += 2;
+        return 0;
+    }
+    std::string str = mRawString.substr(mOffset, mOffset + 2);
+    mOffset += 2;
+    int ret = 0;
+    try {
+        ret = std::stoi(str,0, 16);
+    } catch (const std::out_of_range &e) {
+        RLOGD("out of range: %s, line: %s", e.what(), __LINE__);
+        ret = 0;
+    } catch (const std::invalid_argument &e) {
+        RLOGD("invalid argument: %s, line: %s", e.what(), __LINE__);
+        ret = 0;
+    }
+    return ret;
+}
+
+int NetworkInfoUrcParser::readIntegerFrom2Byte() {
+    if (mRawString.length() < mOffset + DATA_OFFSET_4) {
+        mOffset += 4;
+        return 0;
+    }
+    try {
+        std::string low = mRawString.substr(mOffset, mOffset + DATA_OFFSET_2);
+        std::string high = mRawString.substr(mOffset + DATA_OFFSET_2, mOffset + DATA_OFFSET_4);
+        std::string reverse = high + low;
+        mOffset += 4;
+        int i = std::stoi(reverse,0, DATA_FORMAT);
+        int16_t s = (int16_t) i;
+        return s;
+    } catch (const std::out_of_range &e) {
+        RLOGD("out of range: %s, line: %s", e.what(), __LINE__);
+        return 0;
+    } catch (const std::invalid_argument &e) {
+        RLOGD("invalid argument: %s, line: %s", e.what(), __LINE__);
+        return 0;
+    }
+}
+
+std::string NetworkInfoUrcParser::decodeMcc(int value){
+    value += 111;
+    if (value % 10 == 0) {
+        value -= 10;
+    }
+    if ((value / 10) % 10 == 0) {
+        value -= 100;
+    }
+    if ((value / 100) % 10 == 0) {
+        value -= 1000;
+    }
+    return (std::string("000") + std::to_string(value)).substr(std::to_string(value).length());
+}
+
+std::string NetworkInfoUrcParser::decodeMnc(int value){
+    value += 11;
+    if (value % 10 == 0) {
+        value -= 10;
+    }
+    if ((value / 10) % 10 == 0) {
+        value -= 100;
+    }
+    return (std::string("00") + std::to_string(value)).substr(std::to_string(value).length());
+}
+
+std::vector<std::string> NetworkInfoUrcParser::parseSecurityStatus(int type, std::string info) {
+    std::vector<std::string> m2gCipher {"No Ciphering", "A5/1", "A5/2", "A5/3", "A5/4", "A5/5", "A5/6", "A5/7"};
+    std::vector<std::string> m2gGprs {"No Ciphering", "GEA1", "GEA2", "GEA3"};
+    std::vector<std::string> m3gCipher {"No Ciphering", "UEA0", "UEA1", "", "UEA2"};
+    std::vector<std::string> m3gIntegrity {"No Integrity", "UIA1", "UIA2"};
+    std::vector<std::string> m4gEnasCipher {"EEA0(NULL)", "EEA1(SNOW3G)", "EEA2(AES)", "EEA3(ZUC)"};
+    std::vector<std::string> m4gEnasIntegrity {"EIA0(NULL)", "EIA1(SNOW3G)", "EIA2(AES)", "EIA3(ZUC)"};
+    std::vector<std::string> m4gErrcCipher{"EEA0(NULL)", "EEA1(SNOW3G)", "EEA2(AES)", "EEA3(ZUC)"};
+    std::vector<std::string> m4gErrcIntegrity {"EIA0(NULL)", "EIA1(SNOW3G)", "EIA2(AES)", "EIA3(ZUC)"};
+
+    std::vector<std::string> ret {"---", "---"};
+    if (info.empty()) {
+        return ret;
+    }
+    RLOGD("NetworkInfo ------ Type is: %d", type);
+    RLOGD("NetworkInfo ------ Data is:\n");
+    RLOGD("%s\n", info.c_str());
+    RLOGD("NetworkInfo ---------------------------");
+    mRawString = info;
+    mResult.clear();
+    mOffset = 0;
+    int cipherAlgo;
+    int integrityAlgo;
+
+    if (type == Content::CHANNEL_INDEX) {
+        mOffset += 140 * 2;
+        cipherAlgo = readIntegerFromByte();
+        if (cipherAlgo >= 0 && cipherAlgo < m2gCipher.size()) {
+            ret[0] = m2gCipher[cipherAlgo];
+        }
+    } else if (type == Content::LLC_EM_INFO_INDEX) {
+        mOffset += 32 * 2;
+        cipherAlgo = readIntegerFromByte();
+        if (cipherAlgo >= 0 && cipherAlgo < m2gGprs.size()) {
+            ret[0] = m2gGprs[cipherAlgo];
+        }
+    } else if (type == Content::SECURITY_CONFIGURATION_INDEX) {
+        cipherAlgo = readIntegerFromByte();
+        integrityAlgo = readIntegerFromByte();
+        if (cipherAlgo >= 0 && cipherAlgo < m3gCipher.size()) {
+            ret[0] = m3gCipher[cipherAlgo];
+        }
+        if (integrityAlgo >= 0 && integrityAlgo < m3gIntegrity.size()) {
+            ret[1] = m3gIntegrity[integrityAlgo];
+        }
+    } else if (type == Content::ERRC_EM_SEC_PARAM_INDEX) {
+        mOffset += 2 * 2;
+        integrityAlgo = readIntegerFromByte();
+        cipherAlgo = readIntegerFromByte();
+        if (cipherAlgo >= 0 && cipherAlgo < m4gErrcCipher.size()) {
+            ret[0] = m4gErrcCipher[cipherAlgo];
+        } else if (cipherAlgo == 0xFF) {
+            ret[0] = "N/A";
+        }
+        if (integrityAlgo >= 0 && integrityAlgo < m4gErrcIntegrity.size()) {
+            ret[1] = m4gErrcIntegrity[integrityAlgo];
+        } else if (integrityAlgo == 0xFF) {
+            ret[1] = "N/A";
+        }
+    } else if (type == Content::EMM_L4C_EMM_INFO_INDEX) {
+        mOffset += 89 * 2;
+        integrityAlgo = readIntegerFromByte();
+        cipherAlgo = readIntegerFromByte();
+        if (cipherAlgo >= 0 && cipherAlgo < m4gEnasCipher.size()) {
+            ret[0] = m4gEnasCipher[cipherAlgo];
+        } else if (cipherAlgo == 0xFF) {
+            ret[0] = "N/A";
+        }
+        if (integrityAlgo >= 0 && integrityAlgo < m4gEnasIntegrity.size()) {
+            ret[1] = m4gEnasIntegrity[integrityAlgo];
+        } else if (integrityAlgo == 0xFF) {
+            ret[1] = "N/A";
+        }
+    } else if (type == Content::ERRC_EM_ERRC_STATE_INDEX) {
+        ret[0] = getValueFromByte(mRawString, mOffset, false);
+    }
+    return ret;
+}
+
+std::vector<std::string> NetworkInfoUrcParser::parseAntennaDiversity(int type, std::string info) {
+    std::vector<std::string> ret;
+    if (info.empty()) {
+        return ret;
+    }
+    RLOGD("NetworkInfo ------ Type is: %d", type);
+    RLOGD("NetworkInfo ------ Data is:\n");
+    RLOGD("%s\n",info.c_str());
+    RLOGD("NetworkInfo ---------------------------");
+    mRawString = info;
+    mResult.clear();
+    mOffset = 0;
+
+    switch (type) {
+    case Content::EL1TX_EM_TX_INFO_INDEX:
+    {
+        int band = readIntegerFromByte();
+        if (band == 0) {
+            return ret;
+        }
+        mOffset += 15 * 2;
+        int rsrp0 = readIntegerFrom2Byte();
+        int rsrp1 = readIntegerFrom2Byte();
+        int rssi0 = readIntegerFrom2Byte();
+        int rssi1 = readIntegerFrom2Byte();
+        int snr0 = readIntegerFrom2Byte();
+        int snr1 = readIntegerFrom2Byte();
+        int rsrp = readIntegerFrom2Byte();
+        int rsrq = readIntegerFrom2Byte();
+        int snr = readIntegerFrom2Byte();
+        ret = {std::to_string(rsrp0), std::to_string(rsrq), std::to_string(rssi0),
+                std::to_string(snr0), std::to_string(rsrp1), std::to_string(rsrq),
+                std::to_string(rssi1), std::to_string(snr1), std::to_string(rsrp),
+                std::to_string(rsrq), std::to_string(rssi0 > rssi1 ? rssi0 : rssi1),
+                std::to_string(snr)};
+        break;
+    }
+    case Content::UL1_EM_PRX_DRX_MEASURE_INFO_INDEX:
+    {
+        int rscp0 = readIntegerFrom2Byte();
+        int rscp1 = readIntegerFrom2Byte();
+        int pssi0 = readIntegerFrom2Byte();
+        int pssi1 = readIntegerFrom2Byte();
+        ret = {std::to_string(rscp0), std::to_string(pssi0),
+                std::to_string(rscp1), std::to_string(pssi1),
+                std::to_string(rscp0 > rscp1 ? rscp0 : rscp1),
+                std::to_string(pssi0 > pssi1 ? pssi0 : pssi1)};
+        break;
+    }
+    default:
+        break;
+    }
+    return ret;
+}
+
+std::vector<std::vector<std::string>> NetworkInfoUrcParser::parseCdmaInfo(int type, std::string info) {
+    RLOGD("NetworkInfo ------ Type is: %d", type);
+    RLOGD("NetworkInfo ------ Data is:\n");
+    RLOGD("%s\n", info.c_str());
+    RLOGD("NetworkInfo ---------------------------");
+    mRawString = info;
+    utils::tokenize(info,',',mRawValues);
+    mOffset = 1;
+    mType = type;
+
+    switch (type) {
+    case Content::CDMA_1XRTT_RADIO_INDEX:
+        mLabels = {"Channel",
+        "bandClass",
+        "pilotPN",
+        "rxPower_main(dbm)",
+        "rxPower_div(dbm)",
+        "txPower",
+        "tx_Ant",
+        "FER"};
+        break;
+    case Content::CDMA_1XRTT_INFO_INDEX:
+        mLabels = {"cpState",
+        "Calibration",
+        "RfFileMajorVersion",
+        "RfFileMinorVersion",
+        "RfFileValueVersion",
+        "RfFileCustVersion",
+        "sid",
+        "nid",
+        "sysDetIndication",
+        "regZone",
+        "baseLat",
+        "baseLong",
+        "networkPrefSCI",
+        "qpchMode",
+        "mcc",
+        "imsi_11_12",
+        "currentPacketZoneID",
+        "serviceOption",
+        "T_ADD",
+        "T_DROP",
+        "T_COMP",
+        "T_tDROP"};
+        break;
+    case Content::CDMA_1XRTT_SCH_INFO_INDEX:
+        mLabels = {"ForSchMux",
+        "ForSchRc",
+        "ForSchStatus",
+        "ForSchDuration(20ms)",
+        "ForSchRate",
+        "RevSchMux",
+        "RevSchRc",
+        "RevSchStatus",
+        "RevSchDuration(20ms)",
+        "RevSchRate"};
+        break;
+    case Content::CDMA_1XRTT_STATISTICS_INDEX:
+        mLabels = {"total_msg",
+        "error_msg",
+        "acc_1",
+        "acc_2",
+        "acc_8",
+        "dpchloss_count",
+        "dtchloss_count",
+        "idelHO_count",
+        "hardHO_count",
+        "interFreqIdleHO_count",
+        "silentRetryTimeout_count",
+        "T40_count",
+        "T41_count"};
+        break;
+    case Content::CDMA_1XRTT_SERVING_INDEX:
+        mLabels = {"pilotPN",
+        "pilotEcIo",
+        "pilotPhase"};
+        break;
+    case Content::CDMA_EVDO_SERVING_INFO_INDEX:
+        mLabels = {"Band",
+        "Channel",
+        "PilotPN",
+        "PhySubtype",
+        "RSSI_main(dbm)",
+        "RSSI_div(dbm)",
+        "tx_Ant",
+        "SectorID",
+        "SubnetMask",
+        "ColorCode",
+        "UATI",
+        "PilotInc",
+        "ActiveSetWindow",
+        "NeighborSetWindow",
+        "RemainSetWindow",
+        "PilotAdd",
+        "PilotDrop",
+        "PilotDropTimer"};
+        break;
+    case Content::CDMA_EVDO_ACTIVE_SET_INDEX:
+        mLabels = {"PilotPN",
+        "PilotEcIo",
+        "DRC Cover"};
+        break;
+    case Content::CDMA_EVDO_CANDICATE_SET_INDEX:
+        mLabels = {"band",
+        "channel",
+        "pilotPN",
+        "pilotEcIo"};
+        break;
+    case Content::CDMA_EVDO_NEIGHBOR_SET_INDEX:
+        mLabels = {"band",
+        "channel",
+        "pilotPN",
+        "pilotEcIo"};
+        break;
+    case Content::CDMA_EVDO_FL_INDEX:
+        mLabels = {"C/I",
+        "DRC average value",
+        "FTC crc error count",
+        "FTC total count",
+        "Sync crc error ratio"};
+        break;
+    case Content::CDMA_EVDO_RL_INDEX:
+        mLabels = {"Average tbsize",
+        "RTC retransmit count",
+        "RTC transmit total count",
+        "TX power",
+        "pilot power",
+        "RAB=1 ratio"};
+        break;
+    case Content::CDMA_EVDO_STATE_INDEX:
+        mLabels = {"Session State",
+        "AT State",
+        "ALMP State",
+        "Init State",
+        "Idle State",
+        "Overhead State",
+        "Connected State",
+        "Route Update State"};
+        break;
+    default:
+        break;
+    }
+
+    switch (type) {
+    case Content::CDMA_1XRTT_SERVING_INDEX:
+        return parse1xRttServing();
+    case Content::CDMA_EVDO_ACTIVE_SET_INDEX:
+    case Content::CDMA_EVDO_CANDICATE_SET_INDEX:
+    case Content::CDMA_EVDO_NEIGHBOR_SET_INDEX:
+        return parseCellInfo();
+    default:
+        return parseCommonCdmaInfo();
+    }
+}
+
+std::vector<std::vector<std::string>> NetworkInfoUrcParser::parseCommonCdmaInfo() {
+    std::vector<std::vector<std::string>> ret;
+    for (int i = 0; i < mLabels.size(); i++) {
+        ret.push_back(std::vector<std::string> {mLabels[i], nextValue()});
+    }
+    return ret;
+}
+
+std::vector<std::vector<std::string>> NetworkInfoUrcParser::parseCellInfo() {
+    std::vector<std::vector<std::string>> ret;
+    ret.push_back(mLabels);
+    int columns = mLabels.size();
+    int rows = 0;
+    mColumn = -1;
+    try {
+        rows = std::stoi(nextValue());
+    } catch (const std::out_of_range &e) {
+        RLOGD("out of range: %s, line: %s", e.what(), __LINE__);
+        return ret;;
+    } catch (const std::invalid_argument &e) {
+        RLOGD("invalid argument: %s, line: %s", e.what(), __LINE__);
+        return ret;
+    }
+    for (int i = 0; i < rows; i++) {
+        std::vector<std::string> entry;
+        for (int j = 0; j < columns; j++) {
+            mColumn = j;
+            entry.push_back(nextValue());
+        }
+        ret.push_back(entry);
+    }
+    return ret;
+}
+
+std::vector<std::vector<std::string>> NetworkInfoUrcParser::parse1xRttServing() {
+    std::vector<std::vector<std::string>> ret;
+    ret.push_back(std::vector<std::string> {"Active Set"});
+    std::vector<std::vector<std::string>> active = parseCellInfo();
+    ret.insert(ret.end(), active.begin(), active.end());;
+    ret.push_back(std::vector<std::string> {"Candicate Set"});
+    std::vector<std::vector<std::string>> candicate = parseCellInfo();
+    ret.insert(ret.end(), candicate.begin(), candicate.end());;
+    ret.push_back(std::vector<std::string> {"Neighbor Set"});
+    std::vector<std::vector<std::string>> neighbor = parseCellInfo();
+    ret.insert(ret.end(), neighbor.begin(), neighbor.end());;
+    return ret;
+}
+
+std::string NetworkInfoUrcParser::nextValue() {
+    int index = mOffset;
+    mOffset++;
+    if (mRawValues.empty() || mRawValues.size() <= index) {
+        return "";
+    }
+
+    std::string rawValue = mRawValues[index];
+    int value = 0;
+    try {
+        value = std::stoi(rawValue);
+    } catch (const std::out_of_range &e) {
+        RLOGD("out of range: %s, line: %s", e.what(), __LINE__);
+        return rawValue;
+    } catch (const std::invalid_argument &e) {
+        RLOGD("invalid argument: %s, line: %s", e.what(), __LINE__);
+        return rawValue;
+    }
+
+    std::vector<std::string> array;
+    switch (mType) {
+        case Content::CDMA_1XRTT_INFO_INDEX:
+        switch (index) {
+        case 1:
+            array = {"CP_DISABLED", "CP_SYS_DETERMINATION", "CP_PILOT_ACQUISITION",
+                    "CP_SYNC_ACQUISITION", "CP_TIMING_CHANGE", "CP_IDLE", "CP_UPDATE_OHD_INFO",
+                    "CP_PAGE_RESPONSE", "CP_ORD_MSG_RESP", "CP_ORIGINATION",
+                    "CP_REGISTRATION", "CP_MSG_TRANSMISSION", "CP_TC_INIT",
+                    "CP_TC_WAIT_ORDER", "CP_TC_WAIT_ANSWER", "CP_TC_CONVERSATION",
+                    "CP_TC_RELEASE", "CP_NST", "CP_FROZEN",
+                    "CP_TC_FROZEN"};
+            break;
+        case 2:
+            array = {"TRUE", "FALSE", "Unknown"};
+            break;
+        case 14:
+            array = {"FALSE", "TRUE"};
+            break;
+        case 15:
+            return decodeMcc(value);
+        case 16:
+            return decodeMnc(value);
+        case 19:
+        case 20:
+            return utils::format("%.1f", (float) value / -2);
+        case 22:
+            return std::to_string(value / 10);
+        default:
+            break;
+        }
+        break;
+    case Content::CDMA_1XRTT_SCH_INFO_INDEX:
+        switch (index) {
+        case 1: // for_sch_mux
+        case 6: // rev_sch_mux
+            return utils::format("0x%x", value);
+        case 4: // ForSchDuration
+        case 9: // RevSchDuration
+            if (value == 15) {
+                return "Infinite";
+            }
+            break;
+        default:
+            break;
+        }
+        break;
+    case Content::CDMA_1XRTT_SERVING_INDEX:
+        if (mColumn == 1) {
+            return utils::format("%.1f", (float) value / -2);
+        }
+        break;
+    case Content::CDMA_EVDO_SERVING_INFO_INDEX:
+        switch (index) {
+        case 5: // rssi
+        case 6:
+            return utils::format("%.2f", (float) value / 128);
+        case 15: // t_add
+        case 16: // t_drop
+            return utils::format("%.1f", (float) value / -2);
+        default:
+            break;
+        }
+        break;
+    case Content::CDMA_EVDO_ACTIVE_SET_INDEX:
+        if (mColumn == 1) {
+            return utils::format("%.2f", (float) value / 8);
+        }
+        break;
+    case Content::CDMA_EVDO_CANDICATE_SET_INDEX:
+    case Content::CDMA_EVDO_NEIGHBOR_SET_INDEX:
+        if (mColumn == 3) {
+            return utils::format("%.2f", (float) value / 8);
+        }
+        break;
+    case Content::CDMA_EVDO_FL_INDEX:
+        switch (index) {
+        case 1:
+            return utils::format("%.2f", (float) value / 64);
+        default:
+            break;
+        }
+        break;
+    case Content::CDMA_EVDO_RL_INDEX:
+        switch (index) {
+        case 4:
+        case 5:
+            return utils::format("%.2f", (float) value / 128);
+        default:
+            break;
+        }
+        break;
+    case Content::CDMA_EVDO_STATE_INDEX:
+        switch (index) {
+        case 1:
+            array = {"NEW_SESSION", "ALIVE_SESSION", "PRIOR_SESSION",
+                    "OPENED_SESSION"};
+            break;
+        case 2:
+            array = {"AT_PWROFF", "AT_INACTIVE", "AT_PILOTACQ", "AT_SYNC",
+                    "AT_IDLE", "AT_ACCESS", "AT_CONNECTED"};
+            break;
+        case 3:
+            array = {"ALMP_INIT_STATE", "ALMP_IDLE_STATE", "ALMP_CONN_SETUP_STATE",
+                    "ALMP_CONNECTED_STATE"};
+            break;
+        case 4:
+            array = {"INSP_INACTIVE_STATE", "INSP_NETWORK_DET_STATE",
+                    "INSP_PILOT_ACQ_STATE", "INSP_SYNC_STATE", "INSP_TIMING_CHANGE_STATE",
+                    "INSP_WFR_1XASSTST_STATE"};
+            break;
+        case 5:
+            array = {"IDP_INACTIVE_ST", "IDP_MONITOR_ST", "IDP_SLEEP_ST",
+                    "IDP_CONN_SETUP_ST", "IDP_FREEZE_PENDING_ST", "IDP_FREEZE_ST",
+                    "IDP_CONN_FROZEN_ST", "IDP_STATE_MAX"};
+            break;
+        case 6:
+            array = {"OMP_INACTIVE_ST", "OMP_ACTIVE_ST", "OMP_STATE_MAX"};
+            break;
+        case 7:
+            array = {"CSP_INACTIVE_STATE", "CSP_CLOSING_STATE", "CSP_OPEN_STATE"};
+            break;
+        case 8:
+            array = {"RUP_INACTIVE", "RUP_IDLE", "RUP_CONNECTED",
+                    "RUP_IRAT_MEASUREMENT", "RUP_INVALID"};
+            break;
+        default:
+            break;
+        }
+        break;
+    default:
+        break;
+    }
+
+    if ((!array.empty()) && (value >= 0) && (value < array.size())) {
+        return array[value];
+    }
+    return rawValue;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/networkinfo/NetworkInfoUrcParser.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/networkinfo/NetworkInfoUrcParser.h
new file mode 100644
index 0000000..9842497
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/networkinfo/NetworkInfoUrcParser.h
@@ -0,0 +1,328 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef SRC_EM_NETWORKINFO_NETWORKINFOURCPARSER_H_
+#define SRC_EM_NETWORKINFO_NETWORKINFOURCPARSER_H_
+
+#include <string>
+#include <vector>
+class NetworkInfoUrcParser {
+public:
+    NetworkInfoUrcParser();
+    virtual ~NetworkInfoUrcParser();
+private:
+    static const int DATA_OFFSET_2;
+    static const int DATA_OFFSET_4;
+    static const int DATA_OFFSET_6;
+    static const int DATA_OFFSET_8;
+    static const int DATA_FORMAT;
+    static const int MAX_DATA_PER_LINE;
+
+    static const int TYPE_UINT8;
+    static const int TYPE_UINT16;
+    static const int TYPE_UINT32;
+    static const int TYPE_INT8;
+    static const int TYPE_INT16;
+    static const int TYPE_INT32;
+    static const int TYPE_LONG;
+    static const int TYPE_FLOAT;
+    static const int TYPE_ALIGNMENT;
+    static const int TYPE_STRING;
+
+    static const bool ALIGN_MENT_ENABLE;
+    static const bool GPRS_MODE_ENABLE;
+    static const bool AMR_SUPPORT_ENABLE;
+    static const bool FWPNC_LAI_INFO_ENABLE;
+    static const bool UMTS_R8;
+    static const bool WISDOM_EM;
+    static const bool ADVANCED_EM;
+    static const bool IS_MOLY;
+
+    static const int MODEM_FDD;
+    static const int MODEM_TD;
+
+    std::string mRawString;
+    std::string mResult;
+    int mOffset;
+    std::vector<std::string> mRawValues;
+    std::vector<std::string>  mLabels;
+    int mColumn;
+    int mType;
+private:
+    /**
+     * @param data
+     *            the value of the bit
+     * @param start
+     *            the integer of the start position
+     * @param signed
+     *            the boolean of the signed is false
+     * @return the value of the String for every item
+     */
+    std::string getValueFrom4Byte(std::string data, int start, bool sig);
+    /**
+     * @param data
+     *            the String of the network item information
+     * @param start
+     *            the value of the network item start position bit
+     * @param dataLength
+     *            the block total bit
+     * @param signed
+     *            the define value is false
+     * @return the block value to display
+     */
+    std::string oneBlockFrom4Byte(std::string label, std::string data, int start,bool sig, int dataLength);
+    /**
+     * @param data
+     *            the value of the bit
+     * @param start
+     *            the integer of the start position
+     * @param signed
+     *            the boolean of the signed is false
+     * @return the value of the String for every item
+     */
+    std::string getValueFrom2Byte(std::string data, int start, bool sig);
+    /**
+     * @param data
+     *            the String of the network item information
+     * @param start
+     *            the value of the network item start position bit
+     * @param dataLength
+     *            the block total bit
+     * @param signed
+     *            the define value is false
+     * @return the block value to display
+     */
+    std::string oneBlockFrom2Byte(std::string label, std::string data, int start,bool sig, int dataLength);
+    /**
+     * @param data
+     *            the value of the bit
+     * @param start
+     *            the integer of the start position
+     * @param signed
+     *            the boolean of the signed is false
+     * @return the value of the String for every item
+     */
+    std::string getValueFromByte(std::string data, int start, bool sig);
+    /**
+     * @param data
+     *            the String of the network item information
+     * @param start
+     *            the value of the network item start position bit
+     * @param dataLength
+     *            the block total bit
+     * @param signed
+     *            the define value is false
+     * @return the block value to display
+     */
+    std::string oneBlockFromByte(std::string label, std::string data, int start,bool sig, int dataLength);
+    std::string parseElement(int type, std::string label);
+    std::string parseElement(int type, std::string label, int count);
+    int readIntegerFromByte();
+    int readIntegerFrom2Byte();
+    /*
+     * Modem will encode mcc/mnc before sending to AP, so decode it.
+     * Encoding algorithm:
+     * Suppose MCC is "abc", then encoded MCC will be:
+     * 100 * (a == 0 ? 10 : a) + 10 * (b == 0 ? 10 : b) + (c == 0 ? 10 : c) - 111;
+     * Suppose MNC is "ab", then encoded MNC will be:
+     * 10 * (a == 0 ? 10 : a) + (b == 0 ? 10 : b) - 11;
+     */
+    std::string decodeMcc(int value);
+    std::string decodeMnc(int value);
+    std::vector<std::vector<std::string>> parseCommonCdmaInfo();
+    std::vector<std::vector<std::string>> parseCellInfo();
+    std::vector<std::vector<std::string>> parse1xRttServing();
+    std::string nextValue();
+
+public:
+    /**
+     * @param type
+     *            the integer of the network item to view
+     * @return the value of the network item to display
+     */
+    std::string parseInfo(int type, std::string info, int simType);
+    /**
+     * @return the cellSel information (rr_em_cell_select_para_info_struct)
+     */
+    std::string getCellSelInfo();
+    /**
+     * @return the ChDscr information (rr_em_channel_descr_info_struct)
+     */
+    std::string getChDscrInfo();
+    /**
+     * @return the RACHCtrl information (rr_em_rach_ctrl_para_info_struct)
+     */
+    std::string getRACHCtrlInfo();
+    /**
+     * @return the LAI information
+     */
+    std::string getLAIInfo();
+    /**
+     * @return the Radio Link information (rr_em_radio_link_counter_info_struct)
+     */
+    std::string getRadioLinkInfo();
+    /**
+     * @return the MeasRep information (rr_em_measurement_report_info_struct)
+     */
+    std::string getMeasRepInfo();
+    /**
+     * @return the Calist information (rr_em_ca_list_info_struct)
+     */
+    std::string getCaListInfo();
+    /**
+     * @return the ControlMsg information (rr_em_control_msg_info_struct)
+     */
+    std::string getControlMsgInfo();
+    /**
+     * @return the SI2Q information (rr_em_si2q_info_struct)
+     */
+    std::string getSI2QInfo();
+    /**
+     * @return the MI information (rr_em_mi_info_struct)
+     */
+    std::string getMIInfo();
+    /**
+     * @return the BLK information (rr_em_blk_info_struct)
+     */
+    std::string getBLKInfo();
+    /**
+     * @return the TBF information (rr_em_tbf_status_struct)
+     */
+    std::string getTBFInfo();
+    /**
+     * @return the GPRS GEN information (rr_em_gprs_general_info_struct)
+     */
+    std::string getGPRSGenInfo();
+    std::string get3GGeneralInfo();
+    /**
+     * @return the slce voice information
+     */
+    std::string getSlceVoiceInfo();
+    /**
+     * @return the slce voice information
+     */
+    std::string getSecurityConfigInfo();
+    /**
+     * @return the 3G memory information (mm_em_info_struct)
+     */
+    std::string get3GMmEmInfo();
+    std::string getSmEmInfo();
+    std::string getGmmEmInfo();
+    /**
+     * @return the 3G Tcm information (tcm_mmi_em_info_struct)
+     */
+    std::string get3GTcmMmiEmInfo();
+    /**
+     * @return the 3G CsceEMServCellSStatusInd information (csce_em_serv_cell_s_status_ind_struct)
+     */
+    std::string get3GCsceEMServCellSStatusInd(bool isTdd);
+    /**
+     * @return the 3G CsceEmInfoMultiPlmn information (csce_em_info_multiple_plmn_struct)
+     */
+    std::string get3GCsceEmInfoMultiPlmn();
+
+    /**
+     * @return the 3G MemeEmInfoUmtsCellStatus information (meme_em_info_umts_cell_status_struct)
+     */
+    std::string get3GMemeEmInfoUmtsCellStatus();
+    /**
+     * @return the 3G MemeEmPeriodicBlerReport information (ul2_em_periodic_bler_report_ind)
+     */
+    std::string get3GMemeEmPeriodicBlerReportInd();
+    /**
+     * @return the 3G UrrUmtsSrnc information (urr_umts_srnc_id_struct)
+     */
+    std::string get3GUrrUmtsSrncId();
+    /**
+     * @return the 3G SlceEmPsDataRateStatus information (slce_em_ps_data_rate_status_ind_struct)
+     */
+    std::string get3GSlceEmPsDataRateStatusInd();
+    /**
+     * @return the 3G MemeEmInfoHServCell information (meme_em_info_h_serving_cell_ind_struct)
+     */
+    std::string get3GMemeEmInfoHServCellInd();
+    /**
+     * @return the 3G HandoverSequence information (uas_em_handover_status)
+     */
+    std::string get3GHandoverSequenceIndStuct();
+    /**
+     * @return the Control channel information (rr_em_ctrl_channel_descr_info_struct)
+     */
+    std::string getCtrlchanInfo();
+    /**
+     * @return the 3G Ul2EmAdmPoolStatus information (ul2_em_adm_pool_status_ind_struct)
+     */
+    std::string get3GUl2EmAdmPoolStatusIndStruct();
+    /**
+     * @param isTdd
+     *            is tdd or not
+     *
+     * @return the 3G CsceEMNeighCellSStatus information (csce_em_neigh_cell_s_status_ind_struct)
+     */
+    std::string getxGCsceEMNeighCellSStatusIndStructSize(bool isTdd);
+
+    /**
+     * @return the 3G Ul2EmPsDataRateStatus information (ul2_em_ps_data_rate_status_ind_struct)
+     */
+    std::string get3GUl2EmPsDataRateStatusIndStruct();
+    /**
+     * @return the 3G ul2EmHsdschReconfigStatus information
+     *         (ul2_em_hsdsch_reconfig_status_ind_struct)
+     */
+    std::string get3Gul2EmHsdschReconfigStatusIndStruct();
+    /**
+     * @return the 3G Ul2EmUrlcEventStatus information (ul2_em_urlc_event_status_ind_struct)
+     */
+    std::string get3GUl2EmUrlcEventStatusIndStruct();
+    /**
+     * @return the 3G Ul2EmPeriodicBlerReport information (ul2_em_periodic_bler_report_ind)
+     */
+    std::string get3GUl2EmPeriodicBlerReportInd();
+    std::vector<std::string> parseSecurityStatus(int type, std::string info);
+    std::vector<std::string> parseAntennaDiversity(int type, std::string info);
+    /**
+     * Parse CDMA info.
+     *
+     * @param type
+     *            info type
+     * @param info
+     *            info content
+     * @return formated info
+     */
+    std::vector<std::vector<std::string>> parseCdmaInfo(int type, std::string info);
+
+};
+
+#endif /* SRC_EM_NETWORKINFO_NETWORKINFOURCPARSER_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseRatInfo.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseRatInfo.cpp
new file mode 100644
index 0000000..d9d3629
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseRatInfo.cpp
@@ -0,0 +1,182 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include <string>
+using namespace std;
+
+#include "rfdesense/RfDesenseRatInfo.h"
+#include "rfdesense/RfDesenseTxTest.h"
+
+RfDesenseRatInfo::RfDesenseRatInfo() {
+    // TODO Auto-generated constructor stub
+
+}
+
+RfDesenseRatInfo::~RfDesenseRatInfo() {
+    // TODO Auto-generated destructor stub
+}
+
+std::string RfDesenseRatInfo::getRatName() {
+    return RatName;
+}
+
+void RfDesenseRatInfo::setRatName(std::string mRatname) {
+    if (!mRatname.empty()) {
+        RatName = mRatname;
+    }
+}
+
+bool RfDesenseRatInfo::getRatCheckState() {
+    return RatCheckState;
+}
+
+void RfDesenseRatInfo::setRatCheckState(bool mRatCheckState) {
+    RatCheckState = mRatCheckState;
+}
+
+bool RfDesenseRatInfo::getRatSendState() {
+    return RatSendState;
+}
+
+void RfDesenseRatInfo::setRatSendState(bool mRatSendState) {
+    RatSendState = mRatSendState;
+}
+
+std::string RfDesenseRatInfo::getRatCmdStart() {
+    return RatCmdStart;
+}
+
+void RfDesenseRatInfo::setRatCmdStart(std::string mRatCmdStart) {
+    if (!mRatCmdStart.empty()) {
+        RatCmdStart = mRatCmdStart;
+    }
+}
+
+std::string RfDesenseRatInfo::getRatCmdStop() {
+    return RatCmdStop;
+}
+
+void RfDesenseRatInfo::setRatCmdStop(std::string mRatCmdStop) {
+    if (!mRatCmdStop.empty()) {
+        RatCmdStop = mRatCmdStop;
+    }
+}
+
+std::string RfDesenseRatInfo::getRatCmdSwitch() {
+    return RatCmdSwitch;
+}
+
+void RfDesenseRatInfo::setRatCmdSwitch(std::string mRatCmdSwitch) {
+    RatCmdSwitch = mRatCmdSwitch;
+}
+
+std::string RfDesenseRatInfo::getRatCmdPowerRead() {
+    return RatCmdPowerRead;
+}
+
+void RfDesenseRatInfo::setRatCmdLteBwRb(int ratCmdLteBw, int ratCmdLteRb) {
+    if (ratCmdLteBw == -1) {
+        RatCmdLteBw = DEFAULT_BAND_WIDTH;
+    } else {
+        RatCmdLteBw = ratCmdLteBw;
+    }
+    if (ratCmdLteRb == -1) {
+        RatCmdLteRb = DEFAULT_VRB_LENGTH;
+    } else {
+        RatCmdLteRb = ratCmdLteRb;
+    }
+}
+
+void RfDesenseRatInfo::setRatCmdStart(std::string rat, int channel, int power,
+        int band) {
+    std::string command = "";
+    if (0 == rat.compare(RfDesenseTxTest::mRatName[0])) {  //GSM
+        command = std::string("AT+ERFTX=2,1,") + std::to_string(channel) + ","
+                + std::to_string(4100) + "," + std::to_string(band) + ","
+                + std::to_string(0) + "," + std::to_string(power) + ","
+                + std::to_string(0);
+    } else if (0 == rat.compare(RfDesenseTxTest::mRatName[1])) {    //TDSCDMA
+        command = std::string("AT+ERFTX=0,0,") + std::to_string(band) + ","
+                + std::to_string(channel) + "," + std::to_string(power);
+    } else if (0 == rat.compare(RfDesenseTxTest::mRatName[2])) {    //WCDMA
+        command = std::string("AT+ERFTX=0,0,") + std::to_string(band) + ","
+                + std::to_string(channel) + "," + std::to_string(power);
+    } else if (0 == rat.compare(RfDesenseTxTest::mRatName[3])) {    //LTE(FDD)
+        command = std::string("AT+ERFTX=6,0,2,") + std::to_string(band) + ","
+                + std::to_string(RatCmdLteBw) + "," + std::to_string(channel)
+                + ",1,0,0,0," + std::to_string(RatCmdLteRb) + "," + "0,"
+                + std::to_string(power);
+    } else if (0 == rat.compare(RfDesenseTxTest::mRatName[4])) {    //LTE(TDD)
+        command = std::string("AT+ERFTX=6,0,2,") + std::to_string(band) + ","
+                + std::to_string(RatCmdLteBw) + "," + std::to_string(channel)
+                + ",0,0,0,0," + std::to_string(RatCmdLteRb) + "," + "0,"
+                + std::to_string(power);
+    } else if (0 == rat.compare(RfDesenseTxTest::mRatName[5])) {    //CDMA(EVDO)
+        command = std::string("AT+ERFTX=13,4,") + std::to_string(channel) + ","
+                + std::to_string(band) + "," + std::to_string(power);
+    } else if (0 == rat.compare(RfDesenseTxTest::mRatName[6])) {    //CDMA(1x)
+        command = std::string("AT+ECRFTX=1,") + std::to_string(channel) + ","
+                + std::to_string(band) + "," + std::to_string(power) + ",0";
+    }
+    RatCmdStart = command;
+}
+
+void RfDesenseRatInfo::setRatPowerRead(std::string mRatCmdPowerRead) {
+    RatCmdPowerRead = mRatCmdPowerRead;
+}
+
+std::string RfDesenseRatInfo::getRatband() {
+    return Ratband;
+}
+
+void RfDesenseRatInfo::setRatband(std::string ratband) {
+    Ratband = ratband;
+}
+
+std::string RfDesenseRatInfo::getRatPowerSet() {
+    return RatPowerSet;
+}
+
+void RfDesenseRatInfo::setRatPowerSet(std::string ratPowerSet) {
+    RatPowerSet = ratPowerSet;
+}
+
+int RfDesenseRatInfo::getRatTxtimes() {
+    return RatTxtimes;
+}
+
+void RfDesenseRatInfo::setRatTxtimes(int ratTxtimes) {
+    RatTxtimes = ratTxtimes;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseRatInfo.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseRatInfo.h
new file mode 100644
index 0000000..5bc106f
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseRatInfo.h
@@ -0,0 +1,84 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef RFDESENSERATINFO_H_
+#define RFDESENSERATINFO_H_
+
+#include <string>
+class RfDesenseRatInfo {
+public:
+    const int DEFAULT_BAND_WIDTH = 3;
+    const int DEFAULT_VRB_LENGTH = 1;
+    RfDesenseRatInfo();
+    virtual ~RfDesenseRatInfo();
+    std::string getRatName();
+    void setRatName(std::string mRatname);
+    bool getRatCheckState();
+    void setRatCheckState(bool mRatCheckState);
+    bool getRatSendState();
+    void setRatSendState(bool mRatSendState);
+    std::string getRatCmdStart();
+    void setRatCmdStart(std::string mRatCmdStart);
+    std::string getRatCmdStop();
+    void setRatCmdStop(std::string mRatCmdStop);
+    std::string getRatCmdSwitch();
+    void setRatCmdSwitch(std::string mRatCmdSwitch);
+    std::string getRatCmdPowerRead();
+    void setRatCmdLteBwRb(int ratCmdLteBw, int ratCmdLteRb);
+    void setRatCmdStart(std::string rat, int channel, int power, int band);
+    void setRatPowerRead(std::string mRatCmdPowerRead);
+    std::string getRatband();
+    void setRatband(std::string ratband);
+    std::string getRatPowerSet();
+    void setRatPowerSet(std::string ratPowerSet);
+    int getRatTxtimes();
+    void setRatTxtimes(int ratTxtimes);
+private:
+    std::string RatName;
+    std::string RatCmdStart;
+    std::string RatCmdStop;
+    std::string Ratband;
+    std::string RatPowerSet;
+    std::string RatCmdSwitch;
+    std::string RatCmdPowerRead;
+    bool RatCheckState;
+    bool RatSendState;
+
+    int RatCmdLteRb;
+    int RatCmdLteBw;
+    int RatTxtimes;
+};
+
+#endif /* RFDESENSERATINFO_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTest.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTest.cpp
new file mode 100644
index 0000000..94afa42
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTest.cpp
@@ -0,0 +1,48 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include <memory>
+
+#include "rfdesense/RfDesenseTxTest.h"
+#include "em/em.h"
+
+static RfDesenseTxTest* mTx = NULL;
+int emRfDesenseStart(int len,int *item,int multilen,char *value[]) {
+    if(!mTx) {
+        mTx = RfDesenseTxTest::getInstance();
+    }
+    mTx->emRfDesenseStart(len,item, multilen, value);
+    return 0;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTest.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTest.cpp
new file mode 100644
index 0000000..26759a1
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTest.cpp
@@ -0,0 +1,1233 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include "rfdesense/RfDesenseTxTest.h"
+
+#include <memory>
+#include <list>
+#include <regex>
+#include <cmath>
+#include <string>
+#include <cstdarg>
+#include <cstring>
+
+#include <vendor-ril/telephony/ril.h>
+
+#include  "common.h"
+#include "em.h"
+#include "rfdesense/RfDesenseTxTestCdma.h"
+#include "rfdesense/RfDesenseTxTestGsm.h"
+#include "rfdesense/RfDesenseTxTestLte.h"
+#include "rfdesense/RfDesenseTxTestTd.h"
+#include "util/log_extra.h"
+#include "util/utils.h"
+
+#undef LOG_TAG
+#define LOG_TAG "EM_RfDesenseTxTest"
+
+RfDesenseTxTest* RfDesenseTxTest::m_instance = NULL;
+std::mutex RfDesenseTxTest::mMutex;
+
+const int RfDesenseTxTest::STATE_NONE = 0;
+const int RfDesenseTxTest::STATE_STARTED = 1;
+const int RfDesenseTxTest::STATE_STOPPED = 2;
+
+const int RfDesenseTxTest::MSG_START_TX = 1;
+const int RfDesenseTxTest::MSG_NEXT_RAT = 4;
+const int RfDesenseTxTest::MSG_READ_POWER = 10;
+const int RfDesenseTxTest::MSG_EWMPOLICY_TDSCDMA = 12;
+const int RfDesenseTxTest::MSG_EWMPOLICY_WCDMA = 13;
+const int RfDesenseTxTest::MSG_ECSRA = 14;
+const int RfDesenseTxTest::MSG_SWITCH_RAT_DONE = 15;
+
+int RfDesenseTxTest::mState = STATE_NONE;
+
+long RfDesenseTxTest::mTestDuration = 10;
+long RfDesenseTxTest::mTestCount = 1;
+long RfDesenseTxTest::mTestDurationSended = 0;
+long RfDesenseTxTest::mTestCountSended = 0;
+long RfDesenseTxTest::mCheckLimit = 2;
+long RfDesenseTxTest::mReadbackInterval = 5;
+
+const std::string RfDesenseTxTest::KEY_GSM_ATCMD = "gsm_at_cmd";
+const std::string RfDesenseTxTest::KEY_TDSCDMA_ATCMD = "tdscdma_at_cmd";
+const std::string RfDesenseTxTest::KEY_WCDMA_ATCMD = "wcdma_at_cmd";
+const std::string RfDesenseTxTest::KEY_LTE_FDD_ATCMD = "lte_fdd_at_cmd";
+const std::string RfDesenseTxTest::KEY_LTE_TDD_ATCMD = "lte_tdd_at_cmd";
+const std::string RfDesenseTxTest::KEY_CDMA_1X_ATCMD = "cdma_at_cmd";
+const std::string RfDesenseTxTest::KEY_CDMA_EVDO_ATCMD = "cdma_evdo_at_cmd";
+const std::string RfDesenseTxTest::KEY_TEST_DURATION = "test_duration";
+const std::string RfDesenseTxTest::KEY_TEST_COUNT = "test_count";
+const std::string RfDesenseTxTest::KEY_CHECK_LIMIT = "check_limit";
+const std::string RfDesenseTxTest::KEY_READBACK_INTREVAL = "readback_interval";
+
+const std::string RfDesenseTxTest::DEFAULT_GSM_ATCMD =
+            "AT+ERFTX=2,1,190,4100,128,0,5,0";
+const std::string RfDesenseTxTest::DEFAULT_TDSCDMA_ATCMD = "AT+ERFTX=0,0,1,10087,24";
+const std::string RfDesenseTxTest::DEFAULT_WCDMA_ATCMD = "AT+ERFTX=0,0,1,9750,23";
+const std::string RfDesenseTxTest::DEFAULT_LTE_FDD_ATCMD =
+            "AT+ERFTX=6,0,1,3,3,17475,1,0,0,0,1,0,23";
+const std::string RfDesenseTxTest::DEFAULT_LTE_TDD_ATCMD =
+            "AT+ERFTX=6,0,1,38,3,25950,0,0,0,0,1,0,23";
+const std::string RfDesenseTxTest::DEFAULT_CDMA_EVDO_ATCMD = "AT+ERFTX=13,4,384,0,83";
+const std::string RfDesenseTxTest::DEFAULT_CDMA_1X_ATCMD = "AT+ECRFTX=1,384,0,83,0";
+
+const std::string RfDesenseTxTest::DEFAULT_CDMA_EVDO_ATCMD_93before =
+            "AT+ERFTX=1,384,0,83,1";
+
+const std::vector<std::string> RfDesenseTxTest::mRatName = { "GSM", "TDSCDMA", "WCDMA",
+            "LTE(FDD)", "LTE(TDD)", "CDMA(EVDO)", "CDMA(1X)" };
+std::vector<std::string> RfDesenseTxTest::mRatCmdStart = { DEFAULT_GSM_ATCMD,
+            DEFAULT_TDSCDMA_ATCMD, DEFAULT_WCDMA_ATCMD, DEFAULT_LTE_FDD_ATCMD,
+            DEFAULT_LTE_TDD_ATCMD, DEFAULT_CDMA_EVDO_ATCMD,
+            DEFAULT_CDMA_1X_ATCMD };
+
+std::vector<std::string> RfDesenseTxTest::mRatCmdStop = { "AT+ERFTX=2,0",
+            "AT+ERFTX=0,1", "AT+ERFTX=0,1", "AT+ERFTX=6,0,0", "AT+ERFTX=6,0,0",
+            "AT+ERFTX=13,5", "AT+ECRFTX=0" };
+
+ std::vector<std::string> RfDesenseTxTest::mRatCmdSwitch = { "AT+ERAT=0", "AT+ERAT=1",
+            "AT+ERAT=1", "AT+ERAT=6,4", "AT+ERAT=6,4", "AT+ERAT=7,64",
+            "AT+ERAT=7,32" };
+
+std::vector<std::string> RfDesenseTxTest::mRatCmdPowerRead = { "", "AT+ERFTX=0,3",
+            "AT+ERFTX=0,3", "AT+ERFTX=6,1", "AT+ERFTX=6,1", "AT+ERFTX=13,3",
+            "AT+ERFTX=13,3" };
+std::vector<std::string> RfDesenseTxTest::mRatBand = { "19", "1", "1", "3", "38", "0", "0" };
+std::vector<std::string> RfDesenseTxTest::mRatPowerSet = { "19", "10", "24", "23", "23", "23", "23" };
+std::vector<bool> RfDesenseTxTest::mRatCheck = {false, false,false,false,false,false,false};
+std::vector<bool> RfDesenseTxTest::mSendState = {false, false,false,false,false,false,false};
+std::string RfDesenseTxTest::str_msg = "";
+bool RfDesenseTxTest::trm_flag = false;
+int RfDesenseTxTest::phone_id = 0;
+
+void RfDesenseTxTest::rf_send_at_cmd(std::string cmd, int flag){
+    mCurrentFlag = flag;
+    emSendATCommand(cmd.c_str(),phone_id);
+}
+
+//create thread to send command
+void RfDesenseTxTest::emRfDesenseThread(int id) {
+    mState = STATE_STARTED;
+    int operatorid = id;
+    LOG_D(LOG_TAG, "emRfDesenseThread: operatorid(%d)", operatorid);
+    switch (operatorid) {
+        case 0:{
+            if (trm_flag) {
+                LOG_D(LOG_TAG, "wait modem reset done");
+                std::this_thread::sleep_for(std::chrono::milliseconds(1000*5));
+                trm_flag = false;
+            }
+            if(isRadioOn((RIL_SOCKET_ID)phone_id)) {
+                LOG_D(LOG_TAG, "radio already on");
+                mIsModemEnabled = false;
+                emRadioStateOn();
+            } else {
+                while(!isRadioOn((RIL_SOCKET_ID)phone_id)) {
+                    LOG_D(LOG_TAG, "radio isn't on");
+                    std::this_thread::sleep_for(std::chrono::milliseconds(200));
+                }
+                //turnOnRf();
+                LOG_D(LOG_TAG, "radio on again");
+                registerRadioOn(m_instance);
+                mIsModemEnabled = false;
+            }
+            break;
+        }
+    }
+}
+
+void RfDesenseTxTest::emRadioStateOn(){
+    if (mIsModemEnabled == true) {
+        LOG_D(LOG_TAG, "mIsModemEnabled is true, just return");
+        return;
+    }
+    mIsModemEnabled = true;
+    LOG_D(LOG_TAG, "turn on rf succeed");
+    if (mState == STATE_STARTED) {
+        mCurrectRatInfo = getCurrectRatInfo();
+        if (mCurrectRatInfo
+                && !mCurrectRatInfo->getRatCmdSwitch().empty()) {
+            LOG_D(LOG_TAG, "switch rat(%s)",mCurrectRatInfo->getRatCmdSwitch().c_str());
+            //unregisterRadioOn();
+            rf_send_at_cmd(mCurrectRatInfo->getRatCmdSwitch(), MSG_SWITCH_RAT_DONE);
+        } else {
+            LOG_D(LOG_TAG, "mCurrectRatInfo == null");
+        }
+    }
+}
+
+void RfDesenseTxTest::emRadioStateOfforNotAvailable() {
+    //unregisterRadioOffOrNotAvailable();
+    if (mIsModemNotEnabled == true) {
+        LOG_D(LOG_TAG, "mIsModemNotEnabled is true, just return");
+        return;
+    }
+    mIsModemNotEnabled = true;
+    LOG_D(LOG_TAG, "turn off rf succeed...");
+    if (mCurrectRatInfo) {
+        mCurrectRatInfo->setRatSendState(true);
+        rf_send_at_cmd(mCurrectRatInfo->getRatCmdStart(), MSG_START_TX);
+        LOG_D(LOG_TAG, "send: %s  %s",mCurrectRatInfo->getRatName().c_str() ,mCurrectRatInfo->getRatCmdStart().c_str());
+    } else {
+        LOG_D(LOG_TAG, "mCurrectRatInfo == null");
+    }
+}
+
+void RfDesenseTxTest::emOemHookRaw(int value, int slot_id){
+    if(slot_id != phone_id) {
+        LOG_W(LOG_TAG, "slot_id = %d, main_slot: %d", slot_id, phone_id);
+        //return;
+    }
+    LOG_D(LOG_TAG, "Readback tx power = %d", value);
+    std::string result = "";
+    std::string rat = "";
+    std::lock_guard<std::mutex> guard(mMutex);
+    m_rawUrc = true;
+    m_condVar.notify_one();
+    float getPower = value / 8.0f;
+    if (std::abs(std::stoi(mCurrectRatInfo->getRatPowerSet()) -
+            getPower) > mCheckLimit) {
+        result = "failed\n";
+    } else {
+        result = "succeed\n";
+    }
+
+    std::string s = std::string("Start TX:\n")
+            + std::string("Rat(band)          ") + std::string("Power_Set   ")
+            + std::string("Power_Get    ") + std::string("Result\n");
+    rat = utils::format("%-20s %-15s %-10s",
+            (mCurrectRatInfo->getRatName()+ "(b" + mCurrectRatInfo->getRatband() + ")").c_str(),
+            mCurrectRatInfo->getRatPowerSet().c_str(),
+            std::to_string(getPower).c_str()
+    );
+    std::string ret;
+    if (!result.compare("failed\n")) {
+        ret = utils::format("%10s", result.c_str());
+    } else {
+        ret = utils::format("%10s", result.c_str());
+    }
+    str_msg += s + rat + ret;
+
+}
+
+void RfDesenseTxTest::tx_stop() {
+    LOG_D(LOG_TAG,"tx_stop");
+    std::unique_lock<std::mutex> mlock(mMutex);
+    m_condVar.wait(mlock,[this]{return m_rawUrc;});
+    txTestStop(MSG_NEXT_RAT);
+}
+
+void RfDesenseTxTest::init() {
+    mRequestHandleThread = new RequestHandleThread(this);
+    mRequestHandleThread->run();
+}
+
+RfDesenseTxTest::RfDesenseTxTest() {
+    initRatList();
+}
+
+RfDesenseTxTest::~RfDesenseTxTest() {
+    LOG_D(LOG_TAG, "RfDesenseTxTest destroyed");
+}
+
+void RfDesenseTxTest::txTestStop(int what) {
+    if (mCurrectRatInfo) {
+        rf_send_at_cmd(mCurrectRatInfo->getRatCmdStop(), what);
+        LOG_D(LOG_TAG, "stop: %s %s", mCurrectRatInfo->getRatName().c_str(), mCurrectRatInfo->getRatCmdStop().c_str());
+    } else {
+        LOG_D(LOG_TAG, "mCurrectRatInfo is null");
+        mState = STATE_STOPPED;
+        for (int i = 0; i < mRatList.size(); i++) {
+            mRatList[i]->setRatSendState(false);
+            mRatList[i]->setRatCheckState(false);
+        }
+    }
+}
+
+void RfDesenseTxTest::deInit() {
+
+}
+
+RfDesenseTxTest* RfDesenseTxTest::getInstance() {
+    if(!m_instance) {
+        mMutex.lock();
+        if(!m_instance) {
+            m_instance = new RfDesenseTxTest();
+            m_instance->init();
+        }
+        mMutex.unlock();
+    }
+    return m_instance;
+}
+
+// Method implements of RequestHandleThread
+RfDesenseTxTest::RequestHandleThread::RequestHandleThread(RfDesenseTxTest* tx) : m_looper(NULL) {
+    mTx = tx;
+    LOG_D(LOG_TAG, "RequestHandleThread created");
+}
+
+RfDesenseTxTest::RequestHandleThread::~RequestHandleThread() {
+    mTx = NULL;
+    LOG_D(LOG_TAG, "RequestHandleThread destroyed");
+}
+
+bool RfDesenseTxTest::RequestHandleThread::threadLoop() {
+    LOG_D(LOG_TAG, "RequestHandleThread threadLoop");
+    // start message loop
+    m_looper = Looper::prepare(0);
+    int result;
+    do {
+        result = m_looper->pollAll(-1);
+        LOG_D(LOG_TAG, "RequestHandleThread threadLoop, pull message result = %d", result);
+    } while (result == Looper::POLL_WAKE || result == Looper::POLL_CALLBACK);
+    return true;
+}
+
+sp<Looper> RfDesenseTxTest::RequestHandleThread::getLooper() {
+    return m_looper;
+}
+
+RfDesenseTxTest::RfRequestMessage::RfRequestMessage(RfDesenseTxTest* tx) : mTx(tx),mMsgType(0),
+        response(""),responselen(0), slot(0), e(RIL_E_SUCCESS) {
+}
+
+RfDesenseTxTest::RfRequestMessage::~RfRequestMessage() {
+    LOG_D(LOG_TAG, "RequestHandleThread destroyed");
+}
+
+void RfDesenseTxTest::RfRequestMessage::sendMessage(int delayms) {
+    LOG_D(LOG_TAG, "RfDesenseTxTest::RfRequestMessage, sendMessage delayms=%d", delayms);
+    if(mTx != NULL) {
+        mTx->sendMessage(this, delayms);
+    } else {
+        LOG_D(LOG_TAG, "RfDesenseTxTest::RfRequestHandler mTx is null");
+    }
+}
+
+void RfDesenseTxTest::RfRequestHandler::sendMessage(sp<RfRequestMessage> msg, int delayms) {
+    LOG_D(LOG_TAG, "RfDesenseTxTest::RfRequestHandler, sendMessage msg what=%d delayms=%d", msg->mMsgType, delayms);
+    this->mMsg = msg;
+    if(mTx != NULL) {
+        mTx->sendMessage(mMsg, delayms);
+    } else {
+        LOG_D(LOG_TAG, "RfDesenseTxTest::RfRequestHandler mTx is null");
+    }
+}
+
+RfDesenseTxTest::RfRequestHandler:: ~RfRequestHandler() {
+    mTx = NULL;
+    LOG_D(LOG_TAG, "RfRequestHandler destroyed");
+}
+
+void RfDesenseTxTest::handle_request(string response,int responselen,int slot, RIL_Errno e) {
+    sp<RfRequestMessage> msg = new RfRequestMessage(this);
+    msg->mMsgType = mCurrentFlag;
+    msg->response = response;
+    msg->responselen = responselen;
+    msg->slot = slot;
+    msg->e = e;
+    if(mCurrentFlag == MSG_READ_POWER) {
+        sendMessage(msg, 2*1000);
+    } else {
+        sendMessage(msg, 1000);
+    }
+}
+
+sp<RfDesenseTxTest::RfRequestHandler> RfDesenseTxTest::sendMessage(sp<RfRequestMessage> msg, int delayms) {
+    LOG_D(LOG_TAG, "sendMessage msg token=%d delayms=%d", msg->mMsgType, delayms);
+    sp<RfRequestHandler> handler = new RfRequestHandler(this);
+    handler->mMsg = msg;
+    if(mRequestHandleThread.get()) {
+        sp<Looper> looper = mRequestHandleThread->getLooper();
+        if(looper.get()) {
+            if (delayms > 0) {
+                looper->sendMessageDelayed(ms2ns(delayms),handler, handler->m_dummyMsg);
+            } else {
+                looper->sendMessage(handler, handler->m_dummyMsg);
+            }
+        } else {
+            LOG_D(LOG_TAG, "looper fail");
+        }
+    } else {
+        LOG_D(LOG_TAG, "mRequestHandleThread fail");
+    }
+
+    return handler;
+}
+
+void RfDesenseTxTest::emRfDesenseAtCmdHandle(sp<RfRequestMessage> msg){
+    LOG_D(LOG_TAG, "emRfDesenseAtCmdHandle, type: %d", msg->mMsgType);
+    int responselen = msg->responselen;
+    std::string response = msg->response;
+    switch (msg->mMsgType) {
+    case MSG_SWITCH_RAT_DONE: {
+        if (msg->e == RIL_E_SUCCESS) {
+            LOG_D(LOG_TAG, "switch rat succeed");
+            if (mCurrectRatInfo->getRatName() == mRatName[1]) { // tdscdma
+                LOG_D(LOG_TAG, "end AT+EWMPOLICY=0");
+                rf_send_at_cmd("AT+EWMPOLICY=0", MSG_EWMPOLICY_TDSCDMA);
+            } else if (mCurrectRatInfo->getRatName() == mRatName[2]) { // wcdma
+                LOG_D(LOG_TAG,  "send AT+EWMPOLICY=0");
+                rf_send_at_cmd("AT+EWMPOLICY=0", MSG_EWMPOLICY_WCDMA);
+            } else { // other rat
+                registerRadioOffOrNotAvailable(m_instance);
+                turnOffRf();
+            }
+        } else {
+            LOG_D(LOG_TAG, "switch rat failed");
+            emResultNotifyWithDone(mCurrectRatInfo->getRatName() + " switch rat failed\n");
+        }
+        break;
+    }
+    case MSG_EWMPOLICY_TDSCDMA: {
+        LOG_D(LOG_TAG, "AT+EWMPOLICY=0 send succeed");
+        LOG_D(LOG_TAG, "send AT+ECSRA=2,0,1,0,1,0 ...");
+        rf_send_at_cmd("AT+ECSRA=2,0,1,0,1,0", MSG_ECSRA);
+        break;
+    }
+    case MSG_EWMPOLICY_WCDMA: {
+        LOG_D(LOG_TAG, "AT+EWMPOLICY=0 send succeed");
+        LOG_D(LOG_TAG, "send AT+ECSRA=2,1,0,1,1,0 ...");
+        rf_send_at_cmd("AT+ECSRA=2,1,0,1,1,0", MSG_ECSRA);
+        break;
+    }
+    case MSG_ECSRA: {
+        LOG_D(LOG_TAG, "AT+ECSRA send succeed");
+        turnOffRf();
+        break;
+    }
+    case MSG_START_TX:{
+        if (msg->e == RIL_E_SUCCESS) {
+            LOG_D(LOG_TAG, "start cmd ok");
+            if (utils::is93Modem() && mCurrectRatInfo && !mCurrectRatInfo->getRatCmdPowerRead().empty()) {
+                LOG_D(LOG_TAG,"start read cmd: %s", mCurrectRatInfo->getRatCmdPowerRead().c_str());
+                rf_send_at_cmd(mCurrectRatInfo->getRatCmdPowerRead(), MSG_READ_POWER);
+            } else {
+                LOG_D(LOG_TAG, "don't read");
+                txTestStop(MSG_NEXT_RAT);
+            }
+        } else {
+            LOG_D(LOG_TAG, "start cmd failed");
+            emResultNotifyWithDone(mCurrectRatInfo->getRatName() + " start cmd failed\n");
+        }
+        break;
+    }
+    case MSG_READ_POWER:{
+        mTestDurationSended += mReadbackInterval;
+        if (mTestDurationSended >= mTestDuration) {
+            if (msg->e == RIL_E_SUCCESS) {
+                LOG_D(LOG_TAG, "read tx power succeed");
+                if(m_rawUrc){
+                    txTestStop(MSG_NEXT_RAT);
+                    m_rawUrc = false;
+                } else {
+                   std::thread thread_stop(&RfDesenseTxTest::tx_stop, m_instance);
+                   thread_stop.detach();
+                }
+            } else {
+                LOG_D(LOG_TAG, "read tx power failed");
+                emResultNotifyWithDone(mCurrectRatInfo->getRatName() + " read tx power failed\n");
+            }
+            mTestDurationSended = 0;
+        } else {
+            if (utils::is93Modem() && mCurrectRatInfo && !mCurrectRatInfo->getRatCmdPowerRead().empty()) {
+                LOG_D(LOG_TAG,"(sencond)start read cmd: %s", mCurrectRatInfo->getRatCmdPowerRead().c_str());
+                rf_send_at_cmd(mCurrectRatInfo->getRatCmdPowerRead(),  MSG_READ_POWER);
+            } else {
+                LOG_D(LOG_TAG,"(sencond)start read cmd fail");
+            }
+        }
+        break;
+    }
+    case MSG_NEXT_RAT: {
+        if (msg->e == RIL_E_SUCCESS) {
+            std::string rat = mCurrectRatInfo->getRatName();
+            LOG_D(LOG_TAG, "stop(%s) cmd ok", rat.c_str());
+            mCurrectRatInfo = getCurrectRatInfo();
+            if (mCurrectRatInfo) {
+                LOG_D(LOG_TAG, "error, mCurrectRatInfo should null ");
+            }
+            emResultNotifyWithDone(str_msg + "send all rat done\n");
+            str_msg = "";
+            mState = STATE_STOPPED;
+            for (int i = 0; i < mRatList.size(); i++) {
+                mRatList[i]->setRatSendState(false);
+                mRatList[i]->setRatCheckState(false);
+            }
+//            if(rat == mRatName[1] || rat == mRatName[2]) {
+//                if(utils::is93Modem()){
+//                    utils::mtk_property_set("vendor.ril.mux.report.case", "2");
+//                    utils::mtk_property_set("vendor.ril.muxreport", "1");
+//                }else {
+//                    emSendATCommand("AT+CFUN=1,1");
+//                }
+//                trm_flag = true;
+//            } else {
+//                turnOnRf();
+//            }
+            turnOnRf();
+            trm_flag = true;
+            unregister_response_oem_hook_raw();
+            unregisterOnUnsolOemHookRaw();
+        } else {
+            LOG_D(LOG_TAG, "stop cmd failed");
+            emResultNotifyWithDone(mCurrectRatInfo->getRatName() + " stop cmd failed \n");
+        }
+        break;
+    }
+    default:
+        break;
+    }
+}
+
+void RfDesenseTxTest::RfRequestHandler::handleMessage(const Message& message) {
+    LOG_D(LOG_TAG, "handleMessage msg->mMsgType: %d", mMsg->mMsgType);
+    if(mTx != NULL) {
+        mTx->emRfDesenseAtCmdHandle(mMsg);
+    } else {
+        LOG_D(LOG_TAG, "handleMessage mTx is null");
+    }
+}
+
+void RfDesenseTxTest::handle_gsm_para(const std::string& name, int last_pos,
+        const std::string& sub_name) {
+    bool flag = false;
+    std::shared_ptr<RfDesenseTxTestGsm> gsm =
+            RfDesenseTxTestGsm::get_instance();
+    if (name == rfdesense_gsm_sub[INDEX_GSM_SUB_BAND].name) {
+        flag = gsm->set_band(last_pos);
+    } else if (name == rfdesense_gsm_sub[INDEX_GSM_SUB_CHANNEL].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            gsm->show_channel();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = gsm->set_channel(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    } else if (name == rfdesense_gsm_sub[INDEX_GSM_SUB_POWER].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            gsm->show_power();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = gsm->set_power(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    } else if (name == rfdesense_gsm_sub[INDEX_GSM_SUB_AFC].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            gsm->show_afc();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = gsm->set_afc(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    } else if (name == rfdesense_gsm_sub[INDEX_GSM_SUB_TSC].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            gsm->show_tsc();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = gsm->set_tsc(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    } else if (name == rfdesense_gsm_sub[INDEX_GSM_SUB_PATTERN].name) {
+        flag = gsm->set_pattern(last_pos);
+    }
+
+    if (flag) {
+        mRatList[INDEX_GSM]->setRatCmdStart(gsm->get_command());
+        mRatList[INDEX_GSM]->setRatband(gsm->get_band());
+        mRatList[INDEX_GSM]->setRatPowerSet(gsm->get_power());
+        save(INDEX_GSM);
+    }
+}
+
+void RfDesenseTxTest::handle_tdscdma_para(const std::string& name, int last_pos,
+        const std::string& sub_name) {
+    //"TDSCDMA"
+    bool flag = false;
+    std::shared_ptr<RfDesenseTxTestTd> tdscdma = std::make_shared<
+            RfDesenseTxTestTd>(utils::MODEM_TDSCDMA);
+    if (name == rfdesense_tdscdma_sub[INDEX_3G_SUB_BAND].name) {
+        flag = tdscdma->set_band(last_pos);
+    } else if (name == rfdesense_tdscdma_sub[INDEX_3G_SUB_CHANNEL].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            tdscdma->show_channel();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = tdscdma->set_channel(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    } else if (name == rfdesense_tdscdma_sub[INDEX_3G_SUB_POWER].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            tdscdma->show_power();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = tdscdma->set_power(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    } else {
+        LOG_D(LOG_TAG, "logic error");
+    }
+
+    if (flag) {
+        mRatList[INDEX_TDSCDMA]->setRatCmdStart(tdscdma->get_command());
+        mRatList[INDEX_TDSCDMA]->setRatband(tdscdma->get_band());
+        mRatList[INDEX_TDSCDMA]->setRatPowerSet(tdscdma->get_power());
+        save(INDEX_TDSCDMA);
+    }
+}
+
+void RfDesenseTxTest::handle_wcdma_para(const std::string& name, int last_pos,
+        const std::string& sub_name) {
+    //"WCDMA"
+    bool flag = false;
+    std::shared_ptr<RfDesenseTxTestTd> wcdma = std::make_shared<
+            RfDesenseTxTestTd>(utils::MODEM_WCDMA);
+    if (name == rfdesense_wcdma_sub[INDEX_3G_SUB_BAND].name) {
+        flag = wcdma->set_band(last_pos);
+    } else if (name == rfdesense_wcdma_sub[INDEX_3G_SUB_CHANNEL].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            wcdma->show_channel();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = wcdma->set_channel(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    } else if (name == rfdesense_wcdma_sub[INDEX_3G_SUB_POWER].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            wcdma->show_power();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = wcdma->set_power(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    } else {
+        LOG_D(LOG_TAG, "logic error");
+    }
+
+    if (flag) {
+        mRatList[INDEX_WCDMA]->setRatCmdStart(wcdma->get_command());
+        mRatList[INDEX_WCDMA]->setRatband(wcdma->get_band());
+        mRatList[INDEX_WCDMA]->setRatPowerSet(wcdma->get_power());
+        save(INDEX_WCDMA);
+    }
+}
+
+void RfDesenseTxTest::handle_lte_fdd_para(const std::string& name, int last_pos,
+        const std::string& sub_name) {
+    //LTE(FDD)
+    bool flag = false;
+    std::shared_ptr<RfDesenseTxTestLte> fdd = std::make_shared<
+            RfDesenseTxTestLte>(utils::MODEM_LTE_FDD);
+    if (name == rfdesense_fdd_sub[INDEX_FDD_SUB_MODE].name) {
+        flag = fdd->set_mode(last_pos);
+    } else if (name == rfdesense_fdd_sub[INDEX_FDD_SUB_BAND].name) {
+        flag = fdd->set_band(last_pos);
+    } else if (name == rfdesense_fdd_sub[INDEX_FDD_SUB_BANDWITH].name) {
+        flag = fdd->set_bandwith(last_pos);
+    } else if (name == rfdesense_fdd_sub[INDEX_FDD_SUB_FREQ].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            fdd->show_freq();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = fdd->set_freq(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    } else if (name == rfdesense_fdd_sub[INDEX_FDD_SUB_START].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            fdd->show_start();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = fdd->set_start(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    } else if (name == rfdesense_fdd_sub[INDEX_FDD_SUB_LENGTH].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            fdd->show_length();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = fdd->set_length(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    } else if (name == rfdesense_fdd_sub[INDEX_FDD_SUB_MCS].name) {
+        flag = fdd->set_mcs(last_pos);
+    } else if (name == rfdesense_fdd_sub[INDEX_FDD_SUB_POWER].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            fdd->show_power();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = fdd->set_power(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    } else {
+        LOG_D(LOG_TAG, "error");
+    }
+
+    if (flag) {
+        mRatList[INDEX_LTE_FDD]->setRatCmdStart(fdd->get_command());
+        mRatList[INDEX_LTE_FDD]->setRatband(fdd->get_band());
+        mRatList[INDEX_LTE_FDD]->setRatPowerSet(fdd->get_power());
+        save(INDEX_LTE_FDD);
+    }
+}
+
+void RfDesenseTxTest::handle_lte_tdd_para(const std::string& name, int last_pos,
+        const std::string& sub_name) {
+    //LTE(TDD)
+    bool flag = false;
+    std::shared_ptr<RfDesenseTxTestLte> tdd = std::make_shared<
+            RfDesenseTxTestLte>(utils::MODEM_LTE_TDD);
+    if (name == rfdesense_tdd_sub[INDEX_TDD_SUB_MODE].name) {
+        flag = tdd->set_mode(last_pos);
+    } else if (name == rfdesense_tdd_sub[INDEX_TDD_SUB_BAND].name) {
+        flag = tdd->set_band(last_pos);
+    } else if (name == rfdesense_tdd_sub[INDEX_TDD_SUB_BANDWIDTH].name) {
+        flag = tdd->set_bandwith(last_pos);
+    } else if (name == rfdesense_tdd_sub[INDEX_TDD_SUB_FREQ].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            tdd->show_freq();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = tdd->set_freq(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    } else if (name == rfdesense_tdd_sub[INDEX_TDD_SUB_CONFIG].name) {
+        flag = tdd->set_tdd_config(last_pos);
+    } else if (name == rfdesense_tdd_sub[INDEX_TDD_SUB_SPECIAL].name) {
+        flag = tdd->set_tdd_special(last_pos);
+    } else if (name == rfdesense_tdd_sub[INDEX_TDD_SUB_START].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            tdd->show_start();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = tdd->set_start(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    } else if (name == rfdesense_tdd_sub[INDEX_TDD_SUB_LENGTH].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            tdd->show_length();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = tdd->set_length(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    } else if (name == rfdesense_tdd_sub[INDEX_TDD_SUB_MCS].name) {
+        flag = tdd->set_mcs(last_pos);
+    } else if (name == rfdesense_tdd_sub[INDEX_TDD_SUB_POWER].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            tdd->show_power();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = tdd->set_power(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    } else {
+        LOG_D(LOG_TAG, "error");
+    }
+
+    if (flag) {
+        mRatList[INDEX_LTE_TDD]->setRatCmdStart(tdd->get_command());
+        mRatList[INDEX_LTE_TDD]->setRatband(tdd->get_band());
+        mRatList[INDEX_LTE_TDD]->setRatPowerSet(tdd->get_power());
+        save(INDEX_LTE_TDD);
+    }
+}
+
+void RfDesenseTxTest::handle_cdma_evdo_para(const std::string& name,
+        int last_pos, const std::string& sub_name) {
+    //CDMA(EVDO)
+    bool flag = false;
+    std::shared_ptr<RfDesenseTxTestCdma> evdo = std::make_shared<
+            RfDesenseTxTestCdma>(utils::MODEM_CDMA_EVDO);
+    if (name == rfdesense_cdma_sub[INDEX_CDMA_SUB_BAND].name) {
+        flag = evdo->set_band(last_pos);
+    } else if (name == rfdesense_cdma_sub[INDEX_CDMA_SUB_CHANNEL].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            evdo->show_channel();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = evdo->set_channel(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    } else if (name == rfdesense_cdma_sub[INDEX_CDMA_SUB_MODULATION].name) {
+        flag = evdo->set_modulation(last_pos);
+    } else if (name == rfdesense_cdma_sub[INDEX_CDMA_SUB_POWER].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            evdo->show_power();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = evdo->set_power(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    }
+
+    if (flag) {
+        mRatList[INDEX_CDMA_EVDO]->setRatCmdStart(evdo->get_command());
+        mRatList[INDEX_CDMA_EVDO]->setRatband(evdo->get_band());
+        mRatList[INDEX_CDMA_EVDO]->setRatPowerSet(evdo->get_power());
+        save(INDEX_CDMA_EVDO);
+    }
+}
+
+void RfDesenseTxTest::handle_cdma_1X_para(const std::string& name, int last_pos,
+        const std::string& sub_name) {
+    //CDMA(1X)
+    bool flag = false;
+    std::shared_ptr<RfDesenseTxTestCdma> cdma_1x = std::make_shared<
+            RfDesenseTxTestCdma>(utils::MODEM_CDMA_1X);
+    if (name == rfdesense_cdma_sub[INDEX_CDMA_SUB_BAND].name) {
+        flag = cdma_1x->set_band(last_pos);
+    } else if (name == rfdesense_cdma_sub[INDEX_CDMA_SUB_CHANNEL].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            cdma_1x->show_channel();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = cdma_1x->set_channel(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    } else if (name == rfdesense_cdma_sub[INDEX_CDMA_SUB_MODULATION].name) {
+        flag = cdma_1x->set_modulation(last_pos);
+    } else if (name == rfdesense_cdma_sub[INDEX_CDMA_SUB_POWER].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            cdma_1x->show_power();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = cdma_1x->set_power(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    }
+
+    if (flag) {
+        mRatList[INDEX_CDMA_1X]->setRatCmdStart(cdma_1x->get_command());
+        mRatList[INDEX_CDMA_1X]->setRatband(cdma_1x->get_band());
+        mRatList[INDEX_CDMA_1X]->setRatPowerSet(cdma_1x->get_power());
+        save(INDEX_CDMA_1X);
+    }
+}
+
+bool RfDesenseTxTest::handle_show_default(const std::string& standard) {
+    //show default
+    if (standard == sub_tx_test[INDEX_GSM].name) {
+        //"GSM"
+        std::shared_ptr<RfDesenseTxTestGsm> gsm =
+                RfDesenseTxTestGsm::get_instance();
+        gsm->show_default();
+    } else if (standard == sub_tx_test[INDEX_TDSCDMA].name) {
+        //"TDSCDMA"
+        std::shared_ptr<RfDesenseTxTestTd> tdscdma = std::make_shared<
+                RfDesenseTxTestTd>(utils::MODEM_TDSCDMA);
+        tdscdma->show_default();
+    } else if (standard == sub_tx_test[INDEX_WCDMA].name) {
+        //"WCDMA"
+        std::shared_ptr<RfDesenseTxTestTd> wcdma = std::make_shared<
+                RfDesenseTxTestTd>(utils::MODEM_WCDMA);
+        wcdma->show_default();
+    } else if (standard == sub_tx_test[INDEX_LTE_FDD].name) {
+        //LTE(FDD)
+        std::shared_ptr<RfDesenseTxTestLte> fdd = std::make_shared<
+                RfDesenseTxTestLte>(utils::MODEM_LTE_FDD);
+        fdd->show_default();
+    } else if (standard == sub_tx_test[INDEX_LTE_TDD].name) {
+        //LTE(TDD)
+        std::shared_ptr<RfDesenseTxTestLte> tdd = std::make_shared<
+                RfDesenseTxTestLte>(utils::MODEM_LTE_TDD);
+        tdd->show_default();
+    } else if ((standard == sub_tx_test[INDEX_CDMA_EVDO].name)
+            && utils::isC2KSupport()) {
+        //CDMA(EVDO)
+        std::shared_ptr<RfDesenseTxTestCdma> evdo = std::make_shared<
+                RfDesenseTxTestCdma>(utils::MODEM_CDMA_EVDO);
+        evdo->show_default();
+    } else if ((standard == sub_tx_test[INDEX_CDMA_1X].name)
+            && utils::isC2KSupport()) {
+        //CDMA(1X)
+        std::shared_ptr<RfDesenseTxTestCdma> cdma_1x = std::make_shared<
+                RfDesenseTxTestCdma>(utils::MODEM_CDMA_1X);
+        cdma_1x->show_default();
+    } else {
+        LOG_D(LOG_TAG, "invaild INPUT");
+        return false;
+    }
+    return true;
+}
+
+bool RfDesenseTxTest::handle_para(int len, int classid, int propertyid,int operatorid, const std::string& standard, int* item) {
+    if (len < 5) {
+        LOG_D(LOG_TAG, "logic error");
+        return false;
+    }
+    LOG_D(LOG_TAG, "len: %d, classid: %d, propertyid: %d, operatorid: %d, standard: %s", len, classid,propertyid, operatorid, standard.c_str());
+    int name_pos = item[3];
+    int last_pos = item[4];
+    std::string name =
+            desense_test[classid].subarray[propertyid].subarray[operatorid].subarray[name_pos].name;
+    std::string sub_name =
+            desense_test[classid].subarray[propertyid].subarray[operatorid].subarray[name_pos].subarray[last_pos].name;
+    LOG_D(LOG_TAG, "name_pos: %d, last_pos: %d, name: %s, sub_name: %s", name_pos, last_pos,name.c_str(), sub_name.c_str());
+    if (standard == sub_tx_test[INDEX_GSM].name) {
+        //"GSM"
+        handle_gsm_para(name, last_pos, sub_name);
+    } else if (standard == sub_tx_test[INDEX_TDSCDMA].name) {
+        //"TDSCDMA"
+        handle_tdscdma_para(name, last_pos, sub_name);
+    } else if (standard == sub_tx_test[INDEX_WCDMA].name) {
+        //"WCDMA"
+        handle_wcdma_para(name, last_pos, sub_name);
+    } else if (standard == sub_tx_test[INDEX_LTE_FDD].name) {
+        //LTE(FDD)
+        handle_lte_fdd_para(name, last_pos, sub_name);
+    } else if (standard == sub_tx_test[INDEX_LTE_TDD].name) {
+        //LTE(TDD)
+        handle_lte_tdd_para(name, last_pos, sub_name);
+    } else if ((standard == sub_tx_test[INDEX_CDMA_EVDO].name)
+            && utils::isC2KSupport()) {
+        //CDMA(EVDO)
+        handle_cdma_evdo_para(name, last_pos, sub_name);
+    } else if ((standard == sub_tx_test[INDEX_CDMA_1X].name)
+            && utils::isC2KSupport()) {
+        //CDMA(1X)
+        handle_cdma_1X_para(name, last_pos, sub_name);
+    } else {
+        LOG_D(LOG_TAG, "invaild INPUT");
+        return false;
+    }
+    return true;
+}
+
+bool RfDesenseTxTest::handle_start(const std::string& standard) {
+    //start
+    mState = STATE_STARTED;
+    if (standard == sub_tx_test[INDEX_GSM].name) {
+        //"GSM"
+        mRatList[INDEX_GSM]->setRatCheckState(true);
+    } else if (standard == sub_tx_test[INDEX_TDSCDMA].name) {
+        //"TDSCDMA"
+        mRatList[INDEX_TDSCDMA]->setRatCheckState(true);
+    } else if (standard == sub_tx_test[INDEX_WCDMA].name) {
+        //"WCDMA"
+        mRatList[INDEX_WCDMA]->setRatCheckState(true);
+    } else if (standard == sub_tx_test[INDEX_LTE_FDD].name) {
+        //LTE(FDD)
+        mRatList[INDEX_LTE_FDD]->setRatCheckState(true);
+    } else if (standard == sub_tx_test[INDEX_LTE_TDD].name) {
+        //LTE(TDD)
+        mRatList[INDEX_LTE_TDD]->setRatCheckState(true);
+    } else if ((standard == sub_tx_test[INDEX_CDMA_EVDO].name)
+            && utils::isC2KSupport()) {
+        //CDMA(EVDO)
+        mRatList[INDEX_CDMA_EVDO]->setRatCheckState(true);
+    } else if ((standard == sub_tx_test[INDEX_CDMA_1X].name)
+            && utils::isC2KSupport()) {
+        //CDMA(1X)
+        mRatList[INDEX_CDMA_1X]->setRatCheckState(true);
+    } else {
+        LOG_D(LOG_TAG, "invaild INPUT");
+        return false;
+    }
+    return true;
+}
+
+int RfDesenseTxTest::emRfDesenseStart(int len,int *item,int multilen,char *value[]) {
+    LOG_D(LOG_TAG,"emRfDesenseStart called");
+    update_rat();
+    if (len < 3) {
+        LOG_D(LOG_TAG, "please select redesense get or set");
+        return -1;
+    }
+    int classid = item[0];
+    int propertyid = item[1];
+    int operatorid = item[2];
+    mCurrentSettingsValues.clear();
+    for(int i = 0; i < multilen; i++ ) {
+        mCurrentSettingsValues.push_back(value[i]);
+        LOG_D(LOG_TAG, "value[%d]: %s", i, value[i]);
+    }
+    LOG_D(LOG_TAG, "mCurrentSettingsValues size: " + mCurrentSettingsValues.size());
+    em_arry_t *subarry = &(desense_test[classid].subarray[propertyid]);
+    std::string standard = subarry->name;
+    LOG_D(LOG_TAG,"rfdesense property name: %s, operatorid: %d",subarry->name, operatorid);
+    switch (operatorid) {
+        case 0: { //start
+            str_msg = "";
+            if(!handle_start(standard)) return -1;
+            //emEnableRadio(false);
+            registerOnUnsolOemHookRaw(m_instance);
+            register_response_oem_hook_raw(m_instance);
+            std::thread thread_start(&RfDesenseTxTest::emRfDesenseThread, m_instance, operatorid);
+            thread_start.detach();
+            break;
+        }
+        case 1: {
+            if(!handle_para(len, classid, propertyid, operatorid, standard, item)) return -1;
+            break;
+        }
+        case 2: { //show default
+            if(!handle_show_default(standard)) return -1;
+            break;
+        }
+        default:
+            LOG_D(LOG_TAG, "logic eror ");
+            return -1;
+    }
+    return (0);
+}
+
+std::shared_ptr<RfDesenseRatInfo> RfDesenseTxTest::getCurrectRatInfo() {
+    int index;
+    for (index = 0; index < mRatList.size(); index++) {
+         if (mRatList[index]->getRatCheckState()) {
+             if (mRatList[index]->getRatSendState()) {
+                 continue;
+             }
+             mCurrectRatInfo = mRatList[index];
+             break;
+         }
+     }
+     return mCurrectRatInfo;
+}
+
+void RfDesenseTxTest::turnOffRf(){
+    LOG_D(LOG_TAG, "turn off rf....");
+    mIsModemNotEnabled = false;
+    emEnableRadio(false, phone_id);
+    if(utils::is_support_dsds()){
+        emEnableRadio(false, phone_id == 0? 1:0);
+    }
+}
+
+void RfDesenseTxTest::turnOnRf() {
+    LOG_D(LOG_TAG, "turn on rf....");
+    mIsModemEnabled = false;
+    emEnableRadio(true, phone_id);
+    if(utils::is_support_dsds()){
+        emEnableRadio(true, phone_id == 0? 1:0);
+    }
+}
+
+void RfDesenseTxTest::initRatList() {
+    phone_id = Radio_capability_switch_util::get_main_capability_phone_id();
+    mState = STATE_NONE;
+    if(!utils::is93Modem()){
+        mRatCmdStart[5] = DEFAULT_CDMA_EVDO_ATCMD_93before;
+        mRatCmdStop[5] = "AT+ECRFTX=0";
+    }
+
+    if(utils::is90Modem()) {
+        mRatCmdSwitch[5] = "AT^PREFMODE=4";
+        mRatCmdSwitch[6] = "AT^EIRATMODE=2";
+    }
+    for (int i = 0; i < mRatName.size(); i++) {
+        std::shared_ptr<RfDesenseRatInfo> Info = std::make_shared<RfDesenseRatInfo>();
+        Info->setRatName(mRatName[i]);
+        Info->setRatCmdStart(mRatCmdStart[i]);
+        Info->setRatCmdStop(mRatCmdStop[i]);
+        Info->setRatCmdSwitch(mRatCmdSwitch[i]);
+        Info->setRatPowerRead(mRatCmdPowerRead[i]);
+        Info->setRatband(mRatBand[i]);
+        Info->setRatPowerSet(mRatPowerSet[i]);
+        Info->setRatCheckState(false);
+        Info->setRatSendState(false);
+        mRatList.push_back(Info);
+        if(!(utils::isC2KSupport())){
+            if (i == 4) {
+                break;
+            }
+        }
+    }
+}
+
+void RfDesenseTxTest::update_rat() {
+    for(int i=0; i < mRatList.size(); i++){
+        mRatList[i]->setRatName(mRatName[i]);
+        mRatList[i]->setRatCmdStart(mRatCmdStart[i]);
+        mRatList[i]->setRatCmdStop(mRatCmdStop[i]);
+        mRatList[i]->setRatCmdSwitch(mRatCmdSwitch[i]);
+        mRatList[i]->setRatPowerRead(mRatCmdPowerRead[i]);
+        mRatList[i]->setRatband(mRatBand[i]);
+        mRatList[i]->setRatPowerSet(mRatPowerSet[i]);
+        mRatList[i]->setRatCheckState(false);
+        mRatList[i]->setRatSendState(false);
+        if(!(utils::isC2KSupport())){
+            if (i == 4) {
+                break;
+            }
+        }
+    }
+}
+void RfDesenseTxTest::save(int index) {
+    mRatCmdStart[index] = mRatList[index]->getRatCmdStart();
+    mRatBand[index] = mRatList[index]->getRatband();
+    mRatPowerSet[index] = mRatList[index]->getRatPowerSet();
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTest.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTest.h
new file mode 100644
index 0000000..5f9d0b2
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTest.h
@@ -0,0 +1,257 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef RFDESENSETXTEST_H_
+#define RFDESENSETXTEST_H_
+
+#include <string>
+#include <vector>
+#include <memory>
+#include <mutex>
+#include <thread>
+#include <condition_variable>
+#include <vendor-ril/telephony/ril.h>
+#include <utils/Looper.h>
+#include <utils/Thread.h>
+#include <utils/RefBase.h>
+
+using namespace std;
+using ::android::Looper;
+using ::android::Thread;
+using ::android::MessageHandler;
+using ::android::Message;
+using ::android::sp;
+using ::android::RefBase;
+
+#include "rfdesense/RfDesenseRatInfo.h"
+#include "Radio_capability_switch_util.h"
+
+class RfDesenseTxTest: public android::RefBase {
+public:
+    RfDesenseTxTest();
+    virtual ~RfDesenseTxTest();
+    static RfDesenseTxTest* getInstance();
+    int emRfDesenseStart(int len,int *item,int multilen,char *value[]);
+    void emRadioStateOn();
+    void emRadioStateOfforNotAvailable();
+    void emOemHookRaw(int value, int slot_id);
+    void emRfDesenseAtCmdHandle(char*response, int responselen);
+    static const int STATE_NONE;
+    static const int STATE_STARTED;
+    static const int STATE_STOPPED;
+
+    static const int MSG_START_TX;
+    static const int MSG_NEXT_RAT;
+    static const int MSG_READ_POWER;
+    static const int MSG_EWMPOLICY_TDSCDMA;
+    static const int MSG_EWMPOLICY_WCDMA;
+    static const int MSG_ECSRA;
+    static const int MSG_SWITCH_RAT_DONE;
+
+    static const std::string KEY_GSM_ATCMD;
+    static const std::string KEY_TDSCDMA_ATCMD;
+    static const std::string KEY_WCDMA_ATCMD;
+    static const std::string KEY_LTE_FDD_ATCMD;
+    static const std::string KEY_LTE_TDD_ATCMD;
+    static const std::string KEY_CDMA_1X_ATCMD;
+    static const std::string KEY_CDMA_EVDO_ATCMD;
+    static const std::string KEY_TEST_DURATION;
+    static const std::string KEY_TEST_COUNT;
+    static const std::string KEY_CHECK_LIMIT;
+    static const std::string KEY_READBACK_INTREVAL;
+
+    static const std::string DEFAULT_GSM_ATCMD;
+    static const std::string DEFAULT_TDSCDMA_ATCMD;
+    static const std::string DEFAULT_WCDMA_ATCMD;
+    static const std::string DEFAULT_LTE_FDD_ATCMD;
+    static const std::string DEFAULT_LTE_TDD_ATCMD;
+    static const std::string DEFAULT_CDMA_EVDO_ATCMD;
+    static const std::string DEFAULT_CDMA_1X_ATCMD;
+    static const std::string DEFAULT_CDMA_EVDO_ATCMD_93before;
+    static const std::vector<std::string> mRatName;
+    static std::vector<std::string> mRatCmdStart;
+    static std::vector<std::string> mRatCmdStop;
+    static std::vector<std::string> mRatCmdSwitch;
+    static std::vector<std::string> mRatCmdPowerRead;
+    static std::vector<std::string> mRatBand;
+    static std::vector<std::string> mRatPowerSet;
+    static std::vector<bool> mRatCheck;
+    static std::vector<bool> mSendState;
+    static long mTestDuration;
+    static long mTestCount;
+    static long mTestDurationSended;
+    static long mTestCountSended;
+    static long mCheckLimit;
+    static long mReadbackInterval;
+    std::vector<std::shared_ptr<RfDesenseRatInfo>> mRatList;
+    std::shared_ptr<RfDesenseRatInfo> mCurrectRatInfo;
+
+    const int MSG_QUERY = 0;
+    const int MSG_SET = 1;
+    int mCurrentFlag = 0;
+    std::vector<std::string> mCurrentSettingsValues;
+    static const int INDEX_GSM = 0;
+    static const int INDEX_TDSCDMA = 1;
+    static const int INDEX_WCDMA = 2;
+    static const int INDEX_LTE_FDD = 3;
+    static const int INDEX_LTE_TDD = 4;
+    static const int INDEX_CDMA_EVDO = 5;
+    static const int INDEX_CDMA_1X = 6;
+
+    static constexpr int INDEX_GSM_SUB_BAND = 0;
+    static constexpr int INDEX_GSM_SUB_CHANNEL = 1;
+    static constexpr int INDEX_GSM_SUB_POWER = 2;
+    static constexpr int INDEX_GSM_SUB_AFC = 3;
+    static constexpr int INDEX_GSM_SUB_TSC = 4 ;
+    static constexpr int INDEX_GSM_SUB_PATTERN = 5;
+
+    static constexpr int INDEX_3G_SUB_BAND = 0;
+    static constexpr int INDEX_3G_SUB_CHANNEL = 1;
+    static constexpr int INDEX_3G_SUB_POWER = 2;
+
+    static constexpr int INDEX_CDMA_SUB_BAND = 0;
+    static constexpr int INDEX_CDMA_SUB_MODULATION = 1;
+    static constexpr int INDEX_CDMA_SUB_CHANNEL = 2;
+    static constexpr int INDEX_CDMA_SUB_POWER = 3;
+
+    static constexpr int INDEX_FDD_SUB_MODE = 0;
+    static constexpr int INDEX_FDD_SUB_BAND = 1;
+    static constexpr int INDEX_FDD_SUB_BANDWITH = 2;
+    static constexpr int INDEX_FDD_SUB_FREQ = 3;
+    static constexpr int INDEX_FDD_SUB_START = 4;
+    static constexpr int INDEX_FDD_SUB_LENGTH = 5;
+    static constexpr int INDEX_FDD_SUB_MCS = 6;
+    static constexpr int INDEX_FDD_SUB_POWER = 7;
+
+    static constexpr int INDEX_TDD_SUB_MODE = 0;
+    static constexpr int INDEX_TDD_SUB_BAND = 1;
+    static constexpr int INDEX_TDD_SUB_BANDWIDTH = 2;
+    static constexpr int INDEX_TDD_SUB_FREQ = 3;
+    static constexpr int INDEX_TDD_SUB_CONFIG = 4;
+    static constexpr int INDEX_TDD_SUB_SPECIAL = 5;
+    static constexpr int INDEX_TDD_SUB_START = 6;
+    static constexpr int INDEX_TDD_SUB_LENGTH = 7;
+    static constexpr int INDEX_TDD_SUB_MCS = 8;
+    static constexpr int INDEX_TDD_SUB_POWER = 9;
+
+    class RequestHandleThread: public Thread {
+    public:
+        RequestHandleThread(RfDesenseTxTest* tx);
+        virtual ~RequestHandleThread();
+        sp<Looper> getLooper();
+
+    protected:
+        RfDesenseTxTest* mTx;
+        virtual bool threadLoop();
+    private:
+        sp<Looper> m_looper;
+    };
+
+    class RfRequestMessage: public RefBase {
+    public:
+        RfRequestMessage(RfDesenseTxTest* tx);
+        virtual ~RfRequestMessage();
+        void sendMessage(int delayms);
+    public:
+        int mMsgType;
+        string response;
+        int responselen;
+        int slot;
+        RIL_Errno e;
+    private:
+        RfDesenseTxTest* mTx;
+    };
+
+    class RfRequestHandler: public MessageHandler {
+    public:
+        RfRequestHandler(RfDesenseTxTest* tx): mTx(tx){}
+        virtual ~RfRequestHandler();
+
+    public:
+        void sendMessage(sp<RfRequestMessage> msg, int delayms);
+        void handleMessage(const Message& message);
+        sp<RfRequestMessage> mMsg;
+        // dummy message that makes handler happy
+        Message m_dummyMsg;
+    private:
+        RfDesenseTxTest* mTx;
+    };
+
+public:
+    void emRfDesenseAtCmdHandle(sp<RfRequestMessage> msg);
+    sp<RequestHandleThread> mRequestHandleThread;
+    sp<RfRequestHandler> mRfRequestHandler;
+    // send message to request handler
+    sp<RfRequestHandler> sendMessage(sp<RfRequestMessage> msg, int delayms);
+    void handle_request(string response,int responselen,int slot, RIL_Errno e);
+
+private:
+    std::shared_ptr<RfDesenseRatInfo> getCurrectRatInfo();
+    void update_rat();
+    void tx_stop();
+    void turnOffRf();
+    void turnOnRf();
+    void emRfDesenseThread(int id);
+    void rf_send_at_cmd(std::string cmd, int flag);
+    void save(int index);
+    void txTestStop(int what);
+    static RfDesenseTxTest* m_instance;
+    static std::mutex mMutex;
+    static bool trm_flag;
+    std::condition_variable m_condVar;
+    bool m_rawUrc = false;
+    void initRatList();
+    void handle_gsm_para(const std::string& name, int last_pos,const std::string& sub_name);
+    void handle_tdscdma_para(const std::string& name, int last_pos,const std::string& sub_name);
+    void handle_wcdma_para(const std::string& name, int last_pos,const std::string& sub_name);
+    void handle_lte_fdd_para(const std::string& name, int last_pos,const std::string& sub_name);
+    void handle_lte_tdd_para(const std::string& name, int last_pos,const std::string& sub_name);
+    void handle_cdma_evdo_para(const std::string& name, int last_pos,const std::string& sub_name);
+    void handle_cdma_1X_para(const std::string& name, int last_pos,const std::string& sub_name);
+    bool handle_show_default(const std::string& standard);
+    bool handle_para(int len, int classid, int propertyid, int operatorid,const std::string& standard, int* item);
+    bool handle_start(const std::string& standard);
+
+    static int mState;
+    static std::string str_msg;
+    static int phone_id;
+    bool mIsModemEnabled = true;
+    bool mIsModemNotEnabled = true;
+private:
+    void init();
+    void deInit();
+};
+
+#endif /* RFDESENSETXTEST_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestBase.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestBase.cpp
new file mode 100644
index 0000000..1faa8ae
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestBase.cpp
@@ -0,0 +1,58 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include "rfdesense/RfDesenseTxTestBase.h"
+
+#include "util/log_extra.h"
+
+#undef LOG_TAG
+#define LOG_TAG "EM_RfDesenseTxTestBase"
+
+const int RfDesenseTxTestBase::CHANNEL_DEFAULT = 0;
+const int RfDesenseTxTestBase::CHANNEL_MIN = 1;
+const int RfDesenseTxTestBase::CHANNEL_MAX = 2;
+const int RfDesenseTxTestBase::CHANNEL_MIN2 = 3;
+const int RfDesenseTxTestBase::CHANNEL_MAX2 = 4;
+const int RfDesenseTxTestBase::POWER_DEFAULT = 5;
+const int RfDesenseTxTestBase::POWER_MIN = 6;
+const int RfDesenseTxTestBase::POWER_MAX = 7;
+
+RfDesenseTxTestBase::RfDesenseTxTestBase() {
+    // TODO Auto-generated constructor stub
+
+}
+
+RfDesenseTxTestBase::~RfDesenseTxTestBase() {
+    // TODO Auto-generated destructor stub
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestBase.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestBase.h
new file mode 100644
index 0000000..94b08de
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestBase.h
@@ -0,0 +1,57 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef RFDESENSETXTESTBASE_H_
+#define RFDESENSETXTESTBASE_H_
+
+#include <string>
+#include <vector>
+
+class RfDesenseTxTestBase {
+public:
+    RfDesenseTxTestBase();
+    virtual ~RfDesenseTxTestBase();
+public:
+    static const int CHANNEL_DEFAULT;
+    static const int CHANNEL_MIN;
+    static const int CHANNEL_MAX;
+    static const int CHANNEL_MIN2;
+    static const int CHANNEL_MAX2;
+    static const int POWER_DEFAULT;
+    static const int POWER_MIN;
+    static const int POWER_MAX;
+};
+
+#endif /* RFDESENSETXTESTBASE_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestCdma.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestCdma.cpp
new file mode 100644
index 0000000..b9fc283
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestCdma.cpp
@@ -0,0 +1,225 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include <algorithm>
+#include <iterator>
+#include <stdexcept>
+
+#include "rfdesense/RfDesenseTxTestCdma.h"
+#include "rfdesense/RfDesenseTxTestBase.h"
+#include "util/log_extra.h"
+#include "em.h"
+
+#undef LOG_TAG
+#define LOG_TAG "EM_RfDesenseTxTestCdma"
+
+const int RfDesenseTxTestCdma::INDEX_BAND = 0;
+const int RfDesenseTxTestCdma::INDEX_CHANNEL = 1;
+const int RfDesenseTxTestCdma::INDEX_POWER = 2;
+const int RfDesenseTxTestCdma::INDEX_MODULATION = 3;
+std::string RfDesenseTxTestCdma::band = "";
+std::string RfDesenseTxTestCdma::channel = "";
+std::string RfDesenseTxTestCdma::power = "";
+std::string RfDesenseTxTestCdma::modulation = "";
+std::map<int, std::string> RfDesenseTxTestCdma::evdo_values = {{INDEX_BAND, "0"},{INDEX_CHANNEL, "384"},{INDEX_POWER, "23"}, {INDEX_MODULATION, "1"}};
+std::map<int, std::string> RfDesenseTxTestCdma::cdma_1x_values = {{INDEX_BAND, "0"},{INDEX_CHANNEL, "384"},{INDEX_POWER, "23"}, {INDEX_MODULATION, "0"}};
+
+RfDesenseTxTestCdma::RfDesenseTxTestCdma(int type) {
+    modem_type = type;
+    std::map<int, std::string> tmp;
+    switch(modem_type){
+        case utils::MODEM_CDMA_EVDO:{
+            tmp = evdo_values;
+            break;
+        }
+        case utils::MODEM_CDMA_1X:{
+            tmp = cdma_1x_values;
+            break;
+        }
+        default:
+            break;
+    }
+    if(!tmp.empty()) {
+        band = tmp[INDEX_BAND];
+        channel = tmp[INDEX_CHANNEL];
+        power = tmp [INDEX_POWER];
+        modulation = tmp[INDEX_MODULATION];
+    }
+
+}
+
+void RfDesenseTxTestCdma::show_default() {
+    std::string str;
+    int index = std::stoi(band);
+    std::string modem;
+    if(modem_type == utils::MODEM_CDMA_EVDO) {
+        modem = "CDMA(EVDO) ";
+    } else if(modem_type == utils::MODEM_CDMA_1X){
+        modem = "CDMA(1X) ";
+    }
+    str = modem + "parameters: Band: "
+            + std::string(rfdesense_cdma_band[index].name)
+            + ", modulation: "
+            + (std::stoi(modulation) == 0 ?
+                    std::string("1x") : std::string("EVDO"))
+            + ", Channel(ARFCN): " + channel + ", Power Level(dBm): " + power;
+    emResultNotifyWithDone(str);
+}
+
+RfDesenseTxTestCdma::~RfDesenseTxTestCdma() {
+    // TODO Auto-generated destructor stub
+}
+std::string RfDesenseTxTestCdma::modemTypeToString(int type) {
+    switch(modem_type){
+        case utils::MODEM_CDMA_EVDO:
+            return "CDMA(EVD)";
+        case utils::MODEM_CDMA_1X:
+            return "CDMA(1X)";
+        default:
+            return "UNKNOWN";
+    }
+}
+
+std::string RfDesenseTxTestCdma::get_command(){
+    int tx_power = 0;
+    if (!power.empty()) {
+        tx_power = std::stoi(power) + 60;
+    }
+
+    if (modem_type == utils::MODEM_CDMA_1X) {
+        command = "AT+ECRFTX=1," + channel + "," + band + ","
+                + std::to_string(tx_power)
+                + ","
+                + (modulation == "1" ? "0" : "1");
+    } else if(modem_type == utils::MODEM_CDMA_EVDO) {
+        command = "AT+ERFTX=13,4," + channel + "," + band + ","
+                + std::to_string(tx_power);
+    }
+    return command;
+}
+
+std::string RfDesenseTxTestCdma::get_band(){
+    return band;
+}
+
+std::string RfDesenseTxTestCdma::get_power(){
+    return power;
+}
+
+bool RfDesenseTxTestCdma::set_band(int value){
+    std::string s;
+    if(value < 0 || value > 15) {
+        s = utils::format("band(%d) is out of range", value);
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "band(%d) is out of range", value);
+        return false;
+    }
+    band = std::to_string(value);
+    if(modem_type == utils::MODEM_CDMA_EVDO) {
+        evdo_values[INDEX_BAND] = band;
+    } else if(modem_type == utils::MODEM_CDMA_1X) {
+        cdma_1x_values[INDEX_BAND] = band;
+    } else {
+        s = utils::format("modem(%s) is invalid", modemTypeToString(modem_type));
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "modem(%s) is invalid", modemTypeToString(modem_type));
+        return false;
+    }
+    em_result_notify_ok("band: " + std::string(rfdesense_cdma_band[value].name));
+    return true;
+}
+
+bool RfDesenseTxTestCdma::set_modulation(int value){
+    if (value != 0 && value != 1) {
+        LOG_D(LOG_TAG, "set_modulation value(%d) is out of range",value);
+        return false;
+    }
+    modulation = std::to_string(value);
+    if(modem_type == utils::MODEM_CDMA_EVDO) {
+        evdo_values[INDEX_MODULATION] = modulation;
+    } else if(modem_type == utils::MODEM_CDMA_1X) {
+        cdma_1x_values[INDEX_MODULATION] = modulation;
+    } else {
+        std::string s;
+        s = utils::format("modem(%s) is invalid", modemTypeToString(modem_type));
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "modem(%s) is invalid", modemTypeToString(modem_type));
+        return false;
+    }
+    em_result_notify_ok("modulation: " + (value == 0 ?std::string("1x") : std::string("EVDO")));
+    return true;
+}
+
+bool RfDesenseTxTestCdma::set_channel(std::string str){
+    channel = str;
+    if(modem_type == utils::MODEM_CDMA_EVDO) {
+        evdo_values[INDEX_CHANNEL] = channel;
+    } else if(modem_type == utils::MODEM_CDMA_1X) {
+        cdma_1x_values[INDEX_CHANNEL] = channel;
+    } else {
+        std::string s;
+        s = utils::format("modem(%s) is invalid", modemTypeToString(modem_type));
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "modem(%s) is invalid", modemTypeToString(modem_type));
+        return false;
+    }
+    em_result_notify_ok("channel: " + channel);
+    return true;
+}
+
+bool RfDesenseTxTestCdma::set_power(std::string str){
+    power = str;
+    if(modem_type == utils::MODEM_CDMA_EVDO) {
+        evdo_values[INDEX_POWER] = power;
+    } else if(modem_type == utils::MODEM_CDMA_1X) {
+        cdma_1x_values[INDEX_POWER] = power;
+    } else {
+        std::string s;
+        s = utils::format("modem(%s) is invalid", modemTypeToString(modem_type));
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "modem(%s) is invalid", modemTypeToString(modem_type));
+        return false;
+    }
+    em_result_notify_ok("power: " + power);
+    return true;
+}
+
+void RfDesenseTxTestCdma::show_channel(){
+    emResultNotifyWithDone("Channel(ARFCN): " + channel);
+}
+
+void RfDesenseTxTestCdma::show_power(){
+    emResultNotifyWithDone("Power level(dBm): " + power);
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestCdma.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestCdma.h
new file mode 100644
index 0000000..26cc2ff
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestCdma.h
@@ -0,0 +1,77 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef RFDESENSETXTESTCDMA_H_
+#define RFDESENSETXTESTCDMA_H_
+
+#include <vector>
+#include <string>
+#include <map>
+
+#include "util/utils.h"
+
+class RfDesenseTxTestCdma {
+public:
+    bool init(std::vector<std::string> v);
+    std::string get_command();
+    std::string get_band();
+    std::string get_power();
+    bool set_band(int value);
+    bool set_modulation(int value);
+    bool set_channel(std::string str);
+    bool set_power(std::string str);
+    void show_channel();
+    void show_power();
+    RfDesenseTxTestCdma(int type);
+    void show_default();
+    virtual ~RfDesenseTxTestCdma();
+private:
+    static const int INDEX_BAND;
+    static const int INDEX_CHANNEL;
+    static const int INDEX_POWER;
+    static const int INDEX_MODULATION;
+    int modem_type = utils::MODEM_UNKNOWN;
+    static std::string band;
+    static std::string channel;
+    static std::string power;
+    static std::string modulation;
+    static std::map<int, std::string> evdo_values;
+    static std::map<int, std::string> cdma_1x_values;
+    bool check_band(std::string band);
+    std::string command;
+    std::string modemTypeToString(int type);
+};
+
+#endif /* RFDESENSETXTESTCDMA_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestGsm.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestGsm.cpp
new file mode 100644
index 0000000..793e99f
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestGsm.cpp
@@ -0,0 +1,305 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include "rfdesense/RfDesenseTxTestGsm.h"
+
+#include <algorithm>
+#include <iterator>
+#include <stdexcept>
+
+#include "em.h"
+#include "rfdesense/RfDesenseTxTestBase.h"
+#include "util/log_extra.h"
+#include "util/utils.h"
+
+#undef LOG_TAG
+#define LOG_TAG "EM_RfDesenseTxTestGsm"
+const int RfDesenseTxTestGsm::INDEX_BAND = 0;
+const int RfDesenseTxTestGsm::INDEX_CHANNEL = 1;
+const int RfDesenseTxTestGsm::INDEX_POWER = 2;
+const int RfDesenseTxTestGsm::INDEX_AFC = 3;
+const int RfDesenseTxTestGsm::INDEX_TSC = 4;
+const int RfDesenseTxTestGsm::INDEX_PATTERN = 5;
+std::string RfDesenseTxTestGsm::band = "128";
+std::string RfDesenseTxTestGsm::channel ="190";
+std::string RfDesenseTxTestGsm::power = "5";
+std::string RfDesenseTxTestGsm::afc = "4100";
+std::string RfDesenseTxTestGsm::tsc = "0";
+std::string RfDesenseTxTestGsm::pattern = "0";
+
+const std::vector<std::string> RfDesenseTxTestGsm::band_values = {"128","1", "2", "4", "8", "16"};
+const std::vector<std::vector<std::string>> RfDesenseTxTestGsm::gsm_gmsk_limits = {
+        {"190","128","251","128","251","5","5","19"},
+        {"63","1","124","1","124","5","5","19"},
+        {"62","0","124","975","1023","5","5","19"},
+        {"61","0","124","955","1023","5","5","19"},
+        {"700","512","885","512","885","0","0","15"},
+        {"661","512","810","512","885","0","0","15"}};
+
+std::shared_ptr<RfDesenseTxTestGsm> RfDesenseTxTestGsm::m_instance;
+std::mutex RfDesenseTxTestGsm::mutex;
+
+RfDesenseTxTestGsm::RfDesenseTxTestGsm() {
+
+}
+
+RfDesenseTxTestGsm::~RfDesenseTxTestGsm() {
+    // TODO Auto-generated destructor stub
+}
+
+std::shared_ptr<RfDesenseTxTestGsm> RfDesenseTxTestGsm::get_instance() {
+    if(!m_instance) {
+        mutex.lock();
+        if(!m_instance) {
+            m_instance = std::make_shared<RfDesenseTxTestGsm>();
+        }
+        mutex.unlock();
+    }
+    return m_instance;
+}
+
+std::string RfDesenseTxTestGsm::get_command() {
+    std::string command = "AT+ERFTX=2,1," + channel + "," + afc + "," + band + "," + tsc + "," + power + "," + pattern;
+    LOG_D(LOG_TAG, "GSM command: %s\n", command.c_str());
+    return command;
+}
+
+std::string RfDesenseTxTestGsm::get_band(){
+    return band;
+}
+
+std::string RfDesenseTxTestGsm::get_power(){
+    return power;
+}
+
+bool RfDesenseTxTestGsm::set_band(int value) {
+    LOG_D(LOG_TAG, "values: %d", value);
+    if (value < 0 || value >=  band_values.size()) {
+        std::string s = utils::format("value(%d) is out of range\n", value);
+        LOG_D(LOG_TAG, s.c_str());
+        em_result_notify_fail(s);
+        return false;
+    }
+    this->band = band_values[value];
+    em_result_notify_ok("band: " + std::string(rfdesense_gsm_band[value].name));
+    return true;
+}
+
+bool RfDesenseTxTestGsm::set_pattern(int value) {
+    LOG_D(LOG_TAG, "values: %d", value);
+    if(value < 0 || value > 6) {
+        std::string s = utils::format("pattern(%s) is invalid, range is [0,6]\n" , pattern.c_str());
+        LOG_D(LOG_TAG, s.c_str());
+        em_result_notify_fail(s);
+        return false;
+    }
+    this->pattern = std::to_string(value);
+    em_result_notify_ok("pattern: " + std::string(rfdesense_gsm_pattern[value].name));
+    return true;
+}
+
+bool RfDesenseTxTestGsm::set_channel(std::string value){
+    int index = utils::find_index(band_values, band);
+    if(check_channel(index,value)) {
+        channel = value;
+        em_result_notify_ok("channel: " + channel);
+        return true;
+    }
+    return false;
+}
+
+bool RfDesenseTxTestGsm::set_power(std::string value){
+    int index = utils::find_index(band_values, band);
+    if(check_power(index, value)) {
+        power = value;
+        em_result_notify_ok("power: " + power);
+        return true;
+    }
+    return false;
+}
+bool RfDesenseTxTestGsm::set_afc(std::string value){
+    LOG_D(LOG_TAG,"set_afc: %s", value);
+    if(check_afc(value)){
+        afc = value;
+        em_result_notify_ok("afc: " + afc);
+        return true;
+    }
+    return false;
+}
+
+bool RfDesenseTxTestGsm::set_tsc(std::string value){
+    if(check_tsc(value)) {
+        tsc = value;
+        em_result_notify_ok("tsc: " + tsc);
+        return true;
+    }
+    return false;
+}
+
+bool RfDesenseTxTestGsm::check_channel(int index, std::string channel) {
+    std::string s;
+    if(index >= gsm_gmsk_limits.size()) {
+        s = utils::format("check_channel,index(%d) is invalid", index);
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_channel,index(%d) is invalid", index);
+        return false;
+    }
+    int value = -1;
+    try {
+        value = std::stoi(channel);
+    } catch (std::invalid_argument &err) {
+        s = utils::format("check_channel,channel(%s) is invalid, reason: %s", channel.c_str(), err.what());
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_channel,channel(%s) is invalid, reason: %s", channel.c_str(), err.what());
+        return false;
+    }
+    step = 1;
+    std::vector<std::string> limits = gsm_gmsk_limits[index];
+    min = std::stoi(limits[RfDesenseTxTestBase::CHANNEL_MIN]);
+    max =  std::stoi(limits[RfDesenseTxTestBase::CHANNEL_MAX]);
+    min2 =  std::stoi(limits[RfDesenseTxTestBase::CHANNEL_MIN2]);
+    max2 =  std::stoi(limits[RfDesenseTxTestBase::CHANNEL_MAX2]);
+    if ((value < min || value > max) && (value < min2 || value > max2)) {
+        s = utils::format("check_channel,channel(%s) is invalid, range is [%d, %d] or [%d, %d]" , channel.c_str(), min, max, min2, max2);
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_channel,channel(%s) is invalid, range is [%d, %d] or [%d, %d]" , channel.c_str(), min, max, min2, max2);
+        return false;
+    }
+    return true;
+}
+
+bool RfDesenseTxTestGsm::check_power(int index ,std::string power) {
+    std::string s;
+    if(index >= gsm_gmsk_limits.size()) {
+        s = utils::format("check_power,index(%d) is invalid", index);
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_power,index(%d) is invalid", index);
+        return false;
+    }
+    int value = -1;
+    try {
+        value = std::stoi(power);
+    } catch (std::invalid_argument &err) {
+        s = utils::format("check_power,power(%s) is invalid, reason: %s", power.c_str(), err.what());
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_power,power(%s) is invalid, reason: %s", power.c_str(), err.what());
+        return false;
+    }
+    step = 1;
+    std::vector<std::string> limits = gsm_gmsk_limits[index];
+    min = std::stoi(limits[RfDesenseTxTestBase::POWER_MIN]);
+    max =  std::stoi(limits[RfDesenseTxTestBase::POWER_MAX]);
+    if (value < min || value > max) {
+        s = utils::format("check_power,power(%s) is invalid, range is [%d, %d]" , power.c_str(), min, max);
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_power,power(%s) is invalid, range is [%d, %d]" , power.c_str(), min, max);
+        return false;
+    }
+    return true;
+}
+
+bool RfDesenseTxTestGsm::check_afc(std::string afc) {
+    std::string s;
+    int value = -1;
+    try {
+        value = std::stoi(afc);
+    } catch (std::invalid_argument &err) {
+        s = utils::format("check_afc, afc(%s) is invalid, reason: %s", afc.c_str(), err.what());
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_afc, afc(%s) is invalid, reason: %s", afc.c_str(), err.what());
+        return false;
+    }
+    if(value < 0 || value > 8191) {
+        em_result_notify_fail("check_afc,afc(%s) is invalid, range is (0,8191)");
+        LOG_D(LOG_TAG, "check_afc,afc(%s) is invalid, range is (0,8191)" , afc.c_str());
+        return false;
+    }
+    return true;
+}
+
+bool RfDesenseTxTestGsm::check_tsc(std::string tsc){
+    std::string s;
+    int value = -1;
+    try {
+        value = std::stoi(tsc);
+    } catch (std::invalid_argument &err) {
+        s = utils::format("check_tsc, tsc(%s) is invalid, reason: %s", tsc.c_str(), err.what());
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_tsc, tsc(%s) is invalid, reason: %s", tsc.c_str(), err.what());
+        return false;
+    }
+    if(value < 0 || value > 7) {
+        em_result_notify_fail("check_tsc, tsc(%s) is invalid, range is [0,7]");
+        LOG_D(LOG_TAG, "check_tsc, tsc(%s) is invalid, range is [0,7]" , tsc.c_str());
+        return false;
+    }
+    return true;
+}
+
+bool RfDesenseTxTestGsm::check_pattern(std::string pattern) {
+    int value = -1;
+    try {
+        value = std::stoi(pattern);
+    } catch (std::invalid_argument &err) {
+        LOG_D(LOG_TAG, "check_pattern, pattern(%s) is invalid, reason: %s\n", pattern.c_str(), err.what());
+        return false;
+    }
+    if(value < 0 || value > 6) {
+        LOG_D(LOG_TAG, "check_pattern, pattern(%s) is invalid, range is [0,6]\n" , pattern.c_str());
+        return false;
+    }
+    return true;
+}
+
+void RfDesenseTxTestGsm::show_default() {
+    int band_index = utils::find_index(band_values, band);
+    int pattern_index = std::stoi(pattern);
+    std::string temp = "GSM parameter: Band: " + std::string(rfdesense_gsm_band[band_index].name) +
+            ", Channel(ARFCN): " + channel + ", Power Level: " + power + ", AFC: " + afc + ", TSC: " + tsc +
+            ", PATTERN: " + std::string(rfdesense_gsm_pattern[pattern_index].name);
+    emResultNotifyWithDone(temp);
+}
+
+void RfDesenseTxTestGsm::show_channel(){
+    emResultNotifyWithDone("Channel(ARFCN): " + channel);
+}
+void RfDesenseTxTestGsm::show_power(){
+    emResultNotifyWithDone("Power Level: " + power);
+}
+void RfDesenseTxTestGsm::show_afc(){
+    emResultNotifyWithDone("AFC: " + afc);
+}
+void RfDesenseTxTestGsm::show_tsc(){
+    emResultNotifyWithDone("TSC: " + tsc);
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestGsm.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestGsm.h
new file mode 100644
index 0000000..0963e49
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestGsm.h
@@ -0,0 +1,93 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef RFDESENSETXTESTGSM_H_
+#define RFDESENSETXTESTGSM_H_
+
+#include <string>
+#include <vector>
+#include <memory>
+#include <mutex>
+
+class RfDesenseTxTestGsm {
+public:
+    std::string get_command();
+    std::string get_band();
+    std::string get_power();
+    bool set_band(int value);
+    bool set_pattern(int value);
+    bool set_channel(std::string value);
+    bool set_power(std::string value);
+    bool set_afc(std::string value);
+    bool set_tsc(std::string value);
+    void show_default();
+    void show_channel();
+    void show_power();
+    void show_afc();
+    void show_tsc();
+    RfDesenseTxTestGsm();
+    virtual ~RfDesenseTxTestGsm();
+    static std::shared_ptr<RfDesenseTxTestGsm> get_instance();
+private:
+    static std::shared_ptr<RfDesenseTxTestGsm> m_instance;
+    static std::mutex mutex;
+    int min = -1;
+    int max = -1;
+    int min2 = -1;
+    int max2 = -1;
+    int step = 1;
+    static const int INDEX_BAND;
+    static const int INDEX_CHANNEL;
+    static const int INDEX_POWER;
+    static const int INDEX_AFC;
+    static const int INDEX_TSC;
+    static const int INDEX_PATTERN;
+    static std::string band;
+    static std::string channel;
+    static std::string power;
+    static std::string afc;
+    static std::string tsc;
+    static std::string pattern;
+    std::string command;
+    bool check_channel(int index, std::string channel);
+    bool check_power(int index, std::string power);
+    bool check_afc(std::string afc);
+    bool check_tsc(std::string tsc);
+    bool check_pattern(std::string pattern);
+    static const std::vector<std::string> band_values;
+    static const std::vector<std::vector<std::string>> gsm_gmsk_limits;
+};
+
+#endif /* RFDESENSETXTESTGSM_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestLte.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestLte.cpp
new file mode 100644
index 0000000..56c6275
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestLte.cpp
@@ -0,0 +1,614 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include "rfdesense/RfDesenseTxTestLte.h"
+
+#include <algorithm>
+#include <iterator>
+#include <stdexcept>
+
+#include "rfdesense/RfDesenseTxTestBase.h"
+#include "util/log_extra.h"
+#include "em.h"
+
+#undef LOG_TAG
+#define LOG_TAG "EM_RfDesenseTxTestLte"
+
+const int RfDesenseTxTestLte::INDEX_BAND = 0;
+const int RfDesenseTxTestLte::INDEX_BAND_WIDTH = 1;
+const int RfDesenseTxTestLte::INDEX_FREQ = 2;
+const int RfDesenseTxTestLte::INDEX_VRB_START = 3;
+const int RfDesenseTxTestLte::INDEX_VRB_LENGTH = 4;
+const int RfDesenseTxTestLte::INDEX_MCS = 5;
+const int RfDesenseTxTestLte::INDEX_POWER = 6;
+const int RfDesenseTxTestLte::INDEX_MODE = 7;
+const int RfDesenseTxTestLte::INDEX_TDD_CONFIG = 8;
+const int RfDesenseTxTestLte::INDEX_TDD_SPECIAL = 9;
+std::string RfDesenseTxTestLte::band="";
+std::string RfDesenseTxTestLte::band_width="";
+std::string RfDesenseTxTestLte::freq="";
+std::string RfDesenseTxTestLte::tdd_config="";
+std::string RfDesenseTxTestLte::tdd_special="";
+std::string RfDesenseTxTestLte::vrb_start="";
+std::string RfDesenseTxTestLte::vrb_length="";
+std::string RfDesenseTxTestLte::mcs="";
+std::string RfDesenseTxTestLte::power="";
+std::string RfDesenseTxTestLte::mode="";
+
+const std::vector<std::string> RfDesenseTxTestLte::band_fdd = {"1","2","3","4","5","6","7","8","9","10","11","12",
+            "13","14","19","20","21","22","23","24","25","26","27","28","29","30","31","66"};
+const std::vector<std::string> RfDesenseTxTestLte::band_tdd = {"33","34","35","36","37","38","39","40","41","42","43","44"};
+const std::vector<std::vector<std::string>> RfDesenseTxTestLte::fdd_freq_limits = {
+            {"19200","19800"},
+            {"18500","19100"},
+            {"17100","17850"},
+            {"17100","17550"},
+            {"8240","8490"},
+            {"8300","8400"},
+            {"25000","25700"},
+            {"8800","9150"},
+            {"17499","17849"},
+            {"17100","17700"},
+            {"14279","14479"},
+            {"6990","7160"},
+            {"7770","7870 "},
+            {"7880","7980"},
+            {"0","0"},
+            {"0","0"},
+            {"7040","7160"},
+            {"8150","8300"},
+            {"8300","8450"},
+            {"8320","8620"},
+            {"14479","14629"},
+            {"34100","34900"},
+            {"20000","20200"},
+            {"16265","16605"},
+            {"18500","19150"},
+            {"8140","8490 "},
+            {"8070","8240"},
+            {"7030","7480"},
+            {"0","0"},
+            {"23050","23150"},
+            {"4525","4575"},
+            {"17100","17800"}
+    };
+
+const std::vector<std::vector<std::string>> RfDesenseTxTestLte::tdd_freq_limits = {
+            {"19000","19200"},
+            {"20100","20250"},
+            {"18500","19100"},
+            {"19300","19900"},
+            {"19100","19300"},
+            {"25700","26200"},
+            {"18800","19200"},
+            {"23000","24000"},
+            {"24960","26900"},
+            {"34000","36000"},
+            {"36000","38000"}
+    };
+
+std::map<int, std::string> RfDesenseTxTestLte::lte_fdd_values = { { INDEX_BAND,
+        "3" }, { INDEX_BAND_WIDTH, "3" }, { INDEX_FREQ, "17475" }, { INDEX_VRB_START, "0" }, {
+                INDEX_VRB_LENGTH, "1" }, { INDEX_MCS, "0" }, { INDEX_POWER, "23" }, { INDEX_MODE,
+        "1" }, { INDEX_TDD_CONFIG, "0" }, { INDEX_TDD_SPECIAL, "0" }, };
+std::map<int, std::string> RfDesenseTxTestLte::lte_tdd_valuse= { { INDEX_BAND,
+        "38" }, { INDEX_BAND_WIDTH, "3" }, { INDEX_FREQ, "25950" }, { INDEX_VRB_START, "0" }, {
+                INDEX_VRB_LENGTH, "1" }, { INDEX_MCS, "0" }, { INDEX_POWER, "23" }, { INDEX_MODE,
+        "1" }, { INDEX_TDD_CONFIG, "0" }, { INDEX_TDD_SPECIAL, "0" }, };
+
+RfDesenseTxTestLte::RfDesenseTxTestLte(int type) {
+    modem_type = type;
+    std::map<int, std::string> tmp;
+    if(modem_type == utils::MODEM_LTE_FDD){
+        tmp = lte_fdd_values;
+    } else if(modem_type == utils::MODEM_LTE_TDD) {
+        tmp = lte_tdd_valuse;
+    }
+    LOG_D(LOG_TAG, "modem_type: %d", modem_type);
+    if(!tmp.empty()) {
+        band = tmp[INDEX_BAND];
+        band_width = tmp[INDEX_BAND_WIDTH];
+        freq = tmp[INDEX_FREQ];
+        tdd_config = tmp[INDEX_TDD_CONFIG];
+        tdd_special = tmp[INDEX_TDD_SPECIAL];
+        vrb_start = tmp[INDEX_VRB_START];
+        vrb_length = tmp[INDEX_VRB_LENGTH];
+        mcs = tmp[INDEX_MCS];
+        power = tmp[INDEX_POWER];
+        mode = tmp[INDEX_MODE];
+    }
+
+}
+
+void RfDesenseTxTestLte::show_default() {
+    std::string str;
+    std::string band_width_tmp(rfdesense_lte_bandwidth[std::stoi(band_width)].name);
+    std::string mcs_tmp(rfdesense_lte_mcs[std::stoi(mcs)].name);
+    std::string duplex;
+    if (modem_type == utils::MODEM_LTE_FDD) {
+        duplex = "LTE(fdd) ";
+    } else if (modem_type == utils::MODEM_LTE_FDD) {
+        duplex = "LTE(tdd) ";
+    }
+    str = duplex + "mode: "
+            + (std::stoi(mode) == 0 ?
+                    std::string("single tone") :
+                    std::string("modulation signal")) + ", Band: " + band
+            + ", UL Bandwidth: " + band_width_tmp + ", UL Freq(100kHz): " + freq
+            + ", TDD Config index: " + tdd_config
+            + ", TDD Special SF Config Index: " + tdd_special
+            + ", VRB Start(0~99): " + vrb_start + ", VRB Length(1~100): "
+            + vrb_length + ", MCS: " + mcs_tmp + ", Power Level(dBm)(-50-23): "
+            + power;
+    emResultNotifyWithDone(str);
+}
+
+RfDesenseTxTestLte::~RfDesenseTxTestLte() {
+    // TODO Auto-generated destructor stub
+}
+std::string RfDesenseTxTestLte::modemTypeToString(int type) {
+    switch(modem_type){
+        case utils::MODEM_LTE_FDD:
+            return "LTE(FDD)";
+        case utils::MODEM_LTE_TDD:
+            return "LTE(TDD)";
+        default:
+            return "UNKNOWN";
+    }
+}
+
+std::string RfDesenseTxTestLte::get_command() {
+    std::string atcmd = "";
+    if(utils::is93Modem() && (mode == "0")){
+        atcmd = "AT+ERFTX=6,0,2,";
+    } else {
+        atcmd = "AT+ERFTX=6,0,1,";
+    }
+    command = band + "," + band_width  + ","
+            + freq + ","
+            + (modem_type == utils::MODEM_LTE_TDD ? "0" : "1") + ","
+#if 0
+            + (modem_type == utils::MODEM_LTE_TDD ? tdd_config : "0") + ","
+            + (modem_type == utils::MODEM_LTE_TDD ? tdd_special : "0") + ","
+#endif
+            + tdd_config + ","
+            + tdd_special + ","
+            + vrb_start + ","
+            + vrb_length + ","
+            + mcs + ","
+            + power;
+    LOG_D(LOG_TAG, "modem_type(%) command: %s", modemTypeToString(modem_type), command);
+    return command;
+
+}
+std::string RfDesenseTxTestLte::get_band() {
+    return band;
+}
+std::string RfDesenseTxTestLte::get_power() {
+    return power;
+}
+
+bool RfDesenseTxTestLte::check_band(std::string band) {
+    std::vector<std::string> band_values;
+    if(modem_type == utils::MODEM_LTE_TDD){
+        band_values = band_tdd;
+    } else if(modem_type == utils::MODEM_LTE_FDD) {
+        band_values = band_fdd;
+    } else {
+        LOG_D(LOG_TAG, "check_band(): modem type (%s) isn't right", modemTypeToString(modem_type));
+        return false;
+    }
+
+    auto is_band_find = std::find(band_values.begin(), band_values.end(), band); //band
+    int band_index = -1;
+    if(is_band_find != band_values.end()) {
+        band_index = std::distance(band_values.begin(), is_band_find);
+        LOG_D(LOG_TAG, "checks: band_index: %d, band: %s", band_index, band.c_str());
+    } else {
+        LOG_D(LOG_TAG, "band value(%s) isn't invalid", band.c_str());
+        return false;
+    }
+    return true;
+}
+
+bool RfDesenseTxTestLte::check_band_width(std::string band_width) {
+    int value = -1;
+    try {
+        value = std::stoi(band_width);
+    } catch (std::invalid_argument &err) {
+        LOG_D(LOG_TAG, "check_band_width,check_band_width(%s) is invalid, reason: %s", band_width.c_str(), err.what());
+        return false;
+    }
+    if (value < 0 || value > 5) {
+        LOG_D(LOG_TAG, "check_band_width value range is [%d, %d], input value is %d", 0, 5, value);
+        return false;
+    }
+    return true;
+}
+
+bool RfDesenseTxTestLte::check_freq(std::string freq) {
+    return true;
+}
+
+bool RfDesenseTxTestLte::check_tdd_config(std::string config) {
+    int value = -1;
+    try {
+        value = std::stoi(config);
+    } catch (std::invalid_argument &err) {
+        LOG_D(LOG_TAG, "check_tdd_config,check_tdd_config(%s) is invalid, reason: %s", config.c_str(), err.what());
+        return false;
+    }
+    if(modem_type == utils::MODEM_LTE_TDD){
+        if(value < 0 || value >6){
+            LOG_D(LOG_TAG, "check_tdd_config value range is [%d, %d], input value is %d", 0, 6, value);
+            return false;
+        }
+    } else if(modem_type == utils::MODEM_LTE_FDD) {
+        if(value != 0) {
+            return false;
+        }
+    } else {
+        LOG_D(LOG_TAG, "check_tdd_config(): modem type (%s) isn't right", modemTypeToString(modem_type));
+        return false;
+    }
+    return true;
+}
+
+bool RfDesenseTxTestLte::check_tdd_special(std::string special) {
+    int value = -1;
+    try {
+        value = std::stoi(special);
+    } catch (std::invalid_argument &err) {
+        LOG_D(LOG_TAG, "check_tdd_special,check_tdd_config(%s) is invalid, reason: %s", special.c_str(), err.what());
+        return false;
+    }
+    if(modem_type == utils::MODEM_LTE_TDD){
+        if(value < 0 || value >9){
+            LOG_D(LOG_TAG, "check_tdd_special value range is [%d, %d], input value is %d", 0, 9, value);
+            return false;
+        }
+    } else if(modem_type == utils::MODEM_LTE_FDD) {
+        if(value != 0) {
+            return false;
+        }
+    } else {
+        LOG_D(LOG_TAG, "check_tdd_special(): modem type (%s) isn't right", modemTypeToString(modem_type));
+        return false;
+    }
+    return true;
+}
+
+bool RfDesenseTxTestLte::check_vrb_start(std::string start) {
+    std::string s;
+    int value = -1;
+    try {
+        value = std::stoi(start);
+    } catch (std::invalid_argument &err) {
+        s = utils::format("check_vrb_start,check_vrb_start(%s) is invalid, reason: %s", start.c_str(), err.what());
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_vrb_start,check_vrb_start(%s) is invalid, reason: %s", start.c_str(), err.what());
+        return false;
+    }
+    if (value < 0 || value > 99) {
+        s = utils::format("check_vrb_start value range is [%d, %d], input value is %d", 0, 9, value);
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_vrb_start value range is [%d, %d], input value is %d", 0, 9, value);
+        return false;
+    }
+    return true;
+}
+
+bool RfDesenseTxTestLte::check_vrb_length(std::string length) {
+    std::string s;
+    int value = -1;
+    try {
+        value = std::stoi(length);
+    } catch (std::invalid_argument &err) {
+        s = utils::format("check_vrb_length,check_vrb_length(%s) is invalid, reason: %s", length.c_str(), err.what());
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_vrb_length,check_vrb_length(%s) is invalid, reason: %s", length.c_str(), err.what());
+        return false;
+    }
+    if (value < 1  || value > 100) {
+        s = utils::format("check_vrb_length value range is [%d, %d], input value is %d", 1, 100, value);
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_vrb_length value range is [%d, %d], input value is %d", 1, 100, value);
+        return false;
+    }
+    return true;
+}
+
+bool RfDesenseTxTestLte::check_mcs(std::string mcs) {
+    int value = -1;
+    try {
+        value = std::stoi(mcs);
+    } catch (std::invalid_argument &err) {
+        LOG_D(LOG_TAG, "check_mcs,check_mcs(%s) is invalid, reason: %s", mcs.c_str(), err.what());
+        return false;
+    }
+    if (value < 0 || value > 2) {
+        LOG_D(LOG_TAG, "check_mcs value range is [%d, %d], input value is %d", 0, 2, value);
+        return false;
+    }
+    return true;
+}
+
+bool RfDesenseTxTestLte::check_power(std::string power) {
+    std::string s;
+    int value = -1;
+    try {
+        value = std::stoi(power);
+    } catch (std::invalid_argument &err) {
+        s = utils::format("check_power,check_power(%s) is invalid, reason: %s", power.c_str(), err.what());
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_power,check_power(%s) is invalid, reason: %s", power.c_str(), err.what());
+        return false;
+    }
+    if (value < -50 || value > 23) {
+        s = utils::format("check_power value range is [%d, %d], input value is %d", -50, 23, value);
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_power value range is [%d, %d], input value is %d", -50, 23, value);
+        return false;
+    }
+    return true;
+}
+
+bool RfDesenseTxTestLte::check_mode(std::string mode) {
+    int value = -1;
+    try {
+        value = std::stoi(mode);
+    } catch (std::invalid_argument &err) {
+        LOG_D(LOG_TAG, "check_tone,check_tone(%s) is invalid, reason: %s", mode.c_str(), err.what());
+        return false;
+    }
+    if (value == 0 || value == 1) {
+        LOG_D(LOG_TAG, "check_mode value range is %d or %d, input value is %d", 0, 1, mode);
+        return false;
+    }
+    return true;
+}
+
+bool RfDesenseTxTestLte::set_mode(int value){
+    std::string s;
+    if(value !=0 && value != 1) {
+        s = utils::format("set_mode: value(%d) is out of range", value);
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "set_mode: value(%d) is out of range", value);
+        return false;
+    }
+    mode = std::to_string(value);
+    if(modem_type == utils::MODEM_LTE_FDD){
+        lte_fdd_values[INDEX_MODE] = mode;
+    } else if(modem_type == utils::MODEM_LTE_TDD) {
+        lte_tdd_valuse[INDEX_MODE] = mode;
+    } else {
+        em_result_notify_fail("set_mode error");
+        LOG_D(LOG_TAG, "set_mode error");
+        return false;
+    }
+    em_result_notify_ok("mode: " + (value == 0 ?
+            std::string("single tone") :
+            std::string("modulation signal")));
+    return true;
+}
+
+bool RfDesenseTxTestLte::set_band(int value){
+    std::string s;
+    std::vector<std::string> band_values;
+    if(modem_type == utils::MODEM_LTE_TDD){
+        band_values = band_tdd;
+    } else if(modem_type == utils::MODEM_LTE_FDD) {
+        band_values = band_fdd;
+    } else {
+        s = utils::format("check_band(): modem type (%s) isn't right", modemTypeToString(modem_type));
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_band(): modem type (%s) isn't right", modemTypeToString(modem_type));
+        return false;
+    }
+    if(value < 0 || value >= band_values.size()){
+        s = utils::format("set_band: value(%d) is out of range", value);
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "set_band: value(%d) is out of range", value);
+        return false;
+    }
+    band = band_values[value];
+    if(modem_type == utils::MODEM_LTE_TDD){
+        lte_tdd_valuse[INDEX_BAND] = band;
+    } else if(modem_type == utils::MODEM_LTE_FDD) {
+        lte_fdd_values[INDEX_BAND] = band;
+    } else {
+        s = utils::format("check_band(): modem type (%s) isn't right", modemTypeToString(modem_type));
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_band(): modem type (%s) isn't right", modemTypeToString(modem_type));
+        return false;
+    }
+    em_result_notify_ok("band: " + band);
+    return true;
+}
+
+bool RfDesenseTxTestLte::set_bandwith(int value){
+    std::string s;
+    if (value < 0 || value > 5) {
+        s = utils::format("check_band_width value range is [%d, %d], input value is %d", 0, 5, value);
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_band_width value range is [%d, %d], input value is %d", 0, 5, value);
+        return false;
+    }
+    band_width = std::to_string(value);
+    if(modem_type == utils::MODEM_LTE_FDD){
+        lte_fdd_values[INDEX_BAND_WIDTH] = band_width;
+    } else if(modem_type == utils::MODEM_LTE_TDD) {
+        lte_tdd_valuse[INDEX_BAND_WIDTH] = band_width;
+    } else {
+        em_result_notify_fail("set_bandwith error");
+        LOG_D(LOG_TAG, "set_bandwith error");
+        return false;
+    }
+    em_result_notify_ok(std::string("band_width: ") + rfdesense_lte_bandwidth[value].name);
+    return true;
+}
+
+bool RfDesenseTxTestLte::set_freq(std::string str){
+    freq = str;
+    if(modem_type == utils::MODEM_LTE_FDD){
+        lte_fdd_values[INDEX_FREQ] = freq;
+    } else if(modem_type == utils::MODEM_LTE_TDD) {
+        lte_tdd_valuse[INDEX_FREQ] = freq;
+    } else {
+        em_result_notify_fail("set_freq error");
+        LOG_D(LOG_TAG, "set_freq error");
+        return false;
+    }
+    em_result_notify_ok("freq: " + freq);
+    return true;
+
+}
+
+bool RfDesenseTxTestLte::set_tdd_config(int value){
+    if(modem_type == utils::MODEM_LTE_TDD){
+        if(value < 0 || value >6){
+            std::string s;
+            s = utils::format("check_tdd_config value range is [%d, %d], input value is %d", 0, 6, value);
+            em_result_notify_fail(s);
+            LOG_D(LOG_TAG, "check_tdd_config value range is [%d, %d], input value is %d", 0, 6, value);
+            return false;
+        }
+        tdd_config = std::to_string(value);
+        lte_tdd_valuse[INDEX_TDD_CONFIG] = tdd_config;
+    }
+    em_result_notify_ok("tdd_config: " + tdd_config);
+    return true;
+}
+
+bool RfDesenseTxTestLte::set_tdd_special(int value){
+    if(modem_type == utils::MODEM_LTE_TDD){
+        if(value < 0 || value >9){
+            std::string s;
+            s = utils::format("check_tdd_special value range is [%d, %d], input value is %d", 0, 9, value);
+            em_result_notify_fail(s);
+            LOG_D(LOG_TAG, "check_tdd_special value range is [%d, %d], input value is %d", 0, 9, value);
+            return false;
+        }
+        tdd_special = std::to_string(value);
+        lte_tdd_valuse[INDEX_TDD_SPECIAL] = tdd_special;
+    }
+    em_result_notify_ok("tdd_special: " + tdd_special);
+    return true;
+}
+
+bool RfDesenseTxTestLte::set_start(std::string str){
+    if(!check_vrb_start(str)) return false;
+    vrb_start = str;
+    if(modem_type == utils::MODEM_LTE_FDD){
+        lte_fdd_values[INDEX_VRB_START] = vrb_start;
+    } else if(modem_type == utils::MODEM_LTE_TDD) {
+        lte_tdd_valuse[INDEX_VRB_START] = vrb_start;
+    } else {
+        em_result_notify_fail("set_start error");
+        LOG_D(LOG_TAG, "set_start error");
+        return false;
+    }
+    em_result_notify_ok("vrb_start: " + vrb_start);
+    return true;
+
+}
+
+bool RfDesenseTxTestLte::set_length(std::string str){
+    if(!check_vrb_length(str)) return false;
+    vrb_length = str;
+    if(modem_type == utils::MODEM_LTE_FDD){
+        lte_fdd_values[INDEX_VRB_LENGTH] = vrb_length;
+    } else if(modem_type == utils::MODEM_LTE_TDD) {
+        lte_tdd_valuse[INDEX_VRB_LENGTH] = vrb_length;
+    } else {
+        em_result_notify_fail("set_start error");
+        LOG_D(LOG_TAG, "set_length error");
+        return false;
+    }
+    em_result_notify_ok("vrb_length: " + vrb_length);
+    return true;
+}
+
+bool RfDesenseTxTestLte::set_power(std::string str){
+    if(!check_power(str)) return false;
+    power = str;
+    if(modem_type == utils::MODEM_LTE_FDD){
+        lte_fdd_values[INDEX_POWER] = power;
+    } else if(modem_type == utils::MODEM_LTE_TDD) {
+        lte_tdd_valuse[INDEX_POWER] = power;
+    } else {
+        em_result_notify_fail("set_start error");
+        LOG_D(LOG_TAG, "set_power error");
+        return false;
+    }
+    em_result_notify_ok("power: " + power);
+    return true;
+}
+bool RfDesenseTxTestLte::set_mcs(int value) {
+    if (value < 0 || value > 2) {
+        std::string s;
+        s = utils::format("check_mcs value range is [%d, %d], input value is %d", 0, 2, value);
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_mcs value range is [%d, %d], input value is %d", 0, 2, value);
+        return false;
+    }
+    mcs = std::to_string(value);
+    if(modem_type == utils::MODEM_LTE_FDD){
+        lte_fdd_values[INDEX_MCS] = mcs;;
+    } else if(modem_type == utils::MODEM_LTE_TDD) {
+        lte_tdd_valuse[INDEX_MCS] = mcs;;
+    } else {
+        em_result_notify_fail("set_start error");
+        LOG_D(LOG_TAG, "set_mcs error");
+        return false;
+    }
+    em_result_notify_ok(std::string("mcs: ") + rfdesense_lte_mcs[value].name);
+    return true;
+}
+
+void RfDesenseTxTestLte::show_freq(){
+    emResultNotifyWithDone("UL Freq(100kHZ): " + freq);
+}
+
+void RfDesenseTxTestLte::show_start(){
+    emResultNotifyWithDone("VRB Start(0~99): " + vrb_start);
+}
+
+void RfDesenseTxTestLte::show_length(){
+    emResultNotifyWithDone("VRB Length(1~100): " + vrb_length);
+}
+
+void RfDesenseTxTestLte::show_power(){
+    emResultNotifyWithDone("Power Level(dBm)(-50~23): " + power);
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestLte.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestLte.h
new file mode 100644
index 0000000..8b0f53a
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestLte.h
@@ -0,0 +1,110 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef RFDESENSETXTESTLTE_H_
+#define RFDESENSETXTESTLTE_H_
+
+#include <string>
+#include <vector>
+#include <map>
+
+#include "util/utils.h"
+
+class RfDesenseTxTestLte {
+public:
+    RfDesenseTxTestLte(int type);
+    virtual ~RfDesenseTxTestLte();
+    void show_default();
+    std::string get_command();
+    std::string get_band();
+    std::string get_power();
+    bool set_mode(int value);
+    bool set_band(int value);
+    bool set_bandwith(int value);
+    bool set_freq(std::string str);
+    bool set_tdd_config(int value);
+    bool set_tdd_special(int value);
+    bool set_start(std::string str);
+    bool set_length(std::string str);
+    bool set_mcs(int value);
+    bool set_power(std::string str);
+    void show_freq();
+    void show_start();
+    void show_length();
+    void show_power();
+private:
+    bool check_band(std::string band);
+    bool check_band_width(std::string band_width);
+    bool check_freq(std::string freq);
+    bool check_tdd_config(std::string config);
+    bool check_tdd_special(std::string special);
+    bool check_vrb_start(std::string start);
+    bool check_vrb_length(std::string length);
+    bool check_mcs(std::string mcs);
+    bool check_power(std::string power);
+    bool check_mode(std::string mode);
+    std::string modemTypeToString(int type);
+
+    std::string command;
+    static const int INDEX_BAND;
+    static const int INDEX_BAND_WIDTH;
+    static const int INDEX_FREQ;
+    static const int INDEX_VRB_START;
+    static const int INDEX_VRB_LENGTH;
+    static const int INDEX_MCS;
+    static const int INDEX_POWER;
+    static const int INDEX_MODE;
+    static const int INDEX_TDD_CONFIG;
+    static const int INDEX_TDD_SPECIAL;
+    static std::string band;
+    static std::string band_width;
+    static std::string freq;
+    static std::string tdd_config;
+    static std::string tdd_special;
+    static std::string vrb_start;
+    static std::string vrb_length;
+    static std::string mcs;
+    static std::string power;
+    static std::string mode;
+    static std::map<int, std::string> lte_fdd_values;
+    static std::map<int, std::string> lte_tdd_valuse;
+    int modem_type = utils::MODEM_UNKNOWN;
+    static const std::vector<std::string> band_fdd;
+    static const std::vector<std::string> band_tdd;
+    static const std::vector<std::vector<std::string>> fdd_freq_limits;
+    static const std::vector<std::vector<std::string>> tdd_freq_limits;
+};
+
+#endif /* RFDESENSETXTESTLTE_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestTd.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestTd.cpp
new file mode 100644
index 0000000..f945a71
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestTd.cpp
@@ -0,0 +1,331 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include "rfdesense/RfDesenseTxTestTd.h"
+
+#include <algorithm>
+#include <iterator>
+#include <stdexcept>
+
+#include "em.h"
+#include "rfdesense/RfDesenseTxTestBase.h"
+#include "util/log_extra.h"
+
+#undef LOG_TAG
+#define LOG_TAG "EM_RfDesenseTxTestTd"
+const int RfDesenseTxTestTd::INDEX_BAND = 0;
+const int RfDesenseTxTestTd::INDEX_CHANNEL = 1;
+const int RfDesenseTxTestTd::INDEX_POWER = 2;
+std::string RfDesenseTxTestTd::band = "";
+std::string RfDesenseTxTestTd::channel= "";
+std::string RfDesenseTxTestTd::power= "";
+const std::vector<std::string> RfDesenseTxTestTd::tdscdma_band_values = {"1","6"};
+const std::vector<std::vector<std::string>> RfDesenseTxTestTd::tdscdma_limits = {
+            {"10087","10054","10121","10054","10121","24","10","24"},
+            {"9500","9404","9596","9404","9596","24","10","24"}};
+const std::vector<std::string> RfDesenseTxTestTd::wcdma_band_values = {"1","2","3","4","5","6","7","8","9","10","11","12","13","14","19","20","21","22"};
+const std::vector<std::vector<std::string>> RfDesenseTxTestTd::wcdma_limits = {
+            {"9750","9612","9888","9612","9888","23","-55","24"},
+            {"9262","9262","9538","12","287","23","-55","24"},
+            {"937","937","1288","937","1288","23","-55","24"},
+            {"1312","1312","1513","1662","1862","23","-55","24"},
+            {"4132","4132","4233","782","862","23","-55","24"},
+            {"4162","4162","4188","812","837","23","-55","24"},
+            {"2012","2012","2338","2362","2687","23","-55","24"},
+            {"2712","2712","2863","2712","2863","23","-55","24"},
+            {"8762","8762","8912","8762","8912","23","-55","24"},
+            {"2887","2887","3163","3187","3462","23","-55","24"},
+            {"3487","3487","3562","3487","3562","23","-55","24"},
+            {"3617","3617","3678","3707","3767","23","-55","24"},
+            {"3792","3792","3818","3842","3867","23","-55","24"},
+            {"3892","3892","3918","3942","3967","23","-55","24"},
+            {"312","312","363","387","437","23","-55","24"},
+            {"4287","4287","4413","4287","4413","23","-55","24"},
+            {"462","462","512","462","512","23","-55","24"},
+            {"4437","4437","4813","4437","4813","23","-55","24"}};
+std::map<int, std::string> RfDesenseTxTestTd::tdscdam_values = {{INDEX_BAND, "1"},{INDEX_CHANNEL, "10087"},{INDEX_POWER, "24"}};
+std::map<int, std::string> RfDesenseTxTestTd::wcdma_values = {{INDEX_BAND, "1"},{INDEX_CHANNEL, "9750"},{INDEX_POWER, "23"}};
+
+RfDesenseTxTestTd::RfDesenseTxTestTd(int modemType) {
+    this->modem_type = modemType;
+    if(modem_type == utils::MODEM_TDSCDMA){
+        band = tdscdam_values[INDEX_BAND];
+        channel = tdscdam_values[INDEX_CHANNEL];
+        power = tdscdam_values[INDEX_POWER];
+    } else if(modem_type == utils::MODEM_WCDMA) {
+        band = wcdma_values[INDEX_BAND];
+        channel = wcdma_values[INDEX_CHANNEL];
+        power = wcdma_values[INDEX_POWER];
+    }
+}
+
+RfDesenseTxTestTd::~RfDesenseTxTestTd() {
+    // TODO Auto-generated destructor stub
+}
+
+std::string RfDesenseTxTestTd::modemTypeToString(int type) {
+    switch(modem_type){
+        case utils::MODEM_TDSCDMA:
+            return "TDSCDMA";
+        case utils::MODEM_WCDMA:
+            return "MODEM_WCDMA";
+        default:
+            return "UNKNOWN";
+    }
+}
+
+std::string RfDesenseTxTestTd::get_command() {
+    std::string command = "AT+ERFTX=0,0," + band + "," + channel + "," + power;
+    LOG_D(LOG_TAG, "GSM command: %s", command.c_str());
+    return command;
+}
+
+std::string RfDesenseTxTestTd::get_band(){
+    return band;
+}
+
+std::string RfDesenseTxTestTd::get_power(){
+    return power;
+}
+
+bool RfDesenseTxTestTd::check_channel(int index, std::string channel) {
+    std::string s;
+    std::vector<std::vector<std::string>> limits;
+    if(modem_type == utils::MODEM_TDSCDMA){
+        limits = tdscdma_limits;
+    } else if(modem_type == utils::MODEM_WCDMA) {
+        limits = wcdma_limits;
+    } else {
+        s = utils::format("check_channel(): modem type (%s) isn't right", modemTypeToString(modem_type));
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_channel(): modem type (%s) isn't right", modemTypeToString(modem_type));
+        return false;
+    }
+
+    if(index >= limits.size()) {
+        s = utils::format("check_channel,index(%d) is invalid", index);
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_channel,index(%d) is invalid", index);
+        return false;
+    }
+    int value = -1;
+    try {
+        value = std::stoi(channel);
+    } catch (std::invalid_argument &err) {
+        s = utils::format("check_channel,channel(%s) is invalid, reason: %s", channel.c_str(), err.what());
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_channel,channel(%s) is invalid, reason: %s", channel.c_str(), err.what());
+        return false;
+    }
+    step = 1;
+    std::vector<std::string> limit = limits[index];
+    min = std::stoi(limit[RfDesenseTxTestBase::CHANNEL_MIN]);
+    max =  std::stoi(limit[RfDesenseTxTestBase::CHANNEL_MAX]);
+    min2 =  std::stoi(limit[RfDesenseTxTestBase::CHANNEL_MIN2]);
+    max2 =  std::stoi(limit[RfDesenseTxTestBase::CHANNEL_MAX2]);
+    if ((value < min || value > max) && (value < min2 || value > max2)) {
+        s = utils::format("check_channel,channel(%s) is invalid, range is [%d, %d] or [%d, %d]" , channel.c_str(), min, max, min2, max2);
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_channel,channel(%s) is invalid, range is [%d, %d] or [%d, %d]" , channel.c_str(), min, max, min2, max2);
+        return false;
+    }
+    return true;
+}
+
+bool RfDesenseTxTestTd::check_power(int index ,std::string power) {
+    std::string s;
+    std::vector<std::vector<std::string>> limits;
+    if(modem_type == utils::MODEM_TDSCDMA){
+        limits = tdscdma_limits;
+    } else if(modem_type == utils::MODEM_WCDMA) {
+        limits = wcdma_limits;
+    } else {
+        s = utils::format("check_power(): modem type (%s) isn't right", modemTypeToString(modem_type));
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_power(): modem type (%s) isn't right", modemTypeToString(modem_type));
+        return false;
+    }
+    if(index >= limits.size()) {
+        s = utils::format("check_power,index(%d) is invalid", index);
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_power,index(%d) is invalid", index);
+        return false;
+    }
+    int value = -1;
+    try {
+        value = std::stoi(power);
+    } catch (std::invalid_argument &err) {
+        s = utils::format("check_power,power(%s) is invalid, reason: %s", power.c_str(), err.what());
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_power,power(%s) is invalid, reason: %s", power.c_str(), err.what());
+        return false;
+    }
+    step = 1;
+    std::vector<std::string> limit = limits[index];
+    min = std::stoi(limit[RfDesenseTxTestBase::POWER_MIN]);
+    max =  std::stoi(limit[RfDesenseTxTestBase::POWER_MAX]);
+    if (value < min || value > max) {
+        s = utils::format("check_power,power(%s) is invalid, range is [%d, %d]" , power.c_str(), min, max);
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_power,power(%s) is invalid, range is [%d, %d]" , power.c_str(), min, max);
+        return false;
+    }
+    if (step != 1 && (value - min) % step != 0) {
+        return false;
+    }
+    return true;
+}
+
+void RfDesenseTxTestTd::show_default() {
+    std::string temp;
+    if(modem_type == utils::MODEM_TDSCDMA){
+        int band_index = utils::find_index(tdscdma_band_values, band);
+        temp = "TDSCDMA parameters: Band: " + std::string(rfdesense_tdscdma_band[band_index].name) +
+            ", Channel(ARFCN): " + channel + ", Power Level(dBm): " + power;
+    } else if(modem_type == utils::MODEM_WCDMA) {
+        int band_index = utils::find_index(wcdma_band_values, band);
+        temp = "WCDMA parameters: Band: " + std::string(rfdesense_wcdma_band[band_index].name) +
+            ", Channel(ARFCN): " + channel + ", Power Level(dBm): " + power;
+    }
+    if(!temp.empty()) {
+        emResultNotifyWithDone(temp);
+    } else {
+        em_result_notify_fail("show_default");
+        LOG_D(LOG_TAG, "temp is null ");
+    }
+}
+
+bool RfDesenseTxTestTd::set_band(int value) {
+    std::string s;
+    std::vector<std::string> band_values;
+    if(modem_type == utils::MODEM_TDSCDMA){
+        band_values = tdscdma_band_values;
+    } else if(modem_type == utils::MODEM_WCDMA) {
+        band_values = wcdma_band_values;
+    } else {
+        s = utils::format("set_band(): modem type (%s) isn't right", modemTypeToString(modem_type));
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "set_band(): modem type (%s) isn't right", modemTypeToString(modem_type));
+        return false;
+    }
+    if(value < 0 || value >= band_values.size()) {
+        s = utils::format("set band(). value(%d) is out of range", value);
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "set band(). value(%d) is out of range", value);
+        return false;
+    }
+    band = band_values[value];
+    if(modem_type == utils::MODEM_TDSCDMA){
+        tdscdam_values[INDEX_BAND] = band;
+    } else if(modem_type == utils::MODEM_WCDMA) {
+        wcdma_values[INDEX_BAND] = band;
+    }
+    std::string temp;
+    if(modem_type == utils::MODEM_TDSCDMA){
+        em_result_notify_ok(std::string("band: ") + rfdesense_tdscdma_band[value].name);
+    } else if(modem_type == utils::MODEM_WCDMA) {
+        em_result_notify_ok(std::string("band: ") + rfdesense_wcdma_band[value].name);
+    }
+    return true;
+}
+
+bool RfDesenseTxTestTd::set_channel(std::string str) {
+    std::string s;
+    std::vector<std::string> band_values;
+    if(modem_type == utils::MODEM_TDSCDMA){
+        band_values = tdscdma_band_values;
+    } else if(modem_type == utils::MODEM_WCDMA) {
+        band_values = wcdma_band_values;
+    } else {
+        s = utils::format("set_channel(): modem type (%s) isn't right", modemTypeToString(modem_type));
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "set_channel(): modem type (%s) isn't right", modemTypeToString(modem_type));
+        return false;
+    }
+    int index = utils::find_index(band_values, band);
+    if(index < 0 ) {
+        s = utils::format("set_channel(%s) isn't invalid", band.c_str());
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "set_channel(%s) isn't invalid", band.c_str());
+        return false;
+    }
+    if(!check_channel(index, str)) return false;
+    channel = str;
+    if(modem_type == utils::MODEM_TDSCDMA){
+        tdscdam_values[INDEX_CHANNEL] = channel;
+    } else if(modem_type == utils::MODEM_WCDMA) {
+        wcdma_values[INDEX_CHANNEL] = channel;
+    }
+    em_result_notify_ok("channel: " + channel);
+    return true;
+}
+
+bool RfDesenseTxTestTd::set_power(std::string str) {
+    std::string s;
+    std::vector<std::string> band_values;
+    if(modem_type == utils::MODEM_TDSCDMA){
+        band_values = tdscdma_band_values;
+    } else if(modem_type == utils::MODEM_WCDMA) {
+        band_values = wcdma_band_values;
+    } else {
+        s = utils::format("set_power(): modem type (%s) isn't right", modemTypeToString(modem_type));
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "set_power(): modem type (%s) isn't right", modemTypeToString(modem_type));
+        return false;
+    }
+    int index = utils::find_index(band_values, band);
+    if(index < 0 ) {
+        s = utils::format("set_power(%s) isn't invalid", band.c_str());
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "set_power(%s) isn't invalid", band.c_str());
+        return false;
+    }
+    if(!check_power(index, str)) return false;
+    power = str;
+    if(modem_type == utils::MODEM_TDSCDMA){
+        tdscdam_values[INDEX_POWER] = str;
+    } else if(modem_type == utils::MODEM_WCDMA) {
+        wcdma_values[INDEX_POWER] = str;
+    }
+    em_result_notify_ok("power: " + power);
+    return true;
+}
+
+void RfDesenseTxTestTd::show_channel() {
+    emResultNotifyWithDone("Channel(UarfCN): " + channel);
+}
+
+void RfDesenseTxTestTd::show_power() {
+    emResultNotifyWithDone("Power Level(dBm): " + power);
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestTd.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestTd.h
new file mode 100644
index 0000000..e00508c
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestTd.h
@@ -0,0 +1,87 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef RFDESENSETXTESTTD_H_
+#define RFDESENSETXTESTTD_H_
+
+#include <string>
+#include <vector>
+#include <map>
+
+#include "util/utils.h"
+#include "rfdesense/RfDesenseTxTestBase.h"
+
+
+class RfDesenseTxTestTd {
+public:
+    std::string get_command();
+    std::string get_band();
+    std::string get_power();
+    bool set_band(int value);
+    bool set_channel(std::string str);
+    bool set_power(std::string str);
+    void show_channel();
+    void show_power();
+    RfDesenseTxTestTd(int modemType);
+    void show_default();
+    virtual ~RfDesenseTxTestTd();
+private:
+    //static std::shared_ptr<RfDesenseTxTestTd> m_instance;
+    int modem_type = utils::MODEM_UNKNOWN;
+    int min = -1;
+    int max = -1;
+    int min2 = -1;
+    int max2 = -1;
+    int step = 1;
+    static const int INDEX_BAND;
+    static const int INDEX_CHANNEL;
+    static const int INDEX_POWER;
+    static std::string band;
+    static std::string channel;
+    static std::string power;
+    std::string command;
+    static std::map<int, std::string> tdscdam_values;
+    static std::map<int, std::string> wcdma_values;
+    static const std::vector<std::string> tdscdma_band_values;
+    static const std::vector<std::vector<std::string>> tdscdma_limits;
+    static const std::vector<std::string> wcdma_band_values;
+    static const std::vector<std::vector<std::string>> wcdma_limits;
+    bool checks(std::vector<std::string> v);
+    bool check_channel(int index, std::string channel);
+    bool check_power(int index, std::string power);
+    std::string modemTypeToString(int type);
+};
+
+#endif /* RFDESENSETXTESTTD_H_ */