[Feature]add MT2731_MP2_MR2_SVN388 baseline version

Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/AtLine.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/AtLine.cpp
new file mode 100644
index 0000000..7abba8a
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/AtLine.cpp
@@ -0,0 +1,441 @@
+/* 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 "../util/AtLine.h"
+
+#include <assert.h>
+
+#include "../util/Misc.h"
+
+#define RFX_LOG_TAG "RfxAtLine"
+
+static const char *s_finalResponsesSuccess[] = { "OK", "CONNECT" /* some stacks start up data on another channel */
+};
+
+/**
+ * returns 1 if line is a final response indicating error
+ * See 27.007 annex B
+ * WARNING: NO CARRIER and others are sometimes unsolicited
+ */
+static const char *s_finalResponsesError[] = { "ERROR", "+CMS ERROR:",
+        "+CME ERROR:", "NO CARRIER", /* sometimes! */
+        "NO ANSWER", "NO DIALTONE", "+C2K ERROR:", "+EC2KCME ERROR", /* for distinguish CME error between MD1 and MD3 */
+};
+
+/**
+ * returns 1 if line is a intermediate response
+ * Such as
+ * AT+CMGW <CR>
+ * >XXXXXX  <CTRL+Z> or <ESC>
+ * OK
+ * WARNING: NO CARRIER and others are sometimes unsolicited
+ */
+static const char *s_IntermediatePattern[] = { "> ", };
+
+static const char *s_finalResponsesSuccessInNumeric[] = { "0", "1", };
+
+static const char *s_finalResponsesErrorInNumeric[] = { "2", "3", "4", "6", "7",
+        "8", "+CMS ERROR:", "+CME ERROR:", "+C2K ERROR:", };
+
+static const char *s_ackResponse[] = { "ACK" };
+
+AtLine::AtLine(const AtLine &other) {
+    // Only copy THIS node
+    assert(other.m_pNext == NULL);
+
+    m_line = (char *) calloc(strlen(other.m_line) + 1, sizeof(char));
+    if (m_line == NULL) {
+        //RFX_LOG_E(RFX_LOG_TAG, "OOM");
+        m_pNext = NULL;
+        m_pCur = NULL;
+        return;
+    }
+    memcpy(m_line, other.m_line, strlen(other.m_line));
+    m_line[strlen(other.m_line)] = '\0';
+    m_pNext = NULL;
+
+    // initialize p_cur
+    m_pCur = m_line;
+}
+
+AtLine::AtLine(const char* line, AtLine* next) {
+    m_line = (char *) calloc(strlen(line) + 1, sizeof(char));
+    if (m_line == NULL) {
+        //RFX_LOG_E(RFX_LOG_TAG, "OOM");
+        m_pNext = NULL;
+        m_pCur = NULL;
+        return;
+    }
+    memcpy(m_line, line, strlen(line));
+    m_line[strlen(line)] = '\0';
+    m_pNext = next;
+
+    // initialize p_cur
+    m_pCur = m_line;
+}
+
+AtLine::~AtLine() {
+    if (m_pNext) {
+        delete (m_pNext);
+    }
+
+    m_pCur = NULL;
+    if (m_line) {
+        free(m_line);
+    }
+}
+
+/**
+ * Starts tokenizing an AT response string
+ * Set err to -1 if this is not a valid response string, 0 on success.
+ * updates m_pCur with current position
+ */
+void AtLine::atTokStart(int *err) {
+    *err = 0;
+    m_pCur = m_line;
+    if (m_pCur == NULL) {
+        *err = -1;
+        return;
+    }
+
+    // skip prefix
+    // consume "^[^:]:"
+
+    m_pCur = strchr(m_pCur, ':');
+
+    if (m_pCur == NULL) {
+        *err = -1;
+        return;
+    }
+
+    m_pCur++;
+}
+
+char* AtLine::atTokChar(int *err) {
+    *err = 0;
+    if (m_pCur == NULL) {
+        *err = -1;
+        return NULL;
+    }
+    m_pCur = strchr(m_pCur, '(');
+
+    if (m_pCur == NULL) {
+        *err = -1;
+        return NULL;
+    }
+
+    return (m_pCur++);
+}
+
+void AtLine::skipWhiteSpace() {
+    if (m_pCur == NULL)
+        return;
+
+    while (*m_pCur != '\0' && isspace(*m_pCur)) {
+        m_pCur++;
+    }
+}
+
+void AtLine::skipNextComma() {
+    if (m_pCur == NULL)
+        return;
+
+    while (*m_pCur != '\0' && *m_pCur != ',') {
+        m_pCur++;
+    }
+
+    if (*m_pCur == ',') {
+        m_pCur++;
+    }
+}
+
+char* AtLine::nextTok() {
+    char *ret;
+
+    skipWhiteSpace();
+
+    if (m_pCur == NULL) {
+        ret = NULL;
+    } else if (*m_pCur == '"') {
+        m_pCur++;
+        ret = strsep(&m_pCur, "\"");
+        skipNextComma();
+    } else if (*m_pCur == '(' && *(m_pCur + 1) == '"') {
+        m_pCur = m_pCur + 2;
+        ret = strsep(&m_pCur, "\"");
+        skipNextComma();
+    } else {
+        ret = strsep(&m_pCur, ",");
+    }
+
+    return ret;
+}
+
+/**
+ * Parses the next integer in the AT response line and places it in *p_out
+ * Set err to 0 on success and -1 on fail
+ * updates m_pCur
+ * "base" is the same as the base param in strtol
+ */
+
+int AtLine::atTokNextintBase(int base, int uns, int *err) {
+    int out;
+    char *ret;
+    *err = 0;
+
+    if (m_pCur == NULL) {
+        *err = -1;
+        return 0;
+    }
+
+    ret = nextTok();
+
+    if (ret == NULL) {
+        *err = -1;
+        return 0;
+    } else {
+        long l;
+        char *end;
+
+        if (uns)
+            l = strtoul(ret, &end, base);
+        else
+            l = strtol(ret, &end, base);
+
+        out = (int) l;
+
+        if (end == ret) {
+            *err = -1;
+            return 0;
+        }
+        return out;
+    }
+}
+
+/**
+ * Parses the next base 10 integer in the AT response line
+ * and places it in *p_out
+ * Set err to 0 on success and -1 on fail
+ * updates m_pCur
+ */
+int AtLine::atTokNextint(int *err) {
+    return atTokNextintBase(10, 0, err);
+}
+
+/**
+ * Parses the next base 16 integer in the AT response line
+ * and places it in *p_out
+ * Set err to 0 on success and -1 on fail
+ * updates m_pCur
+ */
+int AtLine::atTokNexthexint(int *err) {
+    return atTokNextintBase(16, 1, err);
+}
+
+bool AtLine::atTokNextbool(int *err) {
+    int result;
+
+    result = atTokNextint(err);
+
+    if (*err < 0) {
+        *err = -1;
+        return false;
+    }
+
+    // booleans should be 0 or 1
+    if (!(result == 0 || result == 1)) {
+        *err = -1;
+        return false;
+    }
+
+    return result ? true : false;
+}
+
+char* AtLine::atTokNextstr(int *err) {
+    *err = 0;
+    if (m_pCur == NULL) {
+        *err = -1;
+        return NULL;
+    }
+
+    return nextTok();
+}
+
+/** returns 1 on "has more tokens" and 0 if no */
+int AtLine::atTokHasmore() {
+    return !(m_pCur == NULL || *m_pCur == '\0');
+}
+
+/// M: eMBMS feature
+void AtLine::atTokEqual(int *err) {
+    *err = 0;
+    m_pCur = m_line;
+    if (m_pCur == NULL) {
+        *err = -1;
+        return;
+    }
+
+    // skip prefix
+    // consume "^[^=]:"
+
+    m_pCur = strchr(m_pCur, '=');
+
+    if (m_pCur == NULL) {
+        *err = -1;
+        return;
+    }
+
+    m_pCur++;
+}
+
+/**
+ * Parses the next long long in the AT response line and places it in *p_out
+ * Set err to 0 on success and -1 on fail
+ * updates m_pCur
+ * "base" is the same as the base param in strtoll
+ */
+
+long long AtLine::atTokNextlonglongBase(int base, int uns, int *err) {
+    char *ret;
+    long long out;
+    *err = 0;
+
+    if (m_pCur == NULL) {
+        *err = -1;
+        return 0;
+    }
+
+    ret = nextTok();
+
+    if (ret == NULL) {
+        *err = -1;
+        return 0;
+    } else {
+        long long ll;
+        char *end;
+
+        if (uns)
+            ll = strtoull(ret, &end, base);
+        else
+            ll = strtoll(ret, &end, base);
+
+        out = ll;
+
+        if (end == ret) {
+            *err = -1;
+            return 0;
+        }
+    }
+
+    return out;
+}
+
+/**
+ * Parse the next base 10 long long in the AT response line
+ * and places it in *p_out
+ * Set err to 0 on success and -1 on fail
+ * updates m_pCur
+ */
+long long AtLine::atTokNextlonglong(int *err) {
+    return atTokNextlonglongBase(10, 0, err);
+}
+
+int AtLine::isFinalResponseSuccess() {
+    for (size_t i = 0; i < NUM_ELEMS(s_finalResponsesSuccess); i++) {
+        if (Misc::strStartsWith(m_line, s_finalResponsesSuccess[i])) {
+            return 1;
+        }
+    }
+
+    return 0;
+}
+
+int AtLine::isFinalResponseErrorEx(int channel_id) {
+    size_t i;
+
+//    int j=0;
+//    for(j=0; j<RfxRilUtils::getSimCount(); j++){
+//        if( (channel_id == (int)(RIL_URC+j*RIL_CHANNEL_OFFSET)) &&
+//                (RfxMisc::strStartsWith(m_line, "NO CARRIER")) ){
+//            // [ALPS01225455]NO CARRIER in URC channel is URC, not final response for mediatek modem
+//            return 0;
+//        }
+//    }
+
+    for (i = 0; i < NUM_ELEMS(s_finalResponsesError); i++) {
+        if (Misc::strStartsWith(m_line, s_finalResponsesError[i])) {
+            return 1;
+        }
+    }
+    return 0;
+}
+
+int AtLine::isIntermediatePattern() {
+    size_t i;
+    for (i = 0; i < NUM_ELEMS(s_IntermediatePattern); i++) {
+        if (!strcmp(m_line, s_IntermediatePattern[i])) {
+            return 1;
+        }
+    }
+    return 0;
+}
+
+bool AtLine::isFinalResponseSuccessInNumeric() {
+    for (size_t i = 0; i < NUM_ELEMS(s_finalResponsesSuccessInNumeric); i++) {
+        if (!strcmp(m_line, s_finalResponsesSuccessInNumeric[i])) {
+            return 1;
+        }
+    }
+    return 0;
+}
+
+bool AtLine::isFinalResponseErrorInNumeric() {
+    for (size_t i = 0; i < NUM_ELEMS(s_finalResponsesErrorInNumeric); i++) {
+        if (!strncmp(m_line, s_finalResponsesErrorInNumeric[i],
+                strlen(s_finalResponsesErrorInNumeric[i]))) {
+            return 1;
+        }
+    }
+    return 0;
+}
+
+bool AtLine::isAckResponse() {
+    for (size_t i = 0; i < NUM_ELEMS(s_ackResponse); i++) {
+        if (!strncmp(m_line, s_ackResponse[i], strlen(s_ackResponse[i]))) {
+            return true;
+        }
+    }
+    return false;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/AtLine.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/AtLine.h
new file mode 100644
index 0000000..8768ac6
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/AtLine.h
@@ -0,0 +1,103 @@
+/* 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 __RFX_AT_LINE_H__
+#define __RFX_AT_LINE_H__
+
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+#define NUM_ELEMS(x) (sizeof(x)/sizeof(x[0]))
+
+class AtLine {
+public:
+    AtLine() :
+            m_line(NULL), m_pNext(NULL) {
+    }
+
+    AtLine(const char* line, AtLine* next);
+
+    // copy constructor
+    AtLine(const AtLine &other);
+
+    ~AtLine();
+
+    AtLine &operator=(const AtLine &other);
+public:
+    AtLine* getNext() const {
+        return m_pNext;
+    }
+    void setNext(AtLine* next) {
+        m_pNext = next;
+    }
+    char *getLine() const {
+        return m_line;
+    }
+    void setLine(char* line) {
+        m_line = line;
+    }
+    char *getCurrentLine() {
+        return m_pCur;
+    }
+    void atTokStart(int *err);
+    int atTokNextint(int *err);
+    int atTokNexthexint(int *err);
+    bool atTokNextbool(int *err);
+    char* atTokNextstr(int *err);
+    int atTokHasmore();
+    char* atTokChar(int *err);
+    void atTokEqual(int *err);
+    long long atTokNextlonglong(int *err);
+    int isFinalResponseSuccess();
+    int isFinalResponseErrorEx(int channel_id);
+    int isIntermediatePattern();
+    bool isFinalResponseSuccessInNumeric();
+    bool isFinalResponseErrorInNumeric();
+    bool isAckResponse();
+
+private:
+    void skipWhiteSpace();
+    void skipNextComma();
+    int atTokNextintBase(int base, int uns, int *err);
+    long long atTokNextlonglongBase(int base, int uns, int *err);
+    char* nextTok();
+
+private:
+    char *m_line; // should dynamic allocate memory?
+    AtLine *m_pNext;
+    char *m_pCur; // current position, initialize at atTokStart
+};
+#endif
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Misc.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Misc.cpp
new file mode 100644
index 0000000..0536a68
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Misc.cpp
@@ -0,0 +1,29 @@
+/* //device/system/reference-ril/misc.c
+ **
+ ** Copyright 2006, The Android Open Source Project
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ **     http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+#include "../util/Misc.h"
+
+/** returns 1 if line starts with prefix, 0 if it does not */
+int Misc::strStartsWith(const char *line, const char *prefix) {
+    for (; *line != '\0' && *prefix != '\0'; line++, prefix++) {
+        if (*line != *prefix) {
+            return 0;
+        }
+    }
+
+    return *prefix == '\0';
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Misc.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Misc.h
new file mode 100644
index 0000000..06ce1b3
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Misc.h
@@ -0,0 +1,36 @@
+/* //device/system/reference-ril/misc.h
+ **
+ ** Copyright 2006, The Android Open Source Project
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ **     http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+#ifndef __RFX_MISC_H__
+#define __RFX_MISC_H__
+
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+class Misc {
+private:
+    Misc() {
+    }
+    ~Misc() {
+    }
+public:
+    /** returns 1 if line starts with prefix, 0 if it does not */
+    static int strStartsWith(const char *line, const char *prefix);
+};
+
+#endif
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/ModemCategory.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/ModemCategory.cpp
new file mode 100644
index 0000000..b9a79ec
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/ModemCategory.cpp
@@ -0,0 +1,123 @@
+/* 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 "ModemCategory.h"
+#include "WorldPhoneUtil.h"
+#include "RatConfiguration.h"
+#include "Radio_capability_switch_util.h"
+#include "common.h"
+#undef LOG_TAG
+#define LOG_TAG "EM_ModemCategory"
+
+const int ModemCategory::MODEM_FDD = 1;
+const int ModemCategory::MODEM_TD = 2;
+const int ModemCategory::MODEM_NO3G = 3;
+const std::string ModemCategory::FK_SIM_SWITCH = "persist.vendor.radio.simswitch";
+const std::string ModemCategory::FK_CDMA_SLOT = "persist.vendor.radio.cdma_slot";
+
+/**
+ * The property is used to check if the card is cdma 3G dual mode card in the slot.
+ */
+std::vector<std::string> ModemCategory::PROPERTY_RIL_CT3G {
+    "vendor.gsm.ril.ct3g",
+    "vendor.gsm.ril.ct3g.2",
+    "vendor.gsm.ril.ct3g.3",
+    "vendor.gsm.ril.ct3g.4",
+};
+
+/**
+ * The property is used to get supported card type of each SIM card in the slot.
+ */
+std::vector<std::string> ModemCategory::PROPERTY_RIL_FULL_UICC_TYPE {
+    "vendor.gsm.ril.fulluicctype",
+    "vendor.gsm.ril.fulluicctype.2",
+    "vendor.gsm.ril.fulluicctype.3",
+    "vendor.gsm.ril.fulluicctype.4"};
+
+ModemCategory::ModemCategory() {
+    // TODO Auto-generated constructor stub
+
+}
+
+ModemCategory::~ModemCategory() {
+    // TODO Auto-generated destructor stub
+}
+
+int ModemCategory::getModemType() {
+    int mode = MODEM_NO3G;
+    int mask = WorldPhoneUtil::get3GDivisionDuplexMode();
+    if ((1 == mask) || (2 == mask)) {
+        mode = mask;
+    }
+    RLOGD("mode = %d", mode);
+    return mode;
+}
+
+bool ModemCategory::isCdma() {
+    return RatConfiguration::isC2kSupported();
+}
+
+bool ModemCategory::isLteSupport() {
+    return (RatConfiguration::isLteFddSupported() || RatConfiguration::isLteTddSupported());
+}
+
+bool ModemCategory::isGsmSupport() {
+    return (RatConfiguration::isGsmSupported());
+}
+
+bool ModemCategory::isWcdmaSupport() {
+    return (RatConfiguration::isWcdmaSupported());
+}
+
+bool ModemCategory::isTdscdmaSupport() {
+    return (RatConfiguration::isTdscdmaSupported());
+}
+
+bool ModemCategory::isCapabilitySim(int type) {
+    int mainCard = Radio_capability_switch_util::get_main_capability_phone_id();
+    bool isCapability = (type == mainCard) ? true : false;
+    RLOGD("The card(%d) is main card = %d", type, isCapability);
+    return isCapability;
+}
+
+bool ModemCategory::checkViceSimCapability(int simType, int capability) {
+    int rat  = get_radio_capa(simType).rat;
+    if ((rat & capability) > 0) {
+        RLOGD("SIM has checked capability. rat: %d, cap: %d", rat , capability);
+        return true;
+    }
+    return false;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/ModemCategory.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/ModemCategory.h
new file mode 100644
index 0000000..847a9d8
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/ModemCategory.h
@@ -0,0 +1,65 @@
+/* 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_UTIL_MODEMCATEGORY_H_
+#define SRC_UTIL_MODEMCATEGORY_H_
+
+#include <string>
+#include <vector>
+class ModemCategory {
+public:
+    static const int MODEM_FDD;
+    static const int MODEM_TD;
+    static const int MODEM_NO3G;
+    static const std::string FK_SIM_SWITCH;
+    static const std::string FK_CDMA_SLOT;
+
+private:
+    static std::vector<std::string> PROPERTY_RIL_CT3G;
+    static std::vector<std::string> PROPERTY_RIL_FULL_UICC_TYPE;
+public:
+    ModemCategory();
+    virtual ~ModemCategory();
+    static int getModemType();
+    static bool isCdma();
+    static bool isLteSupport();
+    static bool isGsmSupport();
+    static bool isWcdmaSupport();
+    static bool isTdscdmaSupport();
+    static bool isCapabilitySim(int type);
+    static bool checkViceSimCapability(int simType, int capability);
+};
+
+#endif /* SRC_UTIL_MODEMCATEGORY_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/MtkRadioAccessFamily.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/MtkRadioAccessFamily.cpp
new file mode 100644
index 0000000..6fa8dc0
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/MtkRadioAccessFamily.cpp
@@ -0,0 +1,267 @@
+/* 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 "MtkRadioAccessFamily.h"
+#include "Phone_utils.h"
+// Radio Access Family
+// 2G
+const int MtkRadioAccessFamily::RAF_UNKNOWN = RIL_RadioAccessFamily::RAF_UNKNOWN;
+const int MtkRadioAccessFamily::RAF_GSM = RIL_RadioAccessFamily::RAF_GSM;
+const int MtkRadioAccessFamily::RAF_GPRS = RIL_RadioAccessFamily::RAF_GPRS;
+const int MtkRadioAccessFamily::RAF_EDGE = RIL_RadioAccessFamily::RAF_EDGE;
+const int MtkRadioAccessFamily::RAF_IS95A = RIL_RadioAccessFamily::RAF_IS95A;
+const int MtkRadioAccessFamily::RAF_IS95B = RIL_RadioAccessFamily::RAF_IS95B;
+const int MtkRadioAccessFamily::RAF_1xRTT = RIL_RadioAccessFamily::RAF_1xRTT;
+// 3G
+const int MtkRadioAccessFamily::RAF_EVDO_0 = RIL_RadioAccessFamily::RAF_EVDO_0;
+const int MtkRadioAccessFamily::RAF_EVDO_A = RIL_RadioAccessFamily::RAF_EVDO_A;
+const int MtkRadioAccessFamily::RAF_EVDO_B = RIL_RadioAccessFamily::RAF_EVDO_B;
+const int MtkRadioAccessFamily::RAF_EHRPD = RIL_RadioAccessFamily::RAF_EHRPD;
+const int MtkRadioAccessFamily::RAF_HSUPA = RIL_RadioAccessFamily::RAF_HSUPA;
+const int MtkRadioAccessFamily::RAF_HSDPA = RIL_RadioAccessFamily::RAF_HSDPA;
+const int MtkRadioAccessFamily::RAF_HSPA = RIL_RadioAccessFamily::RAF_HSPA;
+const int MtkRadioAccessFamily::RAF_HSPAP = RIL_RadioAccessFamily::RAF_HSPAP;
+const int MtkRadioAccessFamily::RAF_UMTS = RIL_RadioAccessFamily::RAF_UMTS;
+const int MtkRadioAccessFamily::RAF_TD_SCDMA =
+        RIL_RadioAccessFamily::RAF_TD_SCDMA;
+// 4G
+const int MtkRadioAccessFamily::RAF_LTE = RIL_RadioAccessFamily::RAF_LTE;
+const int MtkRadioAccessFamily::RAF_LTE_CA = 19; //RIL_RadioAccessFamily::RAF_LTE_CA;
+
+// Grouping of RAFs
+// 2G
+const int MtkRadioAccessFamily::GSM = RAF_GSM | RAF_GPRS | RAF_EDGE;
+const int MtkRadioAccessFamily::CDMA = RAF_IS95A | RAF_IS95B | RAF_1xRTT;
+// 3G
+const int MtkRadioAccessFamily::EVDO = RAF_EVDO_0 | RAF_EVDO_A | RAF_EVDO_B
+        | RAF_EHRPD;
+const int MtkRadioAccessFamily::HS = RAF_HSUPA | RAF_HSDPA | RAF_HSPA
+        | RAF_HSPAP;
+const int MtkRadioAccessFamily::WCDMA = HS | RAF_UMTS | RAF_TD_SCDMA;
+// 4G
+const int MtkRadioAccessFamily::LTE = RAF_LTE | RAF_LTE_CA;
+
+MtkRadioAccessFamily::MtkRadioAccessFamily() {
+    // TODO Auto-generated constructor stub
+
+}
+
+MtkRadioAccessFamily::~MtkRadioAccessFamily() {
+    // TODO Auto-generated destructor stub
+}
+
+int MtkRadioAccessFamily::getRafFromNetworkType(int type) {
+    int raf;
+
+    switch (type) {
+    case Phone_utils::NETWORK_MODE_WCDMA_PREF:
+        raf = GSM | WCDMA;
+        break;
+    case Phone_utils::NETWORK_MODE_GSM_ONLY:
+        raf = GSM;
+        break;
+    case Phone_utils::NETWORK_MODE_WCDMA_ONLY:
+        raf = WCDMA;
+        break;
+    case Phone_utils::NETWORK_MODE_GSM_UMTS:
+        raf = GSM | WCDMA;
+        break;
+    case Phone_utils::NETWORK_MODE_CDMA:
+        raf = CDMA | EVDO;
+        break;
+    case Phone_utils::NETWORK_MODE_LTE_CDMA_EVDO:
+        raf = LTE | CDMA | EVDO;
+        break;
+    case Phone_utils::NETWORK_MODE_LTE_GSM_WCDMA:
+        raf = LTE | GSM | WCDMA;
+        break;
+    case Phone_utils::NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
+        raf = LTE | CDMA | EVDO | GSM | WCDMA;
+        break;
+    case Phone_utils::NETWORK_MODE_LTE_ONLY:
+        raf = LTE;
+        break;
+    case Phone_utils::NETWORK_MODE_LTE_WCDMA:
+        raf = LTE | WCDMA;
+        break;
+    case Phone_utils::NETWORK_MODE_CDMA_NO_EVDO:
+        raf = CDMA;
+        break;
+    case Phone_utils::NETWORK_MODE_EVDO_NO_CDMA:
+        raf = EVDO;
+        break;
+    case Phone_utils::NETWORK_MODE_GLOBAL:
+        raf = GSM | WCDMA | CDMA | EVDO;
+        break;
+    case Phone_utils::NETWORK_MODE_TDSCDMA_ONLY:
+        raf = RAF_TD_SCDMA;
+        break;
+    case Phone_utils::NETWORK_MODE_TDSCDMA_WCDMA:
+        raf = RAF_TD_SCDMA | WCDMA;
+        break;
+    case Phone_utils::NETWORK_MODE_LTE_TDSCDMA:
+        raf = LTE | RAF_TD_SCDMA;
+        break;
+    case Phone_utils::NETWORK_MODE_TDSCDMA_GSM:
+        raf = RAF_TD_SCDMA | GSM;
+        break;
+    case Phone_utils::NETWORK_MODE_LTE_TDSCDMA_GSM:
+        raf = LTE | RAF_TD_SCDMA | GSM;
+        break;
+    case Phone_utils::NETWORK_MODE_TDSCDMA_GSM_WCDMA:
+        raf = RAF_TD_SCDMA | GSM | WCDMA;
+        break;
+    case Phone_utils::NETWORK_MODE_LTE_TDSCDMA_WCDMA:
+        raf = LTE | RAF_TD_SCDMA | WCDMA;
+        break;
+    case Phone_utils::NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA:
+        raf = LTE | RAF_TD_SCDMA | GSM | WCDMA;
+        break;
+    case Phone_utils::NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
+        raf = RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA;
+        break;
+    case Phone_utils::NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
+        raf = LTE | RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA;
+        break;
+    case Phone_utils::NETWORK_MODE_LTE_GSM:
+        raf = LTE | GSM;
+        break;
+    case Phone_utils::NETWORK_MODE_LTE_TDD_ONLY:
+        raf = LTE;
+        break;
+    case Phone_utils::NETWORK_MODE_CDMA_GSM:
+        raf = CDMA | GSM;
+        break;
+    case Phone_utils::NETWORK_MODE_CDMA_EVDO_GSM:
+        raf = CDMA | EVDO | GSM;
+        break;
+    case Phone_utils::NETWORK_MODE_LTE_CDMA_EVDO_GSM:
+        raf = LTE | CDMA | EVDO | GSM;
+        break;
+    default:
+        raf = RAF_UNKNOWN;
+        break;
+    }
+
+    return raf;
+}
+
+/**
+ * if the raf includes ANY bit set for a group
+ * adjust it to contain ALL the bits for that group
+ */
+int MtkRadioAccessFamily::getAdjustedRaf(int raf) {
+    raf = ((GSM & raf) > 0) ? (GSM | raf) : raf;
+    raf = ((WCDMA & raf) > 0) ? (WCDMA | raf) : raf;
+    raf = ((CDMA & raf) > 0) ? (CDMA | raf) : raf;
+    raf = ((EVDO & raf) > 0) ? (EVDO | raf) : raf;
+    raf = ((LTE & raf) > 0) ? (LTE | raf) : raf;
+
+    return raf;
+}
+
+int MtkRadioAccessFamily::getNetworkTypeFromRaf(int raf) {
+    int type;
+
+    raf = getAdjustedRaf(raf);
+
+    switch (raf) {
+    case (GSM | WCDMA):
+        type = Phone_utils::NETWORK_MODE_WCDMA_PREF;
+        break;
+    case GSM:
+        type = Phone_utils::NETWORK_MODE_GSM_ONLY;
+        break;
+    case WCDMA:
+        type = Phone_utils::NETWORK_MODE_WCDMA_ONLY;
+        break;
+    case (CDMA | EVDO):
+        type = Phone_utils::NETWORK_MODE_CDMA;
+        break;
+    case (LTE | CDMA | EVDO):
+        type = Phone_utils::NETWORK_MODE_LTE_CDMA_EVDO;
+        break;
+    case (LTE | GSM | WCDMA):
+        type = Phone_utils::NETWORK_MODE_LTE_GSM_WCDMA;
+        break;
+    case (LTE | CDMA | EVDO | GSM | WCDMA):
+        type = Phone_utils::NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA;
+        break;
+    case LTE:
+        type = Phone_utils::NETWORK_MODE_LTE_ONLY;
+        break;
+    case (LTE | WCDMA):
+        type = Phone_utils::NETWORK_MODE_LTE_WCDMA;
+        break;
+    case CDMA:
+        type = Phone_utils::NETWORK_MODE_CDMA_NO_EVDO;
+        break;
+    case EVDO:
+        type = Phone_utils::NETWORK_MODE_EVDO_NO_CDMA;
+        break;
+    case (GSM | WCDMA | CDMA | EVDO):
+        type = Phone_utils::NETWORK_MODE_GLOBAL;
+        break;
+    case RAF_TD_SCDMA:
+        type = Phone_utils::NETWORK_MODE_TDSCDMA_ONLY;
+        break;
+    case (LTE | RAF_TD_SCDMA):
+        type = Phone_utils::NETWORK_MODE_LTE_TDSCDMA;
+        break;
+    case (RAF_TD_SCDMA | GSM):
+        type = Phone_utils::NETWORK_MODE_TDSCDMA_GSM;
+        break;
+    case (LTE | RAF_TD_SCDMA | GSM):
+        type = Phone_utils::NETWORK_MODE_LTE_TDSCDMA_GSM;
+        break;
+    case (LTE | GSM):
+        type = Phone_utils::NETWORK_MODE_LTE_GSM;
+        break;
+    case (CDMA | GSM):
+        type = Phone_utils::NETWORK_MODE_CDMA_GSM;
+        break;
+    case (CDMA | EVDO | GSM):
+        type = Phone_utils::NETWORK_MODE_CDMA_EVDO_GSM;
+        break;
+    case (LTE | CDMA | EVDO | GSM):
+        type = Phone_utils::NETWORK_MODE_LTE_CDMA_EVDO_GSM;
+        break;
+    default:
+        type = Phone_utils::PREFERRED_NETWORK_MODE;
+        break;
+    }
+
+    return type;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/MtkRadioAccessFamily.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/MtkRadioAccessFamily.h
new file mode 100644
index 0000000..537f622
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/MtkRadioAccessFamily.h
@@ -0,0 +1,85 @@
+/* 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_UTIL_MTKRADIOACCESSFAMILY_H_
+#define SRC_UTIL_MTKRADIOACCESSFAMILY_H_
+
+#include <vendor-ril/telephony/ril.h>
+
+class MtkRadioAccessFamily {
+public:
+    MtkRadioAccessFamily();
+    virtual ~MtkRadioAccessFamily();
+    static int getRafFromNetworkType(int type);
+    static int getAdjustedRaf(int raf);
+    static int getNetworkTypeFromRaf(int raf);
+public:
+    // Radio Access Family
+    // 2G
+    static const int RAF_UNKNOWN;
+    static const int RAF_GSM;
+    static const int RAF_GPRS;
+    static const int RAF_EDGE;
+    static const int RAF_IS95A;
+    static const int RAF_IS95B;
+    static const int RAF_1xRTT;
+    // 3G
+    static const int RAF_EVDO_0;
+    static const int RAF_EVDO_A;
+    static const int RAF_EVDO_B;
+    static const int RAF_EHRPD;
+    static const int RAF_HSUPA;
+    static const int RAF_HSDPA;
+    static const int RAF_HSPA;
+    static const int RAF_HSPAP;
+    static const int RAF_UMTS;
+    static const int RAF_TD_SCDMA;
+    // 4G
+    static const int RAF_LTE;
+    static const int RAF_LTE_CA;
+private:
+    // Grouping of RAFs
+    // 2G
+    static const int GSM;
+    static const int CDMA;
+    // 3G
+    static const int EVDO;
+    static const int HS;
+    static const int WCDMA;
+    // 4G
+    static const int LTE;
+};
+
+#endif /* SRC_UTIL_MTKRADIOACCESSFAMILY_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Phone_utils.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Phone_utils.cpp
new file mode 100644
index 0000000..06b4917
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Phone_utils.cpp
@@ -0,0 +1,203 @@
+ /*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <cutils/properties.h>
+#include <string>
+
+#include "log_extra.h"
+#include "Phone_utils.h"
+#include "utils.h"
+#include "common.h"
+
+#define LOG_TAG "DEMO_PHONE_UTILS"
+
+/* NETWORK_MODE_* See ril.h RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE */
+constexpr int Phone_utils::NETWORK_MODE_WCDMA_PREF; /* GSM/WCDMA (WCDMA preferred) */
+constexpr int Phone_utils::NETWORK_MODE_GSM_ONLY; /* GSM only */
+constexpr int Phone_utils::NETWORK_MODE_WCDMA_ONLY ; /* WCDMA only */
+constexpr int Phone_utils::NETWORK_MODE_GSM_UMTS; /* GSM/WCDMA (auto mode, according to PRL)
+                                        AVAILABLE Application Settings menu*/
+constexpr int Phone_utils::NETWORK_MODE_CDMA; /* CDMA and EvDo (auto mode, according to PRL)
+                                        AVAILABLE Application Settings menu*/
+constexpr int Phone_utils::NETWORK_MODE_CDMA_NO_EVDO; /* CDMA only */
+constexpr int Phone_utils::NETWORK_MODE_EVDO_NO_CDMA; /* EvDo only */
+constexpr int Phone_utils::NETWORK_MODE_GLOBAL; /* GSM/WCDMA, CDMA, and EvDo (auto mode, according to PRL)
+                                        AVAILABLE Application Settings menu*/
+constexpr int Phone_utils::NETWORK_MODE_LTE_CDMA_EVDO; /* LTE, CDMA and EvDo */
+constexpr int Phone_utils::NETWORK_MODE_LTE_GSM_WCDMA; /* LTE, GSM/WCDMA */
+constexpr int Phone_utils::NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA; /* LTE, CDMA, EvDo, GSM/WCDMA */
+constexpr int Phone_utils::NETWORK_MODE_LTE_ONLY; /* LTE Only mode. */
+constexpr int Phone_utils::NETWORK_MODE_LTE_WCDMA; /* LTE/WCDMA */
+constexpr int Phone_utils::NETWORK_MODE_TDSCDMA_ONLY; /* TD-SCDMA only */
+constexpr int Phone_utils::NETWORK_MODE_TDSCDMA_WCDMA; /* TD-SCDMA and WCDMA */
+constexpr int Phone_utils::NETWORK_MODE_LTE_TDSCDMA; /* TD-SCDMA and LTE */
+constexpr int Phone_utils::NETWORK_MODE_TDSCDMA_GSM; /* TD-SCDMA and GSM */
+constexpr int Phone_utils::NETWORK_MODE_LTE_TDSCDMA_GSM; /* TD-SCDMA,GSM and LTE */
+constexpr int Phone_utils::NETWORK_MODE_TDSCDMA_GSM_WCDMA; /* TD-SCDMA, GSM/WCDMA */
+constexpr int Phone_utils::NETWORK_MODE_LTE_TDSCDMA_WCDMA; /* TD-SCDMA, WCDMA and LTE */
+constexpr int Phone_utils::NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA; /* TD-SCDMA, GSM/WCDMA and LTE */
+constexpr int Phone_utils::NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA; /*TD-SCDMA,EvDo,CDMA,GSM/WCDMA*/
+constexpr int Phone_utils::NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA; /* TD-SCDMA/LTE/GSM/WCDMA, CDMA, and EvDo */
+/// M: [Network][C2K]Add the MTK new network type. @{
+constexpr int Phone_utils::NETWORK_MODE_LTE_GSM; /*LTE/GSM */
+constexpr int Phone_utils::NETWORK_MODE_LTE_TDD_ONLY; /* LTE TDD Only mode. */
+constexpr int Phone_utils::NETWORK_MODE_CDMA_GSM; /* CDMA,GSM(2G Global) */
+constexpr int Phone_utils::NETWORK_MODE_CDMA_EVDO_GSM; /* CDMA,EVDO,GSM */
+constexpr int Phone_utils::NETWORK_MODE_LTE_CDMA_EVDO_GSM; /* LTE,CDMA,EVDO,GSM(4G Global, 4M) */
+
+const int Phone_utils::PHONE_TYPE_NONE = 0;
+const int Phone_utils::PHONE_TYPE_GSM = 1;
+const int Phone_utils::PHONE_TYPE_CDMA = 2;
+const int Phone_utils::PHONE_TYPE_SIP = 3;
+const int Phone_utils::PHONE_TYPE_THIRD_PARTY = 4;
+const int Phone_utils::PHONE_TYPE_IMS = 5;
+
+/// @}
+
+/**
+ * Available radio technologies for GSM, UMTS and CDMA.
+ * Duplicates the constants from hardware/radio/include/ril.h
+ * This should only be used by agents working with the ril.  Others
+ * should use the equivalent TelephonyManager.NETWORK_TYPE_*
+ */
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_UNKNOWN;
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_GPRS;
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_EDGE;
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_UMTS;
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_IS95A;
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_IS95B;
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_1xRTT;
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_EVDO_0;
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_EVDO_A;
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_HSDPA;
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_HSUPA;
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_HSPA;
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_EVDO_B;
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_EHRPD;
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_LTE;
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_HSPAP;
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_GSM;
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_TD_SCDMA;
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_IWLAN;
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_LTE_CA;
+
+int Phone_utils::PREFERRED_NETWORK_MODE = init();
+
+const int Phone_utils::APP_FAM_3GPP =  1;
+const int Phone_utils::APP_FAM_3GPP2 = 2;
+const int Phone_utils::APP_FAM_IMS   = 3;
+
+const std::string Phone_utils::RADIO_DSSS_SIM_DISABLE = "persist.radio.dsss.sim.disable";
+int32_t Phone_utils::disable_sim = -1;
+
+int Phone_utils::init() {
+    char mtk_protocol1_rat_config[PROPERTY_VALUE_MAX] = { 0 };
+    char opt_ps1_rat[PROPERTY_VALUE_MAX] = { 0 };
+    char default_network[PROPERTY_VALUE_MAX] = { 0 };
+    utils::mtk_property_get("ro.mtk_protocol1_rat_config",mtk_protocol1_rat_config, "");
+    utils::mtk_property_get("ro.boot.opt_ps1_rat",opt_ps1_rat, "");
+    utils::mtk_property_get("ro.telephony.default_network",default_network, "");
+    std::string mtk_rat(mtk_protocol1_rat_config);
+    std::string rat(opt_ps1_rat);
+    std::string default_rat(default_network);
+    if("C/Lf" == mtk_rat ) {
+        return NETWORK_MODE_LTE_CDMA_EVDO;
+    } else {
+        if(rat.find("C") != std::string::npos) {
+            if(rat.find("L") != std::string::npos) {
+                return NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA;
+            } else {
+                return NETWORK_MODE_GLOBAL;
+            }
+        } else  {
+            if(rat.find("L") != std::string::npos) {
+                return NETWORK_MODE_LTE_GSM_WCDMA;
+            } else {
+                return NETWORK_MODE_WCDMA_PREF;
+            }
+        }
+    }
+}
+
+int Phone_utils::get_enable_sim_for_dsss() {
+    if(disable_sim == -1) {
+        disable_sim = utils::mtk_property_get_int32(RADIO_DSSS_SIM_DISABLE.c_str(), -1);
+        LOG_D(LOG_TAG,"get_enable_sim_for_dsss: %d", disable_sim);
+    }
+
+    if(disable_sim == 2) {
+        return 0; //slot 0 enable, slot 1 disable
+    }else if(disable_sim == 1) {
+        return 1; //slot 1 enable, slot 0 disable
+    }
+    return 0;
+}
+
+Phone_utils::Phone_utils() {
+    // TODO Auto-generated constructor stub
+
+}
+
+Phone_utils::~Phone_utils() {
+    // TODO Auto-generated destructor stub
+}
+
+int Phone_utils::get_phone_count() {
+    int phoneCount = 1;
+    if(utils::is_support_dsds()) {
+        phoneCount = 2;
+    }
+    return phoneCount;
+}
+
+int Phone_utils::get_phone_type(int slot) {
+    int tech = get_voice_radio_tech(slot);
+    LOG_D(LOG_TAG,"get_phone_type: %d", tech);
+    if(isCdma(tech)){
+        return PHONE_TYPE_CDMA;
+    } else {
+        return PHONE_TYPE_GSM;
+    }
+}
+
+bool Phone_utils::isGsm(int radioTechnology){
+    return radioTechnology == RIL_RADIO_TECHNOLOGY_GPRS
+            || radioTechnology == RIL_RADIO_TECHNOLOGY_EDGE
+            || radioTechnology == RIL_RADIO_TECHNOLOGY_UMTS
+            || radioTechnology == RIL_RADIO_TECHNOLOGY_HSDPA
+            || radioTechnology == RIL_RADIO_TECHNOLOGY_HSUPA
+            || radioTechnology == RIL_RADIO_TECHNOLOGY_HSPA
+            || radioTechnology == RIL_RADIO_TECHNOLOGY_LTE
+            || radioTechnology == RIL_RADIO_TECHNOLOGY_HSPAP
+            || radioTechnology == RIL_RADIO_TECHNOLOGY_GSM
+            || radioTechnology == RIL_RADIO_TECHNOLOGY_TD_SCDMA
+            || radioTechnology == RIL_RADIO_TECHNOLOGY_IWLAN
+            || radioTechnology == RIL_RADIO_TECHNOLOGY_LTE_CA;
+}
+
+bool Phone_utils::isCdma(int radioTechnology){
+    return radioTechnology == RIL_RADIO_TECHNOLOGY_IS95A
+            || radioTechnology == RIL_RADIO_TECHNOLOGY_IS95B
+            || radioTechnology == RIL_RADIO_TECHNOLOGY_1xRTT
+            || radioTechnology == RIL_RADIO_TECHNOLOGY_EVDO_0
+            || radioTechnology == RIL_RADIO_TECHNOLOGY_EVDO_A
+            || radioTechnology == RIL_RADIO_TECHNOLOGY_EVDO_B
+            || radioTechnology == RIL_RADIO_TECHNOLOGY_EHRPD;
+}
+
+bool Phone_utils::isLte(int radioTechnology){
+    return radioTechnology == RIL_RADIO_TECHNOLOGY_LTE ||
+            radioTechnology == RIL_RADIO_TECHNOLOGY_LTE_CA;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Phone_utils.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Phone_utils.h
new file mode 100644
index 0000000..b05e5a0
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Phone_utils.h
@@ -0,0 +1,130 @@
+/* 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_UTIL_PHONE_UTILS_H_
+#define SRC_UTIL_PHONE_UTILS_H_
+
+#include <string>
+#include <vendor-ril/telephony/ril.h>
+
+class Phone_utils {
+public:
+    Phone_utils();
+    virtual ~Phone_utils();
+    static int get_phone_count();
+    static bool isGsm(int radioTechnology);
+    static bool isCdma(int radioTechnology);
+    static bool isLte(int radioTechnology);
+    static int get_enable_sim_for_dsss();
+    static int get_phone_type(int slot);
+public:
+    static const int APP_FAM_3GPP;
+    static const int APP_FAM_3GPP2;
+    static const int APP_FAM_IMS;
+    /* NETWORK_MODE_* See ril.h RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE */
+    static constexpr int NETWORK_MODE_WCDMA_PREF     = RIL_PreferredNetworkType::PREF_NET_TYPE_GSM_WCDMA; /* GSM/WCDMA (WCDMA preferred) */
+    static constexpr int NETWORK_MODE_GSM_ONLY       = RIL_PreferredNetworkType::PREF_NET_TYPE_GSM_ONLY; /* GSM only */
+    static constexpr int NETWORK_MODE_WCDMA_ONLY     = RIL_PreferredNetworkType::PREF_NET_TYPE_WCDMA; /* WCDMA only */
+    static constexpr int NETWORK_MODE_GSM_UMTS       = RIL_PreferredNetworkType::PREF_NET_TYPE_GSM_WCDMA_AUTO; /* GSM/WCDMA (auto mode, according to PRL)
+                                            AVAILABLE Application Settings menu*/
+    static constexpr int NETWORK_MODE_CDMA           = RIL_PreferredNetworkType::PREF_NET_TYPE_CDMA_EVDO_AUTO; /* CDMA and EvDo (auto mode, according to PRL)
+                                            AVAILABLE Application Settings menu*/
+    static constexpr int NETWORK_MODE_CDMA_NO_EVDO   = RIL_PreferredNetworkType::PREF_NET_TYPE_CDMA_ONLY; /* CDMA only */
+    static constexpr int NETWORK_MODE_EVDO_NO_CDMA   = RIL_PreferredNetworkType::PREF_NET_TYPE_EVDO_ONLY; /* EvDo only */
+    static constexpr int NETWORK_MODE_GLOBAL         = RIL_PreferredNetworkType::PREF_NET_TYPE_GSM_WCDMA_CDMA_EVDO_AUTO; /* GSM/WCDMA, CDMA, and EvDo (auto mode, according to PRL)
+                                            AVAILABLE Application Settings menu*/
+    static constexpr int NETWORK_MODE_LTE_CDMA_EVDO  = RIL_PreferredNetworkType::PREF_NET_TYPE_LTE_CDMA_EVDO; /* LTE, CDMA and EvDo */
+    static constexpr int NETWORK_MODE_LTE_GSM_WCDMA  = RIL_PreferredNetworkType::PREF_NET_TYPE_LTE_GSM_WCDMA; /* LTE, GSM/WCDMA */
+    static constexpr int NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA = RIL_PreferredNetworkType::PREF_NET_TYPE_LTE_CMDA_EVDO_GSM_WCDMA; /* LTE, CDMA, EvDo, GSM/WCDMA */
+    static constexpr int NETWORK_MODE_LTE_ONLY       = RIL_PreferredNetworkType::PREF_NET_TYPE_LTE_ONLY; /* LTE Only mode. */
+    static constexpr int NETWORK_MODE_LTE_WCDMA      = RIL_PreferredNetworkType::PREF_NET_TYPE_LTE_WCDMA; /* LTE/WCDMA */
+    static constexpr int NETWORK_MODE_TDSCDMA_ONLY            = 13; /*RIL_PreferredNetworkType::PREF_NET_TYPE_TD_SCDMA_ONLY;  TD-SCDMA only */
+    static constexpr int NETWORK_MODE_TDSCDMA_WCDMA           = 14; /*RIL_PreferredNetworkType::PREF_NET_TYPE_TD_SCDMA_WCDMA;  TD-SCDMA and WCDMA */
+    static constexpr int NETWORK_MODE_LTE_TDSCDMA             = 15; /*RIL_PreferredNetworkType::PREF_NET_TYPE_TD_SCDMA_LTE; TD-SCDMA and LTE */
+    static constexpr int NETWORK_MODE_TDSCDMA_GSM             = 16; /*RIL_PreferredNetworkType::PREF_NET_TYPE_TD_SCDMA_GSM;  TD-SCDMA and GSM */
+    static constexpr int NETWORK_MODE_LTE_TDSCDMA_GSM         = 17; /*RIL_PreferredNetworkType::PREF_NET_TYPE_TD_SCDMA_GSM_LTE;  TD-SCDMA,GSM and LTE */
+    static constexpr int NETWORK_MODE_TDSCDMA_GSM_WCDMA       = 18; /*RIL_PreferredNetworkType::PREF_NET_TYPE_TD_SCDMA_GSM_WCDMA;  TD-SCDMA, GSM/WCDMA */
+    static constexpr int NETWORK_MODE_LTE_TDSCDMA_WCDMA       = 19; /*RIL_PreferredNetworkType::PREF_NET_TYPE_TD_SCDMA_WCDMA_LTE;  TD-SCDMA, WCDMA and LTE */
+    static constexpr int NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA   =  20; /*RIL_PreferredNetworkType::PREF_NET_TYPE_TD_SCDMA_GSM_WCDMA_LTE;  TD-SCDMA, GSM/WCDMA and LTE */
+    static constexpr int NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA  = 21; /*RIL_PreferredNetworkType::PREF_NET_TYPE_TD_SCDMA_GSM_WCDMA_CDMA_EVDO_AUTO; TD-SCDMA,EvDo,CDMA,GSM/WCDMA*/
+    static constexpr int NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = 22; /*RIL_PreferredNetworkType::PREF_NET_TYPE_TD_SCDMA_LTE_CDMA_EVDO_GSM_WCDMA;  TD-SCDMA/LTE/GSM/WCDMA, CDMA, and EvDo */
+    /// M: [Network][C2K]Add the MTK new network type. @{
+    static constexpr int NETWORK_MODE_LTE_GSM        = 30; /*LTE/GSM */
+    static constexpr int NETWORK_MODE_LTE_TDD_ONLY   = 31; /* LTE TDD Only mode. */
+    static constexpr int NETWORK_MODE_CDMA_GSM                         = 32; /* CDMA,GSM(2G Global) */
+    static constexpr int NETWORK_MODE_CDMA_EVDO_GSM                    = 33; /* CDMA,EVDO,GSM */
+    static constexpr int NETWORK_MODE_LTE_CDMA_EVDO_GSM                = 34; /* LTE,CDMA,EVDO,GSM(4G Global, 4M) */
+    static const int PHONE_TYPE_NONE;
+    static const int PHONE_TYPE_GSM;
+    static const int PHONE_TYPE_CDMA;
+    static const int PHONE_TYPE_SIP;
+    static const int PHONE_TYPE_THIRD_PARTY;
+    static const int PHONE_TYPE_IMS;
+    /**
+     * Available radio technologies for GSM, UMTS and CDMA.
+     * Duplicates the constants from hardware/radio/include/ril.h
+     * This should only be used by agents working with the ril.  Others
+     * should use the equivalent TelephonyManager.NETWORK_TYPE_*
+     */
+    static constexpr int RIL_RADIO_TECHNOLOGY_UNKNOWN = RIL_RadioTechnology::RADIO_TECH_UNKNOWN;
+    static constexpr int RIL_RADIO_TECHNOLOGY_GPRS = RIL_RadioTechnology::RADIO_TECH_GPRS;
+    static constexpr int RIL_RADIO_TECHNOLOGY_EDGE = RIL_RadioTechnology::RADIO_TECH_EDGE;
+    static constexpr int RIL_RADIO_TECHNOLOGY_UMTS = RIL_RadioTechnology::RADIO_TECH_UMTS;
+    static constexpr int RIL_RADIO_TECHNOLOGY_IS95A = RIL_RadioTechnology::RADIO_TECH_IS95A;
+    static constexpr int RIL_RADIO_TECHNOLOGY_IS95B = RIL_RadioTechnology::RADIO_TECH_IS95B;
+    static constexpr int RIL_RADIO_TECHNOLOGY_1xRTT = RIL_RadioTechnology::RADIO_TECH_1xRTT;
+    static constexpr int RIL_RADIO_TECHNOLOGY_EVDO_0 = RIL_RadioTechnology::RADIO_TECH_EVDO_0;
+    static constexpr int RIL_RADIO_TECHNOLOGY_EVDO_A = RIL_RadioTechnology::RADIO_TECH_EVDO_A;
+    static constexpr int RIL_RADIO_TECHNOLOGY_HSDPA = RIL_RadioTechnology::RADIO_TECH_HSDPA;
+    static constexpr int RIL_RADIO_TECHNOLOGY_HSUPA = RIL_RadioTechnology::RADIO_TECH_HSUPA;
+    static constexpr int RIL_RADIO_TECHNOLOGY_HSPA = RIL_RadioTechnology::RADIO_TECH_HSPA;
+    static constexpr int RIL_RADIO_TECHNOLOGY_EVDO_B = RIL_RadioTechnology::RADIO_TECH_EVDO_B;
+    static constexpr int RIL_RADIO_TECHNOLOGY_EHRPD = RIL_RadioTechnology::RADIO_TECH_EHRPD;
+    static constexpr int RIL_RADIO_TECHNOLOGY_LTE = RIL_RadioTechnology::RADIO_TECH_LTE;
+    static constexpr int RIL_RADIO_TECHNOLOGY_HSPAP = RIL_RadioTechnology::RADIO_TECH_HSPAP;
+    static constexpr int RIL_RADIO_TECHNOLOGY_GSM = RIL_RadioTechnology::RADIO_TECH_GSM;
+    static constexpr int RIL_RADIO_TECHNOLOGY_TD_SCDMA = RIL_RadioTechnology::RADIO_TECH_TD_SCDMA;
+    static constexpr int RIL_RADIO_TECHNOLOGY_IWLAN = RIL_RadioTechnology::RADIO_TECH_IWLAN;
+    static constexpr int RIL_RADIO_TECHNOLOGY_LTE_CA = 19;//RIL_RadioTechnology::RADIO_TECH_LTE_CA;
+
+    static int PREFERRED_NETWORK_MODE;
+private:
+    static const std::string RADIO_DSSS_SIM_DISABLE;
+    static int32_t disable_sim;
+private:
+    static int init();
+};
+
+#endif /* SRC_UTIL_PHONE_UTILS_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Proxycontroller.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Proxycontroller.cpp
new file mode 100644
index 0000000..d173c71
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Proxycontroller.cpp
@@ -0,0 +1,772 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <log/log.h>
+#include <set>
+#include <stdexcept>
+
+#include "Proxycontroller.h"
+#include "common.h"
+#include "network.h"
+#include "data.h"
+#include "bitset"
+#include "utils.h"
+#include "WorldPhoneUtil.h"
+
+#define LOG_TAG "DEMO_Proxy_controller"
+
+constexpr int Proxy_controller::EVENT_NOTIFICATION_RC_CHANGED;
+constexpr int Proxy_controller::EVENT_START_RC_RESPONSE;
+constexpr int Proxy_controller::EVENT_APPLY_RC_RESPONSE;
+constexpr int Proxy_controller::EVENT_FINISH_RC_RESPONSE;
+constexpr int Proxy_controller::EVENT_TIMEOUT;
+
+const int Proxy_controller::SET_RC_STATUS_IDLE             = 0;
+const int Proxy_controller::SET_RC_STATUS_STARTING         = 1;
+const int Proxy_controller::SET_RC_STATUS_STARTED          = 2;
+const int Proxy_controller::SET_RC_STATUS_APPLYING         = 3;
+const int Proxy_controller::SET_RC_STATUS_SUCCESS          = 4;
+const int Proxy_controller::SET_RC_STATUS_FAIL             = 5;
+
+const std::string Proxy_controller::PROPERTY_CAPABILITY_SWITCH = "persist.vendor.radio.simswitch";
+const std::string Proxy_controller::PROPERTY_CAPABILITY_SWITCH_STATE = "persist.vendor.radio.simswitchstate";
+
+// event 1-5 is defined in ProxyController
+const int Proxy_controller::EVENT_RADIO_AVAILABLE = 6;
+const int Proxy_controller::EVENT_RIL_CONNECTED = 7;
+
+// marker for retry cause
+const int Proxy_controller::RC_RETRY_CAUSE_NONE                  = 0;
+const int Proxy_controller::RC_RETRY_CAUSE_WORLD_MODE_SWITCHING  = 1;
+const int Proxy_controller::RC_RETRY_CAUSE_CAPABILITY_SWITCHING  = 2;
+const int Proxy_controller::RC_RETRY_CAUSE_IN_CALL               = 3;
+const int Proxy_controller::RC_RETRY_CAUSE_RADIO_UNAVAILABLE     = 4;
+const int Proxy_controller::RC_RETRY_CAUSE_AIRPLANE_MODE         = 5;
+const int Proxy_controller::RC_RETRY_CAUSE_RESULT_ERROR          = 6;
+
+    // marker for switch conditions pre-checking
+const int Proxy_controller::RC_DO_SWITCH       = 0;
+const int Proxy_controller::RC_NO_NEED_SWITCH  = 1;
+const int Proxy_controller::RC_CANNOT_SWITCH   = 2;
+
+Proxy_controller* Proxy_controller::sInstance = nullptr;
+    // The entire transaction must complete within this amount of time
+    // or a FINISH will be issued to each Logical Modem with the old
+    // Radio Access Family.
+const int Proxy_controller::SET_RC_TIMEOUT_WAITING_MSEC    = (45 * 1000);
+
+Proxy_controller::Proxy_controller() :mRadioCapabilitySessionId(0), mTransactionFailed(false){
+    //***** Class Variables
+    mIsCapSwitching = false;
+    mHasRegisterWorldModeReceiver = false;
+    mHasRegisterPhoneStateReceiver = false;
+    mHasRegisterEccStateReceiver = false;
+    mIsRildReconnected = false;
+    mSetRafRetryCause = RC_RETRY_CAUSE_NONE;
+    // Exception counter
+    onExceptionCount = 0;
+    clearTransaction();
+}
+
+Proxy_controller::~Proxy_controller() {
+    // TODO Auto-generated destructor stub
+}
+
+Proxy_controller::Handle_thread::Handle_thread(): m_looper(NULL){
+    RLOGD("RequestHandleThread created");
+}
+
+Proxy_controller::Handle_thread::~Handle_thread() {
+    RLOGD("RequestHandleThread destroyed");
+}
+
+sp<Looper> Proxy_controller::Handle_thread::getLooper() {
+    return m_looper;
+}
+
+bool Proxy_controller::Handle_thread::threadLoop() {
+    RLOGD("Handler threadLoop");
+    m_looper = Looper::prepare(0);
+    int result;
+    do {
+        result = m_looper->pollAll(-1);
+        RLOGD("Handler threadLoop, pull message result = %d", result);
+    } while (result == Looper::POLL_WAKE || result == Looper::POLL_CALLBACK);
+    return true;
+}
+
+Proxy_controller::Request_message::Request_message(): what(0), slot(-1),e(RIL_E_SUCCESS), is_rc_set(true),id(-1){
+
+}
+
+void Proxy_controller::init() {
+    handle_thread = new Handle_thread();
+    handle_thread->run();
+}
+
+Proxy_controller *Proxy_controller::getInstance() {
+    if (sInstance == NULL) {
+        sInstance = new Proxy_controller();
+        sInstance->init();
+    }
+    return sInstance;
+}
+
+sp<Proxy_controller::Request_handler> Proxy_controller::sendMessage(sp<Request_message> msg, int delayms) {
+    RLOGD("sendMessage msg what=%d delayms=%d", msg->what, delayms);
+    // Create a handler to handle this message
+    sp<Request_handler> handler = new Request_handler(this);
+    handler->msg = msg;
+    // Sand message to looper
+    if(handle_thread.get()) {
+        sp<Looper> looper = handle_thread->getLooper();
+        if(looper.get()) {
+            if (delayms > 0) {
+                looper->sendMessageDelayed(ms2ns(delayms),handler, handler->m_dummyMsg);
+            } else {
+                looper->sendMessage(handler, handler->m_dummyMsg);
+            }
+        } else {
+            RLOGD("looper");
+        }
+    } else {
+        RLOGD("handle_thread");
+    }
+
+    return handler;
+}
+
+void Proxy_controller::handle_request_resp(RIL_RadioCapability* cap, RIL_Errno e, int slot) {
+    if(m_eventId[slot] < 0) {
+        RLOGD("handle_request_resp cap is null.m_eventId[%d]=%d", slot, m_eventId[slot]);
+        return;
+    }
+    RLOGD("handle_request_resp what[%d]: %d , phase: %d", slot,m_eventId[slot], cap->phase);
+    // Create a request message
+    sp<Request_message> msg = new Request_message();
+    msg->what = m_eventId[slot];
+    if(cap != NULL) {
+        msg->cap = (*cap);
+    } else {
+        msg->is_rc_set = false;
+        RLOGD("handle_request_resp[slot%d]: cap is null", slot);
+    }
+    msg->e = e;
+    msg->slot = slot;
+    RLOGD("handle_request_resp logicalModemUuid: %s , phase: %d, rat: %d, session: %d, status: %d, version: %d",
+            msg->cap.logicalModemUuid, msg->cap.phase, msg->cap.rat, msg->cap.session, msg->cap.status, msg->cap.version);
+    sendMessage(msg, 0);
+}
+
+void Proxy_controller::issueFinish(int sessionId) {
+    m_mutex.lock();
+    for (int i = 0; i < SIM_COUNT; i++) {
+        RLOGD("issueFinish: phoneId=%d sessionId= %d  mTransactionFailed=%d", i, sessionId, mTransactionFailed);
+        mRadioAccessFamilyStatusCounter++;
+        sendRadioCapabilityRequest(
+                i,
+                sessionId,
+                RadioCapabilityPhase(RC_PHASE_FINISH),
+                (mTransactionFailed ? mOldRadioAccessFamily[i] :
+                mNewRadioAccessFamily[i]),
+                (mTransactionFailed ? mCurrentLogicalModemIds[i] :
+                mNewLogicalModemIds[i]),
+                (mTransactionFailed ? RadioCapabilityStatus(RC_STATUS_FAIL) :
+                        RadioCapabilityStatus(RC_STATUS_SUCCESS)),
+                EVENT_FINISH_RC_RESPONSE);
+        if (mTransactionFailed) {
+            RLOGD("issueFinish: phoneId: %d status: FAIL", i);
+            // At least one failed, mark them all failed.
+            mSetRadioAccessFamilyStatus[i] = SET_RC_STATUS_FAIL;
+        }
+    }
+    m_mutex.unlock();
+}
+
+void Proxy_controller::onStartRadioCapabilityResponse(sp<Request_message> msg) {
+    m_mutex.lock();
+
+    RIL_RadioCapability rc = msg->cap;
+    if ((rc.session != mRadioCapabilitySessionId.load())) {
+        RLOGD("onStartRadioCapabilityResponse: Ignore session=%d,rc.logicalModemUuid = %d, rc.phase = %d, rc.rat = %d, rc.session = %d, rc.status = %d, rc.version = %d",
+                mRadioCapabilitySessionId.load(), rc.logicalModemUuid,rc.phase,rc.rat,rc.session,rc.status,rc.version);
+        return;
+    }
+    mRadioAccessFamilyStatusCounter--;
+    int id = msg->slot;
+    if (msg->e != RIL_E_SUCCESS) {
+        RLOGD("onStartRadioCapabilityResponse: Error response session=%d", rc.session);
+        RLOGD("onStartRadioCapabilityResponse: phoneId=%d status=FAIL", id);
+        mSetRadioAccessFamilyStatus[id] = SET_RC_STATUS_FAIL;
+        mTransactionFailed = true;
+    } else {
+        RLOGD("onStartRadioCapabilityResponse: phoneId=%d status=STARTED", id);
+        mSetRadioAccessFamilyStatus[id] = SET_RC_STATUS_STARTED;
+    }
+
+    if (mRadioAccessFamilyStatusCounter == 0) {
+        /**
+        std::set<std::string> modemsInUse;
+        for (auto modemId : mNewLogicalModemIds) {
+            if (!(modemsInUse.insert(modemId).second)) {
+                mTransactionFailed = true;
+                RLOGD("ERROR: sending down the same id for different phones");
+            }
+        }
+        **/
+        RLOGD("onStartRadioCapabilityResponse: success=%d", !mTransactionFailed);
+        if (mTransactionFailed) {
+            // Sends a variable number of requests, so don't resetRadioAccessFamilyCounter
+            // here.
+            m_mutex.unlock();
+            issueFinish(mRadioCapabilitySessionId.load());
+            return;
+        } else {
+            // All logical modem accepted the new radio access family, issue the APPLY
+            resetRadioAccessFamilyStatusCounter();
+            for (int i = 0; i < SIM_COUNT; i++) {
+                sendRadioCapabilityRequest(
+                    i,
+                    mRadioCapabilitySessionId.load(),
+                    RadioCapabilityPhase(RC_PHASE_APPLY),
+                    mNewRadioAccessFamily[i],
+                    mNewLogicalModemIds[i],
+                    RadioCapabilityStatus(RC_STATUS_NONE),
+                    EVENT_APPLY_RC_RESPONSE);
+
+               RLOGD("onStartRadioCapabilityResponse: phoneId=%d status=APPLYING", i);
+                mSetRadioAccessFamilyStatus[i] = SET_RC_STATUS_APPLYING;
+            }
+        }
+    }
+    m_mutex.unlock();
+}
+
+void Proxy_controller::onApplyRadioCapabilityErrorHandler(sp<Request_message> msg){
+
+}
+void Proxy_controller::onApplyExceptionHandler(sp<Request_message> msg){
+
+}
+
+void Proxy_controller::onApplyRadioCapabilityResponse(sp<Request_message> msg) {
+    RIL_RadioCapability rc = msg->cap;
+    if ((rc.session != mRadioCapabilitySessionId.load())) {
+        RLOGD("onApplyRadioCapabilityResponse: Ignore session=%d,rc.logicalModemUuid = %d, rc.phase = %d, rc.rat = %d, rc.session = %d, rc.status = %d, rc.version = %d",
+                mRadioCapabilitySessionId.load(), rc.logicalModemUuid,rc.phase,rc.rat,rc.session,rc.status,rc.version);
+        /// M: handle rc error, retry sim switch if possible. @{
+        onApplyRadioCapabilityErrorHandler(msg);
+        /// @}
+        return;
+    }
+    RLOGD("onApplyRadioCapabilityResponse: rc.logicalModemUuid = %d, rc.phase = %d, rc.rat = %d, rc.session = %d, rc.status = %d, rc.version = %d",
+                mRadioCapabilitySessionId.load(), rc.logicalModemUuid,rc.phase,rc.rat,rc.session,rc.status,rc.version);
+    if (msg->e != RIL_E_SUCCESS) {
+        m_mutex.lock();
+        RLOGD("onApplyRadioCapabilityResponse: Error response session=%d",rc.session);
+        int id = msg->slot;
+        /// M: handle exception, retry sim switch if possible. @{
+        onApplyExceptionHandler(msg);
+        /// @}
+        RLOGD("onApplyRadioCapabilityResponse: phoneId=%d status=FAIL", id);
+        mSetRadioAccessFamilyStatus[id] = SET_RC_STATUS_FAIL;
+        mTransactionFailed = true;
+        m_mutex.unlock();
+    } else {
+        RLOGD("onApplyRadioCapabilityResponse: Valid start expecting notification rc.logicalModemUuid = %d, rc.phase = %d, rc.rat = %d, rc.session = %d, rc.status = %d, rc.version = %d",
+                mRadioCapabilitySessionId.load(), rc.logicalModemUuid,rc.phase,rc.rat,rc.session,rc.status,rc.version);
+    }
+}
+
+void Proxy_controller::handle_message_notify(RIL_RadioCapability* cap,int slot) {
+    sp<Request_message> msg = new Request_message();
+    msg->what = EVENT_NOTIFICATION_RC_CHANGED;
+    if(cap != NULL) {
+        msg->cap = (*cap);
+    } else {
+        msg->is_rc_set = false;
+        RLOGD("handle_request_resp[slot%d]: cap is null", slot);
+    }
+    msg->slot = slot;
+    RLOGD("handle_request_resp logicalModemUuid: %s , phase: %d, rat: %d, session: %d, status: %d, version: %d",
+            msg->cap.logicalModemUuid, msg->cap.phase, msg->cap.rat, msg->cap.session, msg->cap.status, msg->cap.version);
+    sendMessage(msg, 0);
+}
+
+void Proxy_controller::onNotificationRadioCapabilityChanged(sp<Request_message> msg) {
+    RIL_RadioCapability rc = msg->cap;
+    if (msg->is_rc_set == false || (rc.session != mRadioCapabilitySessionId.load())) {
+        RLOGD("onNotificationRadioCapabilityChanged: Ignore session=%d,rc.logicalModemUuid = %d, rc.phase = %d, rc.rat = %d, rc.session = %d, rc.status = %d, rc.version = %d",
+                mRadioCapabilitySessionId.load(), rc.logicalModemUuid,rc.phase,rc.rat,rc.session,rc.status,rc.version);
+        return;
+    }
+    m_mutex.lock();
+    RLOGD("onNotificationRadioCapabilityChanged: rc.logicalModemUuid = %d, rc.phase = %d, rc.rat = %d, rc.session = %d, rc.status = %d, rc.version = %d",
+            rc.logicalModemUuid,rc.phase,rc.rat,rc.session,rc.status,rc.version);
+
+    int id = msg->slot;
+    if (msg-> e != RIL_E_SUCCESS ||
+            (rc.status == RadioCapabilityStatus(RC_STATUS_FAIL))) {
+        RLOGD("onNotificationRadioCapabilityChanged: phoneId=%d status=FAIL", id);
+        mSetRadioAccessFamilyStatus[id] = SET_RC_STATUS_FAIL;
+        mTransactionFailed = true;
+    } else {
+        RLOGD("onNotificationRadioCapabilityChanged: phoneId=%d status=SUCCESS(%d)", id, !mTransactionFailed);
+        mSetRadioAccessFamilyStatus[id] = SET_RC_STATUS_SUCCESS;
+        // The modems may have been restarted and forgotten this
+
+        RequestInfo *info = creatRILInfoAndInit(RIL_REQUEST_ALLOW_DATA, OTHER, (RIL_SOCKET_ID)id);
+
+        int switch_id = get_default_sim_data_for_switch();
+        RLOGD("onNotificationRadioCapabilityChanged: phoneId=%d switch_id=%d", id, switch_id);
+        char* argv[2] = {"RIL_REQUEST_ALLOW_DATA","0"};
+        if(id == switch_id) {
+            argv[1] = "1";
+        }
+        setDataAllowed(2, argv, RIL_SOCKET_ID(id), info);
+    }
+
+    mRadioAccessFamilyStatusCounter--;
+    if (mRadioAccessFamilyStatusCounter == 0) {
+        RLOGD("onNotificationRadioCapabilityChanged: APPLY URC success=%d",!mTransactionFailed);
+        m_mutex.unlock();
+        issueFinish(mRadioCapabilitySessionId.load());
+        return;
+    }
+    m_mutex.unlock();
+}
+
+void Proxy_controller::completeRadioCapabilityTransaction() {
+    RLOGD("completeRadioCapabilityTransaction: success=%d" , !mTransactionFailed);
+    if (!mTransactionFailed) {
+
+
+        // make messages about the old transaction obsolete (specifically the timeout)
+        //mRadioCapabilitySessionId++;
+
+        // Reinitialize
+        clearTransaction();
+        android::emResultNotify("default data slot switch success\n");
+    } else {
+        android::emResultNotify("default data slot switch fail, now retry\n");
+        // now revert.
+        mTransactionFailed = false;
+        std::vector<RIL_RadioAccessFamily> rafs = {RAF_UNKNOWN, RAF_UNKNOWN};
+        for (int phoneId = 0; phoneId < SIM_COUNT; phoneId++) {
+            rafs[phoneId] = (RIL_RadioAccessFamily)mOldRadioAccessFamily[phoneId];
+        }
+        doSetRadioCapabilities(rafs);
+    }
+
+}
+
+void Proxy_controller::onFinishRadioCapabilityResponse(sp<Request_message> msg){
+    RIL_RadioCapability rc = msg->cap;;
+    if (msg->is_rc_set == false || (rc.session != mRadioCapabilitySessionId.load())) {
+        RLOGD("onFinishRadioCapabilityResponse: Ignore session=%d,rc.logicalModemUuid = %d, rc.phase = %d, rc.rat = %d, rc.session = %d, rc.status = %d, rc.version = %d",
+                mRadioCapabilitySessionId.load(), rc.logicalModemUuid,rc.phase,rc.rat,rc.session,rc.status,rc.version);
+        return;
+    }
+    m_mutex.lock();
+    RLOGD("onFinishRadioCapabilityResponse mRadioAccessFamilyStatusCounter=%d",mRadioAccessFamilyStatusCounter);
+    mRadioAccessFamilyStatusCounter--;
+    if (mRadioAccessFamilyStatusCounter == 0) {
+        m_mutex.unlock();
+        completeRadioCapabilityTransaction();
+        return;
+    }
+    m_mutex.unlock();
+}
+
+void Proxy_controller::onTimeoutRadioCapability(sp<Request_message> msg){
+    if (msg->id != mRadioCapabilitySessionId.load()) {
+       RLOGD("RadioCapability timeout: Ignore msg->id=%d != mRadioCapabilitySessionId.load()=%d", msg->id,mRadioCapabilitySessionId.load());
+        return;
+    }
+
+    m_mutex.lock();
+    // timed-out.  Clean up as best we can
+    for (int i = 0; i < SIM_COUNT; i++) {
+        RLOGD("RadioCapability timeout: mSetRadioAccessFamilyStatus[%d]=%d",i,mSetRadioAccessFamilyStatus[i]);
+    }
+
+    // Increment the sessionId as we are completing the transaction below
+    // so we don't want it completed when the FINISH phase is done.
+    mRadioCapabilitySessionId++;
+
+    // Reset the status counter as existing session failed
+    mRadioAccessFamilyStatusCounter = 0;
+
+    // send FINISH request with fail status and then uniqueDifferentId
+    mTransactionFailed = true;
+    m_mutex.unlock();
+    issueFinish(mRadioCapabilitySessionId.load());
+}
+
+void Proxy_controller::Request_handler::sendMessage(sp<Request_message> msg, int delayms) {
+    RLOGD("Proxy_controller::Request_handler, sendMessage msg what=%d delayms=%d", msg->what, delayms);
+    // Sand message to looper
+    this->msg = msg;
+    if (delayms > 0) {
+        proxy_controller->handle_thread->getLooper()->sendMessageDelayed(ms2ns(delayms),
+                this, this->m_dummyMsg);
+    } else {
+        proxy_controller->handle_thread->getLooper()->sendMessage(this, this->m_dummyMsg);
+    }
+    return ;
+}
+
+void Proxy_controller::Request_handler::handleMessage(const Message& message) {
+
+    RLOGD("handleMessage msg->what: %d", msg->what);
+    switch( msg->what){
+    case EVENT_START_RC_RESPONSE:
+    {
+        proxy_controller->onStartRadioCapabilityResponse(msg);
+        break;
+    }
+    case EVENT_APPLY_RC_RESPONSE:
+    {
+        proxy_controller->onApplyRadioCapabilityResponse(msg);
+        break;
+    }
+    case EVENT_NOTIFICATION_RC_CHANGED:
+    {
+        proxy_controller->onNotificationRadioCapabilityChanged(msg);
+        break;
+    }
+    case EVENT_FINISH_RC_RESPONSE:
+    {
+        proxy_controller->onFinishRadioCapabilityResponse(msg);
+        break;
+    }
+    case EVENT_TIMEOUT:
+    {
+        proxy_controller->onTimeoutRadioCapability(msg);
+        break;
+    }
+    default:
+        break;
+    }
+}
+
+void Proxy_controller::clearTransaction() {
+    RLOGD("clearTransaction");
+    m_mutex.lock();
+    mSetRadioAccessFamilyStatus.clear();
+    mOldRadioAccessFamily.clear();
+    mNewRadioAccessFamily.clear();
+    m_eventId.clear();
+    mCurrentLogicalModemIds.clear();
+    mNewLogicalModemIds.clear();
+    for (int i = 0; i < 2; i++) {
+        RLOGD("clearTransaction: phoneId=%d status=IDLE",i);
+        mSetRadioAccessFamilyStatus.push_back(SET_RC_STATUS_IDLE);
+        mOldRadioAccessFamily.push_back(0);
+        mNewRadioAccessFamily.push_back(0);
+        mCurrentLogicalModemIds.push_back("");
+        mNewLogicalModemIds.push_back("");
+        mTransactionFailed = false;
+        m_eventId.push_back(-1);
+    }
+    if(handle_thread.get()) {
+        sp<Looper> looper = handle_thread->getLooper();
+        if(looper.get()) {
+            if(timeout_handle.get()) {
+                looper->removeMessages(timeout_handle);
+            } else {
+                RLOGD("clearTransaction,timeout_handle");
+            }
+        } else {
+            RLOGD("clearTransaction,looper");
+        }
+    } else {
+        RLOGD("clearTransaction,handle_thread");
+    }
+    m_mutex.unlock();
+}
+
+int Proxy_controller::checkRadioCapabilitySwitchConditions(std::vector<RIL_RadioAccessFamily> rafs) {
+    m_mutex.lock();
+    mNextRafs = rafs;
+
+    // check if still switching
+    if (mIsCapSwitching == true) {
+        //throw new RuntimeException("is still switching");
+        RLOGD("keep it and return,because capability swithing");
+        mSetRafRetryCause = RC_RETRY_CAUSE_CAPABILITY_SWITCHING;
+        return RC_NO_NEED_SWITCH;
+    } else if (mSetRafRetryCause == RC_RETRY_CAUSE_CAPABILITY_SWITCHING) {
+        RLOGD("setCapability, mIsCapSwitching is not switching, can switch");
+        mSetRafRetryCause = RC_RETRY_CAUSE_NONE;
+    }
+    mIsCapSwitching = true;
+    m_mutex.lock();
+
+    // check if capability switch disabled
+    if (utils::mtk_property_get_bool("ro.vendor.mtk_disable_cap_switch", false) == true) {
+        mNextRafs.clear();
+        completeRadioCapabilityTransaction();
+        RLOGD("skip switching because mtk_disable_cap_switch is true");
+        return RC_NO_NEED_SWITCH;
+    }
+    // check FTA mode
+    if (utils::mtk_property_get_int32("vendor.gsm.gcf.testmode", 0) == 2) {
+        mNextRafs.clear();
+        completeRadioCapabilityTransaction();
+        RLOGD("skip switching because FTA mode");
+        return RC_NO_NEED_SWITCH;
+    }
+    // check EM disable mode
+    if (utils::mtk_property_get_int32("persist.vendor.radio.simswitch.emmode", 1) == 0) {
+        mNextRafs.clear();
+        completeRadioCapabilityTransaction();
+        RLOGD("skip switching because EM disable mode");
+        return RC_NO_NEED_SWITCH;
+    }
+
+    // check world mode switching
+    if (WorldPhoneUtil::isWorldPhoneSupport()) {
+        if (!WorldPhoneUtil::isWorldModeSupport()) {
+            if (/*ModemSwitchHandler.isModemTypeSwitching()*/!isRadioAvailable((RIL_SOCKET_ID)Radio_capability_switch_util::get_main_capability_phone_id())) {
+                RLOGD("world mode switching.");
+                if (!mHasRegisterWorldModeReceiver) {
+                    mHasRegisterWorldModeReceiver = true;
+                }
+                mSetRafRetryCause = RC_RETRY_CAUSE_WORLD_MODE_SWITCHING;
+                m_mutex.lock();
+                mIsCapSwitching = false;
+                m_mutex.unlock();
+                return RC_CANNOT_SWITCH;
+            }
+        } else if (mSetRafRetryCause == RC_RETRY_CAUSE_WORLD_MODE_SWITCHING) {
+            if (mHasRegisterWorldModeReceiver) {
+                mHasRegisterWorldModeReceiver = false;
+                mSetRafRetryCause = RC_RETRY_CAUSE_NONE;
+            }
+        }
+    }
+
+    // check call state
+    if (!(is_call_state_idle(0) || is_call_state_idle(1))) {
+        //throw new RuntimeException("in call, fail to set RAT for phones");
+        RLOGD("setCapability in calling, fail to set RAT for phones");
+        if (!mHasRegisterPhoneStateReceiver) {
+            mHasRegisterPhoneStateReceiver = true;
+        }
+        mSetRafRetryCause = RC_RETRY_CAUSE_IN_CALL;
+        m_mutex.lock();
+        mIsCapSwitching = false;
+        m_mutex.unlock();
+        return RC_CANNOT_SWITCH;
+    } else if (isEccInProgress()) {
+        RLOGD("setCapability in ECC, fail to set RAT for phones");
+        if (!mHasRegisterEccStateReceiver) {
+            mHasRegisterEccStateReceiver = true;
+        }
+        mSetRafRetryCause = RC_RETRY_CAUSE_IN_CALL;
+        m_mutex.lock();
+        mIsCapSwitching = false;
+        m_mutex.unlock();
+        return RC_CANNOT_SWITCH;
+    } else if (mSetRafRetryCause == RC_RETRY_CAUSE_IN_CALL) {
+        if (mHasRegisterPhoneStateReceiver) {
+            mHasRegisterPhoneStateReceiver = false;
+            mSetRafRetryCause = RC_RETRY_CAUSE_NONE;
+        }
+        if (mHasRegisterEccStateReceiver) {
+            mHasRegisterEccStateReceiver = false;
+            mSetRafRetryCause = RC_RETRY_CAUSE_NONE;
+        }
+    }
+
+    // check radio available
+    for (int i = 0; i < SIM_COUNT; i++) {
+        if (!isRadioAvailable((RIL_SOCKET_ID)i)) {
+            //throw new RuntimeException("Phone" + i + " is not available");
+            mSetRafRetryCause = RC_RETRY_CAUSE_RADIO_UNAVAILABLE;
+            //mCi[i].registerForAvailable(mMtkHandler, EVENT_RADIO_AVAILABLE, null);
+            RLOGD("setCapability fail,Phone%d is not available", i);
+            m_mutex.lock();
+            mIsCapSwitching = false;
+            m_mutex.unlock();
+            return RC_CANNOT_SWITCH;
+        } else if (mSetRafRetryCause == RC_RETRY_CAUSE_RADIO_UNAVAILABLE) {
+            //mCi[i].unregisterForAvailable(mMtkHandler);
+            if (i == SIM_COUNT - 1) {
+                mSetRafRetryCause = RC_RETRY_CAUSE_NONE;
+            }
+        }
+    }
+
+    int switchStatus = utils::mtk_property_get_int32(PROPERTY_CAPABILITY_SWITCH.c_str(), 1);
+    // check parameter
+    bool bIsboth3G = false;
+    bool bIsMajorPhone = false;
+    int newMajorPhoneId = 0;
+    for (int i = 0; i < rafs.size(); i++) {
+        bIsMajorPhone = false;
+        if ((rafs[i] & RIL_RadioAccessFamily::RAF_GPRS) > 0) {
+            bIsMajorPhone = true;
+        }
+
+        if (bIsMajorPhone) {
+            newMajorPhoneId = i;
+            if (newMajorPhoneId == (switchStatus - 1)) {
+                RLOGD("no change, skip setRadioCapability");
+                mSetRafRetryCause = RC_RETRY_CAUSE_NONE;
+                mNextRafs.clear();
+                completeRadioCapabilityTransaction();
+                return RC_NO_NEED_SWITCH;
+            }
+            if (bIsboth3G) {
+                RLOGD("set more than one 3G phone, fail");
+                m_mutex.lock();
+                mIsCapSwitching = false;
+                m_mutex.unlock();
+                throw std::runtime_error("input parameter is incorrect");
+            } else {
+                bIsboth3G = true;
+            }
+        }
+    }
+    if (bIsboth3G == false) {
+        m_mutex.lock();
+        mIsCapSwitching = false;
+        m_mutex.unlock();
+        throw std::runtime_error("input parameter is incorrect - no 3g phone");
+    }
+
+    // check operator spec
+    if (!isNeedSimSwitch(newMajorPhoneId, SIM_COUNT)) {
+        RLOGD("check sim card type and skip setRadioCapability");
+        mSetRafRetryCause = RC_RETRY_CAUSE_NONE;
+        mNextRafs.clear();
+        completeRadioCapabilityTransaction();
+        return RC_NO_NEED_SWITCH;
+    }
+
+//    if (!WorldPhoneUtil::isWorldModeSupport() && WorldPhoneUtil::isWorldPhoneSupport()) {
+//        WorldPhoneUtil.getWorldPhone().notifyRadioCapabilityChange(newMajorPhoneId);
+//    }
+    RLOGD("checkRadioCapabilitySwitchConditions, do switch");
+    return RC_DO_SWITCH;
+}
+
+bool Proxy_controller::isEccInProgress() {
+    bool inEcm = utils::mtk_property_get_bool("ril.cdma.inecmmode", false);
+    return inEcm;
+}
+
+bool Proxy_controller::isNeedSimSwitch(int majorPhoneId, int phoneNum) {
+    RLOGD("OMisNeedSimSwitch, majorPhoneId = %d ", majorPhoneId);
+    return !Radio_capability_switch_util::isSkipCapabilitySwitch(majorPhoneId, phoneNum);
+}
+
+bool Proxy_controller::set_Radio_Capability(std::vector<RIL_RadioAccessFamily> rafs) {
+    if (rafs.size() != SIM_COUNT) {
+        RLOGD("Length of input rafs must equal to total phone count");
+    }
+    // Check if there is any ongoing transaction and throw an exception if there
+    // is one as this is a programming error.
+    m_mutex.lock();
+    for (int i = 0; i < rafs.size(); i++) {
+        if (mSetRadioAccessFamilyStatus[i] != SET_RC_STATUS_IDLE) {
+            // TODO: The right behaviour is to cancel previous request and send this.
+            RLOGE("setRadioCapability: Phone[%d] is not idle. Rejecting request.", i);
+            return false;
+        }
+    }
+    m_mutex.unlock();
+
+    // Clear to be sure we're in the initial state
+    clearTransaction();
+
+    return doSetRadioCapabilities(rafs);
+}
+
+void Proxy_controller::resetRadioAccessFamilyStatusCounter() {
+    mRadioAccessFamilyStatusCounter = SIM_COUNT;
+}
+
+std::string Proxy_controller::getLogicalModemIdFromRaf(int raf) {
+    std::string modemUui;
+
+    for (int phoneId = 0; phoneId < SIM_COUNT; phoneId++) {
+        if (get_radio_capa(phoneId).rat == raf) {
+            modemUui = get_radio_capa(phoneId).logicalModemUuid;
+            break;
+        }
+    }
+    return modemUui;
+}
+
+void Proxy_controller::sendRadioCapabilityRequest(int phoneId, int sessionId, int rcPhase,
+            int radioFamily, std::string logicalModemId, int status, int eventId){
+    RequestInfo *info = creatRILInfoAndInit(RIL_REQUEST_SET_RADIO_CAPABILITY, OTHER, (RIL_SOCKET_ID)phoneId);
+
+    char* argv[7] = {"RIL_REQUEST_SET_RADIO_CAPABILITY",
+            const_cast<char*>(std::to_string(RIL_RADIO_CAPABILITY_VERSION).c_str()),
+            const_cast<char*>(std::to_string(sessionId).c_str()),
+            const_cast<char*>(std::to_string(rcPhase).c_str()),
+            const_cast<char*>(std::to_string(radioFamily).c_str()),
+            const_cast<char*>(logicalModemId.c_str()),
+            const_cast<char*>(std::to_string(status).c_str())
+    };
+    setRadioCapability(7, argv,(RIL_SOCKET_ID)phoneId, info);
+    m_eventId[phoneId] = eventId;
+}
+
+bool Proxy_controller::doSetRadioCapabilities(std::vector<RIL_RadioAccessFamily> rafs) {
+    // A new sessionId for this transaction
+    mRadioCapabilitySessionId++;
+    // Start timer to make sure all phones respond within a specific time interval.
+    // Will send FINISH if a timeout occurs.
+    sp<Request_message> msg = new Request_message();
+    msg->what = EVENT_TIMEOUT;
+    msg->id = mRadioCapabilitySessionId.load();
+    timeout_handle = sendMessage(msg, SET_RC_TIMEOUT_WAITING_MSEC);
+
+    m_mutex.lock();
+    RLOGD("setRadioCapability: new request session id=%d", mRadioCapabilitySessionId.load());
+    resetRadioAccessFamilyStatusCounter();
+    for (int i = 0; i < rafs.size(); i++) {
+        RLOGD("setRadioCapability: phoneId=%d status=STARTING", i);
+        mSetRadioAccessFamilyStatus[i] = SET_RC_STATUS_STARTING;
+        mOldRadioAccessFamily[i] = get_radio_capa(i).rat;
+        int requestedRaf = rafs[i];
+        // TODO Set the new radio access family to the maximum of the requested & supported
+        // int supportedRaf = mPhones[i].getRadioAccessFamily();
+        // mNewRadioAccessFamily[i] = requestedRaf & supportedRaf;
+        mNewRadioAccessFamily[i] = requestedRaf;
+
+        mCurrentLogicalModemIds[i] = get_radio_capa(i).logicalModemUuid;
+        // get the logical mode corresponds to new raf requested and pass the
+        // same as part of SET_RADIO_CAP APPLY phase
+        mNewLogicalModemIds[i] = getLogicalModemIdFromRaf(requestedRaf);
+        RLOGD("setRadioCapability: mOldRadioAccessFamily[%d]=%d", i,mOldRadioAccessFamily[i]);
+        RLOGD("setRadioCapability: mNewRadioAccessFamily[%d]=%d", i,mNewRadioAccessFamily[i]);
+        sendRadioCapabilityRequest(
+                i,
+                mRadioCapabilitySessionId.load(),
+                RadioCapabilityPhase(RC_PHASE_START),
+                mOldRadioAccessFamily[i],
+                mCurrentLogicalModemIds[i],
+                RadioCapabilityStatus(RC_STATUS_NONE),
+                EVENT_START_RC_RESPONSE);
+    }
+    m_mutex.unlock();
+    return true;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Proxycontroller.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Proxycontroller.h
new file mode 100644
index 0000000..da3ce2f
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Proxycontroller.h
@@ -0,0 +1,200 @@
+/* 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_UTIL_PROXYCONTROLLER_H_
+#define SRC_UTIL_PROXYCONTROLLER_H_
+
+#include <vector>
+#include <atomic>
+#include <mutex>
+#include <string>
+
+#include <utils/Looper.h>
+#include <utils/Thread.h>
+#include <utils/RefBase.h>
+#include <vendor-ril/telephony/ril.h>
+
+using ::android::Looper;
+using ::android::Thread;
+using ::android::MessageHandler;
+using ::android::Message;
+using ::android::sp;
+using ::android::RefBase;
+
+class Proxy_controller: public RefBase {
+public:
+    static constexpr int EVENT_NOTIFICATION_RC_CHANGED = 1;
+    static constexpr int EVENT_START_RC_RESPONSE = 2;
+    static constexpr int EVENT_APPLY_RC_RESPONSE = 3;
+    static constexpr int EVENT_FINISH_RC_RESPONSE = 4;
+    static constexpr int EVENT_TIMEOUT = 5;
+
+    static const int SET_RC_STATUS_IDLE;
+    static const int SET_RC_STATUS_STARTING;
+    static const int SET_RC_STATUS_STARTED;
+    static const int SET_RC_STATUS_APPLYING;
+    static const int SET_RC_STATUS_SUCCESS;
+    static const int SET_RC_STATUS_FAIL;
+
+    // The entire transaction must complete within this amount of time
+    // or a FINISH will be issued to each Logical Modem with the old
+    // Radio Access Family.
+    static const int SET_RC_TIMEOUT_WAITING_MSEC;
+    static const std::string PROPERTY_CAPABILITY_SWITCH;
+    static const std::string PROPERTY_CAPABILITY_SWITCH_STATE;
+
+// event 1-5 is defined in ProxyController
+    static const int EVENT_RADIO_AVAILABLE;
+    static const int EVENT_RIL_CONNECTED;
+
+// marker for retry cause
+    static const int RC_RETRY_CAUSE_NONE;
+    static const int RC_RETRY_CAUSE_WORLD_MODE_SWITCHING;
+    static const int RC_RETRY_CAUSE_CAPABILITY_SWITCHING;
+    static const int RC_RETRY_CAUSE_IN_CALL;
+    static const int RC_RETRY_CAUSE_RADIO_UNAVAILABLE;
+    static const int RC_RETRY_CAUSE_AIRPLANE_MODE;
+    static const int RC_RETRY_CAUSE_RESULT_ERROR;
+
+// marker for switch conditions pre-checking
+    static const int RC_DO_SWITCH;
+    static const int RC_NO_NEED_SWITCH;
+    static const int RC_CANNOT_SWITCH;
+//***** Class Variables
+private:
+    bool mIsCapSwitching;
+    bool mHasRegisterWorldModeReceiver;
+    bool mHasRegisterPhoneStateReceiver;
+    bool mHasRegisterEccStateReceiver;
+    bool mIsRildReconnected;
+    std::vector<RIL_RadioAccessFamily> mNextRafs;
+    int mSetRafRetryCause;
+// Exception counter
+    int onExceptionCount;
+public:
+    static Proxy_controller* sInstance;
+    static Proxy_controller *getInstance();
+
+    Proxy_controller();
+    virtual ~Proxy_controller();
+    int checkRadioCapabilitySwitchConditions(std::vector<RIL_RadioAccessFamily> rafs);
+    bool isNeedSimSwitch(int majorPhoneId, int phoneNum);
+    bool isEccInProgress();
+    class Handle_thread: public Thread {
+    public:
+        Handle_thread();
+        virtual ~Handle_thread();
+        sp<Looper> getLooper();
+
+    protected:
+        virtual bool threadLoop();
+    private:
+        sp<Looper> m_looper;
+    };
+
+    class Request_message: public RefBase {
+    public:
+        Request_message();
+        virtual ~Request_message() {};
+
+    public:
+        int what;
+        int slot;
+        int id;
+        RIL_Errno e;
+        RIL_RadioCapability cap;
+        bool is_rc_set;
+    };
+
+    class Request_handler: public MessageHandler {
+    public:
+        Request_handler(Proxy_controller* proxy): proxy_controller(proxy){}
+        virtual ~Request_handler() {}
+
+    public:
+        void sendMessage(sp<Request_message> msg, int delayms);
+        void handleMessage(const Message& message);
+        sp<Request_message> msg;
+        // dummy message that makes handler happy
+        Message m_dummyMsg;
+    private:
+        Proxy_controller* proxy_controller;
+    };
+public:
+    // send message to request handler
+    sp<Request_handler> sendMessage(sp<Request_message> msg, int delayms);
+    void handle_request_resp(RIL_RadioCapability* cap, RIL_Errno e, int slot);
+    void handle_message_notify(RIL_RadioCapability* cap,int slot);
+    bool doSetRadioCapabilities(std::vector<RIL_RadioAccessFamily> rafs);
+    bool set_Radio_Capability(std::vector<RIL_RadioAccessFamily> rafs);
+private:
+    sp<Request_handler> timeout_handle;
+    sp<Handle_thread> handle_thread;
+    void init();
+    void clearTransaction();
+    void resetRadioAccessFamilyStatusCounter();
+    std::string getLogicalModemIdFromRaf(int raf);
+    void sendRadioCapabilityRequest(int phoneId, int sessionId, int rcPhase,
+                int radioFamily, std::string logicalModemId, int status, int eventId);
+    void onStartRadioCapabilityResponse(sp<Request_message> msg);
+    void onApplyRadioCapabilityResponse(sp<Request_message> msg);
+    void onApplyRadioCapabilityErrorHandler(sp<Request_message> msg);
+    void onFinishRadioCapabilityResponse(sp<Request_message> msg);
+    void onTimeoutRadioCapability(sp<Request_message> msg);
+    void onApplyExceptionHandler(sp<Request_message> msg);
+    void onNotificationRadioCapabilityChanged(sp<Request_message> msg);
+    void completeRadioCapabilityTransaction();
+    void issueFinish(int sessionId);
+private:
+    std::atomic_int mRadioCapabilitySessionId;
+    std::mutex m_mutex;
+    // record each phone's set radio capability status
+    std::vector<int> mSetRadioAccessFamilyStatus;
+    int mRadioAccessFamilyStatusCounter;
+    bool mTransactionFailed;
+
+    std::vector<std::string> mCurrentLogicalModemIds;
+    std::vector<std::string> mNewLogicalModemIds;
+
+     // Record new and old Radio Access Family (raf) configuration.
+     // The old raf configuration is used to restore each logical modem raf when FINISH is
+     // issued if any requests fail.
+    std::vector<int> mNewRadioAccessFamily;
+    std::vector<int> mOldRadioAccessFamily;
+    std::vector<int> m_eventId;
+};
+
+
+#endif /* SRC_UTIL_PROXYCONTROLLER_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Radio_capability_switch_util.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Radio_capability_switch_util.cpp
new file mode 100644
index 0000000..0147650
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Radio_capability_switch_util.cpp
@@ -0,0 +1,642 @@
+/* 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 <utils/String8.h>
+#include <cutils/properties.h>
+#include <vendor-ril/telephony/ril.h>
+#include <bitset>
+#include <vector>
+
+#include "Radio_capability_switch_util.h"
+#include "utils.h"
+#include "log_extra.h"
+#include "Phone_utils.h"
+#include "common.h"
+#include "Proxycontroller.h"
+#include "RatConfiguration.h"
+#include "MtkRadioAccessFamily.h"
+#include "network.h"
+
+const int Radio_capability_switch_util::SIM_OP_INFO_UNKNOWN = 0;
+const int Radio_capability_switch_util::SIM_OP_INFO_OVERSEA = 1;
+const int Radio_capability_switch_util::SIM_OP_INFO_OP01 = 2;
+const int Radio_capability_switch_util::SIM_OP_INFO_OP02 = 3;
+const int Radio_capability_switch_util::SIM_OP_INFO_OP09 = 4;
+const int Radio_capability_switch_util::SIM_OP_INFO_OP18 = 4;
+
+const int Radio_capability_switch_util::SIM_TYPE_SIM = 0;
+const int Radio_capability_switch_util::SIM_TYPE_USIM = 1;
+const int Radio_capability_switch_util::SIM_TYPE_OTHER = 2;
+
+const int Radio_capability_switch_util::OP01_6M_PRIORITY_OP01_USIM = 0;
+const int Radio_capability_switch_util::OP01_6M_PRIORITY_OP01_SIM = 1;
+const int Radio_capability_switch_util::OP01_6M_PRIORITY_OTHER = 2;
+
+// sync to ril_oem.h for dsda
+const int Radio_capability_switch_util::SIM_SWITCH_MODE_SINGLE_TALK_MDSYS       = 1;
+const int Radio_capability_switch_util::SIM_SWITCH_MODE_SINGLE_TALK_MDSYS_LITE  = 2;
+const int Radio_capability_switch_util::SIM_SWITCH_MODE_DUAL_TALK               = 3;
+const int Radio_capability_switch_util::SIM_SWITCH_MODE_DUAL_TALK_SWAP          = 4;
+const int Radio_capability_switch_util::ENHANCEMENT_T_PLUS_T = 0;
+const int Radio_capability_switch_util::ENHANCEMENT_T_PLUS_W = 1;
+const int Radio_capability_switch_util::ENHANCEMENT_T_PLUS_C = 2;
+const int Radio_capability_switch_util::ENHANCEMENT_W_PLUS_C = 3;
+const int Radio_capability_switch_util::ENHANCEMENT_W_PLUS_W = 4;
+const int Radio_capability_switch_util::ENHANCEMENT_W_PLUS_NA = 5;
+
+#define LOG_TAG "DEMO_RADIO_CAPABILITY_SWITCH_UTIL"
+
+const std::string Radio_capability_switch_util::PROPERTY_ICCID = "vendor.ril.iccid.sim";
+const std::string Radio_capability_switch_util::PROPERTY_CAPABILITY_SWITCH = "persist.vendor.radio.simswitch";
+// OP01 SIMs
+const std::string Radio_capability_switch_util::PLMN_TABLE_OP01[] = {
+    "46000", "46002", "46007", "46008", "45412", "45413",
+    // Lab test IMSI
+    "00101", "00211", "00321", "00431", "00541", "00651",
+    "00761", "00871", "00902", "01012", "01122", "01232",
+    "46004", "46602", "50270"
+};
+
+// OP02 SIMs
+const std::string Radio_capability_switch_util::PLMN_TABLE_OP02[]= {
+    "46001", "46006", "46009", "45407"
+};
+
+// OP09 SIMs
+const std::string Radio_capability_switch_util::PLMN_TABLE_OP09[]= {
+    "46005", "45502", "46003", "46011"
+};
+
+// OP18 SIMs
+const std::string Radio_capability_switch_util::PLMN_TABLE_OP18[] = {
+    "405840", "405854", "405855", "405856",
+    "405857", "405858", "405855", "405856",
+    "405857", "405858", "405859", "405860",
+    "405861", "405862", "405863", "405864",
+    "405865", "405866", "405867", "405868",
+    "405869", "405870", "405871", "405872",
+    "405873", "405874"
+};
+
+// OP02 case
+const std::string Radio_capability_switch_util::NO_SIM_VALUE = "N/A";
+const std::string Radio_capability_switch_util::CN_MCC = "460";
+const std::string Radio_capability_switch_util::PROPERTY_SIM_ICCID[] = {
+    "vendor.ril.iccid.sim1",
+    "vendor.ril.iccid.sim2",
+    "vendor.ril.iccid.sim3",
+    "vendor.ril.iccid.sim4"
+};
+
+const int Radio_capability_switch_util::IMSI_NOT_READY_OR_SIM_LOCKED = 2;
+const int Radio_capability_switch_util::ICCID_ERROR = 3;
+
+// sim icc status
+// 0: imsi not ready
+// 1: imsi ready
+const std::string Radio_capability_switch_util::IMSI_NOT_READY = "0";
+const std::string Radio_capability_switch_util::IMSI_READY = "1";
+const std::string Radio_capability_switch_util::PROPERTY_SIM_IMSI_STATUS[] = {
+    "vendor.ril.imsi.status.sim1",
+    "vendor.ril.imsi.status.sim2",
+    "vendor.ril.imsi.status.sim3",
+    "vendor.ril.imsi.status.sim4"
+};
+
+const std::string Radio_capability_switch_util::PROPERTY_RIL_FULL_UICC_TYPE[] = {
+    "vendor.gsm.ril.fulluicctype",
+    "vendor.gsm.ril.fulluicctype.2",
+    "vendor.gsm.ril.fulluicctype.3",
+    "vendor.gsm.ril.fulluicctype.4",
+};
+
+const std::string Radio_capability_switch_util::PROPERTY_RIL_CT3G[] = {
+    "vendor.gsm.ril.ct3g",
+    "vendor.gsm.ril.ct3g.2",
+    "vendor.gsm.ril.ct3g.3",
+    "vendor.gsm.ril.ct3g.4",
+};
+
+#define PROPERTY_ICCID_PREIFX "vendor.ril.iccid.sim"
+
+std::string Radio_capability_switch_util::get_sim_app_type(int slot) {
+    char buf[PROPERTY_VALUE_MAX] = {0};
+    utils::mtk_property_get(PROPERTY_RIL_FULL_UICC_TYPE[slot].c_str(), buf, "");
+    std::string str(buf);
+    logd(android::String8::format("get slot(%d) type %s", slot, str.c_str()));
+    return str;
+}
+
+Radio_capability_switch_util::Radio_capability_switch_util() {
+    // TODO Auto-generated constructor stub
+}
+
+Radio_capability_switch_util::~Radio_capability_switch_util() {
+    // TODO Auto-generated destructor stub
+}
+
+int Radio_capability_switch_util::get_main_capability_phone_id() {
+    int phoneId = 0;
+    phoneId = utils::mtk_property_get_int32(PROPERTY_CAPABILITY_SWITCH.c_str(), 1) - 1;
+    logd(android::String8::format("getMainCapabilityPhoneId %d",phoneId));
+    return phoneId;
+}
+
+bool Radio_capability_switch_util::is_sim_inserted(int slot) {
+    char iccid[PROPERTY_VALUE_MAX] = {0};
+    android::String8 prop(PROPERTY_ICCID_PREIFX);
+
+    prop.append(android::String8::format("%d", (slot + 1)));
+    utils::mtk_property_get(prop.string(), iccid, "");
+
+    LOG_D(LOG_TAG, "(slot%d)iccid: %s", slot, iccid);
+    if ((strlen(iccid) > 0) && (strcmp(iccid, "N/A") != 0)){
+        return true;
+    }
+    return false;
+}
+
+int Radio_capability_switch_util::get_max_raf_supported(){
+    int maxRaf = RAF_UNKNOWN;
+
+    // RAF_GPRS is a marker of main capability
+    for (int i = 0; i < SIM_COUNT; i++) {
+        int rat = get_radio_capa(i).rat;
+        LOG_D(LOG_TAG, "(slot%d)rat: %d", i, rat);
+        if ((rat & RAF_GPRS) == RAF_GPRS) {
+            maxRaf = rat;
+        }
+    }
+    RLOGD("get_max_raf_supported:  maxRaf= %d" , maxRaf);
+
+    // If the phone capability cannot be updated promptly, the max capability should mark with
+    // GPRS, to avoid using an unknown RAF to trigger sim switch
+    if (maxRaf == RAF_UNKNOWN) {
+        maxRaf |= RAF_GPRS;
+    }
+
+    return maxRaf;
+}
+
+//RIL_RadioAccessFamily
+int Radio_capability_switch_util::get_min_rat_supported(){
+    int minRaf = RAF_UNKNOWN;
+
+    // RAF_GPRS is a marker of main capability
+    for (int i = 0; i < SIM_COUNT; i++) {
+        int rat = get_radio_capa(i).rat;
+        LOG_D(LOG_TAG, "(slot%d)rat: %d", i, rat);
+        if ((rat & RAF_GPRS) == 0) {
+            minRaf = rat;
+        }
+    }
+    RLOGD("get_max_raf_supported:  minRaf= %d" , minRaf);
+    return minRaf;
+}
+
+void Radio_capability_switch_util::sendRadioCapabilityRequest(int slotid) {
+    RequestInfo *info = creatRILInfoAndInit(RIL_REQUEST_SET_RADIO_CAPABILITY, OTHER, (RIL_SOCKET_ID)slotid);
+    char* version  = strdup((std::to_string(RIL_RADIO_CAPABILITY_VERSION)).c_str());
+    char* argv[7] = {"RIL_REQUEST_SET_RADIO_CAPABILITY", "0", "1", "2", "0","modem_sys1_ps0","0"};
+    argv[1] = version;
+    setRadioCapability(7, argv,(RIL_SOCKET_ID)slotid, info);
+    free(version);
+}
+
+void Radio_capability_switch_util::set_default_data_slot(int slot) {
+    int id = get_main_capability_phone_id();
+    if(id == slot) {
+        android::emResultNotify("default data slot is right, no need switch\n");
+        LOG_D(LOG_TAG, "the default data slot capability is right, don't need to set");
+        return;
+    }
+
+    int len = Phone_utils::get_phone_count();
+    std::vector<RIL_RadioAccessFamily> rafs = {RAF_UNKNOWN, RAF_UNKNOWN};
+    if(slot == 0 ){
+        rafs[1] = (RIL_RadioAccessFamily)get_min_rat_supported();
+    } else if(slot == 1) {
+        rafs[0] = (RIL_RadioAccessFamily)get_min_rat_supported();
+    } else {
+        LOG_D(LOG_TAG, "slot is %d, range 0 or 1", slot);
+        return ;
+    }
+    rafs[slot] = (RIL_RadioAccessFamily)get_max_raf_supported();
+    Proxy_controller::getInstance()->set_Radio_Capability(rafs);
+}
+
+/**
+ * Check if need to skip switch capability.
+ *
+ * @param majorPhoneId new major phone ID
+ * @return true : don't switch and stay current capability setting
+ * @       false  :  keep do setCapability
+ */
+bool Radio_capability_switch_util::isSkipCapabilitySwitch(int majorPhoneId, int phoneNum) {
+    std::vector<int> simOpInfo(phoneNum);
+    std::vector<int> simType(phoneNum);
+    int insertedState = 0;
+    int insertedSimCount = 0;
+    int tSimCount = 0;
+    int wSimCount = 0;
+    int cSimCount = 0;
+    std::vector<std::string> currIccId(phoneNum, "");
+    char optr[PROPERTY_VALUE_MAX] = {0};
+    utils::mtk_property_get("persist.vendor.operator.optr", optr, "OM");
+    std::string opSpec(optr);
+    std::string opOM("OM");
+
+    if (isPS2SupportLTE()) {
+        if (phoneNum > 2) {
+            if (majorPhoneId < 2 && get_main_capability_phone_id() < 2
+                    && !RatConfiguration::isC2kSupported()
+                    && !RatConfiguration::isTdscdmaSupported()) {
+                return true;
+            }
+            return false;
+        }
+        // check sim cards number
+        for (int i = 0; i < phoneNum; i++) {
+            char iccid[PROPERTY_VALUE_MAX] = {0};
+            utils::mtk_property_get(std::string(PROPERTY_ICCID).append(std::to_string(i+1)).c_str(), iccid, "");
+            currIccId[i] = iccid;
+            if (currIccId[i].empty()) {
+                LOG_D(LOG_TAG, "iccid not found, do capability switch");
+                return false;
+            }
+            if (!(NO_SIM_VALUE == currIccId[i])) {
+                ++insertedSimCount;
+                insertedState = insertedState | (1 << i);
+            }
+        }
+
+        // no sim card
+        if (insertedSimCount == 0) {
+            LOG_D(LOG_TAG, "no sim card, skip capability switch");
+            return true;
+        }
+
+        // check sim info
+        if (getSimInfo(simOpInfo, simType, insertedState) == false) {
+            LOG_D(LOG_TAG, "cannot get sim operator info, do capability switch");
+            return false;
+        }
+
+        for (int i = 0; i < phoneNum; i++) {
+            if (SIM_OP_INFO_OP01 == simOpInfo[i]) {
+                tSimCount++;
+            } else if (isCdmaCard(i, simOpInfo[i])) {
+                cSimCount++;
+            } else if (SIM_OP_INFO_UNKNOWN!= simOpInfo[i]){
+                wSimCount++;
+            }
+        }
+
+        LOG_D(LOG_TAG, "isSkipCapabilitySwitch : Inserted SIM count: %d, insertedStatus: %d, tSimCount: %d, wSimCount: %d, cSimCount: %d",
+                insertedSimCount, insertedState, tSimCount, wSimCount ,cSimCount );
+
+        if (opOM == opSpec ) {
+            // t + t --> don't need to capability switch
+            if (isSupportSimSwitchEnhancement(ENHANCEMENT_T_PLUS_T)
+                    && (insertedSimCount == 2) && (tSimCount == 2)) {
+                return true;
+            }
+
+            // t + w --> if support real T+W, always on t card
+            if (isSupportSimSwitchEnhancement(ENHANCEMENT_T_PLUS_W)
+                    && (insertedSimCount == 2) && (tSimCount == 1) && (wSimCount == 1)) {
+                if (isTPlusWSupport() && (simOpInfo[majorPhoneId] != SIM_OP_INFO_OP01)) {
+                    return true;
+                }
+            }
+
+            // t + c --> always on c card
+            if (isSupportSimSwitchEnhancement(ENHANCEMENT_T_PLUS_C)
+                    && (insertedSimCount == 2) && (tSimCount == 1) && (cSimCount == 1)) {
+                if (!isCdmaCard(majorPhoneId, simOpInfo[majorPhoneId])) {
+                    return true;
+                }
+            }
+
+            // w + c--> always on c card
+            if (isSupportSimSwitchEnhancement(ENHANCEMENT_W_PLUS_C)
+                    && (insertedSimCount == 2) && (wSimCount == 1) && (cSimCount == 1)) {
+                if (!isCdmaCard(majorPhoneId, simOpInfo[majorPhoneId])) {
+                    return true;
+                }
+            }
+
+        }
+
+        // w + w --> don't need to capability switch
+        if (isSupportSimSwitchEnhancement(ENHANCEMENT_W_PLUS_W)
+                && (insertedSimCount == 2) && (wSimCount == 2)) {
+            return true;
+        }
+
+        // w + empty --> don't need to capability switch
+        if (isSupportSimSwitchEnhancement(ENHANCEMENT_W_PLUS_NA)
+                && (insertedSimCount == 1) && (wSimCount == 1)) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+bool Radio_capability_switch_util::getSimInfo(std::vector<int> simOpInfo, std::vector<int>  simType, int insertedStatus) {
+    std::vector<std::string> strMnc(simOpInfo.size(), "");
+    std::vector<std::string> strSimType(simOpInfo.size(),"");
+    std::string propStr;
+
+    for (int i = 0; i < simOpInfo.size(); i++) {
+        if (i == 0) {
+            propStr = "vendor.gsm.ril.uicctype";
+        } else {
+            propStr = std::string("vendor.gsm.ril.uicctype.").append(std::to_string(i + 1));
+        }
+        char uicctype[PROPERTY_VALUE_MAX] = { 0 };
+        utils::mtk_property_get(propStr.c_str(),uicctype, "");
+        strSimType[i] = uicctype;
+        if (strSimType[i] == "SIM") {
+            simType[i] = Radio_capability_switch_util::SIM_TYPE_SIM;
+        } else if (strSimType[i] == "USIM") {
+            simType[i] = Radio_capability_switch_util::SIM_TYPE_USIM;
+        } else {
+            simType[i] = Radio_capability_switch_util::SIM_TYPE_OTHER;
+        }
+        LOG_D(LOG_TAG, "SimType[%d]= %s, simType[%d]= %d",i, strSimType[i].c_str(), i, simType[i]);
+
+        if (strMnc[i].empty()) {
+            LOG_D(LOG_TAG, "strMnc[%d] is null, get mnc by ril.uim.subscriberid",i);
+            propStr = std::string("vendor.ril.uim.subscriberid.").append(std::to_string(i+1));
+            char uim[PROPERTY_VALUE_MAX] = { 0 };
+            utils::mtk_property_get(propStr.c_str(), uim, "");
+            strMnc[i] = uim;
+        }
+        if (strMnc[i].empty()) {
+            LOG_D(LOG_TAG, "strMnc[%d] is null, get mnc by vendor.gsm.ril.uicc.mccmnc", i);
+            if (i == 0) {
+                propStr = "vendor.gsm.ril.uicc.mccmnc";
+            } else {
+                propStr = std::string("vendor.gsm.ril.uicc.mccmnc.").append(std::to_string(i));
+            }
+            char mccmnc[PROPERTY_VALUE_MAX] = { 0 };
+            utils::mtk_property_get(propStr.c_str(), mccmnc, "");
+            strMnc[i] = mccmnc;
+        }
+
+        if (strMnc[i].empty()) {
+            LOG_D(LOG_TAG, "strMnc[%d] is null", i);
+            strMnc[i] = "";
+        }
+
+        if (strMnc[i].length() >= 6) {
+            strMnc[i] = strMnc[i].substr(0, 6);
+        } else if (strMnc[i].length() >= 5) {
+            strMnc[i] = strMnc[i].substr(0, 5);
+        }
+        LOG_D(LOG_TAG, "insertedStatus: %d, imsi status:", insertedStatus, getSimImsiStatus(i));
+        if ((insertedStatus >= 0) && (((1 << i) & insertedStatus) > 0)) {
+            if (strMnc[i].empty() || strMnc[i] == "error") {
+                LOG_D(LOG_TAG, "SIM is inserted but no imsi");
+                return false;
+            }
+            if (strMnc[i] == "sim_lock") {
+                LOG_D(LOG_TAG, "SIM is lock, wait pin unlock");
+                return false;
+            }
+            if (strMnc[i] == "N/A" || strMnc[i] == "sim_absent") {
+                LOG_D(LOG_TAG, "strMnc have invalid value, return false");
+                return false;
+            }
+        }
+        for (std::string mccmnc : PLMN_TABLE_OP01) {
+            if (strMnc[i].find(mccmnc) == 0) {
+                simOpInfo[i] = SIM_OP_INFO_OP01;
+                break;
+            }
+        }
+        if (simOpInfo[i] == SIM_OP_INFO_UNKNOWN) {
+            for (std::string mccmnc : PLMN_TABLE_OP02) {
+                if (strMnc[i].find(mccmnc) == 0) {
+                    simOpInfo[i] = SIM_OP_INFO_OP02;
+                    break;
+                }
+            }
+        }
+        if (simOpInfo[i] == SIM_OP_INFO_UNKNOWN) {
+            for (std::string mccmnc : PLMN_TABLE_OP09) {
+                if (strMnc[i].find(mccmnc) == 0) {
+                    simOpInfo[i] = SIM_OP_INFO_OP09;
+                    break;
+                }
+            }
+        }
+        char optr[PROPERTY_VALUE_MAX] = { 0 };
+        utils::mtk_property_get("persist.vendor.operator.optr", optr,"");
+        if ("OP18" == std::string(optr)) {
+            if (simOpInfo[i] == SIM_OP_INFO_UNKNOWN) {
+                for (std::string mccmnc : PLMN_TABLE_OP18) {
+                    if (strMnc[i].find(mccmnc) == 0) {
+                        simOpInfo[i] = SIM_OP_INFO_OP18;
+                        break;
+                    }
+                }
+            }
+        }
+        if (simOpInfo[i] == SIM_OP_INFO_UNKNOWN) {
+            if (!(strMnc[i].empty()) && !(strMnc[i] == "N/A")) {
+                simOpInfo[i] = SIM_OP_INFO_OVERSEA;
+            }
+        }
+        LOG_D(LOG_TAG, "strMnc[%d]= %s, simOpInfo[%d]=%d", i, strMnc[i].c_str(), i,simOpInfo[i]);
+    }
+    for(auto info : simOpInfo) {
+        LOG_D(LOG_TAG, "getSimInfo(simOpInfo): %d", info);
+    }
+    for(auto type: simType) {
+        LOG_D(LOG_TAG, "getSimInfo(simType): %d", type);
+    }
+    return true;
+}
+
+std::string Radio_capability_switch_util::getSimImsiStatus(int slot) {
+    char sim_status[PROPERTY_VALUE_MAX] = { 0 };
+    utils::mtk_property_get(PROPERTY_SIM_IMSI_STATUS[slot].c_str(), sim_status,
+            IMSI_NOT_READY.c_str());
+    return std::string(sim_status);
+}
+
+bool Radio_capability_switch_util::isPS2SupportLTE() {
+    char ps2_rat[PROPERTY_VALUE_MAX] = { 0 };
+    utils::mtk_property_get("persist.vendor.radio.mtk_ps2_rat", ps2_rat, "");
+    std::string rat(ps2_rat);
+    if (rat.find('L') != std::string::npos) {
+        LOG_D(LOG_TAG, "isPS2SupportLTE = true");
+        return true;
+    }
+    LOG_D(LOG_TAG, "isPS2SupportLTE = false");
+    return false;
+}
+
+bool Radio_capability_switch_util::isTPlusWSupport() {
+    char tpluswsupport[PROPERTY_VALUE_MAX] = { 0 };
+    utils::mtk_property_get("vendor.ril.simswitch.tpluswsupport", tpluswsupport,
+            "");
+    if ("1" == std::string(tpluswsupport)) {
+        LOG_D(LOG_TAG, "return true for T+W support");
+        return true;
+    }
+    return false;
+}
+
+bool Radio_capability_switch_util::isVolteEnabled(int phoneId) {
+    bool imsUseEnabled = utils::mtk_property_get_bool("persist.mtk.volte.enable", false);
+    if (imsUseEnabled == true) {
+        // check 4G is enabled or not
+        if (is_sim_inserted(phoneId)) {
+            int nwMode = get_preferred_network_type(phoneId);
+            int rafFromNwMode = MtkRadioAccessFamily::getRafFromNetworkType(
+                    nwMode);
+            int rafLteGroup = MtkRadioAccessFamily::RAF_LTE
+                    | MtkRadioAccessFamily::RAF_LTE_CA;
+            if ((rafFromNwMode & rafLteGroup) == 0) {
+                imsUseEnabled = false;
+            }
+            LOG_D(LOG_TAG, "isVolteEnabled, imsUseEnabled = %d, nwMode = %d, rafFromNwMode = %d, rafLteGroup = %d",
+                    imsUseEnabled,nwMode, rafFromNwMode, rafLteGroup);
+        } else {
+            LOG_D(LOG_TAG,"isVolteEnabled, subId[] is null");
+        }
+    }
+    LOG_D(LOG_TAG,"isVolteEnabled = %d", imsUseEnabled);
+    return imsUseEnabled;
+}
+
+bool Radio_capability_switch_util::isHVolteEnabled() {
+    char mtk_ct_volte[PROPERTY_VALUE_MAX] = {0};
+    utils::mtk_property_get("persist.vendor.mtk_ct_volte_support", mtk_ct_volte, "");
+    if ( "2" == std::string(mtk_ct_volte) || "3" == std::string(mtk_ct_volte)) {
+        return true;
+    }
+    return false;
+}
+
+bool Radio_capability_switch_util::isCdmaCard(int phoneId, int opInfo) {
+    bool isCdmaSim = false;
+    if (phoneId < 0
+            || phoneId >= SIM_COUNT) {
+        LOG_D(LOG_TAG, "isCdmaCard invalid phoneId: %d", phoneId);
+        return isCdmaSim;
+    }
+
+    char uicc_type[PROPERTY_VALUE_MAX] = {0};
+    utils::mtk_property_get(PROPERTY_RIL_FULL_UICC_TYPE[phoneId].c_str(), uicc_type, "");
+    std::string cardType(uicc_type);
+    isCdmaSim =
+            (cardType.find("CSIM") != std::string::npos || cardType.find("RUIM") != std::string::npos);
+
+    if (!isCdmaSim && ("SIM" == cardType)) {
+        char ct3g[PROPERTY_VALUE_MAX] = {0};
+        utils::mtk_property_get(PROPERTY_RIL_CT3G[phoneId].c_str(), ct3g, "");
+        std::string uimDualMode(ct3g);
+        if ("1" == uimDualMode) {
+            isCdmaSim = true;
+        }
+    }
+
+    if (opInfo == SIM_OP_INFO_OP09) {
+        isCdmaSim = true;
+    }
+
+    if (isCdmaSim == true && isVolteEnabled(phoneId) == true
+            && isHVolteEnabled() == false) {
+        // if volte is enabled and h-volte is disbale, SRLTE is unused for CT card, treat as CU sim
+        isCdmaSim = false;
+        LOG_D(LOG_TAG,"isCdmaCard, volte is enabled, SRLTE is unused for CT card");
+    }
+
+    return isCdmaSim;
+}
+
+/**
+ * Check if support SIM switch enhancement
+ *
+ * @return true : support SIM switch enhancement.
+ * @       false  :  don't support SIM switch enhancement
+ */
+bool Radio_capability_switch_util::isSupportSimSwitchEnhancement(int simType) {
+    bool ret = false;
+    switch (simType) {
+    // CMCC + CMCC
+    case ENHANCEMENT_T_PLUS_T:
+        ret = true;
+        break;
+
+        // CMCC + CU
+    case ENHANCEMENT_T_PLUS_W:
+        ret = true;
+        break;
+
+        // CMCC + CT
+    case ENHANCEMENT_T_PLUS_C:
+        ret = false;
+        break;
+
+        // CT + CU
+    case ENHANCEMENT_W_PLUS_C:
+        ret = false;
+        break;
+
+        // CU + CU
+    case ENHANCEMENT_W_PLUS_W:
+        ret = true;
+        break;
+
+        // CU + Empty
+    case ENHANCEMENT_W_PLUS_NA:
+        ret = true;
+        break;
+
+    default:
+        break;
+    }
+    return ret;
+}
+
+void Radio_capability_switch_util::logd(android::String8 s) {
+    LOG_D(LOG_TAG, "%s", s.string());
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Radio_capability_switch_util.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Radio_capability_switch_util.h
new file mode 100644
index 0000000..c16ee4d
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Radio_capability_switch_util.h
@@ -0,0 +1,127 @@
+/* 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_UTIL_RADIO_CAPABILITY_SWITCH_UTIL_H_
+#define SRC_UTIL_RADIO_CAPABILITY_SWITCH_UTIL_H_
+
+#include <string>
+#include <utils/String8.h>
+
+class Radio_capability_switch_util {
+public:
+    static const int SIM_OP_INFO_UNKNOWN;
+    static const int SIM_OP_INFO_OVERSEA;
+    static const int SIM_OP_INFO_OP01;
+    static const int SIM_OP_INFO_OP02;
+    static const int SIM_OP_INFO_OP09;
+    static const int SIM_OP_INFO_OP18;
+
+    static const int SIM_TYPE_SIM;
+    static const int SIM_TYPE_USIM;
+    static const int SIM_TYPE_OTHER;
+
+    static const int OP01_6M_PRIORITY_OP01_USIM;
+    static const int OP01_6M_PRIORITY_OP01_SIM;
+    static const int OP01_6M_PRIORITY_OTHER;
+
+    // sync to ril_oem.h for dsda
+    static const int SIM_SWITCH_MODE_SINGLE_TALK_MDSYS;
+    static const int SIM_SWITCH_MODE_SINGLE_TALK_MDSYS_LITE;
+    static const int SIM_SWITCH_MODE_DUAL_TALK;
+    static const int SIM_SWITCH_MODE_DUAL_TALK_SWAP;
+    static const int ENHANCEMENT_T_PLUS_T;
+    static const int ENHANCEMENT_T_PLUS_W;
+    static const int ENHANCEMENT_T_PLUS_C;
+    static const int ENHANCEMENT_W_PLUS_C;
+    static const int ENHANCEMENT_W_PLUS_W;
+    static const int ENHANCEMENT_W_PLUS_NA;
+
+public:
+    Radio_capability_switch_util();
+    virtual ~Radio_capability_switch_util();
+    std::string get_sim_app_type(int slot);
+    static int get_main_capability_phone_id();
+    static bool is_sim_inserted(int slot);
+    static int get_max_raf_supported();
+    static int get_min_rat_supported();
+    static void set_default_data_slot(int slot);
+    static bool isSkipCapabilitySwitch(int majorPhoneId, int phoneNum);
+    static bool isSupportSimSwitchEnhancement(int simType);
+    static bool isVolteEnabled(int phoneId);
+    static bool isHVolteEnabled();
+    static bool isCdmaCard(int phoneId, int opInfo);
+    static bool isTPlusWSupport();
+    static bool isPS2SupportLTE();
+    static bool getSimInfo(std::vector<int> simOpInfo, std::vector<int>  simType, int insertedStatus);
+    static void sendRadioCapabilityRequest(int slotid);
+    static std::string getSimImsiStatus(int slot);
+private:
+    static void logd(android::String8 s);
+private:
+    static const std::string PROPERTY_ICCID;
+    static const std::string PROPERTY_CAPABILITY_SWITCH;
+    // OP01 SIMs
+    static const std::string PLMN_TABLE_OP01[];
+
+    // OP02 SIMs
+    static const std::string PLMN_TABLE_OP02[];
+
+    // OP09 SIMs
+    static const std::string PLMN_TABLE_OP09[];
+
+    // OP18 SIMs
+    static const std::string PLMN_TABLE_OP18[];
+
+    // OP02 case
+    static const std::string NO_SIM_VALUE;
+    static const std::string CN_MCC;
+    static const std::string PROPERTY_SIM_ICCID[];
+
+    static const int IMSI_NOT_READY_OR_SIM_LOCKED;
+    static const int ICCID_ERROR;
+
+    // sim icc status
+    // 0: imsi not ready
+    // 1: imsi ready
+    static const std::string IMSI_NOT_READY;
+    static const std::string IMSI_READY;
+    static const std::string PROPERTY_SIM_IMSI_STATUS[];
+
+    static const std::string PROPERTY_RIL_FULL_UICC_TYPE[];
+
+    static const std::string PROPERTY_RIL_CT3G[];
+};
+
+#endif /* SRC_UTIL_RADIO_CAPABILITY_SWITCH_UTIL_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/RatConfiguration.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/RatConfiguration.cpp
new file mode 100644
index 0000000..60fb5af
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/RatConfiguration.cpp
@@ -0,0 +1,293 @@
+/* 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 <cutils/properties.h>
+
+#include "RatConfiguration.h"
+#include "utils.h"
+
+#define LOG_TAG "DEMO_RatConfig"
+
+const std::string RatConfiguration::PROPERTY_BUILD_RAT_CONFIG =
+        "ro.vendor.mtk_protocol1_rat_config";
+/* the system property of active rat */
+const std::string RatConfiguration::PROPERTY_RAT_CONFIG = "ro.boot.opt_ps1_rat";
+const std::string RatConfiguration::PROPERTY_IS_USING_DEFAULT_CONFIG =
+        "ro.boot.opt_using_default";
+/* the valid characters of the human-readable rat config */
+/* the defination must be sync with ratconfig.c */
+const std::string RatConfiguration::CDMA = "C";
+const std::string RatConfiguration::LteFdd = "Lf";
+const std::string RatConfiguration::LteTdd = "Lt";
+const std::string RatConfiguration::WCDMA = "W";
+const std::string RatConfiguration::TDSCDMA = "T";
+const std::string RatConfiguration::GSM = "G";
+const std::string RatConfiguration::DELIMITER = "/";
+
+/* bitmask */
+/* the defination must be sync with ratconfig.c */
+const int RatConfiguration::MASK_CDMA = (1 << 5);
+const int RatConfiguration::MASK_LteFdd = (1 << 4);
+const int RatConfiguration::MASK_LteTdd = (1 << 3);
+const int RatConfiguration::MASK_WCDMA = (1 << 2);
+const int RatConfiguration::MASK_TDSCDMA = (1 << 1);
+const int RatConfiguration::MASK_GSM = (1);
+
+const int RatConfiguration::MD_MODE_UNKNOWN = 0;
+const int RatConfiguration::MD_MODE_LTG = 8;   //uLTG
+const int RatConfiguration::MD_MODE_LWG = 9;   //uLWG
+const int RatConfiguration::MD_MODE_LWTG = 10;  //uLWTG
+const int RatConfiguration::MD_MODE_LWCG = 11;  //uLWCG
+const int RatConfiguration::MD_MODE_LWCTG = 12;  //uLWTCG(Auto mode)
+const int RatConfiguration::MD_MODE_LTTG = 13;  //LtTG
+const int RatConfiguration::MD_MODE_LFWG = 14;  //LfWG
+const int RatConfiguration::MD_MODE_LFWCG = 15;  //uLfWCG
+const int RatConfiguration::MD_MODE_LCTG = 16;  //uLCTG
+const int RatConfiguration::MD_MODE_LTCTG = 17;  //uLtCTG
+
+int RatConfiguration::max_rat = 0;
+bool RatConfiguration::max_rat_initialized = false;
+int RatConfiguration::actived_rat = 0;
+bool RatConfiguration::is_default_config = true;
+
+RatConfiguration::RatConfiguration() {
+    // TODO Auto-generated constructor stub
+
+}
+
+RatConfiguration::~RatConfiguration() {
+    // TODO Auto-generated destructor stub
+}
+
+/*
+ * transfer rat format from "L/T/G" to bitmask
+ * @params String rat, the rat in format like "L/T/G"
+ * @return int, the rat in bitmask.
+ */
+int RatConfiguration::ratToBitmask(std::string rat) {
+    int iRat = 0;
+    if (rat.find(CDMA) != std::string::npos) {
+        iRat = iRat | MASK_CDMA;
+    }
+    if (rat.find(LteFdd) != std::string::npos) {
+        iRat = iRat | MASK_LteFdd;
+    }
+    if (rat.find(LteTdd) != std::string::npos) {
+        iRat = iRat | MASK_LteTdd;
+    }
+    if (rat.find(WCDMA) != std::string::npos) {
+        iRat = iRat | MASK_WCDMA;
+    }
+    if (rat.find(TDSCDMA) != std::string::npos) {
+        iRat = iRat | MASK_TDSCDMA;
+    }
+    if (rat.find(GSM) != std::string::npos) {
+        iRat = iRat | MASK_GSM;
+    }
+    return iRat;
+}
+
+/*
+ * get the rat of project config
+ * @return int, the rat in bitmask.
+ */
+int RatConfiguration::getMaxRat() {
+    if (!max_rat_initialized) {
+        char rat[PROPERTY_VALUE_MAX] = {0};
+        utils::mtk_property_get(PROPERTY_BUILD_RAT_CONFIG.c_str(), rat, "");
+        std::string sMaxRat(rat);
+        max_rat = ratToBitmask(sMaxRat);
+        char def_rat[PROPERTY_VALUE_MAX] = {0};
+        is_default_config = (utils::mtk_property_get_int32(PROPERTY_IS_USING_DEFAULT_CONFIG.c_str(), 1) != 0) ? true : false;
+        max_rat_initialized = true;
+        RLOGD("getMaxRat: initial %s %d ", sMaxRat.c_str(), max_rat);
+    }
+    return max_rat;
+}
+
+/*
+ * check rat config is supported by project config
+ * @params int iRat, the rat to be checked.
+ * @return boolean,
+ *              true, the rat is supported.
+ *              false, the rat is not supported.
+ */
+bool RatConfiguration::checkRatConfig(int iRat) {
+    int maxrat = getMaxRat();
+    if ((iRat | maxrat) == maxrat) {
+        return true;
+    } else {
+        RLOGD("checkRatConfig: FAIL with %d", iRat);
+        return false;
+    }
+}
+
+/*
+ * get the active rat in bitmask.
+ * @return int, the rat in bitmask.
+ */
+int RatConfiguration::getRatConfig() {
+    int default_rat_config = getMaxRat();
+    if (default_rat_config == 0) {
+        actived_rat = 0;
+        return actived_rat;
+    }
+    if (is_default_config) {
+        actived_rat = default_rat_config;
+        return default_rat_config;
+    }
+    char rat_config[PROPERTY_VALUE_MAX] = {0};
+    utils::mtk_property_get(PROPERTY_RAT_CONFIG.c_str(), rat_config, "");
+    std::string rat(rat_config);
+    if (rat.length() > 0) {
+        actived_rat = ratToBitmask(rat);
+        if (checkRatConfig(actived_rat) == false) {
+            RLOGD("getRatConfig: invalid PROPERTY_RAT_CONFIG, set to max_rat");
+            actived_rat = getMaxRat();
+        }
+    } else {
+        RLOGD("getRatConfig: ger property PROPERTY_RAT_CONFIG fail, initialize");
+        actived_rat = getMaxRat();
+    }
+    return actived_rat;
+}
+
+/*
+ * transfer the format from bitmask to "L/T/G".
+ * @params int iRat, rat in bitmask
+ * @return String, rat in format like "L/T/G".
+ */
+std::string RatConfiguration::ratToString(int iRat) {
+    std::string rat = "";
+    if ((iRat & MASK_CDMA) == MASK_CDMA) {
+        rat += (DELIMITER + CDMA);
+    }
+    if ((iRat & MASK_LteFdd) == MASK_LteFdd) {
+        rat += (DELIMITER + LteFdd);
+    }
+    if ((iRat & MASK_LteTdd) == MASK_LteTdd) {
+        rat += (DELIMITER + LteTdd);
+    }
+    if ((iRat & MASK_WCDMA) == MASK_WCDMA) {
+        rat += (DELIMITER + WCDMA);
+    }
+    if ((iRat & MASK_TDSCDMA) == MASK_TDSCDMA) {
+        rat += (DELIMITER + TDSCDMA);
+    }
+    if ((iRat & MASK_GSM) == MASK_GSM) {
+        rat += (DELIMITER + GSM);
+    }
+    if (rat.length() > 0) {
+        // for remove the delimiter at rat[0]
+        rat = rat.substr(1);
+    }
+    return rat;
+}
+
+/*
+ * check C2k suppport
+ * @return boolean, cases as following
+ *       true, rat is active and project config supports it.
+ *       false, rat is inactive no matter project config supports.
+ */
+bool RatConfiguration::isC2kSupported() {
+    return (getMaxRat() & getRatConfig() & MASK_CDMA) == MASK_CDMA ?
+            true : false;
+}
+
+/*
+ * check LteFdd suppport
+ * @return boolean, cases as following
+ *       true, rat is active and project config supports it.
+ *       false, rat is inactive no matter project config supports.
+ */
+bool RatConfiguration::isLteFddSupported() {
+    return (getMaxRat() & getRatConfig() & MASK_LteFdd) == MASK_LteFdd ?
+            true : false;
+}
+
+/*
+ * check LteTdd suppport
+ * @return boolean, cases as following
+ *       true, rat is active and project config supports it.
+ *       false, rat is inactive no matter project config supports.
+ */
+bool RatConfiguration::isLteTddSupported() {
+    return (getMaxRat() & getRatConfig() & MASK_LteTdd) == MASK_LteTdd ?
+            true : false;
+}
+
+/*
+ * check Wcdma suppport
+ * @return boolean, cases as following
+ *       true, rat is active and project config supports it.
+ *       false, rat is inactive no matter project config supports.
+ */
+bool RatConfiguration::isWcdmaSupported() {
+    return (getMaxRat() & getRatConfig() & MASK_WCDMA) == MASK_WCDMA ?
+            true : false;
+}
+
+/*
+ * check Tdscdma suppport
+ * @return boolean, cases as following
+ *       true, rat is active and project config supports it.
+ *       false, rat is inactive no matter project config supports.
+ */
+bool RatConfiguration::isTdscdmaSupported() {
+    return (getMaxRat() & getRatConfig() & MASK_TDSCDMA) == MASK_TDSCDMA ?
+            true : false;
+}
+
+/*
+ * check GSM suppport
+ * @return boolean, cases as following
+ *       true, rat is active and project config supports it.
+ *       false, rat is inactive no matter project config supports.
+ */
+bool RatConfiguration::isGsmSupported() {
+    return (getMaxRat() & getRatConfig() & MASK_GSM) == MASK_GSM ? true : false;
+}
+
+/*
+ * get the active rat
+ * @return String, the rat in format like C/Lf/Lt/T/W/G
+ */
+std::string RatConfiguration::getActiveRatConfig() {
+    std::string rat = ratToString(getRatConfig());
+    RLOGD("getActiveRatConfig: %s", rat.c_str());
+    return rat;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/RatConfiguration.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/RatConfiguration.h
new file mode 100644
index 0000000..1a941fe
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/RatConfiguration.h
@@ -0,0 +1,99 @@
+/* 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_UTIL_RATCONFIGURATION_H_
+#define SRC_UTIL_RATCONFIGURATION_H_
+
+#include <string>
+class RatConfiguration {
+public:
+    RatConfiguration();
+    virtual ~RatConfiguration();
+    static const std::string PROPERTY_BUILD_RAT_CONFIG;
+    /* the system property of active rat */
+    static const std::string PROPERTY_RAT_CONFIG;
+    static const std::string PROPERTY_IS_USING_DEFAULT_CONFIG;
+    /* the valid characters of the human-readable rat config */
+    /* the defination must be sync with ratconfig.c */
+    static const std::string CDMA;
+    static const std::string LteFdd;
+    static const std::string LteTdd;
+    static const std::string WCDMA;
+    static const std::string TDSCDMA;
+    static const std::string GSM;
+    static const std::string DELIMITER;
+
+    /* bitmask */
+    /* the defination must be sync with ratconfig.c */
+    static const int MASK_CDMA;
+    static const int MASK_LteFdd;
+    static const int MASK_LteTdd;
+    static const int MASK_WCDMA;
+    static const int MASK_TDSCDMA;
+    static const int MASK_GSM;
+
+    static const int MD_MODE_UNKNOWN;
+    static const int MD_MODE_LTG;   //uLTG
+    static const int MD_MODE_LWG;   //uLWG
+    static const int MD_MODE_LWTG;  //uLWTG
+    static const int MD_MODE_LWCG;  //uLWCG
+    static const int MD_MODE_LWCTG;  //uLWTCG(Auto mode)
+    static const int MD_MODE_LTTG;  //LtTG
+    static const int MD_MODE_LFWG;  //LfWG
+    static const int MD_MODE_LFWCG;  //uLfWCG
+    static const int MD_MODE_LCTG;  //uLCTG
+    static const int MD_MODE_LTCTG;  //uLtCTG
+
+    static int max_rat;
+    static bool max_rat_initialized;
+    static int actived_rat;
+    static bool is_default_config;
+public:
+    static int ratToBitmask(std::string rat);
+    static int getMaxRat();
+    static bool checkRatConfig(int iRat);
+    static int getRatConfig();
+    static std::string ratToString(int iRat);
+    static bool isC2kSupported();
+    static bool isLteFddSupported();
+    static bool isLteTddSupported();
+    static bool isWcdmaSupported();
+    static bool isTdscdmaSupported();
+    static bool isGsmSupported();
+    static std::string getActiveRatConfig();
+
+};
+
+#endif /* SRC_UTIL_RATCONFIGURATION_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/WorldPhoneUtil.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/WorldPhoneUtil.cpp
new file mode 100644
index 0000000..0b7f05e
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/WorldPhoneUtil.cpp
@@ -0,0 +1,239 @@
+/* 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 "WorldPhoneUtil.h"
+#include "RatConfiguration.h"
+#include "utils.h"
+#include "log_extra.h"
+
+#undef LOG_TAG
+#define LOG_TAG "DEMO_WorldPhoneUtil"
+const int WorldPhoneUtil::ACTIVE_MD_TYPE_UNKNOWN = 0;
+const int WorldPhoneUtil::ACTIVE_MD_TYPE_WG   = 1;//3G(WCDMA)+2G(GSM)
+const int WorldPhoneUtil::ACTIVE_MD_TYPE_TG   = 2;//3G(TDS-CDMA)+2G(GSM)
+const int WorldPhoneUtil::ACTIVE_MD_TYPE_LWG  = 3;//4G(TDD-LTE+FDD-LTE)+3G(WCDMA)+2G(GSM)
+const int WorldPhoneUtil::ACTIVE_MD_TYPE_LTG  = 4;//4G(TDD-LTE+FDD-LTE)+3G(TDS-CDMA)+2G(GSM)
+    //4G(TDD-LTE+FDD-LTE)+3G(WCDMA+EVDO)+2G(GSM+CDMA2000)
+const int WorldPhoneUtil::ACTIVE_MD_TYPE_LWCG = 5;
+const int WorldPhoneUtil::ACTIVE_MD_TYPE_LtTG = 6;//4G(TDD-LTE)+3G(TDS-CDMA)+2G(GSM)
+const int WorldPhoneUtil::ACTIVE_MD_TYPE_LfWG = 7;//4G(FDD-LTE)+3G(WCDMA)+2G(GSM)
+
+
+const int WorldPhoneUtil::MD_TYPE_UNKNOWN = 0;
+const int WorldPhoneUtil::MD_TYPE_WG      = 3;
+const int WorldPhoneUtil::MD_TYPE_TG      = 4;
+const int WorldPhoneUtil::MD_TYPE_LWG     = 5;
+const int WorldPhoneUtil::MD_TYPE_LTG     = 6;
+const int WorldPhoneUtil::MD_TYPE_FDD     = 100;
+const int WorldPhoneUtil::MD_TYPE_TDD     = 101;
+
+const int WorldPhoneUtil::MD_WORLD_MODE_UNKNOWN = 0;
+const int WorldPhoneUtil::MD_WORLD_MODE_LTG     = 8;   //uLTG
+const int WorldPhoneUtil::MD_WORLD_MODE_LWG     = 9;   //uLWG
+const int WorldPhoneUtil::MD_WORLD_MODE_LWTG    = 10;  //uLWTG
+const int WorldPhoneUtil::MD_WORLD_MODE_LWCG    = 11;  //uLWCG
+const int WorldPhoneUtil::MD_WORLD_MODE_LWCTG   = 12;  //uLWTCG(Auto mode)
+const int WorldPhoneUtil::MD_WORLD_MODE_LTTG    = 13;  //LtTG
+const int WorldPhoneUtil::MD_WORLD_MODE_LFWG    = 14;  //LfWG
+const int WorldPhoneUtil::MD_WORLD_MODE_LFWCG   = 15;  //uLfWCG
+const int WorldPhoneUtil::MD_WORLD_MODE_LCTG    = 16;  //uLCTG
+const int WorldPhoneUtil::MD_WORLD_MODE_LTCTG   = 17;  //uLtCTG
+const int WorldPhoneUtil::MD_WORLD_MODE_LTWG    = 18;  //uLtWG
+const int WorldPhoneUtil::MD_WORLD_MODE_LTWCG   = 19;  //uLTWCG
+const int WorldPhoneUtil::MD_WORLD_MODE_LFTG    = 20;  //uLfTG
+const int WorldPhoneUtil::MD_WORLD_MODE_LFCTG   = 21;  //uLfCTG
+
+std::string WorldPhoneUtil::PROPERTY_RAT_CONFIG = "ro.boot.opt_ps1_rat";
+std::string WorldPhoneUtil::PROPERTY_ACTIVE_MD = "vendor.ril.active.md";
+std::string WorldPhoneUtil::WCDMA = "W";
+std::string WorldPhoneUtil::TDSCDMA = "T";
+std::string WorldPhoneUtil::CDMA = "C";
+const int WorldPhoneUtil::UTRAN_DIVISION_DUPLEX_MODE_UNKNOWN = 0;
+const int WorldPhoneUtil::UTRAN_DIVISION_DUPLEX_MODE_FDD = 1;
+const int WorldPhoneUtil::UTRAN_DIVISION_DUPLEX_MODE_TDD = 2;
+
+    // World mode result cause for EN.
+const int WorldPhoneUtil::WORLD_MODE_RESULT_SUCCESS            = 100;
+const int WorldPhoneUtil::WORLD_MODE_RESULT_ERROR              = 101;
+const int WorldPhoneUtil::WORLD_MODE_RESULT_WM_ID_NOT_SUPPORT  = 102;
+
+    /* bitmask */
+    /* the defination must be sync with ratconfig.c */
+const int WorldPhoneUtil::MASK_CDMA    = (1 << 5);
+const int WorldPhoneUtil::MASK_LTEFDD  = (1 << 4);
+const int WorldPhoneUtil::MASK_LTETDD  = (1 << 3);
+const int WorldPhoneUtil::MASK_WCDMA   = (1 << 2);
+const int WorldPhoneUtil::MASK_TDSCDMA = (1 << 1);
+const int WorldPhoneUtil::MASK_GSM     = (1);
+
+const int WorldPhoneUtil::MODEM_FDD = 1;
+const int WorldPhoneUtil::MODEM_TD = 2;
+const int WorldPhoneUtil::MODEM_NO3G = 3;
+
+WorldPhoneUtil::WorldPhoneUtil() {
+    // TODO Auto-generated constructor stub
+
+}
+
+WorldPhoneUtil::~WorldPhoneUtil() {
+    // TODO Auto-generated destructor stub
+}
+
+bool WorldPhoneUtil::isWorldPhoneSupport() {
+    return (RatConfiguration::isWcdmaSupported()
+            && RatConfiguration::isTdscdmaSupported());
+}
+
+bool WorldPhoneUtil::isLteSupport() {
+    return (RatConfiguration::isLteFddSupported()
+            || RatConfiguration::isLteTddSupported());
+}
+
+bool WorldPhoneUtil::isWorldModeSupport() {
+    //bool is_support = (utils::mtk_property_get_int32("ro.vendor.mtk_md_world_mode_support", 0) == 1);
+    //return is_support;
+    return true;
+}
+
+int WorldPhoneUtil::get3GDivisionDuplexMode() {
+    int duplexMode = UTRAN_DIVISION_DUPLEX_MODE_UNKNOWN;
+    int activeMdType = getActiveModemType();
+
+    switch (activeMdType) {
+        case ACTIVE_MD_TYPE_WG:
+        case ACTIVE_MD_TYPE_LWG:
+        case ACTIVE_MD_TYPE_LWCG:
+        case ACTIVE_MD_TYPE_LfWG:
+            duplexMode = UTRAN_DIVISION_DUPLEX_MODE_FDD;
+            break;
+        case ACTIVE_MD_TYPE_TG:
+        case ACTIVE_MD_TYPE_LTG:
+        case ACTIVE_MD_TYPE_LtTG:
+            duplexMode = UTRAN_DIVISION_DUPLEX_MODE_TDD;
+            break;
+        default:
+            duplexMode = UTRAN_DIVISION_DUPLEX_MODE_UNKNOWN;
+        break;
+    }
+    LOG_D(LOG_TAG, "get3GDivisionDuplexMode= %d", duplexMode);
+    return duplexMode;
+}
+
+int WorldPhoneUtil::getActiveModemType() {
+    int modemType = 0;
+    int activeMdType = ACTIVE_MD_TYPE_UNKNOWN;
+    int activeMode = -1;
+    if (!isWorldModeSupport()) {
+        modemType = getWorldModeId();
+        switch (modemType) {
+            case MD_TYPE_WG:
+                activeMdType = ACTIVE_MD_TYPE_WG;
+                break;
+            case MD_TYPE_TG:
+                activeMdType = ACTIVE_MD_TYPE_TG;
+                break;
+            case MD_TYPE_LWG:
+                activeMdType = ACTIVE_MD_TYPE_LWG;
+                break;
+            case MD_TYPE_LTG:
+                activeMdType = ACTIVE_MD_TYPE_LTG;
+                break;
+            default:
+                activeMdType = ACTIVE_MD_TYPE_UNKNOWN;
+            break;
+        }
+    } else {
+        modemType = getWorldModeId();
+        activeMode = utils::mtk_property_get_int32("vendor.ril.nw.worldmode.activemode",ACTIVE_MD_TYPE_UNKNOWN);
+        switch (modemType) {
+            case MD_WORLD_MODE_LTG:
+            case MD_WORLD_MODE_LCTG:
+            case MD_WORLD_MODE_LFTG:
+            case MD_WORLD_MODE_LFCTG:
+                activeMdType = ACTIVE_MD_TYPE_LTG;
+                break;
+            case MD_WORLD_MODE_LWG:
+            case MD_WORLD_MODE_LTWG:
+                activeMdType = ACTIVE_MD_TYPE_LWG;
+                break;
+            case MD_WORLD_MODE_LWTG:
+            case MD_WORLD_MODE_LWCTG:
+                if (activeMode > 0){
+                    if (activeMode == 1){
+                        //FDD mode
+                        activeMdType = ACTIVE_MD_TYPE_LWG;
+                    } else if (activeMode == 2){
+                        //TDD mode
+                        activeMdType = ACTIVE_MD_TYPE_LTG;
+                    }
+                }
+                break;
+            case MD_WORLD_MODE_LWCG:
+            case MD_WORLD_MODE_LFWCG:
+            case MD_WORLD_MODE_LTWCG:
+                activeMdType = ACTIVE_MD_TYPE_LWCG;
+                break;
+            case MD_WORLD_MODE_LTTG:
+            case MD_WORLD_MODE_LTCTG:
+                activeMdType = ACTIVE_MD_TYPE_LtTG;
+                break;
+            case MD_WORLD_MODE_LFWG:
+                activeMdType = ACTIVE_MD_TYPE_LfWG;
+                break;
+            default:
+                activeMdType = ACTIVE_MD_TYPE_UNKNOWN;
+            break;
+        }
+    }
+    LOG_D(LOG_TAG, "getActiveModemType=%d activeMode=%d",activeMdType , activeMode);
+    return activeMdType;
+}
+
+int WorldPhoneUtil::getWorldModeId() {
+    int modemType = 0;
+    modemType = utils::mtk_property_get_int32(PROPERTY_ACTIVE_MD.c_str(),MD_TYPE_UNKNOWN);
+    return modemType;
+}
+
+int WorldPhoneUtil::getModemType() {
+    int mode = MODEM_NO3G;
+    int mask = get3GDivisionDuplexMode();
+    if ((1 == mask) || (2 == mask)) {
+        mode = mask;
+    }
+    LOG_D(LOG_TAG, "mode = %d", mode);
+    return mode;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/WorldPhoneUtil.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/WorldPhoneUtil.h
new file mode 100644
index 0000000..2b215cd
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/WorldPhoneUtil.h
@@ -0,0 +1,119 @@
+/* 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_UTIL_WORLDPHONEUTIL_H_
+#define SRC_UTIL_WORLDPHONEUTIL_H_
+
+#include <string>
+
+class WorldPhoneUtil {
+private:
+    static const int ACTIVE_MD_TYPE_UNKNOWN;
+    static const int ACTIVE_MD_TYPE_WG;//3G(WCDMA)+2G(GSM)
+    static const int ACTIVE_MD_TYPE_TG;//3G(TDS-CDMA)+2G(GSM)
+    static const int ACTIVE_MD_TYPE_LWG;//4G(TDD-LTE+FDD-LTE)+3G(WCDMA)+2G(GSM)
+    static const int ACTIVE_MD_TYPE_LTG;//4G(TDD-LTE+FDD-LTE)+3G(TDS-CDMA)+2G(GSM)
+    //4G(TDD-LTE+FDD-LTE)+3G(WCDMA+EVDO)+2G(GSM+CDMA2000)
+    static const int ACTIVE_MD_TYPE_LWCG;
+    static const int ACTIVE_MD_TYPE_LtTG;//4G(TDD-LTE)+3G(TDS-CDMA)+2G(GSM)
+    static const int ACTIVE_MD_TYPE_LfWG;//4G(FDD-LTE)+3G(WCDMA)+2G(GSM)
+
+
+    static const int MD_TYPE_UNKNOWN;
+    static const int MD_TYPE_WG;
+    static const int MD_TYPE_TG;
+    static const int MD_TYPE_LWG;
+    static const int MD_TYPE_LTG;
+    static const int MD_TYPE_FDD;
+    static const int MD_TYPE_TDD;
+
+    static const int MD_WORLD_MODE_UNKNOWN;
+    static const int MD_WORLD_MODE_LTG;   //uLTG
+    static const int MD_WORLD_MODE_LWG;   //uLWG
+    static const int MD_WORLD_MODE_LWTG;  //uLWTG
+    static const int MD_WORLD_MODE_LWCG;  //uLWCG
+    static const int MD_WORLD_MODE_LWCTG;  //uLWTCG(Auto mode)
+    static const int MD_WORLD_MODE_LTTG;  //LtTG
+    static const int MD_WORLD_MODE_LFWG;  //LfWG
+    static const int MD_WORLD_MODE_LFWCG;  //uLfWCG
+    static const int MD_WORLD_MODE_LCTG;  //uLCTG
+    static const int MD_WORLD_MODE_LTCTG;  //uLtCTG
+    static const int MD_WORLD_MODE_LTWG;  //uLtWG
+    static const int MD_WORLD_MODE_LTWCG;  //uLTWCG
+    static const int MD_WORLD_MODE_LFTG;  //uLfTG
+    static const int MD_WORLD_MODE_LFCTG;  //uLfCTG
+
+    static std::string PROPERTY_RAT_CONFIG;
+    static std::string PROPERTY_ACTIVE_MD;
+    static std::string WCDMA;
+    static std::string TDSCDMA;
+    static std::string CDMA;
+    static const int UTRAN_DIVISION_DUPLEX_MODE_UNKNOWN;
+    static const int UTRAN_DIVISION_DUPLEX_MODE_FDD;
+    static const int UTRAN_DIVISION_DUPLEX_MODE_TDD;
+
+    // World mode result cause for EN.
+    static const int WORLD_MODE_RESULT_SUCCESS;
+    static const int WORLD_MODE_RESULT_ERROR;
+    static const int WORLD_MODE_RESULT_WM_ID_NOT_SUPPORT;
+
+    /* bitmask */
+    /* the defination must be sync with ratconfig.c */
+    static const int MASK_CDMA;
+    static const int MASK_LTEFDD;
+    static const int MASK_LTETDD;
+    static const int MASK_WCDMA;
+    static const int MASK_TDSCDMA;
+    static const int MASK_GSM;
+
+private:
+    static int getActiveModemType();
+public:
+    static const int MODEM_FDD;
+    static const int MODEM_TD;
+    static const int MODEM_NO3G;
+public:
+    WorldPhoneUtil();
+    virtual ~WorldPhoneUtil();
+    static bool isWorldPhoneSupport();
+    static bool isLteSupport();
+    static bool isWorldModeSupport();
+    static int get3GDivisionDuplexMode();
+    static int getWorldModeId();
+    static int getModemType();
+
+};
+
+#endif /* SRC_UTIL_WORLDPHONEUTIL_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/log_extra.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/log_extra.h
new file mode 100644
index 0000000..ead0d50
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/log_extra.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef TEL_DEMO_SRC_UTIL_LOG_EXTRA_H_
+#define TEL_DEMO_SRC_UTIL_LOG_EXTRA_H_
+
+/*****************************************************************************
+ * Include
+ *****************************************************************************/
+
+#include <log/log.h>
+
+/*****************************************************************************
+ * Example
+ *****************************************************************************/
+/* Add a debug log with your tag, write it like:
+ * LOG_D(tag, "this is a sample");
+ *
+ * Print a variable, write it like:
+ * LOG_D(tag, "this is a sample %d", variable);
+ *
+ * Print multi-variable, write it like:
+ * LOG_D(tag, "this is a sample %d,%d", variable1, variable2);
+ *
+ * Staple output format
+ * %c  char
+ * %s  char* string
+ * %d  sign decimal
+ * %p  pointer
+ * %x  hex
+ *
+ * Add a debug log with your condition and tag, write it like:
+ * LOG_D_IF(condition, tag, "this is a sample");
+ * When condition is not 0 (this is true), the log will be printed, otherwise, no log printed.
+ *
+ */
+
+/*****************************************************************************
+ * Define
+ *****************************************************************************/
+
+/*
+ * Simplified macro to send a verbose radio log message using the user given tag - _tag.
+ */
+#ifndef LOG_V
+#define __LOG_V(_tag, ...) \
+    ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_VERBOSE, _tag, __VA_ARGS__))
+#if LOG_NDEBUG
+#define LOG_V(_tag, ...) do { if (0) { __LOG_V(_tag, __VA_ARGS__); } } while (0)
+#else
+#define LOG_V(_tag, ...) __LOG_V(_tag, __VA_ARGS__)
+#endif
+#endif
+
+#define CONDITION(cond)     (__builtin_expect((cond) != 0, 0))
+
+#ifndef LOG_V_IF
+#if LOG_NDEBUG
+#define LOG_V_IF(cond, _tag, ...)   ((void)0)
+#else
+#define LOG_V_IF(cond, _tag, ...) \
+    ( (CONDITION(cond)) \
+    ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_VERBOSE, _tag, __VA_ARGS__)) \
+    : (void)0 )
+#endif
+#endif
+
+/*
+ * Simplified macro to send a debug radio log message using the user given tag - _tag.
+ */
+#ifndef LOG_D
+#define LOG_D(_tag, ...) \
+    ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_DEBUG, _tag, __VA_ARGS__))
+#endif
+
+#ifndef LOG_D_IF
+#define LOG_D_IF(cond, _tag, ...) \
+    ( (CONDITION(cond)) \
+    ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_DEBUG, _tag, __VA_ARGS__)) \
+    : (void)0 )
+#endif
+
+/*
+ * Simplified macro to send an info radio log message using the user given tag - _tag.
+ */
+#ifndef LOG_I
+#define LOG_I(_tag, ...) \
+    ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO, _tag, __VA_ARGS__))
+#endif
+
+#ifndef LOG_I_IF
+#define LOG_I_IF(cond, _tag, ...) \
+    ( (CONDITION(cond)) \
+    ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO, _tag, __VA_ARGS__)) \
+    : (void)0 )
+#endif
+
+/*
+ * Simplified macro to send a warning radio log message using the user given tag - _tag.
+ */
+#ifndef LOG_W
+#define LOG_W(_tag, ...) \
+    ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_WARN, _tag, __VA_ARGS__))
+#endif
+
+#ifndef LOG_W_IF
+#define LOG_W_IF(cond, _tag, ...) \
+    ( (CONDITION(cond)) \
+    ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_WARN, _tag, __VA_ARGS__)) \
+    : (void)0 )
+#endif
+
+/*
+ * Simplified macro to send an error radio log message using the user given tag - _tag.
+ */
+#ifndef LOG_E
+#define LOG_E(_tag, ...) \
+    ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_ERROR, _tag, __VA_ARGS__))
+#endif
+
+#ifndef LOG_E_IF
+#define LOG_E_IF(cond, _tag, ...) \
+    ( (CONDITION(cond)) \
+    ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_ERROR, _tag, __VA_ARGS__)) \
+    : (void)0 )
+#endif
+
+#ifndef ASSERT_EX
+#define ASSERT_EX(_expr)                                                         \
+    do {                                                                          \
+        if (!(_expr)) {                                                           \
+            LOG_E("ASSERT_EX", "ASSERT_EX:%s, %d", __FILE__, __LINE__);     \
+            LOG_ALWAYS_FATAL();                                        \
+        }                                                                         \
+    } while(0)
+#endif
+
+
+
+#endif /* TEL_DEMO_SRC_UTIL_LOG_EXTRA_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/utils.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/utils.cpp
new file mode 100644
index 0000000..a430d10
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/utils.cpp
@@ -0,0 +1,316 @@
+ /*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cstdarg>
+#include <cstdio>
+#include <string>
+#include <algorithm>
+#include <cutils/properties.h>
+#include <errno.h>
+#include <inttypes.h>
+
+#include "utils.h"
+#include "log_extra.h"
+
+#undef LOG_TAG
+#define LOG_TAG "DEMO_UTILS"
+
+constexpr int utils::MODEM_UNKNOWN;
+constexpr int utils::MODEM_GSM;
+constexpr int utils::MODEM_TDSCDMA;
+constexpr int utils::MODEM_WCDMA;
+constexpr int utils::MODEM_LTE_TDD;
+constexpr int utils::MODEM_LTE_FDD;
+constexpr int utils::MODEM_CDMA_EVDO;
+constexpr int utils::MODEM_CDMA_1X;
+
+utils::utils() {
+    // TODO Auto-generated constructor stub
+
+}
+
+utils::~utils() {
+    // TODO Auto-generated destructor stub
+}
+
+bool utils::is93Modem() {
+#ifdef MD_93_SUPPORT
+    return true;
+#else
+    return false;
+#endif
+}
+
+bool utils::is90Modem() {
+#ifdef MD_90_SUPPORT
+    return true;
+#else
+    return false;
+#endif
+}
+
+bool utils::isC2KSupport() {
+#ifdef C2K_SUPPORT
+    return true;
+#else
+    return false;
+#endif
+}
+
+
+bool utils::isMt2635() {
+#ifdef TARGET_PLATFORM_MT2635
+    return true;
+#else
+    return false;
+#endif
+}
+
+bool utils::isMt2731(){
+#ifdef TARGET_PLATFORM_MT2731
+    return true;
+#else
+    return false;
+#endif
+}
+
+bool utils::is_support_dsds(){
+#ifdef MODE_DSDS
+    return true;
+#else
+    return false;
+#endif
+}
+
+bool utils::is_suppport_dsss(){
+#ifdef MODE_DSSS
+    return true;
+#else
+    return false;
+#endif
+}
+
+/*
+ * Get property
+ */
+int utils::mtk_property_get(const char *key, char *value, const char *default_value)
+{
+    int ali_pro_res = property_get(key, value, default_value);
+    LOG_D(LOG_TAG, "get key is %s, value is %s, result: %d", key, value, ali_pro_res);
+    return ali_pro_res;
+}
+
+/*
+ * Set property
+ */
+int utils::mtk_property_set(const char *key, const char *value)
+{
+    int ret_val = property_set(key, value);
+    LOG_D(LOG_TAG, "set key is %s, value is %s,result: %d", key, value, ret_val);
+    return ret_val;
+}
+
+bool utils::mtk_property_get_bool(const char *key, bool default_value) {
+    if (!key) {
+        return default_value;
+    }
+
+    bool result = default_value;
+    char buf[PROPERTY_VALUE_MAX] = {'\0',};
+
+    int len = property_get(key, buf, "");
+    if (len == 1) {
+        char ch = buf[0];
+        if (ch == '0' || ch == 'n') {
+            result = false;
+        } else if (ch == '1' || ch == 'y') {
+            result = true;
+        }
+    } else if (len > 1) {
+         if (!strcmp(buf, "no") || !strcmp(buf, "false") || !strcmp(buf, "off")) {
+            result = false;
+        } else if (!strcmp(buf, "yes") || !strcmp(buf, "true") || !strcmp(buf, "on")) {
+            result = true;
+        }
+    }
+
+    return result;
+}
+
+intmax_t utils::property_get_imax(const char *key, intmax_t lower_bound, intmax_t upper_bound,
+        intmax_t default_value) {
+    if (!key) {
+        return default_value;
+    }
+
+    intmax_t result = default_value;
+    char buf[PROPERTY_VALUE_MAX] = {'\0',};
+    char *end = NULL;
+
+    int len = property_get(key, buf, "");
+    if (len > 0) {
+        int tmp = errno;
+        errno = 0;
+
+        // Infer base automatically
+        result = strtoimax(buf, &end, /*base*/0);
+        if ((result == INTMAX_MIN || result == INTMAX_MAX) && errno == ERANGE) {
+            // Over or underflow
+            result = default_value;
+            ALOGV("%s(%s,%" PRIdMAX ") - overflow", __FUNCTION__, key, default_value);
+        } else if (result < lower_bound || result > upper_bound) {
+            // Out of range of requested bounds
+            result = default_value;
+            ALOGV("%s(%s,%" PRIdMAX ") - out of range", __FUNCTION__, key, default_value);
+        } else if (end == buf) {
+            // Numeric conversion failed
+            result = default_value;
+            ALOGV("%s(%s,%" PRIdMAX ") - numeric conversion failed",
+                    __FUNCTION__, key, default_value);
+        }
+
+        errno = tmp;
+    }
+
+    return result;
+}
+
+int64_t utils::mtk_property_get_int64(const char *key, int64_t default_value){
+    return (int64_t)property_get_imax(key, INT64_MIN, INT64_MAX, default_value);
+}
+
+int32_t utils::mtk_property_get_int32(const char *key, int32_t default_value) {
+    return (int32_t)property_get_imax(key, INT32_MIN, INT32_MAX, default_value);
+}
+
+int utils::find_index(std::vector<std::string> v, std::string &str) {
+    auto is_find = std::find(v.begin(), v.end(), str);
+    int index = -1;
+    if(is_find != v.end()) {
+        index = std::distance(v.begin(), is_find);
+        LOG_D(LOG_TAG,"find_index: %d, band: %s", index, str.c_str());
+    }
+    return index;
+}
+
+std::string utils::format(const std::string& format, ...) {
+    va_list args;
+    va_start (args, format);
+    size_t len = std::vsnprintf(NULL, 0, format.c_str(), args);
+    va_end(args);
+    std::vector<char> vec(len + 1);
+    va_start(args, format);
+    std::vsnprintf(&vec[0], len + 1, format.c_str(), args);
+    va_end(args);
+    return &vec[0];
+}
+
+void utils::tokenize(std::string const &str, const char delim, std::vector<std::string> &out){
+    std::stringstream ss(str);
+    std::string s;
+    while(std::getline(ss, s ,delim)) {
+        out.push_back(s);
+    }
+}
+
+void utils::tokenize(std::string const &str, const char* delim, std::vector<std::string> &out){
+    char* token = strtok(const_cast<char*>(str.c_str()), delim);
+    while (token != nullptr) {
+        out.push_back(std::string(token));
+        token = strtok(nullptr, delim);
+    }
+}
+
+void utils::setMSimProperty(int phoneId, char *pPropertyName, char *pUpdateValue) {
+    #define MAX_PHONE_NUM 10
+    #define MIN(a,b) ((a)<(b) ? (a) : (b))
+
+    char oldItemValue[PROPERTY_VALUE_MAX] = {0};
+    char newPropertyValue[PROPERTY_VALUE_MAX] = {0};
+    int i = 0;
+    int strLen = 0;
+
+    for (i = 0; i < MAX_PHONE_NUM; i++) {
+        if (i == phoneId) {
+            // use new value
+            strncat(newPropertyValue, pUpdateValue, PROPERTY_VALUE_MAX - strlen(newPropertyValue));
+        } else {
+            getMSimProperty(i, pPropertyName, oldItemValue);
+            strncat(newPropertyValue, oldItemValue, PROPERTY_VALUE_MAX - strlen(newPropertyValue));
+        }
+        if (i != MAX_PHONE_NUM-1) {
+            strncat(newPropertyValue, ",", 1);
+        }
+        memset(oldItemValue, 0, PROPERTY_VALUE_MAX);
+    }
+    LOG_D(LOG_TAG,"setMSimProperty phoneId=%d, newPropertyValue=%s", phoneId, newPropertyValue);
+    // remove no use ','
+    strLen = strlen(newPropertyValue);
+    for (i = (strLen-1); i >= 0; i--) {
+        if (newPropertyValue[i] == ',') {
+            // remove
+            newPropertyValue[i] = '\0';
+        } else {
+            break;
+        }
+    }
+    LOG_D(LOG_TAG,"newPropertyValue %s\n", newPropertyValue);
+    mtk_property_set(pPropertyName, newPropertyValue);
+}
+
+void utils::getMSimProperty(int phoneId, char *pPropertyName,char *pPropertyValue) {
+    char prop[PROPERTY_VALUE_MAX] = {0};
+    char value[PROPERTY_VALUE_MAX] = {0};
+    int count= 0;
+    int propLen = 0;
+    int i = 0;
+    int j = 0;
+
+    mtk_property_get(pPropertyName, prop, "");
+    LOG_D(LOG_TAG,"getMSimProperty pPropertyName=%s, prop=%s", pPropertyName, prop);
+    propLen = strlen(prop);
+    for (i = 0; i < propLen; i++) {
+        if(prop[i] == ',') {
+            count++;
+            if((count-1) == phoneId) {
+                // return current buffer
+                LOG_D(LOG_TAG,"getMSimProperty found! phoneId=%d, value =%s", phoneId, value);
+                strncpy(pPropertyValue, value, strlen(value));
+                return;
+            } else {
+                // clear current buffer
+                j = 0;
+                memset(value, 0, sizeof(char) * PROPERTY_VALUE_MAX);
+            }
+        } else {
+            value[j] = prop[i];
+            j++;
+        }
+    }
+    if (count == phoneId) {
+        strncpy(pPropertyValue, value, strlen(value));
+        LOG_D(LOG_TAG,"getMSimProperty found at end! phoneId=%d, value =%s", phoneId, value);
+    }
+}
+
+bool utils::is_number(const std::string& s) {
+    std::string::const_iterator it = s.begin();
+    while(it != s.end() && std::isdigit(*it))
+    {
+        ++it;
+    }
+    return !s.empty() && it == s.end();
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/utils.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/utils.h
new file mode 100644
index 0000000..83a46a1
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/utils.h
@@ -0,0 +1,80 @@
+/* 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 MODEMCATEGORY_H_
+#define MODEMCATEGORY_H_
+
+#include <string>
+#include <vector>
+#include <sstream>
+#include <cstring>
+
+class utils {
+public:
+    utils();
+    virtual ~utils();
+    static bool is93Modem();
+    static bool is90Modem();
+    static bool isC2KSupport();
+    static bool isMt2635();
+    static bool isMt2731();
+    static bool is_support_dsds();
+    static bool is_suppport_dsss();
+    static int find_index(std::vector<std::string> v, std::string& str);
+    static std::string format(const std::string& format, ...);
+    static void tokenize(std::string const &str, const char delim, std::vector<std::string> &out);
+    static void tokenize(std::string const &str, const char* delim, std::vector<std::string> &out);
+    static int mtk_property_set(const char *key, const char *value);
+    static int mtk_property_get(const char *key, char *value, const char *default_value);
+    static bool mtk_property_get_bool(const char *key, bool default_value);
+    static int64_t mtk_property_get_int64(const char *key, int64_t default_value);
+    static int32_t mtk_property_get_int32(const char *key, int32_t default_value);
+    static void setMSimProperty(int phoneId, char *pPropertyName, char *pUpdateValue);
+    static void getMSimProperty(int phoneId, char *pPropertyName,char *pPropertyValue);
+    static bool is_number(const std::string& s);
+public:
+    static intmax_t property_get_imax(const char *key, intmax_t lower_bound, intmax_t upper_bound,
+            intmax_t default_value);
+    static constexpr int MODEM_UNKNOWN = 0;
+    static constexpr int MODEM_GSM = 1;
+    static constexpr int MODEM_TDSCDMA = 2;
+    static constexpr int MODEM_WCDMA = 3;
+    static constexpr int MODEM_LTE_TDD = 4;
+    static constexpr int MODEM_LTE_FDD = 5;
+    static constexpr int MODEM_CDMA_EVDO = 6;
+    static constexpr int MODEM_CDMA_1X = 7;
+};
+
+#endif /* MODEMCATEGORY_H_ */