[Feature]add MT2731_MP2_MR2_SVN388 baseline version

Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_bandmode.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_bandmode.cpp
new file mode 100644
index 0000000..8b33c18
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_bandmode.cpp
@@ -0,0 +1,833 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include <pthread.h>
+#include <vendor-ril/telephony/ril.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <cutils/jstring.h>
+#include <log/log.h>
+#include <unistd.h>
+#include <math.h>
+#include <string>
+#include <vector>
+#include <stdint.h>
+#include "ModemCategory.h"
+#include  "common.h"
+#include "em/em.h"
+#include "Radio_capability_switch_util.h"
+#include "../util/utils.h"
+#include "MtkRadioAccessFamily.h"
+
+#if EM_MODE_SUPPORT
+
+#undef LOG_TAG
+#define LOG_TAG "EM_BANDMODE"
+
+static const int WCDMA = 1;
+static const int TDSCDMA = 2;
+
+static const int INDEX_GSM_BAND = 0;
+static const int INDEX_UMTS_BAND = 1;
+static const int INDEX_LTE_FDD_BAND = 2;
+static const int INDEX_LTE_TDD_BAND = 3;
+static const int INDEX_LTE_BAND_96 = 4;
+static const int INDEX_LTE_BAND_128 = 5;
+static const int INDEX_LTE_BAND_160 = 6;
+static const int INDEX_LTE_BAND_192 = 7;
+static const int INDEX_LTE_BAND_224 = 8;
+static const int INDEX_LTE_BAND_256 = 9;
+static const int INDEX_CDMA_BAND = 10;
+static const int INDEX_BAND_MAX = 11;
+static const int BAND_SET_INVALID = 1000;
+static int mSimType = -1;
+
+/** GSM mode bit. */
+static const int GSM_EGSM900_BIT = 1;
+static const int GSM_DCS1800_BIT = 3;
+static const int GSM_PCS1900_BIT = 4;
+static const int GSM_GSM850_BIT = 7;
+static const std::vector<int> GSM_BAND_BIT{GSM_EGSM900_BIT,GSM_DCS1800_BIT,GSM_PCS1900_BIT,GSM_GSM850_BIT};
+
+/** Event or message id. */
+static const int EVENT_QUERY_SUPPORTED = 100;
+static const int EVENT_QUERY_CURRENT = 101;
+static const int EVENT_SET_GSM = 110;
+
+static const int EVENT_SET_FAIL = 1;
+static const int EVENT_RESET = 2;
+
+static const std::uint32_t GSM_MAX_VALUE = UINT8_MAX; //255
+static const std::uint32_t UMTS_MAX_VALUE = UINT16_MAX; //65535;
+static const std::uint32_t LTE_MAX_VALUE = UINT32_MAX;//4294967295
+
+/** AT Command. */
+static const std::string QUERY_SUPPORT_COMMAND = "AT+EPBSE=?";
+static const std::string QUERY_CURRENT_COMMAND = "AT+EPBSE?";
+static const std::string SET_COMMAND = "AT+EPBSE=";
+static const std::string SAME_COMMAND = "+EPBSE:";
+
+
+static const int EVENT_QUERY_CURRENT_CDMA = 103;
+static const int EVENT_SET_CDMA = 111;
+
+static const std::string QUERY_CURRENT_COMMAND_CDMA = "AT+ECBANDCFG?";
+static const std::string SET_COMMAND_CDMA = "AT+ECBANDCFG=";
+static const std::string SAME_COMMAND_CDMA = "+ECBANDCFG:";
+
+static pthread_mutex_t s_band_Mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t s_band_Cond = PTHREAD_COND_INITIALIZER;
+#define BLOCK_LOCK() pthread_mutex_lock(&s_band_Mutex)
+#define BLOCK_UNLOCK() pthread_mutex_unlock(&s_band_Mutex)
+#define BLOCK_WAIT() pthread_cond_wait(&s_band_Cond, &s_band_Mutex)
+#define BLOCK_WAKEUP() pthread_cond_broadcast(&s_band_Cond)
+
+bool mIsLteExtend = false;
+int mCurrentEmbandmodeFlag = 0;
+std::vector<long> gsmValues(INDEX_BAND_MAX);
+long cdmaValues = 0;
+
+struct BandModeMap{
+    std::string mName;
+    int mIndex;
+    int mBit;
+    bool mEnable;
+    bool mCheck;
+    BandModeMap(std::string name, int index, int bit ,bool enable, bool check)
+    : mName(name), mIndex(index), mBit(bit), mEnable(enable), mCheck(check) {
+
+    }
+    BandModeMap(BandModeMap&& other): mName(std::move(other.mName)),
+            mIndex(std::move(other.mIndex)),
+            mBit(std::move(other.mBit)),
+            mEnable(std::move(other.mEnable)),
+            mCheck(std::move(other.mCheck)) {
+
+    }
+    BandModeMap& operator=(const BandModeMap& other) = default;
+};
+
+static std::vector<BandModeMap> mModeArray;
+static std::vector<BandModeMap> mCdmaModeArray;
+static const std::vector<std::string> band_mode_gsm { "EGSM900", "DCS1800",
+        "PCS1900", "GSM850" };
+
+static const std::vector<std::string> band_mode_wcdma { "WCDMA-IMT-2000",
+        "WCDMA-PCS-1900", "WCDMA-DCS-1800", "WCDMA-AWS-1700", "WCDMA-CLR-850",
+        "WCDMA-800", "WCDMA-IMT-E-2600", "WCDMA-GSM-900", "WCDMA-1800",
+        "WCDMA-1700" };
+
+static const std::vector<std::string> band_mode_tdscdma { "TD_SCDMA Band A",
+        "TD_SCDMA Band B", "TD_SCDMA Band C", "TD_SCDMA Band D",
+        "TD_SCDMA Band E", "TD_SCDMA Band F" };
+
+static const std::vector<std::string> band_mode_lte_fdd { "Band 1", "Band 2",
+        "Band 3", "Band 4", "Band 5", "Band 6", "Band 7", "Band 8", "Band 9",
+        "Band 10", "Band 11", "Band 12", "Band 13", "Band 14", "Band 15",
+        "Band 16", "Band 17", "Band 18", "Band 19", "Band 20", "Band 21",
+        "Band 22", "Band 23", "Band 24", "Band 25", "Band 26", "Band 27",
+        "Band 28", "Band 29", "Band 30", "Band 31", "Band 32" };
+
+static const std::vector<std::string> band_mode_lte_tdd { "Band 33", "Band 34",
+        "Band 35", "Band 36", "Band 37", "Band 38", "Band 39", "Band 40",
+        "Band 41", "Band 42", "Band 43", "Band 44" };
+
+static const std::vector<std::string> band_mode_lte_96 { "Band 65", "Band 66",
+        "Band 67", "Band 68", "Band 69", "Band 70", "Band 71", "Band 72",
+        "Band 73", "Band 74", "Band 75", "Band 76", "Band 77", "Band 78",
+        "Band 79", "Band 80", "Band 81", "Band 82", "Band 83", "Band 84",
+        "Band 85", "Band 86", "Band 87", "Band 88", "Band 89", "Band 90",
+        "Band 91", "Band 92", "Band 93", "Band 94", "Band 95", "Band 96" };
+
+static const std::vector<std::string> band_mode_lte_128 { "Band 97", "Band 98",
+        "Band 99", "Band 100", "Band 101", "Band 102", "Band 103", "Band 104",
+        "Band 105", "Band 106", "Band 107", "Band 108", "Band 109", "Band 110",
+        "Band 111", "Band 112", "Band 113", "Band 114", "Band 115", "Band 116",
+        "Band 117", "Band 118", "Band 119", "Band 120", "Band 121", "Band 122",
+        "Band 123", "Band 124", "Band 125", "Band 126", "Band 127", "Band 128" };
+
+static const std::vector<std::string> band_mode_lte_160 { "Band 129",
+        "Band 130", "Band 131", "Band 132", "Band 133", "Band 134", "Band 135",
+        "Band 136", "Band 137", "Band 138", "Band 139", "Band 140", "Band 141",
+        "Band 142", "Band 143", "Band 144", "Band 145", "Band 146", "Band 147",
+        "Band 148", "Band 149", "Band 150", "Band 151", "Band 152", "Band 153",
+        "Band 154", "Band 155", "Band 156", "Band 157", "Band 158", "Band 159",
+        "Band 160" };
+
+static const std::vector<std::string> band_mode_lte_192 { "Band 161",
+        "Band 162", "Band 163", "Band 164", "Band 165", "Band 166", "Band 167",
+        "Band 168", "Band 169", "Band 170", "Band 171", "Band 172", "Band 173",
+        "Band 174", "Band 175", "Band 176", "Band 177", "Band 178", "Band 179",
+        "Band 180", "Band 181", "Band 182", "Band 183", "Band 184", "Band 185",
+        "Band 186", "Band 187", "Band 188", "Band 189", "Band 190", "Band 191",
+        "Band 192" };
+
+static const std::vector<std::string> band_mode_lte_224 { "Band 193",
+        "Band 194", "Band 195", "Band 196", "Band 197", "Band 198", "Band 199",
+        "Band 200", "Band 201", "Band 202", "Band 203", "Band 204", "Band 205",
+        "Band 206", "Band 207", "Band 208", "Band 209", "Band 210", "Band 211",
+        "Band 212", "Band 213", "Band 214", "Band 215", "Band 216", "Band 217",
+        "Band 218", "Band 219", "Band 220", "Band 221", "Band 222", "Band 223",
+        "Band 224" };
+
+static const std::vector<std::string> band_mode_lte_256 { "Band 225",
+        "Band 226", "Band 227", "Band 228", "Band 229", "Band 230", "Band 231",
+        "Band 232", "Band 233", "Band 234", "Band 235", "Band 236", "Band 237",
+        "Band 238", "Band 239", "Band 240", "Band 241", "Band 242", "Band 243",
+        "Band 244", "Band 245", "Band 246", "Band 247", "Band 248", "Band 249",
+        "Band 250", "Band 251", "Band 252", "Band 253", "Band 254", "Band 255",
+        "Band 256" };
+
+static const std::vector<std::string> band_mode_cdma {
+        "Band 0(North American Celluar Band)",
+        "Band 1(North American PCS band)", "Band 2(TACS band)",
+        "Band 3(JTACS band)", "Band 4(Korean PCS band)", "Band 5(NMT-450 Band)",
+        "Band 6(IMT-2000 band)", "Band 7(North American 700Mhz Celluar Band)",
+        "Band 8(1800-MHz Band)", "Band 9(900-MHz Band)",
+        "Band 10(Secondary 800 MHz Band)", "Band 11(400 MHz European PAMR Band",
+        "Band 12(800 MHz PAMR Band)",
+        "Band 13(2.5 GHz IMT-2000 Extension Band)",
+        "Band 14(US PCS 1.9GHz Band)", "Band 15(AWS Band)" };
+
+int fgset = false;
+int count = -1;
+std::vector<std::string> choose_vals;
+
+static void sendATCommand(const char *cmd,int msg)
+{
+    BLOCK_LOCK();
+    mCurrentEmbandmodeFlag = msg;
+    emSendATCommand(cmd,mSimType);
+    RLOGD("sendATCommand: wait start");
+    BLOCK_WAIT();
+    RLOGD("sendATCommand: wait end");
+    BLOCK_UNLOCK();
+    return ;
+}
+
+static void setCurrentMode(std::vector<long> values) {
+    for (auto& m : mModeArray) {
+        if ((values[m.mIndex] & (1L << m.mBit)) == 0) {
+            m.mCheck = false;
+        } else {
+            if (m.mEnable) {
+                m.mCheck = true;
+            }
+        }
+        //RLOGD("setCurrentMode labels: %s, enable: %d, check: %d", m.mName.c_str(), m.mEnable, m.mCheck);
+    }
+}
+
+static void setSupportedMode(std::vector<long> values) {
+    for (auto& m : mModeArray) {
+        if ((values[m.mIndex] & (1L << m.mBit)) == 0) {
+            m.mEnable = false;
+        } else {
+            m.mEnable = true;
+        }
+        //RLOGD("setSupportedMode labels: %s, enable: %d", m.mName.c_str(), m.mEnable);
+    }
+}
+
+static void setCurrentModeCdma(const long value) {
+    RLOGD("setCurrentModeCdma: %ld", value);
+    for (auto& m : mCdmaModeArray) {
+        if ((value & (1L << m.mBit)) == 0) {
+            m.mCheck = false;
+        } else {
+            if (m.mEnable) {
+                m.mCheck = true;
+            }
+        }
+        RLOGD("setCurrentModeCdma labels: %s, enable: %d, check: %d", m.mName.c_str(), m.mEnable, m.mCheck);
+    }
+
+}
+
+static void setSupportedModeCdma(const long value) {
+    RLOGD("setSupportedModeCdma: %ld", value);
+    for (auto& m : mCdmaModeArray) {
+        if ((value & (1L << m.mBit)) == 0) {
+            m.mEnable = false;
+        } else {
+            m.mEnable = true;
+        }
+        RLOGD("setSupportedModeCdma labels: %s, enable: %d", m.mName.c_str(), m.mEnable);
+    }
+}
+
+static void showBandModeCdma(char* response, int msg) {
+    std::vector<std::string> out;
+    utils::tokenize(string(response), "\n", out);
+    for(auto i: out) {
+        if(i.find(SAME_COMMAND_CDMA) != std::string::npos) {
+            std::string splitString = i.substr(std::string(SAME_COMMAND_CDMA).size());
+            RLOGD("showBandModeCdma splitString: %s", splitString.c_str());
+            if (msg == EVENT_QUERY_CURRENT_CDMA) {
+                std::vector<std::string> getDigitalVal;
+                utils::tokenize(string(splitString), ",\n", getDigitalVal);
+                std::vector<long> values;
+                try {
+                    for(auto str: getDigitalVal) {
+                        if(str.empty() || str == "\n") {
+                            continue;
+                        }
+                        long v = std::stol(str, 0 ,0);
+                        values.push_back(v);
+                    }
+                } catch (const out_of_range &e) {
+                    RLOGD("out of range: %s", e.what());
+                } catch (const invalid_argument &e) {
+                    RLOGD("invalid argument: %s", e.what());
+                }
+                if(values.size() < 2) {
+                    RLOGD("showBandModeCdma size < 2");
+                    android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+                    return;
+                }
+                setSupportedModeCdma(values[0]);
+                setCurrentModeCdma(values[1]);
+            }
+        }
+    }
+}
+
+static void showBandModeGsm(char* response, int msg) {
+    std::vector<std::string> out;
+    utils::tokenize(string(response), "\n", out);
+    for(auto i: out) {
+        if(i.find(SAME_COMMAND) != std::string::npos) {
+            std::string splitString = i.substr(std::string(SAME_COMMAND).size());
+            RLOGD("showBandModeGsm splitString: %s", splitString.c_str());
+            std::vector<std::string> getDigitalVal;
+            utils::tokenize(string(splitString), ",\n", getDigitalVal);
+            if (getDigitalVal.size() > 0) {
+                std::vector<long> values;
+                for (int i = 0; i < INDEX_BAND_MAX; i++) {
+                    if (getDigitalVal.size() <= i) {
+                        values.push_back(0);
+                        continue;
+                    }
+                    try {
+                        values.push_back(std::stol(getDigitalVal[i], 0 ,0));
+                    } catch (const out_of_range &e) {
+                        values.push_back(0);
+                        RLOGD("out of range: %s", e.what());
+                    } catch (const invalid_argument &e) {
+                        values.push_back(0);
+                        RLOGD("invalid argument: %s", e.what());
+                    }
+                }
+                if (msg == EVENT_QUERY_SUPPORTED) {
+                    setSupportedMode(values);
+                    if (getDigitalVal.size() > 5) {
+                        RLOGD("The Modem support Lte extend band");
+                        mIsLteExtend = true;
+                    } else {
+                        RLOGD("The Modem not support Lte extend band");
+                        mIsLteExtend = false;
+                    }
+                } else {
+                    setCurrentMode(values);
+                }
+            } else {
+                android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+                RLOGD("getDigitalVal is null");
+            }
+        }
+    }
+}
+
+static void printGetBand(int flag) {
+    RLOGD("printGetBand(%d), fgset(%d)", flag, fgset);
+    if(fgset) {
+        return;
+    }
+    if(flag == EVENT_QUERY_CURRENT) {
+        RLOGD("printGetBand start");
+        std::string msg;
+        for (auto& i : mModeArray) {
+            if (i.mEnable && i.mCheck) {
+                if ((i.mIndex == INDEX_GSM_BAND) && (msg.find("GSM Mode:") == std::string::npos)) {
+                    msg.append("GSM Mode:\n");
+                } else if ((i.mIndex == INDEX_UMTS_BAND) && (msg.find("UMTS Mode:") == std::string::npos)) {
+                    msg.append("\nUMTS Mode:\n");
+                } else if ((i.mIndex >= INDEX_LTE_FDD_BAND) && (i.mIndex <= INDEX_LTE_BAND_256) && (msg.find("LTE Mode:") == std::string::npos)) {
+                    msg.append("\nLTE Mode:\n");
+                }
+
+                msg.append("....");
+                msg.append(i.mName);
+                msg.append("\n");
+            }
+        }
+        for (auto& i : mCdmaModeArray) {
+            if (i.mEnable && i.mCheck) {
+                if ((i.mIndex == INDEX_CDMA_BAND) && (msg.find("CDMA Mode:") == std::string::npos)) {
+                    msg.append("\nCDMA Mode: \n");
+                }
+                msg.append("....");
+                msg.append(i.mName);
+                msg.append("\n");
+            }
+        }
+        msg.append("done\n");
+        android::emResultNotify(msg.c_str());
+    }
+}
+
+static void setBandModeCdma(const long value) {
+    RLOGD("setCdmaBandMode: %d", value);
+    string msg = SET_COMMAND_CDMA + std::to_string(value);
+    sendATCommand(msg.c_str(), EVENT_SET_CDMA);
+}
+
+/**
+ * Set the selected modes.
+ *
+ * @param values the integers of mode values
+ * @return false means set failed or success
+ */
+static void setBandMode(std::vector<long> values) {
+    RLOGD("setBandMode values: %ld,%ld,%ld,%ld", values[0],values[1],values[2],values[3]);
+    if (values[0] > GSM_MAX_VALUE
+            || values[1] > UMTS_MAX_VALUE
+            || values[2] > LTE_MAX_VALUE
+            || values[3] > LTE_MAX_VALUE) {
+        android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+        RLOGD("setBandMode,just return");
+        return;
+    }
+
+    std::vector<std::string> modeString {SET_COMMAND + std::to_string(values[0]) + std::string(",") + std::to_string(values[1]), ""};
+    if (ModemCategory::isLteSupport()) {
+        modeString[0] += std::string(",") + std::to_string(values[2]) + std::string(",") + std::to_string(values[3]);
+        if (mIsLteExtend) {
+            for (int i = 4; i < INDEX_BAND_MAX - 1; i++) {
+                modeString[0] += std::string(",") + std::to_string(values[i]);
+            }
+        }
+    }
+    RLOGD("setGsmBandMode AT String: %s", modeString[0].c_str());
+    sendATCommand(modeString[0].c_str(), EVENT_SET_GSM);
+}
+
+static long getValFromBoxCdma() {
+    long value = 0;
+    for (auto& m : mCdmaModeArray) {
+        if (m.mCheck) {
+            value |= 1L << m.mBit;
+        }
+    }
+    return value;
+}
+
+/**
+ * Get the selected mode values.
+ *
+ * @return values from the selected boxes
+ */
+static std::vector<long> getValFromBox(bool judge) {
+    std::vector<long> values(INDEX_BAND_MAX,0);
+    std::vector<long> values_temp(INDEX_BAND_MAX,0);
+    for (auto& m : mModeArray) {
+        if (m.mCheck) {
+            values[m.mIndex] |= 1L << m.mBit;
+            values_temp[m.mIndex] |= 1L << m.mBit;
+        }
+    }
+
+    if (judge) {
+        // band64 to band256 belongs to lte fdd, so check null together
+        for (int i = INDEX_LTE_BAND_96; i <= INDEX_LTE_BAND_256; i++) {
+            values_temp[INDEX_LTE_FDD_BAND] = values_temp[INDEX_LTE_FDD_BAND] | values_temp[i];
+        }
+        // check FDD and TDD ,only all null is invalid
+        values_temp[INDEX_LTE_FDD_BAND] = values_temp[INDEX_LTE_FDD_BAND] | values_temp[INDEX_LTE_TDD_BAND];
+        values_temp[INDEX_LTE_TDD_BAND] = values_temp[INDEX_LTE_FDD_BAND];
+
+        // null select is not allowed.
+        if (values[0] == 0) {
+            values[0] = GSM_MAX_VALUE;
+        }
+        if (values[1] == 0) {
+            values[1] = UMTS_MAX_VALUE;
+        }
+        if (values_temp[2] == 0 && values_temp[3] == 0) {
+            values[2] = LTE_MAX_VALUE;
+            values[3] = LTE_MAX_VALUE;
+            RLOGD("lte not to null");
+        }
+    }
+    return values;
+}
+
+static void printSupportBand(int flag) {
+    RLOGD("printSupportBand, fgset(%d), count(%d), flag(%d)",fgset, count, flag);
+    if(fgset && (count == 0) && (flag == EVENT_QUERY_CURRENT)) {
+        RLOGD("printSupportBand start");
+        std::string msg;
+        for (auto& i : mModeArray) {
+            if (i.mEnable) {
+                if ((i.mIndex == INDEX_GSM_BAND) && (msg.find("GSM Mode:") == std::string::npos)) {
+                    msg.append("GSM Mode:\n");
+                } else if ((i.mIndex == INDEX_UMTS_BAND) && (msg.find("UMTS Mode:") == std::string::npos)) {
+                    msg.append("\nUMTS Mode:\n");
+                } else if ((i.mIndex >= INDEX_LTE_FDD_BAND) && (i.mIndex <= INDEX_LTE_BAND_256) && (msg.find("LTE Mode:") == std::string::npos)) {
+                    msg.append("\nLTE Mode:\n");
+                }
+
+                msg.append("....");
+                msg.append("(");
+                msg.append(std::to_string(i.mIndex));
+                msg.append(".");
+                msg.append(std::to_string(i.mBit));
+                msg.append("): ");
+                msg.append(i.mName);
+                msg.append("....");
+                msg.append(i.mCheck ? "true":"false");
+                msg.append("\n");
+            }
+        }
+        for (auto& i : mCdmaModeArray) {
+            if (i.mEnable) {
+                if ((i.mIndex == INDEX_CDMA_BAND) && (msg.find("CDMA Mode:") == std::string::npos)) {
+                    msg.append("\nCDMA Mode: \n");
+                }
+                msg.append("....");
+                msg.append("(");
+                msg.append(std::to_string(i.mIndex));
+                msg.append(".");
+                msg.append(std::to_string(i.mBit));
+                msg.append("): ");
+                msg.append(i.mName);
+                msg.append("....");
+                msg.append(i.mIndex ? "true":"false");
+                msg.append("\n");
+            }
+        }
+        msg.append("done\n");
+        android::emResultNotify(msg.c_str());
+    }
+}
+
+static void* setGsmBandMode(void* arg) {
+    setBandMode(gsmValues);
+    return NULL;
+}
+
+static void* setCdmaBandMode(void* arg) {
+    setBandModeCdma(cdmaValues);
+    return NULL;
+}
+
+static void emBandmodeAtCmdHandle(char* response, int responselen) {
+    RLOGD("emBandmodeAtCmdHandle, flag=%d, data=%s", mCurrentEmbandmodeFlag, response);
+    switch (mCurrentEmbandmodeFlag) {
+    case EVENT_QUERY_CURRENT_CDMA: {
+        if ((responselen > 0) && (response != NULL)) {
+            showBandModeCdma(response, EVENT_QUERY_CURRENT_CDMA);
+        } else {
+            android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+            RLOGD("don't support(%d)", EVENT_QUERY_CURRENT_CDMA);
+        }
+        BLOCK_WAKEUP();
+        break;
+    }
+    case EVENT_QUERY_SUPPORTED:
+    {
+        if ((responselen > 0) && (response != NULL)) {
+            showBandModeGsm(response, EVENT_QUERY_SUPPORTED);
+        } else {
+            android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+            RLOGD("don't support(%d)", EVENT_QUERY_SUPPORTED);
+        }
+        BLOCK_WAKEUP();
+        break;
+    }
+    case EVENT_QUERY_CURRENT:
+    {
+        if ((responselen > 0) && (response != NULL)) {
+            showBandModeGsm(response, EVENT_QUERY_CURRENT);
+        } else {
+            android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+            RLOGD("don't support(%d)", EVENT_QUERY_CURRENT);
+        }
+        printGetBand(EVENT_QUERY_CURRENT);
+        printSupportBand(EVENT_QUERY_CURRENT);
+        BLOCK_WAKEUP();
+        if(fgset && (count > 0)) {
+            for(auto& val : choose_vals) {
+                RLOGD("handle values: %s", val.c_str());
+                std::vector<std::string> out;
+                utils::tokenize(val, "=", out);
+                if(out.size() == 2) {
+                    std::vector<std::string> indexs;
+                    utils::tokenize(out[0], ".", indexs);
+                    if(indexs.size() == 2) {
+                        try {
+                            int index = std::stoi(indexs[0]);
+                            int bit = std::stoi(indexs[1]);
+                            bool check = std::stoi(out[1]) > 0 ? true : false;
+                            for (auto& i : mModeArray) {
+                                if((i.mIndex == index) && (i.mBit == bit)) {
+                                    i.mCheck = check;
+                                    RLOGD("set gsm band: lales=%s, index=%d, bit=%d, enable=%d, check=%d",
+                                            i.mName.c_str(),i.mIndex, i.mBit, i.mEnable, i.mCheck);
+                                }
+                            }
+                            for (auto& i : mCdmaModeArray) {
+                                if((i.mIndex == index) && (i.mBit == bit)) {
+                                    if((i.mIndex == index) && (i.mBit == bit)) {
+                                        i.mCheck = check;
+                                        RLOGD("set gsm band: lales=%s, index=%d, bit=%d, enable=%d, check=%d",
+                                                i.mName.c_str(),i.mIndex, i.mBit, i.mEnable, i.mCheck);
+                                    }
+                                }
+                            }
+                        } catch (const out_of_range &e) {
+                            RLOGD("out of range: %s", e.what());
+                        } catch (const invalid_argument &e) {
+                            RLOGD("invalid argument: %s", e.what());
+                        }
+                    }else {
+                        RLOGD("invalid parameters: %s", out[0].c_str());
+                        android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+                        return;
+                    }
+
+                } else {
+                    RLOGD("invalid parameters: %s", val.c_str());
+                    android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+                    return;
+                }
+            }
+            cdmaValues = getValFromBoxCdma();
+            gsmValues = getValFromBox(true);
+            pthread_t setBandMode_thread;
+            pthread_create(&setBandMode_thread,NULL, setGsmBandMode, NULL);
+        }
+        break;
+    }
+    case EVENT_SET_GSM:
+    {
+        BLOCK_WAKEUP();
+        if ((responselen > 0) && (response != NULL)) {
+            RLOGD("Set Gsm bandmode success: %s", response);
+            if ((mSimType == 0) && ModemCategory::isCdma() && (!utils::is90Modem())) {
+                pthread_t setBandMode_thread;
+                pthread_create(&setBandMode_thread,NULL, setCdmaBandMode, NULL);
+            } else {
+                RLOGD("don't support cdma, response");
+                android::emResultNotify(RET_STRING_BANDMODE_SUCCESS);
+            }
+        } else {
+            RLOGD("send gsm fail ");
+            android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+        }
+        break;
+    }
+    case EVENT_SET_CDMA:
+    {
+        BLOCK_WAKEUP();
+        if ((responselen > 0) && (response != NULL)) {
+            RLOGD("Set cdma bandmode success: %s", response);
+            android::emResultNotify(RET_STRING_BANDMODE_SUCCESS);
+        } else {
+            RLOGD("send cdma fail ");
+            android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+        }
+        break;
+    }
+    default:
+        break;
+    }
+}
+
+static void queryCurrentCdmaMode() {
+    if (utils::is93Modem()) {
+        //SAME_COMMAND_CDMA;
+        RLOGD("queryCurrentCdmaMode: %s", QUERY_CURRENT_COMMAND_CDMA.c_str());
+        sendATCommand(QUERY_CURRENT_COMMAND_CDMA.c_str(), EVENT_QUERY_CURRENT_CDMA);
+    } else {
+        android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+        RLOGD("don't support");
+    }
+}
+
+/**
+ * Query Modem supported band modes.
+ */
+static void querySupportMode() {
+    //SAME_COMMAND
+    RLOGD("querySupportMode AT String: %s", QUERY_SUPPORT_COMMAND.c_str());
+    sendATCommand(QUERY_SUPPORT_COMMAND.c_str(), EVENT_QUERY_SUPPORTED);
+}
+
+/**
+ * Query Modem is being used band modes.
+ */
+static void queryCurrentMode() {
+    //SAME_COMMAND
+    RLOGD("queryCurrentMode AT String: %s", QUERY_CURRENT_COMMAND.c_str());
+    sendATCommand(QUERY_CURRENT_COMMAND.c_str(), EVENT_QUERY_CURRENT);
+}
+
+static void initGsmArray() {
+    for (int i = 0; i < band_mode_gsm.size(); i++) {
+        mModeArray.emplace_back(band_mode_gsm[i], INDEX_GSM_BAND, GSM_BAND_BIT[i], false, false);
+    }
+}
+
+static void initLteArray() {
+    for (int i = 0; i < band_mode_lte_fdd.size(); i++) {
+        mModeArray.emplace_back(band_mode_lte_fdd[i], INDEX_LTE_FDD_BAND, i, false, false);
+    }
+    for (int i = 0; i < band_mode_lte_tdd.size(); i++) {
+        mModeArray.emplace_back(band_mode_lte_tdd[i], INDEX_LTE_TDD_BAND, i, false, false);
+    }
+    for (int i = 0; i < band_mode_lte_96.size(); i++) {
+        mModeArray.emplace_back(band_mode_lte_96[i], INDEX_LTE_BAND_96, i, false, false);
+    }
+    for (int i = 0; i < band_mode_lte_128.size(); i++) {
+        mModeArray.emplace_back(band_mode_lte_128[i], INDEX_LTE_BAND_128, i, false, false);
+    }
+    for (int i = 0; i < band_mode_lte_160.size(); i++) {
+        mModeArray.emplace_back(band_mode_lte_160[i], INDEX_LTE_BAND_160, i, false, false);
+    }
+    for (int i = 0; i < band_mode_lte_192.size(); i++) {
+        mModeArray.emplace_back(band_mode_lte_192[i], INDEX_LTE_BAND_192, i, false, false);
+    }
+    for (int i = 0; i < band_mode_lte_224.size(); i++) {
+        mModeArray.emplace_back(band_mode_lte_224[i], INDEX_LTE_BAND_224, i, false, false);
+    }
+    for (int i = 0; i < band_mode_lte_256.size(); i++) {
+        mModeArray.emplace_back(band_mode_lte_256[i], INDEX_LTE_BAND_256, i, false, false);
+    }
+}
+
+static void initTdscdmaArray() {
+    for (int i = 0; i < band_mode_tdscdma.size(); i++) {
+        mModeArray.emplace_back(band_mode_tdscdma[i], INDEX_UMTS_BAND, i, false, false);
+    }
+}
+
+static void initWcdmaArray() {
+    for (int i = 0; i < band_mode_wcdma.size(); i++) {
+        mModeArray.emplace_back(band_mode_wcdma[i], INDEX_UMTS_BAND, i, false, false);
+    }
+}
+
+static void initCdmaArray() {
+    for (int i = 0; i < band_mode_cdma.size(); i++) {
+        mCdmaModeArray.emplace_back(band_mode_cdma[i], INDEX_CDMA_BAND, i, false, false);
+    }
+}
+
+static void * emBandmodeThread(void* arg)
+{
+    mModeArray.clear();
+    mCdmaModeArray.clear();
+    initGsmArray();
+    int modemType = ModemCategory::getModemType();
+    if (modemType == TDSCDMA && ModemCategory::isCapabilitySim(mSimType)) {
+        initTdscdmaArray();
+        if (ModemCategory::isLteSupport()) {
+            initLteArray();
+        }
+    } else if (modemType == WCDMA && ModemCategory::isCapabilitySim(mSimType)) {
+        initWcdmaArray();
+        if (ModemCategory::isLteSupport()) {
+            initLteArray();
+        }
+    } else if (!(ModemCategory::isCapabilitySim(mSimType))) {
+        if (ModemCategory::checkViceSimCapability(mSimType, MtkRadioAccessFamily::RAF_UMTS)) {
+            initWcdmaArray();
+        }
+        if (ModemCategory::checkViceSimCapability(mSimType, MtkRadioAccessFamily::RAF_LTE)) {
+            if (ModemCategory::isLteSupport()) {
+                initLteArray();
+            }
+        }
+    }
+
+    if (mSimType == 0 && ModemCategory::isCdma() && !utils::is90Modem()) {
+        initCdmaArray();
+    }
+    if (ModemCategory::isCdma() && !utils::is90Modem() && (mSimType == 0)) {
+        queryCurrentCdmaMode();
+    }
+    querySupportMode();
+    queryCurrentMode();
+    pthread_exit(0);
+}
+
+//AT+EPBSE=gsm,umts,ltefdd,ltetdd
+int emBandmodeStart(int len,int *item,int multilen,char *value[])
+{
+    mSimType = get_default_sim_all_except_data();
+    RLOGD("emBandmodeStart called : simType:%d", mSimType);
+    //1. reset to default: select all supported bands: AT+EPBSE=255,63355
+    if(len < 1)
+    {
+        RLOGD("emBandmodeStart: please select mode to test: 0: get, 1: set ");
+        android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+        return -1;
+    }
+    if((item[0] > 1 ) || (item[0] < 0)){
+        RLOGD("emBandmodeStart: invalid parameter %d",item[0]);
+        android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+        return -1;
+    }
+    if(item[0] == 0){
+        fgset = false;
+    }else{
+        fgset = true;
+        count = multilen;
+        RLOGD("emBandmodeStart count = %d", count);
+        choose_vals.clear();
+        if(count > 0){
+            for(int i=0; i< count; i++) {
+                choose_vals.push_back(value[i]);
+            }
+        }
+    }
+    mCurrentEmbandmodeFlag = 0;
+    android::registerForATcmdResponse(emBandmodeAtCmdHandle);
+    pthread_t embandmode_thread;
+    pthread_create(&embandmode_thread,NULL, emBandmodeThread, NULL);
+    return (0);
+}
+#endif
+