[merged]
1.MT2735_MP1_MR1.0 merged,without MR1.0-dpramk

Change-Id: I652723435ec940ee8c0b9bc6ff2d6e80557a0429
diff --git a/framework/lynq-ril-service/src/Ril_responsedispatch.cpp b/framework/lynq-ril-service/src/Ril_responsedispatch.cpp
index 1f54405..ad253c9 100755
--- a/framework/lynq-ril-service/src/Ril_responsedispatch.cpp
+++ b/framework/lynq-ril-service/src/Ril_responsedispatch.cpp
@@ -1,3 +1,4 @@
+//SPDX-License-Identifier: MediaTekProprietary
 /* Copyright Statement:
  *
  * This software/firmware and related documentation ("MediaTek Software") are
diff --git a/framework/lynq-ril-service/src/atci/ATCI.cpp b/framework/lynq-ril-service/src/atci/ATCI.cpp
old mode 100755
new mode 100644
index af29d33..16f38df
--- a/framework/lynq-ril-service/src/atci/ATCI.cpp
+++ b/framework/lynq-ril-service/src/atci/ATCI.cpp
@@ -1,3 +1,4 @@
+//SPDX-License-Identifier: MediaTekProprietary
 /* Copyright Statement:
  *
  * This software/firmware and related documentation ("MediaTek Software") are
diff --git a/framework/lynq-ril-service/src/cc.cpp b/framework/lynq-ril-service/src/cc.cpp
index 369bd2f..f212ff7 100755
--- a/framework/lynq-ril-service/src/cc.cpp
+++ b/framework/lynq-ril-service/src/cc.cpp
@@ -1,3 +1,4 @@
+//SPDX-License-Identifier: MediaTekProprietary
 /* Copyright Statement:
  *
  * This software/firmware and related documentation ("MediaTek Software") are
@@ -245,7 +246,7 @@
     } else {
         vol_value = get_mixer_ctrl_volume_value(g_mixer_name_volume_bt);
     }
-    RLOGD("The ctrl \"%s\" is set to %d", g_mixer_name_volume, vol_value);
+    RLOGD("The ctrl \"%s\" is set to %ld", g_mixer_name_volume, vol_value);
     return vol_value;
 }
 
@@ -1164,10 +1165,10 @@
     /* DL:0 UL:1 */
     if (path == 0) {
         is_mute = get_mixer_ctrl_value_int(g_DL_mute_name);
-        RLOGD("The ctrl \"%s\" is set to %d", g_DL_mute_name, is_mute);
+        RLOGD("The ctrl \"%s\" is set to %ld", g_DL_mute_name, is_mute);
     } else {
         is_mute = get_mixer_ctrl_value_int(g_UL_mute_name);
-        RLOGD("The ctrl \"%s\" is set to %d", g_UL_mute_name, is_mute);
+        RLOGD("The ctrl \"%s\" is set to %ld", g_UL_mute_name, is_mute);
     }
 
     return is_mute;
@@ -1180,7 +1181,7 @@
 
 int getCallMute() {
     long int cc_mute = mixer_get_mute(1);
-    RLOGD("getCallMute: %d", cc_mute);
+    RLOGD("getCallMute: %ld", cc_mute);
     return cc_mute;
 }
 
@@ -1236,6 +1237,7 @@
         StopRecord();
         sendCallMsg(false); // for Power Manager test.
         dtmf_stop(dtmf_handle);
+        dtmf_handle = NULL;
         if (speechStatus == NORMAL_SPEECH_ON) {
             mixer_set(0);
         } else {
@@ -1353,7 +1355,7 @@
 
     if ((std::stoi(dir) == 1) && (std::stoi(sip_msg_type) == 0)
             && (std::stoi(method) == 4) && (std::stoi(resp_code) == 0)) {
-        std::string msg("SIP CANCEL:");
+        std::string msg("SIP CANCEL:");
         msg.append(reason_text);
         printf("%s", msg.c_str());
     }
@@ -1382,7 +1384,7 @@
         numStrings = responselen / sizeof(char *);
         RLOGD("[slot%d]handleUnsolCallInfoInd: numStrings: %d",socket_id, numStrings);
         if(numStrings < 9) {
-            RLOGE("[slot%d]handleUnsolCallInfoInd, invalid numStrings(%d) < 9, no pau value : numStrings", socket_id);
+            RLOGE("[slot%d]handleUnsolCallInfoInd, invalid numStrings < 9, no pau value : numStrings", socket_id);
             return -1;
         } else {
             RLOGD("[slot%d]handleUnsolCallInfoInd(): pau: %s", socket_id, p_cur[8]);
@@ -1420,7 +1422,7 @@
     numInts = responselen / sizeof(int);
     RLOGD("[slot%d]handleRingbackTone: numInts: %d",socket_id, numInts);
     if(numInts < 1) {
-        RLOGE("[slot%d]handleRingbackTone, invalid numStrings(%d) < 1", socket_id);
+        RLOGE("[slot%d]handleRingbackTone, invalid numStrings < 1", socket_id);
         return -1;
     } else {
         int start = p_int[0];
diff --git a/framework/lynq-ril-service/src/common.cpp b/framework/lynq-ril-service/src/common.cpp
index e385e1c..37e5c41 100755
--- a/framework/lynq-ril-service/src/common.cpp
+++ b/framework/lynq-ril-service/src/common.cpp
@@ -1,4 +1,5 @@
- /*
+// SPDX-License-Identifier: MediaTekProprietary
+/*
  * Copyright (C) 2006 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -36,6 +37,7 @@
 #include "utils.h"
 #include "data.h"
 #include "cc.h"
+
 static pthread_mutex_t s_DataMutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_cond_t s_DataCond = PTHREAD_COND_INITIALIZER;
 
@@ -783,21 +785,29 @@
                 writeStringToParcel(p, items[1].c_str());
             } else if(items[0] == std::string("REQ")) {
                 int request = std::stoi(items[1]);
+
+                // For loop, free before reassign to avoid memory leak
+                if (pRI != NULL) {
+                    free(pRI);
+                }
                 pRI = creatRILInfoAndInit(request, UDP, (RIL_SOCKET_ID) ((0)));
             }
         } else {
             RLOGD("%s, too many \"=\"");
         }
     }
+
     if(pRI && pRI->pCI) {
         p.setDataPosition(pos);
         pRI->pCI->dispatchFunction(p, pRI);
-    } else {
-        if(pRI) {
-            free(pRI);
-            pRI = NULL;
-        }
     }
+
+    // Free to avoid memory leak
+    if(pRI != NULL) {
+        free(pRI);
+        pRI = NULL;
+    }
+
     return true;
 }
 int lynqSocketSendto(int fd,struct sockaddr *dest_addr,int addr_len,char msg[])
diff --git a/framework/lynq-ril-service/src/data/data.cpp b/framework/lynq-ril-service/src/data/data.cpp
index ff64a15..9d5eb1a 100755
--- a/framework/lynq-ril-service/src/data/data.cpp
+++ b/framework/lynq-ril-service/src/data/data.cpp
@@ -1,3 +1,4 @@
+//SPDX-License-Identifier: MediaTekProprietary
 /* Copyright Statement:
  *
  * This software/firmware and related documentation ("MediaTek Software") are
diff --git a/framework/lynq-ril-service/src/data/data_gdbus.cpp b/framework/lynq-ril-service/src/data/data_gdbus.cpp
index 39fc469..3d067b8 100755
--- a/framework/lynq-ril-service/src/data/data_gdbus.cpp
+++ b/framework/lynq-ril-service/src/data/data_gdbus.cpp
@@ -1,3 +1,4 @@
+//SPDX-License-Identifier: MediaTekProprietary
 /* Copyright Statement:
  *
  * This software/firmware and related documentation ("MediaTek Software") are
diff --git a/framework/lynq-ril-service/src/ecall/eCall.cpp b/framework/lynq-ril-service/src/ecall/eCall.cpp
old mode 100755
new mode 100644
index 3e9fed8..da55466
--- a/framework/lynq-ril-service/src/ecall/eCall.cpp
+++ b/framework/lynq-ril-service/src/ecall/eCall.cpp
@@ -1,3 +1,4 @@
+//SPDX-License-Identifier: MediaTekProprietary
 /* Copyright Statement:
  *
  * This software/firmware and related documentation ("MediaTek Software") are
@@ -131,6 +132,7 @@
 static timer_t sT7;
 static timer_t sRedialTimer;
 static timer_t sAutoAnsTimer;
+static timer_t sAutoAnsTimer_ims;
 static timer_t gostResendMsdTimer;
 static timer_t gostDeregistrationTimer;
 
@@ -147,6 +149,7 @@
 static int sT7_sig_value = 7;
 static int redial_sig_value = 8;
 static int autoAns_sig_value = 9;
+static int autoAns_sig_value_ims = 10;
 static int gost_resend_msd_value = 11;
 static int gost_deregistration_value = 12;
 
@@ -166,6 +169,15 @@
         RLOGD("%s(), timer_id(%ld) had stopped", __FUNCTION__, (long)sAutoAnsTimer);
         return true;
     }
+    if(timer_gettime(sAutoAnsTimer_ims, &timespec) == -1) {
+        RLOGD("%s(), get ims_time fail(%s)", __FUNCTION__, strerror(errno));
+        return true;
+    }
+    RLOGD("%s(), ims tv_sec=%ld, tv_nsec=%ld", __FUNCTION__,timespec.it_value.tv_sec, timespec.it_value.tv_nsec);
+    if((timespec.it_value.tv_sec == 0)  && (timespec.it_value.tv_nsec == 0) ) {
+        RLOGD("%s(),ims timer_id(%ld) had stopped", __FUNCTION__, (long)sAutoAnsTimer_ims);
+        return true;
+    }
     return false;
 }
 
@@ -250,6 +262,8 @@
         autoAnswerEcall(true);
     } else if(sig.sival_int == autoAns_sig_value) {
         autoAnswerEcall(false);
+    } else if(sig.sival_int == autoAns_sig_value_ims) {
+        autoAnswerEcall(false);
     } else if(sig.sival_int == gost_resend_msd_value) {
         //send msd
         char** argv = new char*[gost_sms_argv.size()];
@@ -308,6 +322,7 @@
     init_ecall_timer(&sT7,sT7_sig_value);
     init_ecall_timer(&sRedialTimer,redial_sig_value);
     init_ecall_timer(&sAutoAnsTimer,autoAns_sig_value);
+    init_ecall_timer(&sAutoAnsTimer_ims,autoAns_sig_value_ims);
     init_ecall_timer(&gostResendMsdTimer,gost_resend_msd_value);
     init_ecall_timer(&gostDeregistrationTimer, gost_deregistration_value);
 }
@@ -460,19 +475,22 @@
         hangupConnection(2, argv, soc_id, pRI);
         break;
     }
-    case RIL_UNSOL_ECALL_ACTIVE: // =11,
+    case RIL_UNSOL_ECALL_ACTIVE: // = 11,
     {
         if(redial_tag == REDIAL_DOING) {
             redial_tag = REDIAL_SUCCESS;
             stop_ecall_timer(sRedialTimer, redial_sig_value);
         }
         stop_ecall_timer(sAutoAnsTimer, autoAns_sig_value);
+        stop_ecall_timer(sAutoAnsTimer_ims, autoAns_sig_value_ims);
         autoAnswerEcall(false);
         start_ecll_timer(sT2, sT2_sig_value,T2_TIMEOUT);
-        start_ecll_timer(sT5,sT5_sig_value, T5_TIMEOUT);
+        // Start T5 only when need send inband MSD.
+        if (fast_argc)
+            start_ecll_timer(sT5,sT5_sig_value, T5_TIMEOUT);
         break;
     }
-    case RIL_UNSOL_ECALL_DISCONNECTED: //=12,
+    case RIL_UNSOL_ECALL_DISCONNECTED: // = 12
     {
         start_ecll_timer(sAutoAnsTimer,autoAns_sig_value, AUTOANS_TIMEOUT);
         autoAnswerEcall(true);
@@ -505,11 +523,104 @@
         }
         break;
     }
-    //case RIL_UNSOL_ECALL_IMS_MSD_ACK: // = 20,
-    //case RIL_UNSOL_ECALL_IMS_UPDATE_MSD: // = 21,
-    //case RIL_UNSOL_ECALL_UNSPECIFIED: // = 0xffff,
+#if defined(TARGET_PLATFORM_MT2735)
+    case RIL_UNSOL_ECALL_IMS_ACTIVE: // 13 ,
+    {
+        act_fecall_socid = soc_id;
+        act_feCall_Id = p_cur->call_id;
+        stop_ecall_timer(sAutoAnsTimer, autoAns_sig_value);
+        stop_ecall_timer(sAutoAnsTimer_ims, autoAns_sig_value_ims);
+        autoAnswerEcall(false);
+        start_ecll_timer(sT2, sT2_sig_value,T2_TIMEOUT);
+        break;
+    }
+    case RIL_UNSOL_ECALL_IMS_DISCONNECTED: // 14
+    {
+        fast_argc = 0;
+        fast_argv.clear();
+        stop_ecall_timer(sT2, sT2_sig_value);
+        autoAnswerEcall(true);
+        start_ecll_timer(sAutoAnsTimer_ims, autoAns_sig_value_ims, 12*AUTOANS_TIMEOUT);
+        break;
+    }
+    case RIL_UNSOL_ECALL_IMS_MSD_ACK: // 20
+    {
+        saveEcallRecord(p_cur->ind);
+        break;
+    }
+    case RIL_UNSOL_ECALL_IMS_UPDATE_MSD: // 21,
+    {
+        RLOGD("update ims ecall msd_data: %s", msd_data==NULL ? "":msd_data);
+        if(msd_data != NULL) {
+            RequestInfo* pRI = creatRILInfoAndInit(RIL_REQUEST_ECALL_SET_MSD, RSPD, soc_id);
+            char* argv[3] = {"RIL_REQUEST_ECALL_SET_MSD", "", "" };
+            argv[1] = const_cast<char*>(std::to_string(p_cur->call_id).c_str());
+            argv[2] = msd_data;
+            setMSD(3, argv, soc_id, pRI);
+        }
+        break;
+    }
+    case RIL_UNSOL_ECALL_IMS_IN_BAND_TRANSFER: // 22
+    {
+        start_ecll_timer(sT5,sT5_sig_value, T5_TIMEOUT);
+        break;
+    }
+    case RIL_UNSOL_ECALL_IMS_MSD_NACK: // 23
+    {
+        saveEcallRecord(p_cur->ind);
+        break;
+    }
+    case RIL_UNSOL_ECALL_IMS_SRVCC: // 24
+    {
+        start_ecll_timer(sT5,sT5_sig_value, T5_TIMEOUT);
+        break;
+    }
+    case RIL_UNSOL_ECALL_PSAP_CALLBACK_START: // 40
+    {
+        // Similar to receive 11 + 1
+        if(redial_tag == REDIAL_DOING) {
+            redial_tag = REDIAL_SUCCESS;
+            stop_ecall_timer(sRedialTimer, redial_sig_value);
+        }
+        stop_ecall_timer(sAutoAnsTimer, autoAns_sig_value);
+        stop_ecall_timer(sAutoAnsTimer_ims, autoAns_sig_value_ims);
+        autoAnswerEcall(false);
+        start_ecll_timer(sT2, sT2_sig_value,T2_TIMEOUT);
+
+        RLOGD("msd_data: %s", msd_data==NULL ? "":msd_data);
+        if(msd_data != NULL) {
+            RequestInfo* pRI = creatRILInfoAndInit(RIL_REQUEST_ECALL_SET_MSD, RSPD, soc_id);
+            char* argv[3] = {"RIL_REQUEST_ECALL_SET_MSD", "", "" };
+            argv[1] = const_cast<char*>(std::to_string(p_cur->call_id).c_str());
+            argv[2] = msd_data;
+            setMSD(3, argv, soc_id, pRI);
+        }
+        break;
+    }
+    case RIL_UNSOL_ECALL_PSAP_CALLBACK_IMS_UPDATE_MSD: // 41
+    {
+        // Similar to receive 13 + 21
+        act_fecall_socid = soc_id;
+        act_feCall_Id = p_cur->call_id;
+        stop_ecall_timer(sAutoAnsTimer, autoAns_sig_value);
+        stop_ecall_timer(sAutoAnsTimer_ims, autoAns_sig_value_ims);
+        autoAnswerEcall(false);
+        start_ecll_timer(sT2, sT2_sig_value,T2_TIMEOUT);
+
+        RLOGD("update ims ecall msd_data: %s", msd_data==NULL ? "":msd_data);
+        if(msd_data != NULL) {
+            RequestInfo* pRI = creatRILInfoAndInit(RIL_REQUEST_ECALL_SET_MSD, RSPD, soc_id);
+            char* argv[3] = {"RIL_REQUEST_ECALL_SET_MSD", "", "" };
+            argv[1] = const_cast<char*>(std::to_string(p_cur->call_id).c_str());
+            argv[2] = msd_data;
+            setMSD(3, argv, soc_id, pRI);
+        }
+        break;
+    }
+#endif
     default:
-        RLOGD("handleEcallIndication don't handlt the value(%d)", p_cur->ind);
+        RLOGD("handleEcallIndication don't handle the value(%d)", p_cur->ind);
+        break;
     }
 }
 
diff --git a/framework/lynq-ril-service/src/ecall/gost/utils/GostEcallUtils.cpp b/framework/lynq-ril-service/src/ecall/gost/utils/GostEcallUtils.cpp
old mode 100755
new mode 100644
index 301e622..24936fe
--- a/framework/lynq-ril-service/src/ecall/gost/utils/GostEcallUtils.cpp
+++ b/framework/lynq-ril-service/src/ecall/gost/utils/GostEcallUtils.cpp
@@ -1,3 +1,4 @@
+//SPDX-License-Identifier: MediaTekProprietary
 /* Copyright Statement:
  *
  * This software/firmware and related documentation ("MediaTek Software") are
diff --git a/framework/lynq-ril-service/src/em/em.cpp b/framework/lynq-ril-service/src/em/em.cpp
old mode 100755
new mode 100644
index 4a8c7ef..67fc7e7
--- a/framework/lynq-ril-service/src/em/em.cpp
+++ b/framework/lynq-ril-service/src/em/em.cpp
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: MediaTekProprietary
 /* Copyright Statement:
  *
  * This software/firmware and related documentation ("MediaTek Software") are
@@ -61,7 +62,12 @@
     //{"ESM",0,NULL,1,1},
     //{"EMM",0,NULL,1,1},
     //{"MMDC",0,NULL,1,1},
+#ifdef C2K_SUPPORT
     {"EL1",0,NULL,1,1},
+#endif
+#ifdef TARGET_PLATFORM_MT2735
+    {"NR L1 Info",0,NULL,1,1},
+#endif
     //{"Timer Information",0,NULL,1,1},
     //{"TDD TAS",0,NULL,1,1},
     //{"GSM TAS",0,NULL,1,1},
@@ -184,6 +190,9 @@
 };
 em_arry_t hspa[] = {
     {"QUERY",0,NULL,1,1},
+#ifdef TARGET_PLATFORM_MT2735
+    {"QUERY_CAINFO",0,NULL,1,1},
+#endif
 };
 em_arry_t cfu[] = {
     {"Default",0,NULL,1,1},
@@ -192,7 +201,11 @@
 };
 em_arry_t bandmode[] = {
     {"getcurrentband",0,NULL,1,1},
-    {"setBand(eg: 1.1=1 add band, 1.1=0 remove band) or getSupportBand",0,NULL,1,1},
+    {"setBand(eg: 1.1=1 add band, 1.1=0 remove band) or getGSMSupportBand",0,NULL,1,1},
+#ifdef TARGET_PLATFORM_MT2735
+    {"getcurrentNRband",0,NULL,1,1},
+#endif
+//    {"[NR]setBand(eg: 1.1=1 add band, 1.1=0 remove band) or getGSMSupportBand",0,NULL,1,1},
 };
 em_arry_t networkinfo[] = {
     {"RR Cell Sel",0,NULL,1,1},
@@ -262,7 +275,11 @@
 
 em_arry_t antenna_4Gmode[] = {
     {"getmode",0,NULL,1,1},
+#ifdef TARGET_PLATFORM_MT2735
+    {"setmode",0,NULL,1,1},
+#else
     {"setmode",NUM_ITEMS(antenna_setmodes_4g),antenna_setmodes_4g,1,1},
+#endif
 };
 
 em_arry_t antenna_3Gmode[] = {
@@ -275,12 +292,20 @@
     {"setmode",NUM_ITEMS(antenna_setmodes_c2k),antenna_setmodes_c2k,1,1},
 };
 
+em_arry_t antenna_NRmode[] = {
+    {"getmode",0,NULL,1,1},
+    {"setmode",0,NULL,1,1},
+};
+
 em_arry_t antennatest[] = {
     {"4G",NUM_ITEMS(antenna_4Gmode),antenna_4Gmode,1,1},
-    {"3G",NUM_ITEMS(antenna_3Gmode),antenna_3Gmode,1,1},
 #ifdef C2K_SUPPORT
+    {"3G",NUM_ITEMS(antenna_3Gmode),antenna_3Gmode,1,1},
     {"CDMA",NUM_ITEMS(antenna_c2kmode),antenna_c2kmode,1,1},
 #endif
+#ifdef TARGET_PLATFORM_MT2735
+    {"NR",NUM_ITEMS(antenna_NRmode),antenna_NRmode,1,1},
+#endif
 };
 
 em_arry_t time_reg[] = {
@@ -554,12 +579,98 @@
         {"show default",0,NULL,0,0},
 };
 
+em_arry_t rfdesense_nr_tx_mode[] = {
+        {"Tone",0,NULL,0,0},
+        {"PUSCH",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_nr_band[] = {
+        {"1",0,NULL,0,0},
+        {"3",0,NULL,0,0},
+        {"7",0,NULL,0,0},
+        {"8",0,NULL,0,0},
+        {"20",0,NULL,0,0},
+        {"28",0,NULL,0,0},
+        {"38",0,NULL,0,0},
+        {"41",0,NULL,0,0},
+        {"77",0,NULL,0,0},
+        {"78",0,NULL,0,0},
+        {"79",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_nr_bandwidth[] = {
+        {"5M",0,NULL,0,0},
+        {"10M",0,NULL,0,0},
+        {"15M",0,NULL,0,0},
+        {"20M",0,NULL,0,0},
+        {"25M",0,NULL,0,0},
+        {"30M",0,NULL,0,0},
+        {"35M",0,NULL,0,0},
+        {"40M",0,NULL,0,0},
+        {"45M",0,NULL,0,0},
+        {"50M",0,NULL,0,0},
+        {"55M",0,NULL,0,0},
+        {"60M",0,NULL,0,0},
+        {"65M",0,NULL,0,0},
+        {"70M",0,NULL,0,0},
+        {"75M",0,NULL,0,0},
+        {"82M",0,NULL,0,0},
+        {"85M",0,NULL,0,0},
+        {"90M",0,NULL,0,0},
+        {"95M",0,NULL,0,0},
+        {"100M",0,NULL,0,0},
+};
+
+em_arry_t  rfdesense_nr_mcs[] = {
+        {"DFT-S BPSK",0,NULL,0,0},
+        {"CP QPSK",0,NULL,0,0},
+        {"DFT-S QPSK",0,NULL,0,0},
+        {"CP 16QAM",0,NULL,0,0},
+        {"DFT-S 16QAM",0,NULL,0,0},
+        {"CP 64QAM",0,NULL,0,0},
+        {"DFT-S 64QAM",0,NULL,0,0},
+        {"CP 256QAM",0,NULL,0,0},
+        {"DFT-S 256QAM",0,NULL,0,0},
+};
+
+em_arry_t  rfdesense_nr_scs[] = {
+        {"15KHZ(0)",0,NULL,0,0},
+        {"30KHZ(1)",0,NULL,0,0},
+        {"60KHZ(2)",0,NULL,0,0},
+        {"120KHZ(3)",0,NULL,0,0},
+        {"240KHZ(4)",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_nr_sub[] = {
+        {"Tx mode",NUM_ITEMS(rfdesense_nr_tx_mode),rfdesense_nr_tx_mode,0,0},
+        {"Band",NUM_ITEMS(rfdesense_nr_band),rfdesense_nr_band,0,0},
+        {"UL bandwidth",NUM_ITEMS(rfdesense_nr_bandwidth),rfdesense_nr_bandwidth,0,0},
+        {"UL freq(1kHz)",NUM_ITEMS(set_get),set_get,0,0},
+        {"VRB start(0-272)",NUM_ITEMS(set_get),set_get,0,0},
+        {"VRB length(1-273)",NUM_ITEMS(set_get),set_get,0,0},
+        {"MCS",NUM_ITEMS(rfdesense_nr_mcs),rfdesense_nr_mcs,0,0},
+        {"SCS",NUM_ITEMS(rfdesense_nr_scs),rfdesense_nr_scs,0,0},
+        {"Power level(dbm)(-50-23)",NUM_ITEMS(set_get),set_get,0,0},
+        {"Tdd slot config(1-44)",NUM_ITEMS(set_get),set_get,0,0},
+};
+
+em_arry_t rfdesense_nr[] = {
+        {"start",0,NULL,0,0},
+        {"Parameters_set",NUM_ITEMS(rfdesense_nr_sub),rfdesense_nr_sub,0,0},
+        {"show default",0,NULL,0,0},
+};
+
 em_arry_t sub_tx_test[] = {
     { "GSM", NUM_ITEMS(rfdesense_gsm),rfdesense_gsm, 1, 1 },
+#ifndef TARGET_PLATFORM_MT2735
     { "TDSCDMA", NUM_ITEMS(rfdesense_tdscdma), rfdesense_tdscdma, 1, 1 },
+#endif
     { "WCDMA", NUM_ITEMS(rfdesense_wcdma), rfdesense_wcdma, 1, 1 },
     { "LTE(FDD)", NUM_ITEMS(rfdesense_lte_fdd), rfdesense_lte_fdd, 1, 1 },
     { "LTE(TDD)", NUM_ITEMS(rfdesense_lte_tdd), rfdesense_lte_tdd, 1, 1 },
+#ifdef TARGET_PLATFORM_MT2735
+    { "NR", NUM_ITEMS(rfdesense_nr), rfdesense_nr, 1, 1 },
+#endif
 #ifdef C2K_SUPPORT
     { "CDMA(EVDO)", NUM_ITEMS(rfdesense_cdma), rfdesense_cdma, 1, 1 },
     { "CDMA(1x)", NUM_ITEMS(rfdesense_cdma), rfdesense_cdma, 1, 1 },
@@ -578,12 +689,12 @@
 #ifdef C2K_SUPPORT
     {"CDMA modem setting",NUM_ITEMS(c2k_modem_setting),c2k_modem_setting,0,0},
 #endif
-#ifndef TARGET_PLATFORM_MT2735
     {"RF Desense Test ",NUM_ITEMS(desense_test),desense_test,0,0},
-#endif
     {"Modem Test",NUM_ITEMS(modemtest),modemtest,0,0},
     {"HSPA",NUM_ITEMS(hspa),hspa,0,0},
+#ifndef TARGET_PLATFORM_MT2735
     {"CFU",NUM_ITEMS(cfu),cfu,0,0},
+#endif
     {"Antenna Test",NUM_ITEMS(antennatest),antennatest,0,0},
     {"Band Mode",NUM_ITEMS(bandmode),bandmode,0,0},
     {"IMS",NUM_ITEMS(ims),ims,0,0},
@@ -593,15 +704,17 @@
     {"LTE",NUM_ITEMS(lte_info),lte_info,0,0},
 };
 typedef enum {
-#ifdef TARGET_PLATFORM_MT2735
-    MODEM_TEST_ITEM = 0,
-#else
+#ifdef C2K_SUPPORT
     C2K_MODEM_SETTING = 0,
     RF_DESENSE_TEST,
-    MODEM_TEST_ITEM,
+#else
+    RF_DESENSE_TEST = 0,
 #endif
+    MODEM_TEST_ITEM,
     HSPA_ITEM,
+#ifndef TARGET_PLATFORM_MT2735
     CFU_ITEM,
+#endif
     ANTENNATEST_ITEM,
     BANDMODE_ITEM,
     IMS_ITEM,
@@ -619,21 +732,21 @@
     case C2K_MODEM_SETTING:
         emC2kModemSettingStart(len - 1, multilen, &item[1]);
         break;
+    case CFU_ITEM:
+        emCfuStart(len - 1, &item[1]);
+        break;
+#endif
     case RF_DESENSE_TEST:
         emRfDesenseStart(len - 1, &item[1], multilen, value);
         break;
-#endif
     case MODEM_TEST_ITEM:
         emModemtestStart(len - 1, multilen, &item[1]);
         break;
     case HSPA_ITEM:
         emHspaStart(len - 1, &item[1]);
         break;
-    case CFU_ITEM:
-        emCfuStart(len - 1, &item[1]);
-        break;
     case ANTENNATEST_ITEM:
-        emAntennaTestStart(len - 1, &item[1],(value != NULL ? value[0] : NULL));
+        emAntennaTestStart(len - 1, &item[1], multilen, value);
         break;
     case BANDMODE_ITEM:
         emBandmodeStart(len - 1, &item[1], multilen, value);
diff --git a/framework/lynq-ril-service/src/em/em.h b/framework/lynq-ril-service/src/em/em.h
old mode 100755
new mode 100644
index 44e3e13..debdb4a
--- a/framework/lynq-ril-service/src/em/em.h
+++ b/framework/lynq-ril-service/src/em/em.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: MediaTekProprietary
 /* Copyright Statement:
  *
  * This software/firmware and related documentation ("MediaTek Software") are
@@ -95,6 +96,13 @@
 extern em_arry_t rfdesense_cdma_modulation[];
 extern em_arry_t rfdesense_cdma_sub[];
 extern em_arry_t rfdesense_cdma[];
+extern em_arry_t rfdesense_nr_tx_mode[];
+extern em_arry_t rfdesense_nr_band[];
+extern em_arry_t rfdesense_nr_bandwidth[];
+extern em_arry_t rfdesense_nr_mcs[];
+extern em_arry_t rfdesense_nr_scs[];
+extern em_arry_t rfdesense_nr_sub[];
+extern em_arry_t rfdesense_nr[];
 extern em_arry_t sub_tx_test[];
 extern em_arry_t desense_test[];
 extern em_arry_t emmain[];
@@ -132,7 +140,7 @@
 int emCfuStart(int argc, int *item);
 int emBandmodeStart(int len,int *item,int multilen,char *value[]);
 int emNwInfoStart(int argc, int multicnt,int *item);
-int emAntennaTestStart(int argc, int *item,char *value);
+int emAntennaTestStart(int argc, int *item,int multilen,char *value[]);
 int emC2kModemSettingStart(int argc, int multicnt,int *item);
 int emRfDesenseStart(int len,int *item,int multilen,char *value[]);
 
diff --git a/framework/lynq-ril-service/src/em/em_EL1.cpp b/framework/lynq-ril-service/src/em/em_EL1.cpp
old mode 100755
new mode 100644
index 73e8a1a..9551698
--- a/framework/lynq-ril-service/src/em/em_EL1.cpp
+++ b/framework/lynq-ril-service/src/em/em_EL1.cpp
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: MediaTekProprietary
 /* Copyright Statement:
  *
  * This software/firmware and related documentation ("MediaTek Software") are
@@ -44,12 +45,15 @@
 #include  "common.h"
 #include "em/em.h"
 #include "Radio_capability_switch_util.h"
+#include "../util/utils.h"
 
 #if EM_MODE_SUPPORT
 
 #undef LOG_TAG
 #define LOG_TAG "EM_EL1"
 
+#define MAX_RAN_CELL_SIZE 32
+
 static int mItemCount = 0;
 static int mFlag = 0;// at cmd flag
 static int mCurrentFlag = 0; // at cmd handle flag
@@ -57,6 +61,37 @@
 static const int MSG_NW_INFO = 1;
 static const int MSG_NW_INFO_OPEN = 4;
 static const int MSG_NW_INFO_CLOSE = 5;
+static const int MSG_NW_CA_INFO_LTE_NR = 6;
+
+
+static const int IDX_EL1 = -1;
+static const int IDX_CA_INFO_LTE_NR = 0;
+int intput_idx = 0;
+
+static const std::string CMD_SAME_EDMFAPP = "+EDMFAPP: 6,3,";
+
+struct cell_band_bandwidth_struct {
+    /** @brief Cell Identity. */
+    int cid;
+    int c_state;        /*1: SCELL_STATUS_NOTACTIVE 2: SCELL_STATUS_ACTIVE */
+    int cell_band;      /* cell band: 1~1024 */
+    int cell_bandwidth; /* cell bandwidth index */
+    int cc_cw0_cqi;     /*0~15*/
+    int cc_cw1_cqi;     /*0~15*/
+    int cc_pci;         /*0~1024*/
+    int cc_arfcn;       /*22bit*/
+};
+
+struct all_cell_band_bandwidth_struct{
+    int num_serving_lte_cell_dl;
+    int num_serving_lte_cell_ul;
+    int num_serving_nr_cell_dl;
+    int num_serving_nr_cell_ul;
+    cell_band_bandwidth_struct lte_band_bandwidth_dl[MAX_RAN_CELL_SIZE];
+    cell_band_bandwidth_struct lte_band_bandwidth_ul[MAX_RAN_CELL_SIZE];
+    cell_band_bandwidth_struct nr_band_bandwidth_dl[MAX_RAN_CELL_SIZE];
+    cell_band_bandwidth_struct nr_band_bandwidth_ul[MAX_RAN_CELL_SIZE];
+};
 
 static void sendATCommand(const char *cmd,int msg)
 {
@@ -92,6 +127,314 @@
 
 }
 
+static void parseCAInfo(char* data) {
+    RLOGD("parseCAInfo, rsp=%s", data);
+    std::vector<std::string> out;
+    utils::tokenize(string(data), "\n", out);
+    int cell_idx = 0, at_idx = 0;
+    std::string str;
+    str.clear();
+    char tmp[1024] = {0};
+
+    for(auto i: out) {
+        if(i.find(CMD_SAME_EDMFAPP) != std::string::npos) {
+            std::string splitString = i.substr(std::string(CMD_SAME_EDMFAPP).size());
+            std::vector<std::string> getDigitalVal;
+            utils::tokenize(string(splitString), ",\n", getDigitalVal);
+            RLOGD("parseCurrentMode splitString: %s, getDigitalVal.size()=%d",
+                    splitString.c_str(), getDigitalVal.size());
+
+            try {
+                all_cell_band_bandwidth_struct cells_info;
+                memset(&cells_info, 0, sizeof(all_cell_band_bandwidth_struct));
+                str.append("[Cell Info]\n");
+
+                // LTE DL
+                cells_info.num_serving_lte_cell_dl = std::stoi(getDigitalVal[at_idx]);
+                RLOGW("cells_info.num_serving_lte_cell_dl=%d", cells_info.num_serving_lte_cell_dl);
+                sprintf(tmp, "num_serving_lte_cell_dl:%d\n", cells_info.num_serving_lte_cell_dl);
+                str.append(tmp);
+                memset(tmp, 0, sizeof(char)*1024);
+                at_idx++;
+
+                if (cells_info.num_serving_lte_cell_dl != 0) {
+                    for (cell_idx = 0; cell_idx < cells_info.num_serving_lte_cell_dl; cell_idx++) {
+
+                        if (cell_idx >= MAX_RAN_CELL_SIZE) {
+                            RLOGW("cell_idx=%d > MAX_RAN_CELL_SIZE=%d, ignore", cell_idx, MAX_RAN_CELL_SIZE);
+                            continue;
+                        }
+
+                        cells_info.lte_band_bandwidth_dl[cell_idx].cid = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.lte_dl[%d].cid=%d", cell_idx, cells_info.lte_band_bandwidth_dl[cell_idx].cid);
+                        at_idx++;
+
+                        cells_info.lte_band_bandwidth_dl[cell_idx].c_state = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.lte_dl[%d].c_state=%d", cell_idx, cells_info.lte_band_bandwidth_dl[cell_idx].c_state);
+                        at_idx++;
+
+                        cells_info.lte_band_bandwidth_dl[cell_idx].cell_band = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.lte_dl[%d].cell_band=%d", cell_idx, cells_info.lte_band_bandwidth_dl[cell_idx].cell_band);
+                        at_idx++;
+
+                        cells_info.lte_band_bandwidth_dl[cell_idx].cell_bandwidth = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.lte_dl[%d].cell_bandwidth=%d", cell_idx, cells_info.lte_band_bandwidth_dl[cell_idx].cell_bandwidth);
+                        at_idx++;
+
+                        cells_info.lte_band_bandwidth_dl[cell_idx].cc_cw0_cqi = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.lte_dl[%d].cc_cw0_cqi=%d", cell_idx, cells_info.lte_band_bandwidth_dl[cell_idx].cc_cw0_cqi);
+                        at_idx++;
+
+                        cells_info.lte_band_bandwidth_dl[cell_idx].cc_cw1_cqi = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.lte_dl[%d].cc_cw1_cqi=%d", cell_idx, cells_info.lte_band_bandwidth_dl[cell_idx].cc_cw1_cqi);
+                        at_idx++;
+
+                        cells_info.lte_band_bandwidth_dl[cell_idx].cc_pci = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.lte_dl[%d].cc_pci=%d", cell_idx, cells_info.lte_band_bandwidth_dl[cell_idx].cc_pci);
+                        at_idx++;
+
+                        cells_info.lte_band_bandwidth_dl[cell_idx].cc_arfcn = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.lte_dl[%d].cc_arfcn=%d", cell_idx, cells_info.lte_band_bandwidth_dl[cell_idx].cc_arfcn);
+                        at_idx++;
+
+                        sprintf(tmp,
+                                "lte_dl[%d]:\n"
+                                " - cid: %d\n"
+                                " - c_state: %d\n"
+                                " - cell_band: %d\n"
+                                " - cell_bandwidth: %d\n"
+                                " - cc_cw0_cqi: %d\n"
+                                " - cc_cw1_cqi: %d\n"
+                                " - cc_pci: %d\n"
+                                " - cc_arfcn: %d\n",
+                                cell_idx,
+                                cells_info.lte_band_bandwidth_dl[cell_idx].cid,
+                                cells_info.lte_band_bandwidth_dl[cell_idx].c_state,
+                                cells_info.lte_band_bandwidth_dl[cell_idx].cell_band,
+                                cells_info.lte_band_bandwidth_dl[cell_idx].cell_bandwidth,
+                                cells_info.lte_band_bandwidth_dl[cell_idx].cc_cw0_cqi,
+                                cells_info.lte_band_bandwidth_dl[cell_idx].cc_cw1_cqi,
+                                cells_info.lte_band_bandwidth_dl[cell_idx].cc_pci,
+                                cells_info.lte_band_bandwidth_dl[cell_idx].cc_arfcn);
+                        str.append(tmp);
+                        RLOGD("result1 str=%s", str.c_str());
+                        memset(tmp, 0, sizeof(char)*1024);
+                    }
+                }
+
+                // LTE UL
+                cells_info.num_serving_lte_cell_ul = std::stoi(getDigitalVal[at_idx]);
+                RLOGW("cells_info.num_serving_lte_cell_ul=%d", cells_info.num_serving_lte_cell_ul);
+                sprintf(tmp, "num_serving_lte_cell_ul:%d\n", cells_info.num_serving_lte_cell_ul);
+                str.append(tmp);
+                memset(tmp, 0, 1024);
+                at_idx++;
+
+                if (cells_info.num_serving_lte_cell_ul != 0) {
+                    for (cell_idx = 0; cell_idx < cells_info.num_serving_lte_cell_ul; cell_idx++) {
+
+                        if (cell_idx >= MAX_RAN_CELL_SIZE) {
+                            RLOGW("cell_idx=%d >= MAX_RAN_CELL_SIZE=%d, ignore", cell_idx, MAX_RAN_CELL_SIZE);
+                            continue;
+                        }
+
+                        cells_info.lte_band_bandwidth_ul[cell_idx].cid = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.lte_ul[%d].cid=%d", cell_idx, cells_info.lte_band_bandwidth_ul[cell_idx].cid);
+                        at_idx++;
+
+                        cells_info.lte_band_bandwidth_ul[cell_idx].c_state = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.lte_ul[%d].c_state=%d", cell_idx, cells_info.lte_band_bandwidth_ul[cell_idx].c_state);
+                        at_idx++;
+
+                        cells_info.lte_band_bandwidth_ul[cell_idx].cell_band = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.lte_ul[%d].cell_band=%d", cell_idx, cells_info.lte_band_bandwidth_ul[cell_idx].cell_band);
+                        at_idx++;
+
+                        cells_info.lte_band_bandwidth_ul[cell_idx].cell_bandwidth = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.lte_ul[%d].cell_bandwidth=%d", cell_idx, cells_info.lte_band_bandwidth_ul[cell_idx].cell_bandwidth);
+                        at_idx++;
+
+                        cells_info.lte_band_bandwidth_ul[cell_idx].cc_pci = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.lte_ul[%d].cc_pci=%d", cell_idx, cells_info.lte_band_bandwidth_ul[cell_idx].cc_pci);
+                        at_idx++;
+
+                        cells_info.lte_band_bandwidth_ul[cell_idx].cc_arfcn = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.lte_ul[%d].cc_arfcn=%d", cell_idx, cells_info.lte_band_bandwidth_ul[cell_idx].cc_arfcn);
+                        at_idx++;
+
+                        sprintf(tmp,
+                                "lte_ul[%d]:\n"
+                                " - cid: %d\n"
+                                " - c_state: %d\n"
+                                " - cell_band: %d\n"
+                                " - cell_bandwidth: %d\n"
+                                " - cc_pci: %d\n"
+                                " - cc_arfcn: %d\n",
+                                cell_idx,
+                                cells_info.lte_band_bandwidth_ul[cell_idx].cid,
+                                cells_info.lte_band_bandwidth_ul[cell_idx].c_state,
+                                cells_info.lte_band_bandwidth_ul[cell_idx].cell_band,
+                                cells_info.lte_band_bandwidth_ul[cell_idx].cell_bandwidth,
+                                cells_info.lte_band_bandwidth_ul[cell_idx].cc_pci,
+                                cells_info.lte_band_bandwidth_ul[cell_idx].cc_arfcn);
+                        str.append(tmp);
+                        RLOGD("result2 str=%s", str.c_str());
+                        memset(tmp, 0, sizeof(char)*1024);
+                    }
+                }
+
+                // NR DL
+                cells_info.num_serving_nr_cell_dl = std::stoi(getDigitalVal[at_idx]);
+                RLOGW("cells_info.num_serving_nr_cell_dl=%d", cells_info.num_serving_nr_cell_dl);
+                sprintf(tmp, "num_serving_nr_cell_dl:%d\n", cells_info.num_serving_nr_cell_dl);
+                str.append(tmp);
+                memset(tmp, 0, 1024);
+                at_idx++;
+
+                if (cells_info.num_serving_nr_cell_dl != 0) {
+                    for (cell_idx = 0; cell_idx < cells_info.num_serving_nr_cell_dl; cell_idx++) {
+
+                        if (cell_idx >= MAX_RAN_CELL_SIZE) {
+                            RLOGW("cell_idx=%d > MAX_RAN_CELL_SIZE=%d, ignore", cell_idx, MAX_RAN_CELL_SIZE);
+                            continue;
+                        }
+
+                        cells_info.nr_band_bandwidth_dl[cell_idx].cid = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.nr_dl[%d].cid=%d", cell_idx, cells_info.nr_band_bandwidth_dl[cell_idx].cid);
+                        at_idx++;
+
+                        cells_info.nr_band_bandwidth_dl[cell_idx].c_state = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.nr_dl[%d].c_state=%d", cell_idx, cells_info.nr_band_bandwidth_dl[cell_idx].c_state);
+                        at_idx++;
+
+                        cells_info.nr_band_bandwidth_dl[cell_idx].cell_band = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.nr_dl[%d].cell_band=%d", cell_idx, cells_info.nr_band_bandwidth_dl[cell_idx].cell_band);
+                        at_idx++;
+
+                        cells_info.nr_band_bandwidth_dl[cell_idx].cell_bandwidth = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.nr_dl[%d].cell_bandwidth=%d", cell_idx, cells_info.nr_band_bandwidth_dl[cell_idx].cell_bandwidth);
+                        at_idx++;
+
+                        cells_info.nr_band_bandwidth_dl[cell_idx].cc_cw0_cqi = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.nr_dl[%d].cc_cw0_cqi=%d", cell_idx, cells_info.nr_band_bandwidth_dl[cell_idx].cc_cw0_cqi);
+                        at_idx++;
+
+                        cells_info.nr_band_bandwidth_dl[cell_idx].cc_cw1_cqi = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.nr_dl[%d].cc_cw1_cqi=%d", cell_idx, cells_info.nr_band_bandwidth_dl[cell_idx].cc_cw1_cqi);
+                        at_idx++;
+
+                        cells_info.nr_band_bandwidth_dl[cell_idx].cc_pci = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.nr_dl[%d].cc_pci=%d", cell_idx, cells_info.nr_band_bandwidth_dl[cell_idx].cc_pci);
+                        at_idx++;
+
+                        cells_info.nr_band_bandwidth_dl[cell_idx].cc_arfcn = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.nr_dl[%d].cc_arfcn=%d", cell_idx, cells_info.nr_band_bandwidth_dl[cell_idx].cc_arfcn);
+                        at_idx++;
+
+                        sprintf(tmp,
+                                "nr_dl[%d]:\n"
+                                " - cid: %d\n"
+                                " - c_state: %d\n"
+                                " - cell_band: %d\n"
+                                " - cell_bandwidth: %d\n"
+                                " - cc_cw0_cqi: %d\n"
+                                " - cc_cw1_cqi: %d\n"
+                                " - cc_pci: %d\n"
+                                " - cc_arfcn: %d\n",
+                                cell_idx,
+                                cells_info.nr_band_bandwidth_dl[cell_idx].cid,
+                                cells_info.nr_band_bandwidth_dl[cell_idx].c_state,
+                                cells_info.nr_band_bandwidth_dl[cell_idx].cell_band,
+                                cells_info.nr_band_bandwidth_dl[cell_idx].cell_bandwidth,
+                                cells_info.nr_band_bandwidth_dl[cell_idx].cc_cw0_cqi,
+                                cells_info.nr_band_bandwidth_dl[cell_idx].cc_cw1_cqi,
+                                cells_info.nr_band_bandwidth_dl[cell_idx].cc_pci,
+                                cells_info.nr_band_bandwidth_dl[cell_idx].cc_arfcn);
+                        str.append(tmp);
+                        RLOGD("result3 str=%s", str.c_str());
+                        memset(tmp, 0, 1024);
+                    }
+                }
+
+                // NR UL
+                cells_info.num_serving_nr_cell_ul = std::stoi(getDigitalVal[at_idx]);
+                RLOGW("cells_info.num_serving_nr_cell_ul=%d", cells_info.num_serving_nr_cell_ul);
+                sprintf(tmp, "num_serving_nr_cell_ul:%d\n", cells_info.num_serving_nr_cell_ul);
+                str.append(tmp);
+                memset(tmp, 0, 1024);
+
+                at_idx++;
+
+                if (cells_info.num_serving_nr_cell_ul != 0) {
+                    for (cell_idx = 0; cell_idx < cells_info.num_serving_nr_cell_ul; cell_idx++) {
+
+                        if (cell_idx >= MAX_RAN_CELL_SIZE) {
+                            RLOGW("cell_idx=%d > MAX_RAN_CELL_SIZE=%d, ignore", cell_idx, MAX_RAN_CELL_SIZE);
+                            continue;
+                        }
+
+                        cells_info.nr_band_bandwidth_ul[cell_idx].cid = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.nr_ul[%d].cid=%d", cell_idx, cells_info.nr_band_bandwidth_ul[cell_idx].cid);
+                        at_idx++;
+
+                        cells_info.nr_band_bandwidth_ul[cell_idx].c_state = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.nr_ul[%d].c_state=%d", cell_idx, cells_info.nr_band_bandwidth_ul[cell_idx].c_state);
+                        at_idx++;
+
+                        cells_info.nr_band_bandwidth_ul[cell_idx].cell_band = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.nr_ul[%d].cell_band=%d", cell_idx, cells_info.nr_band_bandwidth_ul[cell_idx].cell_band);
+                        at_idx++;
+
+                        cells_info.nr_band_bandwidth_ul[cell_idx].cell_bandwidth = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.nr_ul[%d].cell_bandwidth=%d", cell_idx, cells_info.nr_band_bandwidth_ul[cell_idx].cell_bandwidth);
+                        at_idx++;
+
+                        cells_info.nr_band_bandwidth_ul[cell_idx].cc_pci = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.nr_ul[%d].cc_pci=%d", cell_idx, cells_info.nr_band_bandwidth_ul[cell_idx].cc_pci);
+                        at_idx++;
+
+                        cells_info.nr_band_bandwidth_ul[cell_idx].cc_arfcn = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.nr_ul[%d].cc_arfcn=%d", cell_idx, cells_info.nr_band_bandwidth_ul[cell_idx].cc_arfcn);
+                        at_idx++;
+
+                        sprintf(tmp,
+                                "nr_ul[%d]:\n"
+                                " - cid: %d\n"
+                                " - c_state: %d\n"
+                                " - cell_band: %d\n"
+                                " - cell_bandwidth: %d\n"
+                                " - cc_pci: %d\n"
+                                " - cc_arfcn: %d\n",
+                                cell_idx,
+                                cells_info.nr_band_bandwidth_ul[cell_idx].cid,
+                                cells_info.nr_band_bandwidth_ul[cell_idx].c_state,
+                                cells_info.nr_band_bandwidth_ul[cell_idx].cell_band,
+                                cells_info.nr_band_bandwidth_ul[cell_idx].cell_bandwidth,
+                                cells_info.nr_band_bandwidth_ul[cell_idx].cc_pci,
+                                cells_info.nr_band_bandwidth_ul[cell_idx].cc_arfcn);
+                        str.append(tmp);
+                        RLOGD("result4 str=%s", str.c_str());
+                        memset(tmp, 0, 1024);
+                    }
+                }
+
+                str.append("\ndone\n");
+                RLOGD("final result str=%s", str.c_str());
+                android::emResultNotify(str.c_str());
+
+            } catch (const out_of_range &e) {
+                android::emResultNotify(RET_STRING_LTE_FAIL);
+                RLOGD("out of range: %s", e.what());
+                return;
+            } catch (const invalid_argument &e) {
+                android::emResultNotify(RET_STRING_LTE_FAIL);
+                RLOGD("invalid argument: %s", e.what());
+                return;
+            }
+        }
+    }
+}
+
 static void el1_at_cmd_handle(char*response, int responselen) {
     switch (mCurrentFlag) {
         case MSG_NW_INFO:
@@ -106,6 +449,15 @@
         case MSG_NW_INFO_OPEN:
         case MSG_NW_INFO_CLOSE:
             break;
+        case MSG_NW_CA_INFO_LTE_NR:
+            if ((responselen > 0) && (response != NULL)) {
+                RLOGD("Get response %s", response);
+                parseCAInfo(response);
+            } else {
+                RLOGE("Query CA info fail failed.");
+                android::emResultNotify(RET_STRING_LTE_FAIL);
+            }
+            break;
         default:
             break;
     }
@@ -174,24 +526,52 @@
     }
 }
 
+//create thread to send command
+void * emEl1Thread(void* arg)
+{
+    // EL1
+    if (lte_info[intput_idx].name == "EL1") {
+        RLOGD("emEl1Thread, MSG_NW_INFO");
+
+        //sendATCommand("AT+EINFO?",MSG_NW_INFO);
+        mFlag = 8;
+        char atcommand[32] = {0};
+        sprintf(atcommand,"AT+EINFO=%d,%d,0",mFlag,EM_EL1_INFO);
+        sendATCommand(atcommand, MSG_NW_INFO_OPEN);
+
+    // Send AT+ECAINFO
+    } else if (lte_info[intput_idx].name == "NR L1 Info") {
+        RLOGD("emEl1Thread, query the latest CA information of LTE/NR");
+
+        char atcommand[32] = {0};
+        sprintf(atcommand,"AT+EDMFAPP=6,3");
+        sendATCommand(atcommand, MSG_NW_CA_INFO_LTE_NR);
+    }
+
+    pthread_exit(0);
+}
+
 int em_el1_start(int argc, int multicnt,int *item)
 {
-    RLOGD("em_el1_start called");
+    RLOGD("em_el1_start called, item[0]=%d", item[0]);
+
+    intput_idx = item[0];
     if(argc < 1)
     {
         RLOGD("em_el1_start: please select page to show info");
         android::emResultNotify(RET_STRING_LTE_FAIL);
         return -1;
     }
-    mItemCount = multicnt + 1;
-    RLOGD("mItemCount: %d, item[%d]: %d", mItemCount, multicnt, item[multicnt]);
-    android::registerForNetworkInfo(el1_urc_handle);
+
+    if (lte_info[intput_idx].name == "EL1") {
+        mItemCount = multicnt + 1;
+        RLOGD("mItemCount: %d, item[%d]: %d", mItemCount, multicnt, item[multicnt]);
+        android::registerForNetworkInfo(el1_urc_handle);
+    }
+
     android::registerForATcmdResponse(el1_at_cmd_handle);
-    //sendATCommand("AT+EINFO?",MSG_NW_INFO);
-    mFlag = 8;
-    char atcommand[32] = {0};
-    sprintf(atcommand,"AT+EINFO=%d,%d,0",mFlag,EM_EL1_INFO);
-    sendATCommand(atcommand, MSG_NW_INFO_OPEN);
+    pthread_t emEl1_thread;
+    pthread_create(&emEl1_thread,NULL, emEl1Thread, NULL);
     return (0);
 }
 #endif
diff --git a/framework/lynq-ril-service/src/em/em_antennatest.cpp b/framework/lynq-ril-service/src/em/em_antennatest.cpp
old mode 100755
new mode 100644
index 28d76fa..d804a96
--- a/framework/lynq-ril-service/src/em/em_antennatest.cpp
+++ b/framework/lynq-ril-service/src/em/em_antennatest.cpp
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: MediaTekProprietary
 /* Copyright Statement:
  *
  * This software/firmware and related documentation ("MediaTek Software") are
@@ -59,18 +60,63 @@
 static const int MSG_QUERY_ANTENNA_EGMC_4G = 5;
 static const int MSG_SET_ANTENNA_EGMC_4G = 6;
 static const int MSG_INIT_ANTENNA_EGMC_4G = 7;
+static const int MSG_QUERY_ANTENNA_EGMC_NR = 8;
+static const int MSG_SET_ANTENNA_EGMC_NR = 9;
+
 static const int MODE_INDEX_BASE_3G = 10;
 static const int MODE_INDEX_BASE_2G = 20;
 static const int MODE_EPCM_VALID = 0xFF;
 static const int CELL_2RX_LENGTH = 2;
 static const int CELL_4RX_LENGTH = 4;
 
+static int RAT_4G  = 0;
+#ifdef C2K_SUPPORT
+static int RAT_3G  = 1;
+static int RAT_C2K = 2;
+static int RAT_NR  = 3;
+#else
+static int RAT_3G  = -1;
+static int RAT_C2K = -1;
+static int RAT_NR  = 1;
+#endif
+
+static const std::string CMD_INIT_EGMC_4G = "AT+EGMC=1,\"rx_path\",1,0,3,15,3,15";
+static const std::string CMD_SET_EGMC_4G = "AT+EGMC=1,\"rx_path\"";
+static const std::string CMD_SET_EGMC_NR = "AT+EGMC=1,\"nr_rx_path\"";
+static const std::string CMD_SAME_EGMC = "+EGMC:";
+
 int mCurrentEmantennaFlag = 0;
 bool fgAntennaRead = true;
-static int fgget = -1;
-static int fgset = -1;
 int mAntennaMode = 0;
 char antennaretstring[128] = {0};
+int inputRat = -1;
+std::vector<int> gEgmcParam;
+
+static const std::vector<std::string> antenna_modes_egmc_4rx {
+    "None",             // 0
+    "RX1",              // 1
+    "RX2",              // 2
+    "RX1&RX2",          // 3
+    "RX3",              // 4
+    "RX1&RX3",          // 5
+    "RX2&RX3",          // 6
+    "RX1&RX2&RX3",      // 7
+    "RX4",              // 8
+    "RX1&RX4",          // 9
+    "RX2&RX4",          // 10
+    "RX1&RX2&RX4",      // 11
+    "RX3&RX4",          // 12
+    "RX1&RX3&RX4",      // 13
+    "RX2&RX3&RX4",      // 14
+    "RX1&RX2&RX3&RX4",  // 15
+};
+
+static const std::vector<std::string> antenna_modes_egmc_2rx {
+    "None",
+    "RX1",
+    "RX2",
+    "RX1&RX2",
+};
 
 static const std::vector<std::string> antenna_modes_4g {
     "RX1&RX2",
@@ -99,6 +145,19 @@
     emSendATCommand(cmd, Radio_capability_switch_util::get_main_capability_phone_id());
     return ;
 }
+
+static void queryEgmcAntNR() {
+    char cmd_str[32] = {0};
+    sprintf(cmd_str,"%s","AT+EGMC=0,\"nr_rx_path\"");
+    sendATCommand(cmd_str, MSG_QUERY_ANTENNA_EGMC_NR);
+}
+
+static void queryEgmcAnt4G() {
+    char cmd_str[32] = {0};
+    sprintf(cmd_str,"%s","AT+EGMC=0,\"rx_path\"");
+    sendATCommand(cmd_str, MSG_QUERY_ANTENNA_EGMC_4G);
+}
+
 static void queryCurrentMode() {
     char cmd_str[32] = {0};
     sprintf(cmd_str,"%s","AT+ERXPATH?");
@@ -114,6 +173,26 @@
     }
 }
 
+static void initEgmcAnt4G() {
+    sendATCommand(CMD_INIT_EGMC_4G.c_str(), MSG_INIT_ANTENNA_EGMC_4G);
+}
+
+static void setEgmcAnt4G(int force_mode, int scc_follow_pcc, int pcell_2rx, int pcell_4rx, int scell_2rx, int scell_4rx) {
+    char cmd_str[64] = {0};
+    sprintf(cmd_str,"%s,%d,%d,%d,%d,%d,%d",
+        CMD_SET_EGMC_4G.c_str(), force_mode, scc_follow_pcc, pcell_2rx, pcell_4rx, scell_2rx, scell_4rx);
+    RLOGD("setEgmcAnt4G, cmd:%s", cmd_str);
+    sendATCommand(cmd_str, MSG_SET_ANTENNA_EGMC_4G);
+}
+
+static void setEgmcAntNR(int force_mode, int scc_follow_pcc, int pcell_2rx, int pcell_4rx, int scell_2rx, int scell_4rx) {
+    char cmd_str[64] = {0};
+    sprintf(cmd_str,"%s,%d,%d,%d,%d,%d,%d",
+        CMD_SET_EGMC_NR.c_str(), force_mode, scc_follow_pcc, pcell_2rx, pcell_4rx, scell_2rx, scell_4rx);
+    RLOGD("setEgmcAntNR, cmd:%s", cmd_str);
+    sendATCommand(cmd_str, MSG_SET_ANTENNA_EGMC_NR);
+}
+
 static void setMode(int mode) {
     char cmd_str[32] = {0};
     sprintf(cmd_str,"%s%d","AT+ERXPATH=",mode);
@@ -131,13 +210,100 @@
     }
 }
 
-static void parseCurrentMode(char* data) {
-    RLOGD("parseCurrentMode(%d):%s",fgget, data);
+static void parseEgmcData(char* data) {
+    RLOGD("parseEGMCData(rat=%d), data=%s", inputRat, data);
     std::vector<std::string> out;
     utils::tokenize(string(data), "\n", out);
     std::string str;
     str.clear();
-    if(fgget == 0 || fgget == 1) {
+
+    // 4G response: +EGMC: "rx_path",1,0,3,15,3,12
+    // NR response: +EGMC: "nr_rx_path",3,15,3,12
+    for(auto i: out) {
+        if(i.find(CMD_SAME_EGMC) != std::string::npos) {
+            std::string splitString = i.substr(std::string(CMD_SAME_EGMC).size());
+            std::vector<std::string> getDigitalVal;
+            utils::tokenize(string(splitString), ",\n", getDigitalVal);
+            RLOGD("parseCurrentMode splitString: %s, getDigitalVal.size()=%d",
+                    splitString.c_str(), getDigitalVal.size());
+
+            if (getDigitalVal.size() < 5 &&
+                !((inputRat == RAT_NR) && getDigitalVal.size() == 1)) {
+                android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
+                RLOGD("Modem returned invalid getDigitalVal(%d): %s", getDigitalVal.size(), data);
+                return ;
+            }
+
+            try {
+                int idx_pcell_2rx = 3;
+                // Show result
+                if (inputRat == RAT_4G) {
+                    str.append("4G:");
+
+                } else if (inputRat == RAT_NR){
+                    str.append("NR:");
+                    idx_pcell_2rx = 1;
+                }
+
+                int pcell_2rx = 0, pcell_4rx = 0, scell_2rx = 0, scell_4rx = 0;
+                if ((inputRat == RAT_NR) && (getDigitalVal.size() == 1)) {
+                    pcell_2rx = 0;
+                    pcell_4rx = 0;
+                    scell_2rx = 0;
+                    scell_4rx = 0;
+
+                } else {
+                    pcell_2rx = std::stoi(getDigitalVal[idx_pcell_2rx]);
+                    pcell_4rx = std::stoi(getDigitalVal[++idx_pcell_2rx]);
+                    scell_2rx = std::stoi(getDigitalVal[++idx_pcell_2rx]);
+                    scell_4rx = std::stoi(getDigitalVal[++idx_pcell_2rx]);
+                }
+
+                RLOGD("pcell_2rx=%d, pcell_4rx=%d, scell_2rx=%d, scell_4rx=%d",
+                        pcell_2rx, pcell_4rx, scell_2rx, scell_4rx);
+
+                if (pcell_2rx >= 0 && pcell_2rx < antenna_modes_egmc_2rx.size()) {
+                    str.append("\npcell_2rx: ");
+                    str.append(antenna_modes_egmc_2rx[pcell_2rx]);
+                }
+                if (pcell_4rx >= 0 && pcell_4rx < antenna_modes_egmc_4rx.size()) {
+                    str.append("\npcell_4rx: ");
+                    str.append(antenna_modes_egmc_4rx[pcell_4rx]);
+                }
+                if (scell_2rx >= 0 && scell_2rx < antenna_modes_egmc_2rx.size()) {
+                    str.append("\nscell_2rx: ");
+                    str.append(antenna_modes_egmc_2rx[scell_2rx]);
+                }
+                if (scell_4rx >= 0 && scell_4rx < antenna_modes_egmc_4rx.size()) {
+                    str.append("\nscell_4rx: ");
+                    str.append(antenna_modes_egmc_4rx[scell_4rx]);
+                }
+
+            } catch (const out_of_range &e) {
+                android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
+                RLOGD("out of range: %s", e.what());
+                return;
+            } catch (const invalid_argument &e) {
+                android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
+                RLOGD("invalid argument: %s", e.what());
+                return;
+            }
+        }
+    }
+
+    str.append("\ndone\n");
+    RLOGD("result str=%s", str.c_str());
+    android::emResultNotify(str.c_str());
+}
+
+static void parseCurrentMode(char* data) {
+    RLOGD("parseCurrentMode(rat=%d), rsp=%s", inputRat, data);
+    std::vector<std::string> out;
+    utils::tokenize(string(data), "\n", out);
+    std::string str;
+    str.clear();
+
+    if((inputRat == RAT_4G && !utils::is97Modem())|| inputRat == RAT_3G) {
         for(auto i: out) {
             if(i.find("+ERXPATH:") != std::string::npos) {
                 try {
@@ -179,7 +345,8 @@
             }
         }
         android::emResultNotify(str.c_str());
-    } else if (fgget == 2) {
+
+    } else if (inputRat == RAT_C2K) {
         for(auto i: out) {
             if(i.find("+ERXTESTMODE:") != std::string::npos) {
                 try {
@@ -207,6 +374,13 @@
             }
         }
         android::emResultNotify(str.c_str());
+
+    } else if (inputRat == RAT_4G && utils::is97Modem()) {
+        parseEgmcData(data);
+
+    } else if(inputRat == RAT_NR) {
+        parseEgmcData(data);
+
     } else {
         RLOGE("error choose!!!");
         android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
@@ -219,19 +393,35 @@
     switch (mCurrentEmantennaFlag) {
     case MSG_QUERY_ANTENNA_MODE:
     case MSG_QUERY_ANTENNA_MODE_C2K:
+    case MSG_QUERY_ANTENNA_EGMC_4G:
+    case MSG_QUERY_ANTENNA_EGMC_NR:
         //parse antenna mode.
         if ((responselen > 0) && (response != NULL)) {
-            RLOGD("Get mode %s", response);
+            RLOGD("Get response %s", response);
             parseCurrentMode(response);
         } else {
-            RLOGD("Query antenna mode failed.");
-            sprintf(antennaretstring, "%s%s", ("Query antenna mode failed."),
-            RET_STRING_ANTENNATEST_FAIL);
+            RLOGD("Query antenna mode (rat=%d) failed.", inputRat);
+            sprintf(antennaretstring, "%s%s (rat=%d)", ("Query antenna mode failed."),
+            RET_STRING_ANTENNATEST_FAIL, inputRat);
             android::emResultNotify(antennaretstring);
         }
         android::unregisterNetwork();
         break;
+    case MSG_INIT_ANTENNA_EGMC_4G:
+        if ((responselen > 0) && (response != NULL)) {
+            setEgmcAnt4G(gEgmcParam[0], gEgmcParam[1], gEgmcParam[2], gEgmcParam[3], gEgmcParam[4], gEgmcParam[5]);
+
+        } else {
+            RLOGD("Init EGMC antenna mode (rat=%d) failed.", inputRat);
+            sprintf(antennaretstring, "%s%s (rat=%d)", ("Init antenna mode failed."),
+            RET_STRING_ANTENNATEST_FAIL, inputRat);
+            android::emResultNotify(antennaretstring);
+        }
+
+        break;
     case MSG_SET_ANTENNA_MODE:
+    case MSG_SET_ANTENNA_EGMC_4G:
+    case MSG_SET_ANTENNA_EGMC_NR:
         memset(antennaretstring, 0, sizeof(antennaretstring));
         if ((responselen > 0) && (response != NULL)) {
             RLOGD("Set successful.");
@@ -242,7 +432,6 @@
             sprintf(antennaretstring, "%s\n%s", ("Set failed."),
                     RET_STRING_ANTENNATEST_FAIL);
         }
-        android::unregisterNetwork();
         android::emResultNotify(antennaretstring);
         break;
     default:
@@ -256,47 +445,75 @@
 static void * emAntennaTestThread(void* arg)
 {
     if(fgAntennaRead){
-        if(fgget == 0) { //4G
+        if(inputRat == RAT_4G) {
             if (ModemCategory::isLteSupport()) {
-                queryCurrentMode();
+                if(utils::is97Modem()) {
+                    queryEgmcAnt4G();
+
+                } else {
+                    queryCurrentMode();
+                }
+
             } else {
                 android::emResultNotify("Antenna test don't support for 4G \ndone\n");
             }
-        } else if (fgget == 1){ //3G
+
+        } else if (inputRat == RAT_3G){
             if (ModemCategory::getModemType() == ModemCategory::MODEM_TD) {
                 android::emResultNotify("Antenna test don't support for 3G \ndone\n");
             } else {
                 queryCurrentMode();
             }
-        } else if (fgget == 2) { //C2K
+
+        } else if (inputRat == RAT_C2K) {
             if(ModemCategory::isCdma()) {
                 queryCurrentCdmaMode();
             } else {
                 android::emResultNotify("Antenna test don't support for C2K \ndone\n");
             }
+
+        } else if(inputRat == RAT_NR) {
+            if (ModemCategory::isNrSupport()) {
+                queryEgmcAntNR();
+            } else {
+                android::emResultNotify("Antenna test don't support for NR \ndone\n");
+            }
+
         } else {
             android::emResultNotify("Antenna test index error \ndone\n");
         }
 
     }else{
-        if(fgset == 0) { //4G
+        if(inputRat == RAT_4G) {
             if (ModemCategory::isLteSupport()) {
-                setMode(mAntennaMode);
+                if(utils::is97Modem()) {
+                    initEgmcAnt4G();
+                } else {
+                    setMode(mAntennaMode);
+                }
             } else {
                 android::emResultNotify("Antenna test don't support for 4G \ndone\n");
             }
-        } else if (fgset == 1){ //3G
+        } else if (inputRat == RAT_3G){
             if (ModemCategory::getModemType() == ModemCategory::MODEM_TD) {
                 android::emResultNotify("Antenna test don't support for 3G \ndone\n");
             } else {
                 setMode(mAntennaMode);
             }
-        } else if (fgset == 2) { //C2K
+        } else if (inputRat == RAT_C2K) {
             if(ModemCategory::isCdma()) {
                 setCdmaMode(mAntennaMode);
             } else {
                 android::emResultNotify("Antenna test don't support for C2K \ndone\n");
             }
+        } else if(inputRat == RAT_NR) {
+            if (ModemCategory::isNrSupport() && gEgmcParam.size() == 6) {
+                setEgmcAntNR(gEgmcParam[0], gEgmcParam[1], gEgmcParam[2], gEgmcParam[3], gEgmcParam[4], gEgmcParam[5]);
+            } else {
+                RLOGE("Antenna test don't support for NR or gEgmcParam size=%d", gEgmcParam.size());
+                android::emResultNotify("Antenna test don't support for NR \ndone\n");
+            }
+
         } else {
             android::emResultNotify("Antenna test index error \ndone\n");
         }
@@ -304,41 +521,83 @@
     pthread_exit(0);
 }
 
-int emAntennaTestStart(int argc, int *item,char *value)
+bool handleInputValue(int multilen, char *value[])
+{
+    if (multilen != 6) {
+        RLOGE("error input parameter");
+        android::emResultNotify("Antenna test parameter error, must count=6 \ndone\n");
+        printf("Please reference AT+EGMC = 1,\"rx_path\"[,<force mode>,<scc follow pcc>,<pcell_2rx>,<pcell_4rx>,<scell_2rx>,<scell_4rx>]\n");
+        printf("Example: 2 1 0 3 15 3 12\n");
+        return false;
+    }
+
+    for(int i=0; i< multilen; i++) {
+        printf("value[%d]=%d\n", i, atoi(value[i]));
+        gEgmcParam.push_back(atoi(value[i]));
+    }
+    return true;
+}
+
+int emAntennaTestStart(int argc, int *item, int multilen,char *value[])
 {
     RLOGD("emAntennaTestStart called");
     if(argc < 2){
         RLOGD("please select AntennaTest get or set :");
         return -1;
     }
+
     mCurrentEmantennaFlag = 0;
-    int classid = item[0];
+    gEgmcParam.clear();
+    inputRat = item[0];
     int operatorid = item[1];
-    if((item[0] != 0 ) && (item[0] != 1) && (item[0] != 2)){ // 0 4G 1 3G
-        RLOGD("emAntennaTestStart: invalid parameter %d, operatorid: %d",item[0], operatorid);
+    bool ret = false;
+
+    RLOGD("argc: %d, inputRat: %d, operatorid: %d\n", argc, inputRat, operatorid);
+
+    if((inputRat != RAT_NR) && (inputRat != RAT_4G) && (inputRat != RAT_3G)
+#ifdef C2K_SUPPORT
+        && (inputRat != RAT_C2K)
+#endif
+        ){
+        RLOGD("emAntennaTestStart: invalid inputRat %d, operatorid: %d", inputRat, operatorid);
         android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
         return -1;
     }
+
     switch(operatorid){
         case 0://get
         {
             fgAntennaRead = true;
-            fgget = classid;
             break;
         }
         case 1://set
         {
-            printf("argc: %d, fgset: %d\n", argc, classid);
-            printf("itme[2]: %d\n", item[2]);
-            fgset = classid;
-            if(classid == 0){ // 4G
-               mAntennaMode = item[2];
-            } else if(classid == 1) { //3G
+            printf("argc: %d, inputRat: %d, multilen: %d\n", argc, inputRat, multilen);
+
+            if(inputRat == RAT_4G){
+                if(utils::is97Modem()) {
+                    if(!handleInputValue(multilen, value)) {
+                        return (0);
+                    }
+
+                } else {
+                    printf("itme[2]: %d\n", item[2]);
+                    mAntennaMode = item[2];
+                }
+
+            } else if(inputRat == RAT_3G) {
                 mAntennaMode = item[2]+ MODE_INDEX_BASE_3G;
-            } else if (classid == 2) { //C2K
+
+            } else if (inputRat == RAT_C2K) {
                 mAntennaMode = item[2];
-            } else { // other
-                RLOGW("error classid");
+
+            } else if(inputRat == RAT_NR){
+                if(!handleInputValue(multilen, value)) {
+                    return (0);
+                }
+
+            } else {
+                RLOGE("error input rat");
                 android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
             }
             fgAntennaRead = false;
diff --git a/framework/lynq-ril-service/src/em/em_bandmode.cpp b/framework/lynq-ril-service/src/em/em_bandmode.cpp
old mode 100755
new mode 100644
index 8b33c18..9fecc19
--- a/framework/lynq-ril-service/src/em/em_bandmode.cpp
+++ b/framework/lynq-ril-service/src/em/em_bandmode.cpp
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: MediaTekProprietary
 /* Copyright Statement:
  *
  * This software/firmware and related documentation ("MediaTek Software") are
@@ -36,6 +37,7 @@
 #include <vendor-ril/telephony/ril.h>
 #include <stdlib.h>
 #include <stdio.h>
+#include <algorithm>
 #include <cutils/jstring.h>
 #include <log/log.h>
 #include <unistd.h>
@@ -70,9 +72,12 @@
 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 INDEX_NR_BAND = 12;
 static const int BAND_SET_INVALID = 1000;
 static int mSimType = -1;
 
+static const int NR_VALUES = 3;
+
 /** GSM mode bit. */
 static const int GSM_EGSM900_BIT = 1;
 static const int GSM_DCS1800_BIT = 3;
@@ -81,9 +86,15 @@
 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_QUERY_SUPPORTED_GSM = 100;
+static const int EVENT_QUERY_CURRENT_GSM = 101;
+static const int EVENT_QUERY_CURRENT_CDMA = 102;
+static const int EVENT_QUERY_SUPPORTED_NR = 103;
+static const int EVENT_QUERY_CURRENT_NR = 104;
+
 static const int EVENT_SET_GSM = 110;
+static const int EVENT_SET_CDMA = 111;
+static const int EVENT_SET_NR = 112;
 
 static const int EVENT_SET_FAIL = 1;
 static const int EVENT_RESET = 2;
@@ -98,14 +109,15 @@
 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 const std::string QUERY_SUPPORT_COMMAND_NR = "AT+EPBSEH=?";
+static const std::string QUERY_CURRENT_COMMAND_NR = "AT+EPBSEH?";
+static const std::string SET_COMMAND_NR = "AT+EPBSEH=";
+static const std::string SAME_COMMAND_NR = "+EPBSEH:";
+
 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)
@@ -116,6 +128,8 @@
 bool mIsLteExtend = false;
 int mCurrentEmbandmodeFlag = 0;
 std::vector<long> gsmValues(INDEX_BAND_MAX);
+std::vector<long> nrValues(NR_VALUES);
+
 long cdmaValues = 0;
 
 struct BandModeMap{
@@ -138,8 +152,10 @@
     BandModeMap& operator=(const BandModeMap& other) = default;
 };
 
-static std::vector<BandModeMap> mModeArray;
+static std::vector<BandModeMap> mGsmModeArray;
 static std::vector<BandModeMap> mCdmaModeArray;
+static std::vector<BandModeMap> mNRModeArray;
+
 static const std::vector<std::string> band_mode_gsm { "EGSM900", "DCS1800",
         "PCS1900", "GSM850" };
 
@@ -161,7 +177,9 @@
 
 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" };
+        "Band 41", "Band 42", "Band 43", "Band 44", "Band 45",
+        "Band 46", "Band 47", "Band 48", "Band 49", "Band 50",
+        "Band 51", "Band 52", "Band 53"};
 
 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",
@@ -220,8 +238,32 @@
         "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;
+static const std::vector<std::string> band_mode_nr {
+        "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", "Band 33", "Band 34", "Band 35",
+        "Band 36", "Band 37", "Band 38", "Band 39", "Band 40",
+        "Band 41", "Band 42", "Band 43", "Band 44", "Band 45",
+        "Band 46", "Band 47", "Band 48", "Band 49", "Band 50",
+        "Band 51", "Band 52", "Band 53", "Band 54", "Band 55",
+        "Band 56", "Band 57", "Band 58", "Band 59", "Band 60",
+        "Band 61", "Band 62", "Band 63", "Band 64", "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"};
+
+bool fgset = false;
+bool isNR = false;
+
+int len_count = -1;
 std::vector<std::string> choose_vals;
 
 static void sendATCommand(const char *cmd,int msg)
@@ -236,8 +278,8 @@
     return ;
 }
 
-static void setCurrentMode(std::vector<long> values) {
-    for (auto& m : mModeArray) {
+static void setCurrentModeGsm(std::vector<long> values) {
+    for (auto& m : mGsmModeArray) {
         if ((values[m.mIndex] & (1L << m.mBit)) == 0) {
             m.mCheck = false;
         } else {
@@ -249,8 +291,8 @@
     }
 }
 
-static void setSupportedMode(std::vector<long> values) {
-    for (auto& m : mModeArray) {
+static void setSupportedModeGsm(std::vector<long> values) {
+    for (auto& m : mGsmModeArray) {
         if ((values[m.mIndex] & (1L << m.mBit)) == 0) {
             m.mEnable = false;
         } else {
@@ -287,6 +329,68 @@
     }
 }
 
+static void setCurrentModeNR(std::vector<long> values) {
+    int temp = 0;
+    for (auto& m : mNRModeArray) {
+        if (m.mBit < 32) {
+            if ((values[0] & (1L << m.mBit)) == 0) {
+                m.mCheck = false;
+            } else {
+                if (m.mEnable) {
+                    m.mCheck = true;
+                }
+            }
+        } else if (m.mBit < 64) {
+            temp = m.mBit - 32;
+            if ((values[1] & (1L << temp)) == 0) {
+                m.mCheck = false;
+            } else {
+                if (m.mEnable) {
+                    m.mCheck = true;
+                }
+            }
+        } else {
+            temp = m.mBit - 64;
+            if ((values[2] & (1L << temp)) == 0) {
+                m.mCheck = false;
+            } else {
+                if (m.mEnable) {
+                    m.mCheck = true;
+                }
+            }
+        }
+        //RLOGD("setCurrentModeNR labels: %s, enable: %d, check: %d", m.mName.c_str(), m.mEnable, m.mCheck);
+    }
+}
+
+static void setSupportedModeNR(std::vector<long> values) {
+    int temp = 0;
+    for (auto& m : mNRModeArray) {
+        if (m.mBit < 32) {
+            if ((values[0] & (1L << m.mBit)) == 0) {
+                m.mEnable = false;
+            } else {
+                m.mEnable = true;
+            }
+        } else if (m.mBit < 64) {
+            temp = m.mBit - 32;
+            if ((values[1] & (1L << temp)) == 0) {
+                m.mEnable = false;
+            } else {
+                m.mEnable = true;
+            }
+        } else {
+            temp = m.mBit - 64;
+            if ((values[2] & (1L << temp)) == 0) {
+                m.mEnable = false;
+            } else {
+                m.mEnable = true;
+            }
+        }
+        //RLOGD("setSupportedModeNR 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);
@@ -324,6 +428,7 @@
 }
 
 static void showBandModeGsm(char* response, int msg) {
+    // Support/Current: +EPBSE: 154,262331,2316241119,482,0,0,0,0,0,0
     std::vector<std::string> out;
     utils::tokenize(string(response), "\n", out);
     for(auto i: out) {
@@ -349,8 +454,8 @@
                         RLOGD("invalid argument: %s", e.what());
                     }
                 }
-                if (msg == EVENT_QUERY_SUPPORTED) {
-                    setSupportedMode(values);
+                if (msg == EVENT_QUERY_SUPPORTED_GSM) {
+                    setSupportedModeGsm(values);
                     if (getDigitalVal.size() > 5) {
                         RLOGD("The Modem support Lte extend band");
                         mIsLteExtend = true;
@@ -359,7 +464,7 @@
                         mIsLteExtend = false;
                     }
                 } else {
-                    setCurrentMode(values);
+                    setCurrentModeGsm(values);
                 }
             } else {
                 android::emResultNotify(RET_STRING_BANDMODE_FAIL);
@@ -369,15 +474,70 @@
     }
 }
 
+static void showBandModeNR(char* response, int msg) {
+   // Support: +EPBSEH: "0000009a","000400bb","8A0F08DF000001E200000000","080800D50000012000007000"
+   // Current: +EPBSEH: "0000009a","000400bb","8A0F08DF000001E200000000","080800D50000012000007000"^M OK^M
+   std::vector<std::string> out;
+   utils::tokenize(string(response), "\n", out);
+   for(auto i: out) {
+       if(i.find(SAME_COMMAND_NR) != std::string::npos) {
+           std::string splitString = i.substr(std::string(SAME_COMMAND_NR).size());
+           RLOGD("showBandModeNR splitString: %s", splitString.c_str());
+           std::vector<std::string> getDigitalVal;
+           utils::tokenize(string(splitString), ",\n", getDigitalVal);
+           if (getDigitalVal.size() > 0) {
+               getDigitalVal[3].erase(remove(getDigitalVal[3].begin(), getDigitalVal[3].end(),'\"'));
+               std::string info = utils::addZeroForNum(string(getDigitalVal[3]), 24);
+               RLOGD("showBandModeNR tmpInfo=%s, info=%s", getDigitalVal[3].c_str(), info.c_str());
+
+               std::string string1 = info.substr(0, 8);
+               std::string string2 = info.substr(8, 8);
+               std::string string3 = info.substr(16, 8);
+
+               RLOGD("showBandModeNR string1=%s, string2=%s, string3=%s,",
+                       string1.c_str(), string2.c_str(), string3.c_str());
+
+               std::vector<long> values;
+               try {
+                   values.push_back(std::stol(string1, 0 ,16));
+                   values.push_back(std::stol(string2, 0 ,16));
+                   values.push_back(std::stol(string3, 0 ,16));
+
+                   RLOGD("showBandModeNR values[0]=%ld, values[1]=%ld, values[2]=%ld,",
+                           values[0], values[1], values[2]);
+
+               } 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_NR) {
+                   setSupportedModeNR(values);
+               } else {
+                   setCurrentModeNR(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");
+    if(flag == EVENT_QUERY_CURRENT_GSM) {
+        RLOGD("printGetBand GSM start");
         std::string msg;
-        for (auto& i : mModeArray) {
+        for (auto& i : mGsmModeArray) {
             if (i.mEnable && i.mCheck) {
                 if ((i.mIndex == INDEX_GSM_BAND) && (msg.find("GSM Mode:") == std::string::npos)) {
                     msg.append("GSM Mode:\n");
@@ -392,16 +552,37 @@
                 msg.append("\n");
             }
         }
-        for (auto& i : mCdmaModeArray) {
+
+        if (ModemCategory::isCdma()) {
+            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());
+
+    } else if (flag == EVENT_QUERY_CURRENT_NR) {
+        RLOGD("printGetBand NR start");
+        std::string msg;
+        for (auto& i : mNRModeArray) {
             if (i.mEnable && i.mCheck) {
-                if ((i.mIndex == INDEX_CDMA_BAND) && (msg.find("CDMA Mode:") == std::string::npos)) {
-                    msg.append("\nCDMA Mode: \n");
+                if ((i.mIndex == INDEX_NR_BAND) && (msg.find("NR Mode:") == std::string::npos)) {
+                    msg.append("\nNR Mode:\n");
                 }
                 msg.append("....");
                 msg.append(i.mName);
                 msg.append("\n");
             }
         }
+
         msg.append("done\n");
         android::emResultNotify(msg.c_str());
     }
@@ -413,6 +594,23 @@
     sendATCommand(msg.c_str(), EVENT_SET_CDMA);
 }
 
+static void setBandModeNR(std::vector<long> values_gsm, std::vector<long> values_nr) {
+    RLOGD("setBandModeNR gsmValues: %ld,%ld,%ld,%ld,%ld",
+            values_gsm[0],values_gsm[1],values_gsm[2],values_gsm[3],values_gsm[4]);
+    RLOGD("setBandModeNR nrValues: %ld,%ld,%ld",
+            values_nr[0],values_nr[1],values_nr[2]);
+
+    char cmd_str[1280] = {0};
+    sprintf(cmd_str,"%s\"%08x\",\"%08x\",\"%08x%08x%08x\",\"%08x%08x%08x\"",
+            SET_COMMAND_NR,
+            values_gsm[0], values_gsm[1],
+            values_gsm[2], values_gsm[3], values_gsm[4],
+            values_nr[0],  values_nr[1],  values_nr[2]);
+
+    RLOGD("setBandModeNR AT String:%s", cmd_str);
+    sendATCommand(cmd_str, EVENT_SET_NR);
+}
+
 /**
  * Set the selected modes.
  *
@@ -458,10 +656,10 @@
  *
  * @return values from the selected boxes
  */
-static std::vector<long> getValFromBox(bool judge) {
+static std::vector<long> getValFromBoxGsm(bool judge) {
     std::vector<long> values(INDEX_BAND_MAX,0);
     std::vector<long> values_temp(INDEX_BAND_MAX,0);
-    for (auto& m : mModeArray) {
+    for (auto& m : mGsmModeArray) {
         if (m.mCheck) {
             values[m.mIndex] |= 1L << m.mBit;
             values_temp[m.mIndex] |= 1L << m.mBit;
@@ -493,12 +691,44 @@
     return values;
 }
 
+/**
+ * Get the selected mode values.
+ *
+ * @return values from the selected boxes
+ */
+static std::vector<long> getValFromBoxNR() {
+    std::vector<long> values(NR_VALUES,0);
+
+    int temp = 0;
+    for (auto& m : mNRModeArray) {
+        if (m.mBit < 32) {
+            if (m.mCheck) {
+                values[0] |= 1L << m.mBit;
+            }
+        } else if (m.mBit < 64) {
+            temp = m.mBit - 32;
+            if (m.mCheck) {
+                values[1] |= 1L << temp;
+            }
+        } else {
+            temp = m.mBit - 64;
+            if (m.mCheck) {
+                values[2] |= 1L << temp;
+            }
+        }
+    }
+
+    RLOGD("getValFromBoxNR values[0]=%ld, values[1]=%ld, values[2]=%ld,",
+            values[0], values[1], values[2]);
+    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");
+    RLOGD("printSupportBand, fgset(%d), len_count(%d), flag(%d)",fgset, len_count, flag);
+    if(fgset && (len_count == 0) && (flag == EVENT_QUERY_CURRENT_GSM)) {
+        RLOGD("printSupportBand GSM start");
         std::string msg;
-        for (auto& i : mModeArray) {
+        for (auto& i : mGsmModeArray) {
             if (i.mEnable) {
                 if ((i.mIndex == INDEX_GSM_BAND) && (msg.find("GSM Mode:") == std::string::npos)) {
                     msg.append("GSM Mode:\n");
@@ -520,11 +750,39 @@
                 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");
+
+        if (ModemCategory::isCdma()) {
+            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());
+
+    } else if(fgset && (len_count == 0) && (flag == EVENT_QUERY_CURRENT_NR)) {
+        RLOGD("printSupportBand NR start");
+        std::string msg;
+        for (auto& i : mNRModeArray) {
+            if (i.mEnable) {
+                if ((i.mIndex == INDEX_NR_BAND) && (msg.find("NR Mode:") == std::string::npos)) {
+                    msg.append("\nNR Mode:\n");
+                }
+
                 msg.append("....");
                 msg.append("(");
                 msg.append(std::to_string(i.mIndex));
@@ -533,10 +791,11 @@
                 msg.append("): ");
                 msg.append(i.mName);
                 msg.append("....");
-                msg.append(i.mIndex ? "true":"false");
+                msg.append(i.mCheck ? "true":"false");
                 msg.append("\n");
             }
         }
+
         msg.append("done\n");
         android::emResultNotify(msg.c_str());
     }
@@ -552,42 +811,52 @@
     return NULL;
 }
 
+static void* setNRBandMode(void* arg) {
+    setBandModeNR(gsmValues, nrValues);
+    return NULL;
+}
+
 static void emBandmodeAtCmdHandle(char* response, int responselen) {
-    RLOGD("emBandmodeAtCmdHandle, flag=%d, data=%s", mCurrentEmbandmodeFlag, response);
+    RLOGD("emBandmodeAtCmdHandle, mCurrentEmbandmodeFlag=%d, rsp=%s", mCurrentEmbandmodeFlag, response);
     switch (mCurrentEmbandmodeFlag) {
-    case EVENT_QUERY_CURRENT_CDMA: {
+    case EVENT_QUERY_SUPPORTED_GSM:
+    {
         if ((responselen > 0) && (response != NULL)) {
-            showBandModeCdma(response, EVENT_QUERY_CURRENT_CDMA);
+            showBandModeGsm(response, EVENT_QUERY_SUPPORTED_GSM);
         } else {
             android::emResultNotify(RET_STRING_BANDMODE_FAIL);
-            RLOGD("don't support(%d)", EVENT_QUERY_CURRENT_CDMA);
+            RLOGD("don't support(%d)", EVENT_QUERY_SUPPORTED_GSM);
         }
         BLOCK_WAKEUP();
         break;
     }
-    case EVENT_QUERY_SUPPORTED:
+    case EVENT_QUERY_SUPPORTED_NR:
     {
         if ((responselen > 0) && (response != NULL)) {
-            showBandModeGsm(response, EVENT_QUERY_SUPPORTED);
+            showBandModeNR(response, EVENT_QUERY_SUPPORTED_NR);
         } else {
             android::emResultNotify(RET_STRING_BANDMODE_FAIL);
-            RLOGD("don't support(%d)", EVENT_QUERY_SUPPORTED);
+            RLOGD("don't support(%d)", EVENT_QUERY_SUPPORTED_NR);
         }
         BLOCK_WAKEUP();
         break;
     }
-    case EVENT_QUERY_CURRENT:
+    case EVENT_QUERY_CURRENT_GSM:
     {
         if ((responselen > 0) && (response != NULL)) {
-            showBandModeGsm(response, EVENT_QUERY_CURRENT);
+            showBandModeGsm(response, EVENT_QUERY_CURRENT_GSM);
         } else {
             android::emResultNotify(RET_STRING_BANDMODE_FAIL);
-            RLOGD("don't support(%d)", EVENT_QUERY_CURRENT);
+            RLOGD("don't support(%d)", EVENT_QUERY_CURRENT_GSM);
         }
-        printGetBand(EVENT_QUERY_CURRENT);
-        printSupportBand(EVENT_QUERY_CURRENT);
+
+        if (!isNR) {
+            printGetBand(EVENT_QUERY_CURRENT_GSM);
+            printSupportBand(EVENT_QUERY_CURRENT_GSM);
+        }
         BLOCK_WAKEUP();
-        if(fgset && (count > 0)) {
+
+        if(fgset && !isNR && (len_count > 0)) {
             for(auto& val : choose_vals) {
                 RLOGD("handle values: %s", val.c_str());
                 std::vector<std::string> out;
@@ -600,19 +869,21 @@
                             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) {
+                            for (auto& i : mGsmModeArray) {
                                 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 (ModemCategory::isCdma()) {
+                                for (auto& i : mCdmaModeArray) {
                                     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);
+                                        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);
+                                        }
                                     }
                                 }
                             }
@@ -633,8 +904,11 @@
                     return;
                 }
             }
-            cdmaValues = getValFromBoxCdma();
-            gsmValues = getValFromBox(true);
+
+            if (ModemCategory::isCdma()) {
+                cdmaValues = getValFromBoxCdma();
+            }
+            gsmValues = getValFromBoxGsm(true);
             pthread_t setBandMode_thread;
             pthread_create(&setBandMode_thread,NULL, setGsmBandMode, NULL);
         }
@@ -658,6 +932,88 @@
         }
         break;
     }
+    case EVENT_QUERY_CURRENT_NR:
+    {
+        if ((responselen > 0) && (response != NULL)) {
+            showBandModeNR(response, EVENT_QUERY_CURRENT_NR);
+        } else {
+            android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+            RLOGD("don't support(%d)", EVENT_QUERY_CURRENT_NR);
+        }
+
+        if (isNR) {
+            printGetBand(EVENT_QUERY_CURRENT_NR);
+            printSupportBand(EVENT_QUERY_CURRENT_NR);
+        }
+        BLOCK_WAKEUP();
+
+        if(fgset && isNR && (len_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 : mNRModeArray) {
+                                if((i.mIndex == index) && (i.mBit == bit)) {
+                                    i.mCheck = check;
+                                    RLOGD("set NR 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;
+                }
+            }
+            nrValues = getValFromBoxNR();
+            gsmValues = getValFromBoxGsm(true);
+            pthread_t setBandMode_thread;
+            pthread_create(&setBandMode_thread,NULL, setNRBandMode, NULL);
+        }
+
+        break;
+    }
+    case EVENT_SET_NR:
+    {
+        BLOCK_WAKEUP();
+        if ((responselen > 0) && (response != NULL)) {
+            RLOGD("Set NR bandmode success: %s", response);
+            android::emResultNotify(RET_STRING_BANDMODE_SUCCESS);
+        } else {
+            RLOGD("Set NR bandmode fail ");
+            android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+        }
+        break;
+    }
+    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_SET_CDMA:
     {
         BLOCK_WAKEUP();
@@ -689,63 +1045,81 @@
 /**
  * Query Modem supported band modes.
  */
-static void querySupportMode() {
+static void querySupportModeGSM() {
     //SAME_COMMAND
-    RLOGD("querySupportMode AT String: %s", QUERY_SUPPORT_COMMAND.c_str());
-    sendATCommand(QUERY_SUPPORT_COMMAND.c_str(), EVENT_QUERY_SUPPORTED);
+    RLOGD("querySupportModeGSM AT String: %s", QUERY_SUPPORT_COMMAND.c_str());
+    sendATCommand(QUERY_SUPPORT_COMMAND.c_str(), EVENT_QUERY_SUPPORTED_GSM);
 }
 
 /**
  * Query Modem is being used band modes.
  */
-static void queryCurrentMode() {
+static void queryCurrentModeGSM() {
     //SAME_COMMAND
-    RLOGD("queryCurrentMode AT String: %s", QUERY_CURRENT_COMMAND.c_str());
-    sendATCommand(QUERY_CURRENT_COMMAND.c_str(), EVENT_QUERY_CURRENT);
+    RLOGD("queryCurrentModeGSM AT String: %s", QUERY_CURRENT_COMMAND.c_str());
+    sendATCommand(QUERY_CURRENT_COMMAND.c_str(), EVENT_QUERY_CURRENT_GSM);
+}
+
+/**
+ * Query NR Modem supported band modes.
+ */
+static void querySupportModeNR() {
+    //SAME_COMMAND
+    RLOGD("querySupportModeNR AT String: %s", QUERY_SUPPORT_COMMAND_NR.c_str());
+    sendATCommand(QUERY_SUPPORT_COMMAND_NR.c_str(), EVENT_QUERY_SUPPORTED_NR);
+}
+
+/**
+ * Query NR Modem is being used band modes.
+ */
+static void queryCurrentModeNR() {
+    //SAME_COMMAND
+    RLOGD("queryCurrentModeNR AT String: %s", QUERY_CURRENT_COMMAND_NR.c_str());
+    sendATCommand(QUERY_CURRENT_COMMAND_NR.c_str(), EVENT_QUERY_CURRENT_NR);
 }
 
 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);
+        mGsmModeArray.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);
+        mGsmModeArray.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);
+        mGsmModeArray.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);
+        mGsmModeArray.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);
+        mGsmModeArray.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);
+        mGsmModeArray.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);
+        mGsmModeArray.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);
+        mGsmModeArray.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);
+        mGsmModeArray.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);
+        mGsmModeArray.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);
+        mGsmModeArray.emplace_back(band_mode_wcdma[i], INDEX_UMTS_BAND, i, false, false);
     }
 }
 
@@ -755,12 +1129,21 @@
     }
 }
 
+static void initNRArray() {
+    for (int i = 0; i < band_mode_nr.size(); i++) {
+        mNRModeArray.emplace_back(band_mode_nr[i], INDEX_NR_BAND, i, false, false);
+    }
+}
+
 static void * emBandmodeThread(void* arg)
 {
-    mModeArray.clear();
+    mGsmModeArray.clear();
     mCdmaModeArray.clear();
+    mNRModeArray.clear();
+
     initGsmArray();
     int modemType = ModemCategory::getModemType();
+
     if (modemType == TDSCDMA && ModemCategory::isCapabilitySim(mSimType)) {
         initTdscdmaArray();
         if (ModemCategory::isLteSupport()) {
@@ -782,14 +1165,24 @@
         }
     }
 
+#ifdef C2K_SUPPORT
     if (mSimType == 0 && ModemCategory::isCdma() && !utils::is90Modem()) {
         initCdmaArray();
     }
     if (ModemCategory::isCdma() && !utils::is90Modem() && (mSimType == 0)) {
         queryCurrentCdmaMode();
     }
-    querySupportMode();
-    queryCurrentMode();
+#endif
+
+    querySupportModeGSM();
+    queryCurrentModeGSM();
+
+    if (utils::isMt2735()/* && ModemCategory.CheckViceSimNRCapability(mSimType)*/) {
+        initNRArray();
+        querySupportModeNR();
+        queryCurrentModeNR();
+    }
+
     pthread_exit(0);
 }
 
@@ -797,7 +1190,9 @@
 int emBandmodeStart(int len,int *item,int multilen,char *value[])
 {
     mSimType = get_default_sim_all_except_data();
-    RLOGD("emBandmodeStart called : simType:%d", mSimType);
+    RLOGD("emBandmodeStart called : simType:%d, len=%d, item[0]=%d, multilen=%d",
+            mSimType, len, item[0], multilen);
+
     //1. reset to default: select all supported bands: AT+EPBSE=255,63355
     if(len < 1)
     {
@@ -805,24 +1200,53 @@
         android::emResultNotify(RET_STRING_BANDMODE_FAIL);
         return -1;
     }
-    if((item[0] > 1 ) || (item[0] < 0)){
+    if((item[0] > 2 ) || (item[0] < 0)){
         RLOGD("emBandmodeStart: invalid parameter %d",item[0]);
         android::emResultNotify(RET_STRING_BANDMODE_FAIL);
         return -1;
     }
-    if(item[0] == 0){
+
+    int INDEX_GSM_GET=0, INDEX_GSM_SET=1, INDEX_NR_GET=2, INDEX_NR_SET=3;
+
+    // 1. Get current GSM band
+    if(item[0] == INDEX_GSM_GET){
         fgset = false;
-    }else{
+        isNR = false;
+
+    // 2. Set GSM band
+    } else if(item[0] == INDEX_GSM_SET){
         fgset = true;
-        count = multilen;
-        RLOGD("emBandmodeStart count = %d", count);
+        isNR = false;
+
+        len_count = multilen;
+        RLOGD("emBandmodeStart count = %d", len_count);
         choose_vals.clear();
-        if(count > 0){
-            for(int i=0; i< count; i++) {
+        if(len_count > 0){
+            for(int i=0; i< len_count; i++) {
+                choose_vals.push_back(value[i]);
+            }
+        }
+
+    // 3. Get current NR band
+    } else if(item[0] == INDEX_NR_GET){
+        fgset = false;
+        isNR = true;
+
+    // 4. Set NR band
+    } else if(item[0] == INDEX_NR_SET){
+        fgset = true;
+        isNR = true;
+
+        len_count = multilen;
+        RLOGD("emBandmodeStart count = %d", len_count);
+        choose_vals.clear();
+        if(len_count > 0){
+            for(int i=0; i< len_count; i++) {
                 choose_vals.push_back(value[i]);
             }
         }
     }
+
     mCurrentEmbandmodeFlag = 0;
     android::registerForATcmdResponse(emBandmodeAtCmdHandle);
     pthread_t embandmode_thread;
diff --git a/framework/lynq-ril-service/src/em/em_hspa.cpp b/framework/lynq-ril-service/src/em/em_hspa.cpp
old mode 100755
new mode 100644
index a2df7c5..0782990
--- a/framework/lynq-ril-service/src/em/em_hspa.cpp
+++ b/framework/lynq-ril-service/src/em/em_hspa.cpp
@@ -1,3 +1,4 @@
+//SPDX-License-Identifier: MediaTekProprietary
 /* Copyright Statement:
  *
  * This software/firmware and related documentation ("MediaTek Software") are
@@ -63,38 +64,55 @@
     "HSDPA on\nHSUPA on\nHSPA+ on\n",
 };
 
+char *ca_info_state_array[] = {
+    "0 CA_CONFIGURED: NW configure CA\n",
+    "1 CA_NOT_CONFIGURED: NW remove CA configuration or CA configured is invalid\n",
+    "2 CA_ACTIVATED: Lower layer use CA to transfer data\n",
+    "3 CA_DEACTIVATED: Lower layer does not use CA to transfer data\n",
+};
+
 const int EVENT_HSPA_INFO = 1;
 //const int EVENT_DC_HSPA_INFO = 2;
 const int EVENT_SET_HSPA = 3;
-#define QUERY_CMD "AT+EHSM?"
-#define SET_CMD "AT+EHSM="
-#define RESPONSE_CMD "+EHSM:"
-int mCurrentEmhspaFlag = 0;
+const int EVENT_CA_INFO = 4;
+
+#define HSPA_QUERY_CMD "AT+EHSM?"
+#define HSPA_SET_CMD "AT+EHSM="
+#define HSPA_RESPONSE_CMD "+EHSM:"
+int mCurrentFlag = 0;
 int hspamode = 0;
+int intput_index = 0;
+
+#define ECAINFO_QUERY_CMD "AT+ECAINFO?"
+#define ECAINFO_RESPONSE_CMD "+ECAINFO:"
 
 void  sendATCommand_ehspa(const char *cmd,int msg)
 {
-    mCurrentEmhspaFlag = msg;
+    mCurrentFlag = msg;
     emSendATCommand(cmd, Radio_capability_switch_util::get_main_capability_phone_id());
     return ;
 }
 
 void showHspa(int mode) {
+    std::string str;
     RLOGD("showHspa, mode=%d", mode);
+
     if (mode < 0 || mode >= 4) {
         RLOGD("Modem return invalid mode: %d", mode);
         android::emResultNotify(RET_STRING_HSPA_FAIL);
         return;
     }
     if (WorldPhoneUtil::getModemType() == WorldPhoneUtil::MODEM_TD) {
-        android::emResultNotify(hspa_info_mode_array_td[mode]);
+        str = hspa_info_mode_array_td[mode];
     } else {
-        android::emResultNotify(hspa_info_mode_array_fd[mode]);
+        str = hspa_info_mode_array_fd[mode];
     }
+    str += "\ndone\n";
+    android::emResultNotify(str.c_str());
 }
 
 void parseHspaAtCmd(const char* line) {
-    if (strstr(line, RESPONSE_CMD) != NULL) {
+    if (strstr(line, HSPA_RESPONSE_CMD) != NULL) {
         AtLine* atLine = new AtLine(line, NULL);
         int err;
         atLine->atTokStart(&err);
@@ -114,8 +132,67 @@
     }
 }
 
-void emHspaAtCmdHandle(char*response, int responselen) {
-    switch (mCurrentEmhspaFlag) {
+void parseCAInfoAtCmd(const char* line) {
+    AtLine* atLine = new AtLine(line, NULL);
+    int err, ca_info, pcell_bw, scell_bw1, scell_bw2, scell_bw3, scell_bw4;
+    char cainfo_str[1024] = {0};
+
+    atLine->atTokStart(&err);
+    if (err < 0) {
+        RLOGW("this is not a valid response string");
+        goto invalid;
+    }
+
+    //+ECAINFO: <ca_info>,<pcell_bw>,<scell_bw1>, <scell_bw2>,<scell_bw3>,<scell_bw4>
+    ca_info = atLine->atTokNextint(&err);
+    if (err < 0) {
+        RLOGW("parse ca_info fail");
+        goto invalid;
+    }
+    if (ca_info < 0 || ca_info >= 4) {
+        RLOGW("ca_info return invalid state: %d", ca_info);
+        goto invalid;
+    }
+    pcell_bw = atLine->atTokNextint(&err);
+    if (err < 0) {
+        RLOGW("parse pcell_bw fail");
+        goto invalid;
+    }
+    scell_bw1 = atLine->atTokNextint(&err);
+    if (err < 0) {
+        RLOGW("parse scell_bw1 fail");
+        goto invalid;
+    }
+    scell_bw2 = atLine->atTokNextint(&err);
+    if (err < 0) {
+        RLOGW("parse scell_bw2 fail");
+        goto invalid;
+    }
+    scell_bw3 = atLine->atTokNextint(&err);
+    if (err < 0) {
+        RLOGW("parse scell_bw3 fail");
+        goto invalid;
+    }
+    scell_bw4= atLine->atTokNextint(&err);
+    if (err < 0) {
+        RLOGW("parse scell_bw4 fail");
+        goto invalid;
+    }
+
+    sprintf(cainfo_str, "\n%s\npcell_bw=%d\nscell_bw1=%d\nscell_bw2=%d\nscell_bw3=%d\nscell_bw4=%d\ndone\n",
+            ca_info_state_array[ca_info], pcell_bw, scell_bw1, scell_bw2, scell_bw3, scell_bw4);
+    android::emResultNotify(cainfo_str);
+    delete atLine;
+    return;
+
+invalid:
+    android::emResultNotify(RET_STRING_HSPA_FAIL);
+    delete atLine;
+}
+
+
+void emAtCmdHandle(char*response, int responselen) {
+    switch (mCurrentFlag) {
         case EVENT_HSPA_INFO:
         {
             //parse hspa mode.
@@ -139,6 +216,17 @@
             }
             break;
         }
+        case EVENT_CA_INFO:
+        {
+            if ((responselen > 0) && (response != NULL)) {
+                RLOGD("+ECAINFO response: %s\n",response);
+                parseCAInfoAtCmd(response);
+            }
+            else {
+                android::emResultNotify(RET_STRING_HSPA_FAIL);
+                RLOGD("send fail ");
+            }
+        }
         default:
             break;
     }
@@ -148,12 +236,23 @@
 //create thread to send command
 void * emHspaThread(void* arg)
 {
-    char cmd_str[32] = {0};
-    //sprintf(cmd_str,"%s%d,0", SET_CMD,hspamode);
-    //sendATCommand_ehspa(cmd_str,EVENT_SET_HSPA);
-    sendATCommand_ehspa(QUERY_CMD,EVENT_HSPA_INFO);
-    android::unregisterNetwork();
-    //android::emResultNotify(RET_STRING_HSPA_SUCCESS);
+    // HSPA
+    if (intput_index == 0) {
+        RLOGD("emHspaThread, query HSPA");
+
+        //char cmd_str[32] = {0};
+        //sprintf(cmd_str,"%s%d,0", HSPA_SET_CMD,hspamode);
+        //sendATCommand_ehspa(cmd_str,EVENT_SET_HSPA);
+        sendATCommand_ehspa(HSPA_QUERY_CMD,EVENT_HSPA_INFO);
+        //android::unregisterNetwork();
+        //android::emResultNotify(RET_STRING_HSPA_SUCCESS);
+
+    // Send AT+ECAINFO
+    } else if (intput_index == 1) {
+        RLOGD("emHspaThread, query CA information");
+        sendATCommand_ehspa(ECAINFO_QUERY_CMD, EVENT_CA_INFO);
+    }
+
     pthread_exit(0);
 }
 
@@ -167,15 +266,19 @@
         android::emResultNotify(RET_STRING_HSPA_FAIL);
         return -1;
     }
-    if((item[0] > 1 ) || (item[0] < 0)){
-        RLOGD("emHspaStart: invalid parameter %d",item[0]);
+
+    intput_index = item[0];
+    RLOGD("emHspaStart, intput_index=%d", intput_index);
+    if((intput_index > 1 ) || (intput_index < 0)){
+        RLOGD("emHspaStart: invalid parameter %d", intput_index);
         android::emResultNotify(RET_STRING_HSPA_FAIL);
         return -1;
     }
+
     //int modemapping[2] = {0,2};
-    mCurrentEmhspaFlag = 0;
+    mCurrentFlag = 0;
     //hspamode = modemapping[item[0]];
-    android::registerForATcmdResponse(emHspaAtCmdHandle);
+    android::registerForATcmdResponse(emAtCmdHandle);
     pthread_t emhspa_thread;
     pthread_create(&emhspa_thread,NULL, emHspaThread, NULL);
     return (0);
diff --git a/framework/lynq-ril-service/src/em/em_modemtest.cpp b/framework/lynq-ril-service/src/em/em_modemtest.cpp
old mode 100755
new mode 100644
index 30c2d7f..ba4b5eb
--- a/framework/lynq-ril-service/src/em/em_modemtest.cpp
+++ b/framework/lynq-ril-service/src/em/em_modemtest.cpp
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: MediaTekProprietary
 /* Copyright Statement:
  *
  * This software/firmware and related documentation ("MediaTek Software") are
@@ -136,7 +137,7 @@
     sendATCommand_modemtest(cmd.c_str(), message);
     sendATCommand_modemtest("AT+RFSSYNC", -1);
 }
-
+#ifdef C2K_SUPPORT
 void setCdmaOption() {
     if (modem_option[0] == INDEX_SPIRENT) {
         sendATCommandCdma("\"SPIRENT\"", MODEM_CDMA);
@@ -144,6 +145,7 @@
         sendATCommandCdma("\"NONE\"", MODEM_CDMA);
     }
 }
+#endif
 void  sendATCommand_modemtest(const char *str,int flag,int msg)
 {
     char cmd[32] = {0};
@@ -324,12 +326,14 @@
             }
             break;
         }
+#ifdef C2K_SUPPORT
         case MODEM_CDMA:
         {
             RLOGD("modemTestProcess MODEM_CDMA");
             setCdmaOption();
             break;
         }
+#endif
         case MODEM_FACTORY:
         {
             RLOGD("modemTestProcess MODEM_FACTORY");
@@ -456,7 +460,7 @@
         android::emResultNotify(RET_STRING_MODEMTEST_FAIL);
         return -1;
     }
-    int idmapping[7] = {MODEM_NONE,MODEM_CTA,MODEM_FTA,MODEM_IOT,MODEM_FACTORY,MODEM_FACTORY, MODEM_CDMA};
+    int idmapping[7] = {MODEM_NONE,MODEM_CTA,MODEM_FTA,MODEM_IOT,MODEM_OPERATOR,MODEM_FACTORY, MODEM_CDMA};
     RLOGD("emModemtestStart called item[0]: %d", item[0]);
     modem_id = idmapping[item[0]];
     modem_option_cnt = multicnt;
diff --git a/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTest.cpp b/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTest.cpp
old mode 100755
new mode 100644
index 172ba35..1b08166
--- a/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTest.cpp
+++ b/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTest.cpp
@@ -1,3 +1,4 @@
+//SPDX-License-Identifier: MediaTekProprietary
 /* Copyright Statement:
  *
  * This software/firmware and related documentation ("MediaTek Software") are
@@ -51,6 +52,7 @@
 #include "rfdesense/RfDesenseTxTestGsm.h"
 #include "rfdesense/RfDesenseTxTestLte.h"
 #include "rfdesense/RfDesenseTxTestTd.h"
+#include "rfdesense/RfDesenseTxTestNr.h"
 #include "util/log_extra.h"
 #include "util/utils.h"
 
@@ -65,12 +67,23 @@
 const int RfDesenseTxTest::STATE_STOPPED = 2;
 
 const int RfDesenseTxTest::MSG_START_TX = 1;
+const int RfDesenseTxTest::MSG_CONTINUE_TX = 2;
 const int RfDesenseTxTest::MSG_NEXT_RAT = 4;
 const int RfDesenseTxTest::MSG_READ_POWER = 10;
 const int RfDesenseTxTest::MSG_EWMPOLICY_TDSCDMA = 12;
 const int RfDesenseTxTest::MSG_EWMPOLICY_WCDMA = 13;
 const int RfDesenseTxTest::MSG_ECSRA = 14;
 const int RfDesenseTxTest::MSG_SWITCH_RAT_DONE = 15;
+const int RfDesenseTxTest::MSG_NR_READ_POWER = 20;
+
+int RfDesenseTxTest::INDEX_GSM = -1;
+int RfDesenseTxTest::INDEX_TDSCDMA = -1;
+int RfDesenseTxTest::INDEX_WCDMA = -1;
+int RfDesenseTxTest::INDEX_LTE_FDD = -1;
+int RfDesenseTxTest::INDEX_LTE_TDD = -1;
+int RfDesenseTxTest::INDEX_NR = -1;
+int RfDesenseTxTest::INDEX_CDMA_EVDO = -1;
+int RfDesenseTxTest::INDEX_CDMA_1X = -1;
 
 int RfDesenseTxTest::mState = STATE_NONE;
 
@@ -81,6 +94,8 @@
 long RfDesenseTxTest::mCheckLimit = 2;
 long RfDesenseTxTest::mReadbackInterval = 5;
 
+const static std::string CMD_SAME_EGMC = "+EGMC:";
+
 const std::string RfDesenseTxTest::KEY_GSM_ATCMD = "gsm_at_cmd";
 const std::string RfDesenseTxTest::KEY_TDSCDMA_ATCMD = "tdscdma_at_cmd";
 const std::string RfDesenseTxTest::KEY_WCDMA_ATCMD = "wcdma_at_cmd";
@@ -93,42 +108,124 @@
 const std::string RfDesenseTxTest::KEY_CHECK_LIMIT = "check_limit";
 const std::string RfDesenseTxTest::KEY_READBACK_INTREVAL = "readback_interval";
 
-const std::string RfDesenseTxTest::DEFAULT_GSM_ATCMD =
-            "AT+ERFTX=2,1,190,4100,128,0,5,0";
+const std::string RfDesenseTxTest::DEFAULT_GSM_ATCMD = "AT+ERFTX=2,1,190,4100,128,0,5,0";
 const std::string RfDesenseTxTest::DEFAULT_TDSCDMA_ATCMD = "AT+ERFTX=0,0,1,10087,24";
 const std::string RfDesenseTxTest::DEFAULT_WCDMA_ATCMD = "AT+ERFTX=0,0,1,9750,23";
-const std::string RfDesenseTxTest::DEFAULT_LTE_FDD_ATCMD =
-            "AT+ERFTX=6,0,1,3,3,17475,1,0,0,0,1,0,23";
-const std::string RfDesenseTxTest::DEFAULT_LTE_TDD_ATCMD =
-            "AT+ERFTX=6,0,1,38,3,25950,0,0,0,0,1,0,23";
+const std::string RfDesenseTxTest::DEFAULT_LTE_FDD_ATCMD = "AT+ERFTX=6,0,1,3,3,17475,1,0,0,0,1,0,23";
+const std::string RfDesenseTxTest::DEFAULT_LTE_TDD_ATCMD = "AT+ERFTX=6,0,1,38,3,25950,0,0,0,0,1,0,23";
+const std::string RfDesenseTxTest::DEFAULT_NR_ATCMD = "AT+EGMC=1,\"NrForcedTx\",2,1,1950000,23";
 const std::string RfDesenseTxTest::DEFAULT_CDMA_EVDO_ATCMD = "AT+ERFTX=13,4,384,0,83";
 const std::string RfDesenseTxTest::DEFAULT_CDMA_1X_ATCMD = "AT+ECRFTX=1,384,0,83,0";
 
 const std::string RfDesenseTxTest::DEFAULT_CDMA_EVDO_ATCMD_93before =
             "AT+ERFTX=1,384,0,83,1";
 
-const std::vector<std::string> RfDesenseTxTest::mRatName = { "GSM", "TDSCDMA", "WCDMA",
-            "LTE(FDD)", "LTE(TDD)", "CDMA(EVDO)", "CDMA(1X)" };
-std::vector<std::string> RfDesenseTxTest::mRatCmdStart = { DEFAULT_GSM_ATCMD,
-            DEFAULT_TDSCDMA_ATCMD, DEFAULT_WCDMA_ATCMD, DEFAULT_LTE_FDD_ATCMD,
-            DEFAULT_LTE_TDD_ATCMD, DEFAULT_CDMA_EVDO_ATCMD,
-            DEFAULT_CDMA_1X_ATCMD };
+const std::vector<std::string> RfDesenseTxTest::mRatName = {
+            "GSM"
+#ifndef TARGET_PLATFORM_MT2735
+            , "TDSCDMA"
+#endif
+            , "WCDMA"
+            , "LTE(FDD)", "LTE(TDD)"
+#ifdef TARGET_PLATFORM_MT2735
+            , "NR"
+#endif
+#ifdef C2K_SUPPORT
+            ,"CDMA(EVDO)", "CDMA(1X)"
+#endif
+            };
+std::vector<std::string> RfDesenseTxTest::mRatCmdStart = {
+            DEFAULT_GSM_ATCMD
+#ifndef TARGET_PLATFORM_MT2735
+            , DEFAULT_TDSCDMA_ATCMD
+#endif
+            , DEFAULT_WCDMA_ATCMD
+            , DEFAULT_LTE_FDD_ATCMD, DEFAULT_LTE_TDD_ATCMD
+#ifdef TARGET_PLATFORM_MT2735
+            , DEFAULT_NR_ATCMD
+#endif
+#ifdef C2K_SUPPORT
+            , DEFAULT_CDMA_EVDO_ATCMD, DEFAULT_CDMA_1X_ATCMD
+#endif
+            };
 
-std::vector<std::string> RfDesenseTxTest::mRatCmdStop = { "AT+ERFTX=2,0",
-            "AT+ERFTX=0,1", "AT+ERFTX=0,1", "AT+ERFTX=6,0,0", "AT+ERFTX=6,0,0",
-            "AT+ERFTX=13,5", "AT+ECRFTX=0" };
+std::vector<std::string> RfDesenseTxTest::mRatCmdStop = {
+            "AT+ERFTX=2,0"
+#ifndef TARGET_PLATFORM_MT2735
+            , "AT+ERFTX=0,1"
+#endif
+            , "AT+ERFTX=0,1"
+            , "AT+ERFTX=6,0,0", "AT+ERFTX=6,0,0"
+#ifdef TARGET_PLATFORM_MT2735
+            , "AT+EGMC=1,\"NrForcedTx\",0"
+#endif
+#ifdef C2K_SUPPORT
+            ,"AT+ERFTX=13,5", "AT+ECRFTX=0"
+#endif
+            };
 
- std::vector<std::string> RfDesenseTxTest::mRatCmdSwitch = { "AT+ERAT=0", "AT+ERAT=1",
-            "AT+ERAT=1", "AT+ERAT=6,4", "AT+ERAT=6,4", "AT+ERAT=7,64",
-            "AT+ERAT=7,32" };
+ std::vector<std::string> RfDesenseTxTest::mRatCmdSwitch = {
+            "AT+ERAT=0"
+#ifndef TARGET_PLATFORM_MT2735
+            , "AT+ERAT=1"
+#endif
+            , "AT+ERAT=1"
+            , "AT+ERAT=6,4", "AT+ERAT=6,4"
+#ifdef TARGET_PLATFORM_MT2735
+            , "AT+ERAT=22,128"
+#endif
+#ifdef C2K_SUPPORT
+            , "AT+ERAT=7,64", "AT+ERAT=7,32"
+#endif
+            };
 
-std::vector<std::string> RfDesenseTxTest::mRatCmdPowerRead = { "", "AT+ERFTX=0,3",
-            "AT+ERFTX=0,3", "AT+ERFTX=6,1", "AT+ERFTX=6,1", "AT+ERFTX=13,3",
-            "AT+ERFTX=13,3" };
-std::vector<std::string> RfDesenseTxTest::mRatBand = { "19", "1", "1", "3", "38", "0", "0" };
-std::vector<std::string> RfDesenseTxTest::mRatPowerSet = { "19", "10", "24", "23", "23", "23", "23" };
-std::vector<bool> RfDesenseTxTest::mRatCheck = {false, false,false,false,false,false,false};
-std::vector<bool> RfDesenseTxTest::mSendState = {false, false,false,false,false,false,false};
+std::vector<std::string> RfDesenseTxTest::mRatCmdPowerRead = {
+            ""
+#ifndef TARGET_PLATFORM_MT2735
+            , "AT+ERFTX=0,3"
+#endif
+            , "AT+ERFTX=0,3"
+            , "AT+ERFTX=6,1", "AT+ERFTX=6,1"
+#ifdef TARGET_PLATFORM_MT2735
+            , "AT+EGMC=0,\"NrFetchTxPwr\""
+#endif
+#ifdef C2K_SUPPORT
+            , "AT+ERFTX=13,3", "AT+ERFTX=13,3"
+#endif
+            };
+
+std::vector<std::string> RfDesenseTxTest::mRatBand = {
+            "19"
+#ifndef TARGET_PLATFORM_MT2735
+            , "1"
+#endif
+            , "1"
+            , "3", "38"
+#ifdef TARGET_PLATFORM_MT2735
+            , "1"
+#endif
+#ifdef C2K_SUPPORT
+            , "0", "0"
+#endif
+            };
+
+std::vector<std::string> RfDesenseTxTest::mRatPowerSet = {
+            "19"
+#ifndef TARGET_PLATFORM_MT2735
+            , "10"
+#endif
+            , "24"
+            , "23", "23"
+#ifdef TARGET_PLATFORM_MT2735
+            , "23"
+#endif
+#ifdef C2K_SUPPORT
+            , "23", "23"
+#endif
+            };
+
+std::vector<bool> RfDesenseTxTest::mRatCheck = {false, false, false, false, false, false, false, false};
+std::vector<bool> RfDesenseTxTest::mSendState = {false, false, false, false, false, false, false, false};
 std::string RfDesenseTxTest::str_msg = "";
 bool RfDesenseTxTest::trm_flag = false;
 int RfDesenseTxTest::phone_id = 0;
@@ -158,6 +255,7 @@
                 while(!isRadioOn((RIL_SOCKET_ID)phone_id)) {
                     LOG_D(LOG_TAG, "radio isn't on");
                     std::this_thread::sleep_for(std::chrono::milliseconds(200));
+                    turnOnRf();
                 }
                 //turnOnRf();
                 LOG_D(LOG_TAG, "radio on again");
@@ -200,7 +298,7 @@
     if (mCurrectRatInfo) {
         mCurrectRatInfo->setRatSendState(true);
         rf_send_at_cmd(mCurrectRatInfo->getRatCmdStart(), MSG_START_TX);
-        LOG_D(LOG_TAG, "send: %s  %s",mCurrectRatInfo->getRatName().c_str() ,mCurrectRatInfo->getRatCmdStart().c_str());
+        LOG_D(LOG_TAG, "send:Ratname=%s, RatCmd=%s",mCurrectRatInfo->getRatName().c_str() ,mCurrectRatInfo->getRatCmdStart().c_str());
     } else {
         LOG_D(LOG_TAG, "mCurrectRatInfo == null");
     }
@@ -388,24 +486,53 @@
     return handler;
 }
 
+char* RfDesenseTxTest::msg_type_to_str(int msgType) {
+    switch (msgType) {
+        case MSG_START_TX:
+            return "MSG_START_TX";
+        case MSG_CONTINUE_TX:
+            return "MSG_CONTINUE_TX";
+        case MSG_NEXT_RAT:
+            return "MSG_NEXT_RAT";
+        case MSG_READ_POWER:
+            return "MSG_READ_POWER";
+        case MSG_EWMPOLICY_TDSCDMA:
+            return "MSG_EWMPOLICY_TDSCDMA";
+        case MSG_EWMPOLICY_WCDMA:
+            return "MSG_EWMPOLICY_WCDMA";
+        case MSG_ECSRA:
+            return "MSG_ECSRA";
+        case MSG_SWITCH_RAT_DONE:
+            return "MSG_SWITCH_RAT_DONE";
+        case MSG_NR_READ_POWER:
+            return "MSG_NR_READ_POWER";
+        default:
+            return "unknown type";
+    }
+}
+
 void RfDesenseTxTest::emRfDesenseAtCmdHandle(sp<RfRequestMessage> msg){
-    LOG_D(LOG_TAG, "emRfDesenseAtCmdHandle, type: %d", msg->mMsgType);
+    LOG_D(LOG_TAG, "emRfDesenseAtCmdHandle(), %s", msg_type_to_str(msg->mMsgType));
     int responselen = msg->responselen;
     std::string response = msg->response;
     switch (msg->mMsgType) {
     case MSG_SWITCH_RAT_DONE: {
         if (msg->e == RIL_E_SUCCESS) {
-            LOG_D(LOG_TAG, "switch rat succeed");
-            if (mCurrectRatInfo->getRatName() == mRatName[1]) { // tdscdma
+            LOG_D(LOG_TAG, "switch rat=%s succeed", mCurrectRatInfo->getRatName().c_str());
+#ifndef TARGET_PLATFORM_MT2735
+            if (mCurrectRatInfo->getRatName() == mRatName[INDEX_TDSCDMA]) { // tdscdma
                 LOG_D(LOG_TAG, "end AT+EWMPOLICY=0");
                 rf_send_at_cmd("AT+EWMPOLICY=0", MSG_EWMPOLICY_TDSCDMA);
-            } else if (mCurrectRatInfo->getRatName() == mRatName[2]) { // wcdma
+            } else
+#endif
+            if (mCurrectRatInfo->getRatName() == mRatName[INDEX_WCDMA]) { // wcdma
                 LOG_D(LOG_TAG,  "send AT+EWMPOLICY=0");
                 rf_send_at_cmd("AT+EWMPOLICY=0", MSG_EWMPOLICY_WCDMA);
             } else { // other rat
                 registerRadioOffOrNotAvailable(m_instance);
                 turnOffRf();
             }
+
         } else {
             LOG_D(LOG_TAG, "switch rat failed");
             emResultNotifyWithDone(mCurrectRatInfo->getRatName() + " switch rat failed\n");
@@ -432,9 +559,27 @@
     case MSG_START_TX:{
         if (msg->e == RIL_E_SUCCESS) {
             LOG_D(LOG_TAG, "start cmd ok");
-            if (utils::is93Modem() && mCurrectRatInfo && !mCurrectRatInfo->getRatCmdPowerRead().empty()) {
-                LOG_D(LOG_TAG,"start read cmd: %s", mCurrectRatInfo->getRatCmdPowerRead().c_str());
-                rf_send_at_cmd(mCurrectRatInfo->getRatCmdPowerRead(), MSG_READ_POWER);
+
+            if (utils::is93ModemAndAbove() && mCurrectRatInfo && !mCurrectRatInfo->getRatCmdPowerRead().empty()) {
+#ifdef TARGET_PLATFORM_MT2735
+                // For NR, need send get power after 5s, 10s (2 times)
+                if (mCurrectRatInfo->getRatName() == sub_tx_test[INDEX_NR].name) {
+                    LOG_D(LOG_TAG, "For NR, wait and start read cmd");
+                    sp<RfRequestMessage> nr_msg = new RfRequestMessage(this);
+                    nr_msg->mMsgType = MSG_CONTINUE_TX;
+                    nr_msg->response = msg->response;
+                    nr_msg->responselen = msg->responselen;
+                    nr_msg->slot = msg->slot;
+                    nr_msg->e = RIL_E_SUCCESS;
+                    sendMessage(nr_msg, 1000);
+
+                } else {
+#endif
+                    LOG_D(LOG_TAG,"start read cmd: %s", mCurrectRatInfo->getRatCmdPowerRead().c_str());
+                    rf_send_at_cmd(mCurrectRatInfo->getRatCmdPowerRead(), MSG_READ_POWER);
+#ifdef TARGET_PLATFORM_MT2735
+                }
+#endif
             } else {
                 LOG_D(LOG_TAG, "don't read");
                 txTestStop(MSG_NEXT_RAT);
@@ -445,6 +590,47 @@
         }
         break;
     }
+
+    case MSG_CONTINUE_TX:{
+        mTestDurationSended += mReadbackInterval;
+        if (mTestDurationSended >= mTestDuration) {
+            LOG_D(LOG_TAG, "read tx power succeed");
+            txTestStop(MSG_NEXT_RAT);
+            mTestDurationSended = 0;
+
+        } else {
+            LOG_D(LOG_TAG, "Wait again for mTestDurationSended=%d < %d", mTestDurationSended, mTestDuration);
+            sp<RfRequestMessage> nr_msg = new RfRequestMessage(this);
+            nr_msg->mMsgType = MSG_CONTINUE_TX;
+            nr_msg->response = msg->response;
+            nr_msg->responselen = msg->responselen;
+            nr_msg->slot = msg->slot;
+            nr_msg->e = msg->e;
+            sendMessage(msg, mReadbackInterval*1000);
+
+            if (utils::is93ModemAndAbove() && mCurrectRatInfo && !mCurrectRatInfo->getRatCmdPowerRead().empty()) {
+                LOG_D(LOG_TAG,"start read cmd: %s", mCurrectRatInfo->getRatCmdPowerRead().c_str());
+                rf_send_at_cmd(mCurrectRatInfo->getRatCmdPowerRead(), MSG_NR_READ_POWER);
+            } else {
+                LOG_D(LOG_TAG,"start read cmd fail");
+            }
+        }
+        break;
+    }
+
+    case MSG_NR_READ_POWER:{
+        if ((msg->e == RIL_E_SUCCESS) && (responselen > 0)) {
+            RLOGD("Get response %s", msg->response.c_str());
+            parse_read_power(response);
+
+        } else {
+            LOG_D(LOG_TAG, "read tx power failed");
+            emResultNotifyWithDone(mCurrectRatInfo->getRatName() + " read tx power failed\n");
+        }
+
+        break;
+    }
+
     case MSG_READ_POWER:{
         mTestDurationSended += mReadbackInterval;
         if (mTestDurationSended >= mTestDuration) {
@@ -463,9 +649,9 @@
             }
             mTestDurationSended = 0;
         } else {
-            if (utils::is93Modem() && mCurrectRatInfo && !mCurrectRatInfo->getRatCmdPowerRead().empty()) {
+            if (utils::is93ModemAndAbove() && mCurrectRatInfo && !mCurrectRatInfo->getRatCmdPowerRead().empty()) {
                 LOG_D(LOG_TAG,"(sencond)start read cmd: %s", mCurrectRatInfo->getRatCmdPowerRead().c_str());
-                rf_send_at_cmd(mCurrectRatInfo->getRatCmdPowerRead(),  MSG_READ_POWER);
+                rf_send_at_cmd(mCurrectRatInfo->getRatCmdPowerRead(), MSG_READ_POWER);
             } else {
                 LOG_D(LOG_TAG,"(sencond)start read cmd fail");
             }
@@ -488,7 +674,7 @@
                 mRatList[i]->setRatCheckState(false);
             }
 //            if(rat == mRatName[1] || rat == mRatName[2]) {
-//                if(utils::is93Modem()){
+//                if(utils::is93ModemAndAbove()){
 //                    utils::mtk_property_set("vendor.ril.mux.report.case", "2");
 //                    utils::mtk_property_set("vendor.ril.muxreport", "1");
 //                }else {
@@ -522,6 +708,72 @@
     }
 }
 
+void RfDesenseTxTest::parse_read_power(std::string response) {
+    std::vector<std::string> out;
+    utils::tokenize(response, "\n", out);
+    std::string str;
+    str.clear();
+
+    for(auto i: out) {
+        if(i.find(CMD_SAME_EGMC) != std::string::npos) {
+            std::string splitString = i.substr(std::string(CMD_SAME_EGMC).size());
+            std::vector<std::string> getDigitalVal;
+            utils::tokenize(string(splitString), ",\n", getDigitalVal);
+            RLOGD("parseCurrentMode splitString: %s, getDigitalVal.size()=%d",
+                    splitString.c_str(), getDigitalVal.size());
+
+            if (getDigitalVal.size() <= 0 || getDigitalVal.size() > 2) {
+                LOG_D(LOG_TAG, "read tx power size failed");
+                emResultNotifyWithDone(mCurrectRatInfo->getRatName() + " read tx power failed\n");
+                return ;
+            }
+
+            try {
+                float getPower = std::stof(getDigitalVal[1]);
+                LOG_D(LOG_TAG, "Readback tx power = %f", getPower);
+
+                std::string result = "";
+                std::string rat = "";
+
+                if (std::abs(std::stoi(mCurrectRatInfo->getRatPowerSet()) - getPower) > mCheckLimit) {
+                    result = "failed\n";
+                } else {
+                    result = "succeed\n";
+                }
+
+                std::string s = std::string("Start TX:\n")
+                        + std::string("Rat(band)          ") + std::string("Power_Set   ")
+                        + std::string("Power_Get    ") + std::string("Result\n");
+                rat = utils::format("%-20s   %-15s   %-10s",
+                        (mCurrectRatInfo->getRatName()+ "(b" + mCurrectRatInfo->getRatband() + ")").c_str(),
+                        mCurrectRatInfo->getRatPowerSet().c_str(),
+                        std::to_string(getPower).c_str()
+                );
+
+                std::string ret;
+                if (!result.compare("failed\n")) {
+                    ret = utils::format("%10s", result.c_str());
+                } else {
+                    ret = utils::format("%10s", result.c_str());
+                }
+                str_msg += s + rat + ret;
+
+                RLOGD("%s", str_msg.c_str());
+
+            } catch (const out_of_range &e) {
+                emResultNotifyWithDone(mCurrectRatInfo->getRatName() + " read tx power failed\n");
+                RLOGD("out of range: %s", e.what());
+                return;
+            } catch (const invalid_argument &e) {
+                emResultNotifyWithDone(mCurrectRatInfo->getRatName() + " read tx power failed\n");
+                RLOGD("invalid argument: %s", e.what());
+                return;
+            }
+
+        }
+    }
+}
+
 void RfDesenseTxTest::handle_gsm_para(const std::string& name, int last_pos,
         const std::string& sub_name) {
     bool flag = false;
@@ -877,6 +1129,125 @@
     }
 }
 
+void RfDesenseTxTest::handle_nr_para(const std::string& name, int last_pos,
+        const std::string& sub_name) {
+    //NR
+    bool flag = false;
+    std::shared_ptr<RfDesenseTxTestNr> nr =
+            RfDesenseTxTestNr::get_instance();
+
+    if (name == rfdesense_nr_sub[INDEX_NR_SUB_MODE].name) {
+        flag = nr->set_tx_mode(last_pos);
+
+    } else if (name == rfdesense_nr_sub[INDEX_NR_SUB_BAND].name) {
+        flag = nr->set_band_idx(last_pos);
+
+    } else if (name == rfdesense_nr_sub[INDEX_NR_SUB_BANDWIDTH].name) {
+        flag = nr->set_bandwith_idx(last_pos);
+
+    } else if (name == rfdesense_nr_sub[INDEX_NR_SUB_FREQ].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            nr->show_freq();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = nr->set_freq(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+            em_result_notify_error("get/set input error");
+        }
+
+    } else if (name == rfdesense_nr_sub[INDEX_NR_SUB_START].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            nr->show_start();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = nr->set_vrb_start(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+            em_result_notify_error("get/set input error");
+        }
+
+    } else if (name == rfdesense_nr_sub[INDEX_NR_SUB_LENGTH].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            nr->show_length();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = nr->set_vrb_length(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+            em_result_notify_error("get/set input error");
+        }
+
+    } else if (name == rfdesense_nr_sub[INDEX_NR_SUB_MCS].name) {
+        flag = nr->set_mcs(last_pos);
+
+    } else if (name == rfdesense_nr_sub[INDEX_NR_SUB_SCS].name) {
+        flag = nr->set_scs(last_pos);
+
+    } else if (name == rfdesense_nr_sub[INDEX_NR_SUB_POWER].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            nr->show_power();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = nr->set_power(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+            em_result_notify_error("get/set input error");
+        }
+
+    } else if (name == rfdesense_nr_sub[INDEX_NR_SUB_CONFIG].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            nr->show_config();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = nr->set_tdd_slot_config(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+            em_result_notify_error("get/set input error");
+        }
+    } else {
+        LOG_D(LOG_TAG, "No name=%s", name.c_str());
+        em_result_notify_error("get/set input error");
+    }
+
+    if (flag) {
+        mRatList[INDEX_NR]->setRatCmdStart(nr->get_command());
+        mRatList[INDEX_NR]->setRatband(nr->get_band());
+        mRatList[INDEX_NR]->setRatPowerSet(nr->get_power());
+        save(INDEX_NR);
+    }
+}
+
 void RfDesenseTxTest::handle_cdma_evdo_para(const std::string& name,
         int last_pos, const std::string& sub_name) {
     //CDMA(EVDO)
@@ -984,11 +1355,13 @@
         std::shared_ptr<RfDesenseTxTestGsm> gsm =
                 RfDesenseTxTestGsm::get_instance();
         gsm->show_default();
+#ifndef TARGET_PLATFORM_MT2735
     } else if (standard == sub_tx_test[INDEX_TDSCDMA].name) {
         //"TDSCDMA"
         std::shared_ptr<RfDesenseTxTestTd> tdscdma = std::make_shared<
                 RfDesenseTxTestTd>(utils::MODEM_TDSCDMA);
         tdscdma->show_default();
+#endif
     } else if (standard == sub_tx_test[INDEX_WCDMA].name) {
         //"WCDMA"
         std::shared_ptr<RfDesenseTxTestTd> wcdma = std::make_shared<
@@ -1004,6 +1377,13 @@
         std::shared_ptr<RfDesenseTxTestLte> tdd = std::make_shared<
                 RfDesenseTxTestLte>(utils::MODEM_LTE_TDD);
         tdd->show_default();
+#ifdef TARGET_PLATFORM_MT2735
+    } else if (standard == sub_tx_test[INDEX_NR].name) {
+        //NR
+        std::shared_ptr<RfDesenseTxTestNr> nr =
+                RfDesenseTxTestNr::get_instance();
+        nr->show_default();
+#endif
 #ifdef C2K_SUPPORT
     } else if ((standard == sub_tx_test[INDEX_CDMA_EVDO].name)
             && utils::isC2KSupport()) {
@@ -1041,9 +1421,11 @@
     if (standard == sub_tx_test[INDEX_GSM].name) {
         //"GSM"
         handle_gsm_para(name, last_pos, sub_name);
+#ifndef TARGET_PLATFORM_MT2735
     } else if (standard == sub_tx_test[INDEX_TDSCDMA].name) {
         //"TDSCDMA"
         handle_tdscdma_para(name, last_pos, sub_name);
+#endif
     } else if (standard == sub_tx_test[INDEX_WCDMA].name) {
         //"WCDMA"
         handle_wcdma_para(name, last_pos, sub_name);
@@ -1053,6 +1435,11 @@
     } else if (standard == sub_tx_test[INDEX_LTE_TDD].name) {
         //LTE(TDD)
         handle_lte_tdd_para(name, last_pos, sub_name);
+#ifdef TARGET_PLATFORM_MT2735
+    } else if (standard == sub_tx_test[INDEX_NR].name) {
+        //NR
+        handle_nr_para(name, last_pos, sub_name);
+#endif
 #ifdef C2K_SUPPORT
     } else if ((standard == sub_tx_test[INDEX_CDMA_EVDO].name)
             && utils::isC2KSupport()) {
@@ -1076,9 +1463,11 @@
     if (standard == sub_tx_test[INDEX_GSM].name) {
         //"GSM"
         mRatList[INDEX_GSM]->setRatCheckState(true);
+#ifndef TARGET_PLATFORM_MT2735
     } else if (standard == sub_tx_test[INDEX_TDSCDMA].name) {
         //"TDSCDMA"
         mRatList[INDEX_TDSCDMA]->setRatCheckState(true);
+#endif
     } else if (standard == sub_tx_test[INDEX_WCDMA].name) {
         //"WCDMA"
         mRatList[INDEX_WCDMA]->setRatCheckState(true);
@@ -1088,6 +1477,11 @@
     } else if (standard == sub_tx_test[INDEX_LTE_TDD].name) {
         //LTE(TDD)
         mRatList[INDEX_LTE_TDD]->setRatCheckState(true);
+#ifdef TARGET_PLATFORM_MT2735
+    } else if (standard == sub_tx_test[INDEX_NR].name) {
+        //NR
+        mRatList[INDEX_NR]->setRatCheckState(true);
+#endif
 #ifdef C2K_SUPPORT
     } else if ((standard == sub_tx_test[INDEX_CDMA_EVDO].name)
             && utils::isC2KSupport()) {
@@ -1107,6 +1501,26 @@
 
 int RfDesenseTxTest::emRfDesenseStart(int len,int *item,int multilen,char *value[]) {
     LOG_D(LOG_TAG,"emRfDesenseStart called");
+
+    // Update manu index
+    int idx_count = 0;
+    INDEX_GSM = idx_count;
+#ifndef TARGET_PLATFORM_MT2735
+    INDEX_TDSCDMA = ++idx_count;
+#endif
+    INDEX_WCDMA = ++idx_count;
+    INDEX_LTE_FDD = ++idx_count;
+    INDEX_LTE_TDD = ++idx_count;
+#ifdef TARGET_PLATFORM_MT2735
+    INDEX_NR = ++idx_count;
+#endif
+#ifdef C2K_SUPPORT
+    INDEX_CDMA_EVDO = ++idx_count;
+    INDEX_CDMA_1X = ++idx_count;
+#endif
+    LOG_D(LOG_TAG, "Manu index: GSM=%d, TDSCDMA=%d, WCDMA=%d, LTE_FDD=%d, LTE_TDD=%d, NR=%d, CDMA_EVDO=%d, CDMA_1X=%d",
+            INDEX_GSM, INDEX_TDSCDMA, INDEX_WCDMA, INDEX_LTE_FDD, INDEX_LTE_TDD, INDEX_NR, INDEX_CDMA_EVDO, INDEX_CDMA_1X);
+
     update_rat();
     if (len < 3) {
         LOG_D(LOG_TAG, "please select redesense get or set");
@@ -1115,12 +1529,15 @@
     int classid = item[0];
     int propertyid = item[1];
     int operatorid = item[2];
+    LOG_D(LOG_TAG, "classid=%d, propertyid=%d, operatorid=%d", classid, propertyid, operatorid);
+
     mCurrentSettingsValues.clear();
     for(int i = 0; i < multilen; i++ ) {
         mCurrentSettingsValues.push_back(value[i]);
         LOG_D(LOG_TAG, "value[%d]: %s", i, value[i]);
     }
-    LOG_D(LOG_TAG, "mCurrentSettingsValues size: " + mCurrentSettingsValues.size());
+    LOG_D(LOG_TAG, "mCurrentSettingsValues size: %d" + mCurrentSettingsValues.size());
+
     em_arry_t *subarry = &(desense_test[classid].subarray[propertyid]);
     std::string standard = subarry->name;
     LOG_D(LOG_TAG,"rfdesense property name: %s, operatorid: %d",subarry->name, operatorid);
@@ -1185,7 +1602,8 @@
 void RfDesenseTxTest::initRatList() {
     phone_id = Radio_capability_switch_util::get_main_capability_phone_id();
     mState = STATE_NONE;
-    if(!utils::is93Modem()){
+
+    if(!utils::is93ModemAndAbove()){
         mRatCmdStart[5] = DEFAULT_CDMA_EVDO_ATCMD_93before;
         mRatCmdStop[5] = "AT+ECRFTX=0";
     }
@@ -1194,6 +1612,7 @@
         mRatCmdSwitch[5] = "AT^PREFMODE=4";
         mRatCmdSwitch[6] = "AT^EIRATMODE=2";
     }
+
     for (int i = 0; i < mRatName.size(); i++) {
         std::shared_ptr<RfDesenseRatInfo> Info = std::make_shared<RfDesenseRatInfo>();
         Info->setRatName(mRatName[i]);
@@ -1206,11 +1625,6 @@
         Info->setRatCheckState(false);
         Info->setRatSendState(false);
         mRatList.push_back(Info);
-        if(!(utils::isC2KSupport())){
-            if (i == 4) {
-                break;
-            }
-        }
     }
 }
 
@@ -1225,11 +1639,6 @@
         mRatList[i]->setRatPowerSet(mRatPowerSet[i]);
         mRatList[i]->setRatCheckState(false);
         mRatList[i]->setRatSendState(false);
-        if(!(utils::isC2KSupport())){
-            if (i == 4) {
-                break;
-            }
-        }
     }
 }
 void RfDesenseTxTest::save(int index) {
diff --git a/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTest.h b/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTest.h
old mode 100755
new mode 100644
index 5f9d0b2..8250064
--- a/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTest.h
+++ b/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTest.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: MediaTekProprietary
 /* Copyright Statement:
  *
  * This software/firmware and related documentation ("MediaTek Software") are
@@ -73,12 +74,14 @@
     static const int STATE_STOPPED;
 
     static const int MSG_START_TX;
+    static const int MSG_CONTINUE_TX;
     static const int MSG_NEXT_RAT;
     static const int MSG_READ_POWER;
     static const int MSG_EWMPOLICY_TDSCDMA;
     static const int MSG_EWMPOLICY_WCDMA;
     static const int MSG_ECSRA;
     static const int MSG_SWITCH_RAT_DONE;
+    static const int MSG_NR_READ_POWER;
 
     static const std::string KEY_GSM_ATCMD;
     static const std::string KEY_TDSCDMA_ATCMD;
@@ -97,6 +100,7 @@
     static const std::string DEFAULT_WCDMA_ATCMD;
     static const std::string DEFAULT_LTE_FDD_ATCMD;
     static const std::string DEFAULT_LTE_TDD_ATCMD;
+    static const std::string DEFAULT_NR_ATCMD;
     static const std::string DEFAULT_CDMA_EVDO_ATCMD;
     static const std::string DEFAULT_CDMA_1X_ATCMD;
     static const std::string DEFAULT_CDMA_EVDO_ATCMD_93before;
@@ -122,13 +126,15 @@
     const int MSG_SET = 1;
     int mCurrentFlag = 0;
     std::vector<std::string> mCurrentSettingsValues;
-    static const int INDEX_GSM = 0;
-    static const int INDEX_TDSCDMA = 1;
-    static const int INDEX_WCDMA = 2;
-    static const int INDEX_LTE_FDD = 3;
-    static const int INDEX_LTE_TDD = 4;
-    static const int INDEX_CDMA_EVDO = 5;
-    static const int INDEX_CDMA_1X = 6;
+
+    static int INDEX_GSM;
+    static int INDEX_TDSCDMA;
+    static int INDEX_WCDMA;
+    static int INDEX_LTE_FDD;
+    static int INDEX_LTE_TDD;
+    static int INDEX_NR;
+    static int INDEX_CDMA_EVDO;
+    static int INDEX_CDMA_1X;
 
     static constexpr int INDEX_GSM_SUB_BAND = 0;
     static constexpr int INDEX_GSM_SUB_CHANNEL = 1;
@@ -166,6 +172,17 @@
     static constexpr int INDEX_TDD_SUB_MCS = 8;
     static constexpr int INDEX_TDD_SUB_POWER = 9;
 
+    static constexpr int INDEX_NR_SUB_MODE = 0;
+    static constexpr int INDEX_NR_SUB_BAND = 1;
+    static constexpr int INDEX_NR_SUB_BANDWIDTH = 2;
+    static constexpr int INDEX_NR_SUB_FREQ = 3;
+    static constexpr int INDEX_NR_SUB_START = 4;
+    static constexpr int INDEX_NR_SUB_LENGTH = 5;
+    static constexpr int INDEX_NR_SUB_MCS = 6;
+    static constexpr int INDEX_NR_SUB_SCS = 7;
+    static constexpr int INDEX_NR_SUB_POWER = 8;
+    static constexpr int INDEX_NR_SUB_CONFIG = 9;
+
     class RequestHandleThread: public Thread {
     public:
         RequestHandleThread(RfDesenseTxTest* tx);
@@ -238,11 +255,14 @@
     void handle_wcdma_para(const std::string& name, int last_pos,const std::string& sub_name);
     void handle_lte_fdd_para(const std::string& name, int last_pos,const std::string& sub_name);
     void handle_lte_tdd_para(const std::string& name, int last_pos,const std::string& sub_name);
+    void handle_nr_para(const std::string& name, int last_pos,const std::string& sub_name);
     void handle_cdma_evdo_para(const std::string& name, int last_pos,const std::string& sub_name);
     void handle_cdma_1X_para(const std::string& name, int last_pos,const std::string& sub_name);
     bool handle_show_default(const std::string& standard);
     bool handle_para(int len, int classid, int propertyid, int operatorid,const std::string& standard, int* item);
     bool handle_start(const std::string& standard);
+    void parse_read_power(std::string response);
+    char* msg_type_to_str(int msgType);
 
     static int mState;
     static std::string str_msg;
diff --git a/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestGsm.cpp b/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestGsm.cpp
old mode 100755
new mode 100644
index e09fea1..8bbe469
--- a/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestGsm.cpp
+++ b/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestGsm.cpp
@@ -1,3 +1,4 @@
+//SPDX-License-Identifier: MediaTekProprietary
 /* Copyright Statement:
  *
  * This software/firmware and related documentation ("MediaTek Software") are
@@ -284,8 +285,13 @@
 
 void RfDesenseTxTestGsm::show_default() {
     int band_index = utils::find_index(band_values, band);
+    if (band_index > 5 || band_index < 0) {
+        LOG_W(LOG_TAG, "show_default, band_index=%d, out of range\n" , band_index);
+        band_index = 0;
+    }
+
     int pattern_index = std::stoi(pattern);
-    std::string temp = "GSM parameter: Band: " + std::string(rfdesense_gsm_band[band_index > 5 ? 0 : band_index].name) +
+    std::string temp = "GSM parameter: Band: " + std::string(rfdesense_gsm_band[band_index].name) +
             ", Channel(ARFCN): " + channel + ", Power Level: " + power + ", AFC: " + afc + ", TSC: " + tsc +
             ", PATTERN: " + std::string(rfdesense_gsm_pattern[pattern_index > 6 ? 0 : pattern_index].name);
     emResultNotifyWithDone(temp);
diff --git a/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestNr.cpp b/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestNr.cpp
new file mode 100644
index 0000000..1d49366
--- /dev/null
+++ b/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestNr.cpp
@@ -0,0 +1,412 @@
+// SPDX-License-Identifier: MediaTekProprietary
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include "rfdesense/RfDesenseTxTestNr.h"
+
+#include <algorithm>
+#include <iterator>
+#include <stdexcept>
+
+#include "rfdesense/RfDesenseTxTestBase.h"
+#include "util/log_extra.h"
+#include "em.h"
+
+#undef LOG_TAG
+#define LOG_TAG "EM_RfDesenseTxTestNr"
+
+const int RfDesenseTxTestNr::INDEX_TX_MODE = 0;
+const int RfDesenseTxTestNr::INDEX_BAND = 1;
+const int RfDesenseTxTestNr::INDEX_BAND_WIDTH = 2;
+const int RfDesenseTxTestNr::INDEX_FREQ = 3;
+const int RfDesenseTxTestNr::INDEX_VRB_START = 4;
+const int RfDesenseTxTestNr::INDEX_VRB_LENGTH = 5;
+const int RfDesenseTxTestNr::INDEX_MCS = 6;
+const int RfDesenseTxTestNr::INDEX_SCS = 7;
+const int RfDesenseTxTestNr::INDEX_POWER = 8;
+const int RfDesenseTxTestNr::INDEX_TDD_SLOT_CONFIG = 9;
+const int RfDesenseTxTestNr::INDEX_ANT_MODE = 10;
+
+std::string RfDesenseTxTestNr::mTxMode="";
+int RfDesenseTxTestNr::mBandIdx=0;
+std::string RfDesenseTxTestNr::mBand="";
+int RfDesenseTxTestNr::mBandWidthIdx=0;
+std::string RfDesenseTxTestNr::mBandWidth="";
+std::string RfDesenseTxTestNr::mFreq="";
+std::string RfDesenseTxTestNr::mVrbStart="";
+std::string RfDesenseTxTestNr::mVrbLength="";
+std::string RfDesenseTxTestNr::mMcs="";
+std::string RfDesenseTxTestNr::mScs="";
+std::string RfDesenseTxTestNr::mPower="";
+std::string RfDesenseTxTestNr::mTddSlotConfig="";
+int RfDesenseTxTestNr::mAntMode=0;
+
+std::shared_ptr<RfDesenseTxTestNr> RfDesenseTxTestNr::m_instance;
+std::mutex RfDesenseTxTestNr::mutex;
+
+std::string RfDesenseTxTestNr::DEFAULT_TX_MODE = "0";//TONE
+int RfDesenseTxTestNr::DEFAULT_BAND_IDX = 0;//BAND1
+int RfDesenseTxTestNr::DEFAULT_BAND_WIDTH_IDX = 1;//10MHZ
+std::string RfDesenseTxTestNr::DEFAULT_NR_FREQ = "1950000";
+std::string RfDesenseTxTestNr::DEFAULT_VRB_START = "0";
+std::string RfDesenseTxTestNr::DEFAULT_VRB_LENGTH = "1";
+std::string RfDesenseTxTestNr::DEFAULT_MCS = "0";//DFT-S BPSK
+std::string RfDesenseTxTestNr::DEFAULT_SCS_CONFIG = "0";//15KHZ
+std::string RfDesenseTxTestNr::DEFAULT_POWER = "23";
+std::string RfDesenseTxTestNr::DEFAULT_TDD_SLOT_CONFIG = "1";
+int RfDesenseTxTestNr::DEFAULT_ANT_MODE= 0;
+
+int VRB_START_MIN = 0;
+int VRB_START_MAX = 272;
+int VRB_LENGTH_MIN = 0;
+int VRB_LENGTH_MAX = 273;
+int POWER_MIN = -50;
+int POWER_MAX_PUSCH = 23;
+int POWER_MAX_TONE = 26;
+int TDD_SLOT_CONFIG_MIN = 1;
+int TDD_SLOT_CONFIG_MAX = 44;
+
+const std::vector<std::string> RfDesenseTxTestNr::mBandMapping = {"1", "3", "7", "8", "20", "28", "38", "41", "77", "78", "79"};
+const std::vector<std::string> RfDesenseTxTestNr::mBandWidthMapping = {"5000", "10000", "15000", "20000", "25000", "30000",
+        "35000", "40000", "45000", "50000", "55000", "60000", "65000", "70000", "75000", "80000", "85000", "90000",
+        "95000", "100000"};
+
+RfDesenseTxTestNr::RfDesenseTxTestNr() {
+    LOG_D(LOG_TAG, "RfDesenseTxTestNr()");
+
+    mTxMode = DEFAULT_TX_MODE;
+    mBandIdx = DEFAULT_BAND_IDX;
+    mBand = mBandMapping[mBandIdx];
+    mBandWidthIdx = DEFAULT_BAND_WIDTH_IDX;
+    mBandWidth = mBandWidthMapping[mBandWidthIdx];
+    mFreq = DEFAULT_NR_FREQ;
+    mVrbStart = DEFAULT_VRB_START;
+    mVrbLength = DEFAULT_VRB_LENGTH;
+    mMcs = DEFAULT_MCS;
+    mScs = DEFAULT_SCS_CONFIG;
+    mPower = DEFAULT_POWER;
+    mTddSlotConfig = DEFAULT_TDD_SLOT_CONFIG;
+    mAntMode = DEFAULT_ANT_MODE;
+}
+
+void RfDesenseTxTestNr::show_default() {
+    std::string str;
+    std::string tx_mode_str(rfdesense_nr_tx_mode[std::stoi(mTxMode)].name);
+    std::string band_str(rfdesense_nr_band[mBandIdx].name);
+    std::string band_width_str(rfdesense_nr_bandwidth[mBandWidthIdx].name);
+    std::string mcs_str(rfdesense_nr_mcs[std::stoi(mMcs)].name);
+    std::string scs_str(rfdesense_nr_scs[std::stoi(mScs)].name);
+
+    str = "\nTx mode: " + tx_mode_str
+            + "\nBand: " + band_str
+            + "\nUL Bandwidth: " + band_width_str
+            + "\nUL Freq(1kHz): " + mFreq
+            + "\nVRB Start(0~272): " + mVrbStart
+            + "\nVRB Length(0~273): " + mVrbLength
+            + "\nMCS: " + mcs_str
+            + "\nSCS: " + scs_str
+            + "\nPower Level(dBm)(-50-23): " + mPower
+            + "\nTDD Slot Config: " + mTddSlotConfig;
+
+    LOG_D(LOG_TAG, "show_default, str=%s", str.c_str());
+    emResultNotifyWithDone(str);
+}
+
+RfDesenseTxTestNr::~RfDesenseTxTestNr() {
+    // TODO Auto-generated destructor stub
+}
+
+std::shared_ptr<RfDesenseTxTestNr> RfDesenseTxTestNr::get_instance() {
+    if(!m_instance) {
+        mutex.lock();
+        if(!m_instance) {
+            m_instance = std::make_shared<RfDesenseTxTestNr>();
+        }
+        mutex.unlock();
+    }
+    return m_instance;
+}
+
+std::string RfDesenseTxTestNr::get_command() {
+    std::string command;
+
+    //Tone mode
+    if (mTxMode == "0") {
+        command = "AT+EGMC=1,\"NrForcedTx\",2,";
+        command += mBand + "," + mFreq + "," + mPower;
+
+    //PUSCH mode
+    } else {
+        command = "AT+EGMC=1,\"NrForcedTx\",1,";
+        command += mBand + "," + mBandWidth + "," + mFreq + "," +
+                mVrbStart + "," + mVrbLength + "," + mMcs + ","
+                + mScs + "," + mPower + "," + mTddSlotConfig;
+    }
+
+    LOG_D(LOG_TAG, "NR command: %s\n", command.c_str());
+    return command;
+}
+
+std::string RfDesenseTxTestNr::get_band() {
+    return mBand;
+}
+std::string RfDesenseTxTestNr::get_power() {
+    return mPower;
+}
+
+std::string RfDesenseTxTestNr::get_ant_mode() {
+    std::string ant_str;
+    int antStatustx = DEFAULT_ANT_MODE, antStatusrx = DEFAULT_ANT_MODE;
+
+    if (mAntMode == 1)
+        ant_str = utils::format("AT+EGMC=1,\"NrForceTxRx\",1,%d,%d,0", antStatustx, antStatusrx);
+    else {
+        ant_str = utils::format("AT+EGMC=1,\"NrForceTxRx\",0,,,0");
+    }
+
+    LOG_D(LOG_TAG, "ant_str: %s\n", ant_str.c_str());
+    return ant_str;
+}
+
+bool RfDesenseTxTestNr::set_tx_mode(int mode){
+    std::string s;
+    if(mode !=0 && mode != 1) {
+        s = utils::format("set_mode: mode(%d) is out of range", mode);
+        LOG_E(LOG_TAG, "%s", s.c_str());
+        em_result_notify_fail(s);
+        return false;
+    }
+
+    mTxMode = std::to_string(mode);
+    // For PUSCH mode, we adjust parameter to pass tx
+    if (mTxMode == "1") {
+        mBandIdx = 7;
+        mBand = mBandMapping[mBandIdx]; //Band 41
+        mFreq = "2593010";
+        LOG_D(LOG_TAG, "For PUSCH mode, adjust parameter band=%s, freq=%s", mBand.c_str(), mFreq.c_str());
+    }
+
+    std::string tx_mode_str(rfdesense_nr_tx_mode[std::stoi(mTxMode)].name);
+    em_result_notify_ok("Tx mode=" + tx_mode_str);
+
+    return true;
+}
+
+bool RfDesenseTxTestNr::set_band_idx(int bandidx){
+    std::string s;
+
+    if(bandidx < 0 || bandidx >= mBandMapping.size()){
+        s = utils::format("set_band_idx: bandidx(%d) is out of range", bandidx);
+        LOG_E(LOG_TAG, "%s", s.c_str());
+        em_result_notify_fail(s);
+        return false;
+    }
+
+    mBandIdx = bandidx;
+    mBand = mBandMapping[bandidx];
+
+    em_result_notify_ok("mBand=" + mBand);
+    return true;
+}
+
+bool RfDesenseTxTestNr::set_bandwith_idx(int bandwidthidx){
+    std::string s;
+    if (bandwidthidx < 0 || bandwidthidx >= mBandWidthMapping.size()) {
+        s = utils::format("set_bandwith_idx value range is [%d, %d], input value is %d", 0, mBandWidthMapping.size(), bandwidthidx);
+        LOG_E(LOG_TAG, "%s", s.c_str());
+        em_result_notify_fail(s);
+        return false;
+    }
+
+    mBandWidthIdx = bandwidthidx;
+    mBandWidth = mBandWidthMapping[mBandWidthIdx];
+
+    em_result_notify_ok("mBandWidth=" + mBandWidth);
+    return true;
+}
+
+bool RfDesenseTxTestNr::set_freq(std::string str){
+    mFreq = str;
+    em_result_notify_ok("freq=" + mFreq);
+    return true;
+}
+
+bool RfDesenseTxTestNr::set_vrb_start(std::string start){
+    std::string s;
+    int value = -1;
+    try {
+        value = std::stoi(start);
+    } catch (std::invalid_argument &err) {
+        s = utils::format("set_vrb_start, vrb_start=%s is invalid, reason: %s", start.c_str(), err.what());
+        LOG_E(LOG_TAG, "%s", s.c_str());
+        em_result_notify_fail(s);
+        return false;
+    }
+
+    if (value < VRB_START_MIN || value > VRB_START_MAX) {
+        s = utils::format("set_vrb_start value range is [%d, %d], input value is %d", VRB_START_MIN, VRB_START_MAX, value);
+        LOG_E(LOG_TAG, "%s", s.c_str());
+        em_result_notify_fail(s);
+        return false;
+    }
+
+    mVrbStart = start;
+    em_result_notify_ok("vrb_start=" + mVrbStart);
+    return true;
+}
+
+bool RfDesenseTxTestNr::set_vrb_length(std::string length){
+    std::string s;
+    int value = -1;
+    try {
+        value = std::stoi(length);
+    } catch (std::invalid_argument &err) {
+        s = utils::format("set_vrb_length, vrb_length=%s is invalid, reason: %s", length.c_str(), err.what());
+        LOG_E(LOG_TAG, "%s", s.c_str());
+        em_result_notify_fail(s);
+        return false;
+    }
+
+    if (value < VRB_LENGTH_MIN || value > VRB_LENGTH_MAX) {
+        s = utils::format("set_vrb_length value range is [%d, %d], input value is %d", VRB_LENGTH_MIN, VRB_LENGTH_MAX, value);
+        LOG_E(LOG_TAG, "%s", s.c_str());
+        em_result_notify_fail(s);
+        return false;
+    }
+
+    mVrbLength = length;
+    em_result_notify_ok("vrb_length=" + mVrbLength);
+    return true;
+}
+
+bool RfDesenseTxTestNr::set_mcs(int mcs) {
+    if (mcs < 0 || mcs > 8) {
+        std::string s;
+        s = utils::format("check_mcs value range is [%d, %d], input value is %d", 0, 8, mcs);
+        LOG_E(LOG_TAG, "%s", s.c_str());
+        em_result_notify_fail(s);
+        return false;
+    }
+
+    mMcs = std::to_string(mcs);
+    em_result_notify_ok(std::string("mcs=") + rfdesense_nr_mcs[mcs].name);
+    return true;
+}
+
+bool RfDesenseTxTestNr::set_scs(int scs) {
+    if (scs < 0 || scs > 4) {
+        std::string s;
+        s = utils::format("check_mcs value range is [%d, %d], input value is %d", 0, 4, scs);
+        LOG_E(LOG_TAG, "%s", s.c_str());
+        em_result_notify_fail(s);
+        return false;
+    }
+
+    mScs = std::to_string(scs);
+    em_result_notify_ok(std::string("scs=") + rfdesense_nr_scs[scs].name);
+    return true;
+}
+
+bool RfDesenseTxTestNr::set_power(std::string power){
+    std::string s;
+    int value = -1, powerMax = POWER_MAX_TONE;
+
+    powerMax = (mTxMode == "0")? POWER_MAX_TONE: POWER_MAX_PUSCH;
+
+    try {
+        value = std::stoi(power);
+    } catch (std::invalid_argument &err) {
+        s = utils::format("set_power,check_power(%s) is invalid, reason: %s", power.c_str(), err.what());
+        LOG_E(LOG_TAG, "%s", s.c_str());
+        em_result_notify_fail(s);
+        return false;
+    }
+
+    if (value < POWER_MIN || value > powerMax) {
+        s = utils::format("check_power value range is [%d, %d], input value is %d", POWER_MIN, powerMax, value);
+        LOG_E(LOG_TAG, "%s", s.c_str());
+        em_result_notify_fail(s);
+        return false;
+    }
+
+    mPower = power;
+    em_result_notify_ok("power=" + power);
+    return true;
+}
+
+bool RfDesenseTxTestNr::set_tdd_slot_config(std::string config){
+    std::string s;
+    int value = -1;
+
+    try {
+        value = std::stoi(config);
+    } catch (std::invalid_argument &err) {
+        s = utils::format("set_tdd_slot_config, config(%s) is invalid, reason: %s", config.c_str(), err.what());
+        LOG_E(LOG_TAG, "%s", s.c_str());
+        em_result_notify_fail(s);
+        return false;
+    }
+
+    if(value < TDD_SLOT_CONFIG_MIN || value > TDD_SLOT_CONFIG_MAX){
+        s = utils::format("check_tdd_config value range is [%d, %d], input value is %d", TDD_SLOT_CONFIG_MIN, TDD_SLOT_CONFIG_MAX, value);
+        LOG_E(LOG_TAG, "%s", s.c_str());
+        em_result_notify_fail(s);
+        return false;
+    }
+
+    mTddSlotConfig = config;
+    em_result_notify_ok("tdd_config=" + mTddSlotConfig);
+    return true;
+}
+
+void RfDesenseTxTestNr::show_freq(){
+    emResultNotifyWithDone("UL Freq(1kHZ): " + mFreq);
+}
+
+void RfDesenseTxTestNr::show_start(){
+    emResultNotifyWithDone("VRB Start(0~272): " + mVrbStart);
+}
+
+void RfDesenseTxTestNr::show_length(){
+    emResultNotifyWithDone("VRB Length(0~273): " + mVrbLength);
+}
+
+void RfDesenseTxTestNr::show_power(){
+    emResultNotifyWithDone("Power Level(dBm)(-50~23): " + mPower);
+}
+
+void RfDesenseTxTestNr::show_config(){
+    emResultNotifyWithDone("TDD slot config(1~44): " + mTddSlotConfig);
+}
+
diff --git a/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestNr.h b/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestNr.h
new file mode 100644
index 0000000..9026bf9
--- /dev/null
+++ b/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestNr.h
@@ -0,0 +1,127 @@
+// SPDX-License-Identifier: MediaTekProprietary
+/* 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 RFDESENSETXTESTNR_H_
+#define RFDESENSETXTESTNR_H_
+
+#include <string>
+#include <vector>
+#include <map>
+#include <memory>
+#include <mutex>
+
+#include "util/utils.h"
+
+class RfDesenseTxTestNr {
+public:
+    RfDesenseTxTestNr();
+    virtual ~RfDesenseTxTestNr();
+
+    static std::shared_ptr<RfDesenseTxTestNr> get_instance();
+
+    void show_default();
+    std::string get_command();
+    std::string get_band();
+    std::string get_power();
+    std::string get_ant_mode();
+
+    bool set_tx_mode(int mode);
+    bool set_band_idx(int bandidx);
+    bool set_bandwith_idx(int bandwidthidx);
+    bool set_freq(std::string freq);
+    bool set_vrb_start(std::string start);
+    bool set_vrb_length(std::string length);
+    bool set_mcs(int mcs);
+    bool set_scs(int scs);
+    bool set_power(std::string power);
+    bool set_tdd_slot_config(std::string config);
+
+    void show_freq();
+    void show_start();
+    void show_length();
+    void show_power();
+    void show_config();
+
+private:
+    static std::shared_ptr<RfDesenseTxTestNr> m_instance;
+    static std::mutex mutex;
+    std::string command;
+
+    static const int INDEX_TX_MODE;
+    static const int INDEX_BAND;
+    static const int INDEX_BAND_WIDTH;
+    static const int INDEX_FREQ;
+    static const int INDEX_VRB_START;
+    static const int INDEX_VRB_LENGTH;
+    static const int INDEX_MCS;
+    static const int INDEX_SCS;
+    static const int INDEX_POWER;
+    static const int INDEX_TDD_SLOT_CONFIG;
+    static const int INDEX_ANT_MODE;
+
+    static std::string DEFAULT_TX_MODE;
+    static int DEFAULT_BAND_IDX;
+    static std::string DEFAULT_BAND;
+    static int DEFAULT_BAND_WIDTH_IDX;
+    static std::string DEFAULT_BAND_WIDTH;//40MHZ
+    static std::string DEFAULT_NR_FREQ;
+    static std::string DEFAULT_VRB_START;
+    static std::string DEFAULT_VRB_LENGTH;
+    static std::string DEFAULT_MCS;
+    static std::string DEFAULT_SCS_CONFIG;
+    static std::string DEFAULT_POWER;
+    static std::string DEFAULT_TDD_SLOT_CONFIG;
+    static int DEFAULT_ANT_MODE;
+
+    static std::string mTxMode;
+    static int mBandIdx;
+    static std::string mBand;
+    static int mBandWidthIdx;
+    static std::string mBandWidth;
+    static std::string mFreq;
+    static std::string mVrbStart;
+    static std::string mVrbLength;
+    static std::string mMcs;
+    static std::string mScs;
+    static std::string mPower;
+    static std::string mTddSlotConfig;
+    static int mAntMode;
+
+    static const std::vector<std::string> mBandMapping;
+    static const std::vector<std::string> mBandWidthMapping;
+};
+
+#endif /* RFDESENSETXTESTNR_H_ */
diff --git a/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestTd.cpp b/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestTd.cpp
old mode 100755
new mode 100644
index 3693061..2afe62e
--- a/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestTd.cpp
+++ b/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestTd.cpp
@@ -1,3 +1,4 @@
+//SPDX-License-Identifier: MediaTekProprietary
 /* Copyright Statement:
  *
  * This software/firmware and related documentation ("MediaTek Software") are
diff --git a/framework/lynq-ril-service/src/network.cpp b/framework/lynq-ril-service/src/network.cpp
index 418e0d2..17ba150 100755
--- a/framework/lynq-ril-service/src/network.cpp
+++ b/framework/lynq-ril-service/src/network.cpp
@@ -1,3 +1,4 @@
+//SPDX-License-Identifier: MediaTekProprietary
 /* Copyright Statement:
  *
  * This software/firmware and related documentation ("MediaTek Software") are
@@ -399,19 +400,19 @@
 
 //RIL_REQUEST_QUERY_AVAILABLE_NETWORKS_WITH_ACT
 /**
-* ”data” is NULL
-*”response” is const char ** that should be an arry of n*6, where n is the number of available networks
+* "data" is NULL
+*"response" is const char ** that should be an arry of n*6, where n is the number of available networks
 *
 *((const char **)response)[n+0] is long alpha ONS or EONS
 *((const char **)response)[n+1] is short alpha ONS or EONS
 *((const char **)response)[n+2] is 5 or 6 digit numeric code
 *((const char **)response)[n+3] is a string value of :
-*  “unkonwn”
-*  “available”
-*  “current”
-*  “forbidden”
+*  "unkonwn"
+*  "available"
+*  "current"
+*  "forbidden"
 *((const char **)response)[n+4] is lac
-*((const char **)response)[n+5] is a string value of the Act: “2G”, “3G”, “4G”
+*((const char **)response)[n+5] is a string value of the Act: "2G", "3G", "4G"
 **/
 int getAvailableNetworksWithAct(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
     android::Parcel p;
diff --git a/framework/lynq-ril-service/src/powerManager.cpp b/framework/lynq-ril-service/src/powerManager.cpp
index b3a33fd..9a2551e 100755
--- a/framework/lynq-ril-service/src/powerManager.cpp
+++ b/framework/lynq-ril-service/src/powerManager.cpp
@@ -1,3 +1,4 @@
+//SPDX-License-Identifier: MediaTekProprietary
 /*
 * Copyright Statement:
 *
diff --git a/framework/lynq-ril-service/src/ril.cpp b/framework/lynq-ril-service/src/ril.cpp
index 4e6b97f..268c852 100755
--- a/framework/lynq-ril-service/src/ril.cpp
+++ b/framework/lynq-ril-service/src/ril.cpp
@@ -1,3 +1,4 @@
+//SPDX-License-Identifier: MediaTekProprietary
 /*
 **
 ** Copyright 2006, The Android Open Source Project
@@ -6607,7 +6608,7 @@
 
 #ifdef MEMSET_FREED
     memsetString(eCallReqMsg.address);
-    memset(eCallReqMsg.msd_data, 0, eCallReqMsg.length);
+    memset(eCallReqMsg.msd_data, 0, digitLimit);
 #endif
 
     free(eCallReqMsg.address);
diff --git a/framework/lynq-ril-service/src/sms/cdma/BearerData.cpp b/framework/lynq-ril-service/src/sms/cdma/BearerData.cpp
old mode 100755
new mode 100644
index f3d829c..27dbe9b
--- a/framework/lynq-ril-service/src/sms/cdma/BearerData.cpp
+++ b/framework/lynq-ril-service/src/sms/cdma/BearerData.cpp
@@ -1,3 +1,4 @@
+//SPDX-License-Identifier: MediaTekProprietary
 /*
  * Copyright (C) 2008 The Android Open Source Project
  *
diff --git a/framework/lynq-ril-service/src/sms/cdma/GsmAlphabet.cpp b/framework/lynq-ril-service/src/sms/cdma/GsmAlphabet.cpp
old mode 100755
new mode 100644
index 85f8d27..948fec6
--- a/framework/lynq-ril-service/src/sms/cdma/GsmAlphabet.cpp
+++ b/framework/lynq-ril-service/src/sms/cdma/GsmAlphabet.cpp
@@ -1,3 +1,4 @@
+//SPDX-License-Identifier: MediaTekProprietary
 /*
  * Copyright (C) 2008 The Android Open Source Project
  *
diff --git a/framework/lynq-ril-service/src/sms/cdma/HexDump.cpp b/framework/lynq-ril-service/src/sms/cdma/HexDump.cpp
old mode 100755
new mode 100644
index 13efbd6..8dc01cf
--- a/framework/lynq-ril-service/src/sms/cdma/HexDump.cpp
+++ b/framework/lynq-ril-service/src/sms/cdma/HexDump.cpp
@@ -1,3 +1,4 @@
+//SPDX-License-Identifier: MediaTekProprietary
 /* Copyright Statement:
  *
  * This software/firmware and related documentation ("MediaTek Software") are
diff --git a/framework/lynq-ril-service/src/sms/gsm/sms_pdu.cpp b/framework/lynq-ril-service/src/sms/gsm/sms_pdu.cpp
index 81d07e3..8d9c5fa 100755
--- a/framework/lynq-ril-service/src/sms/gsm/sms_pdu.cpp
+++ b/framework/lynq-ril-service/src/sms/gsm/sms_pdu.cpp
@@ -1,3 +1,4 @@
+//SPDX-License-Identifier: MediaTekProprietary
 /* Copyright Statement:
  *
  * This software/firmware and related documentation ("MediaTek Software") are
diff --git a/framework/lynq-ril-service/src/sms/sms.cpp b/framework/lynq-ril-service/src/sms/sms.cpp
index 50af251..36f45f3 100755
--- a/framework/lynq-ril-service/src/sms/sms.cpp
+++ b/framework/lynq-ril-service/src/sms/sms.cpp
@@ -120,9 +120,7 @@
                 android::Parcel p;
                 size_t pos = p.dataPosition();
                 RequestInfo *pRI_backup = (RequestInfo *)calloc(1, sizeof(RequestInfo));
-                if(pRI_backup == NULL) {
-                    return 0;
-                }
+                if(pRI_backup != NULL) {
                 pRI_backup->token = pRI->token;
                 pRI_backup->pCI = pRI->pCI;
                 pRI_backup->socket_id = pRI->socket_id;
@@ -135,6 +133,7 @@
                 constructGsmSendSmsRilRequest(p, smscPDU, pdu[index]);
                 p.setDataPosition(pos);
                 pRI->pCI->dispatchFunction(p, pRI_backup);
+                }
             }
             for(index = 0; index < msg_num; index++){
                 free(pdu[index]);
diff --git a/framework/lynq-ril-service/src/ss.cpp b/framework/lynq-ril-service/src/ss.cpp
index 2a0ca3f..3b726ad 100755
--- a/framework/lynq-ril-service/src/ss.cpp
+++ b/framework/lynq-ril-service/src/ss.cpp
@@ -1,4 +1,5 @@
- /*
+//SPDX-License-Identifier: MediaTekProprietary
+/*
  * Copyright (C) 2006 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -281,7 +282,6 @@
 
     iconv_close(cd);
 //    **pout = '\0';
-    
     return 0;
 }
 //xxx ussiString
diff --git a/framework/lynq-ril-service/src/util/ModemCategory.cpp b/framework/lynq-ril-service/src/util/ModemCategory.cpp
old mode 100755
new mode 100644
index b9a79ec..31ef0b6
--- a/framework/lynq-ril-service/src/util/ModemCategory.cpp
+++ b/framework/lynq-ril-service/src/util/ModemCategory.cpp
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: MediaTekProprietary
 /* Copyright Statement:
  *
  * This software/firmware and related documentation ("MediaTek Software") are
@@ -106,6 +107,10 @@
     return (RatConfiguration::isTdscdmaSupported());
 }
 
+bool ModemCategory::isNrSupport() {
+    return (RatConfiguration::isNrSupported());
+}
+
 bool ModemCategory::isCapabilitySim(int type) {
     int mainCard = Radio_capability_switch_util::get_main_capability_phone_id();
     bool isCapability = (type == mainCard) ? true : false;
diff --git a/framework/lynq-ril-service/src/util/ModemCategory.h b/framework/lynq-ril-service/src/util/ModemCategory.h
old mode 100755
new mode 100644
index 847a9d8..4ce826d
--- a/framework/lynq-ril-service/src/util/ModemCategory.h
+++ b/framework/lynq-ril-service/src/util/ModemCategory.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: MediaTekProprietary
 /* Copyright Statement:
  *
  * This software/firmware and related documentation ("MediaTek Software") are
@@ -58,6 +59,7 @@
     static bool isGsmSupport();
     static bool isWcdmaSupport();
     static bool isTdscdmaSupport();
+    static bool isNrSupport();
     static bool isCapabilitySim(int type);
     static bool checkViceSimCapability(int simType, int capability);
 };
diff --git a/framework/lynq-ril-service/src/util/RatConfiguration.cpp b/framework/lynq-ril-service/src/util/RatConfiguration.cpp
old mode 100755
new mode 100644
index 60fb5af..8337193
--- a/framework/lynq-ril-service/src/util/RatConfiguration.cpp
+++ b/framework/lynq-ril-service/src/util/RatConfiguration.cpp
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: MediaTekProprietary
 /* Copyright Statement:
  *
  * This software/firmware and related documentation ("MediaTek Software") are
@@ -49,6 +50,7 @@
         "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::NR = "N";
 const std::string RatConfiguration::CDMA = "C";
 const std::string RatConfiguration::LteFdd = "Lf";
 const std::string RatConfiguration::LteTdd = "Lt";
@@ -59,6 +61,7 @@
 
 /* bitmask */
 /* the defination must be sync with ratconfig.c */
+const int RatConfiguration::MASK_NR = (1 << 6);
 const int RatConfiguration::MASK_CDMA = (1 << 5);
 const int RatConfiguration::MASK_LteFdd = (1 << 4);
 const int RatConfiguration::MASK_LteTdd = (1 << 3);
@@ -117,6 +120,9 @@
     if (rat.find(GSM) != std::string::npos) {
         iRat = iRat | MASK_GSM;
     }
+    if (rat.find(NR) != std::string::npos) {
+        iRat = iRat | MASK_NR;
+    }
     return iRat;
 }
 
@@ -192,6 +198,9 @@
  */
 std::string RatConfiguration::ratToString(int iRat) {
     std::string rat = "";
+    if ((iRat & MASK_NR) == MASK_NR) {
+        rat += (DELIMITER + NR);
+    }
     if ((iRat & MASK_CDMA) == MASK_CDMA) {
         rat += (DELIMITER + CDMA);
     }
@@ -283,6 +292,16 @@
 }
 
 /*
+ * check NR 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::isNrSupported() {
+    return (getMaxRat() & getRatConfig() & MASK_NR) == MASK_NR ? true : false;
+}
+
+/*
  * get the active rat
  * @return String, the rat in format like C/Lf/Lt/T/W/G
  */
diff --git a/framework/lynq-ril-service/src/util/RatConfiguration.h b/framework/lynq-ril-service/src/util/RatConfiguration.h
old mode 100755
new mode 100644
index 1a941fe..fd87693
--- a/framework/lynq-ril-service/src/util/RatConfiguration.h
+++ b/framework/lynq-ril-service/src/util/RatConfiguration.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: MediaTekProprietary
 /* Copyright Statement:
  *
  * This software/firmware and related documentation ("MediaTek Software") are
@@ -47,6 +48,7 @@
     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 NR;
     static const std::string CDMA;
     static const std::string LteFdd;
     static const std::string LteTdd;
@@ -57,6 +59,7 @@
 
     /* bitmask */
     /* the defination must be sync with ratconfig.c */
+    static const int MASK_NR;
     static const int MASK_CDMA;
     static const int MASK_LteFdd;
     static const int MASK_LteTdd;
@@ -92,6 +95,7 @@
     static bool isWcdmaSupported();
     static bool isTdscdmaSupported();
     static bool isGsmSupported();
+    static bool isNrSupported();
     static std::string getActiveRatConfig();
 
 };
diff --git a/framework/lynq-ril-service/src/util/utils.cpp b/framework/lynq-ril-service/src/util/utils.cpp
old mode 100755
new mode 100644
index a430d10..2a301b9
--- a/framework/lynq-ril-service/src/util/utils.cpp
+++ b/framework/lynq-ril-service/src/util/utils.cpp
@@ -1,3 +1,4 @@
+ // SPDX-License-Identifier: MediaTekProprietary
  /*
  * Copyright (C) 2006 The Android Open Source Project
  *
@@ -46,6 +47,22 @@
     // TODO Auto-generated destructor stub
 }
 
+bool utils::is93ModemAndAbove() {
+#if defined(MD_93_SUPPORT) || defined(MD_97_SUPPORT)
+    return true;
+#else
+    return false;
+#endif
+}
+
+bool utils::is97Modem() {
+#ifdef MD_97_SUPPORT
+    return true;
+#else
+    return false;
+#endif
+}
+
 bool utils::is93Modem() {
 #ifdef MD_93_SUPPORT
     return true;
@@ -87,6 +104,14 @@
 #endif
 }
 
+bool utils::isMt2735(){
+#ifdef TARGET_PLATFORM_MT2735
+    return true;
+#else
+    return false;
+#endif
+}
+
 bool utils::is_support_dsds(){
 #ifdef MODE_DSDS
     return true;
@@ -234,6 +259,19 @@
     }
 }
 
+std::string utils::addZeroForNum(std::string const &str, int strLength) {
+    std::string result_str;
+    result_str.append(str);
+
+    while (result_str.length() < strLength) {
+        result_str.append("0");
+    }
+
+    LOG_D(LOG_TAG,"addZeroForNum- result_str=%s", result_str.c_str());
+
+    return result_str;
+}
+
 void utils::setMSimProperty(int phoneId, char *pPropertyName, char *pUpdateValue) {
     #define MAX_PHONE_NUM 10
     #define MIN(a,b) ((a)<(b) ? (a) : (b))
diff --git a/framework/lynq-ril-service/src/util/utils.h b/framework/lynq-ril-service/src/util/utils.h
old mode 100755
new mode 100644
index 83a46a1..593a626
--- a/framework/lynq-ril-service/src/util/utils.h
+++ b/framework/lynq-ril-service/src/util/utils.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: MediaTekProprietary
 /* Copyright Statement:
  *
  * This software/firmware and related documentation ("MediaTek Software") are
@@ -45,17 +46,21 @@
 public:
     utils();
     virtual ~utils();
+    static bool is97Modem();
+    static bool is93ModemAndAbove();
     static bool is93Modem();
     static bool is90Modem();
     static bool isC2KSupport();
     static bool isMt2635();
     static bool isMt2731();
+    static bool isMt2735();
     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 std::string addZeroForNum(std::string const &str, int strLength);
     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);