[Feature]add MT2731_MP2_MR2_SVN388 baseline version

Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/lynq/lib/liblynq-tele-ril/MODULE_LICENSE_APACHE2 b/src/lynq/lib/liblynq-tele-ril/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/MODULE_LICENSE_APACHE2
diff --git a/src/lynq/lib/liblynq-tele-ril/Makefile b/src/lynq/lib/liblynq-tele-ril/Makefile
new file mode 100644
index 0000000..2ff74f9
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/Makefile
@@ -0,0 +1,63 @@
+PREFIX   = ../install
+CROSS    = arm-none-linux-
+ROOT     = $(PREFIX)/$(CROSS:%-=%)
+
+#For Yocto use
+
+RFX_TEST_CLIENT = false
+RFX_TEST_AOSP = false
+
+$(warning ########## libvendor_ril BB_TELEFWK_OPTION $(BB_TELEFWK_OPTION) ##########)
+
+		   
+
+SUBDIRS +=  lynq-riltel
+
+
+
+
+
+$(warning ########## lynq-rilcmd SUBDIRS  $(SUBDIRS) ##########)
+export SIM_COUNT?=1
+
+.PHONY: all build clean pack_rootfs
+
+all: build
+
+build: clean
+
+clean:
+	$(warning ########## clean ril ##########)
+	for i in $(SUBDIRS); do			\
+		(cd $$i && make clean);			\
+		if [ $$? != 0 ]; then		\
+			exit 1;					\
+		fi							\
+	done
+
+build:
+	$(warning ########## build ril ##########)
+	for i in $(SUBDIRS); do			\
+		(cd $$i && make);			\
+		if [ $$? != 0 ]; then		\
+			exit 1;					\
+		fi							\
+	done
+
+install:
+	$(warning ########## install ril ##########)
+	for i in $(SUBDIRS); do			\
+		(cd $$i && make install);			\
+		if [ $$? != 0 ]; then		\
+			exit 1;					\
+		fi							\
+	done
+
+pack_rootfs:
+	$(warning ########## pack_rootfs ril ##########)
+	for i in $(SUBDIRS); do			\
+		(cd $$i && make pack_rootfs);			\
+		if [ $$? != 0 ]; then		\
+			exit 1;					\
+		fi							\
+	done
diff --git a/src/lynq/lib/liblynq-tele-ril/NOTICE b/src/lynq/lib/liblynq-tele-ril/NOTICE
new file mode 100644
index 0000000..c5b1efa
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/NOTICE
@@ -0,0 +1,190 @@
+
+   Copyright (c) 2005-2008, The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
diff --git a/src/lynq/lib/liblynq-tele-ril/README b/src/lynq/lib/liblynq-tele-ril/README
new file mode 100644
index 0000000..9a7e82f
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/README
@@ -0,0 +1,13 @@
+WHAT IT DOES?
+=============
+MTK ril proxy core library
+
+HOW IT WAS BUILT?
+==================
+This module is source code released.
+
+HOW TO USE IT?
+==============
+MTK ril proxy daemon will use this library to communicate with GSM and C2K RILD.
+
+All the source code of this folder were written by MediaTek co..
diff --git a/src/lynq/lib/liblynq-tele-ril/include/libtel/lib_tele.h b/src/lynq/lib/liblynq-tele-ril/include/libtel/lib_tele.h
new file mode 100644
index 0000000..9b31587
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/include/libtel/lib_tele.h
@@ -0,0 +1,49 @@
+#ifndef _LIB_TEL_H_
+#define _LIB_TEL_H_
+#include <sys/types.h>
+#include <vendor-ril/telephony/ril.h>
+//#include <msgqril/lib_thread.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+typedef struct{
+    int32_t token;
+    int32_t request;
+    RIL_Errno e;
+}lynqBase;
+typedef enum {
+ SUCCESS = 0,
+ ERROR = 1,
+}RIL_Errcode;
+
+typedef struct
+{
+    void (*recive_new_sms_cb)(RIL_SOCKET_ID soc_id,char *num, char *smsc, char *msg, int charset);
+    void (*incoming_call_cb)(RIL_SOCKET_ID soc_id,int index, char *addr, RIL_CallState state, int toa);
+}user_cb;
+
+extern user_cb *s_Env;
+
+
+/*
+struct RIL_Cb {
+    void (*requestResponse)(int32_t token,RIL_Errcode e,char*response,int responselen);
+    void (*unsolicitedResponse)(char *response,int responselen);
+}*/
+
+//typedef void (*requestResponse)(int32_t token,RIL_Errcode e,char*response,int responselen);
+typedef void (*requestResponse)(int32_t token,RIL_Errcode e,char *response);
+typedef void (*unsolicitedResponse)(int unsolResponse,char *response,int responselen);
+//void lynqRegisterRequestResponse(requestResponse cb);
+void lynqRegisterUnsolicitedResponse(user_cb * cb);
+void registerOnUnsolicitedResponse(user_cb* cb);
+
+int getRequestData(char **data, int lenth);
+int lynq_waitToRcvCmd(char **data, int lenth);
+void lynq_ril_init();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/lynq/lib/liblynq-tele-ril/include/libtel/lynq_call.h b/src/lynq/lib/liblynq-tele-ril/include/libtel/lynq_call.h
new file mode 100644
index 0000000..9f4aca6
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/include/libtel/lynq_call.h
@@ -0,0 +1,89 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#ifndef LYNQ_CALL_H
+#define LYNQ_CALL_H 1
+#include "lib_tele.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define INDEX_IS_NUMBER( alpha_char )   \
+   ( ( (alpha_char >= '0') && (alpha_char <= '9') ) ? 1 : 0 )
+ typedef enum {
+     LYNQ_CALL_ACTIVE = 0,
+     LYNQ_CALL_HOLDING = 1,
+     LYNQ_CALL_DIALING = 2,    /* MO call only */
+     LYNQ_CALL_ALERTING = 3,   /* MO call only */
+     LYNQ_CALL_INCOMING = 4,   /* MT call only */
+     LYNQ_CALL_WAITING = 5       ,/* MT call only */
+     LYNQ_CALL_DACTIVE=6
+ } lynqCallState;
+
+ typedef struct
+{
+    lynqBase base;
+    int call_id;
+    lynqCallState call_state;
+    int toa;
+    char * addr;
+}lynqCallList;
+typedef struct
+{
+    lynqBase base;
+    RIL_LastCallFailCause cause_code;
+    char * vendor_cause;
+}lynqLastCallFailCause;
+int call_Info_Init();
+int lynq_call(const char *addr,lynqCallList *msg);
+int lynq_call_answer(lynqCallList* msg);
+int lynq_call_hang_up(const int callId,lynqBase *base);
+int lynq_reject_call(lynqBase *base);
+int lynq_set_auto_answercall(int mode,int *status);
+int lynq_get_mute_status(int *status);
+int lynq_set_mute_mic(const int enable,int *status);
+int lynq_set_DTMF(const char callnum,lynqBase *base);
+int lynq_set_DTMF_volume(const int volume);
+int lynq_do_multi_conference(lynqCallList *msg);
+int lynq_othercall_hold(const int callindex,lynqBase *base);
+int lynq_hangup_wating_for_call(lynqCallList *msg);
+int lynq_hangup_foreground_resume_background(lynqCallList *msg);
+int lynq_switch_hold_and_active_call(lynqCallList *msg);
+int lynq_get_last_call_fail_cause(lynqLastCallFailCause *msg);
+void lynq_incoming_call_cb(RIL_SOCKET_ID soc_id,int index, char *addr, RIL_CallState state, int toa);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/lynq/lib/liblynq-tele-ril/include/libtel/lynq_data.h b/src/lynq/lib/liblynq-tele-ril/include/libtel/lynq_data.h
new file mode 100644
index 0000000..9bfe0b7
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/include/libtel/lynq_data.h
@@ -0,0 +1,114 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#ifndef YLNQ_DATA_H
+#define YLNQ_DATA_H 1
+#include <vendor-ril/telephony/ril.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MAX_STRING_LEN 500 
+
+typedef struct{
+
+    char apn[MAX_STRING_LEN];
+
+    char apntype[MAX_STRING_LEN];
+    
+    char user[MAX_STRING_LEN];
+
+    char password[MAX_STRING_LEN];
+
+    char authtype[MAX_STRING_LEN];
+
+    char normalprotocol[MAX_STRING_LEN];
+
+    char roamingprotocol[MAX_STRING_LEN];
+ 
+}lynq_data_apn;
+
+typedef struct{
+    int status;//pdn connect status.
+    //int addr;//ccmnil addr.
+    int num;
+    RIL_Errno e;
+}dataCallMsg;
+typedef struct {
+    int             status;     /* A RIL_DataCallFailCause, 0 which is PDP_FAIL_NONE if no error */
+    int             suggestedRetryTime; /* If status != 0, this fields indicates the suggested retry
+                                           back-off timer value RIL wants to override the one
+                                           pre-configured in FW.
+                                           The unit is miliseconds.
+                                           The value < 0 means no value is suggested.
+                                           The value 0 means retry should be done ASAP.
+                                           The value of INT_MAX(0x7fffffff) means no retry. */
+    int             cid;        /* Context ID, uniquely identifies this call */
+    int             active;     /* 0=inactive, 1=active/physical link down, 2=active/physical link up */
+    char           type[10];       /* One of the PDP_type values in TS 27.007 section 10.1.1.
+                                   For example, "IP", "IPV6", "IPV4V6", or "PPP". If status is
+                                   PDP_FAIL_ONLY_SINGLE_BEARER_ALLOWED this is the type supported
+                                   such as "IP" or "IPV6" */
+    char           ifname[100];     /* The network interface name */
+    char           addresses[512];  /* A space-delimited list of addresses with optional "/" prefix length,
+                                   e.g., "192.0.1.3" or "192.0.1.11/16 2001:db8::1/64".
+                                   May not be empty, typically 1 IPv4 or 1 IPv6 or
+                                   one of each. If the prefix length is absent the addresses
+                                   are assumed to be point to point with IPv4 having a prefix
+                                   length of 32 and IPv6 128. */
+    char           dnses[1024];      /* A space-delimited list of DNS server addresses,
+                                   e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1".
+                                   May be empty. */
+    char           gateways[1024];   /* A space-delimited list of default gateway addresses,
+                                   e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1".
+                                   May be empty in which case the addresses represent point
+                                   to point connections. */
+    char           pcscf[100];    /* the Proxy Call State Control Function address
+                                 via PCO(Protocol Configuration Option) for IMS client. */
+    int             mtu;        /* MTU received from network
+                                   Value <= 0 means network has either not sent a value or
+                                   sent an invalid value */
+} LYNQ_Data_Call_Response_v11;
+
+int lynq_data_enable_data(int *PdnState) ; 
+int lynq_data_dectivate_data_call(int *PdnState);
+int lynq_get_data_call_list(LYNQ_Data_Call_Response_v11 **dataCallList,const int listNum,int *realNum);
+int lynq_set_apn();
+int lynq_get_apn();
+int lynq_enable_apn();
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/lynq/lib/liblynq-tele-ril/include/libtel/lynq_network.h b/src/lynq/lib/liblynq-tele-ril/include/libtel/lynq_network.h
new file mode 100644
index 0000000..2a42eee
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/include/libtel/lynq_network.h
@@ -0,0 +1,120 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+ #include "lib_tele.h"
+#ifndef __LYNQ_NETWORK__
+#define __LYNQ_NETWORK__
+#ifdef __cplusplus
+extern "C" {
+#endif
+typedef struct{
+    lynqBase base;
+    char *OperatorFN;    //It is long alpha ONS or EONS
+    char *OperatorSH;    //It is short alpha ONS or EONS
+    char *MccMnc;        //It is 5 or 6 digit numeric code (MCC + MNC)
+}operatorInfo;
+typedef struct{
+    lynqBase base;
+    char *OperatorFN;
+    char *OperatorSH;
+    char *MccMnc;
+    char * NetStatus;   //a string value of the status: "unknown","available","current","forbidden"
+}availableNetwork;
+
+typedef struct{
+    lynqBase base;
+    int mode;
+}networkSelecttionMode;
+typedef struct{
+    lynqBase base;
+    int     regState;               //registration state
+    int     imsRegState;
+    char *  LAC;                    //location area code, it is LAC if registered or NULL id not
+    char *  CID;                    //cell identifier, if registered or NULL id not.
+    RIL_RadioTechnology netType;    //network type
+    RIL_RadioTechnologyFamily radioTechFam;//RIL_RadioTechnologyFamily
+}registrationStateInfo;
+
+typedef struct{
+    lynqBase base;
+    RIL_RadioTechnology radioTech;
+}radioTechnology;
+
+typedef struct{
+    lynqBase base;
+    int pnt; //preffered network type.
+}prefferredNetworkType;
+typedef struct{
+    lynqBase base;
+    char *cid;
+    int rssi;
+}neighboringCellIDs;
+typedef struct{
+    lynqBase base;
+    int bandmode[20];
+}availableBandMode;
+typedef struct{
+    lynqBase base;
+    RIL_CellInfo cellinfo;
+}cellInfoList;
+typedef struct{
+    lynqBase base;
+    RIL_SignalStrength_v10 signalStrength;
+}solicitedSignalStrength;
+int lynq_query_operater(operatorInfo * currentOperator);
+int lynq_query_network_selection_mode(networkSelecttionMode *netselMode);
+int lynq_set_network_selection_mode(const char *mode,const char* mccmnc,lynqBase * base);
+int lynq_query_available_network(availableNetwork *availNet);
+int lynq_query_registration_state(const char *type,registrationStateInfo *regStateInfo);
+int lynq_query_prefferred_networktype(prefferredNetworkType * preNetType);
+int lynq_set_prefferred_networktype(const int preffertype,lynqBase * base);
+int lynq_query_cell_info(cellInfoList * * cellinfo, int listNum, int * realNum);
+int lynq_set_unsol_cell_info_listrate(const int rate,lynqBase * base);
+int lynq_query_neighboring_cellids(neighboringCellIDs **neiCeIDs,const int listNum,int *realNum);
+int lynq_set_band_mode(const int bandmode,lynqBase *base);
+int lynq_query_available_bandmode(availableBandMode*availBanMode);
+int lynq_radio_on(const int data,lynqBase *base);
+int lynq_query_radio_tech(radioTechnology *radioTech);
+int lynq_solicited_signal_strength(solicitedSignalStrength *solSigStren);
+int lynq_modem_on(const int data,lynqBase *base);
+//int  lynq_enter_network_depersonalization(char *code);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
diff --git a/src/lynq/lib/liblynq-tele-ril/include/libtel/lynq_sim.h b/src/lynq/lib/liblynq-tele-ril/include/libtel/lynq_sim.h
new file mode 100644
index 0000000..e9889df
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/include/libtel/lynq_sim.h
@@ -0,0 +1,42 @@
+/*============================================================================= 
+#     FileName: lynq_sim.cpp
+#     Desc: about SIMAPI
+#     Author: mobiletek 
+#     Version: V1.0
+#     LastChange: 2020-07-29 
+#     History: 
+# If you need to use any API under lynq_sim, you must first call the init_sim() function to initialize these functions.
+=============================================================================*/
+#ifndef __LYNQ_SIM__
+#define __LYNQ_SIM__
+#include <sys/types.h>
+#include "lib_tele.h"
+#define MAX_IMSI 20
+#ifdef __cplusplus
+extern "C" {
+#endif
+typedef struct
+{
+    lynqBase base;
+    RIL_CardState card_status;
+    RIL_AppType  card_type;
+    RIL_PinState pin_state;
+}simStatus;
+typedef struct
+{
+    lynqBase base;
+    char imsi[MAX_IMSI];
+    //char *imsi;
+}simImsi;
+int init_sim();
+int lynq_set_default_sim_all(int sim_id);
+int lynq_get_sim_status(simStatus *msg);
+int lynq_get_sim_status_ext(int sim_id );
+int lynq_get_imsi(simImsi * msg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/lynq/lib/liblynq-tele-ril/include/libtel/lynq_sms.h b/src/lynq/lib/liblynq-tele-ril/include/libtel/lynq_sms.h
new file mode 100644
index 0000000..eef3412
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/include/libtel/lynq_sms.h
@@ -0,0 +1,83 @@
+/*============================================================================= 
+#     FileName: lynq_sms.h
+#         Desc: about sms api
+#       Author: zhouqunchao 
+#      Version:  
+#   LastChange: 2020-07-29 
+#      History: 
+ 
+=============================================================================*/
+
+#ifndef YLNQ_SMS_H
+#define YLNQ_SMS_H 1
+#include <sys/types.h>
+#include "lib_tele.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define MIN_MSM_PARAM_NUM 4
+#define MIN_IMS_MSM_PARAM_NUM 6
+#define MIN_WRITE_MSM_PARAM_NUM 5
+#define MSG_MAX_LEN 256
+typedef struct {
+    char *telephonyNumber;
+    char *charset;
+    char *msg;
+    char *smsc;
+} SmsSendData;
+typedef struct{
+lynqBase base;
+RIL_SMS_Response smsResp;
+}smsResponse;
+typedef struct {
+    char *telephonyNumber;
+    char *charset;
+    char *msg;
+    char *retryNum;
+    char *messageRef;
+    char *smsc;    
+} SmsImsSendData;
+
+typedef struct {
+    int  smsStatus; //UnRead\Read\UnSent\Sent
+    char *recPhonNum;
+    char *charset;
+    char *msg;
+    char *smsc;    
+} SmsInfo;
+
+typedef struct{
+lynqBase base;
+int msgStoreIndex;
+}messageStoreInfo;
+
+typedef struct{
+lynqBase base;
+char *smsc;
+}smscCbInfo;
+typedef struct
+{
+    int index;// the index of sms in memory,0-100.
+    int status;//read:0,unread:1
+    int smslen;//the length of sms,the maximum length shall not exceed the length specified in 3GGP protocol(160/70)
+    char message[MSG_MAX_LEN];//sms content
+    RIL_SOCKET_ID soc_id;
+    char teleNum[50];//telephony number
+    int numLen;
+}storeMessageInfo;
+int lynq_send_sms(const char *telephonyNumber, const int charset,const char *msg, const char *smsc, smsResponse* smsResp);
+int lynq_Ims_send_sms(const char *telephonyNumber, const int charset,const char *msg, const char*retryNum,const char *messageRef, const char *smsc,smsResponse *smsResp);
+int lynq_write_sms_to_sim(const int smsStatus,const char *recPhonNum,const int charset,const char *msg,const char *smsc,messageStoreInfo *msgstroeInfo);
+int lynq_report_sms_memory_status(const int status,lynqBase *base);
+int lynq_delet_sms_on_sim(const int index,lynqBase *base);
+int lynq_get_smsc_address(smscCbInfo *smscInfo);
+int lynq_set_smsc_address(const char* serviceNumber,lynqBase *base);
+void lynq_recive_new_sms_cb(RIL_SOCKET_ID soc_id,char * num, char * smsc, char * msg, int charset);
+int lynq_store_sms_to_memory(RIL_SOCKET_ID soc_id,const int status,char * num,const char* sms,lynqBase *base);
+int lynq_get_sms_from_memory(const int index, storeMessageInfo* sms,lynqBase *base);
+int lynq_delete_message_from_memory(const int index,lynqBase *base);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/LICENSE b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/LICENSE
new file mode 100644
index 0000000..77f59ed
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/LICENSE
@@ -0,0 +1,31 @@
+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) 2015. 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.
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/Ril_responsedispatch.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/Ril_responsedispatch.cpp
new file mode 100644
index 0000000..e75e26d
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/Ril_responsedispatch.cpp
@@ -0,0 +1,202 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include <alloca.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <vendor-ril/telephony/ril.h>
+#include "common.h"
+#undef LOG_TAG
+#define LOG_TAG "DEMO_RspDisp"
+
+//data struct
+typedef struct{
+    int request;
+    RIL_SOCKET_ID socket_id;
+    char* arg;
+}ResponseDisptachData;
+
+struct RspDisp_Event{
+    struct RspDisp_Event* next;
+    struct RspDisp_Event* prev;
+    ResponseDisptachData data;
+};
+//global variable
+static pthread_mutex_t s_listMutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t s_listCond = PTHREAD_COND_INITIALIZER;
+//marco define
+#define LIST_LOCK()  pthread_mutex_lock(&s_listMutex)
+#define LIST_UNLOCK() pthread_mutex_unlock(&s_listMutex)
+#define WAITLIST() pthread_cond_wait(&s_listCond,&s_listMutex)
+#define WAKEUPLIST() pthread_cond_signal(&s_listCond)
+
+//list variable and function announce
+static struct RspDisp_Event rspDisp_list;
+void initList(struct RspDisp_Event* list);
+void addToList(struct RspDisp_Event* ev, struct RspDisp_Event* list);
+void removeFromList(struct RspDisp_Event* ev);
+
+void intRspList()
+{
+    LIST_LOCK();
+    initList(&rspDisp_list);
+    LIST_UNLOCK();
+}
+
+//function define
+void initList(struct RspDisp_Event* list)
+{
+    memset(list, 0 ,sizeof(struct RspDisp_Event));
+    list->next = list;
+    list->prev = list;
+    RLOGD("Demo Ril_event init list!");
+}
+
+void addToList(struct RspDisp_Event* ev, struct RspDisp_Event* list)
+{ //add to list tail
+    ev->next = list;
+    ev->prev = list->prev;
+    ev->prev->next = ev;
+    list->prev = ev;
+    RLOGD("Demo Ril_event add an event to list!");
+}
+
+void removeFromList(struct RspDisp_Event* ev)
+{
+    ev->next->prev = ev->prev;
+    ev->prev->next = ev->next;
+    ev->next = NULL;
+    ev->prev = NULL;
+    RLOGD("Demo Ril_event remove an event from list!");
+}
+
+void ARspRequestWithArg(int request, const char* arg,RIL_SOCKET_ID socket_id)
+{
+    struct RspDisp_Event* event = (struct RspDisp_Event*)malloc(sizeof(struct RspDisp_Event));
+
+    if(event == NULL)
+    {
+        RLOGE("malloc event memory error!");
+        return;
+    }
+    RLOGD("A Request happened, request is %s!",android::requestToString(request));
+    event->data.request = request;
+    if (arg != NULL) {
+        event->data.arg = strdup(arg);
+    } else {
+        event->data.arg = NULL;
+    }
+
+    event->data.socket_id = socket_id;
+    event->prev = NULL;
+    event->next = NULL;
+    LIST_LOCK();
+    addToList(event,&rspDisp_list);
+    WAKEUPLIST();
+    LIST_UNLOCK();
+    return;
+}
+
+void ARspRequest (int request,RIL_SOCKET_ID socket_id)
+{
+    ARspRequestWithArg(request, NULL,socket_id);
+}
+
+int dispOnSupport(int request)
+{
+    switch (request){
+    case RIL_REQUEST_GET_CURRENT_CALLS:       return 1;
+    case RIL_REQUEST_ANSWER:                  return 1;
+    case RIL_REQUEST_GET_SIM_STATUS:          return 1;
+    case RIL_REQUEST_DATA_REGISTRATION_STATE: return 1;
+    case RIL_REQUEST_VOICE_REGISTRATION_STATE: return 1;
+    case RIL_REQUEST_SMS_ACKNOWLEDGE:         return 1;
+    case RIL_REQUEST_OEM_HOOK_RAW:              return 1;
+    case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: return 1;
+    case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE: return 1;
+    case RIL_REQUEST_RADIO_POWER: return 1;
+    case RIL_REQUEST_ALLOW_DATA: return 1;
+    case RIL_REQUEST_CDMA_FLASH: return 1;
+    case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: return 1;
+    //case :return 1;
+    default:return 0;
+    }
+}
+//ResponseDispatch function used for :
+// 1. ril request triggered by RIL_onRequestComplete flow
+// 2. ril request triggered by RIL_onUnsolicitedResponse flow
+void responseDispatch()
+{
+    struct RspDisp_Event* event = NULL;
+    RLOGD("start loop!");
+
+    prctl(PR_SET_NAME,(unsigned long)"demo_Rsp_disp");
+
+    //LIST_LOCK();
+    //initList(&rspDisp_list);
+    //LIST_UNLOCK();
+
+    for(;;){
+
+        LIST_LOCK();
+        if(rspDisp_list.next == &rspDisp_list) {    //if blank list  then wait
+            RLOGD("blank list ,then wait!");
+            while(rspDisp_list.next == &rspDisp_list){
+                WAITLIST();
+            }
+        }
+        event = rspDisp_list.next;
+        removeFromList(event);
+        LIST_UNLOCK();
+
+         // do ril request
+         if(dispOnSupport(event->data.request) != 1) {
+            RLOGD("event not support!");
+            goto event_done;
+        }
+        android::RspDispFunction(event->data.request, event->data.arg, event->data.socket_id);
+
+    event_done:
+        if(event != NULL) {
+            if(event->data.arg != NULL) {
+                free(event->data.arg);
+                event->data.arg = NULL;
+            }
+            free(event);
+            event = NULL;
+        }
+    }
+
+    return;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/ATCI.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/ATCI.cpp
new file mode 100644
index 0000000..97376a7
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/ATCI.cpp
@@ -0,0 +1,805 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include <string.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <signal.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <vendor-ril/telephony/ril.h>
+
+#include "common.h"
+#include "util/utils.h"
+#include "atci/ATCI.h"
+#include "atci_util.h"
+#include "atci_at_util.h"
+#include "Radio_capability_switch_util.h"
+
+#ifdef ATCI_PARSE
+#include "atci_sys_cmd.h"
+#include "atci_ss_cmd.h"
+#include "atci_cc_cmd.h"
+#endif
+
+struct sockaddr_un atci_server_addr;
+//struct sockaddr_in atci_server_addr;
+//struct sockaddr_un atci_client_addr;
+#undef LOG_TAG
+#define LOG_TAG "DEMO_ATCI"
+
+#if ATCI_ENABLE_RESPONSE
+char Respose_buf[RESPONSE_BUF_SIZE];
+#endif
+
+#ifdef ATCI_PARSE
+int atci_dispatch_cmd(char *line);
+#endif
+
+int atci_server_socket_fd, atci_client_connect;
+namespace android {
+    extern int s_registerCalled;
+}
+
+#define SOCKET_ZERO   0
+#define SOCKET_SUCC   1
+#define SOCKET_FAIL  -1
+static int ATCI_Token = 0;
+
+int ATCISupport(int request) {
+  switch (request) {
+  case TELEPHONY_REQUEST_SET_CALL_FORWARD:
+    return 1;
+  case TELEPHONY_REQUEST_SET_CALL_WAITING:
+    return 1;
+  case TELEPHONY_REQUEST_SET_CALL_BARRING:
+    return 1;
+  case TELEPHONY_REQUEST_DIAL:
+    return 1;
+  case TELEPHONY_REQUEST_DROP_CONF_CALL_MEMBER:
+    return 1;
+  case TELEPHONY_REQUEST_FLIGHT:
+    return 1;
+  case TELEPHONY_REQUEST_SET_MUTE:
+    return 1;
+  case TELEPHONY_REQUEST_MERGE_CONF_CALLS:
+    return 1;
+  case TELEPHONY_REQUEST_CREATE_IMS_CONF_CALL:
+    return 1;
+  case TELEPHONY_REQUEST_DIAL_WITH_SIP_URI:
+    return 1;
+  default:
+    return 0;
+  }
+}
+const char * ATCIReqRspToString(int request) {
+  switch (request) {
+  case TELEPHONY_REQUEST_SET_CALL_FORWARD:
+    return "SET_CALL_FORWARD";
+  case TELEPHONY_REQUEST_SET_CALL_WAITING:
+    return "SET_CALL_WAITING";
+  case TELEPHONY_REQUEST_SET_CALL_BARRING:
+    return "SET_CALL_BARRING";
+  case TELEPHONY_REQUEST_DIAL:
+    return "DIAL";
+  case TELEPHONY_REQUEST_DROP_CONF_CALL_MEMBER:
+    return "DROP_CONF_CALL_MEMBER";
+  case TELEPHONY_REQUEST_FLIGHT:
+    return "FLIGHT";
+  case TELEPHONY_RESPONSE_FLIGHT:
+    return "RSP_FLIGHT";
+  case TELEPHONY_REQUEST_SET_MUTE:
+    return "SET_MUTE";
+  case TELEPHONY_REQUEST_MERGE_CONF_CALLS:
+    return "MERGE_CONF_CALLS";
+  case TELEPHONY_REQUEST_CREATE_IMS_CONF_CALL:
+    return "CREATE_IMS_CONF_CALL";
+  case TELEPHONY_REQUEST_DIAL_WITH_SIP_URI:
+    return "DIAL_WITH_SIP_URI";
+  default:
+    return "<unknown request>";
+  }
+}
+//return requestNumber
+int ATCIParserRequest(int request) {
+  //char* cPoint = buf;
+  //int reqNum = 0;
+
+  RLOGD("ATCI Parser request number start!");
+
+  //memcpy(&reqNum,cPoint,sizeof(int));
+  RLOGD("Request is %d,%s", request, ATCIReqRspToString(request));
+
+  if (ATCISupport(request) != 1)
+    return -1;
+
+  return request;
+}
+
+int MappingATCI2RIL(int reqNum) {
+  int request = 0;
+  switch (reqNum) {
+  case TELEPHONY_REQUEST_SET_CALL_FORWARD:
+    request = RIL_REQUEST_SET_CALL_FORWARD;
+    break;
+  case TELEPHONY_REQUEST_SET_CALL_WAITING:
+    request = RIL_REQUEST_SET_CALL_WAITING;
+    break;
+  case TELEPHONY_REQUEST_SET_CALL_BARRING:
+    request = RIL_REQUEST_SET_FACILITY_LOCK;
+    break;
+  case TELEPHONY_REQUEST_DIAL:
+    request = RIL_REQUEST_DIAL;
+    break;
+  case TELEPHONY_REQUEST_DROP_CONF_CALL_MEMBER:
+    request = RIL_REQUEST_REMOVE_IMS_CONFERENCE_CALL_MEMBER;
+    break;
+  case TELEPHONY_REQUEST_FLIGHT:
+    request = RIL_REQUEST_RADIO_POWER;
+    break;
+  case TELEPHONY_REQUEST_SET_MUTE:
+    request = RIL_REQUEST_SET_MUTE;
+    break;
+  case TELEPHONY_REQUEST_MERGE_CONF_CALLS:
+    request = RIL_REQUEST_CONFERENCE;
+    break;
+  case TELEPHONY_REQUEST_CREATE_IMS_CONF_CALL:
+    request = RIL_REQUEST_CONFERENCE_DIAL;
+    break;
+  case TELEPHONY_REQUEST_DIAL_WITH_SIP_URI:
+    request = RIL_REQUEST_DIAL_WITH_SIP_URI;
+    break;
+  default:
+    request = -1;
+  }
+
+  return request;
+}
+
+int MappingParameter(int reqNum, int length, char* data, char* buf,
+    char** argv) {
+  int argc = 1;
+  char* cPoint;
+
+  cPoint = buf;
+  switch (reqNum) {
+  case TELEPHONY_REQUEST_SET_CALL_FORWARD: {
+    if (length != sizeof(telephonyRequestSetCallForward)) {
+      RLOGD("Set_Call_Forward data error!");
+      return -1;
+    }
+    telephonyRequestSetCallForward tempSCF;
+    memset(&tempSCF, 0, sizeof(tempSCF));
+    memcpy(&tempSCF, data, length);
+
+    //cmd parameter sequence: status, reason, number, time_seconds, service_class; other not need.
+    argv[1] = cPoint;  //status
+    cPoint += sizeof(tempSCF.status);
+    sprintf(argv[1], "%d", tempSCF.status);
+
+    argv[2] = cPoint; //reason
+    cPoint += sizeof(tempSCF.reason);
+    sprintf(argv[2], "%d", tempSCF.reason);
+
+    argv[5] = cPoint; //service_class
+    cPoint += sizeof(tempSCF.service_class);
+    sprintf(argv[5], "%d", tempSCF.service_class);
+
+    argv[6] = cPoint; //toa
+    cPoint += sizeof(tempSCF.toa);
+    sprintf(argv[6], "%d", tempSCF.toa);
+
+    argv[3] = cPoint;  //number
+    cPoint += sizeof(tempSCF.number);
+    sprintf(argv[3], "%s", tempSCF.number);
+
+    argv[4] = cPoint; //time_seconds
+    sprintf(argv[4], "%d", tempSCF.time_seconds);
+
+    argc += 5;
+    RLOGD(
+        "TELEPHONY_REQUEST_SET_CALL_FORWARD status(%s) reason(%s) number(%s) time_seconds(%s) service_class(%s) --toa(%s)",
+        argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]);
+  }
+    break;
+  case TELEPHONY_REQUEST_SET_CALL_WAITING: {
+    if (length != sizeof(telephonyRequestSetCallWaiting)) {
+      RLOGD("Set_Call_Waiting data error!");
+      return -1;
+    }
+    telephonyRequestSetCallWaiting tempSCW;
+    memset(&tempSCW, 0, sizeof(tempSCW));
+    memcpy(&tempSCW, data, length);
+
+    //cmd parameter sequence: statue, service_code
+    argv[1] = cPoint;  //status
+    cPoint += sizeof(tempSCW.status);
+    sprintf(argv[1], "%d", tempSCW.status);
+
+    argv[2] = cPoint; //service_class
+    sprintf(argv[2], "%d", tempSCW.service_class);
+
+    argc += 2;
+    RLOGD("TELEPHONY_REQUEST_SET_CALL_WAITING status(%s) service_class(%s)",
+        argv[1], argv[2]);
+  }
+    break;
+  case TELEPHONY_REQUEST_SET_CALL_BARRING: {
+    if (length != sizeof(telephonyRequestSetCallBarring)) {
+      RLOGD("Set_Call_Barring data error!");
+      return -1;
+    }
+    telephonyRequestSetCallBarring tempSCB;
+    memset(&tempSCB, 0, sizeof(tempSCB));
+    memcpy(&tempSCB, data, length);
+
+    //cmd parameter sequence: facility, password, serviceclass,enable; other not need.
+    argv[4] = cPoint;  //status
+    cPoint += sizeof(tempSCB.status);
+    sprintf(argv[4], "%d", tempSCB.status);
+
+    argv[1] = cPoint;  //facility
+    cPoint += sizeof(tempSCB.facility);
+    sprintf(argv[1], "%s", tempSCB.facility);
+
+    argv[2] = cPoint;  //password
+    cPoint += sizeof(tempSCB.password);
+    sprintf(argv[2], "%s", tempSCB.password);
+
+    argv[3] = cPoint;  //serviceclass
+    cPoint += sizeof(tempSCB.serviceClass);
+    sprintf(argv[3], "%d", tempSCB.serviceClass);
+
+    argc += 4;
+    RLOGD(
+        "TELEPHONY_REQUEST_SET_CALL_Barring facility(%s) password(%s) service_class(%s) status(enable)(%s)",
+        argv[1], argv[2], argv[3], argv[4]);
+  }
+    break;
+  case TELEPHONY_REQUEST_DIAL: {
+    if (length != sizeof(telephonyRequestDial)) {
+      RLOGD("Request dail data error!");
+      return -1;
+    }
+    telephonyRequestDial tempDIAL;
+    memset(&tempDIAL, 0, sizeof(tempDIAL));
+    memcpy(&tempDIAL, data, length);
+
+    //cmd parameter sequence: callnumber, clir;
+    argv[2] = cPoint;  //clir
+    cPoint += sizeof(tempDIAL.clir);
+    sprintf(argv[2], "%d", tempDIAL.clir);
+
+    argv[1] = cPoint;  //phonyNumber
+    sprintf(argv[1], "%s", tempDIAL.phonyNumber);
+
+    argc += 2;
+    RLOGD("TELEPHONY_REQUEST_DIAL CLIR(%s) PhoneNumber(%s)", argv[2], argv[1]);
+  }
+    break;
+  case TELEPHONY_REQUEST_DROP_CONF_CALL_MEMBER: {
+    if (length != sizeof(telephonyRequestDropConfCallMember)) {
+      RLOGD("DropConfCallMember data error!");
+      return -1;
+    }
+    telephonyRequestDropConfCallMember tempDCCM;
+    memset(&tempDCCM, 0, sizeof(tempDCCM));
+    memcpy(&tempDCCM, data, length);
+
+    //cmd parameter sequence: callId, addr, ToAdd; other not need.
+    argv[1] = cPoint;  //ConfCallID
+    cPoint += sizeof(tempDCCM.confCallID);
+    sprintf(argv[1], "%d", tempDCCM.confCallID);
+
+    argv[2] = cPoint;  //phonyNumber
+    cPoint += sizeof(tempDCCM.phonyNumber);
+    sprintf(argv[2], "%d", tempDCCM.phonyNumber);
+
+    argv[3] = cPoint;  //callIDToAdd
+    sprintf(argv[3], "%d", tempDCCM.callIDToAdd);
+
+    argc += 3;
+    RLOGD(
+        "TELEPHONY_REQUEST_DROP_CONF_CALL_MEMBER ConfCallID(%s) phonyNumber(%s) callIDToAdd(%s)",
+        argv[1], argv[2], argv[3]);
+  }
+    break;
+  case TELEPHONY_REQUEST_FLIGHT: {
+    if (length != sizeof(telephonyRequestFlight)) {
+      RLOGD("Request flight data error!");
+      return -1;
+    }
+    telephonyRequestFlight tempFT;
+    memset(&tempFT, 0, sizeof(tempFT));
+    memcpy(&tempFT, data, length);
+
+    //cmd parameter sequence: mode.
+    argv[1] = cPoint;  //flightModeOn
+    sprintf(argv[1], "%d", (tempFT.flightModeOn == 1 ? 0 : 1));
+
+    argc += 1;
+    RLOGD("TELEPHONY_REQUEST_FLIGHT flight Mode is %s-->(%s)",
+        (tempFT.flightModeOn == 1 ? "On" : "Off"), argv[1]);
+  }
+    break;
+  case TELEPHONY_REQUEST_SET_MUTE: {
+    if (length != sizeof(telephonyRequestSetMute)) {
+      RLOGD("Request flight data error!");
+      return -1;
+    }
+    telephonyRequestSetMute tempSM;
+    memset(&tempSM, 0, sizeof(tempSM));
+    memcpy(&tempSM, data, length);
+
+    //cmd parameter sequence: mode.
+    argv[1] = cPoint;  //isMute
+    sprintf(argv[1], "%d", tempSM.isMute);
+
+    argc += 1;
+    RLOGD("TELEPHONY_REQUERT_SET_MUTE isMute(%s)", argv[1]);
+  }
+    break;
+  case TELEPHONY_REQUEST_MERGE_CONF_CALLS: {
+    RLOGD("TELEPHONY_REQUERT_MERGE_CONF_CALLS (No Parm.)");
+  }
+    break;
+  case TELEPHONY_REQUEST_CREATE_IMS_CONF_CALL: {
+    //cmd parameter sequence: DialMethod, ParticipantsNumber, addresses, clir;
+    argv[1] = cPoint;  //DialMethod
+    sprintf(argv[1], "%d", 0);
+    cPoint += sizeof(int);
+
+    argv[2] = cPoint;  //ParticipantsNumber
+    sprintf(argv[2], "%d", 0);
+    cPoint += sizeof(int);
+    //no address
+    argv[3] = cPoint;  //CLIR
+    sprintf(argv[2], "%s", "0");
+
+    argc += 3;
+    RLOGD(
+        "TELEPHONY_REQUEST_CREATE_IMS_CONF_CALL dialMethod(%d) PhoneNumber(%d),clir(%s)",
+        argv[1], argv[2], argv[3]);
+  }
+    break;
+  case TELEPHONY_REQUEST_DIAL_WITH_SIP_URI: {
+    if (length != sizeof(telephonyRequestDial)) //struct with the same as DIAL
+        {
+      RLOGD("Request DialWithSipUri data error!");
+      return -1;
+    }
+    telephonyRequestDial tempDWSU;
+    memset(&tempDWSU, 0, sizeof(tempDWSU));
+    memcpy(&tempDWSU, data, length);
+
+    //cmd parameter sequence: address, clir;
+    argv[2] = cPoint;  //clir
+    cPoint += sizeof(tempDWSU.clir);
+    sprintf(argv[2], "%d", tempDWSU.clir);
+
+    argv[1] = cPoint;  //address
+    sprintf(argv[1], "%s", tempDWSU.phonyNumber);
+
+    argc += 2;
+    RLOGD("TELEPHONY_REQUEST_DIAL_WITH_SIP_URI CLIR(%d) PhoneNumber(%s)",
+        argv[2], argv[1]);
+  }
+    break;
+  default:
+    break;
+  }
+
+  return argc;
+}
+
+void ATCIResponse(int token, int error, char* data, int reqNum)
+{
+  //int reqNum;
+  char buf[64];
+  if(token&ATCI_TOKEN_MARK != ATCI_TOKEN_MARK) {
+      if(token == 0 && data == NULL && reqNum == 0) {
+          RLOGD("AT%RESTART: %d", error);
+      } else {
+          RLOGE("ATCIRespnse Error, Token not ATCI\n");
+      }
+
+  } else {
+      RLOGD("token is %d,%s",reqNum,android::requestToString(reqNum));
+  }
+
+  memset(buf, 0, sizeof(buf));
+  if(error == 1){
+      sprintf(buf,"%s","ERROR");
+  } else {
+      sprintf(buf,"%s","OK");
+  }
+
+  int len_s = send(atci_client_connect, buf, strlen(buf), 0);
+  RLOGD("Response Buf is %s, send length is %d",buf,len_s);
+}
+
+#ifdef ATCI_PARSE
+int acti_cmd_recv(int fd, char *buf, int len) {
+  int ret = 0;
+  fd_set rfds;
+  //FD_CLR(fd, &rfds);
+  FD_SET(fd, &rfds);
+  ret = select(fd + 1, &rfds, NULL, NULL, NULL);
+  if (ret <= 0) {
+    RLOGE("acti_cmd_recv select error, ret=%d, error=%s(%d),fd=%d", ret,
+        strerror(errno), errno, fd);
+    return SOCKET_FAIL;
+  }
+  if (FD_ISSET(fd, &rfds)) {
+    ret = recv(fd, buf, len, 0);
+    if (ret < 0) {
+      RLOGE("acti_cmd_recv select error, ret=%d, error=%s(%d),fd=%d", ret,
+          strerror(errno), errno, fd);
+      return SOCKET_FAIL;
+    } else if (ret == 0) {
+      RLOGE("acti_cmd_recv recv error, ret=%d, error=%s(%d),fd=%d", ret,
+          strerror(errno), errno, fd);
+      return SOCKET_ZERO;
+    } else {
+      //buf[ret] = '\0';
+    }
+
+  }
+  return SOCKET_SUCC;
+}
+#endif
+
+int atci_sock_recv(int fd, char *buf, int len) {
+  int ret = 0;
+  int offset = 0;
+
+  while (offset < len) {
+    fd_set rfds;
+    FD_SET(fd, &rfds);
+    ret = select(fd + 1, &rfds, NULL, NULL, NULL);
+    if (ret < 0) {
+      if (errno == EINTR || errno == EAGAIN) {
+        continue;
+      }
+      RLOGE("atci_sock_recv select error, ret=%d, error=%s(%d),fd=%d", ret,
+          strerror(errno), errno, fd);
+      return SOCKET_FAIL;
+    } else if (ret == 0) {
+      continue;
+    }
+    if (FD_ISSET(fd, &rfds)) {
+      ret = recv(fd, buf + offset, len - offset, 0);
+      if (ret < 0) {
+        RLOGE("atci_sock_recv recv error, ret=%d, error=%s(%d),fd=%d", ret,
+            strerror(errno), errno, fd);
+        return SOCKET_FAIL;
+      } else if (ret == 0) {
+        RLOGE("atci_sock_recv recv error, ret=%d, error=%s(%d),fd=%d", ret,
+            strerror(errno), errno, fd);
+        return SOCKET_ZERO;
+      }
+      offset += ret;
+    }
+  }
+  return SOCKET_SUCC;
+}
+
+void sendAtciRequest(int request, char* reqStr, int argc, char** argv) {
+    //for dsds, should close two slot radio.
+    if(utils::is_support_dsds() && (request == RIL_REQUEST_RADIO_POWER)){
+        int enable = atoi(argv[1])? 1 : 0;
+        for(int i = 0; i < 2; i++) {
+            //For GCF, enhance AT%Flight=0. only SIM is inserted, radio can open.
+            if(enable){
+                if (Radio_capability_switch_util::is_sim_inserted(i)) {
+                    RequestInfo* pRI = (RequestInfo*) (calloc(1, sizeof(RequestInfo)));
+                    pRI->socket_id = (RIL_SOCKET_ID)i;
+                    android::ATCIRequest(request, reqStr, (void*) (pRI), argc, argv);
+                } {
+                    RLOGD("ignore radio power on command because of absent SIM Card");
+                }
+            } else {
+                RequestInfo* pRI = (RequestInfo*) (calloc(1, sizeof(RequestInfo)));
+                pRI->socket_id = (RIL_SOCKET_ID)i;
+                android::ATCIRequest(request, reqStr, (void*) (pRI), argc, argv);
+            }
+        }
+    } else {
+        RequestInfo* pRI = (RequestInfo*) (calloc(1, sizeof(RequestInfo)));
+        android::ATCIRequest(request, reqStr, (void*) (pRI), argc, argv);
+    }
+  return;
+}
+
+void * StartATCISocket(void *param) {
+  RLOGD("StartATCISocket start\n");
+  socklen_t server_len, client_len;
+  struct sockaddr_un atci_client_addr;
+  //struct sockaddr_in atci_client_addr;
+  char parser_buf[SOCKET_BUF_SIZE];
+  char *argv[ATCI_MAX_ARGS];
+  int argc = 0;
+
+  prctl(PR_SET_NAME, (unsigned long) "ATCI_Thr");
+
+  /* create socket */
+  unlink(ATCI_SERVER_SOCKET);
+  atci_server_socket_fd = socket(AF_UNIX, SOCK_STREAM, 0);
+  //atci_server_socket_fd = socket(AF_INET, SOCK_STREAM, 0);
+  if (atci_server_socket_fd == -1) {
+    RLOGE("Create ATCI Socket Failed:");
+    exit(1);
+  }
+  memset(&atci_server_addr, 0, sizeof(atci_server_addr));
+  atci_server_addr.sun_family = AF_UNIX;
+  //atci_server_addr.sin_family = AF_INET;
+  //atci_server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+  //atci_server_addr.sin_port = htons(10004);
+  strcpy(atci_server_addr.sun_path, ATCI_SERVER_SOCKET);
+  server_len = sizeof(atci_server_addr);
+  /* bind socket port*/
+  if (-1
+      == bind(atci_server_socket_fd, (struct sockaddr *) &atci_server_addr,
+          server_len)) {
+    RLOGE("Server Bind Failed:");
+    exit(1);
+  }
+
+  if (listen(atci_server_socket_fd, 1) == -1) {
+    RLOGE("listen fail!");
+    close(atci_server_socket_fd);
+    exit(1);
+  }
+#ifdef ATCI_PARSE
+  DbgMsg("init cmd handle");
+  if(/*atci_generic_init(NULL)||*/atci_cc_init(NULL)||atci_ss_init(NULL)||atci_sys_init(NULL)) {
+    ErrMsg("module init function error,exit");
+    exit(-1);
+  }
+#endif
+  TryNewLink:
+  client_len = sizeof(atci_client_addr);
+  int conn = accept(atci_server_socket_fd,
+      (struct sockaddr *) &atci_client_addr, &client_len);
+  if (conn <= 0) {
+    RLOGE("accept error!");
+    close(conn);
+    exit(1);
+  }
+  RLOGD("Accept a client , fd is %d", conn);
+  atci_client_connect = conn;
+  socketData recv_data;
+  int ret;
+  /* tranlate data */
+  while (true) {
+    if (!android::s_registerCalled) {
+      sleep(1);
+      continue;
+    }
+#ifdef ATCI_PARSE
+    memset(parser_buf, 0, sizeof(parser_buf));
+    ret = acti_cmd_recv(conn, parser_buf, SOCKET_BUF_SIZE);
+    if (ret < 0) {
+      RLOGE("receive CMD error");
+      continue;
+    } else if (ret == SOCKET_ZERO) {
+      RLOGE("maybe client socket closed 1. retry new link!");
+      goto TryNewLink;
+    }
+    atci_dispatch_cmd(parser_buf);
+#else
+    memset(parser_buf, 0, sizeof(parser_buf));
+    memset(&recv_data, 0, sizeof(socketData));
+
+    //receive_ID
+    ret = atci_sock_recv(conn, (char*) &recv_data.requestId,
+        sizeof(recv_data.requestId));
+    if (ret < 0) {
+      RLOGE("reveive request id is error");
+      continue;
+    } else if (ret == SOCKET_ZERO) {
+      RLOGE("maybe client socket closed 1. retry new link!");
+      goto TryNewLink;
+    }
+    RLOGE("reveive request id is %d", recv_data.requestId);
+
+    //receive_length
+    ret = atci_sock_recv(conn, (char*) &recv_data.datalen,
+        sizeof(recv_data.datalen));
+    if (ret < 0) {
+      RLOGE("reveive request lenth is error");
+      continue;
+    } else if (ret == SOCKET_ZERO) {
+      RLOGE("maybe client socket closed 2. retry new link!");
+      goto TryNewLink;
+    }
+    RLOGE("reveive request lenth is %d", recv_data.datalen);
+
+    //receive_data
+    recv_data.data = (char*) calloc(recv_data.datalen, 1);
+    if (NULL == recv_data.data) {
+      RLOGE("alloc mem error");
+      continue;
+    }
+    ret = atci_sock_recv(conn, recv_data.data, recv_data.datalen);
+    if (ret < 0) {
+      RLOGE("reveive request data is error");
+      free(recv_data.data);
+      recv_data.data = NULL;
+      continue;
+    } else if (ret == SOCKET_ZERO) {
+      RLOGE("maybe client socket closed 3. retry new link!");
+      free(recv_data.data);
+      recv_data.data = NULL;
+      goto TryNewLink;
+    }
+
+    int reqNum = ATCIParserRequest(recv_data.requestId);
+    if (reqNum <= 0) {
+      RLOGE("ATCI command is error!");
+      continue;
+    }
+
+    int request = MappingATCI2RIL(reqNum);
+    char reqStr[RIL_REQUEST_STRING_LENGTH];
+
+    memcpy(reqStr, request2RILStr(request),
+        strlen(request2RILStr(request)) + 1);
+    RLOGD("request is %s", reqStr);
+    argc = MappingParameter(reqNum, recv_data.datalen, recv_data.data,
+        parser_buf, argv);
+    if (argc <= 0) {
+      RLOGE("ATCI command is error!");
+      continue;
+    }
+    free(recv_data.data);
+    recv_data.data = NULL;
+    sendAtciRequest(request, reqStr, argc, argv);
+#endif
+  };
+
+  RLOGD("close socket fd!");
+  close(atci_server_socket_fd);
+
+  RLOGD("exist start ATCI socket thread, errno:%d", errno);
+  // kill self to restart on error
+  kill(0, SIGKILL);
+  return NULL;
+}
+
+#ifdef ATCI_PARSE
+char* atci_get_cmd_prefix(char *line) {
+  int buf_len;
+  char *prefix;
+  char *end_ptr;
+  if (NULL == line) {
+    RLOGD("input is null");
+    return NULL;
+  }
+  end_ptr = line;
+  while (!ATCI_IS_CAHR(*end_ptr, ATCI_EQUAL)
+      && !ATCI_IS_CAHR(*end_ptr, ATCI_QUESTION_MARK)
+      && !ATCI_IS_CAHR(*end_ptr, ATCI_END_CHAR)
+      && !ATCI_IS_CAHR(*end_ptr, ATCI_CR) && !ATCI_IS_CAHR(*end_ptr, ATCI_LF)) {
+    end_ptr++;
+  }
+  buf_len = end_ptr - line + 1;
+  prefix = (char *) calloc(buf_len, 1);
+  if (prefix) {
+    int i;
+    char *in_ptr = line;
+    char *out_ptr = prefix;
+    for (i = 0; i < buf_len - 1; i++) {
+      if (!ATCI_IS_CAHR(*in_ptr, ATCI_SPACE)) {
+        *out_ptr = ATCI_UPPER_TO_LOWER(*in_ptr);
+        out_ptr++;
+      }
+      in_ptr++;
+    }
+    *out_ptr = ATCI_END_CHAR;
+  }
+  RLOGD("get cmd prefix [%d][%s]", buf_len, prefix);
+  return prefix;
+}
+
+int atci_get_cmd_mode(char *line) {
+  int reasult = AT_WRONG_MODE;
+  char *p_cur = NULL;
+  if (NULL == line) {
+    reasult = AT_WRONG_MODE;
+    RLOGD("atci_get_cmd_mode error, input is NULL");
+    return reasult;
+  }
+  p_cur = strchr(line, ATCI_EQUAL);
+  if (NULL == p_cur) {
+    p_cur = strchr(line, ATCI_QUESTION_MARK);
+    if (NULL == p_cur) {
+      reasult = AT_ACTIVE_MODE;
+    } else {
+      reasult = AT_READ_MODE;
+    }
+  } else {
+    p_cur++;
+    atci_at_skip_space(&p_cur);
+    if (ATCI_QUESTION_MARK == *p_cur) {
+      reasult = AT_TEST_MODE;
+    } else {
+      reasult = AT_SET_MODE;
+    }
+  }
+  RLOGD("atci_get_cmd_mode success[%d]", reasult);
+  return reasult;
+}
+
+int atci_dispatch_cmd(char *line) {
+  int ret = SYS_FAIL;
+  char *prefix = NULL;
+  //atci_Info_t* atci_ptr = atci_info_get();
+  atci_cmd_type_t* cmd_handle = NULL;
+  if (NULL == line) {
+    RLOGD("CMD is null");
+    return SYS_FAIL;
+  }
+  RLOGD("enter: %s", line);
+
+  prefix = atci_get_cmd_prefix(line);
+  if (NULL == prefix) {
+    RLOGD("atci_cut_cmd_prefix error");
+    return SYS_FAIL;
+  }
+  RLOGD("find prefix [%s]", prefix);
+  cmd_handle = atci_find_cmd_handler(prefix);
+  free(prefix);
+  if (NULL == cmd_handle) {
+    RLOGD("not find handler");
+  } else {
+    RLOGD("find handler");
+    int cmd_mode = atci_get_cmd_mode(line);
+    char response[MAX_RESP_BUF_LENGTH];
+    memset(response, 0, sizeof(response));
+    RLOGD("write to handler");
+    ret = cmd_handle->cmd_handle_func(line, cmd_mode, cmd_handle->target,
+        response);
+    if (SYS_FAIL == ret) {
+      RLOGD("cmd_handle_func error");
+    } else {
+      RLOGD("cmd_handle_func success");
+    }
+  }
+  return ret;
+}
+#endif
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/ATCI.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/ATCI.h
new file mode 100644
index 0000000..45f9d4f
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/ATCI.h
@@ -0,0 +1,151 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#ifndef __ATCI__
+#define __ATCI__
+
+#include "atci_common.h"
+
+#define PHONE_NUMBER_LENGTH 256
+//#define SPI_URI_LENGTH 256
+#define ATCI_SERVER_SOCKET "/dev/socket/atci_server_socket"
+#define SOCKET_BUF_SIZE 1024
+#if ATCI_ENABLE_RESPONSE
+#define RESPONSE_BUF_SIZE 512
+#endif
+#define COMMAND_LENGTH 1024
+#define ATCI_MAX_ARGS 10
+#define RIL_REQUEST_STRING_LENGTH 128
+#define TELEPHONY_REQUEST_BASE 0
+#define TELEPHONY_RESPONSE_BASE 1000
+
+#define TELEPHONY_REQUEST_SET_CALL_FORWARD (TELEPHONY_REQUEST_BASE + 1)
+#define TELEPHONY_REQUEST_SET_CALL_WAITING (TELEPHONY_REQUEST_BASE + 2)
+#define TELEPHONY_REQUEST_SET_CALL_BARRING (TELEPHONY_REQUEST_BASE + 3)
+#define TELEPHONY_REQUEST_DIAL (TELEPHONY_REQUEST_BASE + 4)
+#define TELEPHONY_REQUEST_DROP_CONF_CALL_MEMBER (TELEPHONY_REQUEST_BASE + 5)
+#define TELEPHONY_REQUEST_FLIGHT (TELEPHONY_REQUEST_BASE + 6)
+#define TELEPHONY_REQUEST_SET_MUTE (TELEPHONY_REQUEST_BASE + 7)
+#define TELEPHONY_REQUEST_MERGE_CONF_CALLS (TELEPHONY_REQUEST_BASE + 8)
+#define TELEPHONY_REQUEST_CREATE_IMS_CONF_CALL (TELEPHONY_REQUEST_BASE +9)
+#define TELEPHONY_REQUEST_DIAL_WITH_SIP_URI (TELEPHONY_REQUEST_BASE +10)
+
+#define TELEPHONY_RESPONSE_FLIGHT (TELEPHONY_RESPONSE_BASE + 1)
+
+#if ATCI_ENABLE_RESPONSE
+extern char Respose_buf[RESPONSE_BUF_SIZE];
+#endif
+//request struct
+typedef struct {
+  int status;
+  int reason;
+  int service_class;
+  int toa;
+  char number[PHONE_NUMBER_LENGTH];
+  int time_seconds;
+} telephonyRequestSetCallForward;
+
+typedef struct {
+  int status;
+  int service_class;
+} telephonyRequestSetCallWaiting;
+
+typedef struct {
+  int status;
+  char facility[32];
+  char password[32];
+  int serviceClass;
+  char aid[32];
+} telephonyRequestSetCallBarring;
+
+typedef struct {
+  int clir;
+  char phonyNumber[PHONE_NUMBER_LENGTH];
+} telephonyRequestDial;
+
+typedef struct {
+  int confCallID;
+  char phonyNumber[PHONE_NUMBER_LENGTH];
+  int callIDToAdd;
+} telephonyRequestDropConfCallMember;
+
+typedef struct {
+  unsigned int flightModeOn;
+} telephonyRequestFlight;
+
+typedef struct {
+  int isMute;
+} telephonyRequestSetMute;
+
+typedef struct {
+  int reserve;
+} telephonyRequestCreateIMSConfCall;
+
+//response struct
+typedef struct {
+  int ret;
+} telephonyResponseFlight;
+
+#if 1 //socket data protocol.
+typedef struct {
+  int requestId;
+  int datalen;
+  char * data;
+} socketData;
+#endif
+
+#ifdef ATCI_PARSE
+
+#define MAX(a,b)  ((a)>(b)?(a):(b))
+
+typedef enum {
+  INCH_TYPE_MIN = 0,
+  INCH_TYPE_UART,
+  INCH_TYPE_CHAR,
+  INCH_TYPE_UTCP,
+  INCH_TYPE_MAX
+} atci_inch_type_e;
+
+typedef struct atci_num_resp_s {
+  char resp[20];
+  int num;
+} atci_num_resp_t;
+
+void sendAtciRequest(int request, char* reqStr, int argc, char** argv);
+#endif
+
+void ATCIResponse(int token, int error, char* data, int reqNum);
+
+void * StartATCISocket(void *param);
+#endif
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/atci_at_util.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/atci_at_util.cpp
new file mode 100644
index 0000000..027d924
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/atci_at_util.cpp
@@ -0,0 +1,104 @@
+#include "atci_common.h"
+#include "atci_at_util.h"
+
+int atci_at_skip_space(char **p_cur) {
+  if (*p_cur == NULL) {
+    return SYS_FAIL;
+  }
+  while (**p_cur == ATCI_SPACE) {
+    (*p_cur)++;
+  }
+  return SYS_SUCC;
+}
+int atci_at_hasmore(char **p_cur) {
+  if (*p_cur == NULL || **p_cur == ATCI_END_CHAR) {
+    return SYS_FAIL;
+  }
+  return SYS_SUCC;
+}
+
+int atci_at_to_equal(char **p_cur) {
+  if (*p_cur == NULL) {
+    return SYS_FAIL;
+  }
+  *p_cur = strchr(*p_cur, ATCI_EQUAL);
+  if (*p_cur == NULL) {
+    return SYS_FAIL;
+  }
+  (*p_cur)++;
+  return SYS_SUCC;
+}
+int atci_at_to_colon(char **p_cur) {
+  if (*p_cur == NULL) {
+    return SYS_FAIL;
+  }
+  *p_cur = strchr(*p_cur, ATCI_COLON);
+  if (*p_cur == NULL) {
+    return SYS_FAIL;
+  }
+  (*p_cur)++;
+  return SYS_SUCC;
+}
+int atci_at_skip_next_comma(char **p_cur) {
+  if (*p_cur == NULL) {
+    return SYS_FAIL;
+  }
+  *p_cur = strchr(*p_cur, ATCI_COMMA);
+  if (*p_cur == NULL) {
+    return SYS_FAIL;
+  }
+  (*p_cur)++;
+  return SYS_SUCC;
+}
+int atci_at_get_next_key(char **p_cur, char **p_out) {
+  if (*p_cur == NULL) {
+    return SYS_FAIL;
+  }
+  atci_at_skip_space(p_cur);
+  if (**p_cur == ATCI_DOUBLE_QUOTE) {
+    (*p_cur)++;
+    *p_out = strsep(p_cur, "\"");
+    atci_at_skip_next_comma(p_cur);
+  } else {
+    *p_out = strsep(p_cur, ",");
+  }
+  return SYS_SUCC;
+}
+
+/**
+ * Parses the next integer in the  line and places it in *p_out
+ * "uns" is indicate in unsigned or not
+ * returns SYS_SUCC on success
+ * returns SYS_FAIL  on fail
+ * updates *p_cur
+ * "base" is the same as the base param in strtol
+ */
+int atci_at_get_nextint_base(char **p_cur, int *p_out, int base, int uns) {
+  char *ret;
+  if (*p_cur == NULL) {
+    return SYS_FAIL;
+  }
+  if (SYS_FAIL == atci_at_get_next_key(p_cur, &ret)) {
+    return SYS_FAIL;
+  } else {
+    long l;
+    char *end;
+    if (uns) {
+      l = strtoul(ret, &end, base);
+    } else {
+      l = strtol(ret, &end, base);
+    }
+    *p_out = (int) l;
+    if (end == ret) {
+      return SYS_FAIL;
+    }
+  }
+  return SYS_SUCC;
+}
+int atci_at_get_nextint(char **p_cur, int *p_out) {
+  return atci_at_get_nextint_base(p_cur, p_out, 10, 0);
+}
+int atci_at_get_nexthexint(char **p_cur, int *p_out) {
+  return atci_at_get_nextint_base(p_cur, p_out, 16, 1);
+}
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/atci_at_util.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/atci_at_util.h
new file mode 100644
index 0000000..dfcc324
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/atci_at_util.h
@@ -0,0 +1,13 @@
+#ifndef _ATCI_AT_UTIL_H_
+#define _ATCI_AT_UTIL_H_
+
+int atci_at_skip_space(char **p_cur);
+int atci_at_hasmore(char **p_cur);
+int atci_at_to_equal(char **p_cur);
+int atci_at_to_colon(char **p_cur);
+int atci_at_skip_next_comma(char **p_cur);
+int atci_at_get_nextint_base(char **p_cur, int *p_out, int base, int uns);
+int atci_at_get_nextint(char **p_cur, int *p_out);
+int atci_at_get_nexthexint(char **p_cur, int *p_out);
+int atci_at_get_next_key(char **p_cur, char **p_out);
+#endif
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/atci_cc_cmd.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/atci_cc_cmd.cpp
new file mode 100644
index 0000000..8a41e90
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/atci_cc_cmd.cpp
@@ -0,0 +1,293 @@
+#include <vendor-ril/telephony/ril.h>
+#include <string.h>
+#include <log/log.h>
+
+#include "ATCI.h"
+#include "atci_util.h"
+#include "atci_at_util.h"
+#include "atci_cc_cmd.h"
+#include "atci_common.h"
+
+#undef LOG_TAG
+#define LOG_TAG "DEMO_ATCI_CC"
+
+atci_cmd_type_t atci_cc_cmd_table[] = {
+//cmd_name      target_type        handler
+    { "at%dial", TARGET_TELEPHONY, atci_cc_dial_hdlr },
+    { "at%mute", TARGET_TELEPHONY, atci_cc_mute_hdlr },
+    { "at%conference", TARGET_TELEPHONY, atci_cc_conference_hdlr },
+    { NULL, TARGET_UNKNOWN, NULL }
+};
+
+int atci_cc_init(void *arg) {
+  int ret;
+  ret = atci_cmd_register(atci_cc_cmd_table);
+  return ret;
+}
+
+int atci_cc_mute_hdlr(char *cmd, int op_mode, int target, char *response) {
+  int ret;
+  switch (op_mode) {
+  case AT_SET_MODE:
+  case AT_READ_MODE:
+  case AT_ACTIVE_MODE:
+  case AT_TEST_MODE: {
+    //paser parameter
+    //send to target handle
+    //ex: at%dial=int,string
+    RLOGD("input cmd[%s]", cmd);
+
+    if (SYS_FAIL == atci_at_to_equal(&cmd)) {
+      //input error
+      return SYS_FAIL;
+      break;
+    }
+
+    RLOGD("reamin data is[%s]", cmd);
+    // get isMute(int)
+
+    int isMute;
+
+    if (SYS_FAIL == atci_at_get_nexthexint(&cmd, &isMute)) {
+      return SYS_FAIL;
+      break;
+    }
+
+    RLOGD("isMute value is %d", isMute);
+
+    //wrire data to target
+    atci_data_req_t req;
+    req.request_id = RIL_REQUEST_SET_MUTE;
+    req.data_len = sizeof(int);
+    req.data = &isMute;
+    RLOGD("input req data");
+
+    char parser_buf[SOCKET_BUF_SIZE] = { 0 };
+    char reqStr[RIL_REQUEST_STRING_LENGTH] = {0};
+    memcpy(reqStr, request2RILStr(req.request_id),
+        strlen(request2RILStr(req.request_id)) + 1);
+    RLOGD("request is %s", reqStr);
+    char* argv[2] = { 0 };
+    argv[0] = reqStr;
+    argv[1] = parser_buf;
+    sprintf(argv[1], "%d", isMute);
+    int argc = 2;
+    RLOGD("RIL_REQUEST_SET_MUTE (%d) ",argv[1]);
+    sendAtciRequest(req.request_id, reqStr, argc, argv);
+    break;
+  }
+  default: {
+    RLOGD("set mute error");
+    break;
+  }
+  }
+  return SYS_SUCC;
+}
+
+int atci_cc_conference_hdlr(char *cmd, int op_mode, int target,
+    char *response) {
+  int ret;
+  int op = -1;
+
+  switch (op_mode) {
+  case AT_SET_MODE:
+  case AT_READ_MODE:
+  case AT_ACTIVE_MODE:
+  case AT_TEST_MODE: {
+    //paser parameter
+    //send to target handle
+    //ex: at%dial=int,string
+    RLOGD("input cmd[%s]", cmd);
+
+    if (SYS_FAIL == atci_at_to_equal(&cmd)) {
+      //input error
+      return SYS_FAIL;
+      break;
+    }
+
+    RLOGD("remain data is[%s]", cmd);
+
+    if (SYS_FAIL == atci_at_get_nexthexint(&cmd, &op)) {
+      return SYS_FAIL;
+      break;
+    }
+
+    if (op > 2 || op < 0) {
+      RLOGD("data op code %d is wrong!", op);
+      return SYS_FAIL;
+      break;
+    }
+
+    //wrire data to target
+    atci_data_req_t req;
+    if (op == 0) {
+      req.request_id = RIL_REQUEST_CONFERENCE;
+      RLOGD("request id is RIL_REQUEST_CONFERENCE!\n");
+
+      char reqStr[RIL_REQUEST_STRING_LENGTH] = {0};
+      memcpy(reqStr, request2RILStr(req.request_id),
+          strlen(request2RILStr(req.request_id)) + 1);
+      RLOGD("request is %s", reqStr);
+      char* argv[1] = { 0 };
+      argv[0] = reqStr;
+      int argc = 1;
+      sendAtciRequest(req.request_id, reqStr, argc, argv);
+    }
+//TBD
+    else {
+      req.request_id = RIL_REQUEST_CONFERENCE_DIAL;
+      RLOGD("request id is RIL_REQUEST_CONFERENCE_DIAL");
+      int argc = 1;
+      char* cPoint;
+      char parser_buf[SOCKET_BUF_SIZE] = { 0 };
+      char reqStr[RIL_REQUEST_STRING_LENGTH] = {0};
+      cPoint = parser_buf;
+      memcpy(reqStr, request2RILStr(req.request_id),
+          strlen(request2RILStr(req.request_id)) + 1);
+      char* argv[4] = { 0 };
+      argv[0] = reqStr;
+
+      //cmd parameter sequence: DialMethod, ParticipantsNumber, addresses, clir;
+      argv[1] = cPoint;  //DialMethod
+      sprintf(argv[1], "%d", 0);
+      cPoint += sizeof(int);
+
+      argv[2] = cPoint;  //ParticipantsNumber
+      sprintf(argv[2], "%d", 0);
+      cPoint += sizeof(int);
+      //no address
+      argv[3] = cPoint;  //CLIR
+      sprintf(argv[2], "%s", "0");
+
+      argc += 3;
+      RLOGD("RIL_REQUEST_CONFERENCE_DIAL dialMethod(%d) PhoneNumber(%d),clir(%s)",
+          argv[1], argv[2], argv[3]);
+      sendAtciRequest(req.request_id, reqStr, argc, argv);
+    }
+  }
+  default: {
+    RLOGD("conference error");
+    break;
+  }
+  }
+  return SYS_SUCC;
+}
+
+int atci_cc_dial_hdlr(char *cmd, int op_mode, int target, char *response) {
+  int ret;
+  int op = -1;
+  int uriflag = 0;
+  char *tmp = NULL;
+  char *p_out = NULL;
+  char ch_tmp;
+  int i = 0;
+
+  switch (op_mode) {
+  case AT_SET_MODE:
+  case AT_READ_MODE:
+  case AT_ACTIVE_MODE:
+  case AT_TEST_MODE: {
+    //paser parameter
+    //send to target handle
+    //ex: at%dial=int,string
+    RLOGD("input cmd[%s]", cmd);
+
+    telephonyRequestDial dial_info;
+    dial_info.clir = 0;
+
+    if (SYS_FAIL == atci_at_to_equal(&cmd)) {
+      //input error
+      return SYS_FAIL;
+      break;
+    }
+
+    RLOGD("remain data is[%s]", cmd);
+
+    tmp = cmd;
+
+    if (SYS_FAIL == atci_at_get_nexthexint(&cmd, &op)) {
+      //return SYS_FAIL;
+      //break ;
+      op = -1;
+    }
+
+    RLOGD("operation info is %d", op);
+
+    if (op >= 0 && op < 5) {
+      // get number (string)
+      if (SYS_FAIL == atci_at_hasmore(&cmd)) {
+        return SYS_FAIL;
+        break;
+      }
+
+      if (SYS_FAIL == atci_at_get_next_key(&cmd, &p_out)) {
+        return SYS_FAIL;
+        break;
+      }
+
+      strcpy(dial_info.phonyNumber, p_out);
+
+      RLOGD("read string is %s", dial_info.phonyNumber);
+    } else {
+      if (SYS_FAIL == atci_at_get_next_key(&tmp, &p_out)) {
+        return SYS_FAIL;
+        break;
+      }
+
+      strcpy(dial_info.phonyNumber, p_out);
+
+      RLOGD("read string is %s", dial_info.phonyNumber);
+    }
+
+    //wrire data to target
+    atci_data_req_t req;
+
+    for (i = 0; i < strlen(dial_info.phonyNumber); i++) {
+      ch_tmp = dial_info.phonyNumber[i];
+      if ((ch_tmp < '0' || ch_tmp > '9') && ch_tmp != '+') {
+        uriflag = 1;
+        break;
+      }
+    }
+
+    if (uriflag == 0) {
+      req.request_id = RIL_REQUEST_DIAL;
+      RLOGD("request id is RIL_REQUEST_DIAL!\n");
+    } else {
+      req.request_id = RIL_REQUEST_DIAL_WITH_SIP_URI;
+      RLOGD("request id is TELEPHONY_REQUEST_DIAL_WITH_SIP_URI!\n");
+    }
+
+    req.data_len = sizeof(dial_info);
+    req.data = &dial_info;
+
+    int argc = 1;
+    char* cPoint;
+    char parser_buf[SOCKET_BUF_SIZE] = { 0 };
+    char reqStr[RIL_REQUEST_STRING_LENGTH] = {0};
+    cPoint = parser_buf;
+    memcpy(reqStr, request2RILStr(req.request_id),
+        strlen(request2RILStr(req.request_id)) + 1);
+    char* argv[3] = { 0 };
+    argv[0] = reqStr;
+
+    argv[2] = cPoint;  //clir
+    cPoint += sizeof(dial_info.clir);
+    sprintf(argv[2], "%d", dial_info.clir);
+
+    argv[1] = cPoint;  //phonyNumber
+    sprintf(argv[1], "%s", dial_info.phonyNumber);
+
+    argc += 2;
+    RLOGD("%s(%s) PhoneNumber(%s)", reqStr, argv[2], argv[1]);
+    sendAtciRequest(req.request_id, reqStr, argc, argv);
+    break;
+  }
+  default: {
+    RLOGD("dial error");
+    break;
+  }
+  }
+  return SYS_SUCC;
+}
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/atci_cc_cmd.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/atci_cc_cmd.h
new file mode 100644
index 0000000..a532180
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/atci_cc_cmd.h
@@ -0,0 +1,13 @@
+/*
+ This is an internal header file.
+ */
+#ifndef __ATCI_CC_CMD_H__
+#define __ATCI_CC_CMD_H__
+
+int atci_cc_init(void *arg);
+int atci_cc_dial_hdlr(char *cmd, int op_type, int target, char *response);
+int atci_cc_conference_hdlr(char *cmd, int op_mode, int target, char *response);
+int atci_cc_mute_hdlr(char *cmd, int op_mode, int target, char *response);
+
+#endif
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/atci_common.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/atci_common.h
new file mode 100644
index 0000000..01e738a
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/atci_common.h
@@ -0,0 +1,162 @@
+//ATCI Service  atcmd
+#ifndef _ATCI_COMMON_H_
+#define _ATCI_COMMON_H_
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <netinet/in.h>
+#include <sys/un.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <termios.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <signal.h>
+#ifndef  ATCI_UT
+#include "log/log.h"
+//#include <sncfg/sncfg.h>
+#include <cutils/properties.h>
+#endif
+#define SYS_SUCC                    0
+#define SYS_FAIL                    -1
+#define INVALIDE_FD                 -1
+#define MAX_CMD_BUF_LENGTH          4096
+#define MAX_RESP_BUF_LENGTH         4096
+#define MUX_APP_NUM                 5
+#define MAX_CMD_HANDLER_MODULE_NUM  20
+#define MAX_CMD_PREFIX_LENGTH       64
+#undef  LOG_TAG
+#define LOG_TAG                     "ATCI"
+
+typedef enum {
+  ATCI_SPACE = ' ',
+  ATCI_EQUAL = '=',
+  ATCI_COMMA = ',',
+  ATCI_SEMICOLON = ';',
+  ATCI_COLON = ':',
+  ATCI_AT = '@',
+  ATCI_HAT = '^',
+  ATCI_MONEY = '$',
+  ATCI_DOUBLE_QUOTE = '"',
+  ATCI_QUESTION_MARK = '?',
+  ATCI_EXCLAMATION_MARK = '!',
+  ATCI_FORWARD_SLASH = '/',
+  ATCI_L_ANGLE_BRACKET = '<',
+  ATCI_R_ANGLE_BRACKET = '>',
+  ATCI_R_BRACKET = ')',
+  ATCI_L_BRACKET = '(',
+  ATCI_L_SQ_BRACKET = '[',
+  ATCI_R_SQ_BRACKET = ']',
+  ATCI_L_CURLY_BRACKET = '{',
+  ATCI_R_CURLY_BRACKET = '}',
+  ATCI_CHAR_STAR = '*',
+  ATCI_CHAR_POUND = '#',
+  ATCI_CHAR_AMPSAND = '&',
+  ATCI_CHAR_PERCENT = '%',
+  ATCI_CHAR_PLUS = '+',
+  ATCI_CHAR_MINUS = '-',
+  ATCI_CHAR_DOT = '.',
+  ATCI_CHAR_ULINE = '_',
+  ATCI_CHAR_TILDE = '~',
+  ATCI_CHAR_REVERSE_SOLIDUS = '\\',
+  ATCI_CHAR_VERTICAL_LINE = '|',
+  ATCI_END_CHAR = '\0',
+  ATCI_CR = '\r',
+  ATCI_LF = '\n',
+  ATCI_CHAR_0 = '0',
+  ATCI_CHAR_1 = '1',
+  ATCI_CHAR_2 = '2',
+  ATCI_CHAR_3 = '3',
+  ATCI_CHAR_4 = '4',
+  ATCI_CHAR_5 = '5',
+  ATCI_CHAR_6 = '6',
+  ATCI_CHAR_7 = '7',
+  ATCI_CHAR_8 = '8',
+  ATCI_CHAR_9 = '9',
+  ATCI_CHAR_A = 'A',
+  ATCI_CHAR_B = 'B',
+  ATCI_CHAR_C = 'C',
+  ATCI_CHAR_D = 'D',
+  ATCI_CHAR_E = 'E',
+  ATCI_CHAR_F = 'F',
+  ATCI_CHAR_G = 'G',
+  ATCI_CHAR_H = 'H',
+  ATCI_CHAR_I = 'I',
+  ATCI_CHAR_J = 'J',
+  ATCI_CHAR_K = 'K',
+  ATCI_CHAR_L = 'L',
+  ATCI_CHAR_M = 'M',
+  ATCI_CHAR_N = 'N',
+  ATCI_CHAR_O = 'O',
+  ATCI_CHAR_P = 'P',
+  ATCI_CHAR_Q = 'Q',
+  ATCI_CHAR_R = 'R',
+  ATCI_CHAR_S = 'S',
+  ATCI_CHAR_T = 'T',
+  ATCI_CHAR_U = 'U',
+  ATCI_CHAR_V = 'V',
+  ATCI_CHAR_W = 'W',
+  ATCI_CHAR_X = 'X',
+  ATCI_CHAR_Y = 'Y',
+  ATCI_CHAR_Z = 'Z',
+  ATCI_CHAR_a = 'a',
+  ATCI_CHAR_b = 'b',
+  ATCI_CHAR_c = 'c',
+  ATCI_CHAR_d = 'd',
+  ATCI_CHAR_e = 'e',
+  ATCI_CHAR_f = 'f',
+  ATCI_CHAR_g = 'g',
+  ATCI_CHAR_h = 'h',
+  ATCI_CHAR_i = 'i',
+  ATCI_CHAR_j = 'j',
+  ATCI_CHAR_k = 'k',
+  ATCI_CHAR_l = 'l',
+  ATCI_CHAR_m = 'm',
+  ATCI_CHAR_n = 'n',
+  ATCI_CHAR_o = 'o',
+  ATCI_CHAR_p = 'p',
+  ATCI_CHAR_q = 'q',
+  ATCI_CHAR_r = 'r',
+  ATCI_CHAR_s = 's',
+  ATCI_CHAR_t = 't',
+  ATCI_CHAR_u = 'u',
+  ATCI_CHAR_v = 'v',
+  ATCI_CHAR_w = 'w',
+  ATCI_CHAR_x = 'x',
+  ATCI_CHAR_y = 'y',
+  ATCI_CHAR_z = 'z',
+} atci_char_enum;
+
+typedef enum {
+  AT_WRONG_MODE, AT_SET_MODE, //Ex: at+eample=xxx
+  AT_READ_MODE, //Ex: at+eample?
+  AT_TEST_MODE, //Ex: at+eample=?
+  AT_ACTIVE_MODE //Ex: at+eample
+} atci_cmd_mode_e;
+
+typedef enum {
+  TARGET_TELEPHONY = 0,
+  /*if need send to new app, add target_type */
+  TARGET_UNKNOWN = MUX_APP_NUM,
+  TARGET_RIL,
+  TARGET_GENERIC,
+  TARGET_PLATFORM,
+  TARGET_BATTERY,
+  TARGET_AUDIO,
+  TARGET_EXTERNAL
+} atci_target_e;
+
+#define ATCI_LOWER_TO_UPPER(alpha_char) (((alpha_char >= ATCI_CHAR_a)&&(alpha_char <= ATCI_CHAR_z)) ?  (alpha_char-32): (alpha_char))
+#define ATCI_UPPER_TO_LOWER(alpha_char) (((alpha_char >= ATCI_CHAR_A)&&(alpha_char <= ATCI_CHAR_Z)) ?  (alpha_char+32): (alpha_char))
+#define ATCI_IS_CAHR(input ,alpha_char) ((alpha_char == input)? 1 : 0)
+
+#define SysMsg(f,a...) RLOGI("( %s, %d: )" f "\n",__FUNCTION__, __LINE__,## a)
+#define DbgMsg(f,a...) RLOGD("( %s, %d: )" f "\n",__FUNCTION__, __LINE__,## a)
+#define ErrMsg(f,a...) RLOGE("( %s, %d: )" f "\n",__FUNCTION__, __LINE__,## a)
+
+#endif
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/atci_ss_cmd.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/atci_ss_cmd.cpp
new file mode 100644
index 0000000..ffcafea
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/atci_ss_cmd.cpp
@@ -0,0 +1,371 @@
+#include <vendor-ril/telephony/ril.h>
+#include <string.h>
+#include <log/log.h>
+
+#include "ATCI.h"
+#include "atci_util.h"
+#include "atci_at_util.h"
+#include "atci_ss_cmd.h"
+
+#undef LOG_TAG
+#define LOG_TAG "DEMO_ATCI_SS"
+atci_cmd_type_t atci_ss_cmd_table[] = {
+    //cmd_name                    target_type                 handler
+    { "at%supplementaryservice", TARGET_TELEPHONY, atci_ss_hdlr },
+    { NULL, TARGET_UNKNOWN, NULL }
+};
+
+int atci_ss_init(void *arg) {
+  int ret;
+  ret = atci_cmd_register(atci_ss_cmd_table);
+  return ret;
+}
+
+char *InfoClassToMmiBSCodeString(AtInfoClassE infoClass) {
+  /**
+   * Basic Service
+   * group number (note)  Telecommunication Service       MMI Service Code
+   *
+   * 1 to 12              All tele and bearer services    no code required
+   *
+   *                      Teleservices
+   * 1 to 6, 12           All teleservices                10
+   * 1                    Telephony                       11
+   * 2 to 6               All data teleservices           12
+   * 6                    Facsimile services              13
+   * 2                    Short Message Services          16
+   * 1, 3 to 6, 12        All teleservices except SMS     19
+   * 12                   Voice group services
+   *                      Voice Group Call Service (VGCS) 17
+   *                      Voice Broadcast Service (VBS)   18
+   *
+   *                      Bearer Service
+   * 7 to 11              All bearer services             20
+   * 7                    All async services              21
+   * 8                    All sync services               22
+   * 8                    All data circuit sync           24
+   * 7                    All data circuit async          25
+   * 13                   All GPRS bearer services        99
+   */
+
+  switch (infoClass) {
+  case CLASS_NONE:
+    return BS_ALL;
+    break;
+  case CLASS_VOICE:
+    return BS_TELEPHONY;
+    break;
+  case (CLASS_DATASYNC_OR_DATAASYNC):
+    return BS_DATA_ALL;
+    break;
+  case CLASS_FAX:
+    return BS_TELE_FAX;
+    break;
+  case CLASS_SMS:
+    return BS_TELE_SMS;
+    break;
+  case (CLASS_VOICE_OR_SMS_OR_FAX):
+    return BS_TELE_ALL;
+    break;
+  case (CLASS_SMS_OR_FAX):
+    return BS_TELE_DATA_ALL;
+    break;
+  case (CLASS_VOICE_OR_FAX):
+    return BS_TELE_ALL_EXCEPT_SMS;
+    break;
+  case CLASS_DATA_SYNC:
+    return BS_DATA_CIRCUIT_SYNC;
+    break;
+  case CLASS_DATA_ASYNC:
+    return BS_DATA_CIRCUIT_ASYNC;
+    break;
+  case (CLASS_DATASYNC_OR_DEDICATEDPACKETACCESS):
+    return BS_DATA_SYNC_ALL;
+    break;
+  case (CLASS_DATASYNC_OR_DEDICATEDPADACCESS):
+    return BS_DATA_ASYNC_ALL;
+    break;
+  case (CLASS_DATASYNC_OR_VOICE):
+    return BS_DATA_SYNC_TELE;
+    break;
+  case CLASS_DEDICATED_PACKET_ACCESS:
+    return BS_GPRS_ALL;
+    break;
+  case (CLASS_MTKVIDEO_OR_DATASYNC):
+    return BS_DATA_CIRCUIT_SYNC;
+    break;
+  case CLASS_MTK_VIDEO:
+    return BS_DATA_CIRCUIT_SYNC;
+    break;
+  default:
+    RLOGE("ATCI unknown infoClass: %d", infoClass);
+    break;
+  }
+  return "";
+}
+
+int atci_ss_hdlr(char *cmd, int op_mode, int target, char *response) {
+  int ret = 0;
+  atci_data_req_t req = { 0 };
+  int status = 0;
+  int service_code = 0;
+
+  //check parameter
+  switch (op_mode) {
+  case AT_SET_MODE:
+  case AT_READ_MODE:
+  case AT_ACTIVE_MODE:
+  case AT_TEST_MODE: {
+    //paser parameter
+    //char *input = "MSG_XXXXXX";
+    //char  output[1024];
+    //int   len = strlen(input);
+
+    RLOGD("input cmd[%s]", cmd);
+    //
+    if (SYS_FAIL == atci_at_to_equal(&cmd)) {
+      //input error
+      break;
+    }
+    RLOGD("ss reamin data is[%s]", cmd);
+
+    atci_at_skip_space(&cmd);
+    RLOGD("after remove space, ss reamin data is[%s]", cmd);
+
+    // get status=int1
+    if (SYS_FAIL == atci_at_get_nextint(&cmd, &status)) {
+      RLOGE("For ss, the first param must be int");
+      break;
+    }
+    RLOGD("status is [%d]", status);
+
+    // get service code, such as CFB(67), CFU(21), CF-No Reply(61), CF-Not Reachable(62), CF-Not logged in(68)
+    //call waiting(43)
+    //incoming call barring while roaming(351)
+    if (SYS_FAIL == atci_at_get_nextint(&cmd, &service_code)) {
+      RLOGE("For ss, the second param must be string(service_code)");
+      break;
+    }
+    RLOGD("read service_code is [%d]", service_code);
+
+    if ((service_code == 67) || (service_code == 21) || (service_code == 61)
+        || (service_code == 62) || (service_code == 68)) {
+      telephonyRequestSetCallForward set_CF_data;
+      char *num = NULL;
+      int service_class = 0;
+      char *MMI_BS_Code = NULL;
+      int int_MMI_BS_Code = 0;
+
+      memset(&set_CF_data, 0, sizeof(telephonyRequestSetCallForward));
+
+      if (SYS_FAIL == atci_at_get_next_key(&cmd, &num)) {
+        RLOGE("For ss CF, the third param must be string(number)");
+        break;
+      }
+      RLOGD("num is [%s]", num);
+
+      if (SYS_FAIL == atci_at_get_nextint(&cmd, &service_class)) {
+        RLOGE("For ss CF, the forth param must be string(service_class)");
+        break;
+      }
+      MMI_BS_Code = InfoClassToMmiBSCodeString((AtInfoClassE)service_class);
+      RLOGD("CF service_class is [%d], MMI_BS_Code is %s", service_class,
+          MMI_BS_Code);
+      int_MMI_BS_Code = atoi(MMI_BS_Code);
+      RLOGD("int_MMI_BS_Code=%d", int_MMI_BS_Code);
+
+      if ((service_code == 61) && (status == 1)) {
+        int timeout_second = 0;
+        if (SYS_FAIL == atci_at_get_nextint(&cmd, &timeout_second)) {
+          RLOGE("For ss enable CF-No Reply, the fifth param must be int");
+          break;
+        }
+        RLOGD("timeout_second is [%d]", timeout_second);
+        set_CF_data.time_seconds = timeout_second;
+      }
+
+      //enable SS means register SS
+      if (status == 1) {
+        set_CF_data.status = status + 2;
+      } else {
+        set_CF_data.status = status;
+      }
+      set_CF_data.reason = service_code;
+      strcpy(set_CF_data.number, num);
+      set_CF_data.service_class = int_MMI_BS_Code;
+
+      //write data to DEMO APP
+      req.request_id = RIL_REQUEST_SET_CALL_FORWARD;
+      req.data_len = sizeof(telephonyRequestSetCallForward);
+      req.data = &set_CF_data;
+      RLOGD("input CF_req data");
+      int argc = 1;
+      char* cPoint;
+      char parser_buf[SOCKET_BUF_SIZE] = { 0 };
+      char reqStr[RIL_REQUEST_STRING_LENGTH] = {0};
+      cPoint = parser_buf;
+      memcpy(reqStr, request2RILStr(req.request_id),
+          strlen(request2RILStr(req.request_id)) + 1);
+      char* argv[7] = { 0 };
+      argv[0] = reqStr;
+
+      //cmd parameter sequence: status, reason, number, time_seconds, service_class; other not need.
+      argv[1] = cPoint;  //status
+      cPoint += sizeof(set_CF_data.status);
+      sprintf(argv[1], "%d", set_CF_data.status);
+
+      argv[2] = cPoint; //reason
+      cPoint += sizeof(set_CF_data.reason);
+      sprintf(argv[2], "%d", set_CF_data.reason);
+
+      argv[5] = cPoint; //service_class
+      cPoint += sizeof(set_CF_data.service_class);
+      sprintf(argv[5], "%d", set_CF_data.service_class);
+
+      argv[6] = cPoint; //toa
+      cPoint += sizeof(set_CF_data.toa);
+      sprintf(argv[6], "%d", set_CF_data.toa);
+
+      argv[3] = cPoint;  //number
+      cPoint += sizeof(set_CF_data.number);
+      sprintf(argv[3], "%s", set_CF_data.number);
+
+      argv[4] = cPoint; //time_seconds
+      sprintf(argv[4], "%d", set_CF_data.time_seconds);
+
+      argc += 5; //remove toa
+      RLOGD(
+          "RIL_REQUEST_SET_CALL_FORWARD status(%s) reason(%s) number(%s) time_seconds(%s) service_class(%s) --toa(%s)",
+          argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]);
+      sendAtciRequest(req.request_id, reqStr, argc, argv);
+      RLOGD("input CF_req data success");
+    } else if (service_code == 43) {
+      telephonyRequestSetCallWaiting set_CW_data;
+      int service_class = 0;
+      char *MMI_BS_Code = NULL;
+      int int_MMI_BS_Code = 0;
+
+      memset(&set_CW_data, 0, sizeof(telephonyRequestSetCallWaiting));
+
+      if (SYS_FAIL == atci_at_get_nextint(&cmd, &service_class)) {
+        RLOGE("For ss CW, the third param must be string(service_class)");
+        break;
+      }
+      MMI_BS_Code = InfoClassToMmiBSCodeString((AtInfoClassE)service_class);
+      RLOGD("CW service_class is [%d], MMI_BS_Code is %s", service_class,
+          MMI_BS_Code);
+      int_MMI_BS_Code = atoi(MMI_BS_Code);
+      RLOGD("int_MMI_BS_Code=%d", int_MMI_BS_Code);
+
+      set_CW_data.status = status;
+      set_CW_data.service_class = int_MMI_BS_Code;
+
+      //write data to DEMO APP
+      req.request_id = RIL_REQUEST_SET_CALL_WAITING;
+      req.data_len = sizeof(telephonyRequestSetCallWaiting);
+      req.data = &set_CW_data;
+      RLOGD("input CW_req data");
+      int argc = 1;
+      char* cPoint;
+      char parser_buf[SOCKET_BUF_SIZE] = { 0 };
+      char reqStr[RIL_REQUEST_STRING_LENGTH] = {0};
+      cPoint = parser_buf;
+      memcpy(reqStr, request2RILStr(req.request_id),
+          strlen(request2RILStr(req.request_id)) + 1);
+      char* argv[3] = { 0 };
+      argv[0] = reqStr;
+
+      //cmd parameter sequence: statue, service_code
+      argv[1] = cPoint;  //status
+      cPoint += sizeof(set_CW_data.status);
+      sprintf(argv[1], "%d", set_CW_data.status);
+
+      argv[2] = cPoint; //service_class
+      sprintf(argv[2], "%d", set_CW_data.service_class);
+
+      argc += 2;
+      RLOGD("RIL_REQUEST_SET_CALL_WAITING status(%s) service_class(%s)",argv[1], argv[2]);
+      sendAtciRequest(req.request_id, reqStr, argc, argv);
+      RLOGD("input CW_req data success");
+    } else if (service_code == 351) {
+      telephonyRequestSetCallBarring set_CB_data;
+      char *password = NULL;
+      int service_class = 0;
+      char *MMI_BS_Code = NULL;
+      int int_MMI_BS_Code = 0;
+
+      memset(&set_CB_data, 0, sizeof(telephonyRequestSetCallBarring));
+
+      if (SYS_FAIL == atci_at_get_next_key(&cmd, &password)) {
+        RLOGE("For ss CB, the third param must be string(password)");
+        break;
+      }
+      RLOGD("password is [%s]", password);
+
+      if (SYS_FAIL == atci_at_get_nextint(&cmd, &service_class)) {
+        RLOGE("For ss CB, the forth param must be string(service_class)");
+        break;
+      }
+      MMI_BS_Code = InfoClassToMmiBSCodeString((AtInfoClassE)service_class);
+      RLOGD("CB service_class is [%d], MMI_BS_Code is %s", service_class,
+          MMI_BS_Code);
+      int_MMI_BS_Code = atoi(MMI_BS_Code);
+      RLOGD("int_MMI_BS_Code=%d", int_MMI_BS_Code);
+
+      set_CB_data.serviceClass = int_MMI_BS_Code;
+      set_CB_data.status = status;
+      strcpy(set_CB_data.password, password);
+      sprintf(set_CB_data.facility, "%d", service_code);
+
+      //write data to DEMO APP
+      req.request_id = RIL_REQUEST_SET_FACILITY_LOCK;
+      req.data_len = sizeof(telephonyRequestSetCallBarring);
+      req.data = &set_CB_data;
+      RLOGD("input CB_req data");
+      int argc = 1;
+      char* cPoint;
+      char parser_buf[SOCKET_BUF_SIZE] = { 0 };
+      char reqStr[RIL_REQUEST_STRING_LENGTH] = {0};
+      cPoint = parser_buf;
+      memcpy(reqStr, request2RILStr(req.request_id),
+          strlen(request2RILStr(req.request_id)) + 1);
+      char* argv[5] = { 0 };
+      argv[0] = reqStr;
+
+      //cmd parameter sequence: facility, password, serviceclass,enable; other not need.
+      argv[4] = cPoint;  //status
+      cPoint += sizeof(set_CB_data.status);
+      sprintf(argv[4], "%d", set_CB_data.status);
+
+      argv[1] = cPoint;  //facility
+      cPoint += sizeof(set_CB_data.facility);
+      sprintf(argv[1], "%s", set_CB_data.facility);
+
+      argv[2] = cPoint;  //password
+      cPoint += sizeof(set_CB_data.password);
+      sprintf(argv[2], "%s", set_CB_data.password);
+
+      argv[3] = cPoint;  //serviceclass
+      cPoint += sizeof(set_CB_data.serviceClass);
+      sprintf(argv[3], "%d", set_CB_data.serviceClass);
+
+      argc += 4;
+      RLOGD("RIL_REQUEST_SET_FACILITY_LOCK facility(%s) password(%s) service_class(%s) status(enable)(%s)",
+          argv[1], argv[2], argv[3], argv[4]);
+      sendAtciRequest(req.request_id, reqStr, argc, argv);
+      RLOGD("input CB_req data success");
+    } else {
+      RLOGE("the service code [%d] is not supported by ATCI_SS now",
+          service_code);
+      return SYS_SUCC;
+    }
+    return SYS_SUCC;
+  }
+  default: {
+    break;
+  }
+  }
+  RLOGD("SS error");
+  return SYS_SUCC;
+}
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/atci_ss_cmd.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/atci_ss_cmd.h
new file mode 100644
index 0000000..a59c92d
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/atci_ss_cmd.h
@@ -0,0 +1,64 @@
+/*
+ This is an internal header file.
+ Here are common definitions for the vendor-ril.
+ */
+
+#ifndef __ATCI_SS_CMD_H__
+#define __ATCI_SS_CMD_H__
+
+/*
+ * <classx> is a sum of integers each representing a class of information (default 7):
+ * 1    voice (telephony)
+ * 2    data (refers to all bearer services; with <mode>=2 this may refer only to some bearer service if TA does not support values 16, 32, 64 and 128)
+ * 4    fax (facsimile services)
+ * 8    short message service
+ * 16   data circuit sync
+ * 32   data circuit async
+ * 64   dedicated packet access
+ * 128  dedicated PAD access
+ */
+typedef enum {
+  CLASS_NONE = 0,
+  CLASS_VOICE = 1,
+  CLASS_DATA = 2,
+  CLASS_FAX = 4,
+  CLASS_DEFAULT = 7,
+  CLASS_SMS = 8,
+  CLASS_DATA_SYNC = 16,
+  CLASS_DATA_ASYNC = 32,
+  CLASS_DEDICATED_PACKET_ACCESS = 64,
+  CLASS_DEDICATED_PAD_ACCESS = 128,
+  CLASS_MTK_LINE2 = 256,
+  CLASS_MTK_VIDEO = 512,
+  CLASS_DATASYNC_OR_DATAASYNC = 48,
+  CLASS_VOICE_OR_SMS_OR_FAX = 13,
+  CLASS_SMS_OR_FAX = 12,
+  CLASS_VOICE_OR_FAX = 5,
+  CLASS_DATASYNC_OR_DEDICATEDPACKETACCESS = 80,
+  CLASS_DATASYNC_OR_DEDICATEDPADACCESS = 160,
+  CLASS_DATASYNC_OR_VOICE = 17,
+  CLASS_MTKVIDEO_OR_DATASYNC = 528
+} AtInfoClassE;
+
+#define BS_ALL                   ""
+#define BS_TELE_ALL              "10"
+#define BS_TELEPHONY             "11"
+#define BS_TELE_DATA_ALL         "12"
+#define BS_TELE_FAX              "13"
+#define BS_TELE_SMS              "16"
+#define BS_TELE_VGCS             "17" /* Not supported by framework */
+#define BS_TELE_VBS              "18" /* Not supported by framework */
+#define BS_TELE_ALL_EXCEPT_SMS   "19"
+#define BS_DATA_ALL              "20"
+#define BS_DATA_ASYNC_ALL        "21"
+#define BS_DATA_SYNC_ALL         "22"
+#define BS_DATA_CIRCUIT_SYNC     "24" /* This is also for VT call */
+#define BS_DATA_CIRCUIT_ASYNC    "25"
+#define BS_DATA_SYNC_TELE        "26" /* Supported by framework */
+#define BS_GPRS_ALL              "99"
+
+int atci_ss_init(void *arg);
+int atci_ss_hdlr(char *cmd, int op_type, int target, char *response);
+
+#endif
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/atci_sys_cmd.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/atci_sys_cmd.cpp
new file mode 100644
index 0000000..ce58981
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/atci_sys_cmd.cpp
@@ -0,0 +1,265 @@
+#include <vendor-ril/telephony/ril.h>
+#include <string.h>
+#include <log/log.h>
+
+#include "ATCI.h"
+#include "atci_util.h"
+#include "atci_at_util.h"
+#include <unistd.h>
+#include <linux/reboot.h>
+#include <sys/syscall.h>
+
+#undef LOG_TAG
+#define LOG_TAG "DEMO_ATCI_SYS"
+#define  RESTART_WAITING_TIME 5*1000*1000
+#define  RESTART_REASON       "AT%RESTART"
+
+int atci_sys_ims_enable_hdlr(char *cmd, int op_mode, int target, char *response) {
+    int ret = SYS_FAIL;
+    int ims_enable;
+    char *p_out = NULL;
+    atci_data_req_t req;
+    //check parameter
+    switch (op_mode) {
+    case AT_SET_MODE:
+    case AT_READ_MODE:
+    case AT_ACTIVE_MODE:
+    case AT_TEST_MODE: {
+      //paser parameter
+      //send to target handle
+      //ex: at@example=string1,2,3,4
+      RLOGD("input cmd[%s]", cmd);
+      if (SYS_FAIL == atci_at_to_equal(&cmd)) {
+        //input error
+        RLOGD("input cmd[%s]", cmd);
+        ret = SYS_FAIL;
+        break;
+      }
+      RLOGD("reamin data is[%s]", cmd);
+
+      // get int
+      if (SYS_FAIL == atci_at_hasmore(&cmd)) {
+        ret = SYS_FAIL;
+        break;
+      }
+      if (SYS_FAIL == atci_at_get_nexthexint(&cmd, &ims_enable)) {
+        ret = SYS_FAIL;
+        break;
+      }
+      if (!((ims_enable == 1) || (ims_enable == 0))) {
+        ret = SYS_FAIL;
+        RLOGD("ims enable mode value set fail by user ims_enable = %d",
+            ims_enable);
+        break;
+      }
+      if (SYS_SUCC == atci_at_get_next_key(&cmd, &p_out)) {
+        ret = SYS_FAIL;
+        RLOGD("Fail because reamin data is[%s]", cmd);
+        break;
+      }
+      //wrire data to target if need
+
+      //input data
+      req.request_id = RIL_REQUEST_SET_IMS_ENABLE;
+      req.data_len = sizeof(ims_enable);
+      req.data = &ims_enable;
+      RLOGD("input req data %d", ims_enable);
+      int argc = 1;
+      char* cPoint;
+      char parser_buf[SOCKET_BUF_SIZE] = { 0 };
+      char reqStr[RIL_REQUEST_STRING_LENGTH];
+      cPoint = parser_buf;
+      memcpy(reqStr, request2RILStr(req.request_id),
+          strlen(request2RILStr(req.request_id)) + 1);
+      char* argv[2] = { 0 };
+      argv[0] = reqStr;
+
+      //cmd parameter sequence: mode.
+      argv[1] = cPoint;  //flightModeOn
+      sprintf(argv[1], "%d", (ims_enable == 1 ? 1 : 0));
+
+      argc += 1;
+      RLOGD("RIL_REQUEST_SET_IMS_ENABLE IMS Mode is %s-->(%s)",
+          (ims_enable == 1 ? "on" : "off"), argv[1]);
+      sendAtciRequest(req.request_id, reqStr, argc, argv);
+      RLOGD("call atci_write_data complete %d", ims_enable);
+      ret = SYS_SUCC;
+      //generate response string
+      break;
+    }
+    default: {
+      ret = SYS_FAIL;
+      break;
+    }
+    }
+    if (SYS_SUCC == ret) {
+      return SYS_SUCC;
+    } else {
+      return SYS_FAIL;
+    }
+}
+
+int
+atci_sys_flight_hdlr(char *cmd, int op_mode, int target, char *response) {
+  int ret = SYS_FAIL;
+  int flight_mode;
+  char *p_out = NULL;
+  atci_data_req_t req;
+  //check parameter
+  switch (op_mode) {
+  case AT_SET_MODE:
+  case AT_READ_MODE:
+  case AT_ACTIVE_MODE:
+  case AT_TEST_MODE: {
+    //paser parameter
+    //send to target handle
+    //ex: at@example=string1,2,3,4
+    RLOGD("input cmd[%s]", cmd);
+    if (SYS_FAIL == atci_at_to_equal(&cmd)) {
+      //input error
+      RLOGD("input cmd[%s]", cmd);
+      ret = SYS_FAIL;
+      break;
+    }
+    RLOGD("reamin data is[%s]", cmd);
+
+    // get int
+    if (SYS_FAIL == atci_at_hasmore(&cmd)) {
+      ret = SYS_FAIL;
+      break;
+    }
+    if (SYS_FAIL == atci_at_get_nexthexint(&cmd, &flight_mode)) {
+      ret = SYS_FAIL;
+      break;
+    }
+    if (!((flight_mode == 1) || (flight_mode == 0))) {
+      ret = SYS_FAIL;
+      RLOGD("flight mode value set fail by user flight_mode = %d",
+          flight_mode);
+      break;
+    }
+    if (SYS_SUCC == atci_at_get_next_key(&cmd, &p_out)) {
+      ret = SYS_FAIL;
+      RLOGD("Fail because reamin data is[%s]", cmd);
+      break;
+    }
+    //wrire data to target if need
+
+    //input data
+    req.request_id = RIL_REQUEST_RADIO_POWER;
+    req.data_len = sizeof(flight_mode);
+    req.data = &flight_mode;
+    RLOGD("input req data %d", flight_mode);
+    int argc = 1;
+    char* cPoint;
+    char parser_buf[SOCKET_BUF_SIZE] = { 0 };
+    char reqStr[RIL_REQUEST_STRING_LENGTH];
+    cPoint = parser_buf;
+    memcpy(reqStr, request2RILStr(req.request_id),
+        strlen(request2RILStr(req.request_id)) + 1);
+    char* argv[2] = { 0 };
+    argv[0] = reqStr;
+
+    //cmd parameter sequence: mode.
+    argv[1] = cPoint;  //flightModeOn
+    sprintf(argv[1], "%d", (flight_mode == 1 ? 0 : 1));
+
+    argc += 1;
+    RLOGD("RIL_REQUEST_RADIO_POWER flight Mode is %s-->(%s)",
+        (flight_mode == 1 ? "On" : "Off"), argv[1]);
+    sendAtciRequest(req.request_id, reqStr, argc, argv);
+    RLOGD("call atci_write_data complete %d", flight_mode);
+    ret = SYS_SUCC;
+    //generate response string
+    break;
+  }
+  default: {
+    ret = SYS_FAIL;
+    break;
+  }
+  }
+  if (SYS_SUCC == ret) {
+    return SYS_SUCC;
+  } else {
+    return SYS_FAIL;
+  }
+}
+
+static void* atci_sys_restart_routine(void *arg){
+
+    usleep(RESTART_WAITING_TIME);
+    sync(); /*Force the changes to disk.*/
+
+    RLOGD("RESTART require restart, ByeBye!!!");
+
+    syscall(SYS_reboot,LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, RESTART_REASON);
+
+    return 0;
+}
+
+int atci_sys_invoke_restart(){
+    int             ret;
+    pthread_attr_t  attr;
+    pthread_t       restart_thread;
+
+    pthread_attr_init(&attr);
+
+    RLOGD("create the restart thread");
+    ret = pthread_create(&restart_thread, &attr, atci_sys_restart_routine, NULL);
+    if(0 != ret){
+        RLOGD("failed to create the restart thread");
+    }
+
+    return ret;
+}
+
+int atci_sys_restart_hdlr (char *cmd,int op_mode,int target,char *response){
+    int ret;
+    //check parameter
+
+    RLOGD("atci_sys_restart_hdlr input cmd[%s]",cmd);
+    switch(op_mode){
+        case AT_SET_MODE:
+        case AT_READ_MODE:
+        case AT_ACTIVE_MODE:
+        case AT_TEST_MODE:{
+            //paser parameter
+            //send to target handle
+            //ex: at@example=string1,2,3,4
+
+            ret = atci_sys_invoke_restart();
+            break;
+        }
+        default:{
+            ret = SYS_FAIL;
+            RLOGD("Op mode error");
+            break;
+        }
+    }
+
+    ATCIResponse(0, ret, NULL, 0);
+
+    if(0 == ret){
+        RLOGD("Restart SUCC");
+        return  SYS_SUCC;
+    } else{
+        RLOGD("Restart Fail");
+        return SYS_FAIL;
+    }
+}
+
+atci_cmd_type_t atci_sys_cmd_table[] = {
+      //cmd_name          target_type                 handler
+    { "AT%FLIGHT", TARGET_TELEPHONY, atci_sys_flight_hdlr },
+//    { "AT%RESTART",TARGET_PLATFORM, atci_sys_restart_hdlr },
+    { "AT%IMSENABLE", TARGET_TELEPHONY, atci_sys_ims_enable_hdlr },
+    { NULL, TARGET_UNKNOWN, NULL }
+};
+
+int atci_sys_init(void *arg) {
+  int ret;
+  ret = atci_cmd_register(atci_sys_cmd_table);
+  RLOGD("Init the atci sys");
+  return ret;
+}
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/atci_sys_cmd.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/atci_sys_cmd.h
new file mode 100644
index 0000000..3c33095
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/atci_sys_cmd.h
@@ -0,0 +1,10 @@
+/*
+ This is an internal header file.
+ Here is a example cmd handle function define.
+ */
+#ifndef __ATCI_SYS_CMD_H__
+#define __ATCI_SYS_CMD_H__
+
+int atci_sys_init(void *arg);
+#endif
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/atci_util.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/atci_util.cpp
new file mode 100644
index 0000000..656a251
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/atci_util.cpp
@@ -0,0 +1,82 @@
+#include <vendor-ril/telephony/ril.h>
+#include <log/log.h>
+
+#include "atci_at_util.h"
+#include "atci_util.h"
+
+#undef LOG_TAG
+#define LOG_TAG "DEMO_ATCI_UTIL"
+
+static atci_cmd_type_t *atci_cmd_table[MAX_CMD_HANDLER_MODULE_NUM];
+int atci_cmd_register(atci_cmd_type_t *ptr) {
+  int i = 0;
+  for (i = 0; i < MAX_CMD_HANDLER_MODULE_NUM; i++) {
+    if (NULL == atci_cmd_table[i]) {
+      atci_cmd_table[i] = ptr;
+      return SYS_SUCC;
+    }
+  }
+  RLOGE("atci_cmd_table,is full,cmd_register fail!!!");
+  return SYS_FAIL;
+}
+
+atci_cmd_type_t* atci_find_cmd_handler(char *prefix) {
+
+  atci_cmd_type_t *reasult = NULL;
+  atci_cmd_type_t **reasult_ptr;
+
+  reasult_ptr = atci_cmd_table;
+  int i, j;
+  for (i = 0; i < MAX_CMD_HANDLER_MODULE_NUM; i++) {
+    atci_cmd_type_t *tmp_ptr;
+    if (NULL == reasult_ptr[i]) {
+      continue;
+    }
+    tmp_ptr = reasult_ptr[i];
+    for (j = 0;; j++) {
+      if (NULL == tmp_ptr[j].cmd_prefix) {
+        break;
+      }
+      //RLOGD("scan [%s]",tmp_ptr[j].cmd_prefix);
+      if (0 == strcasecmp(prefix, tmp_ptr[j].cmd_prefix)) {
+        RLOGD("find cmd[%s] handle", prefix);
+        reasult = &tmp_ptr[j];
+        return reasult;
+      }
+    }
+    if (NULL != reasult) {
+      break;
+    }
+  }
+  RLOGD("can't find cmd[%s],need handle by default", prefix);
+  return reasult;
+}
+
+char* request2RILStr(int request) {
+  switch (request) {
+  case RIL_REQUEST_SET_CALL_FORWARD:
+    return "RIL_REQUEST_SET_CALL_FORWARD";
+  case RIL_REQUEST_SET_CALL_WAITING:
+    return "RIL_REQUEST_SET_CALL_WAITING";
+  case RIL_REQUEST_SET_FACILITY_LOCK:
+    return "RIL_REQUEST_SET_FACILITY_LOCK";
+  case RIL_REQUEST_DIAL:
+    return "RIL_REQUEST_DIAL";
+  case RIL_REQUEST_REMOVE_IMS_CONFERENCE_CALL_MEMBER:
+    return "RIL_REQUEST_REMOVE_IMS_CONFERENCE_CALL_MEMBER";
+  case RIL_REQUEST_RADIO_POWER:
+    return "RIL_REQUEST_RADIO_POWER";
+  case RIL_REQUEST_SET_MUTE:
+    return "RIL_REQUEST_SET_MUTE";
+  case RIL_REQUEST_CONFERENCE:
+    return "RIL_REQUEST_CONFERENCE";
+  case RIL_REQUEST_CONFERENCE_DIAL:
+    return "RIL_REQUEST_CONFERENCE_DIAL";
+  case RIL_REQUEST_DIAL_WITH_SIP_URI:
+    return "RIL_REQUEST_DIAL_WITH_SIP_URI";
+  case RIL_REQUEST_SET_IMS_ENABLE:
+    return "RIL_REQUEST_SET_IMS_ENABLE";
+  default:
+    return "unknown define";
+  }
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/atci_util.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/atci_util.h
new file mode 100644
index 0000000..991ab8d
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/atci/atci_util.h
@@ -0,0 +1,23 @@
+//ATCP Service  atcmd
+#ifndef _ATCI_UTIL_H_
+#define _ATCI_UTIL_H_
+#include "atci_common.h"
+
+typedef int (*atci_cmd_handle_func)(char *cmd, int op_mode, int target,
+    char *response);
+typedef struct atci_cmd_type_s {
+  char *cmd_prefix;
+  atci_target_e target;
+  atci_cmd_handle_func cmd_handle_func;
+} atci_cmd_type_t;
+//socket data protocol.
+typedef struct atci_data_req_s {
+  int request_id;
+  int data_len;
+  void *data;
+} atci_data_req_t;
+
+int atci_cmd_register(atci_cmd_type_t *ptr);
+atci_cmd_type_t* atci_find_cmd_handler(char *prefix);
+char* request2RILStr(int request);
+#endif
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/cc.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/cc.cpp
new file mode 100644
index 0000000..8fea821
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/cc.cpp
@@ -0,0 +1,1408 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include "cc.h"
+#include <alloca.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <cutils/jstring.h>
+#include <stdbool.h>
+#include <glib.h>
+#include <string.h>
+#include <string>
+#include <thread>
+#include "eCall.h"
+
+static int dtmf_volume = 0;
+void *dtmf_handle = NULL;
+
+extern "C" {
+    #include <dtmf.h>
+    #include "mixer_ctrl.h"
+}
+#undef LOG_TAG
+#define LOG_TAG "DEMO_CC"
+
+static speech_status speechStatus = SPEECH_OFF;
+int autoAnswerMode = 0;
+static int inCallRecordMode = 0;
+static call_status inCallstatus = CALL_OFF;
+//int callIndex = 0;
+const char g_card_name[] = "mtk_phonecall";
+/*for speech on*/
+const char g_mixer_name[] = "Speech_on";
+const char g_mixer_name_ecall[] = "Speech_on_ecall";
+const char g_mixer_reset_name[] = "Modem_reset_notify";
+const char g_mixer_name_bt[] = "Speech_on_bt";
+const char g_bt_has_ecnr_name[] = "BT_HAS_ECNR";
+const char g_bt_wbs_name[] = "BT_WBS";
+int g_audio_path = 0; // 0: normal, 1: bt
+int g_bt_has_ecnr_value = 0; // 0: ecnr, 1, no ecnr
+int g_bt_wbs_value = 0; // 0: 8000, 1, 16000
+/*for DL call volume*/
+const char g_mixer_name_volume[] = "DL Call";
+const char g_mixer_name_volume_bt[] = "DL BT";
+
+const char g_DL_mute_name[] = "Speech_DL_mute";
+const char g_UL_mute_name[] = "Speech_UL_mute";
+
+const char *RING_PATH = "/system/etc/tele/ring/ring.wav";
+static bool isRingStart = false;
+
+#if defined(TARGET_PLATFORM_MT2731)||defined(TARGET_PLATFORM_MT2735)
+#define MAX_VOLUME (6)
+#define MIN_VOLUME (0)
+#endif
+
+#ifdef TARGET_PLATFORM_MT2635
+#define MAX_VOLUME (17)
+#define MIN_VOLUME (-23)
+#endif
+
+#define BT_MAX_VOLUME (15)
+#define BT_MIN_VOLUME (0)
+#define DTMF_MAX_VOLUME (36)
+#define DTMF_MIN_VOLUME (0)
+
+int get_call_status(void)
+{
+    return inCallstatus;
+}
+
+void set_audio_path(int path)
+{
+    if ((path != 0) && (path != 1)) {
+        RLOGE("set_audio_path() illegal value %d, we support 0: normal, 1: bt", path);
+        return;
+    }
+
+    g_audio_path = path;
+}
+
+int get_audio_path(void)
+{
+    return g_audio_path;
+}
+
+void set_bt_has_ecnr(int ecnr)
+{
+    if ((ecnr != 0) && (ecnr != 1)) {
+        RLOGE("set_bt_has_ecnr() illegal value %d, we support 0: do ecnr, 1: no ecnr", ecnr);
+        return;
+    }
+
+    g_bt_has_ecnr_value = ecnr;
+}
+
+int get_bt_has_ecnr(void)
+{
+    return g_bt_has_ecnr_value;
+}
+
+void set_bt_wbs(int wbs)
+{
+    if ((wbs < 0) || (wbs > 15)) {
+        RLOGE("set_bt_wbs() illegal value %d, we support 0~15", wbs);
+        return;
+    }
+
+    g_bt_wbs_value = wbs;
+}
+
+int get_bt_wbs(void)
+{
+    return g_bt_wbs_value;
+}
+
+int mixer_init()
+{
+    int ret;
+
+    // only need to set card name once
+    ret = set_card_name(g_card_name);
+    RLOGD("mixer_init(%s) = %d", g_card_name, ret);
+    return ret;
+}
+int mixer_set(int value )
+{
+    int ret;
+
+     //set mixer ctl to om:1 or off:0
+    if(value){
+        ret = set_mixer_ctrl_value_int(isEcallAudioPath() ? g_mixer_name_ecall: g_mixer_name, value);
+        RLOGD("mixer_set(%s) = %d, ret: %d", (isEcallAudioPath() ? g_mixer_name_ecall: g_mixer_name), value, ret);
+    } else {
+        //setEcallAudioPathOn(false);
+        ret = get_mixer_ctrl_value_int(g_mixer_name);
+        RLOGD("mixer_set(get_mixer_ctrl_value_int: %s) = %d", g_mixer_name, ret);
+        if(ret  == 0) {
+            ret = set_mixer_ctrl_value_int(g_mixer_name, value);
+            RLOGD("mixer_set(%s) = %d", g_mixer_name, ret);
+        } else {
+            ret = set_mixer_ctrl_value_int(g_mixer_name_ecall, value);
+            RLOGD("mixer_set(%s) = %d", g_mixer_name_ecall, ret);
+        }
+    }
+
+
+    return ret;
+}
+int mixer_reset_set(int value )
+{
+    int ret;
+
+    // set mixer  to reset:1
+    ret = set_mixer_ctrl_value_int(g_mixer_reset_name, value);
+    RLOGD("mixer_reset_set(%s) = %d", g_mixer_reset_name, ret);
+    return ret;
+}
+int bt_mixer_set(int value)
+{
+    int ret;
+
+    //set mixer ctrl to on:1 or off:0
+    // bt speech
+    int bt_has_ecnr = get_bt_has_ecnr();
+    int bt_wbs = get_bt_wbs();
+    ret = set_mixer_ctrl_value_int(g_bt_has_ecnr_name, bt_has_ecnr);
+    ret = set_mixer_ctrl_value_int(g_bt_wbs_name, bt_wbs);
+    ret = set_mixer_ctrl_value_int(g_mixer_name_bt, value);
+
+    if (ret)
+        RLOGE("set_mixer_ctrl_value_int err: %d", ret);
+    return ret;
+}
+
+int mixer_check(int mix)
+{
+    int ret;
+
+    if (mix == 0) {
+        ret = get_mixer_ctrl_value_int(g_mixer_name);
+    } else if (mix == 1){
+        ret = get_mixer_ctrl_value_int(g_mixer_name_bt);
+    } else {
+        RLOGE("mixer_check wrong mix %d", mix);
+    }
+    RLOGD("The ctrl \"%s\" is set to %d ", g_mixer_name, ret);
+    return ret;
+}
+int mixer_set_volume(int value)
+{
+    int ret;
+    if (get_audio_path() == 0) {
+        ret = set_mixer_ctrl_volume_value(g_mixer_name_volume, value);
+    } else {
+        ret = set_mixer_ctrl_volume_value(g_mixer_name_volume_bt, value);
+    }
+    if (ret)
+        RLOGE("set_mixer_ctrl_volume_value_int err: %d", ret);
+    return ret;
+}
+long int mixer_get_volume()
+{
+    long int vol_value;
+    if (get_audio_path() == 0) {
+        vol_value = get_mixer_ctrl_volume_value(g_mixer_name_volume);
+    } 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);
+    return vol_value;
+}
+
+GstElement *pipeline_element;
+GstState gst_cur_state = GST_STATE_NULL;
+static int gst_status = 0;
+
+int GSM_Init(char* filepath)
+{
+    GstElement *pipeline, *source, *mux, *encoder, *sink;
+    RLOGD("[GSM]GSM Init Start!");
+    /* Initialisation */
+    gst_init (NULL, NULL);
+
+    pipeline = gst_pipeline_new ("3gppmux-test");
+    source   = gst_element_factory_make ("pulsesrc",       "file-source");
+    encoder  = gst_element_factory_make ("faac",           "encoder");
+    mux      = gst_element_factory_make ("3gppmux",        "muxer");
+    sink     = gst_element_factory_make ("filesink",       "output");
+
+    g_object_set(mux, "fragment-duration", 100, NULL);
+    g_object_set(sink, "location", filepath, NULL);
+
+    if (!pipeline || !source || !encoder || !mux || !sink) {
+        if(pipeline) {
+            gst_object_unref (GST_OBJECT (pipeline));
+            pipeline = NULL;
+        }
+        if(source) {
+            gst_object_unref (GST_OBJECT (source));
+            source = NULL;
+        }
+        if(encoder) {
+            gst_object_unref (GST_OBJECT (encoder));
+            encoder = NULL;
+        }
+        if(mux) {
+            gst_object_unref (GST_OBJECT (mux));
+            mux = NULL;
+        }
+        if(sink) {
+            gst_object_unref (GST_OBJECT (sink));
+            sink = NULL;
+        }
+        RLOGE ("[GSM]One element could not be created. Exiting");
+        return -1;
+    }
+
+    gst_bin_add_many (GST_BIN (pipeline), source, encoder, mux, sink, NULL);
+    gst_element_link_many (source, encoder, mux, sink, NULL);
+
+    pipeline_element = pipeline;
+    gst_status = 1; //initial done
+    RLOGD("[GSM]GSM Init Done!");
+    return 0;
+}
+
+int GSM_Start(void)
+{
+    RLOGD("[GSM]GSM Start start!");
+    if(gst_status == 2)
+        return 0;
+
+    if(gst_status == 1 || gst_status ==3) {
+        GstStateChangeReturn ret = gst_element_set_state (pipeline_element, GST_STATE_PLAYING);
+
+        RLOGD("[GSM]Running... return: %d", ret);
+        //g_main_loop_run (gst_loop);
+        gst_status = 2; //start done
+    } else {
+        return -1;
+    }
+    RLOGD("[GSM]GSM Start End!");
+    return 0;
+}
+
+int GSM_Stop()
+{
+    RLOGD("[GSM]GSM Stop Start!");
+    if (gst_status == 4)
+        return 0;
+
+    if(gst_status == 2 || gst_status == 3) {
+    /* Out of the main loop, clean up nicely */
+        gboolean isSend = gst_element_send_event (pipeline_element, gst_event_new_eos ());
+        GstStateChangeReturn ret = gst_element_set_state (pipeline_element, GST_STATE_NULL);
+        RLOGD("[GSM]Returned, stopping playback. ret: %d, isSend: %d", ret, isSend);
+        gst_status = 4;
+    } else {
+        return -1;
+    }
+    RLOGD("[GSM]GSM Stop End!");
+    return 0;
+}
+
+int GSM_Close()
+{
+    RLOGD("[GSM]Deleting pipeline");
+    gst_object_unref (GST_OBJECT (pipeline_element));
+    gst_deinit ();
+    gst_status = 0;
+    RLOGD("[GSM]GSM Close Done!");
+    return 0;
+}
+/*cmd:1, address,
+*2, clirMode,
+*3, if present, uusinfo.type
+*4, as above, uusinfo.Dcs
+*5, as above, uusinfo.userdatalength
+*6, as above, uusinfo.UserData
+*/
+//RIL_REQUEST_DIAL
+int dial(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    size_t pos =  p.dataPosition();
+
+    if (argc < 3 || argv[1]==NULL) {
+        //add log msg
+        free(pRI);
+        return -1;
+    }
+    //address;
+    writeStringToParcel(p, (const char *)argv[1]);
+    //clirMode
+    if (argc >=2) {
+    p.writeInt32(atoi(argv[2]));
+
+    if (argc == 7 && argv[3] != NULL
+        && argv[4] != NULL && argv[5] != NULL
+        && argv[6] != NULL ) {
+        p.writeInt32(1); // UUS information is present
+        p.writeInt32(atoi(argv[3]));
+        p.writeInt32(atoi(argv[4]));
+        p.writeByteArray((size_t)atoi(argv[5]),(uint8_t*)argv[6]);
+    } else {
+        p.writeInt32(0); // UUS information is absent
+    }
+    }
+    p.setDataPosition(pos);
+    setEcallAudioPathOn(false);
+    pRI->pCI->dispatchFunction(p, pRI);
+    inCallstatus = CALL_ON;
+    return 0;
+}
+#if 0 //not need user setup
+//RIL_REQUEST_OEM_HOOK_STRINGS
+int invokeOemRilRequestStrings(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    RLOGD("OEM_HOOK_STRINGS: p1->\"%s\",p2->\"%s\"",argv[1],argv[2]);
+    p.writeInt32(2);
+    writeStringToParcel(p, (const char *)argv[1]);
+    writeStringToParcel(p, "\"\"");//(const char *)argv[2]);
+    p.setDataPosition(pos);
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+#endif
+
+extern void ARspRequest (int request,RIL_SOCKET_ID socket_id);
+//RIL_REQUEST_SET_AUDIO_PATH
+/*cmd:1, speech mode,
+*2, bt_has_ecnr
+*3, bt_wbs
+*/
+int setAudioPath(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    if (argc < 1) {
+        free(pRI);
+        RLOGE("set bt mode need bt_has_encr and bt_wbs");
+        return -1;
+    }
+
+    int temp_audio_path = atoi(argv[1]);
+    int bt_has_ecnr;
+    int bt_wbs;
+    int current_audio_path = get_audio_path();
+    RLOGD("setAudioPath enter");
+    if ((temp_audio_path != 0) && (temp_audio_path != 1)) {
+        RLOGE("audio path illegal %d, only support 0 and 1", temp_audio_path);
+        return -1;
+    }
+    set_audio_path(temp_audio_path);
+    RLOGD("set audio path to %d, current audio path is %d", temp_audio_path, current_audio_path);
+    if (temp_audio_path == 1) {
+        /* bt speech need BT_HAS_ECNR and BT_WBS */
+        bt_has_ecnr = atoi(argv[2]);
+        bt_wbs = atoi(argv[3]);
+        set_bt_has_ecnr(bt_has_ecnr);
+        set_bt_wbs(bt_wbs);
+        RLOGD("set bt_has_ecnr %d, bt_wbs %d", bt_has_ecnr, bt_wbs);
+    }
+    if ((current_audio_path != temp_audio_path)
+        && (get_call_status() == CALL_ON)) {
+        if (current_audio_path == 0) {
+            if (getSpeechStatus() == NORMAL_SPEECH_ON) {
+                RLOGD("normal speech off then bt speech on");
+                mixer_set(0);
+                setSpeechAndStatus(2);
+            }
+        } else {
+            if (getSpeechStatus() == BT_SPEECH_ON) {
+                RLOGD("bt speech off then normal speech on");
+                bt_mixer_set(0);
+                setSpeechAndStatus(1);
+            }
+        }
+    }
+    if (pRI != NULL) {
+        free(pRI);
+    }
+
+    RLOGD("setAudioPath done");
+    return 0;
+}
+
+
+//RIL_REQUEST_HANGUP
+int hangupConnection(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+
+    p.writeInt32(1);
+    p.writeInt32(atoi(argv[1]));
+    p.setDataPosition(pos);
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+//RIL_REQUEST_FORCE_RELEASE_CALL
+int forceReleaseCall(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+
+    p.writeInt32(1);
+    p.writeInt32(atoi(argv[1]));
+    p.setDataPosition(pos);
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+//RIL_REQUEST_SEPARATE_CONNECTION
+int separateConnection(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+
+    p.writeInt32(1);
+    p.writeInt32(atoi(argv[1]));
+    p.setDataPosition(pos);
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+//RIL_REQUEST_DTMF
+//RIL_REQUEST_DTMF_START
+int sendDtmf(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    int number;
+    size_t pos = p.dataPosition();
+    char * c_num = NULL;
+
+    c_num = argv[1];
+    if (c_num == NULL) {
+        free(pRI);
+        return -1;
+    }
+    number = int(c_num[0] - '0');
+    if(number == -6)
+       number = 10;
+    if(number == -13)
+       number = 11;
+    RLOGD("DTMF input number is %s-->%d",c_num,number);
+    if ( number < 0 || number > 15 ) {
+        RLOGE("DTMF input number error");
+        free(pRI);
+        return -1;
+    }
+
+    writeStringToParcel(p, (const char *)argv[1]);
+    p.setDataPosition(pos);
+
+    dtmf_stop(dtmf_handle);
+    gint time_ms = 500;
+    if (pRI->pCI->requestNumber == RIL_REQUEST_DTMF_START) {
+        time_ms = 0;
+    }
+    RLOGD("request: %d, time_ms = %d", pRI->pCI->requestNumber, time_ms);
+    dtmf_handle = dtmf_start(number, time_ms, dtmf_volume, NULL);
+    pRI->pCI->dispatchFunction(p, pRI);
+    if (dtmf_handle == NULL)
+        RLOGE("[DTMF] dtmf_start return NULL!");
+    return 0;
+}
+
+//RIL_REQUEST_UDUB
+int rejectCall(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+//RIL_REQUEST_ANSWER
+int acceptCall(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    inCallstatus = CALL_ON;
+    return 0;
+}
+
+//RIL_REQUEST_HANGUP_ALL
+int hangupAll(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+//RIL_REQUEST_CONFERENCE
+int conference(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+//RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND
+int hangupWaitingOrBackground(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+//RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE
+int switchWaitingOrHoldingAndActive(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+//RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND
+int hangupForegroundResumeBackground(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+//RIL_REQUEST_EXPLICIT_CALL_TRANSFER
+int explicitCallTransfer(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+//RIL_REQUEST_ADD_IMS_CONFERENCE_CALL_MEMBER
+int addImsConferenceCallMember(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+
+    p.writeInt32(3);
+    writeStringToParcel(p, (const char *)argv[1]);//confCallId
+    writeStringToParcel(p, (const char *)argv[2]);//address
+    writeStringToParcel(p, (const char *)argv[3]);//CallIdToAdd
+
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+//RIL_REQUEST_REMOVE_IMS_CONFERENCE_CALL_MEMBER
+int removeImsConferenceCallMember(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+
+    p.writeInt32(3);
+    writeStringToParcel(p, (const char *)argv[1]);//confCallId
+    writeStringToParcel(p, (const char *)argv[2]);//address
+    writeStringToParcel(p, (const char *)argv[3]);//CallIdToRemove
+
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+//RIL_REQUEST_CONFERENCE_DIAL
+//argv[1]:DialMethod
+//argv[2]:ParticipantsNumber
+//argv[2+ParticipantsNumber]:addresss
+//argv[2+ParticipantsNumber+1]:clir
+int conferenceDial(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    int ParticipantsNumber,i;
+
+    if( argc < 3 ) {
+        free(pRI);
+        RLOGE("Error: conference Dial parameter is error!");
+        return -1;
+    }
+
+    ParticipantsNumber = atoi(argv[2]);
+
+    if( argc < (ParticipantsNumber+3) ) {
+        free(pRI);
+        RLOGE("Error: Dial With SIP URI parameter is error! \
+            argc is %d, and need parameter %d",argc,(ParticipantsNumber+3));
+        return -1;
+    }
+
+    p.writeInt32((ParticipantsNumber+3));
+    writeStringToParcel(p, (const char *)argv[1]); //DialMethod
+    writeStringToParcel(p, (const char *)argv[2]); //ParticipantsNumber
+    for( i=0; i<ParticipantsNumber; i++ ){ //address
+        writeStringToParcel(p, (const char *)argv[3+i]);
+    }
+    writeStringToParcel(p, (const char *)argv[3+ParticipantsNumber]);//clir
+
+    p.setDataPosition(pos);
+    setEcallAudioPathOn(false);
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+//RIL_REQUEST_DIAL_WITH_SIP_URI
+int dialWithSipUri(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+
+    if (argc < 3 || argv[1]==NULL) {
+        free(pRI);
+        return -1;
+    }
+
+    writeStringToParcel(p, (const char *)argv[1]);//address
+    /* for compatibility of test script, still receive clirMode and UUS,
+       but don't send them to libvendor-ril */
+#if 0
+    p.writeInt32(atoi(argv[2]));//clirMode
+    p.writeInt32(0); // UUS information is absent
+#endif
+
+    p.setDataPosition(pos);
+    setEcallAudioPathOn(false);
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+//RIL_REQUEST_HOLD_CALL
+int holdCall(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+
+    if (argc < 2 || argv[1]==NULL) {
+        free(pRI);
+        return -1;
+    }
+
+    //callIDToHold
+    p.writeInt32(1);
+    p.writeInt32(atoi(argv[1]));
+
+    p.setDataPosition(pos);
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+//RIL_REQUEST_RESUME_CALL
+int resumeCall(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+
+    if (argc < 2 || argv[1]==NULL) {
+        free(pRI);
+        return -1;
+    }
+
+    //callIDToResume
+    p.writeInt32(1);
+    p.writeInt32(atoi(argv[1]));
+
+    p.setDataPosition(pos);
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+int getCurrentCalls(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+int autoAnswerCall(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    if(argc < 2) {
+        RLOGW("[error],set auto answer call parameter error!");
+        free(pRI);
+        return 0;
+    }
+    //need add lock to pretect.
+    autoAnswerMode = atoi(argv[1]) ? 1 : 0;
+    RLOGD("SetAutoAnserMode is %s",autoAnswerMode ? "On" :"Off");
+    if(pRI) {
+        free(pRI);
+    }
+    return 0;
+}
+
+int inCallRecord(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    int recordEnable = 0;
+    char* filepath = NULL;
+    if(inCallstatus == CALL_OFF || speechStatus == SPEECH_OFF) {
+        RLOGW("[warning],not in calling status. Can't do record!");
+        return 0;
+    }
+
+    if(argc < 3) {
+        free(pRI);
+        RLOGW("[error],inCallRecord parameter error!");
+        return 0;
+    }
+
+    recordEnable = atoi(argv[1]) ? 1 : 0;
+    RLOGD("InCall record %s!",recordEnable ? "enable" : "disable");
+    filepath = argv[2];
+    RLOGD("InCall record file path as \'%s\'",filepath);
+
+   if (recordEnable == 1) {//enable record
+       RLOGD("start GSM!");
+       if(-1 != GSM_Init(filepath) && -1 != GSM_Start()) {
+            inCallRecordMode = 1;
+            RLOGW("inCallRecord Start OK!");
+       }else{
+            inCallRecordMode = 0;
+            RLOGW("[error],inCallRecord Start fail!");
+      }
+    } else { //disable record
+        if (inCallRecordMode == 1) {
+            if(!(-1 != GSM_Stop() && -1 != GSM_Close()))
+                RLOGW("[error],inCallRecord fail!");
+
+            inCallRecordMode = 0;
+        }
+    }
+
+   if(pRI != NULL) {
+       free(pRI);
+   }
+    return 0;
+}
+
+int StopRecord()
+{
+    RLOGD("After Handup, stop record! Before Record is %s",inCallRecordMode ? "Enable" : "Disable");
+    if (inCallRecordMode == 1) {
+         if(!(-1 != GSM_Stop() && -1 != GSM_Close()))
+            RLOGW("[error],inCallRecord fail!");
+
+         inCallRecordMode = 0;
+        /*From GSM report stop_record to PulseAudio send record_off  need 15ms. so after stop record delay 30ms*/
+         usleep(30*1000);
+    }
+    return 0;
+}
+
+int setSpeechVolume(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    int setValue = 0;
+    RLOGD("setSpeechVolume start!");
+
+    if(argc < 2) {
+        free(pRI);
+        RLOGW("Warning: no set volume value!");
+        return -1;
+    }
+
+    setValue = atoi(argv[1]);
+    RLOGD("set Speech Volume value is %d!",setValue);
+    if (get_audio_path() == 0) {
+        if(setValue < MIN_VOLUME || setValue > MAX_VOLUME) {
+            RLOGW("Warning: set volume value is over-range!");
+            return -1;
+        }
+    } else {
+        if(setValue < BT_MIN_VOLUME || setValue > BT_MAX_VOLUME) {
+            RLOGW("Warning: set bt volume value is over-range!");
+            return -1;
+        }
+    }
+    //paramter is from 1 to 7
+    mixer_set_volume(setValue);
+    free(pRI);
+    return 0;
+}
+int setDtmfVolume(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    int setValue = 0;
+    RLOGD("setDtmfVolume start!");
+
+    if(argc < 2) {
+        RLOGW("Warning: no set volume value!");
+        free(pRI);
+        return -1;
+    }
+
+    setValue = atoi(argv[1]);
+    RLOGD("set dtmf Volume value is %d!",setValue);
+    if(setValue < DTMF_MIN_VOLUME || setValue > DTMF_MAX_VOLUME) {
+        RLOGW("Warning: set volume value is over-range!");
+        free(pRI);
+        return -1;
+    }
+    //paramter is from 0 to 36
+    dtmf_volume = setValue;
+
+    free(pRI);
+    return 0;
+}
+
+speech_status getSpeechStatus()
+{
+    return speechStatus;
+}
+
+void setSpeechAndStatus(int value)
+{
+    RLOGD("setSpeechAndStatus value: %d, speechStatus: %d", value, speechStatus);
+    if (value == 1) {
+        speechStatus = NORMAL_SPEECH_ON;
+        mixer_set(1);
+    } else if (value == 2) {
+        speechStatus = BT_SPEECH_ON;
+        bt_mixer_set(1);
+    } else if (value == 0) {
+        speechStatus == BT_SPEECH_ON ? bt_mixer_set(0) : mixer_set(0);
+        speechStatus = SPEECH_OFF;
+    } else {
+        RLOGE("set speech value is invaild!\n");
+    }
+}
+//RIL_REQUEST_EMERGENCY_DIAL
+/*cmd:1, address,
+*2, clirMode,
+*3, if present, uusinfo.type
+*4, as above, uusinfo.Dcs
+*5, as above, uusinfo.userdatalength
+*6, as above, uusinfo.UserData
+*/
+int emergencyDial(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+  android::Parcel p;
+  size_t pos = p.dataPosition();
+
+  if (argc < 3 || argv[1] == NULL)
+  {
+    //add log msg
+    free(pRI);
+    return -1;
+  }
+  //address;
+  writeStringToParcel(p, (const char *) argv[1]);
+  //clirMode
+  if (argc >= 2)
+  {
+    p.writeInt32(atoi(argv[2]));
+
+    if (argc == 7&& argv[3] != NULL
+    && argv[4] != NULL && argv[5] != NULL
+    && argv[6] != NULL)
+    {
+      p.writeInt32(1); // UUS information is present
+      p.writeInt32(atoi(argv[3]));
+      p.writeInt32(atoi(argv[4]));
+      p.writeByteArray((size_t) atoi(argv[5]), (uint8_t*) argv[6]);
+    } else
+    {
+      p.writeInt32(0); // UUS information is absent
+    }
+  }
+  p.setDataPosition(pos);
+  setEcallAudioPathOn(false);
+  pRI->pCI->dispatchFunction(p, pRI);
+  return 0;
+}
+//RIL_REQUEST_SET_ECC_SERVICE_CATEGORY
+int setEccServiceCategory(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+  android::Parcel p;
+  size_t pos =  p.dataPosition();
+
+  //if ( getSpeechStatus() != 1)
+  //    setSpeechAndStatus(1);
+
+  p.writeInt32(1);
+  p.writeInt32(atoi(argv[1]));
+  p.setDataPosition(pos);
+  pRI->pCI->dispatchFunction(p, pRI);
+  return 0;
+}
+//RIL_REQUEST_SET_ECC_LIST
+/* argv[1]: list number
+   argv[2+i]: ECC string
+   argv[3+i]: Categroy
+   argv[4+i]: Conditon
+*/
+int setEccList(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    size_t pos =  p.dataPosition();
+    int num = 0;
+    //if ( getSpeechStatus() != 1)
+    //    setSpeechAndStatus(1);
+    if(argc < 3) {
+        RLOGE("%s parameter error!",__func__);
+        free(pRI);
+        return -1;
+    }
+    num = atoi(argv[1]);
+    RLOGD("list number is %d, argc is %d",num, argc);
+    if((num == 0) || ((argc-2) < num*3)) {
+        RLOGE("%s parameter error!",__func__);
+        free(pRI);
+        return -1;
+    }
+
+    p.writeInt32(num*3);
+    for(int i = 0; i < num; i++){
+        writeStringToParcel(p, (const char *)argv[2+i*3+0]); //ECC
+        writeStringToParcel(p, (const char *)argv[2+i*3+1]); //Category
+        writeStringToParcel(p, (const char *)argv[2+i*3+2]); //Condition
+        RLOGD("list[%d],ECC is %s, Category is %s, Condition is %s!",i+1,argv[2+i*3+0],argv[2+i*3+1],argv[2+i*3+2]);
+    }
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+//RIL_REQUEST_SET_ECC_NUM
+int setEccNum(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    size_t pos =  p.dataPosition();
+    int num = 0;
+
+    if(argc < 2 || argc > 3) {
+        RLOGE("%s parameter error!",__func__);
+        free(pRI);
+        return -1;
+    }
+
+    num = (argc > 2)?2:1;
+
+    p.writeInt32(num);
+    writeStringToParcel(p, (const char *)argv[1]); //ECC number with card
+    RLOGD("Set ECC number with card: %s",argv[1]);
+    if (num>1){
+        writeStringToParcel(p, (const char *)argv[2]); //ECC number without card
+        RLOGD("Set ECC number without card: %s",argv[2]);
+    }
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+//RIL_REQUEST_GET_ECC_NUM
+int getEccNum(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+int handleECCNumResponse(const void *data, int datalen, RIL_SOCKET_ID socket_id){
+    if (data == NULL || datalen <= 0){
+        RLOGE("%s parameter error!",__func__);
+        return -1;
+    }
+
+    printf("[ECC NUM][Slot%d] %s\n", socket_id, (const char*)data);
+    RLOGD("[ECC NUM][Slot%d] %s\n", socket_id, (const char*)data);
+    return 0;
+}
+
+
+//RIL_REQUEST_LAST_CALL_FAIL_CAUSE
+int getLastCallFailCause(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if(argc != 1)
+    {
+        RLOGD("the peremeters numbers isn't right , so return");
+        free(pRI);
+        return -1;
+    }
+    RLOGD("getLastCallFailCause %d: " , pRI->pCI->requestNumber);
+    android::Parcel p;
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+#ifdef C2K_SUPPORT
+static bool is12Key(char c) {
+  return (c >= '0' && c <= '9') || c == '*' || c == '#';
+}
+
+//RIL_REQUEST_CDMA_BURST_DTMF
+int sendBurstDtmf(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI){
+  if(argc < 4) {
+      RLOGE("%s parameter error!",__func__);
+      free(pRI);
+      return -1;
+  }
+  int number;
+  char * c_num = NULL;
+
+  c_num = argv[1];
+  if (c_num == NULL) {
+      free(pRI);
+      return -1;
+  }
+  number = int(c_num[0] - '0');
+  if(number == -6)
+     number = 10;
+  if(number == -13)
+     number = 11;
+  RLOGD("DTMF input number is %s-->%d",c_num,number);
+  if ( number < 0 || number > 15 ) {
+      RLOGE("DTMF input number error");
+      free(pRI);
+      return -1;
+  }
+  dtmf_stop(dtmf_handle);
+  dtmf_handle = dtmf_start(number, 500, dtmf_volume, NULL);
+  android::Parcel p;
+  size_t pos =  p.dataPosition();
+  p.writeInt32(3);
+  writeStringToParcel(p, c_num);
+  writeStringToParcel(p, argv[2]);
+  writeStringToParcel(p, argv[3]);
+  p.setDataPosition(pos);
+  pRI->pCI->dispatchFunction(p, pRI);
+  if (dtmf_handle == NULL)
+      RLOGE("[DTMF] dtmf_start return NULL!");
+  return 0;
+}
+
+//RIL_REQUEST_CDMA_FLASH
+int sendCDMAFeatureCode(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI){
+    if(argc > 2)
+    {
+        RLOGD("the peremeters numbers isn't right , so return");
+        free(pRI);
+        return -1;
+    }
+    android::Parcel p;
+    size_t pos =  p.dataPosition();
+    writeStringToParcel(p, ((argc == 1) ? "" : argv[1]));
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+#endif /*C2K_SUPPORT*/
+
+static int mixer_set_mute(int path, int value)
+{
+    RLOGD("mixer_set_mute path: %d , value: %d", path, value);
+    int ret;
+    /* DL:0 UL:1 */
+    if (path == 0) {
+        ret = set_mixer_ctrl_value_int(g_DL_mute_name, value);
+    } else {
+        ret = set_mixer_ctrl_value_int(g_UL_mute_name, value);
+    }
+    if (ret) {
+        RLOGE("set_mixer_ctrl_volume_value_int err: %d", ret);
+    }
+    return ret;
+}
+
+static long int mixer_get_mute(int path)
+{
+    long int is_mute;
+
+    /* 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);
+    } 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);
+    }
+
+    return is_mute;
+}
+
+int setCallMute(bool mute) {
+    RLOGD("setCallMute: %d", mute);
+    return mixer_set_mute(1, (mute ? 1: 0));
+}
+
+int getCallMute() {
+    long int cc_mute = mixer_get_mute(1);
+    RLOGD("getCallMute: %d", cc_mute);
+    return cc_mute;
+}
+
+void resetMute() {
+    if (getCallMute() > 0) {
+        setCallMute(false);
+    }
+}
+
+void callRing(RIL_SOCKET_ID soc_id)
+{
+    resetMute();
+    if (autoAnswerMode) {
+        RLOGD("Auto Answer MT Call!");
+        android::requestAnswer(soc_id);
+    }
+    return;
+}
+
+void autoAnswerForCdma(RIL_SOCKET_ID socket_id)
+{
+    resetMute();
+    if (autoAnswerMode) {
+        RLOGD("Auto Answer MT Call for cdma");
+        ARspRequest(RIL_REQUEST_CDMA_FLASH, socket_id);
+    }
+    return;
+}
+
+//void callStateChange(void)
+void speechonoff(int callnum)
+{
+    static int callIndex = 0;
+    RLOGD("callnum = %d, Call State Change then judge speech on/off!", callnum);
+    callIndex = callnum;
+    if( callIndex == 1 && speechStatus == SPEECH_OFF) {  //speech on
+        //RLOGD("DemoAPP Call shell command (pactl set-card-profile 0 phonecall)");
+        //system("pactl set-card-profile 0 phonecall");
+        //RLOGD("DemoAPP Call shell command end");
+        if (get_audio_path() == 0) {
+            mixer_set(1);
+            speechStatus = NORMAL_SPEECH_ON;
+        } else {
+            bt_mixer_set(1);
+            speechStatus = BT_SPEECH_ON;
+        }
+        inCallstatus = CALL_ON;
+        RLOGD("[speech]: set on");
+        sendCallMsg(true); //for Power Manager test
+    } else if (callIndex == 0
+               && (speechStatus == NORMAL_SPEECH_ON
+                   || speechStatus == BT_SPEECH_ON)) { //speech off
+        StopRecord();
+        sendCallMsg(false); // for Power Manager test.
+        dtmf_stop(dtmf_handle);
+        if (speechStatus == NORMAL_SPEECH_ON) {
+            mixer_set(0);
+        } else {
+            bt_mixer_set(0);
+        }
+        //RLOGD("DemoAPP Call shell command (pactl set-card-profile 0 HiFi)");
+        //system("pactl set-card-profile 0 HiFi");
+        //RLOGD("DemoAPP Call(pactl set-card-profile 0 HiFi) command end");
+        speechStatus = SPEECH_OFF;
+        inCallstatus = CALL_OFF;
+        resetMute();
+        RLOGD("[speech]: set off");
+    } else {
+        RLOGD("callIndex is %d, speechStatus is %d.",callIndex, speechStatus);
+    }
+
+    return;
+}
+
+//RIL_REQUEST_SET_MUTE
+int setMute(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    if(pRI) {
+        free(pRI);
+    }
+    bool mute = (atoi(argv[1]) > 0) ? true: false;
+    RLOGD("set mute %s", ((atoi(argv[1]) > 0) ? "on": "off"));
+    int ret = setCallMute(mute);
+    std::string str;
+    if(ret) {
+        str.append("set mute fail, please try agian\n");
+    } else {
+        str.append("set mute ");
+        str.append((atoi(argv[1]) > 0) ? "on ": "off ");
+        str.append("success\n");
+    }
+    android::emResultNotify(str.c_str());
+    return 0;
+}
+
+//RIL_REQUEST_GET_MUTE
+int getMute(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    if(pRI) {
+        free(pRI);
+    }
+    std::string str;
+    int mute = getCallMute();
+    //TBC -200 fail status
+    if(mute == -200) {
+        str.append("get mute state fail, please check whether does call exsit. \n");
+    } else {
+        str.append("current mute state is ");
+        str.append((mute == 1) ? "on\n" : "off\n");
+    }
+    android::emResultNotify(str.c_str());
+    return 0;
+}
+
+//RIL_UNSOL_SIP_CALL_PROGRESS_INDICATOR
+int handleUnsolSipCallProgressInd(const void *response, size_t responselen) {
+    if (response == NULL && responselen != 0) {
+        RLOGE("handleUnsolSipCallProgressInd: invalid response: NULL");
+        return -1;
+    }
+    if (responselen % sizeof(char *) != 0) {
+        RLOGE("handleUnsolSipCallProgressInd: invalid response length %d expected multiple of %d\n",
+            (int)responselen, (int)sizeof(char *));
+        return -1;
+    }
+
+    int numStrings = responselen / sizeof(char *);
+    RLOGD("handleUnsolSipCallProgressInd: numStrings: %d", numStrings);
+    if(numStrings < 6) {
+        RLOGE("handleUnsolSipCallProgressInd: invalid response numbers: NULL");
+        return -1;
+    }
+    char **p_cur = (char **) response;
+    //<call_id>,<dir>,<SIP_msg_type>,<method>,<response_code>,"<reason_text>"
+    //if response == <id>, 1, 0, 4, 0, "call completed elsewhere" ,printf "SIP CANCEL:Call completed elsewhere"
+    //if response == <id>, 1, 0, 4, 0, " declined" ,printf "SIP CANCEL:declined"
+    std::string call_id(p_cur[0]);
+    std::string dir(p_cur[1]);
+    std::string sip_msg_type(p_cur[2]);
+    std::string method(p_cur[3]);
+    std::string resp_code(p_cur[4]);
+    std::string reason_text(p_cur[5]);
+    RLOGD("%s, call_id=%s, dir=%s, sip_msg_type=%s, method=%s, resp_code=%s, reason_text=%s",
+            __FUNCTION__, call_id.c_str(),dir.c_str(),sip_msg_type.c_str(),method.c_str(),resp_code.c_str(), reason_text.c_str());
+    printf("call_id=%s, dir=%s, sip_msg_type=%s, method=%s, resp_code=%s, reason_text=%s\n",
+            call_id.c_str(),dir.c_str(),sip_msg_type.c_str(),method.c_str(),resp_code.c_str(), reason_text.c_str());
+
+    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:");
+        msg.append(reason_text);
+        printf("%s", msg.c_str());
+    }
+    return 0;
+}
+
+//RIL_UNSOL_CALL_INFO_INDICATION
+int handleUnsolCallInfoInd(const void *response, size_t responselen, RIL_SOCKET_ID socket_id) {
+    int numStrings = 0;
+
+    if (response == NULL && responselen != 0) {
+        RLOGE("[slot%d]handleUnsolCallInfoInd, invalid response: NULL", socket_id);
+        return -1;
+    }
+    if (responselen % sizeof(char *) != 0) {
+        RLOGE("[slot%d]handleUnsolCallInfoInd: invalid response length %d expected multiple of %d\n",socket_id,
+            (int)responselen, (int)sizeof(char *));
+        return -1;
+    }
+
+    if (response == NULL) {
+        RLOGE("[slot%d]handleUnsolCallInfoInd, length and invalid response : NULL", socket_id);
+    } else {
+        char **p_cur = (char **) response;
+
+        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);
+            return -1;
+        } else {
+            RLOGD("[slot%d]handleUnsolCallInfoInd(): pau: %s", socket_id, p_cur[8]);
+            printf("[slot%d]handleUnsolCallInfoInd(): pau: %s\n", socket_id, p_cur[8]);
+        }
+    }
+    return 0;
+}
+
+static void playtone(int start) {
+    RLOGD("playtone(): start: %d, isRingStart %d", start, isRingStart);
+    char cmd[256];
+    sprintf(cmd, "aplay %s", RING_PATH);
+    system(cmd);
+    isRingStart = false;
+}
+
+//RIL_UNSOL_RINGBACK_TONE
+int handleRingbackTone(const void *response, size_t responselen, RIL_SOCKET_ID socket_id) {
+
+    int numInts = 0;
+
+    if (response == NULL && responselen != 0) {
+        RLOGE("[slot%d]handleRingbackTone, invalid response: NULL", socket_id);
+        return -1;
+    }
+    if (responselen % sizeof(int) != 0) {
+        RLOGE("[slot%d]handleRingbackTone: invalid response length %d expected multiple of %d\n",socket_id,
+            (int)responselen, (int)sizeof(char *));
+        return -1;
+    }
+
+    int *p_int = (int *) response;
+
+    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);
+        return -1;
+    } else {
+        int start = p_int[0];
+        RLOGD("[slot%d]handleRingbackTone(): start: %d, isRingStart %d", socket_id, start, isRingStart);
+        printf("[slot%d]handleRingbackTone(): start: %d, isRingStart %d\n", socket_id, start, isRingStart);
+#if defined(TARGET_PLATFORM_MT2731)
+        if(start && (!isRingStart)) {
+            isRingStart = true;
+            std::thread t(playtone, start);
+            t.detach();
+        } else if((!start) && isRingStart) {
+            isRingStart = false;
+            system("kill $(ps aux | grep '[a]play' | awk '{print $2}')");
+        }
+#endif
+    }
+    return 0;
+}
+
+//RIL_REQUEST_DTMF_STOP
+int stopDtmf(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+
+    dtmf_stop(dtmf_handle);
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/cc.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/cc.h
new file mode 100644
index 0000000..7625368
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/cc.h
@@ -0,0 +1,120 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#ifndef __RIL_CC__
+#define __RIL_CC__
+#include  <vendor-ril/telephony/ril.h>
+#include  "common.h"
+typedef enum {
+    SPEECH_OFF = 0,
+    NORMAL_SPEECH_ON,
+    BT_SPEECH_ON,
+} speech_status;
+
+typedef enum {
+    CALL_OFF = 0,
+    CALL_ON,
+} call_status;
+
+//extern int callIndex;
+int getCallMute();
+int setCallMute(bool mute);
+
+int dial(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setAudioPath(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+speech_status getSpeechStatus();
+void setSpeechAndStatus(int value);
+int forceReleaseCall(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int hangupAll(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int hangupConnection(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+//int invokeOemRilRequestStrings(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int separateConnection(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int rejectCall(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int acceptCall(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int conference(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int hangupWaitingOrBackground(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int switchWaitingOrHoldingAndActive(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int hangupForegroundResumeBackground(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int explicitCallTransfer(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int sendDtmf(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int getMute(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setMute(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int getCurrentCalls(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int autoAnswerCall(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int inCallRecord(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int addImsConferenceCallMember(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int removeImsConferenceCallMember(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int conferenceDial(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int dialWithSipUri(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int holdCall(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int resumeCall(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+//  modem reset
+int mixer_reset_set(int value);
+#if 0
+int setSpeechOn(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setSpeechOff(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+#endif
+int get_call_status(void);
+void set_audio_path(int path);
+int get_audio_path(void);
+void set_bt_has_ecnr(int ecnr);
+int get_bt_has_ecnr(void);
+void set_bt_wbs(int wbs);
+int get_bt_wbs(void);
+int setSpeechVolume(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setDtmfVolume(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+//void callStateChange(void);
+void speechonoff(int callnum);
+void callRing(RIL_SOCKET_ID soc_id);
+int handleUnsolSipCallProgressInd(const void *response, size_t responselen);
+int emergencyDial(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setEccServiceCategory(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setEccList(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int getLastCallFailCause(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setEccNum(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int getEccNum(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int handleECCNumResponse(const void *data, int datalen, RIL_SOCKET_ID socket_id);
+int handleUnsolCallInfoInd(const void *response, size_t responselen, RIL_SOCKET_ID socket_id);
+int handleRingbackTone(const void *response, size_t responselen, RIL_SOCKET_ID socket_id);
+int stopDtmf(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+
+int mixer_init();
+
+#ifdef C2K_SUPPORT
+int sendBurstDtmf(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int sendCDMAFeatureCode(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+void autoAnswerForCdma(RIL_SOCKET_ID socket_id);
+void resetMute();
+#endif /*C2K_SUPPORT*/
+#endif
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/commands.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/commands.h
new file mode 100644
index 0000000..e5fc836
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/commands.h
@@ -0,0 +1,255 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+//SIM
+    {"RIL_REQUEST_GET_IMSI",getIMSIForApp, "get imsi", RIL_REQUEST_GET_IMSI},
+    {"RIL_REQUEST_GET_SIM_STATUS",getIccCardStatus, "get sim status", RIL_REQUEST_GET_SIM_STATUS},
+    {"RIL_REQUEST_ENTER_SIM_PIN",supplyIccPinForApp, "enter sim pin", RIL_REQUEST_ENTER_SIM_PIN},
+    {"RIL_REQUEST_CHANGE_SIM_PIN",changeIccPinForApp, "change sim pin", RIL_REQUEST_CHANGE_SIM_PIN},
+    {"RIL_REQUEST_ENTER_SIM_PUK",supplyIccPukForApp, "enter puk & pin", RIL_REQUEST_ENTER_SIM_PUK},
+    {"RIL_REQUEST_QUERY_ICCID", queryIccidForApp,"get iccid", RIL_REQUEST_QUERY_ICCID},
+    {"RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC", iccTransmitApduBasicChannel, "",RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC},
+    {"RIL_REQUEST_SIM_OPEN_CHANNEL", iccOpenLogicalChannel, "", RIL_REQUEST_SIM_OPEN_CHANNEL},
+    {"RIL_REQUEST_SIM_CLOSE_CHANNEL", iccCloseLogicalChannel, "", RIL_REQUEST_SIM_CLOSE_CHANNEL},
+    {"RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL", iccTransmitApduLogicalChannel, "", RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL},
+    {"RIL_REQUEST_SIM_IO", iccIOForApp, "", RIL_REQUEST_SIM_IO},
+    {"RIL_REQUEST_QUERY_EID", queryEid, "query Eid", RIL_REQUEST_QUERY_EID},
+#ifdef TARGET_PLATFORM_MT2731
+    {"RIL_REQUEST_QUERY_SIM_RETRY_COUNT", querySimRetryCount, "", RIL_REQUEST_QUERY_SIM_RETRY_COUNT},
+#endif
+//Data
+    {"RIL_REQUEST_ALLOW_DATA",setDataAllowed, "allow data", RIL_REQUEST_ALLOW_DATA},
+    {"RIL_REQUEST_SETUP_DATA_CALL",setupDataCall, "set up data", RIL_REQUEST_SETUP_DATA_CALL},
+    {"RIL_REQUEST_DEACTIVATE_DATA_CALL",deactivateDataCall, "deactive data call", RIL_REQUEST_DEACTIVATE_DATA_CALL},
+    {"RIL_REQUEST_SET_INITIAL_ATTACH_APN",setInitialAttachApnargc, "intial attach apn", RIL_REQUEST_SET_INITIAL_ATTACH_APN},
+    {"RIL_REQUEST_DATA_CALL_LIST",getDataCallList,"get data call list",RIL_REQUEST_DATA_CALL_LIST},
+    {"RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE",getLastDataCallFailCause, "last data fail cause" ,RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE},
+    {"RIL_REQUEST_SET_DATA_PROFILE",setDataProfile, "set data profile", RIL_REQUEST_SET_DATA_PROFILE},
+    {"RIL_REQUEST_SYNC_DATA_SETTINGS_TO_MD",syncDataSettingsToMd, "sync data settings to modem", RIL_REQUEST_SYNC_DATA_SETTINGS_TO_MD},
+#ifdef TARGET_PLATFORM_MT2731
+    {"RIL_REQUEST_MODIFY_APN",modifyApnRecord, "modify apn db", RIL_REQUEST_MODIFY_APN},
+    {"RIL_REQUEST_RESET_APN",resetApnRecord, "reset apn db", RIL_REQUEST_RESET_APN},
+#endif
+//CC
+    {"RIL_REQUEST_DIAL",dial,"dial",RIL_REQUEST_DIAL},
+    {"RIL_REQUEST_HANGUP",hangupConnection,"hangup",RIL_REQUEST_HANGUP},
+    {"RIL_REQUEST_SEPARATE_CONNECTION",separateConnection,"separate",RIL_REQUEST_SEPARATE_CONNECTION},
+    {"RIL_REQUEST_UDUB",rejectCall,"reject call",RIL_REQUEST_UDUB},
+    {"RIL_REQUEST_ANSWER",acceptCall,"accept call",RIL_REQUEST_ANSWER},
+    {"RIL_REQUEST_CONFERENCE",conference,"conference",RIL_REQUEST_CONFERENCE},
+    {"RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND",hangupWaitingOrBackground,"hangup Waiting or Background",RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND},
+    {"RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE",switchWaitingOrHoldingAndActive,"switch Waiting Or Holding And Active",RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE},
+    {"RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND",hangupForegroundResumeBackground,"hangup Foreground Resume Background",RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND},
+    {"RIL_REQUEST_EXPLICIT_CALL_TRANSFER",explicitCallTransfer,"explicit Call Transfer",RIL_REQUEST_EXPLICIT_CALL_TRANSFER},
+    {"RIL_REQUEST_DTMF",sendDtmf,"send Dtmf",RIL_REQUEST_DTMF},
+    {"RIL_REQUEST_GET_MUTE",getMute,"get Mute",RIL_REQUEST_GET_MUTE},
+    {"RIL_REQUEST_SET_MUTE",setMute,"set Mute",RIL_REQUEST_SET_MUTE},
+    {"RIL_REQUEST_LAST_CALL_FAIL_CAUSE",getLastCallFailCause, "get last call fail cause", RIL_REQUEST_LAST_CALL_FAIL_CAUSE},
+    {"RIL_REQUEST_GET_CURRENT_CALLS",getCurrentCalls,"get Current Calls",RIL_REQUEST_GET_CURRENT_CALLS},
+    {"RIL_REQUEST_AUTO_ANSWER",autoAnswerCall,"auto answer call",-1},
+    {"RIL_REQUEST_RECORD",inCallRecord,"InCall record",-1},
+
+    #ifdef C2K_SUPPORT
+    {"RIL_REQUEST_CDMA_BURST_DTMF",sendBurstDtmf,"cdma burst dtmf",RIL_REQUEST_CDMA_BURST_DTMF},
+    {"RIL_REQUEST_CDMA_FLASH",sendCDMAFeatureCode,"InCall record",RIL_REQUEST_CDMA_FLASH},
+    #endif /*C2K_SUPPORT*/
+
+    #if 0
+    {"RIL_REQUEST_SET_SPEECH_ON",setSpeechOn,"set Speech On",-1},
+    {"RIL_REQUEST_SET_SPEECH_OFF",setSpeechOff,"set Speech Off",-1},
+    #endif
+    {"RIL_REQUEST_SET_SPEECH_VOLUME",setSpeechVolume,"set Speech Volume",-1},
+    {"RIL_REQUEST_SET_DTMF_VOLUME",setDtmfVolume,"set dtmf Volume",-1},
+//    {"RIL_REQUEST_OEM_HOOK_STRINGS",invokeOemRilRequestStrings,"invoke Oem Ril Request Strings",RIL_REQUEST_OEM_HOOK_STRINGS},
+    {"RIL_REQUEST_ADD_IMS_CONFERENCE_CALL_MEMBER",addImsConferenceCallMember,"add Ims Conference Call Member",RIL_REQUEST_ADD_IMS_CONFERENCE_CALL_MEMBER},
+    {"RIL_REQUEST_REMOVE_IMS_CONFERENCE_CALL_MEMBER",removeImsConferenceCallMember,"remove Ims Conference Call Member",RIL_REQUEST_REMOVE_IMS_CONFERENCE_CALL_MEMBER},
+    {"RIL_REQUEST_CONFERENCE_DIAL",conferenceDial,"conference Dial",RIL_REQUEST_CONFERENCE_DIAL},
+    {"RIL_REQUEST_DIAL_WITH_SIP_URI",dialWithSipUri,"dial With Sip Uri",RIL_REQUEST_DIAL_WITH_SIP_URI},
+    {"RIL_REQUEST_HOLD_CALL",holdCall,"hold Call",RIL_REQUEST_HOLD_CALL},
+    {"RIL_REQUEST_RESUME_CALL",resumeCall,"resume Call",RIL_REQUEST_RESUME_CALL},
+    {"RIL_REQUEST_HANGUP_ALL",hangupAll,"hangup all",RIL_REQUEST_HANGUP_ALL},
+    {"RIL_REQUEST_FORCE_RELEASE_CALL",forceReleaseCall,"force release call",RIL_REQUEST_FORCE_RELEASE_CALL},
+    {"RIL_REQUEST_EMERGENCY_DIAL", emergencyDial,"emergency Dial",RIL_REQUEST_EMERGENCY_DIAL},
+    {"RIL_REQUEST_SET_ECC_SERVICE_CATEGORY", setEccServiceCategory,"set Ecc Service Category",RIL_REQUEST_SET_ECC_SERVICE_CATEGORY},
+    {"RIL_REQUEST_SET_ECC_LIST", setEccList,"set Ecc List",RIL_REQUEST_SET_ECC_LIST},
+    {"RIL_REQUEST_SET_ECC_NUM", setEccNum,"set Ecc Number",RIL_REQUEST_SET_ECC_NUM},
+    {"RIL_REQUEST_GET_ECC_NUM", getEccNum,"get Ecc Number",RIL_REQUEST_GET_ECC_NUM},
+    {"RIL_REQUEST_DTMF_START", sendDtmf,"start dtmf",RIL_REQUEST_DTMF_START},
+    {"RIL_REQUEST_DTMF_STOP", stopDtmf,"stop dtmf",RIL_REQUEST_DTMF_STOP},
+//stateManager
+    {"RIL_REQUEST_DEVICE_IDENTITY",getDeviceIdentity,"get Device Identity",RIL_REQUEST_DEVICE_IDENTITY},
+    {"RIL_REQUEST_GET_IMEI",getIMEI,"get IMEI",RIL_REQUEST_GET_IMEI},
+    {"RIL_REQUEST_GET_IMEISV",getIMEISV,"get IMEISV",RIL_REQUEST_GET_IMEISV},
+    {"RIL_REQUEST_BASEBAND_VERSION",getBasebandVersion,"get Baseband Version",RIL_REQUEST_BASEBAND_VERSION},
+    {"RIL_REQUEST_RESET_RADIO",resetRadio,"reset Radio",RIL_REQUEST_RESET_RADIO},
+    {"RIL_REQUEST_SCREEN_STATE",getScreenState,"get Screen State",RIL_REQUEST_SCREEN_STATE},
+    {"RIL_REQUEST_SET_TRM",setTRM,"set TRM",RIL_REQUEST_SET_TRM},
+    {"RIL_REQUEST_SET_IMS_ENABLE",setIMSEnable,"set IMS enable",RIL_REQUEST_SET_IMS_ENABLE},
+    {"RIL_REQUEST_SET_IMSCFG",setIMSCfg,"set IMS config",RIL_REQUEST_SET_IMSCFG},
+    {"RIL_REQUEST_OEM_HOOK_RAW",sendATCMD,"send AT CMD",RIL_REQUEST_OEM_HOOK_RAW},
+#ifdef KEEP_ALIVE
+    {"RIL_REQUEST_START_KEEPALIVE_PRO",startKeepAlivePro,"start keep alive pro",RIL_REQUEST_START_KEEPALIVE_PRO},
+    {"RIL_REQUEST_STOP_KEEPALIVE_PRO",stopKeepAlivePro,"stop keep alive pro",RIL_REQUEST_STOP_KEEPALIVE_PRO},
+#endif /*KEEP_ALIVE*/
+//network
+    {"RIL_REQUEST_SIGNAL_STRENGTH", getSignalStrength, "getSignalStrength", RIL_REQUEST_SIGNAL_STRENGTH},
+    {"RIL_REQUEST_OPERATOR", getOperator, "getOperator", RIL_REQUEST_OPERATOR},
+    {"RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE",  getNetworkSelectionMode, "getNetworkSelectionMode", RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE},
+    {"RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC", setNetworkSelectionModeAutomatic, "setNetworkSelectionModeAutomatic", RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC},
+    {"RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL",setNetworkSelectionModeManual, "setNetworkSelectionModeManual", RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL},
+    {"RIL_REQUEST_QUERY_AVAILABLE_NETWORKS", getAvailableNetworks, "getAvailableNetworks", RIL_REQUEST_QUERY_AVAILABLE_NETWORKS},
+    {"RIL_REQUEST_VOICE_REGISTRATION_STATE", getVoiceRegistrationState, "getVoiceRegistrationState", RIL_REQUEST_VOICE_REGISTRATION_STATE},
+    {"RIL_REQUEST_DATA_REGISTRATION_STATE", getDataRegistrationState, "getDataRegistrationState", RIL_REQUEST_DATA_REGISTRATION_STATE},
+    {"RIL_REQUEST_IMS_REGISTRATION_STATE", getImsRegistrationState, "getImsRegistrationState", RIL_REQUEST_IMS_REGISTRATION_STATE},
+    {"RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE", getPreferredNetworkType, "getPreferredNetworkType", RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE},
+    {"RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE", setPreferredNetworkType, "setPreferredNetworkType", RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE},
+    {"RIL_REQUEST_SET_LOCATION_UPDATES", setLocationUpdates, "setLocationUpdates", RIL_REQUEST_SET_LOCATION_UPDATES},
+    {"RIL_REQUEST_GET_CELL_INFO_LIST", getCellInfoList, "getCellInfoList",  RIL_REQUEST_GET_CELL_INFO_LIST},
+    {"RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE", setCellInfoListRate, "setCellInfoListRate", RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE},
+    {"RIL_REQUEST_GET_NEIGHBORING_CELL_IDS", getNeighboringCids, "getNeighboringCids", RIL_REQUEST_GET_NEIGHBORING_CELL_IDS},
+    {"RIL_REQUEST_SET_BAND_MODE", setBandMode, "set Band Mode", RIL_REQUEST_SET_BAND_MODE},
+    {"RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE", queryAvailableBandMode, "queryAvailableBandMode", RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE},
+    {"RIL_REQUEST_RADIO_POWER", setRadioPower, "setRadioPower", RIL_REQUEST_RADIO_POWER},
+    {"RIL_REQUEST_VOICE_RADIO_TECH", getVoiceRadioTechnology, "getVoiceRadioTechnology", RIL_REQUEST_VOICE_RADIO_TECH},
+    {"RIL_REQUEST_SET_RADIO_CAPABILITY", setRadioCapability, "set Radio Capability", RIL_REQUEST_SET_RADIO_CAPABILITY},
+    {"RIL_REQUEST_GET_RADIO_CAPABILITY", getRadioCapability, "get Radio Capability", RIL_REQUEST_GET_RADIO_CAPABILITY},
+    {"RIL_REQUEST_MODEM_POWEROFF", setModemPowerOFF, "MODEM OFF", RIL_REQUEST_MODEM_POWEROFF},
+    {"RIL_REQUEST_MODEM_POWERON", setModemPowerON, "MODEM ON", RIL_REQUEST_MODEM_POWERON},
+    {"RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION", supplyNetworkDepersonalization, "",RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION},
+    {"RIL_REQUEST_REPORT_AIRPLANE_MODE", setReportAirplaneMode, "",RIL_REQUEST_REPORT_AIRPLANE_MODE},
+    {"RIL_REQUEST_QUERY_AVAILABLE_NETWORKS_WITH_ACT", getAvailableNetworksWithAct, "",RIL_REQUEST_QUERY_AVAILABLE_NETWORKS_WITH_ACT},
+    //ss
+    {"RIL_REQUEST_SEND_USSD",sendUSSD,"send USSD",RIL_REQUEST_SEND_USSD},
+    {"RIL_REQUEST_CANCEL_USSD",cancelPendingUssd,"cancel pending USSD",RIL_REQUEST_CANCEL_USSD},
+    {"RIL_REQUEST_SEND_USSI",sendUSSI,"send USSI",RIL_REQUEST_SEND_USSI},
+    {"RIL_REQUEST_CANCEL_USSI",cancelPendingUssi,"cancel pending USSI",RIL_REQUEST_CANCEL_USSI},
+    //{"RIL_UNSOL_ON_USSD",cancelPendingUssd,"cancel pending USSD",RIL_REQUEST_CANCEL_USSD},
+    {"RIL_REQUEST_GET_CLIR",getCLIR,"get CLIR",RIL_REQUEST_GET_CLIR},
+    {"RIL_REQUEST_SET_CLIR",setCLIR,"set CLIR",RIL_REQUEST_SET_CLIR},
+    {"RIL_REQUEST_QUERY_CLIP",queryCLIP,"query CLIP",RIL_REQUEST_QUERY_CLIP},
+    {"RIL_REQUEST_QUERY_CALL_FORWARD_STATUS",queryCallForwardStatus,"query call forward status",RIL_REQUEST_QUERY_CALL_FORWARD_STATUS},
+    {"RIL_REQUEST_SET_CALL_FORWARD",setCallForward,"set call forward",RIL_REQUEST_SET_CALL_FORWARD},
+    {"RIL_REQUEST_QUERY_CALL_WAITING",queryCallWaiting,"query call waiting",RIL_REQUEST_QUERY_CALL_WAITING},
+    {"RIL_REQUEST_SET_CALL_WAITING",setCallWaiting,"set call waiting",RIL_REQUEST_SET_CALL_WAITING},
+    {"RIL_REQUEST_CHANGE_BARRING_PASSWORD",changeBarringPassword,"change barring password",RIL_REQUEST_CHANGE_BARRING_PASSWORD},
+    {"RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION",setSuppServiceNotifications,"set supp service notifications",RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION},
+    {"RIL_REQUEST_SET_CLIP",setCLIP,"get clip", RIL_REQUEST_SET_CLIP},
+    {"RIL_REQUEST_GET_COLP",getCOLP,"get colp", RIL_REQUEST_GET_COLP},
+    {"RIL_REQUEST_SET_COLP",setCOLP,"set colp", RIL_REQUEST_SET_COLP},
+    {"RIL_REQUEST_GET_COLR",getCOLR,"get colr", RIL_REQUEST_GET_COLR},
+    {"RIL_REQUEST_QUERY_FACILITY_LOCK",queryFacilityLockForApp, "query sim lock", RIL_REQUEST_QUERY_FACILITY_LOCK},
+    {"RIL_REQUEST_SET_FACILITY_LOCK",setFacilityLockForApp, "set sim lock", RIL_REQUEST_SET_FACILITY_LOCK},
+    //{"RIL_UNSOL_SUPP_SVC_NOTIFICATION",xx,"cancel pending USSD",RIL_UNSOL_SUPP_SVC_NOTIFICATION},
+//stk
+    {"RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND",sendEnvelope,"send Envelope",RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND},
+    {"RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE",sendTerminalResponse,"send Terminal Response",RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE},
+    {"RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS",sendEnvelopeWithStatus,"send Envelope With Status",RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS},
+    {"RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM",handleCallSetupRequestFromSim,"handle Call Setup Request From Sim",RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM},
+    {"RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING",reportStkServiceIsRunning,"report Stk Service Is Running",RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING},
+//sms
+    {"RIL_REQUEST_SEND_SMS",sendSMS,"send SMS",RIL_REQUEST_SEND_SMS},
+    {"RIL_REQUEST_SEND_SMS_EXPECT_MORE",sendSMSExpectMore,"send SMS expect more",RIL_REQUEST_SEND_SMS_EXPECT_MORE},
+    {"RIL_REQUEST_IMS_SEND_SMS",sendImsGsmSms,"send ims gsm sms",RIL_REQUEST_IMS_SEND_SMS},
+    {"RIL_REQUEST_IMS_SEND_SMS_CDMA",sendImsCdmaSms,"send ims gsm sms",RIL_REQUEST_IMS_SEND_SMS},
+    {"RIL_REQUEST_WRITE_SMS_TO_SIM",writeSmsToSim,"write sms to sim",RIL_REQUEST_WRITE_SMS_TO_SIM},
+    {"RIL_REQUEST_DELETE_SMS_ON_SIM",deleteSmsOnSim,"delete sms on sim",RIL_REQUEST_DELETE_SMS_ON_SIM},
+    {"RIL_REQUEST_SMS_ACKNOWLEDGE",acknowledgeLastIncomingGsmSms,"acknowledge last incoming gsm sms",RIL_REQUEST_SMS_ACKNOWLEDGE},
+    {"RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU",acknowledgeIncomingGsmSmsWithPdu,"acknowledge incoming gsm sms with pdu",RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU},
+    {"RIL_REQUEST_REPORT_SMS_MEMORY_STATUS",reportSmsMemoryStatus,"report sms memory status",RIL_REQUEST_REPORT_SMS_MEMORY_STATUS},
+    {"RIL_REQUEST_SET_SMSC_ADDRESS",setSmscAddress,"set smss address",RIL_REQUEST_SET_SMSC_ADDRESS},
+    {"RIL_REQUEST_GET_SMSC_ADDRESS",getSmscAddress,"get smss address",RIL_REQUEST_GET_SMSC_ADDRESS},
+    {"RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG",getGsmBroadcastConfig, "get broadcast config",RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG},
+    {"RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG",setGsmBroadcastConfig,"set gsm broadcast sms config",RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG},
+    {"RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION",setGsmBroadcastActivation,"gsm sms broadcast activation",RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION},
+    {"RIL_REQUEST_GET_SMS_SIM_MEM_STATUS",getSmsSimMemStatus,"get sms sim mem status",RIL_REQUEST_GET_SMS_SIM_MEM_STATUS},	
+    {"RIL_REQUEST_AUTO_SAVE_SMS_TO_SIM",setAutoSaveSmsToSimFlag,"auto save sms to sim",-1},
+    {"RIL_REQUEST_GSM_GET_BROADCAST_LANGUAGE",getGsmBroadcastLanguage, "get broadcast language config",RIL_REQUEST_GSM_GET_BROADCAST_LANGUAGE},
+    {"RIL_REQUEST_GSM_SET_BROADCAST_LANGUAGE",setGsmBroadcastLanguage, "set broadcast language config",RIL_REQUEST_GSM_SET_BROADCAST_LANGUAGE},
+
+    #ifdef C2K_SUPPORT
+    {"RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG",getCdmaBroadcastConfig, "get broadcast config",RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG},
+    {"RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM",deleteSmsOnRUIM,"delete sms on RUIM",RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM},
+    {"RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG",setCdmaBroadcastConfig,"set cdma broadcast sms config",RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG},
+    {"RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION",setCdmaBroadcastActivation,"cdma sms broadcast activation",RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION},
+    {"RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM",writeSmsToRuim,"cdma write sms to RUIM",RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM},
+    {"RIL_REQUEST_CDMA_SEND_SMS",sendCdmaSms, "send cdma message",RIL_REQUEST_CDMA_SEND_SMS},
+    {"RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE", acknowledgeLastIncomingCdmaSms, "Acknowledge the success or failure",RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE},
+    #endif /*C2K_SUPPORT*/
+    //eCall
+#ifdef ECALL_SUPPORT
+    {"RIL_REQUEST_ECALL_FAST_MAKE_ECALL",dialFastEcall,"dial fast ecall",RIL_REQUEST_ECALL_FAST_MAKE_ECALL},
+    {"RIL_REQUEST_ECALL_SET_IVS", setIVS,"set IVS",RIL_REQUEST_ECALL_SET_IVS},
+    {"RIL_REQUEST_ECALL_SET_MSD", setMSD,"set MSD",RIL_REQUEST_ECALL_SET_MSD},
+    {"RIL_REQUEST_ECALL_SET_PSAP", setPASP,"set PSAP",RIL_REQUEST_ECALL_SET_PSAP},
+    {"RIL_REQUEST_ECALL_IVS_PUSH_MSD", IVSPushMSD,"IVS push MSD",RIL_REQUEST_ECALL_IVS_PUSH_MSD},
+    {"RIL_REQUEST_ECALL_PSAP_PULL_MSD", PSAPPushMSD,"PSAP push MSD",RIL_REQUEST_ECALL_PSAP_PULL_MSD},
+    {"RIL_REQUEST_ECALL_SET_TEST_NUM", setTestNum,"set test num",RIL_REQUEST_ECALL_SET_TEST_NUM},
+    {"RIL_REQUEST_ECALL_SET_RECONF_NUM", setReconfNum,"set reconfigure num",RIL_REQUEST_ECALL_SET_RECONF_NUM},
+    {"RIL_REQUEST_ECALL_MAKE_ECALL", makeECall,"make eCall",RIL_REQUEST_ECALL_MAKE_ECALL},
+    {"RIL_REQUEST_ECALL_RESET_IVS", resetIVS,"reset IVS",RIL_REQUEST_ECALL_RESET_IVS},
+    {"RIL_REQUEST_ECALL_CTRL_SEQUENCE",setCTRLSequence,"Set CTRL Sequence",RIL_REQUEST_ECALL_CTRL_SEQUENCE},
+    {"RIL_REQUEST_ECALL_SET_PRI",setEmsdpri,"Set pri",RIL_REQUEST_ECALL_SET_PRI},
+    {"RIL_REQUEST_ECALL_SET_NAD_DEREGISTRATION_TIME",setNadDeregTime,"Set NAD deregistration time",RIL_REQUEST_ECALL_SET_NAD_DEREGISTRATION_TIME},
+    {"RIL_REQUEST_ECALL_SET_REGISTRATION_STATE",setNadRegState,"Set NAD registration state",RIL_REQUEST_ECALL_SET_REGISTRATION_STATE},
+    {"RIL_REQUEST_DEMO_LOCAL_SET_ECALL_TYPE",setEcallType,"Set ecall type",-1},
+    {"RIL_REQUEST_DEMO_LOCAL_GET_ECALL_TYPE",getEcallType,"get ecall type",-1},
+    {"RIL_REQUEST_DEMO_LOCAL_SET_GOST_ATTEMPTS",gostTransmitAttemptsSet,"Set gost ecall Attempts",-1},
+    {"RIL_REQUEST_DEMO_LOCAL_SET_GOST_INTERVAL",gostTransmitIntervalSet,"Set gost ecall Interval",-1},
+    {"RIL_REQUEST_DEMO_LOCAL_SET_GOST_DEFAULT",gostTransmitDefaultSet,"Set gost ecall default",-1},
+    #endif /*ECALL_SUPPORT*/
+
+#ifdef MODE_DSDS
+    {"SET_DEFAULT_SIM_ALL",set_default_sim_all, "set default sim_all", -1},
+    {"GET_DEFAULT_SIM_ALL",get_default_sim_all, "get default sim_all", -1},
+    {"SET_DEFAULT_SIM_VOICE",set_default_sim_voice, "set default sim_voice", -1},
+    {"GET_DEFAULT_SIM_VOICE",get_default_sim_voice, "get default sim_voice", -1},
+    {"SET_DEFAULT_SIM_DATA",set_default_sim_data, "set default sim_data", -1},
+    {"GET_DEFAULT_SIM_DATA",get_default_sim_data, "get default sim_data", -1},
+    {"SET_DEFAULT_SIM_SMS",set_default_sim_sms, "set default sim_sms", -1},
+    {"GET_DEFAULT_SIM_SMS",get_default_sim_sms, "get default sim_sms", -1},
+    {"SET_DEFAULT_SIM_ALL_EXCEPT_DATA",set_default_sim_all_except_data, "set default sim_all", -1},
+    {"GET_DEFAULT_SIM_ALL_EXCEPT_DATA",get_default_sim_all_except_data, "get default sim_all", -1},
+#endif /*MODE_DSSS*/
+    {"GET_MAIN_SIM_CARD",get_main_sim_card, "get main sim card", -1},
+    //BT related
+    {"RIL_REQUEST_SET_AUDIO_PATH",setAudioPath,"set audio path",-1},
+//other
+    {"QUIT", com_quit, "Quit using rild" , -1},
+    {"ENABLESYSLOG", enableSyslog, "enable syslog" , -1},
+    //{"APN_SETTING", apnSetting, "show/add/delete/updata apn setting" , -1},
+    {"EM_MAIN", em_start, "EM: main entry" , -1},
+    {"UPDATE_SIGNAL_PRINTF", updateSignalPrintf, "open/close signal printf log" , -1},
+    {"ENABLE_BT_RESPONSE", enableBTResponse, "enable BT response" , -1},
+    {"LOCAL_SET_MSD_DATA_FOR_TEST", setMsdDateForTest, "setMsdDateForTest" , -1},
+    {(char *)NULL, NULL, (char *)NULL , -1},
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/common.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/common.cpp
new file mode 100644
index 0000000..3bf0ad4
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/common.cpp
@@ -0,0 +1,824 @@
+ /*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <string.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include<fcntl.h>
+#include<sys/stat.h>
+#include<sys/types.h>
+#include<unistd.h>
+#include <assert.h>
+#include <log/log.h>
+#include <vendor-ril/telephony/ril.h>
+#include <string>
+#include <mutex>
+#include <vector>
+#include <cutils/properties.h>
+
+#include "Radio_capability_switch_util.h"
+#include "common.h"
+#include "Phone_utils.h"
+#include "utils.h"
+#include "data.h"
+#include "cc.h"
+#include <liblog/lynq_deflog.h>
+#undef LOG_TAG
+#define LOG_TAG "DEMO_COMMON"
+
+static pthread_mutex_t s_DataMutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t s_DataCond = PTHREAD_COND_INITIALIZER;
+
+/*
+typedef enum {
+    STATE_IN_SERVICE        =0,
+    STATE_OUT_OF_SERVICE    =1,
+    STATE_EMERGENCY_ONLY    =2,
+    STATE_POWER_OFF         =3
+} Service_State;
+*/
+RfDesenseTxTest* m_RfDesense;
+static RIL_CardStatus_v6* cur_CardS_Status[2] = {NULL, NULL};
+static RIL_RadioCapability radio_capability[2];
+
+static int cur_voice_radio_tech[2] = {RADIO_TECH_UNKNOWN, RADIO_TECH_UNKNOWN};
+
+static int reg_voice_service_state[2] = {0, 0};
+static int reg_data_service_state[2] = {0, 0};
+static int reg_data_radio_tech[2] = {RADIO_TECH_UNKNOWN, RADIO_TECH_UNKNOWN};
+static int reg_voice_radio_tech[2] = {RADIO_TECH_UNKNOWN, RADIO_TECH_UNKNOWN};
+static int preferred_network_type[2]  = {Phone_utils::PREFERRED_NETWORK_MODE, Phone_utils::PREFERRED_NETWORK_MODE};
+static int radio_status[2] = {RADIO_STATE_UNAVAILABLE, RADIO_STATE_UNAVAILABLE};
+static std::vector<int> call_state[2];
+
+static int default_sim_all = RIL_SOCKET_1;
+static int default_sim_all_except_data =  RIL_SOCKET_1;
+static int default_sim_voice = RIL_SOCKET_1;
+static int default_sim_data = RIL_SOCKET_1;
+static int default_sim_sms = RIL_SOCKET_1;
+static bool isNeedReconnect = false;
+
+static std::int32_t token = 0;
+static std::mutex g_mutex;
+
+static int regCodeToRadioTechnology(int request, int code, int slot);
+
+void update_call_state(void *response, size_t responselen, int slot) {
+    int num = responselen / sizeof(RIL_Call *);
+    if(num == 0) {
+        call_state[slot].clear();
+        RLOGD("[SIM%d]clear call state", slot);
+    } else {
+        call_state[slot].clear();
+        for (int i = 0 ; i < num ; i++) {
+            RIL_Call *p_cur = ((RIL_Call **) response)[i];
+            /* each call info */
+            call_state[slot].push_back(p_cur->state);
+            RLOGD("[SIM%d][id:%d]update_call_state: %d", slot,p_cur->index, p_cur->state);
+            if(p_cur->isMT) {
+                resetMute();
+            }
+        }
+    }
+}
+
+int is_call_state_idle(int slot) {
+    bool is_idle = true;
+    if(!call_state[slot].empty()) {
+        is_idle = false;
+    }
+    RLOGD("[SIM%d]is_call_state_idle: %d", slot, is_idle);
+    return is_idle;
+}
+
+void update_preferred_network_type(int type, int slot) {
+    RLOGD("[SIM%d]update_preferred_network_type: %d", slot, type);
+    preferred_network_type[slot] = type;
+}
+
+int get_preferred_network_type(int slot) {
+    return preferred_network_type[slot];
+}
+
+static int needBlockReq(int request)
+{
+#ifdef ENABLE_BLOCK_FEATURE
+    return 1;
+#endif
+
+    switch (request){
+        case RIL_REQUEST_RADIO_POWER: return 1;
+        case RIL_REQUEST_SET_IMS_ENABLE: return 1;
+        //case RIL_REQUEST_DATA_REGISTRATION_STATE: return 1;
+        default: return 0;
+    }
+    return 0;
+}
+
+static int setupToken(int token, int mode, int block)
+{
+    switch (mode){
+    case INIT:
+        token |= INIT_TOKEN_MARK;
+        break;
+    case UDP:
+        token |= RIL_TOKEN_MARK;
+        break;
+    case ATCI:
+        token |= ATCI_TOKEN_MARK;
+        break;
+    case RSPD:
+        token |= RSP_DISP_TOKEN_MARK;
+        break;
+    case OTHER:
+        token |= OTHER_TOKEN_MARK;
+        break;
+    default:
+        break;
+    }
+
+    if(block)
+        token |= BLOCK_MARK;
+
+    return token;
+}
+
+bool isDataConnectEnable(int slot) {
+    char value[PROPERTY_VALUE_MAX] = {0};
+    utils::getMSimProperty(slot,PROP_DEFAULT_DATA_SIM_STATUS, value);
+    if(atoi(value) == 1)  {
+        return true;
+    }
+    return false;
+}
+
+void updataDataConnectState(int slot, bool state) {
+    utils::setMSimProperty(slot,PROP_DEFAULT_DATA_SIM_STATUS, const_cast<char*>(state ? "1":"0"));
+}
+
+std::int32_t GenerateToken(int mode, int request) {
+    g_mutex.lock();
+    if (token +1 == TOKEN_MODE) {
+        token = 1;
+    } else {
+        token++;
+    }
+    std::int32_t t= 0;
+    t = setupToken(token,mode,needBlockReq(request));
+    g_mutex.unlock();
+    return t;
+}
+
+RequestInfo* creatRILInfoAndInit(int request, int mode, RIL_SOCKET_ID soc_id)
+{
+    RequestInfo *pRI  = (RequestInfo *)calloc(1, sizeof(RequestInfo));
+    if(pRI ==NULL){
+        RLOGE("%s,memory alloc error!",__func__);
+        return NULL;
+    }
+    android::initRequestInfo(pRI,request,mode, soc_id);
+    return pRI;
+}
+
+void set_default_sim_all_except_data(int slot_id) {
+    RLOGD("set_default_sim_all excpet data: %d", slot_id);
+    default_sim_all_except_data =  slot_id;
+    set_default_sim_voice(slot_id);
+    set_default_sim_sms(slot_id);
+}
+
+int get_default_sim_all_except_data() {
+    return default_sim_all_except_data;
+}
+
+void set_default_sim_all(int slot_id){
+    RLOGD("set_default_sim_all: %d", slot_id);
+    default_sim_all =  slot_id;
+    set_default_sim_all_except_data(slot_id);
+    set_default_sim_data(slot_id);
+}
+
+int get_default_sim_all(){
+    return default_sim_all;
+}
+
+void set_default_sim_voice(int slot_id){
+    RLOGD("set_default_sim_voice: %d", slot_id);
+    default_sim_voice = slot_id;
+}
+
+int get_default_sim_voice(){
+    return default_sim_voice;
+}
+
+void set_default_sim_data(int slot) {
+    RLOGD("set_default_sim_data: %d", slot);
+    pthread_mutex_lock(&s_DataMutex);
+    if(get_default_sim_data() != slot) {
+        if(isDataConnectEnable(get_default_sim_data())) {
+            isNeedReconnect = true;
+            deactivateDataCall(0,NULL,(RIL_SOCKET_ID)0,NULL);
+            RLOGD("set_default_sim_data, wait deactive data call done");
+            pthread_cond_wait(&s_DataCond, &s_DataMutex);
+            RLOGD("set_default_sim_data, deactive data call done");
+        }
+        RLOGD("set_default_sim_data, set prop");
+        default_sim_data = slot;
+        utils::mtk_property_set(PROP_DEFAULT_DATA_SIM, std::to_string(default_sim_data + 1).c_str());
+        while(!isRadioAvailable(RIL_SOCKET_ID(slot))) {
+            sleep(1);
+            RLOGD("[SIM%d]set_default_sim_data(RIL_REQUEST_SET_RADIO_CAPABILITY): wait radio available", slot);
+        }
+        syncDataSettings(RIL_SOCKET_ID(slot));
+        if(utils::is_support_dsds()) {
+            Radio_capability_switch_util::sendRadioCapabilityRequest(slot);
+        }
+    }
+    pthread_mutex_unlock(&s_DataMutex);
+}
+
+bool isNeedConnect() {
+    return isNeedReconnect;
+}
+
+void resetConnect() {
+    isNeedReconnect = false;
+}
+int get_default_sim_data_for_switch() {
+    return default_sim_data;
+}
+
+int get_default_sim_data(){
+    default_sim_data = utils::mtk_property_get_int32(PROP_DEFAULT_DATA_SIM, 1) -1;
+    return default_sim_data;
+}
+
+void set_default_sim_sms(int slot_id){
+    RLOGD("set_default_sim_sms: %d", slot_id);
+    default_sim_sms = slot_id;
+}
+
+int get_default_sim_sms() {
+    return default_sim_sms;
+}
+
+static int regCodeToServiceState(int request,int code, int slot);
+static int reg_Code_To_Service_State(int request,int code, int slot);
+
+const char * radioStateToString(RIL_RadioState s) {
+    switch (s) {
+    case RADIO_STATE_OFF:
+        return "RADIO_OFF";
+    case RADIO_STATE_UNAVAILABLE:
+        return "RADIO_UNAVAILABLE";
+    case RADIO_STATE_SIM_NOT_READY:
+        return "RADIO_SIM_NOT_READY";
+    case RADIO_STATE_SIM_LOCKED_OR_ABSENT:
+        return "RADIO_SIM_LOCKED_OR_ABSENT";
+    case RADIO_STATE_SIM_READY:
+        return "RADIO_SIM_READY";
+    case RADIO_STATE_RUIM_NOT_READY:
+        return "RADIO_RUIM_NOT_READY";
+    case RADIO_STATE_RUIM_READY:
+        return "RADIO_RUIM_READY";
+    case RADIO_STATE_RUIM_LOCKED_OR_ABSENT:
+        return "RADIO_RUIM_LOCKED_OR_ABSENT";
+    case RADIO_STATE_NV_NOT_READY:
+        return "RADIO_NV_NOT_READY";
+    case RADIO_STATE_NV_READY:
+        return "RADIO_NV_READY";
+    case RADIO_STATE_ON:
+        return "RADIO_ON";
+    default:
+        return "<unknown state>";
+    }
+}
+
+const char *rilSocketIdToString(RIL_SOCKET_ID socket_id) {
+    switch (socket_id) {
+    case RIL_SOCKET_1:
+        return "RIL_SOCKET_1";
+#if (SIM_COUNT >= 2)
+    case RIL_SOCKET_2:
+        return "RIL_SOCKET_2";
+#endif
+#if (SIM_COUNT >= 3)
+        case RIL_SOCKET_3:
+        return "RIL_SOCKET_3";
+#endif
+#if (SIM_COUNT >= 4)
+        case RIL_SOCKET_4:
+        return "RIL_SOCKET_4";
+#endif
+    default:
+        return "not a valid RIL";
+    }
+}
+
+void update_radio_capa(RIL_RadioCapability* cap, int slot) {
+    memset(&radio_capability[slot], 0, sizeof(RIL_RadioCapability));
+    if(cap != NULL) {
+        strcpy(radio_capability[slot].logicalModemUuid,cap->logicalModemUuid);
+        radio_capability[slot].phase = cap->phase;
+        radio_capability[slot].rat = cap->rat;
+        radio_capability[slot].session = cap->session;
+        radio_capability[slot].status = cap->status;
+        radio_capability[slot].version = cap->version;
+    }
+}
+
+RIL_RadioCapability get_radio_capa(int slot) {
+    return radio_capability[slot];
+}
+
+void update_voice_radio_tech(int code, int slot) {
+    cur_voice_radio_tech[slot] = code;
+}
+
+int get_voice_radio_tech(int slot){
+    return cur_voice_radio_tech[slot];
+}
+
+void updateCardStatusV6(RIL_CardStatus_v6 *card_status,int slot)
+{
+    if(cur_CardS_Status[slot] != NULL) {
+        RLOGD("[slot%d]updateCardStatusV6", slot);
+        for(int i = 0; i < cur_CardS_Status[slot]->num_applications; i++) {
+        free(cur_CardS_Status[slot]->applications[i].aid_ptr);
+        cur_CardS_Status[slot]->applications[i].aid_ptr = NULL;
+        free(cur_CardS_Status[slot]->applications[i].app_label_ptr);
+        cur_CardS_Status[slot]->applications[i].app_label_ptr = NULL;
+        }
+        free(cur_CardS_Status[slot]);
+        cur_CardS_Status[slot] = NULL;
+    }
+    cur_CardS_Status[slot] = (RIL_CardStatus_v6 *)calloc(1, sizeof(RIL_CardStatus_v6));
+    memset(cur_CardS_Status[slot], 0, sizeof(RIL_CardStatus_v6));
+    cur_CardS_Status[slot]->card_state = card_status->card_state;
+    cur_CardS_Status[slot]->cdma_subscription_app_index = card_status->cdma_subscription_app_index;
+    cur_CardS_Status[slot]->gsm_umts_subscription_app_index = card_status->gsm_umts_subscription_app_index;
+    cur_CardS_Status[slot]->ims_subscription_app_index = card_status->ims_subscription_app_index;
+    cur_CardS_Status[slot]->num_applications = card_status->num_applications;
+    cur_CardS_Status[slot]->universal_pin_state = card_status->universal_pin_state;
+    RLOGD("[slot%d]updateCardStatusV6 card_state: %d, cdma_index: %d, gsm_index: %d, "
+            "ims_index: %d, num_applications: %d, universal_pin_state: %d",
+            slot,
+            cur_CardS_Status[slot]->card_state,
+            cur_CardS_Status[slot]->cdma_subscription_app_index,
+            cur_CardS_Status[slot]->gsm_umts_subscription_app_index,
+            cur_CardS_Status[slot]->ims_subscription_app_index,
+            cur_CardS_Status[slot]->num_applications,
+            cur_CardS_Status[slot]->universal_pin_state);
+    if(card_status)
+    {
+        for(int i = 0; i < card_status->num_applications; i++) {
+            cur_CardS_Status[slot]->applications[i].app_state       = card_status->applications[i].app_state;
+            cur_CardS_Status[slot]->applications[i].app_type        = card_status->applications[i].app_type;
+            cur_CardS_Status[slot]->applications[i].perso_substate  = card_status->applications[i].perso_substate;
+            cur_CardS_Status[slot]->applications[i].pin1            = card_status->applications[i].pin1;
+            cur_CardS_Status[slot]->applications[i].pin1_replaced   = card_status->applications[i].pin1_replaced;
+            cur_CardS_Status[slot]->applications[i].pin2            = card_status->applications[i].pin2;
+            cur_CardS_Status[slot]->applications[i].aid_ptr = strdup(card_status->applications[i].aid_ptr);
+            cur_CardS_Status[slot]->applications[i].app_label_ptr = strdup(card_status->applications[i].app_label_ptr);
+        }
+    } else {
+        RLOGD("[slot%d]updateCardStatusV6: sim card message is null", slot);
+    }
+}
+int getSimState(RIL_SOCKET_ID slot)
+{
+    int state = 0;
+    if(cur_CardS_Status[slot] != NULL)
+    {
+        state = cur_CardS_Status[slot]->card_state;
+    }
+    else
+    {
+        LYDBGLOG("cur_CardS_Status[slot] == NULL\n");
+    }
+    RLOGD("[slot%d][getSimState] , sim card state: %d", slot,state);
+    return state;
+
+}
+char* getAid(int slot)
+{
+    char* aid = "";
+    int index = -1;
+    if(cur_CardS_Status[slot] != NULL){
+        if(Phone_utils::get_phone_type(slot) == Phone_utils::PHONE_TYPE_CDMA) {
+            index = cur_CardS_Status[slot]->cdma_subscription_app_index;
+        } else {
+            index = cur_CardS_Status[slot]->gsm_umts_subscription_app_index;
+        }
+        if(index >= 0 && index < cur_CardS_Status[slot]->num_applications) {
+            aid =  cur_CardS_Status[slot]->applications[index].aid_ptr;
+        }
+    }
+    RLOGD("[slot%d] index: %d, getAid: %s", slot, index, aid);
+    return aid;
+}
+
+void update_reg_voice_service_state(int request, char *code, int slot, int32_t token)
+{
+    if((reg_voice_service_state[slot] != atoi(code)) || ((token&RIL_TOKEN_MARK) == RIL_TOKEN_MARK)) {
+        reg_voice_service_state[slot] = atoi(code);
+        regCodeToServiceState(request, atoi(code), slot);
+    }
+}
+
+int get_reg_voice_service_state(int request, int slot)
+{
+    int state = 0;
+    int temp=0;
+    if(reg_voice_service_state[slot]) {
+        //reg_voice_service_state[slot] = atoi(code);
+        temp = reg_voice_service_state[slot];
+        state = reg_Code_To_Service_State(request, temp, slot);
+    }
+    return state;
+}
+
+
+void update_reg_voice_radio_tech(int request, int code, int slot, int32_t token) {
+    if((reg_voice_radio_tech[slot] != code) || ((token&RIL_TOKEN_MARK) == RIL_TOKEN_MARK)){
+        reg_voice_radio_tech[slot] = code;
+        regCodeToRadioTechnology(request, code, slot);
+    }
+}
+
+void update_reg_data_service_state(int request, char *code,int slot, int32_t token)
+{
+    if((reg_data_service_state[slot] != atoi(code)) || ((token&RIL_TOKEN_MARK) == RIL_TOKEN_MARK)) {
+        reg_data_service_state[slot] = atoi(code);
+        regCodeToServiceState(request, atoi(code), slot);
+    }
+}
+
+void update_reg_data_radio_tech(int request, int code, int slot, int32_t token){
+    if((reg_data_radio_tech[slot] != code) || ((token&RIL_TOKEN_MARK) == RIL_TOKEN_MARK)) {
+        reg_data_radio_tech[slot] = code;
+        regCodeToRadioTechnology(request, code, slot);
+    }
+}
+
+void registerRadioOn(RfDesenseTxTest* rf){
+    if(!m_RfDesense) {
+        m_RfDesense = rf;
+    }
+}
+
+void unregisterRadioOn() {
+    if(m_RfDesense) {
+        m_RfDesense == NULL;
+    }
+}
+
+void registerRadioOffOrNotAvailable(RfDesenseTxTest* rf){
+    if(!m_RfDesense) {
+        m_RfDesense = rf;
+    }
+}
+
+void unregisterRadioOffOrNotAvailable() {
+    if(m_RfDesense) {
+        m_RfDesense == NULL;
+    }
+}
+
+void registerOnUnsolOemHookRaw(RfDesenseTxTest* rf){
+    if(!m_RfDesense) {
+        m_RfDesense = rf;
+    }
+}
+
+void unregisterOnUnsolOemHookRaw(){
+    if(m_RfDesense) {
+        m_RfDesense == NULL;
+    }
+}
+
+void register_response_oem_hook_raw(RfDesenseTxTest* rf){
+    if(!m_RfDesense) {
+        m_RfDesense = rf;
+    }
+}
+
+void unregister_response_oem_hook_raw(){
+    if(m_RfDesense) {
+        m_RfDesense == NULL;
+    }
+}
+
+void updateRadioStatus(int newValue ,RIL_SOCKET_ID soc_id)
+{
+    RLOGD("updateRadioStatus oldState: %d, newState: %d", radio_status[soc_id], newValue);
+    bool newOn = (newValue == RADIO_STATE_ON);
+    bool oldOn = (radio_status[soc_id] == RADIO_STATE_ON);
+    bool newAvaiable = (newValue != RADIO_STATE_UNAVAILABLE);
+    bool oldAvaiable = (radio_status[soc_id] != RADIO_STATE_UNAVAILABLE);
+    if (newOn && !oldOn) {
+        RLOGD("RadioStateOn");
+        //printf("[SIM%d] radio on\n",soc_id +1);
+        if(m_RfDesense){
+            m_RfDesense->emRadioStateOn();
+        }
+    }
+
+    if ((!newOn || !newAvaiable) && !((!oldOn || !oldAvaiable))) {
+        RLOGD("RadioStateOfforNotAvailable");
+        //printf("[SIM%d] radio off or not available\n",soc_id +1);
+        if(m_RfDesense){
+            m_RfDesense->emRadioStateOfforNotAvailable();
+        }
+    }
+    if(newValue != radio_status[soc_id]) {
+        radio_status[soc_id] = newValue;
+    }
+}
+
+bool isRadioOn(RIL_SOCKET_ID soc_id)
+{
+    return radio_status[soc_id] == RADIO_STATE_ON;
+}
+
+bool isRadioAvailable(RIL_SOCKET_ID soc_id)
+{
+    return radio_status[soc_id] != RADIO_STATE_UNAVAILABLE;
+}
+static int reg_Code_To_Service_State(int request,int code, int slot)
+{
+    RLOGD("[slot%d][LYNQ]reg_Code_To_Service_State %d, request: %s",slot, code, android::requestToString(request));
+    switch (code)
+    {
+        case 0:
+        case 2: // 2 is "searching"
+        case 3: // 3 is "registration denied"
+        case 4: // 4 is "unknown" no vaild in current baseband
+        case 10:// same as 0, but indicates that emergency call is possible.
+        case 12:// same as 2, but indicates that emergency call is possible.
+        case 13:// same as 3, but indicates that emergency call is possible.
+        case 14:// same as 4, but indicates that emergency call is possible.
+        {
+            if(request == RIL_REQUEST_VOICE_REGISTRATION_STATE) {
+                RLOGD("[QUERY][VOICE REG_STATUS][SIM%d] The current service state is OUT OF SERVICE\n", slot);
+            } else {
+                RLOGD("[QUERY][DATA  REG_STATUS][SIM%d] The current service state is OUT OF SERVICE\n", slot);
+            }
+            return STATE_OUT_OF_SERVICE;
+        }
+
+        case 1:
+        case 5:
+        {
+            if(request == RIL_REQUEST_VOICE_REGISTRATION_STATE) {
+                RLOGD("[QUERY][VOICE REG_STATUS][SIM%d] The current service state is IN SERVICE\n", slot);
+            } else {
+                RLOGD("[QUERY][DATA  REG_STATUS][SIM%d] The current service state is IN SERVICE\n", slot);
+            }
+            return STATE_IN_SERVICE;
+        }
+
+        default:
+        {
+            if(request == RIL_REQUEST_VOICE_REGISTRATION_STATE) {
+                RLOGD("[QUERY][VOICE REG_STATUS][SIM%d] Unexpected service state %d\n", slot, code);
+            } else {
+                RLOGD("[QUERY][DATA  REG_STATUS][SIM%d] Unexpected service state %d\n", slot, code);
+            }
+            RLOGW("[SIM%d]regCodeToServiceState: unexpected service state %d", slot, code);
+            return STATE_OUT_OF_SERVICE;
+        }
+    }
+}
+
+
+static int regCodeToServiceState(int request,int code, int slot)
+{
+    RLOGD("[slot%d]regCodeToServiceState %d, request: %s",slot, code, android::requestToString(request));
+    switch (code)
+    {
+        case 0:
+        case 2: // 2 is "searching"
+        case 3: // 3 is "registration denied"
+        case 4: // 4 is "unknown" no vaild in current baseband
+        case 10:// same as 0, but indicates that emergency call is possible.
+        case 12:// same as 2, but indicates that emergency call is possible.
+        case 13:// same as 3, but indicates that emergency call is possible.
+        case 14:// same as 4, but indicates that emergency call is possible.
+        {
+            if(request == RIL_REQUEST_VOICE_REGISTRATION_STATE) {
+                printf("[QUERY][VOICE REG_STATUS][SIM%d] The current service state is OUT OF SERVICE\n", slot);
+            } else {
+                printf("[QUERY][DATA  REG_STATUS][SIM%d] The current service state is OUT OF SERVICE\n", slot);
+            }
+            return STATE_OUT_OF_SERVICE;
+        }
+
+        case 1:
+        case 5:
+        {
+            if(request == RIL_REQUEST_VOICE_REGISTRATION_STATE) {
+                printf("[QUERY][VOICE REG_STATUS][SIM%d] The current service state is IN SERVICE\n", slot);
+            } else {
+                printf("[QUERY][DATA  REG_STATUS][SIM%d] The current service state is IN SERVICE\n", slot);
+            }
+            return STATE_IN_SERVICE;
+        }
+
+        default:
+        {
+            if(request == RIL_REQUEST_VOICE_REGISTRATION_STATE) {
+                printf("[QUERY][VOICE REG_STATUS][SIM%d] Unexpected service state %d\n", slot, code);
+            } else {
+                printf("[QUERY][DATA  REG_STATUS][SIM%d] Unexpected service state %d\n", slot, code);
+            }
+            RLOGW("[SIM%d]regCodeToServiceState: unexpected service state %d", slot, code);
+            return STATE_OUT_OF_SERVICE;
+        }
+    }
+}
+
+static int regCodeToRadioTechnology(int request, int code, int slot) {
+    RLOGD("[slot%d]regCodeToRadioTechnology %d, request: %s",slot, code, android::requestToString(request));
+    switch(code) {
+    case RADIO_TECH_LTE:
+    {
+        if(request == RIL_REQUEST_VOICE_REGISTRATION_STATE) {
+            printf("[QUERY][VOICE REG_STATUS][SIM%d] The registered radio technology is 4G\n", slot);
+        } else {
+            printf("[QUERY][DATA  REG_STATUS][SIM%d] The registered radio technology is 4G\n", slot);
+        }
+        break;
+    }
+    case RADIO_TECH_GSM:
+    case RADIO_TECH_GPRS:
+    case RADIO_TECH_EDGE:
+    case RADIO_TECH_IS95A:
+    case RADIO_TECH_IS95B:
+    case RADIO_TECH_1xRTT:
+    {
+        if(request == RIL_REQUEST_VOICE_REGISTRATION_STATE) {
+            printf("[QUERY][VOICE REG_STATUS][SIM%d] The registered radio technology is 2G\n", slot);
+        } else {
+            printf("[QUERY][DATA  REG_STATUS][SIM%d] The registered radio technology is 2G\n", slot);
+        }
+        break;
+    }
+    case RADIO_TECH_UMTS:
+    case RADIO_TECH_HSDPA:
+    case RADIO_TECH_HSUPA:
+    case RADIO_TECH_HSPA:
+    case RADIO_TECH_EHRPD:
+    case RADIO_TECH_HSPAP:
+    case RADIO_TECH_TD_SCDMA:
+    case RADIO_TECH_EVDO_0:
+    case RADIO_TECH_EVDO_A:
+    case RADIO_TECH_EVDO_B:
+    {
+        if(request == RIL_REQUEST_VOICE_REGISTRATION_STATE) {
+            printf("[QUERY][VOICE REG_STATUS][SIM%d] The registered radio technology is 3G\n", slot);
+        } else {
+            printf("[QUERY][DATA  REG_STATUS][SIM%d] The registered radio technology is 3G\n", slot);
+        }
+        break;
+    }
+    case RADIO_TECH_UNKNOWN:
+    {
+        if(request == RIL_REQUEST_VOICE_REGISTRATION_STATE) {
+            printf("[QUERY][VOICE REG_STATUS][SIM%d] The registered radio technology is unknown\n", slot);
+        } else {
+            printf("[QUERY][DATA  REG_STATUS][SIM%d] The registered radio technology is unknown\n", slot);
+        }
+        break;
+    }
+    default:
+    {
+        if(request == RIL_REQUEST_VOICE_REGISTRATION_STATE) {
+            printf("[QUERY][VOICE REG_STATUS][SIM%d] %d is unexpected value\n",slot, code);
+        } else {
+            printf("[QUERY][DATA  REG_STATUS][SIM%d] %d is unexpected value\n",slot, code);
+        }
+    }
+    }
+    return 0;
+}
+
+int get_reg_data_radio_tech(int slot) {
+    return reg_data_radio_tech[slot];
+}
+
+int get_reg_voice_radio_tech(int slot) {
+    return reg_voice_radio_tech[slot];
+}
+
+#ifdef ECALL_SUPPORT
+void ConvertMsd(const char *msdChar, unsigned char *msd) {
+  unsigned int n, x;
+
+  for (n = 0; n < MSD_MAX_LENGTH; n++) {
+    if (sscanf(&msdChar[n<<1], "%2x", &x) == 1) {
+        msd[n] = x;
+    } else {
+        RLOGE("invalid MSD characters");
+        break;
+    }
+  }
+}
+#endif /*ECALL_SUPPORT*/
+
+bool isFinalResponseErrorEx(char* str) {
+    AtLine atline(str, NULL);
+    return (atline.isFinalResponseErrorEx(0) == 1 ? true : false);
+}
+
+int get_atci_sim(){
+    return utils::mtk_property_get_int32(ATCI_SIM, 0);
+}
+
+static char *findNextChar(char *p, char c, int length)
+{
+    char *ptr = p;
+    int i = 0;
+    while (i++ < length)
+    {
+        if (*ptr++ == c)
+            return ptr;
+    }
+    return NULL;
+}
+
+static int getGMTval(char *pdata)
+{
+    char *ptr;
+    ptr = findNextChar(pdata, '+', strlen(pdata));
+    if (ptr == NULL)
+    {
+        ptr = findNextChar(pdata, '-', strlen(pdata));
+        if (ptr == NULL)
+        {
+            return 0;
+        }
+    }
+    return atoi(ptr);
+}
+
+static void adjustGMT2LocalTime(struct tm *src, int dGMTval)
+{
+    time_t t1, t2;
+    struct tm * ptm;
+    char buf[255];
+    int dShiftSec;
+
+    dShiftSec = dGMTval * 15 * 60;
+    t1 = mktime(src);
+    t2 = (time_t)(t1 + dShiftSec);
+    ptm = gmtime(&t2);
+
+    memcpy(src, ptm, sizeof(struct tm));
+}
+
+void updateSystemTime(const void *data, int datalen)
+{
+    char strTime[32];
+    struct tm tm;
+    time_t t;
+    int dGMTval;
+
+    if (data == NULL || datalen <= 0)
+        return;
+
+    memset(strTime, 0, sizeof(strTime));
+    strcat(strTime, "20");
+    strcat(strTime, (const char *)data);
+
+    dGMTval = getGMTval(strTime);
+    memset(&tm, 0, sizeof(struct tm));
+    strptime(strTime, "%Y/%m/%d,%H:%M:%S", &tm);
+
+    adjustGMT2LocalTime(&tm, dGMTval);
+
+    t = mktime(&tm);
+    stime(&t);
+
+    return;
+}
+void notifyDataSignal() {
+    RLOGE("notifyDataSignal()");
+    pthread_mutex_lock(&s_DataMutex);
+    pthread_cond_broadcast(&s_DataCond);
+    pthread_mutex_unlock(&s_DataMutex);
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/common.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/common.h
new file mode 100644
index 0000000..7bc0e47
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/common.h
@@ -0,0 +1,235 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#ifndef YOCTO_COMMON_DATA_H
+#define YOCTO_COMMON_DATA_H
+
+#include <memory>
+#include <vendor-ril/telephony/ril.h>
+#include <binder/Parcel.h>
+#include <log/log.h>
+#include <sys/prctl.h>
+#include <cstdint>
+#include <pthread.h>
+#include "lib_tele.h"
+#include "powerManager.h"
+#include "rfdesense/RfDesenseTxTest.h"
+#include "util/AtLine.h"
+
+#define DEBUG 0
+#define FUNCTION_CALLED(time,msg) printf("%s: %s %s called\n",(time), __func__ ,(msg));
+#define FUNCTION_RETURN(time,msg) printf("%s: %s %s returns\n",(time), __func__ ,(msg));
+
+#define EM_MODE_SUPPORT 1
+#ifdef ATCI_PARSE
+#define ATCI_ENABLE_RESPONSE 1
+#endif
+//#define ENABLE_BLOCK_FEATURE
+#define BLOCK_MARK          0x10000000
+#define RSP_DISP_TOKEN_MARK 0x01000000
+#define ATCI_TOKEN_MARK     0x02000000
+#define RIL_TOKEN_MARK      0x04000000
+#define INIT_TOKEN_MARK     0x08000000
+#define OTHER_TOKEN_MARK    0x20000000;
+#define TOKEN_MODE 0x01000000
+#define INIT 1
+#define UDP  2
+#define ATCI 3
+#define RSPD 4
+#define OTHER 5
+
+#define MAX_LEN 101
+#define MAX_QUEST_LEN 12
+#define PROP_DEFAULT_DATA_SIM "persist.vendor.radio.data.sim"
+#define PROP_DEFAULT_DATA_SIM_STATUS "vendor.radio.data.enable"
+#define ATCI_SIM "persist.vendor.service.atci.sim"
+//#define PROP_DATA_ALLOW_STATUS "vendor.ril.data.allow.status"
+
+/* 
+The range of error values unique to LYNQ is 8000 to 10000.
+The sim card state is error.
+*/
+#define LYNQ_E_CARDSTATE_ERROR 8000
+/* The voice service state is out of service*/
+#define LYNQ_E_STATE_OUT_OF_SERVICE 8001
+/* The voice service state is EMERGENCY_ONLY*/
+#define LYNQ_E_STATE_EMERGENCY_ONLY 8002
+/* The radio power is power off*/
+#define LYNQ_E_STATE_POWER_OFF 8003
+#define LYNQ_E_TIME_OUT 8004
+/* The logic conflict*/
+#define LYNQ_E_CONFLICT 9000
+/*Null anomaly*/
+#define LYNQ_E_NULL_ANONALY 9001
+#define UNSET -1
+extern int autoAnswerMode;
+
+typedef enum {
+    STATE_IN_SERVICE        =0,
+    STATE_OUT_OF_SERVICE    =1,
+    STATE_EMERGENCY_ONLY    =2,
+    STATE_POWER_OFF         =3
+} Service_State;
+
+
+typedef struct {
+    int requestNumber;
+    void (*dispatchFunction) (android::Parcel &p, struct RequestInfo *pRI);
+    int(*responseFunction) (android::Parcel &p, void *response, size_t responselen);
+} CommandInfo;
+
+typedef struct RequestInfo {
+    int32_t token;      //this is not RIL_Token
+    CommandInfo *pCI;
+    struct RequestInfo *p_next;
+    char cancelled;
+    char local;         // responses to local commands do not go back to command process
+    RIL_SOCKET_ID socket_id;
+} RequestInfo;
+
+typedef struct {
+    char *name;           /* User printable name of the function. */
+    int (*func)(int argc, char *argv[], RIL_SOCKET_ID socket_id, RequestInfo *pRI);       /* Function to call to do the job. */
+    char *doc;            /* Documentation for this function.  */
+    int request;
+} COMMAND;
+
+void updateCardStatusV6(RIL_CardStatus_v6 *card_status,int slot);
+char* getAid(int slot);
+
+void update_reg_voice_service_state(int request, char* code, int slot, int32_t token);
+void update_reg_voice_radio_tech(int request, int code, int slot, int32_t token);
+void update_reg_data_service_state(int request, char* code, int slot, int32_t token);
+void update_reg_data_radio_tech(int request, int code, int slot, int32_t token);
+void update_preferred_network_type(int type, int slot);
+void update_call_state(void *response, size_t responselen, int slot);
+
+int is_call_state_idle(int slot);
+int get_preferred_network_type(int slot);
+int get_reg_data_radio_tech(int slot);
+int get_reg_voice_radio_tech(int slot);
+void update_voice_radio_tech(int code, int slot);
+int get_voice_radio_tech(int slot);
+void update_radio_capa(RIL_RadioCapability* cap, int slot);
+RIL_RadioCapability get_radio_capa(int slot);
+std::int32_t GenerateToken(int mode, int request);
+
+void updateRadioStatus(int newValue,RIL_SOCKET_ID soc_id);
+bool isRadioOn(RIL_SOCKET_ID soc_id);
+bool isRadioAvailable(RIL_SOCKET_ID soc_id);
+
+bool isDataConnectEnable(int slot);
+void updataDataConnectState(int slot, bool state);
+const char *radioStateToString(RIL_RadioState);
+const char * rilSocketIdToString(RIL_SOCKET_ID socket_id);
+typedef void (*appResponse)(int32_t token,RIL_Errno e,char*response);
+typedef void (*appOnUnsolicitedResponse)(char *response);
+
+#if EM_MODE_SUPPORT
+typedef void (* netwokInfoNotify)(int type, char *data);
+typedef void (*atCmdResponse)(char *response,int responselen);
+extern RfDesenseTxTest* m_RfDesense;
+
+void registerRadioOn(RfDesenseTxTest* rf);
+void unregisterRadioOn();
+void registerRadioOffOrNotAvailable(RfDesenseTxTest* rf);
+void unregisterRadioOffOrNotAvailable();
+void registerOnUnsolOemHookRaw(RfDesenseTxTest* rf);
+void unregisterOnUnsolOemHookRaw();
+void register_response_oem_hook_raw(RfDesenseTxTest* rf);
+void unregister_response_oem_hook_raw();
+
+bool isFinalResponseErrorEx(char* str);
+
+void set_default_sim_all(int slot_id);
+int get_default_sim_all();
+void set_default_sim_voice(int slot_id);
+int get_default_sim_voice();
+void set_default_sim_data(int slot);
+int get_default_sim_data_for_switch();
+bool isNeedConnect();
+void resetConnect();
+int get_default_sim_data();
+void set_default_sim_sms(int slot_id);
+int get_default_sim_sms();
+void set_default_sim_all_except_data(int slot_id);
+int get_default_sim_all_except_data();
+RequestInfo* creatRILInfoAndInit(int request, int mode, RIL_SOCKET_ID soc_id);
+int get_atci_sim();
+
+
+/*mobiletek smart*/
+int getSimState(RIL_SOCKET_ID slot);
+int get_reg_voice_service_state(int request, int slot);
+/*mobiletek smart*/
+
+
+void updateSystemTime(const void *data, int datalen);
+void notifyDataSignal();
+#endif
+#ifdef ECALL_SUPPORT
+void ConvertMsd(const char *msdChar, unsigned char *msd);
+#endif /*ECALL_SUPPORT*/
+namespace android {
+    void initRequestInfo(RequestInfo *pRI, int  request, int mode, RIL_SOCKET_ID soc_id);
+    const char * requestToString(int request);
+    const int RspDispFunction(int request,char* arg, RIL_SOCKET_ID socket_id);
+    void requestSMSACKNOWLEDGE(RIL_SOCKET_ID soc_id);
+    void requestAnswer(RIL_SOCKET_ID soc_id);
+    void writeStringToParcel(Parcel &p, const char *s);
+    void RIL_startEventLoop(void);
+    void startATCILoop(void);
+    void startGdbusLoop(void);
+    void startPMLoop(void);
+    void registerForAppResponse(appResponse cb);
+    void unregisterAppResponse();
+    void registerOnUnsolicitedResponse(user_cb* cb);
+    void unregisterAppResponse();
+    void registerForATcmdResponse(atCmdResponse cb);
+    void unregisterNetwork();
+    void registerForNetworkInfo(netwokInfoNotify cb);
+    void unregisterATcmd();
+    int emResultNotify(const char *str);
+    void ATCIRequest(int request, char* reqString, void* t,int argc, char**argv);
+	void startWakupLoop(void);
+    //void registerForAppResponse(appResponse cb);
+    //void registerOnUnsolicitedResponse(appOnUnsolicitedResponse cb);
+    //void lynqResponseCallback(char*response);
+    //void lynqOnUnsolicitedResponseCallback(char*response);
+    int getRequestData(char **data, int lenth);
+    int specialRequestController(char **data, int lenth,int* token);
+
+}
+
+#endif
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/data/data.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/data/data.cpp
new file mode 100644
index 0000000..9400bcb
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/data/data.cpp
@@ -0,0 +1,1499 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <binder/Parcel.h>
+#include <vendor-ril/telephony/ril.h>
+#include <pal/pal_nm.h>
+#include <string.h>
+#include <log/log.h>
+#include <strings.h>
+#include <apn_interface.h>
+#include <vector>
+#include <string>
+
+#include "data/data.h"
+#include "common.h"
+
+#include "data/data_gdbus.h"
+#include "Radio_capability_switch_util.h"
+#include "util/utils.h"
+
+#undef LOG_TAG
+#define LOG_TAG "DEMO_DATA"
+
+#define SKIP_DATA_SETTINGS -2
+
+typedef struct {
+    char apn_type[10];
+    int cid;
+    int net_id;
+    char ifname[16];
+}map_cid;
+
+struct apntype_2_bitmask {
+char *type;
+int typebitmask;
+};
+
+#define APN_TYPE_ALL "*"
+#define TEXT_APN_TYPE_DEFAULT "default"
+#define TEXT_APN_TYPE_IMS "ims"
+#define TEXT_APN_TYPE_MMS "mms"
+#define TEXT_APN_TYPE_SUPL "supl"
+#define TEXT_APN_TYPE_DUN "dun"
+#define TEXT_APN_TYPE_HIPRI "hipri"
+#define TEXT_APN_TYPE_FOTA "fota"
+#define TEXT_APN_TYPE_CBS "cbs"
+#define TEXT_APN_TYPE_EMERGENCY "emergency"
+#define TEXTAPN_TYPE_IA "ia"
+#define TEXT_APN_TYPE_DM "dm"
+#define TEXT_APN_TYPE_WAP "wap"
+#define TEXT_APN_TYPE_NET "net"
+#define TEXT_APN_TYPE_CMMAIL "cmmail"
+#define TEXT_APN_TYPE_TETHERING "tethering"
+#define TEXT_APN_TYPE_RCSE "rcse"
+#define TEXT_APN_TYPE_XCAP "xcap"
+#define TEXT_APN_TYPE_RCS "rcs"
+
+//for IOT card type
+#define IOT_TEXT_APN_TYPE_DEFAULT "iot_default"
+#define IOT_TEXT_APN_TYPE_NET_0 "iot_net_0"
+#define IOT_TEXT_APN_TYPE_NET_1 "iot_net_1"
+#define IOT_TEXT_APN_TYPE_NET_2 "iot_net_2"
+#define IOT_TEXT_APN_TYPE_NET_3 "iot_net_3"
+#define IOT_TEXT_APN_TYPE_NET_4 "iot_net_4"
+#define IOT_TEXT_APN_TYPE_NET_5 "iot_net_5"
+#define IOT_TEXT_APN_TYPE_NET_6 "iot_net_6"
+
+#ifdef TARGET_PLATFORM_MT2731
+#define DATAASST_PDN_APN_TYPE_UNKNOWN      0x0
+#define DATAASST_PDN_APN_TYPE_DEFAULT      0x1
+#define DATAASST_PDN_APN_TYPE_MMS          0x2
+#define DATAASST_PDN_APN_TYPE_SUPL         0x4
+#define DATAASST_PDN_APN_TYPE_DUN          0x8
+#define DATAASST_PDN_APN_TYPE_HIPRI        0x10
+#define DATAASST_PDN_APN_TYPE_FOTA         0x20
+#define DATAASST_PDN_APN_TYPE_IMS          0x40
+#define DATAASST_PDN_APN_TYPE_CBS          0x80
+#define DATAASST_PDN_APN_TYPE_IA           0x100
+#define DATAASST_PDN_APN_TYPE_EMERGENCY    0x200
+#define DATAASST_PDN_APN_TYPE_WAP          0x400
+#define DATAASST_PDN_APN_TYPE_XCAP         0x800
+#define DATAASST_PDN_APN_TYPE_RCS          0x1000
+#define DATAASST_PDN_APN_TYPE_BIP          0x2000
+#define DATAASST_PDN_APN_TYPE_VSIM         0x4000
+#else
+#define DATAASST_PDN_APN_TYPE_UNKNOWN (0x00000000)
+#define DATAASST_PDN_APN_TYPE_DEFAULT (0x00000001)
+#define DATAASST_PDN_APN_TYPE_IMS (0x00000002)
+#define DATAASST_PDN_APN_TYPE_MMS (0x00000004)
+#define DATAASST_PDN_APN_TYPE_SUPL (0x00000008)
+#define DATAASST_PDN_APN_TYPE_DUN (0x00000010)
+#define DATAASST_PDN_APN_TYPE_HIPRI (0x00000020)
+#define DATAASST_PDN_APN_TYPE_FOTA (0x00000040)
+#define DATAASST_PDN_APN_TYPE_CBS (0x00000080)
+#define DATAASST_PDN_APN_TYPE_EMERGENCY (0x00000100)
+#define DATAASST_PDN_APN_TYPE_IA (0x00000200)
+#define DATAASST_PDN_APN_TYPE_DM (0x00000400)
+#define DATAASST_PDN_APN_TYPE_WAP (0x00000800)
+#define DATAASST_PDN_APN_TYPE_NET (0x00001000)
+#define DATAASST_PDN_APN_TYPE_CMMAIL (0x00002000)
+#define DATAASST_PDN_APN_TYPE_TETHERING (0x00004000)
+#define DATAASST_PDN_APN_TYPE_RCSE (0x00008000)
+#define DATAASST_PDN_APN_TYPE_XCAP (0x00010000)
+#define DATAASST_PDN_APN_TYPE_RCS (0x00020000)
+#endif
+//for IOT
+#define IOT_DATAASST_PDN_APN_TYPE_DEFAULT   (0x00100000)
+#define IOT_DATAASST_PDN_APN_TYPE_NET_0     (0x00200000)
+#define IOT_DATAASST_PDN_APN_TYPE_NET_1     (0x00400000)
+#define IOT_DATAASST_PDN_APN_TYPE_NET_2     (0x00800000)
+#define IOT_DATAASST_PDN_APN_TYPE_NET_3     (0x01000000)
+#define IOT_DATAASST_PDN_APN_TYPE_NET_4     (0x02000000)
+#define IOT_DATAASST_PDN_APN_TYPE_NET_5     (0x04000000)
+#define IOT_DATAASST_PDN_APN_TYPE_NET_6     (0x08000000)
+
+#define LEN 128
+char line[LEN] = {0};
+char csname[27] = {0};
+static int net_id = 1000;
+
+int ims_type_in_db = 0;
+
+static int data_call_num = 0;
+
+RIL_Data_Call_Response_v6 *data_call_response = NULL;
+const int INVALID_VALUE = -1;
+const int INVALID = -2;
+int gcid = -1;
+bool isEnable = false;
+
+char  cur_apn_type[12]={0};
+
+int SETUP_DATA_AUTH_NONE      = 0;
+int SETUP_DATA_AUTH_PAP       = 1;
+int SETUP_DATA_AUTH_CHAP      = 2;
+int SETUP_DATA_AUTH_PAP_CHAP  = 3;
+
+char* SETUP_DATA_PROTOCOL_IPV4    = "IP";
+char* SETUP_DATA_PROTOCOL_IPV6   = "IPV6";
+char* SETUP_DATA_PROTOCOL_IPV4V6 = "IPV4V6";
+
+map_cid current_cid[8] = {
+    {"", -1, -1, ""}, \
+    {"", -1, -1, ""}, \
+    {"", -1, -1, ""}, \
+    {"", -1, -1, ""}, \
+    {"", -1, -1, ""}, \
+    {"", -1, -1, ""}, \
+    {"", -1, -1, ""}, \
+    {"", -1, -1, ""}
+};
+
+//when 1, libvendor-ril manage the PDN retry , network configuration than create from ril request.
+bool isEnableLocalconf(){
+    bool isEnable;
+    RLOGD("enable configuration: %d", isEnable);
+
+    char prop_value[64] = { 0 };
+
+    utils::mtk_property_get("persist.pdnby.vendor",prop_value,"0");
+
+    isEnable = atoi(prop_value);
+
+    RLOGD("mtk_property_get configuration: %d", isEnable);
+    return isEnable;
+}
+
+/* Deactivate data call reasons */
+int DEACTIVATE_REASON_NONE = 0;
+int DEACTIVATE_REASON_RADIO_OFF = 1;
+int DEACTIVATE_REASON_PDP_RESET = 2;
+
+char dns[4][40] = {0};
+int dnsNum = 0;
+
+int findCellularName(char *s)
+{
+    int i = 0;
+    while (i < LEN) {
+        if (strncmp((s + i), "cellular_", 9) == 0) {
+            strncpy(csname, (s + i), 26);
+            csname[26] = '\0';
+            RLOGD("cellular service name is %s\n", csname);
+            return i;
+        } else {
+            i++;
+        }
+    }
+    return -1;
+}
+
+int getCellularService()
+{
+    FILE *cmd = popen("connmanctl services | grep cellular", "r");
+
+    if (cmd == NULL) {
+        RLOGD("open pipe fail!\n");
+        return -1;
+    }
+
+    fgets(line, LEN, cmd);
+    RLOGD("line is %s\n", line);
+
+    pclose(cmd);
+    return 0;
+}
+
+char* checkParameters(char* para)
+{
+    if (strcasecmp(para, "null") == 0) {
+        return "";
+    } else {
+        return para;
+    }
+}
+
+void updateApntype(char* apntype)
+{
+    if(strcasecmp(cur_apn_type, "ims") == 0
+        || strcasecmp(cur_apn_type, "xcap") == 0
+        || strcasecmp(cur_apn_type, "ia") == 0)
+    {
+        RLOGD("the current apn type: %s, don't set router, so just return", cur_apn_type);
+        return;
+    }
+
+    for(int i =0; i < 8; i++)
+    {
+        if((strcmp(current_cid[i].apn_type, "") == 0) || (current_cid[i].cid == INVALID_VALUE))
+        {
+            memset(current_cid[i].apn_type,0, strlen(current_cid[i].apn_type));
+            strcpy(current_cid[i].apn_type, apntype);
+            RLOGD("updateApntype[%d]: %s", i, apntype);
+            break;
+        }
+    }
+}
+
+void updatenetId(char* apntype, int net_id)
+{
+    for(int i =0; i < 8; i++)
+    {
+        for (int i = 0; i < 8 ; i++)
+        {
+            if(current_cid[i].net_id== INVALID_VALUE
+                && (strcmp(current_cid[i].apn_type, apntype) == 0))
+            {
+                current_cid[i].net_id = net_id;
+                RLOGD("updatenetId[%d]: %d", i, net_id);
+            }
+        }
+    }
+}
+
+void updateInterfaceName(char* apntype,char* interface_name)
+{
+    for (int i = 0; i < 8 ; i++)
+    {
+        if((strcmp(current_cid[i].ifname, "") == 0)
+            && (strcmp(current_cid[i].apn_type, apntype) == 0))
+        {
+            memset(current_cid[i].ifname,0, strlen(current_cid[i].ifname));
+            strncpy(current_cid[i].ifname, interface_name, sizeof(current_cid[i].ifname) - 1);
+            current_cid[i].ifname[sizeof(current_cid[i].ifname) - 1] = '\0';
+            RLOGD("updateinterfaceName[%d]: %s", i, current_cid[i].ifname);
+            break;
+        }
+    }
+}
+void destroyCid(char* apntype)
+{
+    for(int i =0; i < 8; i++)
+    {
+        if(strcmp(current_cid[i].apn_type, apntype) == 0)
+        {
+            strcpy(current_cid[i].apn_type, "");
+            current_cid[i].cid = -1;
+            current_cid[i].net_id = -1;
+            strcpy(current_cid[i].ifname, "");
+            RLOGD("destroyCid[%d]: %s",i, apntype);
+            break;
+        }
+    }
+}
+
+int getcid(char* apntype)
+{
+    int cid = INVALID_VALUE;
+    for(int i = 0; i < 8; i++)
+    {
+        if(strcmp(current_cid[i].apn_type, apntype) == 0)
+        {
+            cid = current_cid[i].cid;
+            break;
+        }
+    }
+    RLOGD("getcid: %d , apntype: %s", cid, apntype);
+    return cid;
+}
+
+int getnetId(char* apntype)
+{
+    int netid = INVALID_VALUE;
+    for(int i = 0; i < 8; i++)
+    {
+        if(strcmp(current_cid[i].apn_type, apntype) == 0)
+        {
+            netid = current_cid[i].net_id;
+            break;
+        }
+    }
+    RLOGD("getnetId: %d , apntype: %s", netid, apntype);
+    return netid;
+}
+
+char* getIfnameFromCache(char* apnType)
+{
+    char* interfaceName = NULL;
+    for(int i = 0; i < 8; i++)
+    {
+        if(strcmp(current_cid[i].apn_type, apnType) == 0)
+        {
+            interfaceName = current_cid[i].ifname;
+            break;
+        }
+    }
+    RLOGD("getIfnameFromCache: %s, apntype: %s", interfaceName, apnType);
+    return interfaceName;
+}
+
+char* getDns(char* apnType)
+{
+    RLOGD("getDns start data_call_num: %d", data_call_num);
+    char dnses[150] = "";
+    int cid = getcid(apnType);
+    if(cid == INVALID_VALUE)
+    {
+        RLOGD("cid is invalid");
+        return NULL;
+    }
+    for(int i = 0 ; i < data_call_num; i++)
+    {
+        if((data_call_response != NULL) && (data_call_response[i].cid == cid))
+        {
+            strncpy(dnses, data_call_response[i].dnses, sizeof(dnses)-1);
+            dnses[sizeof(dnses) -1] = '\0';
+        }
+    }
+    RLOGD("dnses: %s", dnses);
+    if (strcmp(dnses, "") == 0)
+    {
+        RLOGD("dnses is null");
+        return NULL;
+    }
+
+    dns[4][40] = {0};
+    dnsNum = 0;
+
+    RLOGD("fill data");
+    if(strstr(dnses, " "))
+    {
+        char* p = strtok(dnses, " ");
+        while(p)
+        {
+            if(dnsNum < 4)
+            {
+                RLOGD("dns[%d]: %s",dnsNum, p);
+                strcpy(dns[dnsNum],p);
+                dnsNum++;
+            }
+            p = strtok(NULL, " ");
+        }
+    } else {
+        RLOGD("dns: %s, only one", dnses);
+        strcpy(dns[dnsNum],dnses);
+        dnsNum++;
+    }
+    return dnses;
+}
+
+char* getAddress(char* apnType, const char token)
+{
+    char* ip = NULL;
+    char* addrs = NULL;
+    int cid = getcid(apnType);
+    if(cid == INVALID_VALUE)
+    {
+        RLOGD("cid is invalid");
+        return NULL;
+    }
+    for(int i = 0 ; i < data_call_num; i++)
+    {
+        if((data_call_response != NULL) && (data_call_response[i].cid == cid))
+        {
+            addrs = data_call_response[i].addresses;
+        }
+    }
+    if(!addrs)
+    {
+        RLOGD("addresss is null");
+        return NULL;
+    }
+    if(strstr(addrs, " "))
+    {
+        char* p = strtok(addrs, " ");
+        while(p)
+        {
+            if(strchr(p, token))
+            {
+                ip = p;
+                break;
+            } else {
+                p = strtok(p, " ");
+            }
+        }
+    } else {
+        if(strchr(addrs, token))
+        {
+            ip = addrs;
+        }
+    }
+    RLOGD("ip: %s", ip);
+    return ip;
+}
+
+char* getGateWay(char* apnType, const char token)
+{
+    char* gateway = NULL;
+    char* gateways = NULL;
+    int cid = getcid(apnType);
+    if(cid == INVALID_VALUE)
+    {
+        RLOGD("cid is invalid");
+        return NULL;
+    }
+    for(int i = 0 ; i < data_call_num; i++)
+    {
+        if((data_call_response != NULL) && (data_call_response[i].cid == cid))
+        {
+            gateways = data_call_response[i].gateways;
+        }
+    }
+    if(!gateways)
+    {
+        RLOGD("gateways is null");
+        return NULL;
+    }
+    if(strstr(gateways, " "))
+    {
+        char* p = strtok(gateways, " ");
+        while(p)
+        {
+            if(strchr(p, token))
+            {
+                gateway = p;
+                break;
+            } else {
+                p = strtok(p, " ");
+            }
+        }
+    } else {
+        if(strchr(gateways, token))
+        {
+            gateway = gateways;
+        }
+    }
+    RLOGD("gateway : %s", gateway);
+    return gateway;
+}
+char* getInterfaceNameFromLocal(char* apnType)
+{
+    char* interfaceName = NULL;
+    int cid = getcid(apnType);
+    if(cid == INVALID_VALUE)
+    {
+        RLOGD("cid is invalid");
+        return NULL;
+    }
+    for(int i = 0 ; i < 8; i++)
+    {
+        if(current_cid[i].cid == cid)
+        {
+            interfaceName = current_cid[i].ifname;
+        }
+    }
+    RLOGD("interfaceName: %s", interfaceName);
+    return interfaceName;
+}
+char* getInterfaceName(char* apnType)
+{
+    char* interfaceName = NULL;
+    int cid = getcid(apnType);
+    if(cid == INVALID_VALUE)
+    {
+        RLOGD("cid is invalid");
+        return NULL;
+    }
+    for(int i = 0 ; i < data_call_num; i++)
+    {
+        if((data_call_response != NULL) && (data_call_response[i].cid == cid))
+        {
+            interfaceName= data_call_response[i].ifname;
+        }
+    }
+    RLOGD("interfaceName: %s", interfaceName);
+    return interfaceName;
+}
+
+void configInterNetNetwork(char * apnType)
+{
+    //if route had filled. do fill the router information
+    char* interface_name = getInterfaceName(apnType);
+    if(!interface_name)
+    {
+        RLOGW("config fail, interface_name is nul");
+        return;
+    }
+    //if mal had set the route, don't set it.
+    unsigned int netid = 0;
+    int value = nm_interface_get_netid(interface_name, &netid);
+    if(netid > 0) {
+        RLOGW("the netid exsited. value: %d, netid: %d ", value, netid);
+        return;
+    }
+    if(net_id +1 >= 2000 ) {
+        net_id =  1001;
+    } else {
+        net_id++;
+    }
+
+    RLOGD("NET_ID: %d", net_id);
+    updatenetId(apnType,net_id);
+
+    char* temp_gateway = NULL;
+    char ipv4_gateway[16] = "";
+    char ipv6_gateway[40] = "";
+    temp_gateway = getGateWay(apnType, '.');
+    if(temp_gateway != NULL) {
+    strcpy(ipv4_gateway, temp_gateway);
+    }
+    temp_gateway = NULL;
+    temp_gateway = getGateWay(apnType,':');
+    if(temp_gateway != NULL) {
+        strcpy(ipv6_gateway, temp_gateway);
+    }
+
+
+    int prefix_len_ipv4 = 8;
+    int prefix_len_ipv6 = 64;
+    char* temp_dns[4] = {0};
+
+    updateInterfaceName(apnType,interface_name);
+    getDns(apnType);
+    char* DESTIONNATION_IPV4 = "0.0.0.0/0";
+    char* DESTIONNATION_IPV6 = "::/0";
+
+    RLOGD("nm_network_create() netid: %d", net_id);
+    if(nm_network_create(net_id, NULL) != 0)
+    {
+        RLOGD("nm_network_create() fail");
+        goto DEMO_CONFIG_NET_IF_ERR_1;
+    }
+
+    RLOGD("nm_network_interface_add() netid: %d, interface_name: %s", net_id, interface_name);
+    if(nm_network_interface_add(net_id, interface_name) != 0)
+    {
+        RLOGD("nm_network_interface_add() fail");
+        goto DEMO_CONFIG_NET_IF_ERR_2;
+    }
+
+    RLOGD("nm_network_route_add() netid: %d, ifname: %s, destion_ipv4: %s, ipv4_gateway: %s", net_id, interface_name, DESTIONNATION_IPV4,ipv4_gateway);
+    if (strlen(ipv4_gateway) != 0 && nm_network_route_add(net_id, interface_name, DESTIONNATION_IPV4,ipv4_gateway, 0, 1) != 0)
+    {
+        RLOGD("nm_network_route_add() gateway_v4 fail");
+        goto DEMO_CONFIG_NET_IF_ERR_2;
+    }
+
+    RLOGD("nm_network_route_add() netid: %d, ifname: %s, destion_ipv6: %s, ipv6_gateway: %s", net_id, interface_name, DESTIONNATION_IPV6,ipv6_gateway);
+    if (strlen(ipv6_gateway) != 0 && nm_network_route_add(net_id, interface_name, DESTIONNATION_IPV6,ipv6_gateway, 0, 1) != 0)
+    {
+        RLOGD("nm_network_route_add() gateway_v6 fail");
+        goto DEMO_CONFIG_NET_IF_ERR_2;
+    }
+
+    for (int k = 0 ; k < dnsNum; k++)
+    {
+        temp_dns[k] = dns[k];
+    }
+
+    if (nm_resolver_dns_set(net_id, interface_name, temp_dns, dnsNum, NM_NETWORK_TYPE_INTERNET) !=0)
+    {
+        RLOGD("nm_resolver_dns_set() fail");
+        goto DEMO_CONFIG_NET_IF_ERR_3;
+    }
+
+    if(strstr(apnType, "default") != NULL) {
+        RLOGD("nm_network_default_set(): netid: %d", net_id);
+        if(nm_network_default_set(net_id) != 0)
+        {
+            RLOGD("nm_network_default_set() fail");
+            return;
+        }
+    }
+
+    RLOGD("Demo App config network Done");
+    return;
+
+DEMO_CONFIG_NET_IF_ERR_3:
+    if(nm_resolver_dns_clear(net_id) != 0)
+    {
+        RLOGD("nm_resolver_dns_clear fail.");
+    }
+
+DEMO_CONFIG_NET_IF_ERR_2:
+    if(nm_network_interface_remove(net_id, interface_name) != 0)
+    {
+        RLOGD("nm_network_interface_remove fail.");
+    }
+
+DEMO_CONFIG_NET_IF_ERR_1:
+    if(nm_network_destroy(net_id) != 0)
+    {
+        RLOGD("nm_network_destroy fail.");
+    }
+    destroyCid(apnType);
+}
+
+void releaseInternetNetworkconfig(char* apnType)
+{
+    if(strcasecmp(cur_apn_type, "ims") == 0
+        || strcasecmp(cur_apn_type, "xcap") == 0
+        || strcasecmp(cur_apn_type, "ia") == 0)
+    {
+        RLOGD("the current apn type: %s, don't set router, so just return", cur_apn_type);
+        return;
+    }
+
+    char* ifname = getInterfaceNameFromLocal(apnType);
+
+    if((ifname == NULL)||(strcmp("", ifname) == 0))
+    {
+        RLOGD("interface_name is \"\"");
+        return;
+    }
+
+    //if mal had set the route, don't set it.
+    unsigned int netid = 0;
+    int value = nm_interface_get_netid(ifname, &netid);
+    RLOGD("query netid. value: %d, netid: %d ", value, netid);
+    if(netid <= 0) return;
+
+    if(nm_resolver_dns_clear(netid) != 0)
+    {
+        RLOGD("nm_resolver_dns_clear fail.");
+    }
+
+    if(nm_network_interface_remove(netid, ifname) != 0)
+    {
+        RLOGD("nm_network_interface_remove fail.");
+    }
+
+    if(nm_network_destroy(netid) != 0)
+    {
+        RLOGD("nm_network_destroy fail.");
+    }
+}
+
+int getApnProfileID(char *apnType)
+{
+    int profile_id;
+    if (strcasecmp(apnType, "mms") == 0) {
+        profile_id = DATA_PROFILE_MMS;
+    } else if (strcasecmp(apnType, "supl") == 0) {
+        profile_id =DATA_PROFILE_SUPL;
+    } else if (strcasecmp(apnType, "dun") == 0) {
+        profile_id = DATA_PROFILE_TETHERED;
+    } else if (strcasecmp(apnType, "hipri") == 0) {
+        profile_id = DATA_PROFILE_HIPRI; // DEFAULT for now
+    } else if (strcasecmp(apnType, "fota") == 0) {
+        profile_id = DATA_PROFILE_FOTA;
+    }else if (strcasecmp(apnType, "ims") == 0) {
+        profile_id = DATA_PROFILE_IMS;
+    }else if (strcasecmp(apnType, "cbs") == 0) {
+        profile_id = DATA_PROFILE_CBS;
+    } else if (strcasecmp(apnType, "emergency") == 0) {
+        profile_id = DATA_PROFILE_EMERGENCY;
+    } else if (strcasecmp(apnType, "wap") == 0) {
+        profile_id = DATA_PROFILE_WAP;
+    }else if (strcasecmp(apnType, "xcap") == 0) {
+        profile_id = DATA_PROFILE_XCAP;
+    }else if (strcasecmp(apnType, "rcs") == 0) {
+        profile_id = DATA_PROFILE_RCS;
+    }else if (strcasecmp(apnType, "bip") == 0) {
+        profile_id = DATA_PROFILE_BIP;
+    }else if (strcasecmp(apnType, "vsim") == 0) {
+        profile_id = DATA_PROFILE_VSIM;
+    }else {
+        profile_id = DATA_PROFILE_DEFAULT;
+    }
+
+    RLOGD("getApnProfileID apn type :%s, profile_id: %d",apnType, profile_id);
+    return profile_id;
+}
+
+int setDataAllowed(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    if(argc != 2)
+    {
+        free(pRI);
+        RLOGD("the peremeters numbers isn't right , so return");
+        return -1;
+    }
+
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    p.writeInt32(1);
+    p.writeInt32(atoi(argv[1])); //allowed ? 1:0
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+int setupDataCall(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    if(argc > 2){
+        return setupDataCallargc(argc,argv,socket_id,pRI);
+    }
+    char cmd[256];
+    getCellularService();
+    findCellularName(line);
+    sprintf(cmd, "connmanctl connect %s", csname);
+    int ret = system(cmd);
+    memset(line, LEN*sizeof(char), 0);
+    memset(line, 27*sizeof(char), 0);
+
+    updataDataConnectState(get_default_sim_data(), true);
+    /* no response from telecore, free pRI prevent memory leak */
+    if (pRI != NULL) {
+        free(pRI);
+    }
+
+    return ret;
+}
+
+int getIntefaceId(char * apnType) {
+    int all_interface_id[5] = {1,2,3,7,0};
+    int temp_cid = INVALID_VALUE;
+    if (getcid(apnType) == INVALID_VALUE) {
+        bool is_find = false;
+        for(int i=0; i<5; i++)
+        {
+            temp_cid = all_interface_id[i];
+            bool is_exsited = false;
+            for (int j=0; j < 8; j++)
+            {
+                if (current_cid[j].cid != INVALID_VALUE && current_cid[j].cid == temp_cid)
+                {
+                    is_exsited = true;
+                    break;
+                }
+            }
+            if(!is_exsited)
+            {
+                is_find = true;
+                break;
+            }
+        }
+        if(!is_find)
+        {
+            RLOGE("PDN numbers is max, cann't create new PDN");
+            temp_cid = INVALID_VALUE;
+        } else {
+            // for *default* type. should use interface 0 as interface id.
+            if (strstr(apnType, "default") != NULL && temp_cid != 0)
+            {
+                temp_cid = 0;
+            }
+        }
+    }
+    RLOGD("getInterfaceId apn type: %s, inteface id : %d", apnType, temp_cid);
+    return temp_cid;
+}
+
+int  setupDataCallargc(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    if(argc != 8)
+    {
+        free(pRI);
+        RLOGD("the parameters numbers isn't right , so return");
+        return -1;
+    }
+
+    char radioTechnoloy[2];
+    char profile[8]={};
+    char* apnType = argv[2];
+    if(strcasecmp(apnType, "null") == 0)
+    {
+        free(pRI);
+        RLOGD("apnType shouldn't is null");
+        return -1;
+    }
+    if(!isEnableLocalconf()) {
+        free(pRI);
+        return enableData(true, apnType);
+    }
+    for(int i =0; i < 8; i++)
+    {
+        if(apnType != NULL && strcmp(current_cid[i].apn_type, apnType) == 0)
+        {
+            free(pRI);
+            RLOGD("PDN existed, only return. type: %s",apnType);
+            return -1;
+        }
+    }
+    //cur_apn_type = apnType;
+    memset(cur_apn_type, 0, sizeof(cur_apn_type));
+    memcpy(cur_apn_type,apnType,sizeof(cur_apn_type));
+    RLOGD("cur_apn_Type is %s",cur_apn_type);
+
+    char* apn = argv[1];
+    if(strcasecmp(apn, "null") == 0)
+    {
+        free(pRI);
+        RLOGD("apn shouldn't is null");
+        return -1;
+    }
+    char* user = checkParameters(argv[3]);
+    char* password = checkParameters(argv[4]);
+    char* protocol;
+    sprintf(radioTechnoloy, "%d",get_reg_data_radio_tech(Radio_capability_switch_util::get_main_capability_phone_id()));
+
+    sprintf(profile, "%d", getApnProfileID(apnType));
+    char authtype[2];
+    if(strcasecmp(argv[5], "null") == 0)
+    {
+        int temp = (strcmp(user, "") == 0) ? SETUP_DATA_AUTH_NONE : SETUP_DATA_AUTH_PAP_CHAP;
+        sprintf(authtype, "%d", temp);
+    } else {
+        strcpy(authtype, argv[5]);
+    }
+    authtype[1] = '\0';
+    //TBD
+    if(/*getDataRoamingFromRegistration()*/ false)
+    {
+        if(strcasecmp(argv[7], "null") == 0)
+        {
+            protocol = SETUP_DATA_PROTOCOL_IPV4;
+        } else {
+            protocol = argv[7];
+        }
+    } else {
+        if(strcasecmp(argv[6], "null") == 0)
+        {
+            protocol = SETUP_DATA_PROTOCOL_IPV4;
+        } else {
+            protocol = argv[6];
+        }
+    }
+
+    if(getIntefaceId(apnType) == INVALID_VALUE)
+    {
+        free(pRI);
+        RLOGE("the PDN exsited for %s type or PDN number max", apnType);
+        return -1;
+    }
+
+    char interface_id[2] = {0};
+    sprintf(interface_id, "%d", (getIntefaceId(apnType) + 1));
+    interface_id[1] = '\0';
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    p.writeInt32(8);
+    writeStringToParcel(p,radioTechnoloy);
+    writeStringToParcel(p,profile);
+    writeStringToParcel(p,apn);
+    writeStringToParcel(p,user);
+    writeStringToParcel(p,password);
+    writeStringToParcel(p,authtype);
+    writeStringToParcel(p,protocol);
+    writeStringToParcel(p, interface_id);
+    p.setDataPosition(pos);
+    updateApntype(apnType);
+    RLOGD("setupDataCallargc: \nradioTechnoloy: %s\nprofileId: %s\napn: %s\n \
+        username: %s\npassword: %s\nauthType: %s\nprotocol %s\napnType: %s\ninterface_id: %s",radioTechnoloy,profile,apn,
+        user,password,authtype,protocol,apnType, interface_id);
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+int deactivateDataCallarc(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    if(argc != 2)
+    {
+        free(pRI);
+        RLOGD("the peremeters numbers isn't right , so return");
+        return -1;
+    }
+
+    char* apnType = argv[1];
+    if(!isEnableLocalconf()) {
+        free(pRI);
+        return enableData(false, apnType);
+    }
+    char cid[8];
+    char reason[8];
+    int temp_cid = getcid(apnType);
+    if(temp_cid == INVALID_VALUE)
+    {
+        free(pRI);
+        RLOGD("cid is invalid");
+        return -1;
+    }
+    sprintf(cid, "%d", temp_cid);
+
+    sprintf(reason,"%d",DEACTIVATE_REASON_NONE);
+
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    p.writeInt32(2);
+    writeStringToParcel(p,cid);
+    writeStringToParcel(p,reason);
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+    releaseInternetNetworkconfig(apnType);
+    destroyCid(apnType);
+    RLOGD("deactivateDataCall() done");
+    return 0;
+}
+
+int deactivateDataCall(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    if(argc == 2){
+        char* apnType = argv[1];
+        
+        return deactivateDataCallarc(argc,argv,socket_id,pRI);       
+    }
+    char cmd[256];
+    getCellularService();
+    findCellularName(line);
+    sprintf(cmd, "connmanctl disconnect %s", csname);
+    int ret = system(cmd);
+    memset(line, LEN*sizeof(char), 0);
+    memset(line, 27*sizeof(char), 0);
+    updataDataConnectState(get_default_sim_data(), false);
+    /* no response from telecore, free pRI prevent memory leak */
+    if (pRI != NULL) {
+        free(pRI);
+    }
+
+    return ret;
+}
+
+#if 0
+int apnSetting(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    //apn show add delete update
+    free(pRI);
+    if(argc < 2){
+        RLOGD("the peremeters numbers isn't right , so return");
+        return -1;
+    }
+    int ret = APN_ERR;
+    apn_list_t* g_apnlist = NULL;
+    if(strncmp(argv[1], "show", 4) == 0){
+        apn_record_t* record = apn_malloc_record();
+        apn_build_cRecord(record, APN_PROP_MCC, mcc);
+        apn_build_iRecord(record, APN_PROP_iMNC, mnc);
+        if(g_apnlist){
+            apn_free_list(g_apnlist);
+            g_apnlist = NULL;
+        }
+        apn_query_db(record, &g_apnlist);
+        RLOGD("apn list count %d\n",g_apnlist->count);
+        apn_record_t* instance = g_apnlist->top;
+        char apn_list[2048] = {0};
+        int len = 0;
+        while(instance != NULL) {
+            for (int i = 0; i < instance->count; i++) {
+                if (instance->values[i] != NULL) {
+                    if (i == (instance->count - 1)) {
+                        sprintf(apn_list+len,"%s/%s\n ",apn_get_prop_name(instance->columnIdx[i]),instance->values[i]);
+                    }else{
+                        sprintf(apn_list+len,"%s/%s; ",apn_get_prop_name(instance->columnIdx[i]),instance->values[i]);
+                    }
+                    len = strlen(apn_list);
+                }
+            }
+            instance = (apn_record_t* )instance->next;
+        }
+        apn_free_record(record);
+        android::emResultNotify(apn_list);
+        RLOGD("Apn list: /%s",apn_list);
+    }
+    if(strncmp(argv[1], "add", 3) == 0){
+        int i = 0;
+        int apnidx = APN_ERR;
+        apn_record_t* record = apn_malloc_record();
+        RLOGD("add record count = %d",(argc-2));
+        for (i = 0; i < (argc - 2 ) ; i+=2){
+            apnidx = apn_get_idx_by_name(argv[i+2]);
+            if(apnidx != APN_ERR){
+                apn_build_iRecord(record,apnidx,argv[i+3]);
+            }else{
+                RLOGD("record name [%s] is not invalid",argv[i+2]);
+            }
+        }
+        ret = apn_insert_record_db(record);
+        apn_free_record(record);
+        if(ret == -1){
+            android::emResultNotify("add apn fail.\n");
+        }else{
+            android::emResultNotify("add apn success.\n");
+        }
+    }
+    if(strncmp(argv[1], "delete", 6) == 0){
+        if(argc < 3){
+            RLOGD("the peremeters numbers isn't right , so return");
+            return -1;
+        }
+        int apnid = atoi(argv[2]);
+        RLOGD("delete id %d",apnid);
+        ret = apn_delete_record_db(apnid);
+        if(ret == -1){
+            android::emResultNotify("delete apn fail.\n");
+        }else{
+            android::emResultNotify("delete apn success.\n");
+        }
+    }
+    if(strncmp(argv[1], "update", 6) == 0){
+        if(argc < 3){
+            RLOGD("the peremeters numbers isn't right , so return");
+        }
+        int apnid = atoi(argv[2]);
+        char *updateid_str = NULL;
+        //get the select record and update it : _id
+        apn_record_t* instance = g_apnlist->top;
+        while(instance != NULL) {
+            char *value = NULL;
+            value = (char *)apn_get_prop_from_record(instance,APN_PROP_iId);
+            if(value != NULL){
+                if(apnid == atoi(value)){
+                    updateid_str = value;
+                    break;
+                }
+            }else{
+                RLOGD("warning: record has no id");
+            }
+            instance = (apn_record_t* )instance->next;
+        }
+        if(updateid_str == NULL){
+            RLOGD("the apn id(%d) is not exist in apn database, please check" ,apnid);
+            android::emResultNotify("update fail, the apn id to update is not exist in apn database");
+            return -1;
+        }
+        apn_record_t* record = apn_malloc_record();
+        int columnidx = -1;
+        apn_build_iRecord(record,APN_PROP_iId,updateid_str);
+        for(int i = 0; i < (argc - 3) ; i+=2){
+            columnidx = apn_get_idx_by_name(argv[i+3]);
+            if(columnidx != APN_ERR){
+                apn_build_iRecord(record,columnidx,argv[i+4]);
+            }else{
+                RLOGD("record name [%s] is not invalid",argv[i+2]);
+            }
+        }
+        ret = apn_update_record_db(record);
+        apn_free_record(record);
+        if(ret == -1){
+            android::emResultNotify("update apn fail.\n");
+        }else{
+            android::emResultNotify("update apn success.\n");
+        }
+    }
+
+}
+#endif
+
+int setInitialAttachApnargc(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    if(argc != 6)
+    {
+        free(pRI);
+        RLOGD("the peremeters numbers isn't right , so return");
+        return -1;
+    }
+
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    char* apn = checkParameters(argv[1]);
+    char* protocol;
+    if(strcasecmp(argv[2], "null") == 0)
+    {
+        protocol = SETUP_DATA_PROTOCOL_IPV4;
+    } else {
+        protocol = argv[2];
+    }
+    int authType = -1;
+    if(strcasecmp("null", argv[3]) != 0)
+    {
+        authType = atoi(argv[3]);
+    }
+    char* username = checkParameters(argv[4]);
+    char* password = checkParameters(argv[5]);
+    writeStringToParcel(p,apn); //apn
+    writeStringToParcel(p,protocol); //protocol
+    p.writeInt32(authType);  //authType
+    writeStringToParcel(p,username);//username
+    writeStringToParcel(p,password);//password
+    p.setDataPosition(pos);
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+int getDataCallList(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    if(argc != 1)
+    {
+        free(pRI);
+        RLOGD("the peremeters numbers isn't right , so return");
+        return -1;
+    }
+
+    android::Parcel p;
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+int getLastDataCallFailCause(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    if(argc != 1)
+    {
+        free(pRI);
+        RLOGD("the peremeters numbers isn't right , so return");
+        return -1;
+    }
+
+    android::Parcel p;
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+void updateRILDataCallResponsev6(int num ,RIL_Data_Call_Response_v6* p_cur)
+{
+    if(!isEnableLocalconf()) return;
+    data_call_num = num;
+    if(strcasecmp(cur_apn_type, "ims") == 0
+        || strcasecmp(cur_apn_type, "xcap") == 0
+        || strcasecmp(cur_apn_type, "ia") == 0)
+    {
+        RLOGD("the current apn type: %s, don't set router, so just return", cur_apn_type);
+        return;
+    }
+
+    if(data_call_response != NULL)
+    {
+        free(data_call_response);
+    }
+
+    data_call_response = (RIL_Data_Call_Response_v6 *)calloc(1, num*sizeof(RIL_Data_Call_Response_v6));
+    if(p_cur)
+    {
+        memcpy(data_call_response,p_cur, num*sizeof(RIL_Data_Call_Response_v6));
+        int j;
+        RLOGD("num: %d", num);
+        for (j = num-1; j >=0 ; j--)
+        {
+            int temp_cid = data_call_response[j].cid;
+            int k;
+            for(k = 0; k < 8 ; k++)
+            {
+                if(current_cid[k].cid == temp_cid)
+                {
+                    break;
+                }
+            }
+
+            if (k >= 8)
+            {
+                break;
+            }
+        }
+
+        RLOGD("updateRILDataCallResponsev6()... j: %d", j);
+        if(j < 0)
+        {
+            RLOGD("don't update data map_cid");
+            return;
+        }
+
+        int new_cid = data_call_response[j].cid;
+        RLOGD("updateRILDataCallResponsev6()... j: %d, new_cid: %d",j, new_cid);
+
+        for (int i = 0; i < 8 ; i++)
+        {
+            if((strcmp(current_cid[i].apn_type, "") != 0) && current_cid[i].cid == INVALID_VALUE)
+            {
+                RLOGD("update current_cid[%d]: %d", i , new_cid);
+                current_cid[i].cid = new_cid;
+                break;
+            }
+        }
+    configInterNetNetwork(cur_apn_type);
+    } else {
+        RLOGD("updateRILDataCallResponsev6 fail");
+    }
+}
+
+void handleUnsolDataCalllistChange(int num ,RIL_Data_Call_Response_v6* p_cur){
+    for(int i =0; i < 8; i++)
+    {
+        int temp_cid = current_cid[i].cid;
+        if(temp_cid != -1){
+            int j;
+            bool isContant = false;
+            for(j=0; j < num; j++){
+                if(p_cur[i].cid == temp_cid){
+                    isContant = true;
+                    break;
+                }
+            }
+            RLOGD("isContant = %d, curent_cid[%d].cid = %d", isContant, i, temp_cid);
+            if(!isContant){
+                releaseInternetNetworkconfig(current_cid[i].apn_type);
+                destroyCid(current_cid[i].apn_type);
+            }
+        }
+    }
+}
+
+static int getApntypeBitmask(const char *type)
+{
+    struct apntype_2_bitmask  apntypebitmask[] = {
+            {TEXT_APN_TYPE_DEFAULT,DATAASST_PDN_APN_TYPE_DEFAULT},
+            {TEXT_APN_TYPE_IMS,DATAASST_PDN_APN_TYPE_IMS},
+            {TEXT_APN_TYPE_MMS,DATAASST_PDN_APN_TYPE_MMS},
+            {TEXT_APN_TYPE_SUPL,DATAASST_PDN_APN_TYPE_SUPL},
+            {TEXT_APN_TYPE_DUN,DATAASST_PDN_APN_TYPE_DUN},
+            {TEXT_APN_TYPE_HIPRI,DATAASST_PDN_APN_TYPE_HIPRI},
+            {TEXT_APN_TYPE_FOTA,DATAASST_PDN_APN_TYPE_FOTA},
+            {TEXT_APN_TYPE_CBS,DATAASST_PDN_APN_TYPE_CBS},
+            {TEXT_APN_TYPE_EMERGENCY,DATAASST_PDN_APN_TYPE_EMERGENCY},
+            {TEXTAPN_TYPE_IA,DATAASST_PDN_APN_TYPE_IA},
+#if !(defined(TARGET_PLATFORM_MT2731))
+            {TEXT_APN_TYPE_DM,DATAASST_PDN_APN_TYPE_DM},
+#endif
+            {TEXT_APN_TYPE_WAP,DATAASST_PDN_APN_TYPE_WAP},
+#if !(defined(TARGET_PLATFORM_MT2731))
+            {TEXT_APN_TYPE_NET,DATAASST_PDN_APN_TYPE_NET},
+            {TEXT_APN_TYPE_CMMAIL,DATAASST_PDN_APN_TYPE_CMMAIL},
+            {TEXT_APN_TYPE_TETHERING,DATAASST_PDN_APN_TYPE_TETHERING},
+            {TEXT_APN_TYPE_RCSE,DATAASST_PDN_APN_TYPE_RCSE},
+#endif
+            {TEXT_APN_TYPE_XCAP,DATAASST_PDN_APN_TYPE_XCAP},
+            {TEXT_APN_TYPE_RCS,DATAASST_PDN_APN_TYPE_RCS},
+            {IOT_TEXT_APN_TYPE_DEFAULT ,IOT_DATAASST_PDN_APN_TYPE_DEFAULT}, //for IOT
+            {IOT_TEXT_APN_TYPE_NET_0 ,IOT_DATAASST_PDN_APN_TYPE_NET_0},//for IOT
+            {IOT_TEXT_APN_TYPE_NET_1 ,IOT_DATAASST_PDN_APN_TYPE_NET_1},//for IOT
+            {IOT_TEXT_APN_TYPE_NET_2 ,IOT_DATAASST_PDN_APN_TYPE_NET_2},//for IOT
+            {IOT_TEXT_APN_TYPE_NET_3 ,IOT_DATAASST_PDN_APN_TYPE_NET_3},//for IOT
+            {IOT_TEXT_APN_TYPE_NET_4 ,IOT_DATAASST_PDN_APN_TYPE_NET_4},//for IOT
+            {IOT_TEXT_APN_TYPE_NET_5 ,IOT_DATAASST_PDN_APN_TYPE_NET_5},//for IOT
+            {IOT_TEXT_APN_TYPE_NET_6 ,IOT_DATAASST_PDN_APN_TYPE_NET_6},//for IOT
+    };
+    int len = sizeof(apntypebitmask)/sizeof(apntype_2_bitmask);
+    for(int i = 0; i < len ; i++){
+        if(strcasecmp(type,apntypebitmask[i].type) == 0)
+            return apntypebitmask[i].typebitmask;
+     }
+    return DATAASST_PDN_APN_TYPE_UNKNOWN;
+}
+
+static int check_is_number(char* str) {
+    if(utils::is_number(str)){
+        return atoi(str);
+    } else {
+        return INVALID;
+    }
+}
+
+//RIL_REQUEST_SET_DATA_PROFILE
+int setDataProfile(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    int count = check_is_number(argv[1]);
+    if(count == INVALID) {
+        free(pRI);
+        printf("the peremeters count(%s) isn't invalid , so return\n", argv[1]);
+        RLOGD("the peremeters count(%s) isn't invalid , so return", argv[1]);
+        return -1;
+    }
+
+    if((argc-2) != 11*count) {
+        free(pRI);
+        printf("the peremeters numbers isn't right , so return\n");
+        RLOGD("the peremeters numbers isn't right , so return");
+        return -1;
+    }
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    p.writeInt32(count); //profileId
+    for (int i=2; i < argc; i++) {
+        int profileId = 0;
+        std::vector<std::string> v;
+        utils::tokenize(std::string(argv[i]),',',v);
+        int index = 0;
+        for(auto s: v) {
+            RLOGD("%d:%s",index, s.c_str());
+            profileId  |= getApntypeBitmask(s.c_str());
+            index++;
+        }
+        p.writeInt32(profileId); //profileId
+        char* apn = checkParameters(argv[i+1]);
+        writeStringToParcel(p,apn); //apn
+        char* protocol;
+        if(strcasecmp(argv[i+2], "null") == 0)
+        {
+            protocol = SETUP_DATA_PROTOCOL_IPV4V6;
+        } else {
+            protocol = argv[i+2];
+        }
+        writeStringToParcel(p,protocol); //protocol
+        int authType = -1;
+        if((strcasecmp("null", argv[i+3]) != 0) && (strcasecmp("-1", argv[i+3]) != 0))
+        {
+            authType = check_is_number(argv[i+3]);
+            if (authType == INVALID) {
+                free(pRI);
+                printf("the peremeters authType(%s) isn't invalid , so return\n", argv[i+3]);
+                return -1;
+            }
+        }
+        p.writeInt32(authType);  //authType
+        char* username = checkParameters(argv[i+4]);
+        writeStringToParcel(p,username);//username
+        char* password = checkParameters(argv[i+5]);
+        writeStringToParcel(p,password);//password
+        int type = check_is_number(argv[i+6]);
+        if(type == INVALID) {
+            free(pRI);
+            printf("the peremeters type(%s) isn't invalid , so return\n", argv[i+6]);
+            RLOGD("the peremeters type(%s) isn't invalid , so return", argv[i+6]);
+            return -1;
+        }
+        p.writeInt32(type);  //type
+        int maxConnsTime = check_is_number(argv[i+7]);
+        if(maxConnsTime == INVALID) {
+            free(pRI);
+            printf("the peremeters maxConnsTime(%s) isn't invalid , so return\n", argv[i+7]);
+            RLOGD("the peremeters maxConnsTime(%s) isn't invalid , so return", argv[i+7]);
+            return -1;
+        }
+        p.writeInt32(maxConnsTime);  //maxConnsTime
+        int maxConns = check_is_number(argv[i+8]);
+        if(maxConns == INVALID) {
+            free(pRI);
+            printf("the peremeters maxConns(%s) isn't invalid , so return\n", argv[i+8]);
+            RLOGD("the peremeters maxConns(%s) isn't invalid , so return", argv[i+8]);
+            return -1;
+        }
+        p.writeInt32(maxConns);  //maxConns
+        int waitTime = check_is_number(argv[i+9]);
+        if(waitTime == INVALID) {
+            free(pRI);
+            printf("the peremeters waitTime(%s) isn't invalid , so return\n", argv[i+9]);
+            RLOGD("the peremeters waitTime(%s) isn't invalid , so return", argv[i+9]);
+            return -1;
+        }
+        p.writeInt32(waitTime);  //waitTime
+        int enabled = check_is_number(argv[i+10]);
+        if(enabled == INVALID) {
+            free(pRI);
+            printf("the peremeters enabled(%s) isn't invalid , so return\n", argv[i+10]);
+            RLOGD("the peremeters enabled(%s) isn't invalid , so return", argv[i+10]);
+            return -1;
+        }
+        p.writeInt32(enabled);  //enabled
+        RLOGD("index=%d",i);
+        i = i+10;
+    }
+    p.setDataPosition(pos);
+
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+/**
+* RIL_REQUEST_SYNC_DATA_SETTINGS_TO_MD
+*
+* Set data features.
+ * The domestic roaming/international roaming should not set with roaming in the same project.
+* The default data SIM should not set by this RIL request directly
+*
+* "data" is const int *
+* ((const int*)data)[0] specify if data enable or not,-2 means skip this setting.
+* ((const int*)data)[1] specify the roaming setting, -2 means skip this setting.
+* ((const int*)data)[2] specify the default data sim, -2 means skip this setting.
+* ((const int*)data)[3] specify the domestic roaming setting, -2 means skip this setting.
+* ((const int*)data)[4] specify the international roaming setting, -2 means skip this setting.
+*
+* "response" is the NULL.
+*
+* Valid errors:
+* SUCCESS
+* GENERIC_FAILURE
+*/
+int syncDataSettingsToMd(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if (argc != 6){
+        RLOGD("syncDataSettingsToMd parameters  number isn't enough");
+        free(pRI);
+        return -1;
+    }
+    int32_t data_enable = std::stoi(argv[1]);
+    int32_t roaming = std::stoi(argv[2]);
+    int32_t default_data = std::stoi(argv[3]);
+    int32_t domes_roa = std::stoi(argv[4]);
+    int32_t inter_roa = std::stoi(argv[5]);
+    RLOGD("syncDataSettingsToMd  data_enable=%d, roaming=%d, default_data=%d, domes_roa=%d inter_roa=%d",
+            data_enable, roaming, default_data, domes_roa, inter_roa);
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    p.writeInt32(5);
+    p.writeInt32(data_enable);
+    p.writeInt32(roaming);
+    p.writeInt32(default_data);
+    p.writeInt32(domes_roa);
+    p.writeInt32(inter_roa);
+
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+int syncDataSettings(RIL_SOCKET_ID socket_id) {
+    char* slotID = "1";
+    if(socket_id == 0) {
+        slotID = "0";
+    }
+    char* tmp[6] = {"RIL_REQUEST_SYNC_DATA_SETTINGS_TO_MD", "-2", "-2", slotID, "-2", "-2"};
+    RequestInfo *pRI = creatRILInfoAndInit(RIL_REQUEST_SYNC_DATA_SETTINGS_TO_MD, OTHER, socket_id);
+    if(pRI == NULL) return -1;
+    syncDataSettingsToMd(6,tmp,socket_id,pRI);
+    return 0;
+}
+
+int modifyApnRecord(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    free(pRI);
+    if (argc < 3){
+        RLOGD("%s parameters  number isn't enough", __FUNCTION__);
+        return -1;
+    }
+    RLOGD("%s,cmd:%s,record:%s", __FUNCTION__,argv[1],argv[2]);
+    int cmd = std::stoi(argv[1]);
+    char* record = argv[2];
+    modifyApnDB(cmd, record);
+    return 0;
+}
+
+int resetApnRecord(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    RLOGD("%s", __FUNCTION__);
+    free(pRI);
+    resetApnDB();
+    return 0;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/data/data.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/data/data.h
new file mode 100644
index 0000000..657f8be
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/data/data.h
@@ -0,0 +1,59 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#ifndef YOCTO_DATA_H
+#define YOCTO_DATA_H 1
+
+#include <vendor-ril/telephony/ril.h>
+#include  "common.h"
+
+int setDataAllowed(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setupDataCallargc(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setupDataCall(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int deactivateDataCall(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setInitialAttachApn(RequestInfo *pRI);
+int setDataProfilesAsNeeded(RequestInfo *pRI);
+int setInitialAttachApnargc(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int apnSetting(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int getApnDbIms();
+void updateRILDataCallResponsev6(int num ,RIL_Data_Call_Response_v6* p_cur);
+int getDataCallList(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int getLastDataCallFailCause(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+void handleUnsolDataCalllistChange(int num ,RIL_Data_Call_Response_v6* p_cur);
+int setDataProfile(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int syncDataSettingsToMd(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int syncDataSettings(RIL_SOCKET_ID socket_id);
+int modifyApnRecord(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int resetApnRecord(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+#endif
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/data/data_gdbus.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/data/data_gdbus.cpp
new file mode 100644
index 0000000..7f4e27d
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/data/data_gdbus.cpp
@@ -0,0 +1,290 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include <unistd.h>
+#include <string.h>
+#include <log/log.h>
+#include <vendor-ril/telephony/ril.h>
+extern "C" {
+#include <gio/gio.h>
+#include <glib.h>
+}
+
+#include "common.h"
+
+#define LOG_TAG "DEMO_DATA_GDBUS"
+#define TELEPHONY_SERVICE "mtk.telephony" /*well-known bus name */
+#define TELEPHONY_DATA_INTERFACE "mtk.telephony.Data" /*interface name*/
+#define TELEPHONY_DATA_PATH "/mtk/telephony/data" /*object name*/
+
+GMainLoop *loop = NULL;
+GDBusProxy *proxy = NULL;
+MTK_Data_Call_Response_v1 req_response;
+MTK_Data_Call_Response_v1 urc_response;
+
+void freeMem(MTK_Data_Call_Response_v1 response)
+{
+    g_free(response.apnType);
+    g_free(response.type);
+    g_free(response.ifname);
+    g_free(response.addresses);
+    g_free(response.dnses);
+    g_free(response.gateways);
+    g_free(response.pcscf);
+}
+
+char* apnState2string(RIL_Data_Call_PdnState apnState) {
+    switch (apnState) {
+    case RIL_Data_Call_PdnState::PDN_CONNECTED:
+        return "PDN_CONNECTED";
+    case RIL_Data_Call_PdnState::PDN_CONNECTING:
+        return "PDN_CONNECTING";
+    case RIL_Data_Call_PdnState::PDN_DISCONNECTED:
+        return "PDN_DISCONNECTED";
+    case RIL_Data_Call_PdnState::PDN_DISCONNECTING:
+        return "PDN_DISCONNECTING";
+    case RIL_Data_Call_PdnState::PDN_FAILED:
+        return "PDN_FAILED";
+    case RIL_Data_Call_PdnState::PDN_IDLE:
+        return "PDN_IDLE";
+    case RIL_Data_Call_PdnState::PDN_RETRYING:
+        return "PDN_RETRYING";
+    case RIL_Data_Call_PdnState::PDN_SCANNING:
+        return "PDN_SCANNING";
+    default:
+        return "UNKNOWN";
+    }
+}
+
+void dumpResponse(MTK_Data_Call_Response_v1 *dataCallResponse)
+{
+    RLOGD("dumpResponse: netId: %d, pdnState: %s, status: %d, cId: %d, apnType: %s,"
+            " protocolType: %s, ifaceName: %s, address: %s, dns: %s, gateway: %s, pcscf: %s, mtu: %d, apn: %s",
+            dataCallResponse->netId, apnState2string(RIL_Data_Call_PdnState(dataCallResponse->pdnState)),
+            dataCallResponse->status, dataCallResponse->cId, dataCallResponse->apnType, dataCallResponse->type,
+            dataCallResponse->ifname, dataCallResponse->addresses, dataCallResponse->dnses,
+            dataCallResponse->gateways, dataCallResponse->pcscf, dataCallResponse->mtu, dataCallResponse->apnName);
+}
+
+void parse(GVariant* result, MTK_Data_Call_Response_v1* data) {
+    g_variant_get(result, "((iiiisssssssis))", &(data->netId),
+            &(data->pdnState), &(data->status),
+            &(data->cId), &(data->apnType), &(data->type),
+            &(data->ifname), &(data->addresses),
+            &(data->dnses), &(data->gateways),
+            &(data->pcscf), &(data->mtu),&(data->apnName));
+}
+
+void proxy_method_cb (GDBusProxy   *proxy,
+                                      GAsyncResult *res,
+                                      gpointer      user_data)
+{
+    RLOGD("method call back");
+    GError *error;
+    GVariant *result;
+
+    error = NULL;
+    result = g_dbus_proxy_call_finish(proxy, res, &error);
+
+    if(error != NULL)
+    {
+        RLOGD("method call back error %s", error->message);
+        g_error_free(error);
+        return;
+    }
+    freeMem(req_response);
+    parse(result, &req_response);
+    dumpResponse(&req_response);
+    g_variant_unref(result);
+}
+
+int enableData (bool isEnable, gchar *apn_type)
+{
+    RLOGD("send: %s, %s", (isEnable ? "TRUE": "FALSE"), apn_type);
+    g_dbus_proxy_call(proxy,
+            "enableData",
+            g_variant_new("(bs)", isEnable, apn_type),
+            G_DBUS_CALL_FLAGS_NONE,
+            -1,
+            NULL,
+            (GAsyncReadyCallback) proxy_method_cb,
+            NULL);
+    return 1;
+}
+
+void modifyApnDB_method_cb (GDBusProxy   *proxy,
+                                      GAsyncResult *res,
+                                      gpointer      user_data)
+{
+    RLOGD("method call back");
+    GError *error;
+    GVariant *result;
+    gchar* reason = NULL;
+
+    error = NULL;
+    result = g_dbus_proxy_call_finish(proxy, res, &error);
+
+    if(error != NULL)
+    {
+        RLOGD("method call back error %s", error->message);
+        printf("modify apn db error: %s\n", error->message);
+        g_error_free(error);
+        return;
+    }
+    //reason = const_cast<gchar*>(g_variant_dup_string(result, NULL));
+    g_variant_get (result, "(&s)", &reason);
+    RLOGD("modifyApnDB_method_cb reason %s", ((reason == NULL)? "":reason));
+    printf("modify apn db success, return message: %s\n", ((reason == NULL)? "":reason));
+    //printf("modifyApnDB_method_cb reason %s\n", ((reason == NULL)? "":reason));
+    g_variant_unref(result);
+}
+
+int modifyApnDB(int cmd, gchar *record) {
+    RLOGD("%s: cmd: %d, record:%s", __FUNCTION__, cmd, record);
+    g_dbus_proxy_call(proxy,
+            "modifyApnDB",
+            g_variant_new("(is)", cmd, record),
+            G_DBUS_CALL_FLAGS_NONE,
+            -1,
+            NULL,
+            (GAsyncReadyCallback) modifyApnDB_method_cb,
+            NULL);
+    return 1;
+}
+
+void resetApnDB_method_cb (GDBusProxy   *proxy,
+                                      GAsyncResult *res,
+                                      gpointer      user_data)
+{
+    RLOGD("resetApnDB_method_cb call back");
+    GError *error;
+    GVariant *result;
+    gchar* reason = NULL;
+
+    error = NULL;
+    result = g_dbus_proxy_call_finish(proxy, res, &error);
+
+    if(error != NULL)
+    {
+        RLOGD("method call back error %s", error->message);
+        printf("reset apn DB error: %s\n", error->message);
+        g_error_free(error);
+        return;
+    }
+    g_variant_get (result, "(&s)", &reason);
+    //reason = const_cast<gchar*>(g_variant_dup_string(result, NULL));
+    RLOGD("resetApnDB_method_cb reason %s", ((reason == NULL)? "":reason));
+    printf("reset apn DB success, return message: %s\n", ((reason == NULL)? "":reason));
+    //printf("resetApnDB_method_cb reason %s\n", ((reason == NULL)? "":reason));
+    g_variant_unref(result);
+}
+
+int resetApnDB() {
+    RLOGD("%s", __FUNCTION__);
+    g_dbus_proxy_call(proxy,
+            "resetApnDB",NULL,
+            G_DBUS_CALL_FLAGS_NONE,
+            -1,
+            NULL,
+            (GAsyncReadyCallback) resetApnDB_method_cb,
+            NULL);
+    return 1;
+}
+
+void proxy_signals_on_signal (GDBusProxy  *proxy,
+                              const gchar *sender_name,
+                              const gchar *signal_name,
+                              GVariant    *parameters,
+                              gpointer     user_data)
+{
+    RLOGD("signal_name: %s", signal_name);
+    freeMem(urc_response);
+    parse(parameters, &urc_response);
+    dumpResponse(&urc_response);
+
+    if(g_strcmp0(signal_name, "default") == 0)
+    {
+        if(urc_response.pdnState == RIL_Data_Call_PdnState::PDN_DISCONNECTED) {
+            notifyDataSignal();
+        }
+    }
+
+}
+
+void proxy_ready(GObject *source, GAsyncResult *result, gpointer user_data) {
+    GError *error;
+
+    error = NULL;
+    proxy = g_dbus_proxy_new_for_bus_finish(result, &error);
+    if (proxy == NULL) {
+        RLOGE("create proxy fail");
+        return ;
+    }
+    RLOGD("proxy is ready");
+    gulong signal_handler_id;
+
+    signal_handler_id = g_signal_connect(proxy, "g-signal",
+            G_CALLBACK (proxy_signals_on_signal), NULL);
+    if (signal_handler_id == 0) {
+        RLOGE("listen singal fail!");
+    }
+}
+
+void* init_data_gdbus_cb(void *param)
+{
+    /* all the tests rely on a shared main loop */
+    loop = g_main_loop_new(NULL, FALSE);
+
+    g_dbus_proxy_new_for_bus(G_BUS_TYPE_SYSTEM,
+            G_DBUS_PROXY_FLAGS_NONE,
+            NULL, /* GDBusInterfaceInfo */
+            TELEPHONY_SERVICE, /* name */
+            TELEPHONY_DATA_PATH, /* object path */
+            TELEPHONY_DATA_INTERFACE, /* interface */
+            NULL, /* GCancellable */
+            proxy_ready,
+            NULL);
+
+    g_main_loop_run(loop);
+
+    RLOGD("data gdbus main loop run()");
+    if(proxy != NULL) {
+        g_object_unref (proxy);
+    }
+    if(loop != NULL) {
+        g_main_loop_unref(loop);
+    }
+}
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/data/data_gdbus.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/data/data_gdbus.h
new file mode 100644
index 0000000..a6928ea
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/data/data_gdbus.h
@@ -0,0 +1,45 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+
+#ifndef FILES_DATA_GDBUS_H_
+#define FILES_DATA_GDBUS_H_
+#include <gio/gio.h>
+#include <glib.h>
+int enableData (bool isEnalbe, gchar *apn_type);
+int modifyApnDB(int cmd, gchar *record);
+int resetApnDB();
+void* init_data_gdbus_cb(void *param);
+#endif /* FILES_DATA_GDBUS_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/eCall.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/eCall.cpp
new file mode 100644
index 0000000..48db868
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/eCall.cpp
@@ -0,0 +1,1306 @@
+//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) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include "ecall/eCall.h"
+
+#include <vendor-ril/telephony/ril.h>
+#include <string>
+#include <vector>
+#include <glib.h>
+#include <cutils/jstring.h>
+#include <time.h>
+#include <signal.h>
+#include <pthread.h>
+#include <string.h>
+#include <memory>
+
+#include "util/utils.h"
+#include "cc.h"
+#include "common.h"
+#include "sms/sms.h"
+#include "sms/gsm/sms_pdu.h"
+#include "./gost/utils/GostEcallUtils.h"
+#include "./gost/sslp/SslpManager.h"
+#include "./gost/sslp/ecall/EcallUtils.h"
+#include "network.h"
+
+#undef LOG_TAG
+#define LOG_TAG "DEMO_ECALL"
+#define PROP_ECALL_TEST_CASE "vendor.gost.ecall.ecall_case_test"
+#define PROP_ECALL_DEREGIST_TIME "vendor.gost.ecall.nad_deregistration_time_minute"
+#define PROP_ECALL_REDIAL_TIMER "vendor.ecall.redial.timer" //default 120s
+
+int fast_argc = 0;
+std::vector<std::string> fast_argv;
+int fast_ecall_socket_id = -1;
+static ECALL_TYPE ecall_type = ECALL_TYPE::EN16454_ECALL;
+static bool inNeedRegister = false;
+static bool gostFastEcallFlg = false;
+static bool is_ecall_audio_path = false;
+
+int gost_sms_argc = 0;
+std::vector<std::string> gost_sms_argv;
+int gost_sms_socket_id = -1;
+
+typedef enum {
+    REDIAL_DOING = 1,
+    REDIAL_SUCCESS = 2,
+    REDIAL_EXPIRES = 3,
+    REDIAL_UNKNOWN = 4,
+}ecall_redial_status;
+
+int act_fecall_socid = -1;
+int act_feCall_Id = -1;
+static ecall_redial_status redial_tag = REDIAL_UNKNOWN;
+static bool normal_ecall_tag = false;
+
+#ifdef ECALL_SUPPORT
+extern speech_status getSpeechStatus();
+extern void setSpeechAndStatus(int value);
+int resetIVS(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int dialFastEcall(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+void start_ecll_timer(timer_t timer, int signal_value, int milliseconds);
+//RIL_REQUEST_ECALL_SET_MSD
+int setMSD(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int T7GostEcallSmsMsd(sigval_t sig);
+int setNadRegState(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int gostStartDeregisterTimer();
+
+static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
+//#define PROP_ECALL_MSD_DATA "vendor.ecall.msd.data"
+static char* msd_data = NULL;
+
+//LOCAL_SET_MSD_DATA_FOR_TEST
+int setMsdDateForTest(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if (argc < 1 || argv[1] == NULL) {
+        RLOGD("setMsdDateForTest invalid parameters");
+        free(pRI);
+        return -1;
+    }
+    char *msd_data_src = (char*) argv[1];
+    int len = strlen(msd_data_src);
+
+    if (len % 2 == 1) {
+        RLOGD("setMsdDateForTest invalid parameters, length is't right");
+        free(pRI);
+        return -1;
+    }
+    if(msd_data) {
+        free(msd_data);
+        msd_data = NULL;
+    }
+    msd_data = strdup(msd_data_src);
+    RLOGD("setMsdDateForTest() data: %s", (msd_data == NULL ? "": msd_data));
+    return 0;
+}
+
+static timer_t sT2;
+static timer_t sT5;
+static timer_t sT6;
+static timer_t sT7;
+static timer_t sRedialTimer;
+static timer_t sAutoAnsTimer;
+static timer_t gostResendMsdTimer;
+static timer_t gostDeregistrationTimer;
+
+#define T2_TIMEOUT 60*60*1000
+#define T5_TIMEOUT 5*1000
+#define T6_TIMEOUT 5*1000
+#define T7_TIMEOUT 20*1000
+//#define REDIAL_TIMEOUT 2*60*1000
+#define AUTOANS_TIMEOUT 60*60*1000
+
+static int sT2_sig_value = 2;
+static int sT5_sig_value = 5;
+static int sT6_sig_value = 6;
+static int sT7_sig_value = 7;
+static int redial_sig_value = 8;
+static int autoAns_sig_value = 9;
+static int gost_resend_msd_value = 11;
+static int gost_deregistration_value = 12;
+
+bool isEcallAudioPath() {
+    RLOGD("%s , is_ecall_audio_path: %d", __FUNCTION__, is_ecall_audio_path);
+    return is_ecall_audio_path;
+}
+
+bool isEcallAutoanswerTimerFinish() {
+    struct itimerspec timespec;
+    if(timer_gettime(sAutoAnsTimer, &timespec) == -1) {
+        RLOGD("%s(), get time fail(%s)", __FUNCTION__, strerror(errno));
+        return true;
+    }
+    RLOGD("%s(), 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(), timer_id(%ld) had stopped", __FUNCTION__, (long)sAutoAnsTimer);
+        return true;
+    }
+    return false;
+}
+
+void setEcallAudioPathOn(bool on) {
+    RLOGD("%s() , is_ecall_audio_path: %d, on: %d", __FUNCTION__, is_ecall_audio_path, on);
+
+    if((is_ecall_audio_path != on) && (isEcallAutoanswerTimerFinish())) {
+        is_ecall_audio_path = on;
+    }
+    RLOGD("%s() , is_ecall_audio_path: %d", __FUNCTION__, is_ecall_audio_path);
+}
+
+void autoAnswerEcall(bool on) {
+    RLOGD("%s() , is_ecall_audio_path: %d, on: %d", __FUNCTION__, is_ecall_audio_path, on);
+    if(is_ecall_audio_path != on) {
+        is_ecall_audio_path = on;
+    }
+    if(on) {
+        char* argv[2] = {"", "1"};
+        autoAnswerCall(2, argv, RIL_SOCKET_ID(0), NULL); //unused socket id;
+    } else {
+        char* argv[2] = {"", "0"};
+        autoAnswerCall(2, argv, RIL_SOCKET_ID(0), NULL); //unused socket id;
+    }
+}
+
+void saveFastEcallData(int argc, char** argv ,RIL_SOCKET_ID id) {
+    fast_ecall_socket_id = id;
+    fast_argc = argc;
+    fast_argv.clear();
+    for(int i = 0; i < argc; i++) {
+        RLOGD("fast_argv[%d] = %s", i, (argv[i]==NULL)? "NULL":argv[i]);
+        fast_argv.push_back(argv[i]);
+    }
+}
+
+void resetEcallIVSandAudio(int mode, RIL_SOCKET_ID id) {
+    RequestInfo* pRI = creatRILInfoAndInit(RIL_REQUEST_ECALL_RESET_IVS, mode, id);
+    resetIVS(0, NULL, id, pRI);
+//    char* argv[2] = { "RIL_REQUEST_SET_MUTE", "0" };
+//    setMute(2, argv, id, NULL);
+}
+
+void ecall_timer_handler(sigval_t sig) {
+    RLOGD("ecall_timer_handler, sig_value: %d", sig.sival_int);
+    int s;
+    s = pthread_mutex_lock(&mtx);
+    if(s != 0) {
+        RLOGE("ecall_timer_handler, pthead_mutex_lock fail");
+    }
+    if(sig.sival_int == sT2_sig_value) {
+        RLOGD("T2 timeout, call_Id=%d, socket_id=%d", act_feCall_Id, act_fecall_socid);
+        if(act_feCall_Id == -1 || act_fecall_socid == -1) {
+            goto done;
+        }
+        RequestInfo* pRI = creatRILInfoAndInit(RIL_REQUEST_HANGUP, UDP, RIL_SOCKET_ID(act_fecall_socid));
+        char* id = const_cast<char*>(std::to_string(act_feCall_Id).c_str());
+        char* argv[2] = { "RIL_REQUEST_HANGUP", "" };
+        argv[1] = id;
+        hangupConnection(2, argv, RIL_SOCKET_ID(act_fecall_socid), pRI);
+        act_fecall_socid = -1;
+        act_feCall_Id = -1;
+    } else if(sig.sival_int == sT5_sig_value
+            || sig.sival_int == sT6_sig_value
+            || sig.sival_int == sT7_sig_value) {
+        normal_ecall_tag = false;
+        resetEcallIVSandAudio(UDP, RIL_SOCKET_ID(fast_ecall_socket_id));
+        if(0 != T7GostEcallSmsMsd(sig))
+        {
+            if(sig.sival_int == sT5_sig_value || sig.sival_int == sT7_sig_value) {
+                fast_argc = 0;
+                fast_argv.clear();
+            }
+        }
+    } else if(sig.sival_int == redial_sig_value) {
+        redial_tag = REDIAL_EXPIRES;
+        RequestInfo* pRI = creatRILInfoAndInit(RIL_REQUEST_ECALL_RESET_IVS, UDP,RIL_SOCKET_ID(fast_ecall_socket_id));
+        resetIVS(0, NULL, RIL_SOCKET_ID(fast_ecall_socket_id), pRI);
+        fast_argc = 0;
+        fast_argv.clear();
+        start_ecll_timer(sAutoAnsTimer, autoAns_sig_value, AUTOANS_TIMEOUT);
+        autoAnswerEcall(true);
+    } else if(sig.sival_int == autoAns_sig_value) {
+        autoAnswerEcall(false);
+    } else if(sig.sival_int == gost_resend_msd_value) {
+        //send msd
+        char** argv = new char*[gost_sms_argv.size()];
+        argv[gost_sms_argv.size()] = nullptr;
+        for(int i=0; i < gost_sms_argv.size(); i++) {
+            char* temp = new char[gost_sms_argv[i].size()];
+            strcpy(temp, gost_sms_argv[i].c_str());
+            argv[i] = temp;
+        }
+
+        RequestInfo *pRI = creatRILInfoAndInit(RIL_REQUEST_SEND_SMS, UDP, (RIL_SOCKET_ID)gost_sms_socket_id);
+        sendSMS(gost_sms_argc, argv, pRI->socket_id, pRI);
+
+        for(int i=0; i < gost_sms_argv.size(); i++) {
+            delete argv[i];
+        }
+        delete argv;
+    } else if(sig.sival_int == gost_deregistration_value) {
+        RIL_SOCKET_ID id = (RIL_SOCKET_ID)fast_ecall_socket_id;
+        if(id == -1) {
+            id = (RIL_SOCKET_ID)get_default_sim_all_except_data();
+        }
+        RequestInfo* pRI = creatRILInfoAndInit(RIL_REQUEST_ECALL_SET_REGISTRATION_STATE, UDP, id);
+        char* argv[2] = { "RIL_REQUEST_ECALL_SET_REGISTRATION_STATE", "0" };
+        setNadRegState(2, argv, id, pRI);
+    }
+    else {
+        RLOGE("ecall_timer_handler, sig_value is invalid!");
+    }
+done:
+    s = pthread_mutex_unlock(&mtx);
+    if(s != 0) {
+        RLOGE("ecall_timer_handler, pthread_mutex_unlock fail");
+    }
+
+}
+
+void init_ecall_timer(timer_t* timer, int signal_value) {
+
+    struct sigevent sevp;
+    memset(&sevp, 0, sizeof(sevp));
+    sevp.sigev_value.sival_int = signal_value;
+    sevp.sigev_notify = SIGEV_THREAD;
+    sevp.sigev_notify_function = ecall_timer_handler;
+
+    if(timer_create(CLOCK_MONOTONIC, &sevp, timer) == -1) {
+        RLOGE("init_ecall_timer()  failed reason=[%s]", strerror(errno));
+    }
+    RLOGD("init_ecall_timer(), timer_Id = %ld, signal_value=%d", (long)(*timer), signal_value);
+}
+
+void init_ecall_timer_all() {
+    init_ecall_timer(&sT2,sT2_sig_value);
+    init_ecall_timer(&sT5,sT5_sig_value);
+    init_ecall_timer(&sT6,sT6_sig_value);
+    init_ecall_timer(&sT7,sT7_sig_value);
+    init_ecall_timer(&sRedialTimer,redial_sig_value);
+    init_ecall_timer(&sAutoAnsTimer,autoAns_sig_value);
+    init_ecall_timer(&gostResendMsdTimer,gost_resend_msd_value);
+    init_ecall_timer(&gostDeregistrationTimer, gost_deregistration_value);
+}
+
+void start_ecll_timer(timer_t timer, int signal_value, int milliseconds) {
+    RLOGD("start_ecll_timer(), timer_id=%ld, signal_value=%d, time=%d",(long)timer, signal_value, milliseconds);
+
+    struct itimerspec expire;
+    expire.it_interval.tv_sec = 0;
+    expire.it_interval.tv_nsec = 0;
+    expire.it_value.tv_sec = milliseconds/1000;
+    expire.it_value.tv_nsec = (milliseconds%1000)*1000000;
+    if (timer_settime(timer, 0, &expire, NULL) == -1) {
+        RLOGE("timer_settime  failed reason=[%s]", strerror(errno));
+    }
+}
+
+void stop_ecall_timer(timer_t timer, int signal_value) {
+    RLOGD("stop_ecall_timer(), timer_id=%ld, signal_value=%d", (long)timer, signal_value);
+    struct itimerspec timespec;
+    if(timer_gettime(timer, &timespec) == -1) {
+        RLOGD("stop_ecall_timer(), get time fail(%s)", strerror(errno));
+        return;
+    }
+    RLOGD("stop_ecall_timer(), tv_sec=%ld, tv_nsec=%ld",timespec.it_value.tv_sec, timespec.it_value.tv_nsec);
+    if((timespec.it_value.tv_sec == 0)  && (timespec.it_value.tv_nsec == 0) ) {
+        RLOGD("stop_ecall_timer(), timer_id(%ld) had stopped, just return", (long)timer);
+        return;
+    } else {
+        start_ecll_timer(timer, signal_value, 0);
+    }
+}
+
+void saveEcallRecord(RIL_ECall_Indication ind) {
+    std::string str;
+    if(ind == RIL_UNSOL_ECALL_ALACK_POSITIVE_RECEIVED) {
+        str = "ECALL_ALACK_POSITIVE_RECEIVED";
+    } else if(ind == RIL_UNSOL_ECALL_ALACK_CLEARDOWN_RECEIVED) {
+        str = "ECALL_ALACK_CLEARDOWN_RECEIVED";
+    } else {
+        str = "";
+    }
+    struct timespec real;
+    clock_gettime(CLOCK_REALTIME, &real);
+    RLOGD("saveEcallRecord(%s) tv_s:%ld, tv_ns:%ld",str.c_str(), real.tv_sec, real.tv_nsec);
+    char utc_time[100]={0};
+    strftime(utc_time, sizeof(utc_time), "%D %T", gmtime(&real.tv_sec));
+    printf("saveEcallRecord, %s,UTC: data_time=%ld\n", str.c_str(),utc_time);
+    RLOGD("saveEcallRecord, %s,UTC: data_time=%ld", str.c_str(),utc_time);
+    char local_time[100]={0};
+    struct tm t;
+    strftime(local_time, sizeof(local_time), "%D %T", localtime_r(&real.tv_sec, &t));
+    printf("saveEcallRecord, %s,local: data_time=%ld\n", str.c_str(),local_time);
+    RLOGD("saveEcallRecord, %s,UTC: data_time=%ld", str.c_str(),utc_time);
+}
+
+void redialFastEcall(RIL_SOCKET_ID socket_id) {
+    if(isGostEcall())
+    {
+        RLOGD("gost ecall redialFastEcall return for test");
+        return;
+    }
+    RequestInfo* pRI = creatRILInfoAndInit(RIL_REQUEST_ECALL_FAST_MAKE_ECALL, UDP, socket_id);
+    char** argv = new char*[fast_argv.size()];
+    for(int i=0; i < fast_argv.size(); i++) {
+        argv[i] = new char[fast_argv[i].size() +1];
+        memset(argv[i], 0 , fast_argv[i].size() +1);
+        strncpy(argv[i], fast_argv[i].c_str(),fast_argv[i].size());
+        argv[i][fast_argv[i].size()] = '\0';
+    }
+
+    dialFastEcall(fast_argc, argv, socket_id, pRI);
+
+    for(int i=0; i < fast_argv.size(); i++) {
+        delete [] argv[i];
+    }
+    delete []argv;
+}
+
+void handleEcallIndication(const void* data, int datalen, RIL_SOCKET_ID soc_id) {
+    if (data == NULL || datalen != sizeof(RIL_Ecall_Unsol_Indications)) {
+      if (data == NULL) {
+        RLOGE("handleEcallIndication invalid response: NULL");
+      } else {
+        RLOGE("handleEcallIndication: invalid response length %d expecting len: %d",
+              sizeof(RIL_Ecall_Unsol_Indications), data);
+      }
+      return ;
+    }
+
+    RIL_Ecall_Unsol_Indications *p_cur = (RIL_Ecall_Unsol_Indications *)data;
+    RLOGD("handleEcallIndication, call_id: %d, ind: %d",p_cur->call_id, p_cur->ind);
+    switch(p_cur->ind){
+    case RIL_UNSOL_ECALL_SENDING_START: // = 1,
+    {
+        RLOGD("handleEcallIndication: normal_ecall_tag=%d", normal_ecall_tag);
+        if(!normal_ecall_tag){
+            //char msd_data[MSD_MAX_LENGTH]= {0};
+            //utils::mtk_property_get(PROP_ECALL_MSD_DATA, msd_data, NULL);
+            RLOGD("msd_data: %s", msd_data==NULL ? "":msd_data);
+            if(msd_data != NULL) {
+//                char* arg[2] = { "RIL_REQUEST_SET_MUTE", "1" };
+//                setMute(2, arg, soc_id, 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);
+            }
+        } else {
+            stop_ecall_timer(sT5, sT5_sig_value);
+        }
+        break;
+    }
+    case RIL_UNSOL_ECALL_SENDING_MSD: // = 2,
+    {
+        start_ecll_timer(sT7,sT7_sig_value, T7_TIMEOUT);
+        act_fecall_socid = soc_id;
+        act_feCall_Id = p_cur->call_id;
+        break;
+    }
+    case RIL_UNSOL_ECALL_LLACK_RECEIVED: // = 3,
+    {
+        fast_argc = 0;
+        fast_argv.clear();
+        stop_ecall_timer(sT7, sT7_sig_value);
+        start_ecll_timer(sT6, sT6_sig_value, T6_TIMEOUT);
+        act_fecall_socid = soc_id;
+        act_feCall_Id = p_cur->call_id;
+        normal_ecall_tag = false;
+        break;
+    }
+    case RIL_UNSOL_ECALL_ALACK_POSITIVE_RECEIVED: // = 4,
+    {
+        stop_ecall_timer(sT6, sT6_sig_value);
+        resetEcallIVSandAudio(RSPD, soc_id);
+        saveEcallRecord(p_cur->ind);
+        break;
+    }
+    case RIL_UNSOL_ECALL_ALACK_CLEARDOWN_RECEIVED: // = 5,
+    {
+        stop_ecall_timer(sT6, sT6_sig_value);
+        stop_ecall_timer(sT2, sT2_sig_value);
+        resetEcallIVSandAudio(RSPD, soc_id);
+        saveEcallRecord(p_cur->ind);
+        RequestInfo* pRI = creatRILInfoAndInit(RIL_REQUEST_HANGUP, RSPD, soc_id);
+        char* id = const_cast<char*>(std::to_string(p_cur->call_id).c_str());
+        char* argv[2] = { "RIL_REQUEST_HANGUP", "" };
+        argv[1] = id;
+        hangupConnection(2, argv, soc_id, pRI);
+        break;
+    }
+    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);
+        autoAnswerEcall(false);
+        start_ecll_timer(sT2, sT2_sig_value,T2_TIMEOUT);
+        start_ecll_timer(sT5,sT5_sig_value, T5_TIMEOUT);
+        break;
+    }
+    case RIL_UNSOL_ECALL_DISCONNECTED: //=12,
+    {
+        start_ecll_timer(sAutoAnsTimer,autoAns_sig_value, AUTOANS_TIMEOUT);
+        autoAnswerEcall(true);
+        stop_ecall_timer(sT2, sT2_sig_value);
+        if(isGostEcall())
+        {
+            //start deregistration time
+            start_ecll_timer(gostDeregistrationTimer, gost_deregistration_value, gostStartDeregisterTimer());
+        }
+
+        break;
+    }
+    case RIL_UNSOL_ECALL_ABNORMAL_HANGUP: //=15,
+    {
+        RLOGD(" make fast ecall redial start,  redial_tag: %d", redial_tag);
+        if(redial_tag != REDIAL_DOING) {
+            stop_ecall_timer(sT2, sT2_sig_value);
+            stop_ecall_timer(sT5,sT5_sig_value);
+            stop_ecall_timer(sT6,sT6_sig_value);
+            stop_ecall_timer(sT7,sT7_sig_value);
+            int32_t timer = utils::mtk_property_get_int32(PROP_ECALL_REDIAL_TIMER, 120);
+            RLOGD(" make fast ecall redial start,  vendor.ecall.redial.timer: %d", timer);
+            start_ecll_timer(sRedialTimer, redial_sig_value, timer*1000);
+        }
+        if(redial_tag != REDIAL_SUCCESS || redial_tag != REDIAL_EXPIRES){
+            redial_tag = REDIAL_DOING;
+            RequestInfo* pRI = creatRILInfoAndInit(RIL_REQUEST_ECALL_RESET_IVS, UDP, soc_id);
+            resetIVS(0, NULL, soc_id, pRI);
+            redialFastEcall(soc_id);
+        }
+        break;
+    }
+    //case RIL_UNSOL_ECALL_IMS_MSD_ACK: // = 20,
+    //case RIL_UNSOL_ECALL_IMS_UPDATE_MSD: // = 21,
+    //case RIL_UNSOL_ECALL_UNSPECIFIED: // = 0xffff,
+    default:
+        RLOGD("handleEcallIndication don't handlt the value(%d)", p_cur->ind);
+    }
+}
+
+//RIL_REQUEST_ECALL_SET_IVS
+int setIVS(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+  android::Parcel p;
+  size_t pos = p.dataPosition();
+
+  if (getSpeechStatus() == SPEECH_OFF) {
+    if (get_audio_path() == 0) {
+      setSpeechAndStatus(1);
+    } else {
+      setSpeechAndStatus(2);
+    }
+  }
+
+  //paramter int. 0 disable, 1 enable
+  p.writeInt32(1);
+  p.writeInt32(atoi(argv[1]) ? 1 : 0);
+  p.setDataPosition(pos);
+  pRI->pCI->dispatchFunction(p, pRI);
+  return 0;
+}
+
+//RIL_REQUEST_ECALL_SET_MSD
+int setMSD(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+  android::Parcel p;
+  size_t pos = p.dataPosition();
+  int digitCount;
+  uint8_t uct;
+  int digitLimit;
+  char *msd_data_src = (char *) argv[2];
+  unsigned char msd_data_dst[MSD_MAX_LENGTH];
+  int len = strlen(msd_data_src);
+
+  if (argc < 2 || argv[2] == NULL || len % 2 == 1) {
+    //add log msg
+    free(pRI);
+    return -1;
+  }
+
+  if (getSpeechStatus() == SPEECH_OFF) {
+    if (get_audio_path() == 0) {
+      setSpeechAndStatus(1);
+    } else {
+      setSpeechAndStatus(2);
+    }
+  }
+  //call_id
+  p.writeInt32(atoi(argv[1]));
+  //msd_data Convert MSD to byte representation
+  RLOGD("msd_data_src: msd_data_src length = %d %s\n", strlen(msd_data_src),
+      msd_data_src);
+  ConvertMsd((const char *) argv[2], msd_data_dst);
+
+  digitLimit = MIN(len / 2, MSD_MAX_LENGTH);
+  p.writeInt32(digitLimit);
+
+  for (digitCount = 0; digitCount < digitLimit; digitCount++) {
+    p.write(&(msd_data_dst[digitCount]), sizeof(uint8_t));
+  }
+
+  p.setDataPosition(pos);
+  pRI->pCI->dispatchFunction(p, pRI);
+  return 0;
+}
+//RIL_REQUEST_ECALL_SET_PSAP
+int setPASP(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+  android::Parcel p;
+  size_t pos = p.dataPosition();
+
+  if (getSpeechStatus() == SPEECH_OFF) {
+    if (get_audio_path() == 0) {
+      setSpeechAndStatus(1);
+    } else {
+      setSpeechAndStatus(2);
+    }
+  }
+
+  //paramter int. 0 disable, 1 enable
+  p.writeInt32(1);
+  p.writeInt32(atoi(argv[1]) ? 1 : 0);
+  p.setDataPosition(pos);
+  pRI->pCI->dispatchFunction(p, pRI);
+  return 0;
+}
+
+//RIL_REQUEST_ECALL_IVS_PUSH_MSD
+int IVSPushMSD(int argc, char **argv, RIL_SOCKET_ID socket_id,
+    RequestInfo *pRI) {
+  android::Parcel p;
+
+  if (getSpeechStatus() == SPEECH_OFF) {
+    if (get_audio_path() == 0) {
+      setSpeechAndStatus(1);
+    } else {
+      setSpeechAndStatus(2);
+    }
+  }
+
+  //paramter none
+  pRI->pCI->dispatchFunction(p, pRI);
+  return 0;
+}
+//RIL_REQUEST_ECALL_PSAP_PULL_MSD
+int PSAPPushMSD(int argc, char **argv, RIL_SOCKET_ID socket_id,
+    RequestInfo *pRI) {
+  android::Parcel p;
+
+  if (getSpeechStatus() == SPEECH_OFF) {
+    if (get_audio_path() == 0) {
+      setSpeechAndStatus(1);
+    } else {
+      setSpeechAndStatus(2);
+    }
+  }
+
+  //paramter none
+  pRI->pCI->dispatchFunction(p, pRI);
+  return 0;
+}
+int setCTRLSequence(int argc, char **argv, RIL_SOCKET_ID socket_id,
+    RequestInfo *pRI) {
+  android::Parcel p;
+  size_t pos = p.dataPosition();
+
+  if (argc < 1 || argc > 4) {
+    //add log msg
+    free(pRI);
+    return -1;
+  }
+  //CTRL Sequence
+  p.writeInt32(3);
+  writeStringToParcel(p, (const char *) argv[1]);
+  writeStringToParcel(p, (const char *) argv[2]);
+  writeStringToParcel(p, (const char *) argv[3]);
+
+  p.setDataPosition(pos);
+  pRI->pCI->dispatchFunction(p, pRI);
+
+  return 0;
+}
+//RIL_REQUEST_ECALL_RESET_IVS
+int resetIVS(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+  android::Parcel p;
+
+  if (getSpeechStatus() == SPEECH_OFF) {
+    if (get_audio_path() == 0) {
+      setSpeechAndStatus(1);
+    } else {
+      setSpeechAndStatus(2);
+    }
+  }
+
+  //paramter none
+  pRI->pCI->dispatchFunction(p, pRI);
+  return 0;
+}
+//RIL_REQUEST_ECALL_SET_TEST_NUM
+int setTestNum(int argc, char **argv, RIL_SOCKET_ID socket_id,
+    RequestInfo *pRI) {
+  android::Parcel p;
+  size_t pos = p.dataPosition();
+
+  if(argc -1 == 0) {
+    p.writeInt32(0);
+    p.writeInt32(0);
+    writeStringToParcel(p, "");
+  } else if (argc -1 == 1) {
+    p.writeInt32(1);
+    p.writeInt32(atoi(argv[1]) ? 1 : 0);
+    writeStringToParcel(p, "");
+  } else if (argc - 1 == 2) {
+    p.writeInt32(2);
+    p.writeInt32(atoi(argv[1]) ? 1 : 0);
+    writeStringToParcel(p, (const char *) argv[2]);
+  } else {
+    RLOGD("parameters is invalid");
+    free(pRI);
+    return -1;
+  }
+  p.setDataPosition(pos);
+  pRI->pCI->dispatchFunction(p, pRI);
+  return 0;
+}
+
+//RIL_REQUEST_ECALL_SET_RECONF_NUM
+int setReconfNum(int argc, char **argv, RIL_SOCKET_ID socket_id,
+    RequestInfo *pRI) {
+  android::Parcel p;
+  size_t pos = p.dataPosition();
+  if(argc -1 == 0) {
+    p.writeInt32(0);
+    p.writeInt32(0);
+    writeStringToParcel(p, "");
+  } else if (argc -1 == 1) {
+    p.writeInt32(1);
+    p.writeInt32(atoi(argv[1]) ? 1 : 0);
+    writeStringToParcel(p, "");
+  } else if (argc - 1 == 2) {
+    p.writeInt32(2);
+    p.writeInt32(atoi(argv[1]) ? 1 : 0);
+    writeStringToParcel(p, (const char *) argv[2]);
+  } else {
+    RLOGD("parameters is invalid");
+    free(pRI);
+    return -1;
+  }
+  p.setDataPosition(pos);
+  pRI->pCI->dispatchFunction(p, pRI);
+  return 0;
+}
+
+//RIL_REQUEST_ECALL_MAKE_ECALL
+int makeECall(int argc, char **argv, RIL_SOCKET_ID socket_id,
+    RequestInfo *pRI) {
+  android::Parcel p;
+  size_t pos = p.dataPosition();
+  //paramter int, type
+  int type;
+  type = atoi(argv[1]);
+  if (type < 0 || type > 3) {
+    RLOGW("makeECall type is invaild. set default 0!");
+    type = 0;
+  }
+
+  p.writeInt32(1);
+  p.writeInt32(type);
+  p.setDataPosition(pos);
+  setEcallAudioPathOn(true);
+  pRI->pCI->dispatchFunction(p, pRI);
+  return 0;
+}
+
+//RIL_REQUEST_ECALL_FAST_MAKE_ECALL
+/*cmd:1, ecall_cat,
+*2, ecall_variant,
+*3, address
+*4, msd_data
+*/
+int dialFastEcall(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    if(isGostEcall())
+    {
+        if(inNeedRegister)
+        {
+            RLOGD("%s:%d", __FUNCTION__, __LINE__);
+            gostFastEcallFlg = true;
+            gostNetworkSelectionSet(socket_id);
+            while(inNeedRegister)
+            {
+                sleep(1);
+                RLOGD("%s:%d", __FUNCTION__, __LINE__);
+            }
+            stop_ecall_timer(gostDeregistrationTimer,gost_deregistration_value);
+        }
+    }
+    saveFastEcallData(argc, argv, socket_id);
+    if (argc < 5 || argv[3] == NULL || argv[4] == NULL) {
+        //add log msg
+        free(pRI);
+        return -1;
+    }
+    android::Parcel p;
+    size_t pos =  p.dataPosition();
+    int digitCount;
+    uint8_t uct;
+    int digitLimit;
+    char *msd_data_src = (char *)argv[4];
+    unsigned char msd_data_dst[MSD_MAX_LENGTH];
+    int len = strlen(msd_data_src);
+
+    if (len%2 == 1) {
+        //add log msg
+        free(pRI);
+        return -1;
+    }
+    //ecall_cat
+    p.writeInt32(atoi(argv[1]));
+    //ecall_variant
+    p.writeInt32(atoi(argv[2]));
+    //address;
+    if(strcasecmp(argv[3], "null") == 0)
+    {
+        writeStringToParcel(p, "");
+    } else {
+        writeStringToParcel(p, (const char *)argv[3]);
+    }
+
+    //msd_data Convert MSD to byte representation
+    RLOGD("msd_data_src: %s , length = %d", msd_data_src, strlen(msd_data_src));
+    ConvertMsd((const char *)argv[4], msd_data_dst);
+
+    digitLimit= MIN(len/2, MSD_MAX_LENGTH);
+    p.writeInt32(digitLimit);
+
+    for (digitCount = 0 ; digitCount < digitLimit; digitCount ++) {
+        p.write(&(msd_data_dst[digitCount]), sizeof(uint8_t));
+    }
+
+    p.setDataPosition(pos);
+    normal_ecall_tag = true;
+    setEcallAudioPathOn(true);
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+
+//RIL_REQUEST_ECALL_SET_PRI
+int setEmsdpri(int argc, char **argv, RIL_SOCKET_ID socket_id,
+        RequestInfo *pRI) {
+    if (argc != 5) {
+        RLOGW("parameter is invalid");
+        free(pRI);
+        return 0;
+    }
+    int data1 = atoi(argv[1]);
+    int data2 = atoi(argv[2]);
+    int data3 = atoi(argv[3]);
+    int data4 = atoi(argv[4]);
+
+    if (data1 + data2 + data3 + data4 != 10) {
+        RLOGW("parameter is invalid , %d,%d,%d,%d", data1, data2, data3, data4);
+        free(pRI);
+        return 0;
+    }
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    p.writeInt32(4);
+    p.writeInt32(data1);
+    p.writeInt32(data2);
+    p.writeInt32(data3);
+    p.writeInt32(data4);
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+//RIL_REQUEST_ECALL_SET_NAD_DEREGISTRATION_TIME
+/*
+ * "data" is const ints*
+ *  ((const int *)data)[0] is purpose, 0-for eCall(currently only support 0, can be extended in future)
+ *  ((const int *)data)[1] is mode, 1-set timer; 0-reset timer
+ *  ((const int *)data)[2] is timer1, timer value (minute) set for emergency call
+ *  ((const int *)data)[3] is timer2, timer value (minute) set for rest/reconfiguration call,
+ *
+ *   in current, timer1 and timer2 prefer to be the same value.
+ */
+int setNadDeregTime(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if (argc != 5) {
+        RLOGW("parameter is invalid");
+        free(pRI);
+        return 0;
+    }
+
+    int purpose = atoi(argv[1]);
+    int mode = (atoi(argv[2]) != 0) ? 1 : 0;
+    int timer1 = atoi(argv[3]);
+    int timer2 = atoi(argv[4]);
+    if (timer1 != timer2) {
+        RLOGW("setNadDeregTime, parameter is invalid:data3 != data4");
+        free(pRI);
+        return 0;
+    }
+
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    p.writeInt32(4);
+    p.writeInt32(purpose);
+    p.writeInt32(mode);
+    p.writeInt32(timer1);
+    p.writeInt32(timer2);
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+/**
+* RIL_REQUEST_ECALL_SET_REGISTRATION_STATE
+*
+* REQUEST to set nad registration state of ecall only sim
+*
+* "data" is const ints*
+*  ((const int *)data)[0] is state, 0-deregister from NW, enter the eCall inactivity procedure;
+*                                             1-register to NW, leave the eCall inactivity procedure(not support, reserved for future use)
+* "response" is NULL
+*
+* Valid errors:
+*  SUCCESS
+*  GENERIC_FAILURE
+*/
+int setNadRegState(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if(argc != 2) {
+      RLOGW("parameter is invalid");
+      free(pRI);
+      return 0;
+    }
+
+    int state = (atoi(argv[1])!= 0) ? 1 : 0;
+
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    p.writeInt32(1);
+    p.writeInt32(state);
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+int setEcallType(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if(argc < 2) {
+        RLOGW("[error],setEcallType parameter error!");
+        free(pRI);
+        return 0;
+    }
+    RLOGD("setEcallType is %s",argv[1]);
+    int value = atoi(argv[1]);
+    switch(value) {
+    case 1:
+    {
+        ecall_type = ECALL_TYPE::EN16454_ECALL;
+        break;
+    }
+    case 2:
+    {
+        ecall_type = ECALL_TYPE::GOST_ECALL;
+        break;
+    }
+    case 3:
+    {
+        ecall_type = ECALL_TYPE::NG_ECALL;
+        break;
+    }
+    default:
+        RLOGD("setEcallType error %s",argv[1]);
+    }
+
+    if(pRI) {
+        free(pRI);
+    }
+    return 0;
+}
+
+int getEcallType(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    RLOGD("%s, %d", __FUNCTION__, ecall_type);
+
+    if(ecall_type == ECALL_TYPE::EN16454_ECALL) {
+        printf("the current test type is: EN16454 ECALL\n");
+    } else if(ecall_type == ECALL_TYPE::GOST_ECALL) {
+        printf("the current test type is: GOST ECALL\n");
+    } else if (ecall_type == ECALL_TYPE::NG_ECALL) {
+        printf("the current test type is: NG ECALL (IMS)\n");
+    } else {
+        printf("the current test type is: unknown\n");
+    }
+
+    if(pRI) {
+        free(pRI);
+    }
+    return 0;
+}
+
+bool isEn16454Ecall() {
+    bool value = (ecall_type == ECALL_TYPE::EN16454_ECALL);
+    RLOGD("%s=%d, type = %d", __FUNCTION__, value, ecall_type);
+    return value;
+}
+
+bool isGostEcall() {
+    bool value = (ecall_type == ECALL_TYPE::GOST_ECALL);
+    RLOGD("%s=%d, type = %d", __FUNCTION__, value, ecall_type);
+    return value;
+}
+
+bool isNgEcall() {
+    bool value = (ecall_type == ECALL_TYPE::NG_ECALL);
+    RLOGD("%s=%d, type = %d", __FUNCTION__, value, ecall_type);
+    return value;
+}
+
+void gostSaveSmsData(int argc, char** argv ,RIL_SOCKET_ID id) {
+    gost_sms_socket_id = id;
+    gost_sms_argc = argc;
+    gost_sms_argv.clear();
+    for(int i = 0; i < argc; i++) {
+        gost_sms_argv.push_back(argv[i]);
+    }
+}
+
+void gostDelSaveSmsData() {
+    if(fast_argc != 0)
+    {
+        fast_argc = 0;
+        fast_argv.clear();
+    }
+}
+
+#define INT_MEM_TRANSMIT_ATTEMPTS 10
+#define INT_MEM_TRANSMIT_INTERVAL (60*60*1000)
+static int gost_attempts = INT_MEM_TRANSMIT_ATTEMPTS;
+static int gost_interval = INT_MEM_TRANSMIT_INTERVAL;
+
+void gostSetInNeedRegister(bool flags)
+{
+    RLOGD("%s:flags(%d) change!", __FUNCTION__, flags);
+    inNeedRegister = flags;
+}
+void gostFastEcallFlgSet(bool flags)
+{
+    RLOGD("%s:flags(%d) change!", __FUNCTION__, flags);
+    gostFastEcallFlg = flags;
+}
+
+int gostTransmitAttemptsSet(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    if(argc < 2) {
+        RLOGW("[error],gostTransmitAttemptsSet parameter error!");
+        free(pRI);
+        return 0;
+    }
+
+    int attempts = atoi(argv[1]);;
+    gost_attempts = attempts;
+    RLOGD("%s:gost_attempts(%d)", __FUNCTION__, gost_attempts);
+
+    if(pRI) {
+        free(pRI);
+    }
+    return 0;
+}
+
+int gostStartDeregisterTimer()
+{
+    char configNum[16]= {0};
+    int timerValue;
+    utils::mtk_property_get(PROP_ECALL_DEREGIST_TIME, configNum, "60");
+    timerValue = atoi(configNum) * 60 * 1000;
+    RLOGD("%s:configNum(%d)", __FUNCTION__, timerValue);
+    return timerValue;
+}
+
+int gostTransmitIntervalSet(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    if(argc < 2) {
+        RLOGW("[error],gostTransmitIntervalSet parameter error!");
+        free(pRI);
+        return 0;
+    }
+
+    int interval = atoi(argv[1]);;
+    gost_interval = interval;
+    RLOGD("%s:gost_interval(%d)", __FUNCTION__, gost_interval);
+
+    if(pRI) {
+        free(pRI);
+    }
+    return 0;
+}
+
+int gostTransmitDefaultSet(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    gost_attempts = INT_MEM_TRANSMIT_ATTEMPTS;
+    gost_interval = INT_MEM_TRANSMIT_INTERVAL;
+    RLOGD("%s:gost_attempts(%d), gost_interval(%d)", __FUNCTION__, gost_attempts, gost_interval);
+
+    if(pRI) {
+        free(pRI);
+    }
+    return 0;
+}
+
+int gostNetworkSelectionSet(int soc_id)
+{
+    RLOGD("%s:soc_id(%d)", __FUNCTION__, soc_id);
+    if(isGostEcall() && gostFastEcallFlg)
+    {
+        RequestInfo *pRI = creatRILInfoAndInit(RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC, UDP, (RIL_SOCKET_ID)(soc_id));
+        if(pRI == NULL)
+        {
+            RLOGE("error PRI is NULL");
+            return 0;
+        }
+        char* argv[1] = {"RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC"};
+        setNetworkSelectionModeAutomatic(1, argv, (RIL_SOCKET_ID)(soc_id), pRI);
+    }
+    return 0;
+}
+
+int gostEcallResendMsd(bool flg)
+{
+    static int resendnum = 0;
+
+    //no resend
+    if(!flg)
+    {
+        if(resendnum != 0)
+        {
+            stop_ecall_timer(gostResendMsdTimer,gost_resend_msd_value);
+        }
+        resendnum = 0;
+        return 0;
+    }
+
+    //abandon
+    if(resendnum > gost_attempts)
+    {
+        resendnum = 0;
+        stop_ecall_timer(gostResendMsdTimer,gost_resend_msd_value);
+        return 0;
+    }
+
+    //resend
+    resendnum++;
+    start_ecll_timer(gostResendMsdTimer, gost_resend_msd_value, gost_interval);
+}
+
+int T7GostEcallSmsMsd(sigval_t sig) {
+    char** argv = new char*[fast_argv.size()];
+    char msd[512];
+    char saveEcallData[512];
+    char sdata[512];
+
+    if((sig.sival_int != sT7_sig_value) && (sig.sival_int != sT5_sig_value))
+    {
+        return -1;
+    }
+
+    if(isGostEcall())
+    {
+        //for test
+        char testCase[140]= {0};
+        utils::mtk_property_get(PROP_ECALL_TEST_CASE, testCase, "test");
+        if(strcmp(testCase, "33470") == 0)
+        {
+            RLOGD("%s:testCase(%s) not need send sms", __FUNCTION__, testCase);
+            return -1;
+        }
+
+        if(fast_argv.size() < 5) {
+            RLOGD("%s:testCase(%s) fast_argv size(%d) is not right", __FUNCTION__, testCase,fast_argv.size());
+            return -1;
+        }
+        for(int i=0; i < fast_argv.size(); i++) {
+            argv[i] = new char[fast_argv[i].size() +1];
+            memset(argv[i], 0 , fast_argv[i].size() +1);
+            strncpy(argv[i], fast_argv[i].c_str(),fast_argv[i].size());
+            argv[i][fast_argv[i].size()] = '\0';
+        }
+
+        RLOGD("num:%s, data:%s\n", argv[3], argv[4]);
+        char *msd_data_src = (char *)argv[4];
+        int len = strlen(msd_data_src);
+        std::shared_ptr<SslpManager> manager = std::make_shared<SslpManager>();
+        std::string data = manager->encodeAllRecords(service_support_layer_protocol::EGTS_ECALL_SERVICE,
+                service_support_layer_protocol::EGTS_ECALL_SERVICE,
+                EcallUtils::EGTS_SR_RAW_MSD_DATA,
+                msd_data_src);
+        //encode
+        RLOGD("T7:data.c_str():%s\n", data.c_str());
+        int pt = GOST_EGTS_PT_APPDATA;
+        gostTransferLayerEncode(msd, 0, const_cast<char*> (data.c_str()), pt, sizeof(msd));
+        RLOGD("T7:msd:%s\n", msd);
+        gostSendSmsForMsd(fast_ecall_socket_id, argv[3], msd);
+        for(int i=0; i < fast_argv.size(); i++) {
+            delete [] argv[i];
+        }
+        delete []argv;
+
+        return 0;
+    }
+
+    return -1;
+}
+
+#define GOST_OK 0
+#define GOST_ERROR -1
+int gostInitEcallViaSms(int soc_id, char *num, int ecalltype, char *msd)
+{
+    //init ecall
+    RequestInfo *pRI = creatRILInfoAndInit(RIL_REQUEST_ECALL_FAST_MAKE_ECALL, UDP, (RIL_SOCKET_ID)(soc_id));
+    if(pRI == NULL)
+    {
+        RLOGE("error PRI is NULL");
+        return 0;
+    }
+
+    int argc = 5;
+    char *argv[5];
+    argv[0] = "RIL_REQUEST_ECALL_FAST_MAKE_ECALL";
+    if(ecalltype)
+    {
+        argv[1] = "2";//1:Manual 2:auto
+    }
+    else
+    {
+        argv[1] = "1";//1:Manual 2:auto
+    }
+    argv[2] = "2";    //1:test ecall 2:Emergency eCall 3:Reconfiguration eCall
+//    argv[3] = "1";    //1:Pull mode 2:push mode
+    argv[3] = num;
+    argv[4] = msd;
+    dialFastEcall(argc, argv, (RIL_SOCKET_ID)(soc_id), pRI);
+    return 0;
+}
+
+int gostParseSmsHandle(int soc_id, char *num, char *msg)
+{
+    char msd[512] = {0};
+    char sdata[512] = {0};
+    char server_data[512] = {0};
+    int server_len;
+    int parseStatus;
+    gost_transfer_head_t stransferHead;
+
+    memset(&stransferHead, 0, sizeof(stransferHead));
+    parseStatus = gostTransferLayerDecode(msg, server_data, &server_len, &stransferHead);
+    const char* SFRD = server_data;
+    uint16_t FDL = server_len;
+    std::shared_ptr<SslpManager> sMg = std::make_shared<SslpManager>();
+    parseStatus += sMg->decodeAllRecords(SFRD, FDL);
+    std::uint16_t cmd = UINT16_MAX;
+    if(sMg->isIncludedCmdCode(EcallUtils::EGTS_ECALL_REQ)) {
+        cmd = EcallUtils::EGTS_ECALL_REQ;
+    } else if(sMg->isIncludedCmdCode(EcallUtils::EGTS_ECALL_MSD_REQ)) {
+        cmd = EcallUtils::EGTS_ECALL_MSD_REQ;
+    } else if(sMg->isIncludedCmdCode(EcallUtils::EGTS_ECALL_DEREGISTRATION)) {
+        cmd = EcallUtils::EGTS_ECALL_DEREGISTRATION;
+    }
+    if(cmd == UINT16_MAX) {
+        MTK_RLOGW("don't support this ack,just return");
+        return -1;
+    }
+    MTK_RLOGD("the cmd = 0X%04X, parseStatus = %d", cmd, parseStatus);
+    std::string sslp_ack = sMg->encodeAck(service_support_layer_protocol::EGTS_COMMANDS_SERVICE,
+            service_support_layer_protocol::EGTS_COMMANDS_SERVICE,
+            CmdUtils::EGTS_SR_COMMAND_DATA,
+            cmd,
+            (parseStatus == GOST_OK));
+    strncpy(sdata, sslp_ack.c_str(), 512);
+    int pt = GOST_EGTS_PT_RESPONSE;
+    gostResponseTypeSfrdEncode(sdata, stransferHead, parseStatus);
+    gostTransferLayerEncode(msd, 0, sdata, pt, sizeof(msd));
+    //send SMS ACK
+    gostSendSmsForMsd(soc_id, num, msd);
+
+    if (parseStatus == GOST_OK) {
+        if(cmd == EcallUtils::EGTS_ECALL_REQ) {
+            int ecalltype = sMg->getEcallReqPara(); // 0 manual , 1: auto
+            //make fast ECALL;
+            if(msd_data == NULL) {
+                RLOGW("msd_data is empty, please input");
+                return -1;
+            }
+
+            char ecallNum[64] = {0};
+            if(fast_argv.size() > 4)
+            {
+                strcpy(ecallNum, fast_argv[3].c_str());
+            }
+            gostInitEcallViaSms(soc_id, ecallNum, ecalltype, msd_data);
+        } else if(cmd == EcallUtils::EGTS_ECALL_MSD_REQ) {
+            //check whether need send SMS by decoding transport value in command.
+            if(sMg->isNeedNewSms()) {
+                  //TBD: send new SMS;
+                if(msd_data == NULL) {
+                    RLOGW("msd_data is empty, please input");
+                    return -1;
+                }
+                std::string msdData(msd_data);
+                std::shared_ptr<SslpManager> sMg = std::make_shared<SslpManager>();
+                std::string records = sMg->encodeAllRecords(service_support_layer_protocol::EGTS_ECALL_SERVICE,
+                        service_support_layer_protocol::EGTS_ECALL_SERVICE, EcallUtils::EGTS_SR_RAW_MSD_DATA, msdData);
+                //transport encode and sms send
+                int pt = GOST_EGTS_PT_APPDATA;
+                memset(msd, 0, sizeof(msd));
+                gostTransferLayerEncode(msd, 0, const_cast<char*> (records.c_str()), pt, sizeof(msd));
+                gostSendSmsForMsd(soc_id, num, msd);
+            }
+        } else if(cmd == EcallUtils::EGTS_ECALL_DEREGISTRATION) {
+            MTK_RLOGD("send RIL_REQUEST_ECALL_SET_REGISTRATION_STATE 0");
+            RIL_SOCKET_ID id = (RIL_SOCKET_ID)fast_ecall_socket_id;
+            if(id == -1) {
+                id = (RIL_SOCKET_ID)get_default_sim_all_except_data();
+            }
+            RequestInfo* pRI = creatRILInfoAndInit(RIL_REQUEST_ECALL_SET_REGISTRATION_STATE, UDP, id);
+            char* argv[2] = { "RIL_REQUEST_ECALL_SET_REGISTRATION_STATE", "0" };
+            setNadRegState(2, argv, id, pRI);
+        }
+    }
+    return 0;
+}
+#endif /*ECALL_SUPPORT*/
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/eCall.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/eCall.h
new file mode 100644
index 0000000..f04c020
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/eCall.h
@@ -0,0 +1,101 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#ifndef __RIL_ECALL__
+#define __RIL_ECALL__
+#include "common.h"
+#include <vendor-ril/telephony/ril.h>
+
+#ifdef ECALL_SUPPORT
+
+typedef enum {
+    UNKNOWN,
+    EN16454_ECALL,
+    GOST_ECALL,
+    NG_ECALL,
+} ECALL_TYPE;
+
+typedef enum {
+    GOST_EGTS_PT_RESPONSE = 0,
+    GOST_EGTS_PT_APPDATA,
+    GOST_EGTS_PT_SIGNED_APPDATA,
+} ECALL_PT_T;
+
+typedef enum {
+    ECALL_INACTIVITY = 0,
+    ECALL_DEREGISTRATION,
+} GOST_ECALL_RETURN_T;
+
+enum {
+    ECALL_NETWORK_SELECT_COMPLETE = 0,
+    ECALL_NETWORK_SELECTING,
+};
+
+int setIVS(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setTestNum(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setReconfNum(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setMSD(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setPASP(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int makeECall(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int IVSPushMSD(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int PSAPPushMSD(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setMSDMode(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int dialFastEcall(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setCTRLSequence(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int resetIVS(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setEmsdpri(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+void handleEcallIndication(const void* data, int datalen, RIL_SOCKET_ID soc_id);
+void init_ecall_timer_all();
+int setMsdDateForTest(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setNadDeregTime(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setNadRegState(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setEcallType(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int getEcallType(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+bool isEn16454Ecall();
+bool isGostEcall();
+bool isNgEcall();
+int gostTransmitAttemptsSet(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int gostTransmitIntervalSet(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int gostTransmitDefaultSet(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int gostNetworkSelectionSet(int soc_id);
+void gostSaveSmsData(int argc, char** argv ,RIL_SOCKET_ID id);
+void gostDelSaveSmsData();
+int gostParseSmsHandle(int soc_id, char *num, char *msg);
+int gostEcallResendMsd(bool flg);
+void gostSetInNeedRegister(bool flags);
+void gostFastEcallFlgSet(bool flags);
+bool isEcallAudioPath();
+void setEcallAudioPathOn(bool on);
+#endif /*ECALL_SUPPORT*/
+#endif
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/IndividualRecord.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/IndividualRecord.cpp
new file mode 100644
index 0000000..d1940ab
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/IndividualRecord.cpp
@@ -0,0 +1,392 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include <bitset>
+
+#include "IndividualRecord.h"
+#include "../utils/GostEcallUtils.h"
+
+using namespace std;
+
+#undef LOG_TAG
+#define LOG_TAG "DEMO_EGOST_IndividualRecord"
+
+std::atomic_uint16_t IndividualRecord::initRecNum (0);
+
+IndividualRecord::IndividualRecord() {
+    RL = 0; //little-endian = 0;
+    RN = 0; //little-endian = 0;
+
+    RFL = 0;
+    SSOD = UINT8_MAX;
+    RSOD = UINT8_MAX;
+    RPP = UINT8_MAX;
+    TMFE = 0;
+    EVFE = 0;
+    OBFE = 0;
+
+    OID = UINT32_MAX; //O, depends: OBFE
+    EVID = UINT32_MAX; //O,depends: EVFE
+    TM = UINT32_MAX; //O, depends: TMFE
+    SST = UINT8_MAX;
+    RST = UINT8_MAX;
+    RD="";
+}
+
+IndividualRecord::~IndividualRecord() {
+}
+
+std::uint8_t IndividualRecord::getEvfe() const {
+    return EVFE;
+}
+
+void IndividualRecord::setEvfe(std::uint8_t evfe) {
+    EVFE = evfe;
+}
+
+std::uint32_t IndividualRecord::getEvid() const {
+    return EVID;
+}
+
+void IndividualRecord::setEvid(std::uint32_t evid) {
+    EVID = evid;
+}
+
+std::uint8_t IndividualRecord::getObfe() const {
+    return OBFE;
+}
+
+void IndividualRecord::setObfe(std::uint8_t obfe) {
+    OBFE = obfe;
+}
+
+std::uint32_t IndividualRecord::getOid() const {
+    return OID;
+}
+
+void IndividualRecord::setOid(std::uint32_t oid) {
+    OID = oid;
+}
+
+//const std::vector<std::uint8_t>& IndividualRecord::getRd() const {
+//    return RD;
+//}
+//
+//void IndividualRecord::setRd(const std::vector<std::uint8_t> &rd) {
+//    RD = rd;
+//}
+
+std::uint8_t IndividualRecord::getRfl() const {
+    return RFL;
+}
+
+void IndividualRecord::setRfl(std::uint8_t rfl) {
+    RFL = rfl;
+}
+
+std::uint16_t IndividualRecord::getRl() const {
+    return RL;
+}
+
+void IndividualRecord::setRl(std::uint16_t rl) {
+    RL = rl;
+}
+
+std::uint16_t IndividualRecord::getRn() const {
+    return RN;
+}
+
+void IndividualRecord::setRn(std::uint16_t rn) {
+    RN = rn;
+}
+
+std::uint8_t IndividualRecord::getRpp() const {
+    return RPP;
+}
+
+void IndividualRecord::setRpp(std::uint8_t rpp) {
+    RPP = rpp;
+}
+
+std::uint8_t IndividualRecord::getRsod() const {
+    return RSOD;
+}
+
+void IndividualRecord::setRsod(std::uint8_t rsod) {
+    RSOD = rsod;
+}
+
+std::uint8_t IndividualRecord::getSsod() const {
+    return SSOD;
+}
+
+void IndividualRecord::setSsod(std::uint8_t ssod) {
+    SSOD = ssod;
+}
+
+std::uint32_t IndividualRecord::getTm() const {
+    return TM;
+}
+
+void IndividualRecord::setTm(std::uint32_t tm) {
+    TM = tm;
+}
+
+std::uint8_t IndividualRecord::getTmfe() const {
+    return TMFE;
+}
+
+void IndividualRecord::setTmfe(std::uint8_t tmfe) {
+    TMFE = tmfe;
+}
+
+const std::string& IndividualRecord::getRd() const {
+    return RD;
+}
+
+void IndividualRecord::setRd(const std::string rd) {
+    RD = rd;
+}
+
+std::uint8_t IndividualRecord::getRst() const {
+    return RST;
+}
+
+void IndividualRecord::setRst(std::uint8_t rst) {
+    RST = rst;
+}
+
+std::uint8_t IndividualRecord::getSst() const {
+    return SST;
+}
+
+std::string IndividualRecord::encodeAllSubRecords(std::uint8_t sst, std::uint8_t rst,std::uint8_t srt, std::string msd) {
+    std::shared_ptr<IndividualSubRecord> enSubRecords = std::make_shared<IndividualSubRecord>(sst, rst);
+    enSubRecords->setSrt(srt);
+
+    //encode RD;
+    std::string rd = enSubRecords->encodeAllService(msd);
+    MTK_RLOGD("RD encode result is: %s", rd.c_str());
+    if(rd.empty()) {
+        MTK_RLOGW("encode RD fail");
+        return "";
+    }
+
+    //encode RL
+    std::string rl = encodeValue((rd.size()/2), 4, "RL");
+    MTK_RLOGD("RL encode result is: %s", rl.c_str());
+    if(rl.empty()) {
+        MTK_RLOGW("encode RL fail");
+        return "";
+    }
+
+    //encode RN
+    std::string rn = encodeValue(generalRecodeNum(), 4, "RN");
+    MTK_RLOGD("RN encode result is: %s", rn.c_str());
+    if(rn.empty()) {
+        MTK_RLOGW("encode RN fail");
+        return "";
+    }
+
+    //encode RFL
+    bitset<8> rfl;
+    rfl[7] = 1; //SSOD
+    std::string rflStr = encodeValue(rfl.to_ulong(), 2, "RFL");
+    MTK_RLOGD("RFL encode result is: %s", rflStr.c_str());
+    if(rflStr.empty()) {
+        MTK_RLOGW("encode RFL fail");
+        return "";
+    }
+
+    //encode SST
+    std::string sstStr = encodeValue(sst, 2, "SST");
+    if(sstStr.empty()) {
+        MTK_RLOGW("encode SST fail");
+        return "";
+    }
+
+    //encode RST
+    std::string rstStr = encodeValue(rst, 2, "RST");
+    if(rstStr.empty()) {
+        MTK_RLOGW("encode RST fail");
+        return "";
+    }
+
+    return rl + rn + rflStr + sstStr + rstStr + rd;
+}
+
+void IndividualRecord::setSst(std::uint8_t sst) {
+    SST = sst;
+}
+
+int IndividualRecord::decodeAllSubRecords() {
+    if(RD.empty()) {
+        MTK_RLOGW("record data is null , just return");
+        return -1;
+    }
+    MTK_RLOGD("RD: %s", RD.c_str());
+    uint32_t index = 0;
+    int64_t ret = 0;
+    while(index < RD.length()) {
+        std::shared_ptr<IndividualSubRecord> subRec = make_shared<IndividualSubRecord>(SST, RST);
+        //decode SRT(Subrecord type)
+        ret = decodeValue(RD, index, 2, "SRT(Subrecord type)");
+        if(ret == -1) {
+            MTK_RLOGW("decode SRT fail");
+            return -1;
+        }
+        MTK_RLOGD("index: %d, SRT: 0X%02x",index, (uint8_t)ret);
+        subRec->setSrt((uint8_t)ret);
+
+        //SRL(subrecord length)
+        ret = decodeValue(RD, index, 4, "SRL(subrecord length)");
+        if(ret == -1) {
+            MTK_RLOGW("decode SRL fail");
+            return -1;
+        }
+        MTK_RLOGD("index: %d, SRL: 0X%04x",index, (uint16_t)ret);
+        subRec->setSrl((uint16_t)ret);
+
+        //decode SRD(subrecord Data);
+        if(subRec->getSrl() > 0) {
+            std::string sub = decodeData(RD, subRec->getSrl(), "SRD(subrecord Data)", index);
+            if(sub.empty()) {
+                MTK_RLOGW("decode RD fail");
+                return -1;
+            }
+            MTK_RLOGD("index: %d, SRD: %s",index, sub.c_str());
+            subRec->setSrd(sub);
+            ret = subRec->decodeAllService();
+            if(ret == -1) {
+                MTK_RLOGW("decodeAllService() fail");
+                return -1;
+            }
+            deSubRecords.push_back(subRec);
+        }
+    }
+    return 0;
+}
+
+bool IndividualRecord::isIncludedCmdCode(std::uint16_t cmd) {
+    MTK_RLOGD("cmd=0X%04X", cmd);
+    if(deSubRecords.size() == 0) {
+        MTK_RLOGW("no decode sub records");
+        return false;
+    }
+    bool ret = false;
+    for(auto &rec : deSubRecords) {
+        ret = rec->isIncludedCmdCode(cmd);
+        if(ret)
+        {
+            MTK_RLOGD("cmd=0X%04X is included",cmd);
+            break;
+        }
+    }
+    return ret;
+}
+
+std::string IndividualRecord::encodeAck(std::uint8_t sst_value, std::uint8_t rst_value, std::uint8_t subType, std::uint16_t cmd, bool ack) {
+
+    //encode RD;
+    std::string rd("");
+    for(auto &rec : deSubRecords) {
+        if(rec->isIncludedCmdCode(cmd)) {
+            rd += rec->encodeAck(subType, cmd, ack);
+        }
+    }
+
+    //encode RL
+    std::string rl = encodeValue((rd.size()/2), 4, "RL");
+    MTK_RLOGD("encode RL(0X%04X) result: %s",rd.size()/2, rl.c_str());
+
+    //encode RN
+    std::uint16_t value = generalRecodeNum();
+    std::string rn = encodeValue(value, 4, "RL");
+    MTK_RLOGD("encode RN(0X%04X) result: %s",value, rn.c_str());
+
+    bitset<8> rfl;
+    rfl[7] = 1;
+    std::string rflStr = encodeValue(rfl.to_ulong(), 2, "RFL");
+    MTK_RLOGD("encode RFL(0X%02X) result: %s",rfl.to_ulong(), rflStr.c_str());
+
+    //encode SST
+    std::string sst = encodeValue(sst_value, 2, "SST");
+    MTK_RLOGD("encode SST(%d) result: %s",sst_value, sst.c_str());
+
+    //encode RST
+    std::string rst = encodeValue(rst_value, 2, "RST");
+    MTK_RLOGD("encode RST(%d) result: %s",rst_value, rst.c_str());
+    return rl + rn + rflStr + sst + rst + rd;
+}
+
+bool IndividualRecord::isNeedNewSms() {
+    if(deSubRecords.size() == 0) {
+        MTK_RLOGW("no decode sub records");
+        return false;
+    }
+    bool ret = false;
+    for(auto &rec : deSubRecords) {
+        ret = rec->isIncludedCmdCode(EcallUtils::EGTS_ECALL_MSD_REQ);
+        if(ret)
+        {
+            MTK_RLOGD("EGTS_ECALL_MSD_REQ is included");
+            ret = rec->isNeedNewSms();
+            break;
+        }
+    }
+    return ret;
+}
+
+int IndividualRecord::getEcallReqPara() {
+    if(deSubRecords.size() == 0) {
+        MTK_RLOGW("no decode sub records");
+        return 0;
+    }
+    int ret = 0;
+    for(auto &rec : deSubRecords) {
+        bool isExsit = rec->isIncludedCmdCode(EcallUtils::EGTS_ECALL_REQ);
+        if(isExsit)
+        {
+            MTK_RLOGD("EGTS_ECALL_REQ is included");
+            ret = rec->getEcallReqPara();
+            break;
+        }
+    }
+    return ret;
+}
+
+std::uint16_t IndividualRecord::generalRecodeNum() {
+    return initRecNum++;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/IndividualRecord.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/IndividualRecord.h
new file mode 100644
index 0000000..7c83693
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/IndividualRecord.h
@@ -0,0 +1,117 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef INDIVIDUALRECORD_H_
+#define INDIVIDUALRECORD_H_
+
+#include <cstdint>
+#include <string>
+#include <vector>
+#include <memory>
+#include <atomic>
+
+#include "IndividualSubRecord.h"
+
+//p23, table14
+class IndividualRecord {
+public:
+    IndividualRecord();
+    virtual ~IndividualRecord();
+    int decodeAllSubRecords();
+    std::string encodeAllSubRecords(std::uint8_t sst, std::uint8_t rst,std::uint8_t srt, std::string msd);
+    std::uint8_t getEvfe() const;
+    void setEvfe(std::uint8_t evfe);
+    std::uint32_t getEvid() const;
+    void setEvid(std::uint32_t evid);
+    std::uint8_t getObfe() const;
+    void setObfe(std::uint8_t obfe);
+    std::uint32_t getOid() const;
+    void setOid(std::uint32_t oid);
+    //const std::vector<std::uint8_t>& getRd() const;
+    //void setRd(const std::vector<std::uint8_t> &rd);
+    std::uint8_t getRfl() const;
+    void setRfl(std::uint8_t rfl);
+    std::uint16_t getRl() const;
+    void setRl(std::uint16_t rl);
+    std::uint16_t getRn() const;
+    void setRn(std::uint16_t rn);
+    std::uint8_t getRpp() const;
+    void setRpp(std::uint8_t rpp);
+    std::uint8_t getRsod() const;
+    void setRsod(std::uint8_t rsod);
+    std::uint8_t getSsod() const;
+    void setSsod(std::uint8_t ssod);
+    std::uint32_t getTm() const;
+    void setTm(std::uint32_t tm);
+    std::uint8_t getTmfe() const;
+    void setTmfe(std::uint8_t tmfe);
+    const std::string& getRd() const;
+    void setRd(const std::string rd);
+    std::uint8_t getRst() const;
+    void setRst(std::uint8_t rst);
+    std::uint8_t getSst() const;
+    void setSst(std::uint8_t sst);
+    bool isIncludedCmdCode(std::uint16_t cmd);
+    std::string encodeAck(std::uint8_t sst_value, std::uint8_t rst_value, std::uint8_t subType, std::uint16_t cmd, bool ack);
+    bool isNeedNewSms();
+    int getEcallReqPara();
+private:
+    std::uint16_t RL; //little-endian;
+    std::uint16_t RN; //little-endian;
+
+    std::uint8_t RFL;
+    std::uint8_t SSOD;
+    std::uint8_t RSOD;
+    std::uint8_t RPP;
+    std::uint8_t TMFE;
+    std::uint8_t EVFE;
+    std::uint8_t OBFE;
+
+    std::uint32_t OID; //O, depends: OBFE
+    std::uint32_t EVID; //O,depends: EVFE
+    std::uint32_t TM; //O, depends: TMFE
+    std::uint8_t SST;
+    std::uint8_t RST;
+    //std::vector<std::uint8_t> RD; // depends RL, 3-65498 byte;
+    std::string RD; // depends RL, 3-65498 byte;
+
+    std::vector<std::shared_ptr<IndividualSubRecord>> deSubRecords;
+    std::shared_ptr<IndividualSubRecord> enSubRecords;
+
+    static std::atomic_uint16_t initRecNum;
+    static std::uint16_t generalRecodeNum();
+};
+
+#endif /* INDIVIDUALRECORD_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/IndividualSubRecord.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/IndividualSubRecord.cpp
new file mode 100644
index 0000000..17f62f2
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/IndividualSubRecord.cpp
@@ -0,0 +1,292 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include <bitset>
+
+#include "IndividualSubRecord.h"
+#include "../utils/GostEcallUtils.h"
+#include "./commands/CmdUtils.h"
+#include "./ecall/EcallUtils.h"
+
+using namespace std;
+
+#undef LOG_TAG
+#define LOG_TAG "DEMO_EGOST_IndividualSubRecord"
+
+
+IndividualSubRecord::IndividualSubRecord(uint8_t sst, uint8_t rst) {
+    SRT = UINT8_MAX;
+    SRL = 0;
+    SRD = ""; //o, 0-65495;
+    mSst = sst;
+    mRst = rst;
+
+}
+
+IndividualSubRecord::~IndividualSubRecord() {
+    // TODO Auto-generated destructor stub
+}
+
+const std::string& IndividualSubRecord::getSrd() const {
+    return SRD;
+}
+
+void IndividualSubRecord::setSrd(const std::string srd) {
+    SRD = srd;
+}
+
+std::uint16_t IndividualSubRecord::getSrl() const {
+    return SRL;
+}
+
+void IndividualSubRecord::setSrl(std::uint16_t srl) {
+    SRL = srl;
+}
+
+std::uint8_t IndividualSubRecord::getSrt() const {
+    return SRT;
+}
+
+void IndividualSubRecord::setSrt(std::uint8_t srt) {
+    SRT = srt;
+}
+
+std::string IndividualSubRecord::encodeAck(std::uint8_t subType, std::uint16_t cmd, bool ack) {
+    if(subType == CmdUtils::EGTS_SR_COMMAND_DATA) {
+        if(!mDeSrComDtFmt) {
+            MTK_RLOGW("sub command data is null");
+            return "";
+        }
+        //encode SRT
+        std::string srt = encodeValue(subType, 2, "SRT");
+        MTK_RLOGD("encode SRT(0X%02X) result: %s",subType, srt.c_str());
+
+        //encode SRL and SRD
+        std::string srd = mDeSrComDtFmt->encode(cmd, ack);
+        if(srd.empty()) {
+            MTK_RLOGW("encode  cmd(0X%04X) is empty", cmd);
+        }
+        MTK_RLOGD("encode SRD(cmd: 0X%04X) result: %s",cmd, srd.c_str());
+        //SRL
+        std::string srl =  encodeValue((srd.size()/2), 4, "SRL");
+        MTK_RLOGD("encode SRL(0X%04X) result: %s",srd.size()/2, srl.c_str());
+        return srt + srl + srd;
+    }
+    MTK_RLOGW("encodeAck fail ,don't support subtype(%u)", subType);
+    return "";
+}
+
+int IndividualSubRecord::decodeComService() {
+    uint32_t index = 0;
+    int64_t ret = 0;
+    if (SRT == CmdUtils::EGTS_SR_COMMAND_DATA) {
+        mDeSrComDtFmt = std::make_shared<SrComDataFormat>();
+        //decode srComDtFmt->type
+        ret = decodeValue(SRD, index, 2, "srComDtFmt->type");
+        if (ret == -1) {
+            MTK_RLOGW("decode type fail");
+            return -1;
+        }
+        MTK_RLOGD("index: %d, type: 0X%02x", index, (uint8_t )ret);
+        mDeSrComDtFmt->setType((uint8_t) (ret));
+        bitset<8> tmp(mDeSrComDtFmt->getType());
+        mDeSrComDtFmt->setCt(
+                (tmp[7] << 3) | (tmp[6]) << 2 | (tmp[5] << 1) | tmp[4]);
+        mDeSrComDtFmt->setCct(
+                (tmp[3] << 3) | (tmp[2]) << 2 | (tmp[1] << 1) | tmp[0]);
+        MTK_RLOGD("index: %d, ct=0X%02X, cct=0X%02X", index, mDeSrComDtFmt->getCt(),
+                mDeSrComDtFmt->getCct());
+        //decode CID(command identifier)
+        ret = decodeValue(SRD, index, 8, "CID(command identifier)");
+        if (ret == -1) {
+            MTK_RLOGW("decode CID fail");
+            return -1;
+        }
+        MTK_RLOGD("index: %d, CID: 0X%08x", index, (uint32_t )ret);
+        mDeSrComDtFmt->setCid((uint32_t) (ret));
+        //decode SID(source identifier)
+        ret = decodeValue(SRD, index, 8, "SID(source identifier)");
+        if (ret == -1) {
+            MTK_RLOGW("decode SID fail");
+            return -1;
+        }
+        MTK_RLOGD("index: %d, SID: 0X%08x", index, (uint32_t )ret);
+        mDeSrComDtFmt->setSid((uint32_t) (ret));
+        //decode srComDtFmt->fileExs
+        ret = decodeValue(SRD, index, 2, "srComDtFmt->fileExs");
+        if (ret == -1) {
+            MTK_RLOGW("decode fileExs fail");
+            return -1;
+        }
+        MTK_RLOGD("index: %d, fileExs: 0X%02x", index, (uint8_t )ret);
+        mDeSrComDtFmt->setFileExs((uint8_t) (ret));
+        bitset<8> tp(mDeSrComDtFmt->getFileExs());
+        mDeSrComDtFmt->setAcfe(tp[1]);
+        mDeSrComDtFmt->setChsfe(tp[0]);
+        MTK_RLOGD("index: %d, acfe=0X%02X, chsfe=0X%02X", index, mDeSrComDtFmt->getAcfe(),
+                mDeSrComDtFmt->getChsfe());
+        //decode CHS(charset)
+        if (mDeSrComDtFmt->getChsfe()) {
+            ret = decodeValue(SRD, index, 2, "CHS(charset)");
+            if (ret == -1) {
+                MTK_RLOGW("decode CHS fail");
+                return -1;
+            }
+            MTK_RLOGD("index: %d, CHS: 0X%02x", index, (uint8_t )ret);
+            mDeSrComDtFmt->setChs((uint8_t) (ret));
+        }
+        //decode ACL(Authorisation Code Length)
+        if (mDeSrComDtFmt->getAcfe()) {
+            ret = decodeValue(SRD, index, 2, "ACL(Authorisation Code Length)");
+            if (ret == -1) {
+                MTK_RLOGW("decode ACL fail");
+                return -1;
+            }
+            MTK_RLOGD("index: %d, ACL: 0X%02x", index, (uint8_t )ret);
+            mDeSrComDtFmt->setAcl((uint8_t) (ret));
+        }
+        //decode AC(Authorisation Code)
+        if (mDeSrComDtFmt->getAcl()) {
+            std::string sub = decodeData(SRD, mDeSrComDtFmt->getAcl(),
+                    "AC(Authorisation Code)", index);
+            if (sub.empty()) {
+                MTK_RLOGW("decode AC fail");
+                return -1;
+            }
+            MTK_RLOGD("index: %d, AC: %s", index, sub.c_str());
+            mDeSrComDtFmt->setAc(sub);
+        }
+        //decode CD(Command Data)
+        if (index < SRD.size()) {
+            std::string sub = SRD.substr(index);
+            mDeSrComDtFmt->setCd(sub);
+            ret = mDeSrComDtFmt->decodeSrCmomDt();
+            if (ret == -1) {
+                MTK_RLOGW("decode decodeSrCmomDt fail");
+                return -1;
+            }
+        } else {
+            MTK_RLOGW("decode CD fail");
+            return -1;
+        }
+    } else if (SRT == CmdUtils::EGTS_SR_RECORD_RESPONSE) {
+    } else {
+    }
+    return 0;
+}
+
+int IndividualSubRecord::decodeAllService() {
+    //TBD,
+    //need check other conditions. maybe response.
+    if(SRL == 0 || SRD.empty()) {
+        MTK_RLOGW("SRD don't exist. don't need decode");
+        return 0;
+    }
+    MTK_RLOGD("sst=%d, rst =%d, srt = %d, %s", mSst, mRst, SRT, SRD.c_str());
+//    uint32_t index = 0;
+//    int64_t ret = 0;
+    if(mSst == service_support_layer_protocol::EGTS_COMMANDS_SERVICE) { //TBD. is this condition right ?
+        int ret = decodeComService();
+        if(ret == -1) {
+            MTK_RLOGW("decode decodeComService fail");
+            return -1;
+        }
+    } else {
+        MTK_RLOGW("don't support, just return");
+    }
+    return 0;
+
+
+}
+
+std::string IndividualSubRecord::encodeAllService(std::string msd) {
+    if(SRT == EcallUtils::EGTS_SR_RAW_MSD_DATA) {
+        //encode SRT
+        std::string srt = encodeValue(SRT, 2, "SRT");
+        MTK_RLOGD("srt encode result: %s", srt.c_str());
+        if(srt.empty()) {
+            MTK_RLOGW("encode SRT fail");
+            return "";
+        }
+
+        mSrRawMsdDt = std::make_shared<SrRawMsdData>();
+        mSrRawMsdDt->setFm(1); // 1: packe encoding as per GOST 33464;
+        mSrRawMsdDt->setMsd(msd);
+
+        //encode SRD
+        std::string srd = mSrRawMsdDt->encode();
+        MTK_RLOGD("srd encode result: %s", srd.c_str());
+        if(srd.empty()) {
+            MTK_RLOGW("encode srd fail");
+            return "";
+        }
+
+        //encode SRL
+        std::string srl = encodeValue((srd.length()/2), 4, "SRL");
+        MTK_RLOGD("SRL encode result: %s", srl.c_str());
+        if(srl.empty()) {
+            MTK_RLOGW("encode SRL fail");
+            return "";
+        }
+        return srt + srl + srd;
+    }
+    MTK_RLOGW("don't support this SRT(%d) encode", SRT);
+    return "";
+}
+
+bool IndividualSubRecord::isIncludedCmdCode(std::uint16_t cmd) {
+    MTK_RLOGD("cmd=0X%04X", cmd);
+    if(!mDeSrComDtFmt) {
+        MTK_RLOGW("no decode command sub records");
+        return false;
+    }
+    return mDeSrComDtFmt->isIncludedCmdCode(cmd);
+}
+
+bool IndividualSubRecord::isNeedNewSms() {
+    if(!mDeSrComDtFmt) {
+        MTK_RLOGW("no decode command sub records");
+        return false;
+    }
+    return mDeSrComDtFmt->isNeedNewSms();
+}
+
+int IndividualSubRecord::getEcallReqPara() {
+    if(!mDeSrComDtFmt) {
+        MTK_RLOGW("no decode command sub records");
+        return 0;
+    }
+    return mDeSrComDtFmt->getEcallReqPara();
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/IndividualSubRecord.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/IndividualSubRecord.h
new file mode 100644
index 0000000..b6e9ba3
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/IndividualSubRecord.h
@@ -0,0 +1,79 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef INDIVIDUALSUBRECORD_H_
+#define INDIVIDUALSUBRECORD_H_
+
+#include <cstdint>
+#include <string>
+#include <vector>
+#include <memory>
+
+#include "./commands/SrComDataFormat.h"
+#include "ecall/SrRawMsdData.h"
+
+//p24, table15
+class IndividualSubRecord {
+public:
+    IndividualSubRecord(uint8_t sst, uint8_t rst);
+    virtual ~IndividualSubRecord();
+    const std::string& getSrd() const;
+    void setSrd(const std::string srd);
+    std::uint16_t getSrl() const;
+    void setSrl(std::uint16_t srl);
+    std::uint8_t getSrt() const;
+    void setSrt(std::uint8_t srt);
+    int decodeAllService();
+    std::string encodeAllService(std::string msd);
+    bool isIncludedCmdCode(std::uint16_t cmd);
+    std::string encodeAck(std::uint8_t subType, std::uint16_t cmd, bool ack);
+    bool isNeedNewSms();
+    int getEcallReqPara();
+private:
+    std::uint8_t SRT;
+    std::uint16_t SRL;
+    //std::vector<std::uint8_t> SRD; //o, 0-65495;
+    std::string SRD; //o, 0-65495;
+
+    std::uint8_t mSst;
+    std::uint8_t mRst;
+
+    std::shared_ptr<SrComDataFormat> mDeSrComDtFmt;
+    int decodeComService();
+
+    std::shared_ptr<SrRawMsdData> mSrRawMsdDt;
+};
+
+#endif /* INDIVIDUALSUBRECORD_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/SslpManager.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/SslpManager.cpp
new file mode 100644
index 0000000..95310cf
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/SslpManager.cpp
@@ -0,0 +1,266 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include <cstdlib>
+#include <cstring>
+#include <bitset>
+
+#include "SslpManager.h"
+#include "../utils/GostEcallUtils.h"
+#include "./ecall/EcallUtils.h"
+
+using namespace std;
+
+#undef LOG_TAG
+#define LOG_TAG "DEMO_EGOST_SslpManager"
+
+SslpManager::SslpManager() {
+    // TODO Auto-generated constructor stub
+
+}
+
+SslpManager::~SslpManager() {
+    // TODO Auto-generated destructor stub
+}
+
+int SslpManager::decodeAllRecords(const char* sfrd , std::uint16_t len) {
+    if(sfrd == NULL || len == 0) {
+        MTK_RLOGW("srfd, service frame data is invalid");
+        return -1;
+    }
+
+    std::string str(sfrd);
+    if(str.size() != len * 2) {
+        MTK_RLOGW("srfd size(%llu) != len(%d)*2, service frame data is invalid, just return", str.size(), (len*2));
+        return -1;
+    }
+
+    // must be even
+    if ((str.size()) & 1) {
+        MTK_RLOGW("srfd size(%llu) isn't even, service len is invalid, just return", str.size());
+        return -1;
+    }
+
+    MTK_RLOGD("sfrd(%d): %s",len*2, (sfrd == NULL ? "":sfrd));
+    uint32_t index = 0;
+    int64_t ret = 0;
+    while(index < str.length()) {
+        std::shared_ptr<IndividualRecord> rec = make_shared<IndividualRecord>();
+        //decode RL
+        ret = decodeValue(str, index, 4, "RL(Record Length)");
+        if(ret == -1) {
+            MTK_RLOGW("decode RL fail");
+            return -1;
+        }
+        MTK_RLOGD("index: %d, RL: 0X%04x",index, (uint16_t)ret);
+        rec->setRl((uint16_t)ret);
+
+        //decode RN
+        ret = decodeValue(str, index, 4, "RN(Record Number)");
+        if(ret == -1) {
+            MTK_RLOGW("decode RN fail");
+            return -1;
+        }
+        MTK_RLOGD("index: %d, RN: 0X%04x",index, (uint16_t)ret);
+        rec->setRn((uint16_t)ret);
+
+        //decode RFL(record flags)
+        ret = decodeValue(str, index, 2, "RFL(record flags)");
+        if(ret == -1) {
+            MTK_RLOGW("decode RFL fail");
+            return -1;
+        }
+        MTK_RLOGD("index: %d, RFL: 0X%02x",index, (uint8_t)ret);
+        rec->setRfl((uint8_t)ret);
+        bitset<8> rfl(rec->getRfl());
+        rec->setSsod(rfl[7]);
+        rec->setRsod(rfl[6]);
+        rec->setRpp((rfl[5]<<2)|(rfl[4]<<1)|(rfl[3]));
+        rec->setTmfe(rfl[2]);
+        rec->setEvfe(rfl[1]);
+        rec->setObfe(rfl[0]);
+        MTK_RLOGD("ssod=%d, rsod=%d, rpp=%d, tmfe=%d, evfe=%d, obfe=%d",
+                rec->getSsod(),
+                rec->getRsod(),
+                rec->getRpp(),
+                rec->getTmfe(),
+                rec->getEvfe(),
+                rec->getObfe());
+
+        //decode OID(object Identifier)
+        if(rec->getObfe()) {
+            ret = decodeValue(str, index, 8, "OID(object Identifier)");
+            if(ret == -1) {
+                MTK_RLOGW("decode OID fail");
+                return -1;
+            }
+            MTK_RLOGD("index: %d, OID: 0X%08x",index, (uint32_t)ret);
+            rec->setOid((uint32_t)ret);
+        }
+
+        //decode EVID(Event Identifier)
+        if(rec->getEvfe()) {
+            ret = decodeValue(str, index, 8, "EVID(Event Identifier)");
+            if(ret == -1) {
+                MTK_RLOGW("decode EVID fail");
+                return -1;
+            }
+            MTK_RLOGD("index: %d, EVID: 0X%08x",index, (uint32_t)ret);
+            rec->setEvid((uint32_t)ret);
+        }
+
+        //decode TM(Time)
+        if(rec->getTmfe()) {
+            ret = decodeValue(str, index, 8, "TM(Time)");
+            if(ret == -1) {
+                MTK_RLOGW("decode TM fail");
+                return -1;
+            }
+            MTK_RLOGD("index: %d, TM: 0X%08x",index, (uint32_t)ret);
+            rec->setTm((uint32_t)ret);
+        }
+
+        //decode SST(source service type)
+        ret = decodeValue(str, index, 2, "SST(source service type)");
+        if(ret == -1) {
+            MTK_RLOGW("decode SST fail");
+            return -1;
+        }
+        MTK_RLOGD("index: %d, SST: 0X%02x",index, (uint8_t)ret);
+        rec->setSst((uint8_t)ret);
+
+        //decode RST(recipient service type)
+        ret = decodeValue(str, index, 2, "RST(recipient service type)");
+        if(ret == -1) {
+            MTK_RLOGW("decode RST fail");
+            return -1;
+        }
+        MTK_RLOGD("index: %d, RST: 0X%02x",index, (uint8_t)ret);
+        rec->setRst((uint8_t)ret);
+
+        //decode RD(record Data);
+        std::string sub = decodeData(str, rec->getRl(), "RD(record Data)", index);
+        if(sub.empty()) {
+            MTK_RLOGW("decode RD fail");
+            return -1;
+        }
+        MTK_RLOGD("index: %d, RD: %s",index, sub.c_str());
+        rec->setRd(sub);
+        ret = rec->decodeAllSubRecords();
+        if(ret == -1) {
+            MTK_RLOGW("decodeAllSubRecords() fail");
+            return -1;
+        }
+        deRecords.push_back(rec);
+    }
+    return 0;
+}
+
+bool SslpManager::isIncludedCmdCode(std::uint16_t cmd) {
+    MTK_RLOGD("cmd=0X%04X", cmd);
+    if(deRecords.size() == 0) {
+        MTK_RLOGW("no decode records");
+        return false;
+    }
+    bool ret = false;
+    for(auto &rec : deRecords) {
+        ret = rec->isIncludedCmdCode(cmd);
+        if(ret)
+        {
+            MTK_RLOGD("cmd=0X%04X is included",cmd);
+            break;
+        }
+    }
+    return ret;
+}
+
+std::vector<std::shared_ptr<IndividualRecord> >& SslpManager::getDeRecords() {
+    return deRecords;
+}
+
+std::string SslpManager::encodeAllRecords(std::uint8_t sst, std::uint8_t rst,std::uint8_t srt, std::string msd) {
+    std::shared_ptr<IndividualRecord> enRecords = std::make_shared<IndividualRecord>();
+    std::string sslp = enRecords->encodeAllSubRecords(sst,rst, srt, msd);
+    MTK_RLOGD("sslp: %s", sslp.c_str());
+    return sslp;
+}
+
+std::string SslpManager::encodeAck(std::uint8_t sst_value, std::uint8_t rst_value, std::uint8_t subType,
+        std::uint16_t cmd, bool ack) {
+    std::string sslp("");
+    for(auto &rec : deRecords) {
+        if(rec->isIncludedCmdCode(cmd)) {
+            sslp += rec->encodeAck(sst_value, rst_value, subType, cmd, ack);
+        }
+    }
+    MTK_RLOGD("sslp: %s", sslp.c_str());
+    return sslp;
+}
+
+bool SslpManager::isNeedNewSms() {
+    if(deRecords.size() == 0) {
+        MTK_RLOGW("no decode records");
+        return false;
+    }
+    bool ret = false;
+    for(auto &rec : deRecords) {
+        ret = rec->isIncludedCmdCode(EcallUtils::EGTS_ECALL_MSD_REQ);
+        if(ret)
+        {
+            MTK_RLOGD("EGTS_ECALL_MSD_REQ is included");
+            ret = rec->isNeedNewSms();
+            break;
+        }
+    }
+    return ret;
+}
+
+int SslpManager::getEcallReqPara() {
+    if(deRecords.size() == 0) {
+        MTK_RLOGW("no decode records");
+        return 0;
+    }
+    int ret = 0;
+    for(auto &rec : deRecords) {
+        bool isExsit = rec->isIncludedCmdCode(EcallUtils::EGTS_ECALL_REQ);
+        if(isExsit)
+        {
+            MTK_RLOGD("EGTS_ECALL_REQ is included");
+            ret = rec->getEcallReqPara();
+            break;
+        }
+    }
+    return ret;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/SslpManager.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/SslpManager.h
new file mode 100644
index 0000000..8a6905c
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/SslpManager.h
@@ -0,0 +1,67 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef SSLP_SSLPMANAGER_H_
+#define SSLP_SSLPMANAGER_H_
+
+#include <cstdint>
+#include <string>
+#include <vector>
+#include <memory>
+
+#include "IndividualRecord.h"
+
+class SslpManager {
+public:
+    SslpManager();
+    virtual ~SslpManager();
+    int decodeAllRecords(const char* sfrd , std::uint16_t len);
+    bool isIncludedCmdCode(std::uint16_t cmd);
+    bool isNeedNewSms();
+    int getEcallReqPara();
+    //sst ,rst service_support_layer_protocol::EGTS_ECALL_SERVICE, service_support_layer_protocol::EGTS_ECALL_SERVICE
+    std::string encodeAllRecords(std::uint8_t sst, std::uint8_t rst,std::uint8_t srt, std::string msd); //srt: EcallUtils::EGTS_SR_RAW_MSD_DATA
+    std::vector<std::shared_ptr<IndividualRecord> >& getDeRecords();
+    //sst, rst service_support_layer_protocol::EGTS_COMMANDS_SERVICE, service_support_layer_protocol::EGTS_COMMANDS_SERVICE,
+    //CmdUtils::EGTS_SR_COMMAND_DATA,
+    //cmd: EcallUtils: 1.EGTS_ECALL_DEREGISTRATION 2. EGTS_ECALL_MSD_REQ.3 EGTS_ECALL_REQ
+    std::string encodeAck(std::uint8_t sst_value, std::uint8_t rst_value, std::uint8_t subType, std::uint16_t cmd, bool ack);
+
+private:
+    std::vector<std::shared_ptr<IndividualRecord>> deRecords;
+    std::shared_ptr<IndividualRecord> enRecords;
+};
+
+#endif /* SSLP_SSLPMANAGER_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/commands/CmdUtils.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/commands/CmdUtils.cpp
new file mode 100644
index 0000000..b0afece
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/commands/CmdUtils.cpp
@@ -0,0 +1,102 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include "CmdUtils.h"
+#include "../../utils/GostEcallUtils.h"
+using namespace std;
+
+#undef LOG_TAG
+#define LOG_TAG "DEMO_EGOST_CmdUtils"
+CmdUtils::CmdUtils() {
+    // TODO Auto-generated constructor stub
+
+}
+
+CmdUtils::~CmdUtils() {
+    // TODO Auto-generated destructor stub
+}
+
+int CmdUtils::decodeCmdCommand(std::uint16_t cmd, const std::string &data) {
+    MTK_RLOGD("cmd=0X%02X, data: %s", cmd, (data.empty() ? "": data.c_str()));
+    MTK_RLOGW("don't support, just return");
+    return 0;
+}
+
+bool CmdUtils::isCmdCommands(std::uint16_t cmd) {
+    MTK_RLOGD("cmd=0X%02X", cmd);
+    switch (cmd) {
+    case EGTS_RAW_DATA:
+    case EGTS_TEST_MODE:
+    case EGTS_CONFIG_RESET:
+    case EGTS_SET_AUTH_CODE:
+    case EGTS_RESTART:
+        //radio mute
+    case EGTS_RADIO_MUTE_DELAY:
+    case EGTS_RADIO_UNMUTE_DELAY:
+        //GEneral-purpose settings
+    case EGTS_GPRS_APN:
+    case EGTS_SERVER_ADDRESS:
+    case EGTS_SIM_PIN:
+    case EGTS_INT_MEM_TRANSMIT_INTERVAL:
+    case EGTS_INT_MEM_TRANSMIt_ATTEMPTS:
+        //test mode
+    case EGTS_TEST_REGISTRATION_PERIOD:
+    case EGTS_MODE_END_DISTANCE:
+        //service station mode
+    case EGTS_GARAGE_MODE_END_DISTANCE:
+    case EGTS_GARAGE_MODE_PIN:
+        //Miscellaneous parameters
+    case EGTS_GNSS_POWER_OFF_TIME:
+    case EGTS_GNSS_DATA_RATE:
+    case EGTS_GNSS_MIN_ELEVATION:
+        //Device parameters
+    case EGTS_UNIT_ID:
+    case EGTS_UNIT_IMEI:
+    case EGTS_UNIT_RS485_BAUD_RATE:
+    case EGTS_UNIT_RS485_STOP_BITS:
+    case EGTS_UNIT_RS485_PARITY:
+    case EGTS_UNIT_HOME_DISPATCHER_ID:
+    case EGTS_SERVICE_AUTH_METHOD:
+    case EGTS_SERVER_CHECK_IN_PERIOD:
+    case EGTS_SERVER_CHECK_IN_ATTEMPTS:
+    case EGTS_SERVER_PACKET_TOUT:
+    case EGTS_SERVER_PACKET_RETRANSMIT_ATTEMPTS:
+    case EGTS_UINT_MIC_LEVEL:
+    case EGTS_UINT_SPK_LEVEL: {
+        return true;
+    }
+    }
+    return false;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/commands/CmdUtils.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/commands/CmdUtils.h
new file mode 100644
index 0000000..45b3380
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/commands/CmdUtils.h
@@ -0,0 +1,100 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef SSLP_COMMANDS_CMDUTILS_H_
+#define SSLP_COMMANDS_CMDUTILS_H_
+
+#include <cstdint>
+#include <string>
+
+class CmdUtils {
+public:
+    CmdUtils();
+    virtual ~CmdUtils();
+    int decodeCmdCommand(std::uint16_t cmd, const std::string& data);
+
+    static bool isCmdCommands(std::uint16_t cmd);
+public:
+    //sub records;
+    static constexpr std::uint8_t EGTS_SR_RECORD_RESPONSE = 0;
+    static constexpr std::uint8_t EGTS_SR_COMMAND_DATA = 51;
+
+    //List of commands sent to IVDS table 32 p40;
+    static constexpr std::uint16_t EGTS_RAW_DATA = 0x0000;
+    static constexpr std::uint16_t EGTS_TEST_MODE = 0x0001;
+    static constexpr std::uint16_t EGTS_CONFIG_RESET = 0x0006;
+    static constexpr std::uint16_t EGTS_SET_AUTH_CODE = 0x0007;
+    static constexpr std::uint16_t EGTS_RESTART = 0x0008;
+
+    //list of acknowledgements for commands and messages, table 33 p41
+    //    static constexpr std::uint16_t EGTS_RAW_DATA = 0x0000;
+
+    //LIst of IVDS parameters table34 p41;
+    //radio mute
+    static constexpr std::uint16_t EGTS_RADIO_MUTE_DELAY = 0x0201;
+    static constexpr std::uint16_t EGTS_RADIO_UNMUTE_DELAY = 0x0202;
+    //GEneral-purpose settings
+    static constexpr std::uint16_t EGTS_GPRS_APN = 0x0203;
+    static constexpr std::uint16_t EGTS_SERVER_ADDRESS = 0x0204;
+    static constexpr std::uint16_t EGTS_SIM_PIN = 0x0205;
+    static constexpr std::uint16_t EGTS_INT_MEM_TRANSMIT_INTERVAL = 0x0206;
+    static constexpr std::uint16_t EGTS_INT_MEM_TRANSMIt_ATTEMPTS = 0x0207;
+    //test mode
+    static constexpr std::uint16_t EGTS_TEST_REGISTRATION_PERIOD = 0x0242;
+    static constexpr std::uint16_t EGTS_MODE_END_DISTANCE = 0x020A;
+    //service station mode
+    static constexpr std::uint16_t EGTS_GARAGE_MODE_END_DISTANCE = 0x020B;
+    static constexpr std::uint16_t EGTS_GARAGE_MODE_PIN = 0x020C;
+    //Miscellaneous parameters
+    static constexpr std::uint16_t EGTS_GNSS_POWER_OFF_TIME = 0x0301;
+    static constexpr std::uint16_t EGTS_GNSS_DATA_RATE = 0x0302;
+    static constexpr std::uint16_t EGTS_GNSS_MIN_ELEVATION = 0x0303;
+    //Device parameters
+    static constexpr std::uint16_t EGTS_UNIT_ID = 0x0404;
+    static constexpr std::uint16_t EGTS_UNIT_IMEI = 0x0405;
+    static constexpr std::uint16_t EGTS_UNIT_RS485_BAUD_RATE = 0x0406;
+    static constexpr std::uint16_t EGTS_UNIT_RS485_STOP_BITS = 0x0407;
+    static constexpr std::uint16_t EGTS_UNIT_RS485_PARITY = 0x0408;
+    static constexpr std::uint16_t EGTS_UNIT_HOME_DISPATCHER_ID = 0x0411;
+    static constexpr std::uint16_t EGTS_SERVICE_AUTH_METHOD = 0x0412;
+    static constexpr std::uint16_t EGTS_SERVER_CHECK_IN_PERIOD = 0x0413;
+    static constexpr std::uint16_t EGTS_SERVER_CHECK_IN_ATTEMPTS = 0x0414;
+    static constexpr std::uint16_t EGTS_SERVER_PACKET_TOUT = 0x0415;
+    static constexpr std::uint16_t EGTS_SERVER_PACKET_RETRANSMIT_ATTEMPTS = 0x0416;
+    static constexpr std::uint16_t EGTS_UINT_MIC_LEVEL = 0x0417;
+    static constexpr std::uint16_t EGTS_UINT_SPK_LEVEL = 0x0418;
+};
+
+#endif /* SSLP_COMMANDS_CMDUTILS_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/commands/CommandAck.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/commands/CommandAck.cpp
new file mode 100644
index 0000000..1167a0b
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/commands/CommandAck.cpp
@@ -0,0 +1,82 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include "CommandAck.h"
+#include "../../utils/GostEcallUtils.h"
+#include "CmdUtils.h"
+
+using namespace std;
+
+#undef LOG_TAG
+#define LOG_TAG "DEMO_EGOST_CommandAck"
+
+CommandAck::CommandAck() {
+    ADR = 0x0000;
+    CCD = UINT16_MAX;
+    DT = ""; //O (0,65200)
+
+}
+
+CommandAck::~CommandAck() {
+    // TODO Auto-generated destructor stub
+}
+
+std::uint16_t CommandAck::getAdr() const {
+    return ADR;
+}
+
+void CommandAck::setAdr(std::uint16_t adr) {
+    ADR = adr;
+}
+
+std::uint16_t CommandAck::getCcd() const {
+    return CCD;
+}
+
+void CommandAck::setCcd(std::uint16_t ccd) {
+    CCD = ccd;
+}
+
+const std::string& CommandAck::getDt() const {
+    return DT;
+}
+
+int CommandAck::decodeCmdAckDt() {
+    return 0;
+}
+
+void CommandAck::setDt(const std::string dt) {
+    DT = dt;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/commands/CommandAck.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/commands/CommandAck.h
new file mode 100644
index 0000000..d3286fa
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/commands/CommandAck.h
@@ -0,0 +1,68 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef SSLP_COMMANDS_COMMANDACK_H_
+#define SSLP_COMMANDS_COMMANDACK_H_
+
+#include <cstdint>
+#include <string>
+#include <vector>
+#include <memory>
+
+#include "../ecall/EcallUtils.h"
+
+//p39, table 31
+class CommandAck {
+public:
+    CommandAck();
+    virtual ~CommandAck();
+    int decodeCmdAckDt();
+    std::uint16_t getAdr() const;
+    void setAdr(std::uint16_t adr);
+    std::uint16_t getCcd() const;
+    void setCcd(std::uint16_t ccd);
+    const std::string& getDt() const;
+    void setDt(const std::string dt);
+
+private:
+    std::shared_ptr<EcallUtils> mEnEcallUtils;
+    std::uint16_t ADR;
+    std::uint16_t CCD; //table32 ,table43
+    std::string DT; //O (0,65200) //table 33
+    //std::vector<std::uint8_t> DT; //O (0,65200)
+
+};
+
+#endif /* SSLP_COMMANDS_COMMANDACK_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/commands/CommandBody.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/commands/CommandBody.cpp
new file mode 100644
index 0000000..3bf5e20
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/commands/CommandBody.cpp
@@ -0,0 +1,143 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include "CommandBody.h"
+#include "../../utils/GostEcallUtils.h"
+
+using namespace std;
+
+#undef LOG_TAG
+#define LOG_TAG "DEMO_EGOST_CommandBody"
+
+CommandBody::CommandBody() {
+    ADR  = UINT16_MAX;
+
+    //8bit
+    SzAct = UINT8_MAX;
+    SZ = UINT8_MAX; //4bit
+    ACT = UINT8_MAX; //4bit
+
+    CCD = UINT16_MAX;
+    DT = "";  //O
+}
+
+CommandBody::~CommandBody() {
+    // TODO Auto-generated destructor stub
+}
+
+std::uint8_t CommandBody::getAct() const {
+    return ACT;
+}
+
+void CommandBody::setAct(std::uint8_t act) {
+    ACT = act;
+}
+
+std::uint16_t CommandBody::getAdr() const {
+    return ADR;
+}
+
+void CommandBody::setAdr(std::uint16_t adr) {
+    ADR = adr;
+}
+
+std::uint16_t CommandBody::getCcd() const {
+    return CCD;
+}
+
+void CommandBody::setCcd(std::uint16_t ccd) {
+    CCD = ccd;
+}
+
+const std::string& CommandBody::getDt() const {
+    return DT;
+}
+
+void CommandBody::setDt(const std::string dt) {
+    DT = dt;
+}
+
+std::uint8_t CommandBody::getSz() const {
+    return SZ;
+}
+
+void CommandBody::setSz(std::uint8_t sz) {
+    SZ = sz;
+}
+
+std::uint8_t CommandBody::getSzAct() const {
+    return SzAct;
+}
+
+void CommandBody::setSzAct(std::uint8_t szAct) {
+    SzAct = szAct;
+}
+
+int CommandBody::decodeCmdDt() {
+    if (EcallUtils::isEcallCmd(CCD)) {
+        deEcallUtils = std::make_shared<EcallUtils>();
+        deEcallUtils->decodeECallCmd(CCD, DT);
+    } else if (CmdUtils::isCmdCommands(CCD)) {
+        deCmdUtils = std::make_shared<CmdUtils>();
+        deCmdUtils->decodeCmdCommand(CCD, DT);
+    } else {
+        MTK_RLOGW("don't support, return");
+    }
+    return 0;
+}
+
+bool CommandBody::isIncludedCmdCode(std::uint16_t cmd) {
+    bool ret = (cmd == CCD);
+    MTK_RLOGD("cmd=0X%04X, ccd=0X%04X, ret: %d", cmd, CCD, ret);
+    return ret;
+}
+
+bool CommandBody::isNeedNewSms() {
+    MTK_RLOGD("ccd=0X%04X", CCD);
+    if(!deEcallUtils) {
+        MTK_RLOGW("no decode ecall utils");
+        return false;
+    }
+    return deEcallUtils->isNeedNewSms();
+}
+
+int CommandBody::getEcallReqPara() {
+    MTK_RLOGD("ccd=0X%04X", CCD);
+    if(!deEcallUtils) {
+        MTK_RLOGW("no decode ecall utils");
+        return 0;
+    }
+    return deEcallUtils->getEcallReqPara();
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/commands/CommandBody.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/commands/CommandBody.h
new file mode 100644
index 0000000..7a791e4
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/commands/CommandBody.h
@@ -0,0 +1,91 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef SSLP_COMMANDS_COMMANDBODY_H_
+#define SSLP_COMMANDS_COMMANDBODY_H_
+
+#include <cstdint>
+#include <string>
+#include <vector>
+#include <memory>
+
+#include "../ecall/EcallUtils.h"
+#include "CmdUtils.h"
+
+//p39, table 30
+class CommandBody {
+public:
+    CommandBody();
+    virtual ~CommandBody();
+    int decodeCmdDt();
+    std::uint8_t getAct() const;
+    void setAct(std::uint8_t act);
+    std::uint16_t getAdr() const;
+    void setAdr(std::uint16_t adr);
+    std::uint16_t getCcd() const;
+    void setCcd(std::uint16_t ccd);
+    const std::string& getDt() const;
+    void setDt(const std::string dt);
+    std::uint8_t getSz() const;
+    void setSz(std::uint8_t sz);
+    std::uint8_t getSzAct() const;
+    void setSzAct(std::uint8_t szAct);
+    bool isIncludedCmdCode(std::uint16_t cmd);
+    bool isNeedNewSms();
+    int getEcallReqPara();
+private:
+    std::shared_ptr<CmdUtils> deCmdUtils;
+    std::shared_ptr<EcallUtils> deEcallUtils;
+
+    std::uint16_t ADR;
+
+    //8bit
+    std::uint8_t SzAct;
+    std::uint8_t SZ; //4bit
+    std::uint8_t ACT; //4bit
+
+    std::uint16_t CCD;
+    std::string DT;  //O
+    //std::vector<std::uint8_t> DT; //O
+
+    //ACT(action)
+    static constexpr std::uint8_t COMMAND_PARA = 0;
+    static constexpr std::uint8_t QUERY_VALUE = 1;
+    static constexpr std::uint8_t SET_VALUE = 2;
+    static constexpr std::uint8_t ADD_NEW_PARA = 3;
+    static constexpr std::uint8_t REMOVE_EXIST_PARA = 4;
+};
+
+#endif /* SSLP_COMMANDS_COMMANDBODY_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/commands/SrComDataFormat.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/commands/SrComDataFormat.cpp
new file mode 100644
index 0000000..79f3c3b
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/commands/SrComDataFormat.cpp
@@ -0,0 +1,393 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include <bitset>
+#include <memory>
+
+#include "SrComDataFormat.h"
+#include "../../utils/GostEcallUtils.h"
+#include "CmdUtils.h"
+
+using namespace std;
+
+#undef LOG_TAG
+#define LOG_TAG "DEMO_EGOST_SrComDataFmt"
+
+//CT: command type
+const std::uint8_t SrComDataFormat::CT_COMCONF;
+const std::uint8_t SrComDataFormat::CT_MSGCONF;
+const std::uint8_t SrComDataFormat::CT_MSGFROM;
+const std::uint8_t SrComDataFormat::CT_MSGTO;
+const std::uint8_t SrComDataFormat::CT_COM;
+const std::uint8_t SrComDataFormat::CT_DELCOM;
+const std::uint8_t SrComDataFormat::CT_SUBREQ;
+const std::uint8_t SrComDataFormat::CT_DELIV;
+
+//CCT-type fo acknowledgement (make sense for CT_COMCONF, CT_MSGCONF, or CT_DELIV commands)
+const std::uint8_t SrComDataFormat::CC_OK;
+const std::uint8_t SrComDataFormat::CC_ERROR;
+const std::uint8_t SrComDataFormat::CC_ILL;
+const std::uint8_t SrComDataFormat::CC_DEL;
+const std::uint8_t SrComDataFormat::CC_NFOUND;
+const std::uint8_t SrComDataFormat::CC_NCONF;
+const std::uint8_t SrComDataFormat::CC_INPROG;
+
+//CHS -character encoding used in the CD field that contains the command body
+const std::uint8_t SrComDataFormat::cp_1251;
+const std::uint8_t SrComDataFormat::IA5;
+const std::uint8_t SrComDataFormat::binary_data;
+const std::uint8_t SrComDataFormat::Latin1;
+const std::uint8_t SrComDataFormat::binary_data_2;
+const std::uint8_t SrComDataFormat::JIS;
+const std::uint8_t SrComDataFormat::cyrillic;
+const std::uint8_t SrComDataFormat::latin_Hebrew;
+const std::uint8_t SrComDataFormat::UCS2;
+
+SrComDataFormat::SrComDataFormat() {
+    type = UINT8_MAX;
+    CT = UINT8_MAX; //4bit
+    CCT = UINT8_MAX;//4bit
+
+    CID = UINT32_MAX;
+    SID = UINT32_MAX;
+
+    fileExs = UINT8_MAX;
+    ACFE = 0; //1bit
+    CHSFE = 0; //1bit
+
+    CHS = UINT8_MAX; // O (CHSFE)
+    ACL = 0; //O (ACFE)
+    std::string AC = ""; //O (0, 255)
+    std::string CD = ""; //O (0, 65205)
+
+}
+
+SrComDataFormat::~SrComDataFormat() {
+    // TODO Auto-generated destructor stub
+}
+
+const std::string& SrComDataFormat::getAc() const {
+    return AC;
+}
+
+void SrComDataFormat::setAc(const std::string ac) {
+    AC = ac;
+}
+
+std::uint8_t SrComDataFormat::getAcfe() const {
+    return ACFE;
+}
+
+void SrComDataFormat::setAcfe(std::uint8_t acfe) {
+    ACFE = acfe;
+}
+
+std::uint8_t SrComDataFormat::getAcl() const {
+    return ACL;
+}
+
+void SrComDataFormat::setAcl(std::uint8_t acl) {
+    ACL = acl;
+}
+
+std::uint8_t SrComDataFormat::getCct() const {
+    return CCT;
+}
+
+void SrComDataFormat::setCct(std::uint8_t cct) {
+    CCT = cct;
+}
+
+const std::string& SrComDataFormat::getCd() const {
+    return CD;
+}
+
+void SrComDataFormat::setCd(const std::string cd) {
+    CD = cd;
+}
+
+std::uint8_t SrComDataFormat::getChs() const {
+    return CHS;
+}
+
+void SrComDataFormat::setChs(std::uint8_t chs) {
+    CHS = chs;
+}
+
+std::uint8_t SrComDataFormat::getChsfe() const {
+    return CHSFE;
+}
+
+void SrComDataFormat::setChsfe(std::uint8_t chsfe) {
+    CHSFE = chsfe;
+}
+
+std::uint32_t SrComDataFormat::getCid() const {
+    return CID;
+}
+
+void SrComDataFormat::setCid(std::uint32_t cid) {
+    CID = cid;
+}
+
+std::uint8_t SrComDataFormat::getCt() const {
+    return CT;
+}
+
+void SrComDataFormat::setCt(std::uint8_t ct) {
+    CT = ct;
+}
+
+std::uint8_t SrComDataFormat::getFileExs() const {
+    return fileExs;
+}
+
+void SrComDataFormat::setFileExs(std::uint8_t fileExs) {
+    this->fileExs = fileExs;
+}
+
+std::uint32_t SrComDataFormat::getSid() const {
+    return SID;
+}
+
+void SrComDataFormat::setSid(std::uint32_t sid) {
+    SID = sid;
+}
+
+std::uint8_t SrComDataFormat::getType() const {
+    return type;
+}
+
+void SrComDataFormat::setType(std::uint8_t type) {
+    this->type = type;
+}
+
+int SrComDataFormat::getEcallReqPara() {
+    if(!mCmdBody) {
+        MTK_RLOGW("no decode command body sub records");
+        return 0;
+    }
+    return mCmdBody->getEcallReqPara();
+}
+
+int SrComDataFormat::decodeCtComCfg() {
+    uint32_t index = 0;
+    int64_t ret = 0;
+    mCmdAck = std::make_shared<CommandAck>();
+
+    //ADR(address)
+    ret = decodeValue(CD, index, 4, "ADR(address)");
+    if (ret == -1) {
+        MTK_RLOGW("decode ADR fail");
+        return -1;
+    }
+    MTK_RLOGD("index: %d, ADR: 0X%04x", index, (uint16_t )ret);
+    mCmdAck->setAdr((uint16_t) (ret));
+
+    //CCD(command code)
+    ret = decodeValue(CD, index, 4, "CCD(command code)");
+    if (ret == -1) {
+        MTK_RLOGW("decode CCD fail");
+        return -1;
+    }
+    MTK_RLOGD("index: %d, CCD: 0X%04x", index, (uint16_t )ret);
+    mCmdAck->setCcd((uint16_t) (ret));
+
+    //DT(data)
+    if (index < CD.size()) {
+        std::string sub = CD.substr(index);
+        mCmdAck->setDt(sub);
+        ret = mCmdAck->decodeCmdAckDt();
+        if (ret == -1) {
+            MTK_RLOGW("decode decodeCmdDt fail");
+            return -1;
+        }
+    }
+    return 0;
+}
+
+int SrComDataFormat::decodeCtCom() {
+    uint32_t index = 0;
+    int64_t ret = 0;
+    mCmdBody = std::make_shared<CommandBody>();
+
+    //ADR(address)
+    ret = decodeValue(CD, index, 4, "ADR(address)");
+    if (ret == -1) {
+        MTK_RLOGW("decode ADR fail");
+        return -1;
+    }
+    MTK_RLOGD("index: %d, ADR: 0X%04x", index, (uint16_t )ret);
+    mCmdBody->setAdr((uint16_t) (ret));
+
+    //decode CommandBody->SzAct
+    ret = decodeValue(CD, index, 2, "CommandBody->SzAct");
+    if (ret == -1) {
+        MTK_RLOGW("decode SzAct fail");
+        return -1;
+    }
+    MTK_RLOGD("index: %d, SzAct: 0X%02x", index, (uint8_t )ret);
+    mCmdBody->setSzAct((uint8_t) ((ret)));
+    bitset<8> tmp(mCmdBody->getSzAct());
+    mCmdBody->setSz((tmp[7] << 3) | (tmp[6]) << 2 | (tmp[5] << 1) | tmp[4]);
+    mCmdBody->setAct((tmp[3] << 3) | (tmp[2]) << 2 | (tmp[1] << 1) | tmp[0]);
+    MTK_RLOGD("index: %d, ct=0X%02X, cct=0X%02X", index, mCmdBody->getSz(),mCmdBody->getAct());
+
+    //CCD(command code)
+    ret = decodeValue(CD, index, 4, "CCD(command code)");
+    if (ret == -1) {
+        MTK_RLOGW("decode CCD fail");
+        return -1;
+    }
+    MTK_RLOGD("index: %d, CCD: 0X%04x", index, (uint16_t )ret);
+    mCmdBody->setCcd((uint16_t) (ret));
+
+    //DT(data)
+    if (index < CD.size()) {
+        std::string sub = CD.substr(index);
+        mCmdBody->setDt(sub);
+        ret = mCmdBody->decodeCmdDt();
+        if (ret == -1) {
+            MTK_RLOGW("decode decodeCmdDt fail");
+            return -1;
+        }
+    }
+    return 0;
+}
+
+int SrComDataFormat::decodeSrCmomDt() {
+    //TBD .check CHS(charset) of  CD(command data) ? how to handle ?
+    if(CD.empty()) {
+        MTK_RLOGW("CD is empty");
+        return 0;
+    }
+    MTK_RLOGD("CT=0X%02X, CCT = %02X,, CD: %s ", CT, CCT, CD.c_str());
+    if(CT == CT_COM) {
+        int ret = decodeCtCom();
+        if(ret == -1) {
+            MTK_RLOGW("decodeCtCom fail , just return");
+            return -1;
+        }
+    } else if(CT == CT_COMCONF) {
+        int ret = decodeCtComCfg();
+        if(ret == -1) {
+            MTK_RLOGW("decodeCtComCfg fail , just return");
+            return -1;
+        }
+    } else {
+        MTK_RLOGW("CT(%d) don't define", CT);
+    }
+    return 0;
+}
+
+std::string SrComDataFormat::ct2str(uint8_t ct) {
+    MTK_RLOGD("ct: %d", ct);
+    switch(ct) {
+    case CT_COMCONF : return "acknowledgement of command";
+    case CT_MSGCONF : return "acknowledement of message";
+    case CT_MSGFROM : return "information message from IVDS";
+    case CT_MSGTO   : return "information message for output to vehicle display device";
+    case CT_COM     : return "command to be executed on the vehicle";
+    case CT_DELCOM  : return "deleting the previous command from the execution queue";
+    case CT_SUBREQ  : return "additional sub-request for execution(for a command sent before)";
+    case CT_DELIV   : return "acknowledgement of command/message delivery";
+    default: return "unknown";
+    }
+}
+
+std::string SrComDataFormat::cct2str(uint8_t cct) {
+    MTK_RLOGD("cct: %d", cct);
+    switch(cct) {
+    case CC_OK     : return "successful completion, positive response";
+    case CC_ERROR  : return "processing failed";
+    case CC_ILL    : return "command can not be executed";
+    case CC_DEL    : return "command deleted successfully";
+    case CC_NFOUND : return "command to be deleted isn't found";
+    case CC_NCONF  : return "successful execution, negative response";
+    case CC_INPROG : return "command dispatched for processing";
+    default: return "unknown";
+    }
+}
+
+bool SrComDataFormat::isIncludedCmdCode(std::uint16_t cmd) {
+    MTK_RLOGD("cmd=0X%04X", cmd);
+    if(!mCmdBody) {
+        MTK_RLOGW("no decode command body sub records");
+        return false;
+    }
+    return mCmdBody->isIncludedCmdCode(cmd);
+}
+
+//std::string encodeValue(int64_t value, uint8_t charset, const std::string tag);
+std::string SrComDataFormat::encode(std::uint16_t cmd, bool ack) {
+    MTK_RLOGD("cmd=0X%04X, cct=%u, ct=%u, ack=%d", cmd, CCT, CT, ack);
+    if(!mCmdBody) {
+        MTK_RLOGW("no decode command body sub records");
+        return "";
+    }
+    bool ret = mCmdBody->isIncludedCmdCode(cmd);
+    if(ret) {
+        //encode CT and CCT
+        if(CT != CT_COM) {
+            MTK_RLOGW("no CT_COM, don't support");
+            return "";
+        }
+        uint8_t value = (CT_COMCONF << 4) + (ack ? CC_OK : CC_ERROR);
+        std::string ctCct = encodeValue(value, 2, "CT&CCT");
+
+        //encode CID
+        std::string cid = encodeValue(CID, 8, "CID");
+        MTK_RLOGD("encode CID(0X%04X) result: %s",CID, cid.c_str());
+
+        //encode SID;
+        std::string sid = encodeValue(SID, 8, "SID");
+        MTK_RLOGD("encode SID(0X%04X) result: %s",SID, sid.c_str());
+
+        //encode ACFE&CHSFE
+        bitset<8> flag;
+        std::string fe = encodeValue(flag.to_ulong(), 2, "ACFE&CHSF");
+        MTK_RLOGD("encode ACFE&CHSFE(0X%02X) result: %s",flag.to_ulong(), fe.c_str());
+        return ctCct + cid + sid + fe;
+    }
+    return "";
+}
+
+bool SrComDataFormat::isNeedNewSms() {
+    if(!mCmdBody) {
+        MTK_RLOGW("no decode command body sub records");
+        return false;
+    }
+    return mCmdBody->isNeedNewSms();
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/commands/SrComDataFormat.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/commands/SrComDataFormat.h
new file mode 100644
index 0000000..bab5e68
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/commands/SrComDataFormat.h
@@ -0,0 +1,139 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include <cstdint>
+#include <string>
+#include <vector>
+#include <memory>
+
+#include "CommandBody.h"
+#include "CommandAck.h"
+
+#ifndef SRCOMDATAFORMAT_H_
+#define SRCOMDATAFORMAT_H_
+
+//p37, table 28
+class SrComDataFormat {
+public:
+    SrComDataFormat();
+    virtual ~SrComDataFormat();
+    int decodeSrCmomDt();
+    const std::string& getAc() const;
+    void setAc(const std::string ac);
+    std::uint8_t getAcfe() const;
+    void setAcfe(std::uint8_t acfe);
+    std::uint8_t getAcl() const;
+    void setAcl(std::uint8_t acl);
+    std::uint8_t getCct() const;
+    void setCct(std::uint8_t cct);
+    const std::string& getCd() const;
+    void setCd(const std::string cd);
+    std::uint8_t getChs() const;
+    void setChs(std::uint8_t chs);
+    std::uint8_t getChsfe() const;
+    void setChsfe(std::uint8_t chsfe);
+    std::uint32_t getCid() const;
+    void setCid(std::uint32_t cid);
+    std::uint8_t getCt() const;
+    void setCt(std::uint8_t ct);
+    std::uint8_t getFileExs() const;
+    void setFileExs(std::uint8_t fileExs);
+    std::uint32_t getSid() const;
+    void setSid(std::uint32_t sid);
+    std::uint8_t getType() const;
+    void setType(std::uint8_t type);
+    bool isIncludedCmdCode(std::uint16_t cmd);
+    std::string encode(std::uint16_t cmd, bool ack);
+    bool isNeedNewSms();
+    int getEcallReqPara();
+private:
+
+    std::shared_ptr<CommandBody> mCmdBody;
+    std::shared_ptr<CommandAck> mCmdAck;
+
+    std::uint8_t type;
+    std::uint8_t CT; //4bit
+    std::uint8_t CCT;//4bit
+
+    std::uint32_t CID;
+    std::uint32_t SID;
+
+    std::uint8_t fileExs;
+    std::uint8_t ACFE; //1bit
+    std::uint8_t CHSFE; //1bit
+
+    std::uint8_t CHS; // O (CHSFE)
+    std::uint8_t ACL; //O (ACFE)
+    //std::vector<std::uint8_t> AC; //O (0, 255)
+    //std::vector<std::uint8_t> CD; //O (0, 65205)
+    std::string AC; //O (0, 255)
+    std::string CD; //O (0, 65205)
+
+    std::string ct2str(uint8_t ct);
+    std::string cct2str(uint8_t cct);
+    int decodeCtCom();
+    int decodeCtComCfg();
+
+    //CT: command type
+    static const std::uint8_t CT_COMCONF = 0b0001;
+    static const std::uint8_t CT_MSGCONF = 0b0010;
+    static const std::uint8_t CT_MSGFROM = 0b0011;
+    static const std::uint8_t CT_MSGTO = 0b0100;
+    static const std::uint8_t CT_COM = 0b0101;
+    static const std::uint8_t CT_DELCOM = 0b0110;
+    static const std::uint8_t CT_SUBREQ = 0b0111;
+    static const std::uint8_t CT_DELIV = 0b1000;
+
+    //CCT-type fo acknowledgement (make sense for CT_COMCONF, CT_MSGCONF, or CT_DELIV commands)
+    static const std::uint8_t CC_OK = 0b0000;
+    static const std::uint8_t CC_ERROR = 0b0001;
+    static const std::uint8_t CC_ILL = 0b0010;
+    static const std::uint8_t CC_DEL = 0b0011;
+    static const std::uint8_t CC_NFOUND = 0b0100;
+    static const std::uint8_t CC_NCONF = 0b0101;
+    static const std::uint8_t CC_INPROG = 0b0110;
+
+    //CHS -character encoding used in the CD field that contains the command body
+    static const std::uint8_t cp_1251     = 0;
+    static const std::uint8_t IA5         = 1;
+    static const std::uint8_t binary_data = 2;
+    static const std::uint8_t Latin1      = 3;
+    static const std::uint8_t binary_data_2 = 4;
+    static const std::uint8_t JIS         = 5;
+    static const std::uint8_t cyrillic    = 6;
+    static const std::uint8_t latin_Hebrew= 7;
+    static const std::uint8_t  UCS2        = 8;
+};
+
+#endif /* SRCOMDATAFORMAT_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/ecall/EcallUtils.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/ecall/EcallUtils.cpp
new file mode 100644
index 0000000..e23174f
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/ecall/EcallUtils.cpp
@@ -0,0 +1,224 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include "EcallUtils.h"
+#include "../../utils/GostEcallUtils.h"
+using namespace std;
+
+#undef LOG_TAG
+#define LOG_TAG "DEMO_EGOST_EcallUtils"
+
+EcallUtils::EcallUtils() {
+    // TODO Auto-generated constructor stub
+
+}
+
+EcallUtils::~EcallUtils() {
+    // TODO Auto-generated destructor stub
+}
+
+const std::string& EcallUtils::getEcallMsdReq() const {
+    return ecallMsdReq;
+}
+
+void EcallUtils::setEcallMsdReq(const std::string ecallMsdReq) {
+    this->ecallMsdReq = ecallMsdReq;
+}
+
+std::uint8_t EcallUtils::getEcallReq() const {
+    return ecallReq;
+}
+
+void EcallUtils::setEcallReq(std::uint8_t ecallReq) {
+    this->ecallReq = ecallReq;
+}
+
+std::int32_t EcallUtils::getMid() const {
+    return mid;
+}
+
+void EcallUtils::setMid(std::int32_t mid) {
+    this->mid = mid;
+}
+
+std::uint8_t EcallUtils::getTransport() const {
+    return transport;
+}
+
+void EcallUtils::setTransport(std::uint8_t transport) {
+    this->transport = transport;
+}
+
+int EcallUtils::decodeMsgReq(const string& data) {
+    if (data.empty()) {
+        MTK_RLOGD("data is invalid, return");
+        return -1;
+    }
+    MTK_RLOGD("data: %s", data.c_str());
+    uint32_t index = 0;
+    int64_t ret = 0;
+    //MID(message identifier)
+    ret = decodeValue(data, index, 8, "MID(message identifier)");
+    if (ret == -1) {
+        MTK_RLOGW("decode MID fail");
+        return -1;
+    }
+    MTK_RLOGD("index: %d, MID: %d", index, (int32_t )ret);
+    mid = (int32_t) (ret);
+    //transport
+    ret = decodeValue(data, index, 2, "transport");
+    if (ret == -1) {
+        MTK_RLOGW("decode transport fail");
+        return -1;
+    }
+    MTK_RLOGD("index: %d, transport: %u", index, (uint8_t )ret);
+    transport = (uint8_t) (ret);
+    ecallMsdReq = data;
+    if(data.size() != index) {
+        MTK_RLOGW("maybe error data.size(%d) != index", data.size(), index);
+        return -1;
+    }
+    return 0;
+}
+
+const std::string& EcallUtils::getNumber() const {
+    return number;
+}
+
+void EcallUtils::setNumber(const std::string number) {
+    this->number = number;
+}
+
+int EcallUtils::decodeReq(const string& data) {
+    if (data.empty()) {
+        MTK_RLOGD("data is invalid, return");
+        return -1;
+    }
+    MTK_RLOGD("data: %s", data.c_str());
+    uint32_t index = 0;
+    int64_t ret = 0;
+
+    //ecallReq
+    ret = decodeValue(data, index, 2, "ecallReq");
+    if (ret == -1) {
+        MTK_RLOGW("decode ecallReq fail");
+        return -1;
+    }
+    MTK_RLOGD("index: %d, ecallReq: %u", index, (uint8_t )ret);
+    ecallReq = (uint8_t) (ret);
+    return 0;
+}
+
+int EcallUtils::decodeECallCmd(std::uint16_t cmd, const string& data) {
+    MTK_RLOGD("cmd=0X%02X, data: %s", cmd, (data.empty() ? "": data.c_str()));
+    if(cmd == EGTS_ECALL_MSD_REQ) {
+        int ret = decodeMsgReq(data);
+        if(ret == -1) {
+            MTK_RLOGW("decodeMsgReq() fail");
+            return -1;
+        }
+    } else if(cmd == EGTS_ECALL_REQ) {
+        int ret = decodeReq(data);
+        if(ret == -1) {
+            MTK_RLOGW("decodeReq() fail");
+            return -1;
+        }
+    } else if(cmd == EGTS_ECALL_DEREGISTRATION) {
+        MTK_RLOGD("decocde EGTS_ECALL_DEREGISTRATION success");
+        return 0;
+    } else {
+        MTK_RLOGW("don't support, just return");
+    }
+    return 0;
+}
+
+bool EcallUtils::isEcallCmd(std::uint16_t cmd) {
+    MTK_RLOGD("cmd=0X%02X", cmd);
+    switch (cmd) {
+    case EGTS_ECALL_REQ:
+    case EGTS_ECALL_MSD_REQ:
+    case EGTS_ACCEL_DATA:
+    case EGTS_TRACK_DATA:
+    case EGTS_ECALL_DEREGISTRATION:
+        ///General-purpose settings
+    case EGTS_ECALL_TEST_NUMBER:
+        //service configuration and configuration data. Base Service of Road Accident Emergency Response System.
+    case EGTS_ECALL_ON:
+    case EGTS_ECALL_CRASH_SIGNAL_INTERNAL:
+    case EGTS_ECALL_CRASH_SIGNAL_EXTERNAL:
+    case EGTS_ECALL_SOS_BUTTON_TIME:
+    case EGTS_ECALL_NO_AUTOMATIC_TRIGGERING:
+    case EGTS_ASI15_TRESHOLD:
+    case EGTS_ECALL_MODE_PIN:
+    case EGTS_ECALL_CCFT:
+    case EGTS_ECALL_INVITATION_SIGNAL_DURATION:
+    case EGTS_ECALL_SEND_MSG_PERIOD:
+    case EGTS_ECALL_AL_ACK_PERIOD:
+    case EGTS_ECALL_MSD_MAX_TRANSMISSON_TIME:
+    case EGTS_ECALL_NAD_DEREGISTRATION_TIMER:
+    case EGTS_ECALL_DIAL_DURATION:
+    case EGTS_ECALL_AUTO_DIAL_ATTEMPTS:
+    case EGTS_ECALL_MANUAL_DIAL_ATTEMPTS:
+    case EGTS_ECALL_MANUAL_CAN_CANCEL:
+    case EGTS_ECALL_SMS_FALLBACK_NUMBER:
+        //Acceleration profile recording in case of road accidents
+    case IGNITION_OFF_FOLLOW_UP_TIME1:
+    case IGNITION_OFF_FOLLOW_UP_TIME2:
+    case EGTS_CRASH_RECORD_TIME:
+    case EGTS_CRASH_RECORD_RESOLUTION:
+    case EGTS_CRASH_PRE_RECORD_TIME:
+    case EGTS_CRASH_PRE_RECORD_RESOLUTION:
+    case EGTS_TRACK_RECORD_TIME:
+    case EGTS_TRACK_PRE_RECORD_TIME:
+    case EGTS_TRACK_RECORD_RESOLUTION:
+        //vehicle parameters
+    case EGTS_VEHICLE_VIN:
+    case EGTS_VEHICLE_PROPULSION_STORAGE_TYPE:
+    case EGTS_VEHICLE_TYPE: {
+        return true;
+    }
+    }
+    return false;
+}
+
+bool EcallUtils::isNeedNewSms() {
+    MTK_RLOGD("transport = %d", transport);
+    return (transport == 2);
+}
+
+int EcallUtils::getEcallReqPara() {
+    MTK_RLOGD("ecallReq = %d", ecallReq);
+    return ecallReq;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/ecall/EcallUtils.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/ecall/EcallUtils.h
new file mode 100644
index 0000000..d34604e
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/ecall/EcallUtils.h
@@ -0,0 +1,139 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef SSLP_ECALL_ECALLUTILS_H_
+#define SSLP_ECALL_ECALLUTILS_H_
+
+#include <cstdint>
+#include <string>
+
+class EcallUtils {
+public:
+    EcallUtils();
+    virtual ~EcallUtils();
+    const std::string& getEcallMsdReq() const;
+    void setEcallMsdReq(const std::string ecallMsdReq);
+    std::uint8_t getEcallReq() const;
+    void setEcallReq(std::uint8_t ecallReq);
+    std::int32_t getMid() const;
+    void setMid(std::int32_t mid);
+    std::uint8_t getTransport() const;
+    void setTransport(std::uint8_t transport);
+
+    int decodeECallCmd(std::uint16_t cmd, const std::string& data);
+
+    static bool isEcallCmd(std::uint16_t cmd);
+    const std::string& getNumber() const;
+    void setNumber(const std::string number);
+    bool isNeedNewSms();
+    int getEcallReqPara();
+public:
+
+    //EGTS_ECALL_SERVICE  7.2 47page , accident emergency response service
+    static constexpr std::uint8_t EGTS_SR_RECORD_RESPONSE=0; // EGTS_PT_APPDATA_type
+    static constexpr std::uint8_t  EGTS_SR_ACCEL_DATA = 20; //GPRS transfer
+    static constexpr std::uint8_t EGTS_SR_RAW_MSD_DATA = 40;
+    static constexpr std::uint8_t EGTS_SR_RAW_TRACK_DATA = 62; //GPRS transfer
+
+private:
+    //EGTS_ECALL_REQ
+    std::uint8_t ecallReq = 0;
+
+    //EGTS_ECALL_MSD_REQ
+    std::string ecallMsdReq = "";
+    std::int32_t mid = 0;
+    std::uint8_t transport = 2;
+
+    //EGTS_ECALL_SMS_FALLBACK_NUMBER
+    std::string number = "112";
+
+    int decodeMsgReq(const std::string& data);
+    int decodeReq(const std::string& data);
+
+public:
+    //List of commands sent to IVDS table46 p52.
+    //parameters. uint8_t , 0 - manual call; 1-automatic call
+    static constexpr std::uint16_t EGTS_ECALL_REQ = 0x0112;
+    //parameters. int32_t MID: message identifier of the requested MSD.
+    //            uint8_t TRANSPORT: 0-any, to be selected by the IVDS, 2-SMS
+    static constexpr std::uint16_t EGTS_ECALL_MSD_REQ = 0x0113;
+    static constexpr std::uint16_t EGTS_ACCEL_DATA = 0x0114;
+    static constexpr std::uint16_t EGTS_TRACK_DATA = 0x0115;
+    static constexpr std::uint16_t EGTS_ECALL_DEREGISTRATION = 0x116;
+
+    //list of IVDS parameters.table47 p52
+
+    ///General-purpose settings
+    static constexpr std::uint16_t EGTS_ECALL_TEST_NUMBER = 0x020D;
+
+    //service configuration and configuration data. Base Service of Road Accident Emergency Response System.
+    static constexpr std::uint16_t EGTS_ECALL_ON = 0x0210;
+    static constexpr std::uint16_t EGTS_ECALL_CRASH_SIGNAL_INTERNAL = 0x0211;
+    static constexpr std::uint16_t EGTS_ECALL_CRASH_SIGNAL_EXTERNAL = 0x0212;
+    static constexpr std::uint16_t EGTS_ECALL_SOS_BUTTON_TIME = 0x0213;
+    static constexpr std::uint16_t EGTS_ECALL_NO_AUTOMATIC_TRIGGERING = 0x0214;
+    static constexpr std::uint16_t EGTS_ASI15_TRESHOLD = 0x0215;
+    static constexpr std::uint16_t EGTS_ECALL_MODE_PIN = 0x0216;
+    static constexpr std::uint16_t EGTS_ECALL_CCFT = 0x0217;
+    static constexpr std::uint16_t EGTS_ECALL_INVITATION_SIGNAL_DURATION = 0x0218;
+    static constexpr std::uint16_t EGTS_ECALL_SEND_MSG_PERIOD = 0x0219;
+    static constexpr std::uint16_t EGTS_ECALL_AL_ACK_PERIOD = 0x021A;
+    static constexpr std::uint16_t EGTS_ECALL_MSD_MAX_TRANSMISSON_TIME = 0x021B;
+    static constexpr std::uint16_t EGTS_ECALL_NAD_DEREGISTRATION_TIMER = 0x021D;
+    static constexpr std::uint16_t EGTS_ECALL_DIAL_DURATION = 0x021E;
+    static constexpr std::uint16_t EGTS_ECALL_AUTO_DIAL_ATTEMPTS = 0x021F;
+    static constexpr std::uint16_t EGTS_ECALL_MANUAL_DIAL_ATTEMPTS = 0x0220;
+    static constexpr std::uint16_t EGTS_ECALL_MANUAL_CAN_CANCEL = 0x0222;
+    static constexpr std::uint16_t EGTS_ECALL_SMS_FALLBACK_NUMBER = 0x0223;
+
+    //Acceleration profile recording in case of road accidents
+    static constexpr std::uint16_t IGNITION_OFF_FOLLOW_UP_TIME1 = 0x0224;
+    static constexpr std::uint16_t IGNITION_OFF_FOLLOW_UP_TIME2 = 0x0225;
+    static constexpr std::uint16_t EGTS_CRASH_RECORD_TIME = 0x0251;
+    static constexpr std::uint16_t EGTS_CRASH_RECORD_RESOLUTION = 0x0252;
+    static constexpr std::uint16_t EGTS_CRASH_PRE_RECORD_TIME = 0x0253;
+    static constexpr std::uint16_t EGTS_CRASH_PRE_RECORD_RESOLUTION = 0x0254;
+    static constexpr std::uint16_t EGTS_TRACK_RECORD_TIME = 0x025A;
+    static constexpr std::uint16_t EGTS_TRACK_PRE_RECORD_TIME = 0x025B;
+    static constexpr std::uint16_t EGTS_TRACK_RECORD_RESOLUTION = 0x025C;
+
+    //vehicle parameters
+    static constexpr std::uint16_t EGTS_VEHICLE_VIN = 0x0311;
+    static constexpr std::uint16_t EGTS_VEHICLE_PROPULSION_STORAGE_TYPE = 0x0313;
+    static constexpr std::uint16_t EGTS_VEHICLE_TYPE = 0x0312;
+
+};
+
+#endif /* SSLP_ECALL_ECALLUTILS_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/ecall/SrRawMsdData.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/ecall/SrRawMsdData.cpp
new file mode 100644
index 0000000..086d27e
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/ecall/SrRawMsdData.cpp
@@ -0,0 +1,84 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include "../../utils/GostEcallUtils.h"
+#include "SrRawMsdData.h"
+using namespace std;
+
+#undef LOG_TAG
+#define LOG_TAG "DEMO_EGOST_SrRawMsdData"
+
+SrRawMsdData::SrRawMsdData() {
+    FM = 1;
+    MSD = "";
+}
+
+SrRawMsdData::~SrRawMsdData() {
+    // TODO Auto-generated destructor stub
+}
+
+std::string SrRawMsdData::encode() {
+    if(MSD.empty()) {
+        MTK_RLOGW("encode EGTS_SR_RAW_MSD_DATA fail, MSD is empty");
+        return "";
+    }
+    MTK_RLOGD("FM=%d, MSD: %s", FM, MSD.c_str());
+
+    //encode FM
+    std::string strFm = encodeValue(FM, 2, "FM");
+    MTK_RLOGD("FM encode result: %s", strFm.c_str());
+    if(strFm.empty()) {
+        MTK_RLOGW("encode strFm fail");
+        return "";
+    }
+    //TBD, only for test, MSD don't need encode.
+    return strFm.append(MSD);
+}
+
+std::uint8_t SrRawMsdData::getFm() const {
+    return FM;
+}
+
+void SrRawMsdData::setFm(std::uint8_t fm) {
+    FM = fm;
+}
+
+const std::string& SrRawMsdData::getMsd() const {
+    return MSD;
+}
+
+void SrRawMsdData::setMsd(const std::string msd) {
+    MSD = msd;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/ecall/SrRawMsdData.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/ecall/SrRawMsdData.h
new file mode 100644
index 0000000..de88ee7
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/ecall/SrRawMsdData.h
@@ -0,0 +1,61 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef SSLP_ECALL_SRRAWMSDDATA_H_
+#define SSLP_ECALL_SRRAWMSDDATA_H_
+
+#include <cstdint>
+#include <vector>
+#include <memory>
+#include <string>
+
+//p49, table 43
+class SrRawMsdData {
+public:
+    SrRawMsdData();
+    virtual ~SrRawMsdData();
+    std::string encode();
+    std::uint8_t getFm() const;
+    void setFm(std::uint8_t fm);
+    const std::string& getMsd() const;
+    void setMsd(const std::string msd);
+
+private:
+    std::uint8_t FM;
+    std::string MSD; //(0,116)
+    //std::vector<std::uint8_t> MSD; // (0,116)
+};
+
+#endif /* SSLP_ECALL_SRRAWMSDDATA_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/ecall/SrRecResp.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/ecall/SrRecResp.cpp
new file mode 100644
index 0000000..62fa3e9
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/ecall/SrRecResp.cpp
@@ -0,0 +1,46 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include "SrRecResp.h"
+
+SrRespFormat::SrRespFormat() {
+    // TODO Auto-generated constructor stub
+
+}
+
+SrRespFormat::~SrRespFormat() {
+    // TODO Auto-generated destructor stub
+}
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/ecall/SrRecResp.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/ecall/SrRecResp.h
new file mode 100644
index 0000000..1883bd0
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/ecall/SrRecResp.h
@@ -0,0 +1,52 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef SSLP_ECALL_SRRESPFORMAT_H_
+#define SSLP_ECALL_SRRESPFORMAT_H_
+
+#include <cstdint>
+#include <string>
+
+//p48->p27 7.3.1->6.7.2.1. table 18
+class SrRespFormat {
+public:
+    SrRespFormat();
+    virtual ~SrRespFormat();
+private:
+    uint16_t CRN;
+    uint8_t RST;
+};
+
+#endif /* SSLP_ECALL_SRRESPFORMAT_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/ecall/SrTrackData.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/ecall/SrTrackData.cpp
new file mode 100644
index 0000000..281d90a
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/ecall/SrTrackData.cpp
@@ -0,0 +1,46 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include "SrTrackData.h"
+
+SrTrackData::SrTrackData() {
+    // TODO Auto-generated constructor stub
+
+}
+
+SrTrackData::~SrTrackData() {
+    // TODO Auto-generated destructor stub
+}
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/ecall/SrTrackData.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/ecall/SrTrackData.h
new file mode 100644
index 0000000..313b6af
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/ecall/SrTrackData.h
@@ -0,0 +1,57 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+
+
+#ifndef SSLP_ECALL_SRTRACKDATA_H_
+#define SSLP_ECALL_SRTRACKDATA_H_
+
+#include <cstdint>
+#include <string>
+#include <vector>
+
+//p49 7.3.4
+class SrTrackData {
+public:
+    SrTrackData();
+    virtual ~SrTrackData();
+private:
+    std::uint8_t SA;
+    std::uint32_t ATM;
+    std::string TDS1;
+    std::vector<std::uint8_t> TDSS;
+};
+
+#endif /* SSLP_ECALL_SRTRACKDATA_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/ecall/srTrackDataTds.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/ecall/srTrackDataTds.cpp
new file mode 100644
index 0000000..06bc1e1
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/ecall/srTrackDataTds.cpp
@@ -0,0 +1,46 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include "srTrackDataTds.h"
+
+srTrackDataTds::srTrackDataTds() {
+    // TODO Auto-generated constructor stub
+
+}
+
+srTrackDataTds::~srTrackDataTds() {
+    // TODO Auto-generated destructor stub
+}
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/ecall/srTrackDataTds.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/ecall/srTrackDataTds.h
new file mode 100644
index 0000000..40ed83f
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/ecall/srTrackDataTds.h
@@ -0,0 +1,66 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+
+#ifndef SSLP_ECALL_SRTRACKDATATDS_H_
+#define SSLP_ECALL_SRTRACKDATATDS_H_
+
+#include <cstdint>
+#include <string>
+
+class srTrackDataTds {
+public:
+    srTrackDataTds();
+    virtual ~srTrackDataTds();
+private:
+    //1byte
+    std::uint8_t TNDE; //1bit
+    std::uint8_t LOHS; //1bit
+    std::uint8_t LAHS; //1bit
+    std::uint8_t RTM; //4bit
+
+    std::uint32_t LAT; //O depends on TNDE
+    std::uint32_t LONG; //O depends on TNDE
+
+    //16bit
+    std::uint8_t SPDL; //O depends on TNDE
+    std::uint8_t DIRH; //O 1bit most significant bit(bit 8) of the DIR parameter. depends on TNDE
+    std::uint8_t SPDH; //O 7bit, depends on TNDE
+
+    std::uint8_t DIR; //O, depends on TNDE
+
+};
+
+#endif /* SSLP_ECALL_SRTRACKDATATDS_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/firmware/FirmwareUtils.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/firmware/FirmwareUtils.h
new file mode 100644
index 0000000..9439ea9
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/firmware/FirmwareUtils.h
@@ -0,0 +1,51 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+
+#ifndef SSLP_FIRMWARE_FIRMWAREUTILS_H_
+#define SSLP_FIRMWARE_FIRMWAREUTILS_H_
+
+#include <cstdint>
+#include <string>
+
+typedef enum {
+    EGTS_SR_RECORD_RESPONSE = 0,
+    EGTS_SR_SERVICE_PART_DATA = 33,
+    EGTS_SR_SERVICE_FULL_DATA = 34,
+}sr_firmware_service;
+
+
+
+#endif /* SSLP_FIRMWARE_FIRMWAREUTILS_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/firmware/SrServiceFullData.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/firmware/SrServiceFullData.cpp
new file mode 100644
index 0000000..982a279
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/firmware/SrServiceFullData.cpp
@@ -0,0 +1,46 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include "SrServiceFullData.h"
+
+SrServiceFullData::SrServiceFullData() {
+    // TODO Auto-generated constructor stub
+
+}
+
+SrServiceFullData::~SrServiceFullData() {
+    // TODO Auto-generated destructor stub
+}
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/firmware/SrServiceFullData.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/firmware/SrServiceFullData.h
new file mode 100644
index 0000000..bcab11f
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/firmware/SrServiceFullData.h
@@ -0,0 +1,53 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef SSLP_FIRMWARE_SRSERVICEFULLDATA_H_
+#define SSLP_FIRMWARE_SRSERVICEFULLDATA_H_
+
+#include <cstdint>
+#include <string>
+#include <vector>
+
+//table 38, p47
+class SrServiceFullData {
+public:
+    SrServiceFullData();
+    virtual ~SrServiceFullData();
+private:
+    std::vector<std::uint8_t> ODH;
+    std::vector<std::uint8_t> OD;
+};
+
+#endif /* SSLP_FIRMWARE_SRSERVICEFULLDATA_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/firmware/SrServicePartData.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/firmware/SrServicePartData.cpp
new file mode 100644
index 0000000..a2b489b
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/firmware/SrServicePartData.cpp
@@ -0,0 +1,46 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include "SrServicePartData.h"
+
+SrServicePartData::SrServicePartData() {
+    // TODO Auto-generated constructor stub
+
+}
+
+SrServicePartData::~SrServicePartData() {
+    // TODO Auto-generated destructor stub
+}
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/firmware/SrServicePartData.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/firmware/SrServicePartData.h
new file mode 100644
index 0000000..e840bdf
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/firmware/SrServicePartData.h
@@ -0,0 +1,60 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+
+#ifndef SSLP_FIRMWARE_SRSERVICEPARTDATA_H_
+#define SSLP_FIRMWARE_SRSERVICEPARTDATA_H_
+
+#include <cstdint>
+#include <string>
+#include <vector>
+
+//table 36, p45
+class SrServicePartData {
+public:
+    SrServicePartData();
+    virtual ~SrServicePartData();
+
+private:
+    std::uint16_t ID;
+    std::uint16_t PN;
+    std::uint16_t EPQ;
+    std::vector<std::uint8_t> ODH; //O
+    std::vector<std::uint8_t> OD; //(1, 65400)
+    //std::string ODH //O
+    //std::string OD; (1, 65400)
+};
+
+#endif /* SSLP_FIRMWARE_SRSERVICEPARTDATA_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/firmware/srSerPartDtObjHeader.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/firmware/srSerPartDtObjHeader.cpp
new file mode 100644
index 0000000..6a9e94e
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/firmware/srSerPartDtObjHeader.cpp
@@ -0,0 +1,46 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include "srSerPartDtObjHeader.h"
+
+srSerPartDtObjHeader::srSerPartDtObjHeader() {
+    // TODO Auto-generated constructor stub
+
+}
+
+srSerPartDtObjHeader::~srSerPartDtObjHeader() {
+    // TODO Auto-generated destructor stub
+}
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/firmware/srSerPartDtObjHeader.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/firmware/srSerPartDtObjHeader.h
new file mode 100644
index 0000000..cfd83fd
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/sslp/firmware/srSerPartDtObjHeader.h
@@ -0,0 +1,62 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+
+#ifndef SSLP_FIRMWARE_SRSERPARTDTOBJHEADER_H_
+#define SSLP_FIRMWARE_SRSERPARTDTOBJHEADER_H_
+
+#include <cstdint>
+#include <string>
+
+//table37 p46.
+class srSerPartDtObjHeader {
+public:
+    srSerPartDtObjHeader();
+    virtual ~srSerPartDtObjHeader();
+
+private:
+    //uint8_t
+    std::uint8_t OA;
+    std::uint8_t OT; //1bit (bit1)
+    std::uint8_t MT; //1bit (bit0)
+
+    std::uint8_t CMI;
+    std::uint16_t VER;
+    std::uint16_t WOS;
+    std::string FN; //O
+    std::string D;
+};
+
+#endif /* SSLP_FIRMWARE_SRSERPARTDTOBJHEADER_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/utils/GostEcallUtils.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/utils/GostEcallUtils.cpp
new file mode 100644
index 0000000..1b6989e
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/utils/GostEcallUtils.cpp
@@ -0,0 +1,200 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include "GostEcallUtils.h"
+#include "GsmUtils.h"
+
+#include <string>
+#include <cstdio>
+
+
+using namespace std;
+
+#undef LOG_TAG
+#define LOG_TAG "DEMO_ECALL_GOST_UTILS"
+
+string getResultCode(int code) {
+    MTK_RLOGD("code=%d",code);
+    switch(code){
+    case EGTS_PC_OK: return "Processing Succeeded";
+    case EGTS_PC_IN_PROGRESS: return "Processing in progress(processing result is not known yet";
+    case EGTS_PC_UNS_PROTOCOL: return "protocol not supported";
+    case EGTS_PC_DECRYPT_ERROR: return "Decryption error";
+    case EGTS_PC_PORC_DENIED: return "Processing not permitted";
+    case EGTS_PC_INC_HEADERFORM: return "Incorrect header format";
+    case EGTS_PC_INC_DATAFORM: return "Incorrect data format";
+    case EGTS_PC_UNS_TYPE: return "Type not supported";
+    case EGTS_PC_NOTEN_PARAMS: return "Incorrect number of parameters";
+    case EGTS_PC_DBL_PROC: return "Processing retry attempt";
+    case EGTS_PC_PROC_SRC_DENIED: return "Data Processing not permitted for this source";
+    case EGTS_PC_HEADERCRC_ERROR: return "Header checksum error";
+    case EGTS_PC_DATACRC_ERROR: return "Data checksum error";
+    case EGTS_PC_INVDATALEN: return "Invalid data length";
+    case EGTS_PC_ROUTE_NFOUND: return "Route not found";
+    case EGTS_PC_ROUTE_CLOSED: return "Route closed";
+    case EGTS_PC_ROUTE_DENIED: return "Route not permitted";
+    case EGTS_PC_INVADDR: return "Invalid address";
+    case EGTS_PC_TTLEXPIRED: return "Time to live expired";
+    case EGTS_PC_NO_ACK: return "No acknowledgement reeived";
+    case EGTS_PC_OBJ_NFOUND: return "Object not found";
+    case EGTS_PC_EVENT_NFOUND: return "Event not found";
+    case EGTS_PC_SRVC_NFOUND: return "Service not found";
+    case EGTS_PC_SRVC_DENIED: return "Service denied";
+    case EGTS_PC_SRVC_UNKN: return "Service type unknown";
+    case EGTS_PC_AUTH_DENIED: return "Authorisation denied";
+    case EGTS_PC_ALREADY_EXISTS: return "Object already present";
+    case EGTS_PC_ID_NFOUND: return "Identifier not found";
+    case EGTS_PC_INC_DATETIME: return "Incorrect data and time";
+    case EGTS_PC_IO_ERROR: return "Input/output error";
+    case EGTS_PC_NO_RES_AVAIL: return "Insufficient resources";
+    case EGTS_PC_MODULE_FAULT: return "Internal module fault";
+    case EGTS_PC_MODULE_PWR_FLT: return "Power circuit fault";
+    case EGTS_PC_MODULE_PROC_FLT: return "Module processor fault";
+    case EGTS_PC_MODULE_SW_FLT: return "Module software fault";
+    case EGTS_PC_MODULE_FW_FLT: return "Module firmware fault";
+    case EGTS_PC_MODULE_IO_FLT: return "Module I/O fault";
+    case EGTS_PC_MODULE_MEM_FLT: return "Internal module memory fault";
+    case EGTS_PC_TEST_FAILED: return "Test failed";
+    default: return "unknown";
+    }
+}
+
+std::string decodeData(const std::string &str, std::uint32_t offset, const std::string &tag, std::uint32_t &index) {
+    uint32_t len = str.size();
+    if (len < (index + offset*2)) {
+        MTK_RLOGW("decode %s fail, len(%d) < to_len(%d)", tag.c_str(), len,index + offset*2);
+        return "";
+    }
+    std::string sub = str.substr(index, offset*2);
+    MTK_RLOGD("before %s(from:%d, offset: %d): %s", tag.c_str(),index, offset*2, sub.c_str());
+    index = index + offset*2;
+    return sub;
+}
+
+int64_t decodeValue(const std::string &str, std::uint32_t &index,std::uint32_t offset, const std::string &tag) {
+    if(offset != 2 && offset != 4 &&  offset != 8) {
+        MTK_RLOGW("%s offset(%d) is invalid, just return ", tag.c_str(), offset);
+        return -1;
+    }
+    uint32_t len = str.size();
+    if (len < (index + offset)) {
+        MTK_RLOGW("decode %s fail, len(%d) < to_len(%d)", tag.c_str(), len,
+                index + offset);
+        //return -1;
+    }
+    std::string sub = str.substr(index, offset);
+    //RLOGD("before %s(from:%d, offset: %d): %s", tag.c_str(), index, offset, sub.c_str());
+    index = index + offset;
+    int ret = -1;
+    switch(offset) {
+    case 2:
+    {
+        ret = gsm_hex2_to_byte(sub.c_str());
+        break;
+    }
+    case 4:
+    {
+        ret = gsm_hex4_to_short(sub.c_str());
+        break;
+    }
+    case 8:
+    {
+        ret = gsm_hex8_to_int(sub.c_str());
+        break;
+    }
+    default:
+    {
+        MTK_RLOGW("%s offset(%d) is invalid, just return ", tag.c_str(), offset);
+        return -1;
+    }
+    }
+
+    if(ret == -1) {
+        MTK_RLOGW("decode %s(gsm_hex%d_to_xxx) fail", tag.c_str(), offset);
+        return -1;
+    }
+
+    switch(offset) {
+    case 2:
+    {
+        //RLOGD("0X%02x", (uint8_t)ret);
+        break;
+    }
+    case 4:
+    {
+        //RLOGD("0X%04x", (uint16_t)ret);
+        break;
+    }
+    case 8:
+    {
+        //RLOGD("0X%08x", (uint32_t)ret);
+        break;
+    }
+    }
+    return ret;
+}
+
+std::string encodeValue(int64_t value, uint8_t charset, const std::string tag) {
+    MTK_RLOGD("value = %lld, charset=%u, encode: %s", value, charset, tag.c_str());
+    if((charset != 2) &&(charset != 4) && (charset != 8)) {
+        MTK_RLOGW("charset don't support,just return");
+        return "";
+    }
+    char *hex = new char[charset+1]();
+    switch(charset) {
+    case 2: {
+        gsm_hex_from_byte(hex,value);
+        break;
+    }
+    case 4: {
+        gsm_hex_from_short(hex,value);
+        break;
+    }
+    case 8: {
+        gsm_hex_from_int(hex, value);
+        break;
+    }
+    default: {
+        MTK_RLOGW("error");
+        return "";
+    }
+    }
+    MTK_RLOGD("%s", hex);
+    std::string str(hex, charset);
+    MTK_RLOGD("encode(%s=%lld) is : %s",tag.c_str(), value, str.c_str());
+    delete [] hex;
+    hex = NULL;
+    return str;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/utils/GostEcallUtils.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/utils/GostEcallUtils.h
new file mode 100644
index 0000000..7cf7334
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/utils/GostEcallUtils.h
@@ -0,0 +1,132 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef GOSTECALLUTILS_H_
+#define GOSTECALLUTILS_H_
+
+#include <cstdio>
+#include <string>
+#include <cstdint>
+
+#if 1
+#include <log/log.h>
+#define MTK_RLOGE(fmt, args...) RLOGE("%s: " fmt, __FUNCTION__, ##args)
+#define MTK_RLOGD(fmt, args...) RLOGD("%s: " fmt, __FUNCTION__, ##args)
+#define MTK_RLOGW(fmt, args...) RLOGW("%s: " fmt, __FUNCTION__, ##args)
+#define MTK_RLOGI(fmt, args...) RLOGI("%s: " fmt, __FUNCTION__, ##args)
+#else
+#define MTK_RLOGE(fmt, args...) printf("%s(%d): %s() "#fmt"\n",__FILE__,__LINE__,__func__,##args)
+#define MTK_RLOGD(fmt, args...) printf("%s(%d): %s() "#fmt"\n",__FILE__,__LINE__,__func__,##args)
+#define MTK_RLOGW(fmt, args...) printf("%s(%d): %s() "#fmt"\n",__FILE__,__LINE__,__func__,##args)
+#define MTK_RLOGI(fmt, args...) printf("%s(%d): %s() "#fmt"\n",__FILE__,__LINE__,__func__,##args)
+#endif
+
+//p25, table 16
+typedef enum {
+    //this service may be used by the IVDS only after a new TCP/IP connection with
+    //the telematic platform is established.
+    EGTS_AUTH_SERVICE=1,
+    EGTS_TELEDATA_SERVICE=2,
+    //process of commands and acknowledgements transferred between the IVDS,
+    //telematic platform and client applications.
+    EGTS_COMMANDS_SERVICE=4, //6.7.3 37page
+    //p45 6.7.4 This service is intended for downloading data to the IVDS,
+    //including configuration data and firmware updates for modules and units of the IVDS
+    // itself as well as of its connected peripheral equipment.
+    EGTS_FIRMWARE_SERVICE=9,
+    //7.2 47page , accident emergency response service
+    //support EGTS_COMMANDS_SERVICE
+    //support EGTS_ECALL_REQ and EGTS_ECALL_MSD_REQ
+    EGTS_ECALL_SERVICE=10,
+}service_support_layer_protocol;
+
+typedef enum {
+    EGTS_SR_AUTH_RECORD_RESPONSE = 0,
+    EGTS_SR_TERM_IDENTIFY = 1,
+    EGTS_SR_MODULE_DATA = 2,
+    EGTS_SR_VEHICLE_DATA = 3,
+    EGTS_SR_AUTH_PARAMS = 6,
+    EGTS_SR_AUTH_INFO = 7,
+    EGTS_SR_SERVICE_INFO = 8,
+    EGTS_SR_RESULT_CODE = 9,
+}sub_records_egts_auth_ser;
+
+typedef enum {
+    EGTS_PC_OK = 0,
+    EGTS_PC_IN_PROGRESS = 1,
+    EGTS_PC_UNS_PROTOCOL = 128,
+    EGTS_PC_DECRYPT_ERROR = 129,
+    EGTS_PC_PORC_DENIED = 130,
+    EGTS_PC_INC_HEADERFORM=131,
+    EGTS_PC_INC_DATAFORM=132,
+    EGTS_PC_UNS_TYPE = 133,
+    EGTS_PC_NOTEN_PARAMS = 134,
+    EGTS_PC_DBL_PROC = 135,
+    EGTS_PC_PROC_SRC_DENIED=136,
+    EGTS_PC_HEADERCRC_ERROR=137,
+    EGTS_PC_DATACRC_ERROR=138,
+    EGTS_PC_INVDATALEN=139,
+    EGTS_PC_ROUTE_NFOUND=140,
+    EGTS_PC_ROUTE_CLOSED=141,
+    EGTS_PC_ROUTE_DENIED=142,
+    EGTS_PC_INVADDR=143,
+    EGTS_PC_TTLEXPIRED=144,
+    EGTS_PC_NO_ACK=145,
+    EGTS_PC_OBJ_NFOUND=146,
+    EGTS_PC_EVENT_NFOUND=147,
+    EGTS_PC_SRVC_NFOUND=148,
+    EGTS_PC_SRVC_DENIED=149,
+    EGTS_PC_SRVC_UNKN=150,
+    EGTS_PC_AUTH_DENIED=151,
+    EGTS_PC_ALREADY_EXISTS=152,
+    EGTS_PC_ID_NFOUND=153,
+    EGTS_PC_INC_DATETIME=154,
+    EGTS_PC_IO_ERROR=155,
+    EGTS_PC_NO_RES_AVAIL=156,
+    EGTS_PC_MODULE_FAULT=157,
+    EGTS_PC_MODULE_PWR_FLT=158,
+    EGTS_PC_MODULE_PROC_FLT = 159,
+    EGTS_PC_MODULE_SW_FLT=160,
+    EGTS_PC_MODULE_FW_FLT=161,
+    EGTS_PC_MODULE_IO_FLT=162,
+    EGTS_PC_MODULE_MEM_FLT=163,
+    EGTS_PC_TEST_FAILED=164,
+}ecall_result_code;
+
+std::string decodeData(const std::string &str, std::uint32_t offset, const std::string &tag, std::uint32_t &index);
+int64_t decodeValue(const std::string &str, std::uint32_t &index,std::uint32_t offset, const std::string &tag);
+std::string encodeValue(int64_t value, uint8_t charset, const std::string tag);
+
+#endif /* GOSTECALLUTILS_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/utils/GsmUtils.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/utils/GsmUtils.cpp
new file mode 100644
index 0000000..3ac4391
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/utils/GsmUtils.cpp
@@ -0,0 +1,1168 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include "GsmUtils.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+/** UTILITIES
+ **/
+byte_t gsm_int_to_bcdi(int value) {
+    return (byte_t) ((value / 10) | ((value % 10) << 4));
+}
+
+int gsm_int_from_bcdi(byte_t val) {
+    int ret = 0;
+
+    if ((val & 0xf0) <= 0x90)
+        ret = (val >> 4);
+
+    if ((val & 0x0f) <= 0x09)
+        ret |= (val & 0x0f) * 10;
+
+    return ret;
+}
+
+#if 0
+    static int
+    gsm_bcdi_to_ascii( cbytes_t  bcd, int  bcdlen, bytes_t  dst )
+    {
+        static byte_t  bcdichars[14] = "0123456789*#,N";
+
+        int  result = 0;
+        int  shift  = 0;
+
+        while (bcdlen > 0) {
+            int  c = (bcd[0] >> shift) & 0xf;
+
+            if (c == 0xf && bcdlen == 1)
+                break;
+
+            if (c < 14) {
+                if (dst) dst[result] = bcdichars[c];
+                result += 1;
+            }
+            bcdlen --;
+            shift += 4;
+            if (shift == 8) {
+                bcd++;
+                shift = 0;
+            }
+        }
+        return result;
+    }
+#endif
+
+#if 0
+    static int
+    gsm_bcdi_from_ascii( cbytes_t  ascii, int  asciilen, bytes_t  dst )
+    {
+        cbytes_t  end    = ascii + asciilen;
+        int       result = 0;
+        int       phase  = 0x01;
+
+        while (ascii < end) {
+            int  c = *ascii++;
+
+            if (c == '*')
+                c = 11;
+            else if (c == '#')
+                c = 12;
+            else if (c == ',')
+                c = 13;
+            else if (c == 'N')
+                c = 14;
+            else {
+                c -= '0';
+                if ((unsigned)c >= 10)
+                    break;
+            }
+            phase = (phase << 4) | c;
+            if (phase & 0x100) {
+                if (dst) dst[result] = (byte_t) phase;
+                result += 1;
+                phase   = 0x01;
+            }
+        }
+        if (phase != 0x01) {
+            if (dst) dst[result] = (byte_t)( phase | 0xf0 );
+            result += 1;
+        }
+        return  result;
+    }
+#endif
+
+int gsm_hexchar_to_int(char c) {
+    if ((unsigned) (c - '0') < 10)
+        return c - '0';
+    if ((unsigned) (c - 'a') < 6)
+        return 10 + (c - 'a');
+    if ((unsigned) (c - 'A') < 6)
+        return 10 + (c - 'A');
+    return -1;
+}
+
+int gsm_hexchar_to_int0(char c) {
+    int ret = gsm_hexchar_to_int(c);
+
+    return (ret < 0) ? 0 : ret;
+}
+
+int gsm_hex2_to_byte(const char *hex) {
+    int hi = gsm_hexchar_to_int(hex[0]);
+    int lo = gsm_hexchar_to_int(hex[1]);
+
+    if (hi < 0 || lo < 0)
+        return -1;
+
+    return ((hi << 4) | lo);
+}
+
+int gsm_hex4_to_short(const char *hex) {  //little endian
+    int lo = gsm_hex2_to_byte(hex);
+    int hi = gsm_hex2_to_byte(hex + 2);
+
+    if (hi < 0 || lo < 0)
+        return -1;
+
+    return ((hi << 8) | lo);
+}
+
+int64_t  gsm_hex8_to_int( const char*  hex ) {  //little endian
+    int lo = gsm_hex4_to_short(hex);
+    int hi = gsm_hex4_to_short(hex + 4);
+
+    if (hi < 0 || lo < 0)
+        return -1;
+
+    return ((hi << 16) | lo);
+}
+
+int gsm_hex2_to_byte0(const char *hex) {
+    int hi = gsm_hexchar_to_int0(hex[0]);
+    int lo = gsm_hexchar_to_int0(hex[1]);
+
+    return (byte_t) ((hi << 4) | lo);
+}
+
+void gsm_hex_from_byte(char *hex, int val) {
+    static const char hexdigits[] = "0123456789abcdef";
+
+    hex[0] = hexdigits[(val >> 4) & 15];
+    hex[1] = hexdigits[val & 15];
+}
+
+void gsm_hex_from_short(char *hex, int val) {
+    gsm_hex_from_byte(hex, val);
+    gsm_hex_from_byte(hex + 2, (val >> 8));
+}
+
+void gsm_hex_from_int(char* hex, int64_t val) {
+    gsm_hex_from_short(hex, val);
+    gsm_hex_from_short(hex + 4, (val >> 16));
+}
+/** HEX
+ **/
+void gsm_hex_to_bytes0(cbytes_t hex, int hexlen, bytes_t dst) {
+    int nn;
+
+    for (nn = 0; nn < hexlen / 2; nn++) {
+        dst[nn] = (byte_t) gsm_hex2_to_byte0((const char*) hex + 2 * nn);
+    }
+    if (hexlen & 1) {
+        dst[nn] = gsm_hexchar_to_int0(hex[2 * nn]) << 4;
+    }
+}
+
+int gsm_hex_to_bytes(cbytes_t hex, int hexlen, bytes_t dst) {
+    int nn;
+
+    if (hexlen & 1) /* must be even */
+        return -1;
+
+    for (nn = 0; nn < hexlen / 2; nn++) {
+        int c = gsm_hex2_to_byte((const char*) hex + 2 * nn);
+        if (c < 0)
+            return -1;
+        dst[nn] = (byte_t) c;
+    }
+    return hexlen / 2;
+}
+
+void gsm_hex_from_bytes(char *hex, cbytes_t src, int srclen) {
+    int nn;
+
+    for (nn = 0; nn < srclen; nn++) {
+        gsm_hex_from_byte(hex + 2 * nn, src[nn]);
+    }
+}
+
+/** ROPES
+ **/
+
+void gsm_rope_init(GsmRope rope) {
+    rope->data = NULL;
+    rope->pos = 0;
+    rope->max = 0;
+    rope->error = 0;
+}
+
+void gsm_rope_init_alloc(GsmRope rope, int count) {
+    rope->data = rope->data0;
+    rope->pos = 0;
+    rope->max = sizeof(rope->data0);
+    rope->error = 0;
+
+    if (count > 0) {
+        rope->data = (bytes_t) calloc(count, 1);
+        rope->max = count;
+
+        if (rope->data == NULL) {
+            rope->error = 1;
+            rope->max = 0;
+        }
+    }
+}
+
+int gsm_rope_done(GsmRope rope) {
+    int result = rope->error;
+
+    if (rope->data && rope->data != rope->data0)
+        free(rope->data);
+
+    rope->data = NULL;
+    rope->pos = 0;
+    rope->max = 0;
+    rope->error = 0;
+
+    return result;
+}
+
+bytes_t gsm_rope_done_acquire(GsmRope rope, int *psize) {
+    bytes_t result = rope->data;
+
+    *psize = rope->pos;
+    if (result == rope->data0) {
+        result = (bytes_t) calloc(1, rope->pos);
+        if (result != NULL)
+            memcpy(result, rope->data, rope->pos);
+    }
+    return result;
+}
+
+int gsm_rope_ensure(GsmRope rope, int new_count) {
+    if (rope->data != NULL) {
+        int old_max = rope->max;
+        bytes_t old_data = rope->data == rope->data0 ? NULL : rope->data;
+        int new_max = old_max;
+        bytes_t new_data;
+
+        while (new_max < new_count) {
+            new_max += (new_max >> 1) + 4;
+        }
+        new_data = (bytes_t) realloc(old_data, new_max);
+        if (new_data == NULL) {
+            rope->error = 1;
+            return -1;
+        }
+        rope->data = new_data;
+        rope->max = new_max;
+    } else {
+        rope->max = new_count;
+    }
+    return 0;
+}
+
+static int gsm_rope_can_grow(GsmRope rope, int count) {
+    if (!rope->data || rope->error)
+        return 0;
+
+    if (rope->pos + count > rope->max) {
+        if (rope->data == NULL)
+            rope->max = rope->pos + count;
+
+        else if (rope->error || gsm_rope_ensure(rope, rope->pos + count) < 0)
+            return 0;
+    }
+    return 1;
+}
+
+void gsm_rope_add_c(GsmRope rope, char c) {
+    if (gsm_rope_can_grow(rope, 1)) {
+        rope->data[rope->pos] = (byte_t) c;
+    }
+    rope->pos += 1;
+}
+
+void gsm_rope_add(GsmRope rope, const void *buf, int buflen) {
+    if (gsm_rope_can_grow(rope, buflen)) {
+        memcpy(rope->data + rope->pos, (const char*) buf, buflen);
+    }
+    rope->pos += buflen;
+}
+
+void*
+gsm_rope_reserve(GsmRope rope, int count) {
+    void *result = NULL;
+
+    if (gsm_rope_can_grow(rope, count)) {
+        if (rope->data != NULL)
+            result = rope->data + rope->pos;
+    }
+    rope->pos += count;
+
+    return result;
+}
+
+/* skip a given number of Unicode characters in a utf-8 byte string */
+cbytes_t utf8_skip(cbytes_t utf8, cbytes_t utf8end, int count) {
+    cbytes_t p = utf8;
+    cbytes_t end = utf8end;
+
+    for (; count > 0; count--) {
+        int c;
+
+        if (p >= end)
+            break;
+
+        c = *p++;
+        if (c > 128) {
+            while (p < end && (p[0] & 0xc0) == 0x80)
+                p++;
+        }
+    }
+    return p;
+}
+
+static __inline__ int utf8_next(cbytes_t *pp, cbytes_t end) {
+    cbytes_t p = *pp;
+    int result = -1;
+
+    if (p < end) {
+        int c = *p++;
+        if (c >= 128) {
+            if ((c & 0xe0) == 0xc0)
+                c &= 0x1f;
+            else if ((c & 0xf0) == 0xe0)
+                c &= 0x0f;
+            else
+                c &= 0x07;
+
+            while (p < end && (p[0] & 0xc0) == 0x80) {
+                c = (c << 6) | (p[0] & 0x3f);
+                p++;
+            }
+        }
+        result = c;
+        *pp = p;
+    }
+    return result;
+}
+
+__inline__ int utf8_write(bytes_t utf8, int offset, int v) {
+    int result;
+
+    if (v < 128) {
+        result = 1;
+        if (utf8)
+            utf8[offset] = (byte_t) v;
+    } else if (v < 0x800) {
+        result = 2;
+        if (utf8) {
+            utf8[offset + 0] = (byte_t) (0xc0 | (v >> 6));
+            utf8[offset + 1] = (byte_t) (0x80 | (v & 0x3f));
+        }
+    } else if (v < 0x10000) {
+        result = 3;
+        if (utf8) {
+            utf8[offset + 0] = (byte_t) (0xe0 | (v >> 12));
+            utf8[offset + 1] = (byte_t) (0x80 | ((v >> 6) & 0x3f));
+            utf8[offset + 2] = (byte_t) (0x80 | (v & 0x3f));
+        }
+    } else {
+        result = 4;
+        if (utf8) {
+            utf8[offset + 0] = (byte_t) (0xf0 | ((v >> 18) & 0x7));
+            utf8[offset + 1] = (byte_t) (0x80 | ((v >> 12) & 0x3f));
+            utf8[offset + 2] = (byte_t) (0x80 | ((v >> 6) & 0x3f));
+            utf8[offset + 3] = (byte_t) (0x80 | (v & 0x3f));
+        }
+    }
+    return result;
+}
+
+static __inline__ int ucs2_write(bytes_t ucs2, int offset, int v) {
+    if (ucs2) {
+        ucs2[offset + 0] = (byte_t) (v >> 8);
+        ucs2[offset + 1] = (byte_t) (v);
+    }
+    return 2;
+}
+
+int utf8_check(cbytes_t p, int utf8len) {
+    cbytes_t end = p + utf8len;
+    int result = 0;
+
+    if (p) {
+        while (p < end) {
+            int c = *p++;
+            if (c >= 128) {
+                int len;
+                if ((c & 0xe0) == 0xc0) {
+                    len = 1;
+                } else if ((c & 0xf0) == 0xe0) {
+                    len = 2;
+                } else if ((c & 0xf8) == 0xf0) {
+                    len = 3;
+                } else
+                    goto Exit;
+                /* malformed utf-8 */
+
+                if (p + len > end) /* string too short */
+                    goto Exit;
+
+                for (; len > 0; len--, p++) {
+                    if ((p[0] & 0xc0) != 0x80)
+                        goto Exit;
+                }
+            }
+        }
+        result = 1;
+    }
+    Exit: return result;
+}
+
+/** UCS2 to UTF8
+ **/
+
+/* convert a UCS2 string into a UTF8 byte string, assumes 'buf' is correctly sized */
+int ucs2_to_utf8(cbytes_t ucs2, int ucs2len, bytes_t buf) {
+    int nn;
+    int result = 0;
+
+    for (nn = 0; nn < ucs2len; ucs2 += 2, nn++) {
+        int c = (ucs2[0] << 8) | ucs2[1];
+        result += utf8_write(buf, result, c);
+    }
+    return result;
+}
+
+/* count the number of UCS2 chars contained in a utf8 byte string */
+int utf8_to_ucs2(cbytes_t utf8, int utf8len, bytes_t ucs2) {
+    cbytes_t p = utf8;
+    cbytes_t end = p + utf8len;
+    int result = 0;
+
+    while (p < end) {
+        int c = utf8_next(&p, end);
+
+        if (c < 0)
+            break;
+
+        result += ucs2_write(ucs2, result, c);
+    }
+    return result / 2;
+}
+
+/** GSM ALPHABET
+ **/
+
+#define  GSM_7BITS_ESCAPE   0x1b
+#define  GSM_7BITS_UNKNOWN  0
+
+static const unsigned short gsm7bits_to_unicode[128] = { '@', 0xa3, '$', 0xa5,
+        0xe8, 0xe9, 0xf9, 0xec, 0xf2, 0xc7, '\n', 0xd8, 0xf8, '\r', 0xc5, 0xe5,
+        0x394, '_', 0x3a6, 0x393, 0x39b, 0x3a9, 0x3a0, 0x3a8, 0x3a3, 0x398,
+        0x39e, 0, 0xc6, 0xe6, 0xdf, 0xc9, ' ', '!', '"', '#', 0xa4, '%', '&',
+        '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4',
+        '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', 0xa1, 'A', 'B',
+        'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+        'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 0xc4, 0xd6, 0x147,
+        0xdc, 0xa7, 0xbf, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
+        'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y',
+        'z', 0xe4, 0xf6, 0xf1, 0xfc, 0xe0, };
+
+static const unsigned short gsm7bits_extend_to_unicode[128] = { 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, '\f', 0, 0, 0, 0, 0, 0, 0, 0, 0, '^', 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '{', '}', 0, 0, 0, 0, 0, '\\', 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '[', '~', ']', 0, '|', 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0x20ac, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
+
+static int unichar_to_gsm7(int unicode) {
+    int nn;
+    for (nn = 0; nn < 128; nn++) {
+        if (gsm7bits_to_unicode[nn] == unicode) {
+            return nn;
+        }
+    }
+    return -1;
+}
+
+static int unichar_to_gsm7_extend(int unichar) {
+    int nn;
+    for (nn = 0; nn < 128; nn++) {
+        if (gsm7bits_extend_to_unicode[nn] == unichar) {
+            return nn;
+        }
+    }
+    return -1;
+}
+
+/* return the number of septets needed to encode a unicode charcode */
+static int unichar_to_gsm7_count(int unicode) {
+    int nn;
+
+    nn = unichar_to_gsm7(unicode);
+    if (nn >= 0)
+        return 1;
+
+    nn = unichar_to_gsm7_extend(unicode);
+    if (nn >= 0)
+        return 2;
+
+    return 0;
+}
+
+cbytes_t utf8_skip_gsm7(cbytes_t utf8, cbytes_t utf8end,
+        int gsm7len) {
+    cbytes_t p = utf8;
+    cbytes_t end = utf8end;
+
+    while (gsm7len > 0) {
+        cbytes_t q = p;
+        int c = utf8_next(&q, end);
+        int len;
+
+        if (c < 0)
+            break;
+
+        len = unichar_to_gsm7_count(c);
+        if (len == 0) /* unknown chars are replaced by spaces */
+            len = 1;
+
+        if (len > gsm7len)
+            break;
+
+        gsm7len -= len;
+        p = q;
+    }
+    return p;
+}
+
+int utf8_check_gsm7(cbytes_t utf8, int utf8len) {
+    cbytes_t utf8end = utf8 + utf8len;
+
+    while (utf8 < utf8end) {
+        int c = utf8_next(&utf8, utf8end);
+        if (unichar_to_gsm7_count(c) == 0)
+            return 0;
+    }
+    return 1;
+}
+
+int utf8_from_gsm7(cbytes_t src, int septet_offset, int septet_count,
+        bytes_t utf8) {
+    int shift = (septet_offset & 7);
+    int escaped = 0;
+    int result = 0;
+
+    src += (septet_offset >> 3);
+    for (; septet_count > 0; septet_count--) {
+        int c = (src[0] >> shift) & 0x7f;
+        int v;
+
+        if (shift > 1) {
+            c = ((src[1] << (8 - shift)) | c) & 0x7f;
+        }
+
+        if (escaped) {
+            v = gsm7bits_extend_to_unicode[c];
+        } else if (c == GSM_7BITS_ESCAPE) {
+            escaped = 1;
+            goto NextSeptet;
+        } else {
+            v = gsm7bits_to_unicode[c];
+        }
+
+        result += utf8_write(utf8, result, v);
+
+        NextSeptet: shift += 7;
+        if (shift >= 8) {
+            shift -= 8;
+            src += 1;
+        }
+    }
+    return result;
+}
+
+int utf8_from_unpackedgsm7(cbytes_t src, int septet_offset,
+        int septet_count, bytes_t utf8) {
+    RIL_GSM_UTIL_UNUSED_PARM(septet_offset);
+    int escaped = 0;
+    int result = 0;
+
+    for (; septet_count > 0; septet_count--) {
+        int c = src[0] & 0x7f;
+        int v;
+
+        if (escaped) {
+            v = gsm7bits_extend_to_unicode[c];
+            /* Solve [ALPS00271799][SW.GIN2_SINGLE]Missing var for USSD strings receipt for Movistar Peru, mtk04070, 20120424 */
+            escaped = 0;
+        } else if (c == GSM_7BITS_ESCAPE) {
+            escaped = 1;
+            goto NextSeptet;
+        } else {
+            v = gsm7bits_to_unicode[c];
+        }
+
+        result += utf8_write(utf8, result, v);
+
+        NextSeptet: src += 1;
+    }
+    return result;
+}
+
+int utf8_from_gsm8(cbytes_t src, int count, bytes_t utf8) {
+    int result = 0;
+    int escaped = 0;
+
+    for (; count > 0; count--) {
+        int c = *src++;
+
+        if (c == 0xff)
+            break;
+
+        if (c == GSM_7BITS_ESCAPE) {
+            if (escaped) { /* two escape characters => one space */
+                c = 0x20;
+                escaped = 0;
+            } else {
+                escaped = 1;
+                continue;
+            }
+        } else {
+            if (c >= 0x80) {
+                c = 0x20;
+                escaped = 0;
+            } else if (escaped) {
+                c = gsm7bits_extend_to_unicode[c];
+            } else
+                c = gsm7bits_to_unicode[c];
+        }
+
+        result += utf8_write(utf8, result, c);
+    }
+    return result;
+}
+
+/* convert a GSM 7-bit message into a unicode character array
+ * the 'dst' array must contain at least 160 chars. the function
+ * returns the number of characters decoded
+ *
+ * assumes the 'dst' array has at least septet_count items, returns the
+ * number of unichars really written
+ */
+int ucs2_from_gsm7(bytes_t ucs2, cbytes_t src, int septet_offset,
+        int septet_count) {
+    const unsigned char *p = src + (septet_offset >> 3);
+    int shift = (septet_offset & 7);
+    int escaped = 0;
+    int result = 0;
+
+    for (; septet_count > 0; septet_count--) {
+        unsigned val = (p[0] >> shift) & 0x7f;
+
+        if (shift > 1)
+            val = (val | (p[1] << (8 - shift))) & 0x7f;
+
+        if (escaped) {
+            int c = gsm7bits_to_unicode[val];
+
+            result += ucs2_write(ucs2, result, c);
+            escaped = 0;
+        } else if (val == GSM_7BITS_ESCAPE) {
+            escaped = 1;
+        } else {
+            val = gsm7bits_extend_to_unicode[val];
+            if (val == 0)
+                val = 0x20;
+
+            result += ucs2_write(ucs2, result, val);
+        }
+    }
+    return result / 2;
+}
+
+/* count the number of septets required to write a utf8 string */
+static int utf8_to_gsm7_count(cbytes_t utf8, int utf8len) {
+    cbytes_t utf8end = utf8 + utf8len;
+    int result = 0;
+
+    while (utf8 < utf8end) {
+        int len;
+        int c = utf8_next(&utf8, utf8end);
+
+        if (c < 0)
+            break;
+
+        len = unichar_to_gsm7_count(c);
+        if (len == 0) /* replace non-representables with space */
+            len = 1;
+
+        result += len;
+    }
+    return result;
+}
+
+typedef struct {
+    bytes_t dst;
+    unsigned pad;
+    int bits;
+    int offset;
+} BWriterRec, *BWriter;
+
+static void bwriter_init(BWriter writer, bytes_t dst, int start) {
+    int shift = start & 7;
+
+    writer->dst = dst + (start >> 3);
+    writer->pad = 0;
+    writer->bits = shift;
+    writer->offset = start;
+
+    if (shift > 0) {
+        writer->pad = writer->dst[0] & ~(0xFF << shift);
+    }
+}
+
+static void bwriter_add7(BWriter writer, unsigned value) {
+    writer->pad |= (unsigned) (value << writer->bits);
+    writer->bits += 7;
+    if (writer->bits >= 8) {
+        writer->dst[0] = (byte_t) writer->pad;
+        writer->bits -= 8;
+        writer->pad >>= 8;
+        writer->dst += 1;
+    }
+    writer->offset += 7;
+}
+
+static int bwriter_done(BWriter writer) {
+    if (writer->bits > 0) {
+        writer->dst[0] = (byte_t) writer->pad;
+        writer->pad = 0;
+        writer->bits = 0;
+        writer->dst += 1;
+    }
+    return writer->offset;
+}
+
+/* convert a utf8 string to a gsm7 byte string - return the number of septets written */
+int utf8_to_gsm7(cbytes_t utf8, int utf8len, bytes_t dst,
+        int offset) {
+    const unsigned char *utf8end = utf8 + utf8len;
+    BWriterRec writer[1];
+
+    if (dst == NULL)
+        return utf8_to_gsm7_count(utf8, utf8len);
+
+    bwriter_init(writer, dst, offset);
+    while (utf8 < utf8end) {
+        int c = utf8_next(&utf8, utf8end);
+        int nn;
+
+        if (c < 0)
+            break;
+
+        nn = unichar_to_gsm7(c);
+        if (nn >= 0) {
+            bwriter_add7(writer, nn);
+            continue;
+        }
+
+        nn = unichar_to_gsm7_extend(c);
+        if (nn >= 0) {
+            bwriter_add7(writer, GSM_7BITS_ESCAPE);
+            bwriter_add7(writer, nn);
+            continue;
+        }
+
+        /* unknown => replaced by space */
+        bwriter_add7(writer, 0x20);
+    }
+    return bwriter_done(writer);
+}
+
+int utf8_to_gsm8(cbytes_t utf8, int utf8len, bytes_t dst) {
+    const unsigned char *utf8end = utf8 + utf8len;
+    int result = 0;
+
+    while (utf8 < utf8end) {
+        int c = utf8_next(&utf8, utf8end);
+        int nn;
+
+        if (c < 0)
+            break;
+
+        nn = unichar_to_gsm7(c);
+        if (nn >= 0) {
+            if (dst)
+                dst[result] = (byte_t) nn;
+            result += 1;
+            continue;
+        }
+
+        nn = unichar_to_gsm7_extend(c);
+        if (nn >= 0) {
+            if (dst) {
+                dst[result + 0] = (byte_t) GSM_7BITS_ESCAPE;
+                dst[result + 1] = (byte_t) nn;
+            }
+            result += 2;
+            continue;
+        }
+
+        /* unknown => space */
+        if (dst)
+            dst[result] = 0x20;
+        result += 1;
+    }
+    return result;
+}
+
+int ucs2_to_gsm7(cbytes_t ucs2, int ucs2len, bytes_t dst,
+        int offset) {
+    const unsigned char *ucs2end = ucs2 + ucs2len * 2;
+    BWriterRec writer[1];
+
+    bwriter_init(writer, dst, offset);
+    while (ucs2 < ucs2end) {
+        int c = *ucs2++;
+        int nn;
+
+        for (nn = 0; nn < 128; nn++) {
+            if (gsm7bits_to_unicode[nn] == c) {
+                bwriter_add7(writer, nn);
+                goto NextUnicode;
+            }
+        }
+        for (nn = 0; nn < 128; nn++) {
+            if (gsm7bits_extend_to_unicode[nn] == c) {
+                bwriter_add7(writer, GSM_7BITS_ESCAPE);
+                bwriter_add7(writer, nn);
+                goto NextUnicode;
+            }
+        }
+
+        /* unknown */
+        bwriter_add7(writer, 0x20);
+
+        NextUnicode: ;
+    }
+    return bwriter_done(writer);
+}
+
+int ucs2_to_gsm8(cbytes_t ucs2, int ucs2len, bytes_t dst) {
+    const unsigned char *ucs2end = ucs2 + ucs2len * 2;
+    bytes_t dst0 = dst;
+
+    while (ucs2 < ucs2end) {
+        int c = *ucs2++;
+        int nn;
+
+        for (nn = 0; nn < 128; nn++) {
+            if (gsm7bits_to_unicode[nn] == c) {
+                *dst++ = (byte_t) nn;
+                goto NextUnicode;
+            }
+        }
+        for (nn = 0; nn < 128; nn++) {
+            if (gsm7bits_extend_to_unicode[nn] == c) {
+                dst[0] = (byte_t) GSM_7BITS_ESCAPE;
+                dst[1] = (byte_t) nn;
+                dst += 2;
+                goto NextUnicode;
+            }
+        }
+
+        /* unknown */
+        *dst++ = 0x20;
+
+        NextUnicode: ;
+    }
+    return (dst - dst0);
+}
+
+int gsm_bcdnum_to_ascii(cbytes_t bcd, int count, bytes_t dst) {
+    int result = 0;
+    int shift = 0;
+
+    while (count > 0) {
+        int c = (bcd[0] >> shift) & 0xf;
+
+        if (c == 15 && count == 1) /* ignore trailing 0xf */
+            break;
+
+        if (c >= 14)
+            c = 0;
+
+        if (dst)
+            dst[result] = "0123456789*#,N"[c];
+        result += 1;
+
+        count--;
+        shift += 4;
+        if (shift == 8) {
+            shift = 0;
+            bcd += 1;
+        }
+    }
+    return result;
+}
+
+int gsm_bcdnum_from_ascii(cbytes_t ascii, int asciilen,
+        bytes_t dst) {
+    cbytes_t end = ascii + asciilen;
+    int result = 0;
+    int phase = 0x01;
+
+    while (ascii < end) {
+        int c = *ascii++;
+
+        if (c == '*')
+            c = 10;
+        else if (c == '#')
+            c = 11;
+        else if (c == ',')
+            c = 12;
+        else if (c == 'N')
+            c = 13;
+        else {
+            c -= '0';
+            if ((unsigned) c >= 10U)
+                return -1;
+        }
+        phase = (phase << 4) | c;
+        result += 1;
+        if (phase & 0x100) {
+            if (dst)
+                dst[result / 2] = (byte_t) phase;
+            phase = 0x01;
+        }
+    }
+
+    if (result & 1) {
+        if (dst)
+            dst[result / 2] = (byte_t) (phase | 0xf0);
+    }
+    return result;
+}
+
+/** ADN: Abbreviated Dialing Number
+ **/
+
+#define  ADN_FOOTER_SIZE     14
+#define  ADN_OFFSET_NUMBER_LENGTH   0
+#define  ADN_OFFSET_TON_NPI         1
+#define  ADN_OFFSET_NUMBER_START    2
+#define  ADN_OFFSET_NUMBER_END      11
+#define  ADN_OFFSET_CAPABILITY_ID   12
+#define  ADN_OFFSET_EXTENSION_ID    13
+
+/* see 10.5.1 of 3GPP 51.011 */
+static int sim_adn_alpha_to_utf8(cbytes_t alpha, cbytes_t end, bytes_t dst) {
+    int result = 0;
+
+    /* ignore trailing 0xff */
+    while (alpha < end && end[-1] == 0xff)
+        end--;
+
+    if (alpha >= end)
+        return 0;
+
+    if (alpha[0] == 0x80) { /* UCS/2 source encoding */
+        alpha += 1;
+        result = ucs2_to_utf8(alpha, (end - alpha) / 2, dst);
+    } else {
+        int is_ucs2 = 0;
+        int len = 0, base = 0;
+
+        if (alpha + 3 <= end && alpha[0] == 0x81) {
+            is_ucs2 = 1;
+            len = alpha[1];
+            base = alpha[2] << 7;
+            alpha += 3;
+            if (len > end - alpha)
+                len = end - alpha;
+        } else if (alpha + 4 <= end && alpha[0] == 0x82) {
+            is_ucs2 = 1;
+            len = alpha[1];
+            base = (alpha[2] << 8) | alpha[3];
+            alpha += 4;
+            if (len > end - alpha)
+                len = end - alpha;
+        }
+
+        if (is_ucs2) {
+            end = alpha + len;
+            while (alpha < end) {
+                int c = alpha[0];
+                if (c >= 0x80) {
+                    result += utf8_write(dst, result, base + (c & 0x7f));
+                    alpha += 1;
+                } else {
+                    /* GSM character set */
+                    int count;
+                    for (count = 0; alpha + count < end && alpha[count] < 128;
+                            count++)
+                        ;
+                    result += utf8_from_gsm8(alpha, count,
+                            (dst ? dst + result : NULL));
+                    alpha += count;
+                }
+            }
+        } else {
+            result = utf8_from_gsm8(alpha, end - alpha, dst);
+        }
+    }
+    return result;
+}
+
+#if 0
+    static int
+    sim_adn_alpha_from_utf8( cbytes_t  utf8, int  utf8len, bytes_t  dst )
+    {
+        int   result = 0;
+
+        if (utf8_check_gsm7(utf8, utf8len)) {
+            /* GSM 7-bit compatible, encode directly as 8-bit string */
+            result = utf8_to_gsm8(utf8, utf8len, dst);
+        } else {
+            /* otherwise, simply try UCS-2 encoding, nothing more serious at the moment */
+            if (dst) {
+                dst[0] = 0x80;
+            }
+            result = 1 + utf8_to_ucs2(utf8, utf8len, dst ? (dst+1) : NULL)*2;
+        }
+        return  result;
+    }
+#endif
+
+int sim_adn_record_from_bytes(SimAdnRecord rec, cbytes_t data,
+        int len) {
+    cbytes_t end = data + len;
+    cbytes_t footer = end - ADN_FOOTER_SIZE;
+    int num_len;
+
+    rec->adn.alpha[0] = 0;
+    rec->adn.number[0] = 0;
+    rec->ext_record = 0xff;
+
+    if (len < ADN_FOOTER_SIZE)
+        return -1;
+
+    /* alpha is optional */
+    if (len > ADN_FOOTER_SIZE) {
+        cbytes_t dataend = data + len - ADN_FOOTER_SIZE;
+        int count = sim_adn_alpha_to_utf8(data, dataend, NULL);
+        int alphaLen = sizeof(rec->adn.alpha) - 1;
+        if (count > alphaLen) /* too long */
+            return -1;
+
+        sim_adn_alpha_to_utf8(data, dataend, rec->adn.alpha);
+        rec->adn.alpha[count] = 0;
+    }
+
+    num_len = footer[ADN_OFFSET_NUMBER_LENGTH];
+    if (num_len > 11)
+        return -1;
+
+    /* decode TON and number to ASCII, NOTE: this is lossy !! */
+    {
+        int ton = footer[ADN_OFFSET_TON_NPI];
+        bytes_t number = (bytes_t) rec->adn.number;
+        int number_len = sizeof(rec->adn.number) - 1;
+        int count;
+
+        if (ton != 0x81 && ton != 0x91)
+            return -1;
+
+        if (ton == 0x91) {
+            *number++ = '+';
+            number_len -= 1;
+        }
+
+        count = gsm_bcdnum_to_ascii(footer + ADN_OFFSET_NUMBER_START,
+                num_len * 2, number);
+        number[count] = 0;
+    }
+    return 0;
+}
+
+int sim_adn_record_to_bytes(SimAdnRecord rec, bytes_t data,
+        int datalen) {
+    bytes_t end = data + datalen;
+    bytes_t footer = end - ADN_FOOTER_SIZE;
+    int ton = 0x81;
+    cbytes_t number = (cbytes_t) rec->adn.number;
+
+    if (number[0] == '+') {
+        ton = 0x91;
+        number += 1;
+    }
+    footer[0] = (strlen((const char*) number) + 1) / 2 + 1;
+    /* XXXX: TODO */
+    return 0;
+}
+
+/* Convert "00 00" to "00 20" */
+int zero4_to_space(bytes_t ucs2, int ucs2len) {
+    int i, count = 0;
+
+    //LOGD("zero4_to_space\n");
+    /* Ignore the last character */
+    for (i = 0; i < (ucs2len - 2); i += 2) {
+        if ((ucs2[i] == 0) && (ucs2[i + 1] == 0)) {
+            ucs2[i + 1] = 0x20; /* Space character */
+            count++;
+        }
+        //LOGD("%d %d ", ucs2[i], ucs2[i+1]);
+    }
+    //LOGD("\n");
+    return count;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/utils/GsmUtils.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/utils/GsmUtils.h
new file mode 100644
index 0000000..2a28f95
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/gost/utils/GsmUtils.h
@@ -0,0 +1,239 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef UTILS_GSMUTILS_H_
+#define UTILS_GSMUTILS_H_
+
+#include <cstdint>
+
+#define RIL_GSM_UTIL_UNUSED_PARM(x) (x)   //eliminate "warning: unused parameter"
+
+/** USEFUL TYPES
+ **/
+
+typedef unsigned char  byte_t;
+typedef byte_t*        bytes_t;
+typedef const byte_t*  cbytes_t;
+
+#ifndef MIN
+    #define MIN(x, y)   ((x) <= (y))? (x): (y)
+#endif
+
+/** BCD
+ **/
+
+/* convert a 8-bit value into the corresponding nibble-bcd byte */
+byte_t   gsm_int_to_bcdi( int  value );
+
+/* convert a nibble-bcd byte into an int, invalid nibbles are silently converted to 0 */
+int      gsm_int_from_bcdi( byte_t  value );
+
+/** HEX
+ **/
+
+/* try to convert a hex string into a byte string, assumes 'dst' is properly sized, and hexlen is even.
+ * returns the number of bytes on exit, or -1 in case of badly formatted data */
+int      gsm_hex_to_bytes  ( cbytes_t  hex, int  hexlen, bytes_t  dst );
+
+/* convert a hex string into a byte string, assumes 'dst' is properly sized, and hexlen is even.
+ * no checks are performed */
+void     gsm_hex_to_bytes0 ( cbytes_t  hex, int  hexlen, bytes_t  dst );
+
+/* convert a byte string into a hex string, assumes 'hex' is properly sized */
+void     gsm_hex_from_bytes( char*  hex, cbytes_t  src, int  srclen );
+
+/* convert a hexchar to an int, returns -1 on error */
+int      gsm_hexchar_to_int( char  c );
+
+/* convert a hexchar to an int, returns 0 on error */
+int      gsm_hexchar_to_int0( char  c );
+
+/* convert a 2-char hex value into an int, returns -1 on error */
+int      gsm_hex2_to_byte( const char*  hex );
+
+/* convert a 2-char hex value into an int, returns 0 on error */
+int      gsm_hex2_to_byte0( const char*  hex );
+
+/* convert a 4-char hex value into an int, returns -1 on error */
+int      gsm_hex4_to_short( const char*  hex );
+
+/* convert a 4-char hex value into an int, returns -1 on error */
+int64_t  gsm_hex8_to_int( const char*  hex );
+
+/* convert a 4-char hex value into an int, returns 0 on error */
+int      gsm_hex4_to_short0( const char*  hex );
+
+/* write a byte to a 2-byte hex string */
+void     gsm_hex_from_byte( char*  hex, int  val );
+
+void     gsm_hex_from_short( char*  hex, int  val );
+
+void     gsm_hex_from_int(char* hex, int64_t val);
+
+/** UTF-8 and GSM Alphabet
+ **/
+
+/* check that a given utf8 string is well-formed, returns 1 on success, 0 otherwise */
+int      utf8_check( cbytes_t  utf8, int  utf8len );
+
+/* check that all characters in a given utf8 string can be encoded into the GSM alphabet.
+   returns 1 if TRUE, 0 otherwise */
+int      utf8_check_gsm7( cbytes_t  utf8, int  utf8len );
+
+/* try to skip enough utf8 characters to generate gsm7len GSM septets */
+cbytes_t utf8_skip_gsm7( cbytes_t  utf8, cbytes_t  utf8end, int  gsm7len );
+
+/* convert a utf-8 string into a GSM septet string, assumes 'dst' is NULL or is properly sized,
+   and that all characters are representable. 'offset' is the starting bit offset in 'dst'.
+   non-representable characters are replaced by spaces.
+   returns the number of septets, */
+int      utf8_to_gsm7( cbytes_t  utf8, int  utf8len, bytes_t  dst, int  offset );
+
+/* convert a utf8 string into an array of 8-bit unpacked GSM septets,
+ * assumes 'dst' is NULL or is properly sized, returns the number of GSM bytes */
+int      utf8_to_gsm8( cbytes_t  utf8, int  utf8len, bytes_t  dst );
+
+/* convert a GSM septets string into a utf-8 byte string. assumes that 'utf8' is NULL or properly
+   sized. 'offset' is the starting bit offset in 'src', 'count' is the number of input septets.
+   return the number of utf8 bytes. */
+int      utf8_from_gsm7( cbytes_t  src, int  offset, int  count, bytes_t  utf8 );
+
+/* convert an unpacked GSM septets string into a utf-8 byte string. assumes that 'utf8' is NULL or properly
+   sized. 'offset' is the starting bit offset in 'src', 'count' is the number of input septets.
+   return the number of utf8 bytes. */
+int      utf8_from_unpackedgsm7( cbytes_t  src, int  offset, int  count, bytes_t  utf8 );
+
+/* convert an unpacked 8-bit GSM septets string into a utf-8 byte string. assumes that 'utf8'
+   is NULL or properly sized. 'count' is the number of input bytes.
+   returns the number of utf8 bytes */
+int      utf8_from_gsm8( cbytes_t  src, int  count, bytes_t  utf8 );
+
+
+/** UCS-2 and GSM Alphabet
+ **
+ ** Note that here, 'ucs2' really refers to non-aligned UCS2-BE, as used by the GSM standard
+ **/
+
+/* check that all characters in a given ucs2 string can be encoded into the GSM alphabet.
+   returns 1 if TRUE, 0 otherwise */
+int      ucs2_check_gsm7( cbytes_t  ucs2, int  ucs2len );
+
+/* convert a ucs2 string into a GSM septet string, assumes 'dst' is NULL or properly sized,
+   'offset' is the starting bit offset in 'dst'. non-representable characters are replaced
+   by spaces. returns the number of septets */
+int      ucs2_to_gsm7( cbytes_t  ucs2, int  ucs2len, bytes_t  dst, int  offset );
+
+/* convert a ucs2 string into a GSM septet string, assumes 'dst' is NULL or properly sized,
+   non-representable characters are replaced by spaces. returns the number of bytes */
+int      ucs2_to_gsm8( cbytes_t  ucs2, int  ucs2len, bytes_t  dst );
+
+/* convert a GSM septets string into a ucs2 string. assumes that 'ucs2' is NULL or
+   properly sized. 'offset' is the starting bit offset in 'src', 'count' is the number
+   of input septets. return the number of ucs2 characters (not bytes) */
+int      ucs2_from_gsm7( bytes_t   ucs2, cbytes_t  src, int  offset, int  count );
+
+/* convert an 8-bit unpacked GSM septets string into a ucs2 string. assumes that 'ucs2'
+   is NULL or properly sized. 'count' is the number of input septets. return the number
+   of ucs2 characters (not bytes) */
+int      ucs2_from_gsm8( bytes_t   ucs2, cbytes_t  src, int  count );
+
+
+/** UCS2 to/from UTF8
+ **/
+
+/* convert a ucs2 string into a utf8 byte string, assumes 'utf8' NULL or properly sized.
+   returns the number of utf8 bytes*/
+int      ucs2_to_utf8( cbytes_t  ucs2, int  ucs2len, bytes_t  utf8 );
+
+/* convert a utf8 byte string into a ucs2 string, assumes 'ucs2' NULL or properly sized.
+   returns the number of ucs2 chars */
+extern int      utf8_to_ucs2( cbytes_t  utf8, int  utf8len, bytes_t  ucs2 );
+
+/* try to skip a given number of characters in a utf-8 byte string, return new position */
+cbytes_t  utf8_skip( cbytes_t   utf8, cbytes_t   utf8end, int  count);
+
+/** Dial Numbers: TON byte + 'count' bcd numbers
+ **/
+
+/* convert a bcd-coded GSM dial number into an ASCII string (not zero-terminated)
+   assumes 'dst' is NULL or properly sized, returns 0 in case of success, -1 in case of error.
+   'num_digits' is the number of digits, not input bytes. a trailing 0xf0 is ignored automatically
+   return the number of ASCII chars */
+int  gsm_bcdnum_to_ascii  ( cbytes_t  bcd, int  num_digits, bytes_t  dst );
+
+/* convert an ASCII dial-number into a bcd-coded string, returns the number of 4-bit nibbles written, */
+int  gsm_bcdnum_from_ascii( cbytes_t  ascii, int  asciilen, bytes_t  dst );
+
+/** ADN: Abbreviated Dialing Numbers
+ **/
+#define  SIM_ADN_MAX_ALPHA        20  /* maximum number of characters in ADN alpha tag */
+#define  SIM_ADN_MAX_NUMBER       20  /* maximum digits in ADN number */
+
+typedef struct {
+    byte_t  alpha [ SIM_ADN_MAX_ALPHA*3+1 ];  /* alpha tag in zero-terminated utf-8      */
+    char    number[ SIM_ADN_MAX_NUMBER+1 ];   /* dialing number in zero-terminated ASCII */
+}
+SimAdnRec, *SimAdn;
+
+typedef struct {
+    SimAdnRec       adn;
+    byte_t          ext_record;  /* 0 or 0xFF means no extension */
+}
+SimAdnRecordRec, *SimAdnRecord;
+
+int  sim_adn_record_from_bytes( SimAdnRecord  rec, cbytes_t  data, int  datalen );
+int  sim_adn_record_to_bytes  ( SimAdnRecord  rec, bytes_t   data, int  datalen );
+
+/** ROPES
+ **/
+
+typedef struct {
+    bytes_t         data;
+    int             max;
+    int             pos;
+    int             error;
+    unsigned char   data0[16];
+} GsmRopeRec, *GsmRope;
+
+void      gsm_rope_init( GsmRope  rope );
+void      gsm_rope_init_alloc( GsmRope  rope, int  alloc );
+int       gsm_rope_done( GsmRope  rope );
+bytes_t   gsm_rope_done_acquire( GsmRope  rope, int  *psize );
+void      gsm_rope_add_c( GsmRope  rope, char  c );
+void      gsm_rope_add( GsmRope  rope, const void*  str, int  len );
+void*     gsm_rope_reserve( GsmRope  rope, int  len );
+int       zero4_to_space(bytes_t  ucs2, int ucs2len) ;
+
+#endif /* UTILS_GSMUTILS_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em.cpp
new file mode 100644
index 0000000..7e9609f
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em.cpp
@@ -0,0 +1,734 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include "em/em.h"
+
+#include <vendor-ril/telephony/ril.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <cutils/jstring.h>
+#include <log/log.h>
+#include <unistd.h>
+#include <math.h>
+#include  "common.h"
+
+#if EM_MODE_SUPPORT
+
+#undef LOG_TAG
+#define LOG_TAG "EM_ENTRY"
+
+#define NUM_ITEMS(a)     (sizeof (a) / sizeof (a)[0])
+em_arry_t lte_info[] = {
+    //{"4G ERRC Misc Info",0,NULL,1,1},
+    //{"4G LTE Support Band",0,NULL,1,1},
+    //{"4G Active Intra-RAT Meas (LTE)",0,NULL,1,1},
+    //{"4G Active Inter-RAT Meas (UMTS)",0,NULL,1,1},
+    //{"4G Active Inter-RAT Meas (GSM)",0,NULL,1,1},
+    //{"4G SIB Receive Status",0,NULL,1,1},
+    //{"4G CSG Autonomous Search",0,NULL,1,1},
+    //{"4G Config Info",0,NULL,1,1},
+    //{"ESM",0,NULL,1,1},
+    //{"EMM",0,NULL,1,1},
+    //{"MMDC",0,NULL,1,1},
+    {"EL1",0,NULL,1,1},
+    //{"Timer Information",0,NULL,1,1},
+    //{"TDD TAS",0,NULL,1,1},
+    //{"GSM TAS",0,NULL,1,1},
+    //{"WCDMA TAS",0,NULL,1,1},
+    //{"LTE TAS",0,NULL,1,1},
+};
+em_arry_t ims_setting[] = {
+    {"get",0,NULL,0,0},
+    {"set",0,NULL,0,0},
+};
+em_arry_t ims_common[] = {
+    {"operator_code",2,ims_setting,0,0},
+    {"sms_support",2,ims_setting,0,0},
+    {"voice_support",2,ims_setting,0,0}
+};
+em_arry_t ims_call[] = {
+    {"UA_call_codec_order1",2,ims_setting,0,0},
+    {"UA_call_codec_order2",2,ims_setting,0,0},
+    {"UA_call_codec_order3",2,ims_setting,0,0},
+    {"silence_dropcall_threshold",2,ims_setting,0,0},
+    {"jbm_load_params_enable",2,ims_setting,0,0},
+    {"jbm_prebuf_len",2,ims_setting,0,0},
+};
+em_arry_t ims_registration[] = {
+    {"emergency_reg_retain_timer",2,ims_setting,0,0},
+    {"UA_reg_auth_password",2,ims_setting,0,0},
+    {"UA_reg_auth_name",2,ims_setting,0,0},
+    {"VoLTE_Setting_SIP_TCP_On_Demand",2,ims_setting,0,0},
+};
+em_arry_t ims[] = {
+    {"Common",NUM_ITEMS(ims_common),ims_common,1,1},
+    {"Call",NUM_ITEMS(ims_call),ims_call,1,1},
+    {"Registration",NUM_ITEMS(ims_registration),ims_registration,1,1},
+};
+em_arry_t gprs[] = {
+    {"ATTACH",0,NULL,1,1},
+    {"DETACH",0,NULL,1,1},
+    {"ATTACH_CONTINUE",0,NULL,1,1},
+    {"DETACH_CONTINUE",0,NULL,1,1},
+    {"SELECT_ATTACH_TYPE_1",0,NULL,1,1},
+    {"SELECT_ATTACH_TYPE_0",0,NULL,1,1},
+};
+em_arry_t networkselection[] = {
+    {"GSM/WCDMA (WCDMA preferred)",0,NULL,1,1},
+    {"GSM only",0,NULL,1,1},
+    {"WCDMA only",0,NULL,1,1},
+    {"GSM/WCDMA (auto)",0,NULL,1,1},
+    {"LTE only",0,NULL,1,1},
+    {"4G/3G/2G(auto)",0,NULL,1,1},
+    {"4G/3G",0,NULL,1,1},
+};
+em_arry_t modem_cta[] = {
+    {"Integrity Check",0,NULL,1,1},
+    {"RLC TL1",0,NULL,1,1},
+    {"K1297",0,NULL,1,1},
+    {"SN Conflict",0,NULL,1,1},
+    {"CF query",0,NULL,1,1},
+    {"DLMN lock",0,NULL,1,1},
+    {"Measurement open",0,NULL,1,1},
+    {"Disable DPA",0,NULL,1,1},
+    {"Intra CMR",0,NULL,1,1},
+};
+em_arry_t modem_fta[] = {
+    {"ANITE",0,NULL,1,1},
+    {"CRTUG",0,NULL,1,1},
+    {"CRTUW",0,NULL,1,1},
+    {"ANRITSU",0,NULL,1,1},
+    {"CMW500",0,NULL,1,1},
+};
+em_arry_t modem_C2K_Test_MODEM[] = {
+    { "NONE", 0, NULL, 1, 1 },
+    { "SPIRENT", 0,NULL, 1, 1 },
+};
+em_arry_t modemtest[] = {
+    {"NONE",0,NULL,1,1},
+    {"CTA",NUM_ITEMS(modem_cta),modem_cta,1,1},
+    {"FTA",NUM_ITEMS(modem_fta),modem_fta,1,1},
+    {"IOT",0,NULL,1,1},
+    {"OPERATOR",0,NULL,1,1},
+    {"FACTORY",0,NULL,1,1},
+    {"CDMA Test Mode", NUM_ITEMS(modem_C2K_Test_MODEM),modem_C2K_Test_MODEM,1,1},
+};
+em_arry_t hspa[] = {
+    {"QUERY",0,NULL,1,1},
+};
+em_arry_t cfu[] = {
+    {"Default",0,NULL,1,1},
+    {"Always query",0,NULL,1,1},
+    {"Always not query",0,NULL,1,1},
+};
+em_arry_t bandmode[] = {
+    {"getcurrentband",0,NULL,1,1},
+    {"setBand(eg: 1.1=1 add band, 1.1=0 remove band) or getSupportBand",0,NULL,1,1},
+};
+em_arry_t networkinfo[] = {
+    {"RR Cell Sel",0,NULL,1,1},
+    {"RR Ch Dscr",0,NULL,1,1},
+    {"RR Ctrl chan",0,NULL,1,1},
+    {"RR RACH Ctrl",0,NULL,1,1},
+    {"RR LAI Info",0,NULL,1,1},
+    {"RR Radio Link",0,NULL,1,1},
+    {"RR Meas Rep",0,NULL,1,1},
+    {"RR Ca List",0,NULL,1,1},
+    {"RR Control Msg",0,NULL,1,1},
+    {"RR SI2Q Info",0,NULL,1,1},
+    {"RR MI Info",0,NULL,1,1},
+    {"RR BLK Info",0,NULL,1,1},
+    {"RR TBF Info",0,NULL,1,1},
+    {"RR GPRS Gen",0,NULL,1,1},
+    {"SMEmInfo",0,NULL,1,1},
+    {"3GMmEmInfo",0,NULL,1,1},
+    {"GmmEmInfo",0,NULL,1,1},
+#if 1
+    {"3GTcmMmiEmInfo",0,NULL,1,1},
+    {"3GGeneralStatusInd",0,NULL,1,1},
+    {"xGCsceEMNeighCellSStatusInd",0,NULL,1,1},
+    {"3GCsceEMServCellSStatusInd",0,NULL,1,1},
+    {"3GCsceEmInfoMultiPlmn",0,NULL,1,1},
+    {"3GMemeEmPeriodicBlerReportInd",0,NULL,1,1},
+    {"3GUrrUmtsSrncId",0,NULL,1,1},
+    {"3GMemeEmInfoHServCellInd",0,NULL,1,1},
+#endif
+#if 1//fdd
+    {"3GMemeEmInfoUmtsCellStatus",0,NULL,1,1},
+    {"3GSlceEmPsDataRateStatusInd",0,NULL,1,1},
+#endif
+#if 0//tdd
+    {"3GHandoverSequenceIndStuct",0,NULL,1,1},
+    {"3GUl2EmAdmPoolStatusIndStruct",0,NULL,1,1},
+    {"3GUl2EmPsDataRateStatusIndStruct",0,NULL,1,1},
+    {"3GUl2EmHsdschReconfigStatusIndStruct",0,NULL,1,1},
+    {"3GUl2EmUrlcEventStatusIndStruct",0,NULL,1,1},
+    {"3G Ul2EmPeriodicBlerReportInd",0,NULL,1,1},
+#endif
+#if 0 //lte
+    {"3G speech codec",0,NULL,1,1},//lte
+    {"Security Configuration",0,NULL,1,1},//lte
+#endif
+};
+
+em_arry_t antenna_setmodes_4g[] {
+    {"RX1&RX2", 0, NULL, 1, 1},
+    {"RX1", 0, NULL, 1, 1},
+    {"RX2", 0, NULL, 1, 1},
+};
+
+em_arry_t antenna_setmodes_3g[] {
+    {"RX1", 0, NULL, 1, 1},
+    {"RX2", 0, NULL, 1, 1},
+    {"RX1&RX2", 0, NULL, 1, 1},
+    {"Resume default setting", 0, NULL, 1, 1},
+};
+
+em_arry_t antenna_setmodes_c2k[] {
+    {"Resume default setting", 0, NULL, 1, 1},
+    {"RX1", 0, NULL, 1, 1},
+    {"RX2", 0, NULL, 1, 1},
+    {"RX1&RX2", 0, NULL, 1, 1},
+};
+
+em_arry_t antenna_4Gmode[] = {
+    {"getmode",0,NULL,1,1},
+    {"setmode",NUM_ITEMS(antenna_setmodes_4g),antenna_setmodes_4g,1,1},
+};
+
+em_arry_t antenna_3Gmode[] = {
+    {"getmode",0,NULL,1,1},
+    {"setmode",NUM_ITEMS(antenna_setmodes_3g),antenna_setmodes_3g,1,1},
+};
+
+em_arry_t antenna_c2kmode[] = {
+    {"getmode",0,NULL,1,1},
+    {"setmode",NUM_ITEMS(antenna_setmodes_c2k),antenna_setmodes_c2k,1,1},
+};
+
+em_arry_t antennatest[] = {
+    {"4G",NUM_ITEMS(antenna_4Gmode),antenna_4Gmode,1,1},
+    {"3G",NUM_ITEMS(antenna_3Gmode),antenna_3Gmode,1,1},
+    {"CDMA",NUM_ITEMS(antenna_c2kmode),antenna_c2kmode,1,1},
+};
+
+em_arry_t time_reg[] = {
+    { "disable", 0,NULL, 1, 1 },
+    { "enable", 0, NULL, 1, 1 },
+};
+
+em_arry_t c2k_modem_setting[] {
+        {"TIME REG",NUM_ITEMS(time_reg),time_reg,1,1},
+};
+
+em_arry_t rfdesense_setting[] = {
+    {"start",0,NULL,0,0},
+    {"set",0,NULL,0,0},
+//    {"set_check_Limit",0,NULL,0,0},
+//    {"get_check_Limit",0,NULL,0,0},
+};
+
+em_arry_t set_get[] = {
+        {"get",0,NULL,0,0},
+        {"set",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_gsm_band[] = {
+        {"GSM 850",0,NULL,0,0},
+        {"P-GSM 900",0,NULL,0,0},
+        {"E-GSM 900",0,NULL,0,0},
+        {"R-GSM 900",0,NULL,0,0},
+        {"DCS 1800",0,NULL,0,0},
+        {"PCS 1900",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_gsm_pattern[] = {
+        {"RFTOOL_NB_TX_RANDOM_WITH_TSC",0,NULL,0,0},
+        {"RFTOOL_NB_TX_ALL_ONES_WITHOUT_TSC",0,NULL,0,0},
+        {"RFTOOL_AB_TX_RANDOM_WITH_SYNC_SEQ",0,NULL,0,0},
+        {"RFTOOL_CONT_TX_ALL_ZEROS",0,NULL,0,0},
+        {"RFTOOL_CONT_TX_ALL_ONES",0,NULL,0,0},
+        {"RFTOOL_CONT_TX_ALTERNATE_BITS",0,NULL,0,0},
+        {"RFTOOL_CONT_TX_PSEUDO_RANDOM",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_gsm_sub[] = {
+        {"Band",NUM_ITEMS(rfdesense_gsm_band),rfdesense_gsm_band,0,0},
+        {"Channel(ARFCN)",NUM_ITEMS(set_get),set_get,0,0},
+        {"Power Level",NUM_ITEMS(set_get),set_get,0,0},
+        {"AFC",NUM_ITEMS(set_get),set_get,0,0},
+        {"TSC",NUM_ITEMS(set_get),set_get,0,0},
+        {"PATTERN",NUM_ITEMS(rfdesense_gsm_pattern),rfdesense_gsm_pattern,0,0},
+};
+
+em_arry_t rfdesense_gsm[] = {
+        {"start",0,NULL,0,0},
+        {"Parameters_set",NUM_ITEMS(rfdesense_gsm_sub),rfdesense_gsm_sub,0,0},
+        {"show default",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_tdscdma_band[] = {
+        {"Band A",0,NULL,0,0},
+        {"Band F",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_tdscdma_sub[] = {
+        {"Band",NUM_ITEMS(rfdesense_tdscdma_band),rfdesense_tdscdma_band,0,0},
+        {"Channel(ARFCN)",NUM_ITEMS(set_get),set_get,0,0},
+        {"Power Level(dBm)",NUM_ITEMS(set_get),set_get,0,0},
+};
+
+em_arry_t rfdesense_tdscdma[] = {
+        {"start",0,NULL,0,0},
+        {"Parameters_set",NUM_ITEMS(rfdesense_tdscdma_sub),rfdesense_tdscdma_sub,0,0},
+        {"show default",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_wcdma_band[] = {
+        {"Band 1",0,NULL,0,0},
+        {"Band 2",0,NULL,0,0},
+        {"Band 3",0,NULL,0,0},
+        {"Band 4",0,NULL,0,0},
+        {"Band 5",0,NULL,0,0},
+        {"Band 6",0,NULL,0,0},
+        {"Band 7",0,NULL,0,0},
+        {"Band 8",0,NULL,0,0},
+        {"Band 9",0,NULL,0,0},
+        {"Band 10",0,NULL,0,0},
+        {"Band 11",0,NULL,0,0},
+        {"Band 12",0,NULL,0,0},
+        {"Band 13",0,NULL,0,0},
+        {"Band 14",0,NULL,0,0},
+        {"Band 19",0,NULL,0,0},
+        {"Band 20",0,NULL,0,0},
+        {"Band 21",0,NULL,0,0},
+        {"Band 22",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_wcdma_sub[] = {
+        {"Band",NUM_ITEMS(rfdesense_wcdma_band),rfdesense_wcdma_band,0,0},
+        {"Channel(ARFCN)",NUM_ITEMS(set_get),set_get,0,0},
+        {"Power Level(dBm)",NUM_ITEMS(set_get),set_get,0,0},
+};
+
+em_arry_t rfdesense_wcdma[] {
+        {"start",0,NULL,0,0},
+        {"Parameters_set",NUM_ITEMS(rfdesense_wcdma_sub),rfdesense_wcdma_sub,0,0},
+        {"show default",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_lte_mode[] = {
+        {"single tone",0,NULL,0,0},
+        {"modulation signal",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_fdd_band[] = {
+        {"1",0,NULL,0,0},
+        {"2",0,NULL,0,0},
+        {"3",0,NULL,0,0},
+        {"4",0,NULL,0,0},
+        {"5",0,NULL,0,0},
+        {"6",0,NULL,0,0},
+        {"7",0,NULL,0,0},
+        {"8",0,NULL,0,0},
+        {"9",0,NULL,0,0},
+        {"10",0,NULL,0,0},
+        {"11",0,NULL,0,0},
+        {"12",0,NULL,0,0},
+        {"13",0,NULL,0,0},
+        {"14",0,NULL,0,0},
+        {"15",0,NULL,0,0},
+        {"16",0,NULL,0,0},
+        {"17",0,NULL,0,0},
+        {"18",0,NULL,0,0},
+        {"19",0,NULL,0,0},
+        {"20",0,NULL,0,0},
+        {"21",0,NULL,0,0},
+        {"22",0,NULL,0,0},
+        {"23",0,NULL,0,0},
+        {"24",0,NULL,0,0},
+        {"25",0,NULL,0,0},
+        {"26",0,NULL,0,0},
+        {"27",0,NULL,0,0},
+        {"28",0,NULL,0,0},
+        {"29",0,NULL,0,0},
+        {"30",0,NULL,0,0},
+        {"31",0,NULL,0,0},
+        {"66",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_lte_bandwidth[] = {
+        {"1.4M",0,NULL,0,0},
+        {"3M",0,NULL,0,0},
+        {"5M",0,NULL,0,0},
+        {"10M",0,NULL,0,0},
+        {"15M",0,NULL,0,0},
+        {"20M",0,NULL,0,0},
+};
+
+em_arry_t  rfdesense_lte_mcs[] = {
+        {"QPSK",0,NULL,0,0},
+        {"16QAM",0,NULL,0,0},
+        {"64QAM",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_fdd_sub[] = {
+        {"mode",NUM_ITEMS(rfdesense_lte_mode),rfdesense_lte_mode,0,0},
+        {"band",NUM_ITEMS(rfdesense_fdd_band),rfdesense_fdd_band,0,0},
+        {"UL Bandwidth",NUM_ITEMS(rfdesense_lte_bandwidth),rfdesense_lte_bandwidth,0,0},
+        {"UL Freq(100kHz)",NUM_ITEMS(set_get),set_get,0,0},
+        {"VRB Start(0-99)",NUM_ITEMS(set_get),set_get,0,0},
+        {"VRB Length(1-100)",NUM_ITEMS(set_get),set_get,0,0},
+        {"MCS",NUM_ITEMS(rfdesense_lte_mcs),rfdesense_lte_mcs,0,0},
+        {"Power Level(dbm)(-50_23)",NUM_ITEMS(set_get),set_get,0,0},
+};
+
+em_arry_t rfdesense_lte_fdd[] = {
+        {"start",0,NULL,0,0},
+        {"Parameters_set",NUM_ITEMS(rfdesense_fdd_sub),rfdesense_fdd_sub,0,0},
+        {"show default",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_tdd_band[] = {
+        {"33",0,NULL,0,0},
+        {"34",0,NULL,0,0},
+        {"35",0,NULL,0,0},
+        {"36",0,NULL,0,0},
+        {"37",0,NULL,0,0},
+        {"38",0,NULL,0,0},
+        {"39",0,NULL,0,0},
+        {"40",0,NULL,0,0},
+        {"41",0,NULL,0,0},
+        {"42",0,NULL,0,0},
+        {"43",0,NULL,0,0},
+        {"44",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_tdd_config[] = {
+        {"0",0,NULL,0,0},
+        {"1",0,NULL,0,0},
+        {"2",0,NULL,0,0},
+        {"3",0,NULL,0,0},
+        {"4",0,NULL,0,0},
+        {"5",0,NULL,0,0},
+        {"6",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_tdd_special[] = {
+        {"0",0,NULL,0,0},
+        {"1",0,NULL,0,0},
+        {"2",0,NULL,0,0},
+        {"3",0,NULL,0,0},
+        {"4",0,NULL,0,0},
+        {"5",0,NULL,0,0},
+        {"6",0,NULL,0,0},
+        {"7",0,NULL,0,0},
+        {"8",0,NULL,0,0},
+        {"9",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_tdd_sub[] = {
+        {"mode",NUM_ITEMS(rfdesense_lte_mode),rfdesense_lte_mode,0,0},
+        {"band",NUM_ITEMS(rfdesense_tdd_band),rfdesense_tdd_band,0,0},
+        {"UL Bandwidth",NUM_ITEMS(rfdesense_lte_bandwidth),rfdesense_lte_bandwidth,0,0},
+        {"UL Freq(100kHz)",NUM_ITEMS(set_get),set_get,0,0},
+        {"TDD Config Index",NUM_ITEMS(rfdesense_tdd_config),rfdesense_tdd_config,0,0},
+        {"TDD Special SF Config Index",NUM_ITEMS(rfdesense_tdd_special),rfdesense_tdd_special,0,0},
+        {"VRB Start(0-99)",NUM_ITEMS(set_get),set_get,0,0},
+        {"VRB Length(1-100)",NUM_ITEMS(set_get),set_get,0,0},
+        {"MCS",NUM_ITEMS(rfdesense_lte_mcs),rfdesense_lte_mcs,0,0},
+        {"Power Level(dbm)(-50_23)",NUM_ITEMS(set_get),set_get,0,0},
+};
+
+em_arry_t rfdesense_lte_tdd[] = {
+        {"start",0,NULL,0,0},
+        {"Parameters_set",NUM_ITEMS(rfdesense_tdd_sub),rfdesense_tdd_sub,0,0},
+        {"show default",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_cdma_band[] = {
+        {"Band 0",0,NULL,0,0},
+        {"Band 1",0,NULL,0,0},
+        {"Band 2",0,NULL,0,0},
+        {"Band 3",0,NULL,0,0},
+        {"Band 4",0,NULL,0,0},
+        {"Band 5",0,NULL,0,0},
+        {"Band 6",0,NULL,0,0},
+        {"Band 7",0,NULL,0,0},
+        {"Band 8",0,NULL,0,0},
+        {"Band 9",0,NULL,0,0},
+        {"Band 10",0,NULL,0,0},
+        {"Band 11",0,NULL,0,0},
+        {"Band 12",0,NULL,0,0},
+        {"Band 13",0,NULL,0,0},
+        {"Band 14",0,NULL,0,0},
+        {"Band 15",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_cdma_modulation[] = {
+        {"1X",0,NULL,0,0},
+        {"EVDO",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_cdma_sub[] = {
+        {"Band",NUM_ITEMS(rfdesense_cdma_band),rfdesense_cdma_band,0,0},
+        {"modulation",NUM_ITEMS(rfdesense_cdma_modulation),rfdesense_cdma_modulation,0,0},
+        {"Channel(ARFCN)",NUM_ITEMS(set_get),set_get,0,0},
+        {"Power Level(dBm)",NUM_ITEMS(set_get),set_get,0,0},
+};
+
+em_arry_t rfdesense_cdma[] = {
+        {"start",0,NULL,0,0},
+        {"Parameters_set",NUM_ITEMS(rfdesense_cdma_sub),rfdesense_cdma_sub,0,0},
+        {"show default",0,NULL,0,0},
+};
+
+em_arry_t sub_tx_test[] = {
+    { "GSM", NUM_ITEMS(rfdesense_gsm),rfdesense_gsm, 1, 1 },
+    { "TDSCDMA", NUM_ITEMS(rfdesense_tdscdma), rfdesense_tdscdma, 1, 1 },
+    { "WCDMA", NUM_ITEMS(rfdesense_wcdma), rfdesense_wcdma, 1, 1 },
+    { "LTE(FDD)", NUM_ITEMS(rfdesense_lte_fdd), rfdesense_lte_fdd, 1, 1 },
+    { "LTE(TDD)", NUM_ITEMS(rfdesense_lte_tdd), rfdesense_lte_tdd, 1, 1 },
+#ifdef C2K_SUPPORT
+    { "CDMA(EVDO)", NUM_ITEMS(rfdesense_cdma), rfdesense_cdma, 1, 1 },
+    { "CDMA(1x)", NUM_ITEMS(rfdesense_cdma), rfdesense_cdma, 1, 1 },
+#endif/*C2K_SUPPORT*/
+};
+
+em_arry_t desense_test[] {
+        {"Tx Test",NUM_ITEMS(sub_tx_test),sub_tx_test,1,1},
+};
+
+em_arry_t no_support[] {
+        {"NO SUPPORT",0,NULL,0,0},
+};
+
+em_arry_t emmain[] = {
+    {"CDMA modem setting",NUM_ITEMS(c2k_modem_setting),c2k_modem_setting,0,0},
+    {"RF Desense Test ",NUM_ITEMS(desense_test),desense_test,0,0},
+    {"Modem Test",NUM_ITEMS(modemtest),modemtest,0,0},
+    {"HSPA",NUM_ITEMS(hspa),hspa,0,0},
+    {"CFU",NUM_ITEMS(cfu),cfu,0,0},
+    {"Antenna Test",NUM_ITEMS(antennatest),antennatest,0,0},
+    {"Band Mode",NUM_ITEMS(bandmode),bandmode,0,0},
+    {"IMS",NUM_ITEMS(ims),ims,0,0},
+    //{"Network Info",NUM_ITEMS(networkinfo),networkinfo,0,0},
+    {"Network Info",NUM_ITEMS(no_support),no_support,0,0},
+    {"LTE",NUM_ITEMS(lte_info),lte_info,0,0},
+    //{"GPRS Attach",NUM_ITEMS(gprs),gprs,0,0}, // replace data allow script
+    //{"NetworkSelection",NUM_ITEMS(networkselection),networkselection,0,0}, // repplace with script
+};
+typedef enum {
+    C2K_MODEM_SETTING = 0,
+    RF_DESENSE_TEST,
+    MODEM_TEST_ITEM,
+    HSPA_ITEM,
+    CFU_ITEM,
+    ANTENNATEST_ITEM,
+    BANDMODE_ITEM,
+    IMS_ITEM,
+    NO_SUPPORT,
+    //NETWORKINFO_ITEM,
+    LTE_ITEM,
+}EM_MAIN_ITEM;
+em_arry_t em = {"Telephony",NUM_ITEMS(emmain),emmain,0,0};
+int em_main(int len, int *item, int multilen, char *value[]) {
+    int testclass = item[0];
+    RLOGD("em_main testclase %d", testclass);
+    switch (testclass) {
+    case C2K_MODEM_SETTING:
+        emC2kModemSettingStart(len - 1, multilen, &item[1]);
+        break;
+    case RF_DESENSE_TEST:
+        emRfDesenseStart(len - 1, &item[1], multilen, value);
+        break;
+    case MODEM_TEST_ITEM:
+        emModemtestStart(len - 1, multilen, &item[1]);
+        break;
+    case HSPA_ITEM:
+        emHspaStart(len - 1, &item[1]);
+        break;
+    case CFU_ITEM:
+        emCfuStart(len - 1, &item[1]);
+        break;
+    case ANTENNATEST_ITEM:
+        emAntennaTestStart(len - 1, &item[1],(value != NULL ? value[0] : NULL));
+        break;
+    case BANDMODE_ITEM:
+        emBandmodeStart(len - 1, &item[1], multilen, value);
+        break;
+    case IMS_ITEM:
+        emImsStart(len - 1, &item[1], (value != NULL ? value[0] : NULL));
+        break;
+//    case NETWORKINFO_ITEM:
+//        emNwInfoStart(len - 1, multilen, &item[1]);
+//        break;
+    case LTE_ITEM:
+        //lte_em_start(len - 1, multilen, &item[1]);
+        em_el1_start(len - 1, multilen, &item[1]);
+        break;
+    case NO_SUPPORT:
+        android::emResultNotify("don't support\n");
+        break;
+    default:
+        break;
+    }
+    return 0;
+}
+
+int em_start(int argc, char *argv[], RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    RLOGD("em_start called");
+    int i = 0;
+    em_arry_t *em_test = &em;
+    em_arry_t *em_sub = NULL;
+    RLOGD("Welcome to EM %s",em_test->name);
+    char output[2048] = {0};
+    int len = 0;
+
+    if(argc < 2){
+        for(i = 0; i < em_test->subcnt; i++){
+            sprintf(output+len,"%d:%s\n",i+1,em_test->subarray[i].name);
+            len = strlen(output);
+        }
+        RLOGD("%s",output);
+        android::emResultNotify(output);
+        return 0;
+    }
+    int itemlevel = 0;
+    int select_argvi[32] = {0};
+    int current_argvi = -1;
+    for(itemlevel = 1; itemlevel < argc; itemlevel++){
+        select_argvi[itemlevel-1] = atoi(argv[itemlevel]) - 1;
+        current_argvi = select_argvi[itemlevel-1];
+        if (em_test->subcnt < current_argvi + 1) {
+            sprintf(output, "the select index %d is out of bounds, please reselect.\nfail\n",current_argvi + 1);
+            android::emResultNotify(output);
+            return -1;
+        }
+        if(em_test->subarray[current_argvi].subarray == NULL){
+            for(i = 0 ; i < (argc - itemlevel - 1); i++){
+                select_argvi[itemlevel + i] = atoi(argv[itemlevel+1+i]) - 1;
+            }
+            RLOGD("em_test->subarray[%d].name: %s",current_argvi, em_test->subarray[current_argvi].name);
+            if(strncmp(em_test->subarray[current_argvi].name,"set",3) == 0){
+                em_main(itemlevel,&select_argvi[0],(argc - itemlevel - 1),&argv[itemlevel+1]);
+            }
+            else{
+                RLOGD("item level %d",itemlevel);
+                em_main(itemlevel,&select_argvi[0],(argc - itemlevel - 1),NULL);
+            }
+            //android::emResultNotify("done\n");
+            break;
+        }else{
+            RLOGD("em_sub[%d].name: %s, itemlevel: %d, argc: %d ",current_argvi, (em_test->subarray[current_argvi].name), itemlevel, argc);
+            em_sub = &em_test->subarray[current_argvi];
+            if(itemlevel == (argc - 1)){
+                memset(output,0,2048);
+                len = 0;
+
+                for(i = 0; i < em_sub->subcnt; i++){
+                    //RLOGD("%d:%s",i+1,em_sub->subarray[i].name);
+                    sprintf(output+len,"%d:%s\n",i+1,em_sub->subarray[i].name);
+                    len = strlen(output);
+                }
+                RLOGD("%s",output);
+                android::emResultNotify(output);
+            }
+            em_test = em_sub;
+        }
+    }
+    return 0;
+}
+
+extern void ARspRequestWithArg(int request, const char* arg, RIL_SOCKET_ID soc_id);
+
+void emSendATCommand(const char *cmd, int soc_id)
+{
+    ARspRequestWithArg(RIL_REQUEST_OEM_HOOK_RAW, cmd, (RIL_SOCKET_ID)soc_id);
+}
+
+void emEnableRadio(bool isEnable, int soc_id) {
+    //check main phone
+    ARspRequestWithArg(RIL_REQUEST_RADIO_POWER, (isEnable ? "1" : "0"), (RIL_SOCKET_ID)soc_id);
+}
+
+std::vector<std::string> getCdmaCmdArr(std::vector<std::string> cmdArray) {
+#ifndef MD_93_SUPPORT
+    return cmdArray;
+#else
+    std::vector<std::string> cmdArrayNew(2);
+    cmdArrayNew[0] = cmdArray[0];
+    cmdArrayNew[1] = cmdArray[1];
+    return cmdArrayNew;
+#endif /*MD_93_SUPPORT*/
+}
+
+int emResultNotifyWithDone(std::string str) {
+    std::string tmp = str + std::string("\ndone\n");
+    android::emResultNotify(tmp.c_str());
+    return 0;
+}
+
+int emResultNotifyEx(std::string str) {
+    std::string tmp = str + std::string("\n");
+    android::emResultNotify(tmp.c_str());
+    return 0;
+}
+
+int em_result_only_msg(std::string str) {
+    std::string tmp = str + std::string("\nonly_em_message\n");
+    android::emResultNotify(tmp.c_str());
+    return 0;
+}
+
+int em_result_notify_fail(std::string str) {
+    std::string tmp = "fail, " + str;
+    emResultNotifyWithDone(tmp);
+    return 0;
+}
+
+int em_result_notify_ok(std::string str) {
+    std::string tmp = "OK, " + str;
+    emResultNotifyWithDone(tmp);
+    return 0;
+}
+
+int em_result_notify_error(std::string str) {
+    std::string tmp = "error, " + str;
+    emResultNotifyWithDone(tmp);
+    return 0;
+}
+#endif
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em.h
new file mode 100644
index 0000000..44e3e13
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em.h
@@ -0,0 +1,149 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#ifndef __RIL_EM_API__
+#define __RIL_EM_API__
+
+#include  <vendor-ril/telephony/ril.h>
+#include <string>
+#include <vector>
+
+#include  "common.h"
+
+typedef struct em_arry_{
+    char *name;  /* main test name. */
+    int subcnt;
+    struct em_arry_ *subarray; 	  /* Function to call to do the job. */
+    int unsol;
+    int reply;
+} em_arry_t;
+extern em_arry_t lte_info[];
+extern em_arry_t ims_setting[];
+extern em_arry_t ims_common[];
+extern em_arry_t ims_call[] ;
+extern em_arry_t ims_registration[];
+extern em_arry_t ims[];
+extern em_arry_t gprs[];
+extern em_arry_t networkselection[];
+extern em_arry_t modem_cta[];
+extern em_arry_t modem_fta[];
+extern em_arry_t modem_C2K_Test_MODEM[];
+extern em_arry_t modemtest[];
+extern em_arry_t hspa[];
+extern em_arry_t cfu[];
+extern em_arry_t bandmode[];
+extern em_arry_t networkinfo[];
+extern em_arry_t antenna_4Gmode[];
+extern em_arry_t antenna_3Gmode[];
+extern em_arry_t antennatest[];
+extern em_arry_t time_reg[];
+extern em_arry_t c2k_modem_setting[];
+extern em_arry_t set_get[];
+extern em_arry_t rfdesense_gsm_band[];
+extern em_arry_t rfdesense_gsm_pattern[];
+extern em_arry_t rfdesense_gsm_sub[];
+extern em_arry_t rfdesense_gsm[];
+extern em_arry_t rfdesense_tdscdma_band[];
+extern em_arry_t rfdesense_tdscdma_sub[];
+extern em_arry_t rfdesense_tdscdma[];
+extern em_arry_t rfdesense_wcdma_band[];
+extern em_arry_t rfdesense_wcdma_sub[];
+extern em_arry_t rfdesense_wcdma[];
+extern em_arry_t rfdesense_lte_mode[];
+extern em_arry_t rfdesense_fdd_band[] ;
+extern em_arry_t rfdesense_lte_bandwidth[];
+extern em_arry_t  rfdesense_lte_mcs[];
+extern em_arry_t rfdesense_fdd_sub[];
+extern em_arry_t rfdesense_lte_fdd[];
+extern em_arry_t rfdesense_tdd_band[];
+extern em_arry_t rfdesense_tdd_config[];
+extern em_arry_t rfdesense_tdd_special[];
+extern em_arry_t rfdesense_tdd_sub[];
+extern em_arry_t rfdesense_lte_tdd[];
+extern em_arry_t rfdesense_cdma_band[];
+extern em_arry_t rfdesense_cdma_modulation[];
+extern em_arry_t rfdesense_cdma_sub[];
+extern em_arry_t rfdesense_cdma[];
+extern em_arry_t sub_tx_test[];
+extern em_arry_t desense_test[];
+extern em_arry_t emmain[];
+
+#define RET_STRING_IMS_SUCCESS "IMS test success\ndone\n"
+#define RET_STRING_IMS_FAIL "IMS test fail\ndone\n"
+#define RET_STRING_GPRS_SUCCESS "GPRS test success\ndone\n"
+#define RET_STRING_GPRS_FAIL "GPRS test fail\ndone\n"
+#define RET_STRING_NWSELECTION_SUCCESS "Network Selection success\ndone\n"
+#define RET_STRING_NWSELECTION_FAIL "Network Selection fail\ndone\n"
+#define RET_STRING_MODEMTEST_SUCCESS "Modem test success\ndone\n"
+#define RET_STRING_MODEMTEST_FAIL "Modem test fail\ndone\n"
+#define RET_STRING_HSPA_SUCCESS "HSPA test success\ndone\n"
+#define RET_STRING_HSPA_FAIL "HSPA test fail\ndone\n"
+#define RET_STRING_LTE_SUCCESS "LTE success\ndone\n"
+#define RET_STRING_LTE_FAIL "LTE fail\ndone\n"
+#define RET_STRING_CFU_SUCCESS "CFU success\ndone\n"
+#define RET_STRING_CFU_FAIL "CFU fail\ndone\n"
+#define RET_STRING_BANDMODE_SUCCESS "Bandmode success\ndone\n"
+#define RET_STRING_BANDMODE_FAIL "Bandmode fail\ndone\n"
+#define RET_STRING_NWINFO_SUCCESS "NetworkInfo success\ndone\n"
+#define RET_STRING_NWINFO_FAIL "NetworkInfo fail\ndone\n"
+#define RET_STRING_ANTENNATEST_SUCCESS "Antenna test success\ndone\n"
+#define RET_STRING_ANTENNATEST_FAIL "Antenna test fail\ndone\n"
+#define RET_STRING_C2K_MODEM_SETTING_SUCCESS "c2k modem setting success\ndone\n";
+#define RET_STRING_C2K_MODEM_SETTING_FAIL "c2k modem setting fail\ndone\n";
+
+int emImsStart(int argc, int *item,char *value);
+int emGprsStart(int argc, int *item,char *value);
+int emNetworkSelectionStart(int argc,int selectpos);
+int emModemtestStart(int argc, int multicnt,int *item);
+int emHspaStart(int argc, int *item);
+int lte_em_start(int argc, int multicnt,int *item);
+int em_el1_start(int argc, int multicnt,int *item);
+int emCfuStart(int argc, int *item);
+int emBandmodeStart(int len,int *item,int multilen,char *value[]);
+int emNwInfoStart(int argc, int multicnt,int *item);
+int emAntennaTestStart(int argc, int *item,char *value);
+int emC2kModemSettingStart(int argc, int multicnt,int *item);
+int emRfDesenseStart(int len,int *item,int multilen,char *value[]);
+
+std::vector<std::string> getCdmaCmdArr(std::vector<std::string> cmdArray);
+int em_result_notify_fail(std::string str);
+int em_result_notify_ok(std::string str);
+int em_result_notify_error(std::string str);
+int emResultNotifyWithDone(std::string str);
+int emResultNotifyEx(std::string str);
+int em_result_only_msg(std::string str);
+void emSendATCommand(const char *cmd, int soc_id);
+void emEnableRadio(bool isEnable, int soc_id);
+int em_start(int argc, char *argv[], RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+#endif
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_EL1.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_EL1.cpp
new file mode 100644
index 0000000..73e8a1a
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_EL1.cpp
@@ -0,0 +1,198 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include <vendor-ril/telephony/ril.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <cutils/jstring.h>
+#include <log/log.h>
+#include <unistd.h>
+#include <math.h>
+#include "em/em_el1_public_struct.h"
+#include  "common.h"
+#include "em/em.h"
+#include "Radio_capability_switch_util.h"
+
+#if EM_MODE_SUPPORT
+
+#undef LOG_TAG
+#define LOG_TAG "EM_EL1"
+
+static int mItemCount = 0;
+static int mFlag = 0;// at cmd flag
+static int mCurrentFlag = 0; // at cmd handle flag
+
+static const int MSG_NW_INFO = 1;
+static const int MSG_NW_INFO_OPEN = 4;
+static const int MSG_NW_INFO_CLOSE = 5;
+
+static void sendATCommand(const char *cmd,int msg)
+{
+    mCurrentFlag = msg;
+    emSendATCommand(cmd, get_default_sim_all_except_data());
+    return ;
+}
+
+static char hex2char(unsigned int hex) {
+    if (hex >= '0' && hex <= '9') {
+        return hex - '0';
+    }
+    if (hex >= 'A' && hex <= 'F') {
+        return 0xA + hex - 'A';
+    }
+    if (hex >= 'a' && hex <= 'f') {
+        return 0xA + hex - 'a';
+    }
+    return 0;
+}
+
+static void hex2char(char *input, int input_len, char *buf, int buf_size) {
+    RLOGD("hex2char, input_len: %d, buf_size: %d", input_len, buf_size);
+    memset(buf, 0, buf_size);
+    //respose data lack of 8 byte, corresponding to header
+    //ref_count(1)+lp_reserved(1)+ msg_len(2) + em_info(4)
+    if (input_len < (buf_size-8) * 2) { // should not happen
+        buf_size = input_len / 2;
+    }
+    for (int i = 0; i < buf_size; i++) {
+        buf[i+8] = (hex2char(input[i * 2]) << 4) + hex2char(input[i * 2 + 1]);
+    }
+
+}
+
+static void el1_at_cmd_handle(char*response, int responselen) {
+    switch (mCurrentFlag) {
+        case MSG_NW_INFO:
+            if ((responselen > 0) && (response != NULL)) {
+                RLOGD("el1_at_cmd_handle response %s\n",response);
+                //mFlag = FLAG_OFFSET_BIT;
+            }
+            else {
+                RLOGD("send fail ");
+            }
+            break;
+        case MSG_NW_INFO_OPEN:
+        case MSG_NW_INFO_CLOSE:
+            break;
+        default:
+            break;
+    }
+}
+
+static void el1_parse(char *output,char * input){
+    em_el1_status_ind_struct buf;
+    hex2char(input, strlen(input), (char *)&buf, sizeof(em_el1_status_ind_struct));
+    snprintf(output, 8192,
+            "[Cell Info]\n"
+            "  band: %u,%u,%u,%u\n"
+            "  DL_BW: %u,%u,%u,%u\n"
+            "  UL_BW: %u,%u,%u,%u\n"
+            "  TM: %u,%u,%u,%u\n"
+            "  PCI: %d,%d,%d,%d\n"
+            "  EARFCN: %u,%u,%u,%u\n"
+            "[DL]\n"
+            "  dl_rssi: (%d,%d),(%d,%d),(%d,%d),(%d,%d)\n"
+            "  dl_rsrp: (%d,%d),(%d,%d),(%d,%d),(%d,%d)\n"
+            "  dl_rsrq: (%d,%d),(%d,%d),(%d,%d),(%d,%d)\n"
+            "  dl_sinr: (%d,%d),(%d,%d),(%d,%d),(%d,%d)\n"
+            "  rsrp: %d,%d,%d,%d\n"
+            "  rsrq: %d,%d,%d,%d\n"
+            "  sinr: %d,%d,%d,%d\n"
+            "  rsSNR: %d,%d,%d,%d\n"
+            "  tm: %d,%d,%d,%d\n"
+            "  rsrp_l1_rxpath_sum_dBm: %d,%d,%d,%d\n"
+            "  rsrq_l1_rxpath_sum_dB: %d,%d,%d,%d\n"
+            "  snr_l1_rxpath_sum_dB: %d,%d,%d,%d\n",
+        buf.cell_info[0].band, buf.cell_info[1].band,buf.cell_info[2].band,buf.cell_info[3].band,
+        buf.cell_info[0].dl_bw, buf.cell_info[1].dl_bw,buf.cell_info[2].dl_bw,buf.cell_info[3].dl_bw,
+        buf.cell_info[0].ul_bw, buf.cell_info[1].ul_bw,buf.cell_info[2].ul_bw,buf.cell_info[3].ul_bw,
+        buf.cell_info[0].tm, buf.cell_info[1].tm,buf.cell_info[2].tm,buf.cell_info[3].tm,
+        buf.cell_info[0].pci, buf.cell_info[1].pci,buf.cell_info[2].pci,buf.cell_info[3].pci,
+        buf.cell_info[0].earfcn, buf.cell_info[1].earfcn,buf.cell_info[2].earfcn,buf.cell_info[3].earfcn,
+        buf.dl_info[0].dl_rssi[0],buf.dl_info[0].dl_rssi[1],buf.dl_info[1].dl_rssi[0],buf.dl_info[1].dl_rssi[1],
+        buf.dl_info[2].dl_rssi[0],buf.dl_info[2].dl_rssi[1],buf.dl_info[3].dl_rssi[0],buf.dl_info[3].dl_rssi[1],
+        buf.dl_info[0].dl_rsrp[0],buf.dl_info[0].dl_rsrp[1],buf.dl_info[1].dl_rsrp[0],buf.dl_info[1].dl_rsrp[1],
+        buf.dl_info[2].dl_rsrp[0],buf.dl_info[2].dl_rsrp[1],buf.dl_info[3].dl_rsrp[0],buf.dl_info[3].dl_rsrp[1],
+        buf.dl_info[0].dl_rsrq[0],buf.dl_info[0].dl_rsrq[1],buf.dl_info[1].dl_rsrq[0],buf.dl_info[1].dl_rsrq[1],
+        buf.dl_info[2].dl_rsrq[0],buf.dl_info[2].dl_rsrq[1],buf.dl_info[3].dl_rsrq[0],buf.dl_info[3].dl_rsrq[1],
+        buf.dl_info[0].dl_sinr[0],buf.dl_info[0].dl_sinr[1],buf.dl_info[1].dl_sinr[0],buf.dl_info[1].dl_sinr[1],
+        buf.dl_info[2].dl_sinr[0],buf.dl_info[2].dl_sinr[1],buf.dl_info[3].dl_sinr[0],buf.dl_info[3].dl_sinr[1],
+        buf.dl_info[0].rsrp, buf.dl_info[1].rsrp, buf.dl_info[2].rsrp, buf.dl_info[3].rsrp,
+        buf.dl_info[0].rsrq, buf.dl_info[1].rsrq, buf.dl_info[2].rsrq, buf.dl_info[3].rsrq,
+        buf.dl_info[0].sinr, buf.dl_info[1].sinr, buf.dl_info[2].sinr, buf.dl_info[3].sinr,
+        buf.dl_info[0].rsSNR, buf.dl_info[1].rsSNR, buf.dl_info[2].rsSNR, buf.dl_info[3].rsSNR,
+        buf.dl_info[0].tm, buf.dl_info[1].tm, buf.dl_info[2].tm, buf.dl_info[3].tm,
+        buf.dl_info[0].rsrp_l1_rxpath_sum_dBm, buf.dl_info[1].rsrp_l1_rxpath_sum_dBm, buf.dl_info[2].rsrp_l1_rxpath_sum_dBm, buf.dl_info[3].rsrp_l1_rxpath_sum_dBm,
+        buf.dl_info[0].rsrq_l1_rxpath_sum_dB, buf.dl_info[1].rsrq_l1_rxpath_sum_dB, buf.dl_info[2].rsrq_l1_rxpath_sum_dB, buf.dl_info[3].rsrq_l1_rxpath_sum_dB,
+        buf.dl_info[0].snr_l1_rxpath_sum_dB, buf.dl_info[1].snr_l1_rxpath_sum_dB, buf.dl_info[2].snr_l1_rxpath_sum_dB, buf.dl_info[3].snr_l1_rxpath_sum_dB
+        );
+}
+
+static void  el1_urc_handle(int type, char *data){
+    RLOGD("el1_urc_handle type %d data %s\n",type,data);
+    if(type == EM_EL1_INFO) {
+        char outbuf[8192] = {0};
+        el1_parse(outbuf,data);
+        android::emResultNotify(outbuf);
+        android::emResultNotify(RET_STRING_LTE_SUCCESS);
+        android::unregisterNetwork();
+        char atcommand[32] = {0};
+        sprintf(atcommand,"AT+EINFO=%d,%d,1",mFlag,EM_EL1_INFO);
+        sendATCommand(atcommand, MSG_NW_INFO_CLOSE);
+    }
+}
+
+int em_el1_start(int argc, int multicnt,int *item)
+{
+    RLOGD("em_el1_start called");
+    if(argc < 1)
+    {
+        RLOGD("em_el1_start: please select page to show info");
+        android::emResultNotify(RET_STRING_LTE_FAIL);
+        return -1;
+    }
+    mItemCount = multicnt + 1;
+    RLOGD("mItemCount: %d, item[%d]: %d", mItemCount, multicnt, item[multicnt]);
+    android::registerForNetworkInfo(el1_urc_handle);
+    android::registerForATcmdResponse(el1_at_cmd_handle);
+    //sendATCommand("AT+EINFO?",MSG_NW_INFO);
+    mFlag = 8;
+    char atcommand[32] = {0};
+    sprintf(atcommand,"AT+EINFO=%d,%d,0",mFlag,EM_EL1_INFO);
+    sendATCommand(atcommand, MSG_NW_INFO_OPEN);
+    return (0);
+}
+#endif
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_antennatest.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_antennatest.cpp
new file mode 100644
index 0000000..87c8380
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_antennatest.cpp
@@ -0,0 +1,355 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include <vendor-ril/telephony/ril.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <cutils/jstring.h>
+#include <log/log.h>
+#include <unistd.h>
+#include <math.h>
+#include <vector>
+#include <string>
+#include <stdexcept>
+#include  "common.h"
+#include "em/em.h"
+#include "ModemCategory.h"
+#include "Radio_capability_switch_util.h"
+#include "../util/utils.h"
+
+#if EM_MODE_SUPPORT
+
+#undef LOG_TAG
+#define LOG_TAG "EM_ANTENNA"
+
+static const int MSG_QUERY_ANTENNA_MODE = 1;
+static const int MSG_SET_ANTENNA_MODE = 2;
+static const int MSG_QUERY_ANTENNA_MODE_C2K = 4;
+static const int MSG_QUERY_ANTENNA_EGMC_4G = 5;
+static const int MSG_SET_ANTENNA_EGMC_4G = 6;
+static const int MSG_INIT_ANTENNA_EGMC_4G = 7;
+static const int MODE_INDEX_BASE_3G = 10;
+static const int MODE_EPCM_VALID = 0xFF;
+static const int CELL_2RX_LENGTH = 2;
+static const int CELL_4RX_LENGTH = 4;
+
+int mCurrentEmantennaFlag = 0;
+bool fgAntennaRead = true;
+static int fgget = -1;
+static int fgset = -1;
+int mAntennaMode = 0;
+char antennaretstring[128] = {0};
+
+static const std::vector<std::string> antenna_modes_4g {
+    "RX1&RX2",
+    "RX1",
+    "RX2"
+};
+
+static const std::vector<std::string> antenna_modes_3g {
+    "Please select a mode:",
+    "RX1",
+    "RX2",
+    "RX1&RX2",
+    "Resume default setting"
+};
+
+static const std::vector<std::string> antenna_modes_c2k_mode {
+    "Resume default setting",
+    "RX1",
+    "RX2",
+    "RX1&RX2"
+};
+
+static void  sendATCommand(const char *cmd,int msg)
+{
+    mCurrentEmantennaFlag = msg;
+    emSendATCommand(cmd, Radio_capability_switch_util::get_main_capability_phone_id());
+    return ;
+}
+static void queryCurrentMode() {
+    char cmd_str[32] = {0};
+    sprintf(cmd_str,"%s","AT+ERXPATH?");
+    sendATCommand(cmd_str, MSG_QUERY_ANTENNA_MODE);
+}
+
+void queryCurrentCdmaMode() {
+    if (utils::is93Modem()) {
+        sendATCommand("AT+ERXTESTMODE?", MSG_QUERY_ANTENNA_MODE_C2K);
+    } else {
+        android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
+        RLOGD("don't support");
+    }
+}
+
+static void setMode(int mode) {
+    char cmd_str[32] = {0};
+    sprintf(cmd_str,"%s%d","AT+ERXPATH=",mode);
+    sendATCommand(cmd_str, MSG_SET_ANTENNA_MODE);
+}
+
+static void setCdmaMode(int mode) {
+    std::string str("AT+ERXTESTMODE=");
+    str.append(std::to_string(mode));
+    if (utils::is93Modem()) {
+        sendATCommand(str.c_str(), MSG_SET_ANTENNA_MODE);
+    } else {
+        android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
+        RLOGD("don't support");
+    }
+}
+
+static void parseCurrentMode(char* data) {
+    RLOGD("parseCurrentMode(%d):%s",fgget, data);
+    std::vector<std::string> out;
+    utils::tokenize(string(data), "\n", out);
+    std::string str;
+    str.clear();
+    if(fgget == 0 || fgget == 1) {
+        for(auto i: out) {
+            if(i.find("+ERXPATH:") != std::string::npos) {
+                try {
+                    int mode = std::stoi(i.substr(std::string("+ERXPATH:").size()));
+                    if (mode < 0 || (mode >= antenna_modes_4g.size()
+                            && mode >= MODE_INDEX_BASE_3G + mode >= antenna_modes_4g.size()
+                            &&  mode != MODE_EPCM_VALID)) {
+                        android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
+                        RLOGD("Modem returned invalid mode(%d): %s",mode, data);
+                        return ;
+                    } else {
+                        if (mode == MODE_EPCM_VALID) {
+                            android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
+                        } else if (mode >= MODE_INDEX_BASE_3G) {
+                            if(ModemCategory::getModemType() != ModemCategory::MODEM_TD) {
+                                int pos = mode - MODE_INDEX_BASE_3G + 1;
+                                RLOGD("parseCurrent3GMode is: %d", pos);
+                                str.append("3G:");
+                                str.append(antenna_modes_3g[pos]);
+                                str.append(" ");
+                            }
+                        } else {
+                            if (ModemCategory::isLteSupport()) {
+                                RLOGD("parseCurrentLteMode is: %d", mode);
+                                str.append("4G:");
+                                str.append(antenna_modes_4g[mode]);
+                                str.append(" ");
+                            }
+                        }
+                    }
+                    str.append("\ndone\n");
+                } catch (const out_of_range &e) {
+                    android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
+                    RLOGD("out of range: %s", e.what());
+                    return;
+                } catch (const invalid_argument &e) {
+                    android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
+                    RLOGD("invalid argument: %s", e.what());
+                    return;
+                }
+            }
+        }
+        android::emResultNotify(str.c_str());
+    } else if (fgget == 2) {
+        for(auto i: out) {
+            if(i.find("+ERXTESTMODE:") != std::string::npos) {
+                try {
+                    int mode = std::stoi(i.substr(std::string("+ERXTESTMODE:").size()));
+                    if (mode < 0 || mode >= antenna_modes_c2k_mode.size()) {
+                        android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
+                        RLOGD("Modem returned invalid mode(%d): %s",mode, data);
+                        return;
+                    } else {
+                        RLOGD("parseCurrentC2KMode is: %d", mode);
+                        str.append("CDMA:");
+                        str.append(antenna_modes_c2k_mode[mode]);
+                        str.append(" ");
+                    }
+                    str.append("\ndone\n");
+                } catch (const out_of_range &e) {
+                    android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
+                    RLOGD("out of range: %s", e.what());
+                    return;
+                } catch (const invalid_argument &e) {
+                    android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
+                    RLOGD("invalid argument: %s", e.what());
+                    return;
+                }
+            }
+        }
+        android::emResultNotify(str.c_str());
+    } else {
+        RLOGE("error choose!!!");
+        android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
+    }
+    return;
+}
+
+
+static void emAntennaAtCmdHandle(char*response, int responselen) {
+    switch (mCurrentEmantennaFlag) {
+    case MSG_QUERY_ANTENNA_MODE:
+    case MSG_QUERY_ANTENNA_MODE_C2K:
+        //parse antenna mode.
+        if ((responselen > 0) && (response != NULL)) {
+            RLOGD("Get mode %s", response);
+            parseCurrentMode(response);
+        } else {
+            RLOGD("Query antenna mode failed.");
+            sprintf(antennaretstring, "%s%s", ("Query antenna mode failed."),
+            RET_STRING_ANTENNATEST_FAIL);
+            android::emResultNotify(antennaretstring);
+        }
+        android::unregisterNetwork();
+        break;
+    case MSG_SET_ANTENNA_MODE:
+        memset(antennaretstring, 0, sizeof(antennaretstring));
+        if ((responselen > 0) && (response != NULL)) {
+            RLOGD("Set successful.");
+            sprintf(antennaretstring, "%s\n%s", ("Set successful."),
+                    RET_STRING_ANTENNATEST_SUCCESS);
+        } else {
+            RLOGD("Set failed.");
+            sprintf(antennaretstring, "%s\n%s", ("Set failed."),
+                    RET_STRING_ANTENNATEST_FAIL);
+        }
+        android::unregisterNetwork();
+        android::emResultNotify(antennaretstring);
+        break;
+    default:
+        RLOGD("error(%d)", mCurrentEmantennaFlag);
+        break;
+    }
+}
+
+
+//create thread to send command
+static void * emAntennaTestThread(void* arg)
+{
+    if(fgAntennaRead){
+        if(fgget == 0) { //4G
+            if (ModemCategory::isLteSupport()) {
+                queryCurrentMode();
+            } else {
+                android::emResultNotify("Antenna test don't support for 4G \ndone\n");
+            }
+        } else if (fgget == 1){ //3G
+            if (ModemCategory::getModemType() == ModemCategory::MODEM_TD) {
+                android::emResultNotify("Antenna test don't support for 3G \ndone\n");
+            } else {
+                queryCurrentMode();
+            }
+        } else if (fgget == 2) { //C2K
+            if(ModemCategory::isCdma()) {
+                queryCurrentCdmaMode();
+            } else {
+                android::emResultNotify("Antenna test don't support for C2K \ndone\n");
+            }
+        } else {
+            android::emResultNotify("Antenna test index error \ndone\n");
+        }
+
+    }else{
+        if(fgset == 0) { //4G
+            if (ModemCategory::isLteSupport()) {
+                setMode(mAntennaMode);
+            } else {
+                android::emResultNotify("Antenna test don't support for 4G \ndone\n");
+            }
+        } else if (fgset == 1){ //3G
+            if (ModemCategory::getModemType() == ModemCategory::MODEM_TD) {
+                android::emResultNotify("Antenna test don't support for 3G \ndone\n");
+            } else {
+                setMode(mAntennaMode);
+            }
+        } else if (fgset == 2) { //C2K
+            if(ModemCategory::isCdma()) {
+                setCdmaMode(mAntennaMode);
+            } else {
+                android::emResultNotify("Antenna test don't support for C2K \ndone\n");
+            }
+        } else {
+            android::emResultNotify("Antenna test index error \ndone\n");
+        }
+    }
+    pthread_exit(0);
+}
+
+int emAntennaTestStart(int argc, int *item,char *value)
+{
+    RLOGD("emAntennaTestStart called");
+    if(argc < 2){
+        RLOGD("please select AntennaTest get or set :");
+        return -1;
+    }
+    mCurrentEmantennaFlag = 0;
+    int classid = item[0];
+    int operatorid = item[1];
+    if((item[0] != 0 ) && (item[0] != 1) && (item[0] != 2)){ // 0 4G 1 3G
+        RLOGD("emAntennaTestStart: invalid parameter %d, operatorid: %d",item[0], operatorid);
+        android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
+        return -1;
+    }
+    switch(operatorid){
+        case 0://get
+        {
+            fgAntennaRead = true;
+            fgget = classid;
+            break;
+        }
+        case 1://set
+        {
+            printf("argc: %d, fgset: %d\n", argc, classid);
+            printf("itme[2]: %d\n", item[2]);
+            fgset = classid;
+            if(classid == 0){ // 4G
+               mAntennaMode = item[2];
+            } else if(classid == 1) { //3G
+                mAntennaMode = item[2]+ MODE_INDEX_BASE_3G;
+            } else if (classid == 2) { //C2K
+                mAntennaMode = item[2];
+            } else { // other
+                RLOGW("error classid");
+                android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
+            }
+            fgAntennaRead = false;
+            break;
+        }
+    }
+    android::registerForATcmdResponse(emAntennaAtCmdHandle);
+    pthread_t emantenna_thread;
+    pthread_create(&emantenna_thread,NULL, emAntennaTestThread, NULL);
+    return (0);
+}
+#endif
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_bandmode.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_bandmode.cpp
new file mode 100644
index 0000000..8b33c18
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_bandmode.cpp
@@ -0,0 +1,833 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include <pthread.h>
+#include <vendor-ril/telephony/ril.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <cutils/jstring.h>
+#include <log/log.h>
+#include <unistd.h>
+#include <math.h>
+#include <string>
+#include <vector>
+#include <stdint.h>
+#include "ModemCategory.h"
+#include  "common.h"
+#include "em/em.h"
+#include "Radio_capability_switch_util.h"
+#include "../util/utils.h"
+#include "MtkRadioAccessFamily.h"
+
+#if EM_MODE_SUPPORT
+
+#undef LOG_TAG
+#define LOG_TAG "EM_BANDMODE"
+
+static const int WCDMA = 1;
+static const int TDSCDMA = 2;
+
+static const int INDEX_GSM_BAND = 0;
+static const int INDEX_UMTS_BAND = 1;
+static const int INDEX_LTE_FDD_BAND = 2;
+static const int INDEX_LTE_TDD_BAND = 3;
+static const int INDEX_LTE_BAND_96 = 4;
+static const int INDEX_LTE_BAND_128 = 5;
+static const int INDEX_LTE_BAND_160 = 6;
+static const int INDEX_LTE_BAND_192 = 7;
+static const int INDEX_LTE_BAND_224 = 8;
+static const int INDEX_LTE_BAND_256 = 9;
+static const int INDEX_CDMA_BAND = 10;
+static const int INDEX_BAND_MAX = 11;
+static const int BAND_SET_INVALID = 1000;
+static int mSimType = -1;
+
+/** GSM mode bit. */
+static const int GSM_EGSM900_BIT = 1;
+static const int GSM_DCS1800_BIT = 3;
+static const int GSM_PCS1900_BIT = 4;
+static const int GSM_GSM850_BIT = 7;
+static const std::vector<int> GSM_BAND_BIT{GSM_EGSM900_BIT,GSM_DCS1800_BIT,GSM_PCS1900_BIT,GSM_GSM850_BIT};
+
+/** Event or message id. */
+static const int EVENT_QUERY_SUPPORTED = 100;
+static const int EVENT_QUERY_CURRENT = 101;
+static const int EVENT_SET_GSM = 110;
+
+static const int EVENT_SET_FAIL = 1;
+static const int EVENT_RESET = 2;
+
+static const std::uint32_t GSM_MAX_VALUE = UINT8_MAX; //255
+static const std::uint32_t UMTS_MAX_VALUE = UINT16_MAX; //65535;
+static const std::uint32_t LTE_MAX_VALUE = UINT32_MAX;//4294967295
+
+/** AT Command. */
+static const std::string QUERY_SUPPORT_COMMAND = "AT+EPBSE=?";
+static const std::string QUERY_CURRENT_COMMAND = "AT+EPBSE?";
+static const std::string SET_COMMAND = "AT+EPBSE=";
+static const std::string SAME_COMMAND = "+EPBSE:";
+
+
+static const int EVENT_QUERY_CURRENT_CDMA = 103;
+static const int EVENT_SET_CDMA = 111;
+
+static const std::string QUERY_CURRENT_COMMAND_CDMA = "AT+ECBANDCFG?";
+static const std::string SET_COMMAND_CDMA = "AT+ECBANDCFG=";
+static const std::string SAME_COMMAND_CDMA = "+ECBANDCFG:";
+
+static pthread_mutex_t s_band_Mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t s_band_Cond = PTHREAD_COND_INITIALIZER;
+#define BLOCK_LOCK() pthread_mutex_lock(&s_band_Mutex)
+#define BLOCK_UNLOCK() pthread_mutex_unlock(&s_band_Mutex)
+#define BLOCK_WAIT() pthread_cond_wait(&s_band_Cond, &s_band_Mutex)
+#define BLOCK_WAKEUP() pthread_cond_broadcast(&s_band_Cond)
+
+bool mIsLteExtend = false;
+int mCurrentEmbandmodeFlag = 0;
+std::vector<long> gsmValues(INDEX_BAND_MAX);
+long cdmaValues = 0;
+
+struct BandModeMap{
+    std::string mName;
+    int mIndex;
+    int mBit;
+    bool mEnable;
+    bool mCheck;
+    BandModeMap(std::string name, int index, int bit ,bool enable, bool check)
+    : mName(name), mIndex(index), mBit(bit), mEnable(enable), mCheck(check) {
+
+    }
+    BandModeMap(BandModeMap&& other): mName(std::move(other.mName)),
+            mIndex(std::move(other.mIndex)),
+            mBit(std::move(other.mBit)),
+            mEnable(std::move(other.mEnable)),
+            mCheck(std::move(other.mCheck)) {
+
+    }
+    BandModeMap& operator=(const BandModeMap& other) = default;
+};
+
+static std::vector<BandModeMap> mModeArray;
+static std::vector<BandModeMap> mCdmaModeArray;
+static const std::vector<std::string> band_mode_gsm { "EGSM900", "DCS1800",
+        "PCS1900", "GSM850" };
+
+static const std::vector<std::string> band_mode_wcdma { "WCDMA-IMT-2000",
+        "WCDMA-PCS-1900", "WCDMA-DCS-1800", "WCDMA-AWS-1700", "WCDMA-CLR-850",
+        "WCDMA-800", "WCDMA-IMT-E-2600", "WCDMA-GSM-900", "WCDMA-1800",
+        "WCDMA-1700" };
+
+static const std::vector<std::string> band_mode_tdscdma { "TD_SCDMA Band A",
+        "TD_SCDMA Band B", "TD_SCDMA Band C", "TD_SCDMA Band D",
+        "TD_SCDMA Band E", "TD_SCDMA Band F" };
+
+static const std::vector<std::string> band_mode_lte_fdd { "Band 1", "Band 2",
+        "Band 3", "Band 4", "Band 5", "Band 6", "Band 7", "Band 8", "Band 9",
+        "Band 10", "Band 11", "Band 12", "Band 13", "Band 14", "Band 15",
+        "Band 16", "Band 17", "Band 18", "Band 19", "Band 20", "Band 21",
+        "Band 22", "Band 23", "Band 24", "Band 25", "Band 26", "Band 27",
+        "Band 28", "Band 29", "Band 30", "Band 31", "Band 32" };
+
+static const std::vector<std::string> band_mode_lte_tdd { "Band 33", "Band 34",
+        "Band 35", "Band 36", "Band 37", "Band 38", "Band 39", "Band 40",
+        "Band 41", "Band 42", "Band 43", "Band 44" };
+
+static const std::vector<std::string> band_mode_lte_96 { "Band 65", "Band 66",
+        "Band 67", "Band 68", "Band 69", "Band 70", "Band 71", "Band 72",
+        "Band 73", "Band 74", "Band 75", "Band 76", "Band 77", "Band 78",
+        "Band 79", "Band 80", "Band 81", "Band 82", "Band 83", "Band 84",
+        "Band 85", "Band 86", "Band 87", "Band 88", "Band 89", "Band 90",
+        "Band 91", "Band 92", "Band 93", "Band 94", "Band 95", "Band 96" };
+
+static const std::vector<std::string> band_mode_lte_128 { "Band 97", "Band 98",
+        "Band 99", "Band 100", "Band 101", "Band 102", "Band 103", "Band 104",
+        "Band 105", "Band 106", "Band 107", "Band 108", "Band 109", "Band 110",
+        "Band 111", "Band 112", "Band 113", "Band 114", "Band 115", "Band 116",
+        "Band 117", "Band 118", "Band 119", "Band 120", "Band 121", "Band 122",
+        "Band 123", "Band 124", "Band 125", "Band 126", "Band 127", "Band 128" };
+
+static const std::vector<std::string> band_mode_lte_160 { "Band 129",
+        "Band 130", "Band 131", "Band 132", "Band 133", "Band 134", "Band 135",
+        "Band 136", "Band 137", "Band 138", "Band 139", "Band 140", "Band 141",
+        "Band 142", "Band 143", "Band 144", "Band 145", "Band 146", "Band 147",
+        "Band 148", "Band 149", "Band 150", "Band 151", "Band 152", "Band 153",
+        "Band 154", "Band 155", "Band 156", "Band 157", "Band 158", "Band 159",
+        "Band 160" };
+
+static const std::vector<std::string> band_mode_lte_192 { "Band 161",
+        "Band 162", "Band 163", "Band 164", "Band 165", "Band 166", "Band 167",
+        "Band 168", "Band 169", "Band 170", "Band 171", "Band 172", "Band 173",
+        "Band 174", "Band 175", "Band 176", "Band 177", "Band 178", "Band 179",
+        "Band 180", "Band 181", "Band 182", "Band 183", "Band 184", "Band 185",
+        "Band 186", "Band 187", "Band 188", "Band 189", "Band 190", "Band 191",
+        "Band 192" };
+
+static const std::vector<std::string> band_mode_lte_224 { "Band 193",
+        "Band 194", "Band 195", "Band 196", "Band 197", "Band 198", "Band 199",
+        "Band 200", "Band 201", "Band 202", "Band 203", "Band 204", "Band 205",
+        "Band 206", "Band 207", "Band 208", "Band 209", "Band 210", "Band 211",
+        "Band 212", "Band 213", "Band 214", "Band 215", "Band 216", "Band 217",
+        "Band 218", "Band 219", "Band 220", "Band 221", "Band 222", "Band 223",
+        "Band 224" };
+
+static const std::vector<std::string> band_mode_lte_256 { "Band 225",
+        "Band 226", "Band 227", "Band 228", "Band 229", "Band 230", "Band 231",
+        "Band 232", "Band 233", "Band 234", "Band 235", "Band 236", "Band 237",
+        "Band 238", "Band 239", "Band 240", "Band 241", "Band 242", "Band 243",
+        "Band 244", "Band 245", "Band 246", "Band 247", "Band 248", "Band 249",
+        "Band 250", "Band 251", "Band 252", "Band 253", "Band 254", "Band 255",
+        "Band 256" };
+
+static const std::vector<std::string> band_mode_cdma {
+        "Band 0(North American Celluar Band)",
+        "Band 1(North American PCS band)", "Band 2(TACS band)",
+        "Band 3(JTACS band)", "Band 4(Korean PCS band)", "Band 5(NMT-450 Band)",
+        "Band 6(IMT-2000 band)", "Band 7(North American 700Mhz Celluar Band)",
+        "Band 8(1800-MHz Band)", "Band 9(900-MHz Band)",
+        "Band 10(Secondary 800 MHz Band)", "Band 11(400 MHz European PAMR Band",
+        "Band 12(800 MHz PAMR Band)",
+        "Band 13(2.5 GHz IMT-2000 Extension Band)",
+        "Band 14(US PCS 1.9GHz Band)", "Band 15(AWS Band)" };
+
+int fgset = false;
+int count = -1;
+std::vector<std::string> choose_vals;
+
+static void sendATCommand(const char *cmd,int msg)
+{
+    BLOCK_LOCK();
+    mCurrentEmbandmodeFlag = msg;
+    emSendATCommand(cmd,mSimType);
+    RLOGD("sendATCommand: wait start");
+    BLOCK_WAIT();
+    RLOGD("sendATCommand: wait end");
+    BLOCK_UNLOCK();
+    return ;
+}
+
+static void setCurrentMode(std::vector<long> values) {
+    for (auto& m : mModeArray) {
+        if ((values[m.mIndex] & (1L << m.mBit)) == 0) {
+            m.mCheck = false;
+        } else {
+            if (m.mEnable) {
+                m.mCheck = true;
+            }
+        }
+        //RLOGD("setCurrentMode labels: %s, enable: %d, check: %d", m.mName.c_str(), m.mEnable, m.mCheck);
+    }
+}
+
+static void setSupportedMode(std::vector<long> values) {
+    for (auto& m : mModeArray) {
+        if ((values[m.mIndex] & (1L << m.mBit)) == 0) {
+            m.mEnable = false;
+        } else {
+            m.mEnable = true;
+        }
+        //RLOGD("setSupportedMode labels: %s, enable: %d", m.mName.c_str(), m.mEnable);
+    }
+}
+
+static void setCurrentModeCdma(const long value) {
+    RLOGD("setCurrentModeCdma: %ld", value);
+    for (auto& m : mCdmaModeArray) {
+        if ((value & (1L << m.mBit)) == 0) {
+            m.mCheck = false;
+        } else {
+            if (m.mEnable) {
+                m.mCheck = true;
+            }
+        }
+        RLOGD("setCurrentModeCdma labels: %s, enable: %d, check: %d", m.mName.c_str(), m.mEnable, m.mCheck);
+    }
+
+}
+
+static void setSupportedModeCdma(const long value) {
+    RLOGD("setSupportedModeCdma: %ld", value);
+    for (auto& m : mCdmaModeArray) {
+        if ((value & (1L << m.mBit)) == 0) {
+            m.mEnable = false;
+        } else {
+            m.mEnable = true;
+        }
+        RLOGD("setSupportedModeCdma labels: %s, enable: %d", m.mName.c_str(), m.mEnable);
+    }
+}
+
+static void showBandModeCdma(char* response, int msg) {
+    std::vector<std::string> out;
+    utils::tokenize(string(response), "\n", out);
+    for(auto i: out) {
+        if(i.find(SAME_COMMAND_CDMA) != std::string::npos) {
+            std::string splitString = i.substr(std::string(SAME_COMMAND_CDMA).size());
+            RLOGD("showBandModeCdma splitString: %s", splitString.c_str());
+            if (msg == EVENT_QUERY_CURRENT_CDMA) {
+                std::vector<std::string> getDigitalVal;
+                utils::tokenize(string(splitString), ",\n", getDigitalVal);
+                std::vector<long> values;
+                try {
+                    for(auto str: getDigitalVal) {
+                        if(str.empty() || str == "\n") {
+                            continue;
+                        }
+                        long v = std::stol(str, 0 ,0);
+                        values.push_back(v);
+                    }
+                } catch (const out_of_range &e) {
+                    RLOGD("out of range: %s", e.what());
+                } catch (const invalid_argument &e) {
+                    RLOGD("invalid argument: %s", e.what());
+                }
+                if(values.size() < 2) {
+                    RLOGD("showBandModeCdma size < 2");
+                    android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+                    return;
+                }
+                setSupportedModeCdma(values[0]);
+                setCurrentModeCdma(values[1]);
+            }
+        }
+    }
+}
+
+static void showBandModeGsm(char* response, int msg) {
+    std::vector<std::string> out;
+    utils::tokenize(string(response), "\n", out);
+    for(auto i: out) {
+        if(i.find(SAME_COMMAND) != std::string::npos) {
+            std::string splitString = i.substr(std::string(SAME_COMMAND).size());
+            RLOGD("showBandModeGsm splitString: %s", splitString.c_str());
+            std::vector<std::string> getDigitalVal;
+            utils::tokenize(string(splitString), ",\n", getDigitalVal);
+            if (getDigitalVal.size() > 0) {
+                std::vector<long> values;
+                for (int i = 0; i < INDEX_BAND_MAX; i++) {
+                    if (getDigitalVal.size() <= i) {
+                        values.push_back(0);
+                        continue;
+                    }
+                    try {
+                        values.push_back(std::stol(getDigitalVal[i], 0 ,0));
+                    } catch (const out_of_range &e) {
+                        values.push_back(0);
+                        RLOGD("out of range: %s", e.what());
+                    } catch (const invalid_argument &e) {
+                        values.push_back(0);
+                        RLOGD("invalid argument: %s", e.what());
+                    }
+                }
+                if (msg == EVENT_QUERY_SUPPORTED) {
+                    setSupportedMode(values);
+                    if (getDigitalVal.size() > 5) {
+                        RLOGD("The Modem support Lte extend band");
+                        mIsLteExtend = true;
+                    } else {
+                        RLOGD("The Modem not support Lte extend band");
+                        mIsLteExtend = false;
+                    }
+                } else {
+                    setCurrentMode(values);
+                }
+            } else {
+                android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+                RLOGD("getDigitalVal is null");
+            }
+        }
+    }
+}
+
+static void printGetBand(int flag) {
+    RLOGD("printGetBand(%d), fgset(%d)", flag, fgset);
+    if(fgset) {
+        return;
+    }
+    if(flag == EVENT_QUERY_CURRENT) {
+        RLOGD("printGetBand start");
+        std::string msg;
+        for (auto& i : mModeArray) {
+            if (i.mEnable && i.mCheck) {
+                if ((i.mIndex == INDEX_GSM_BAND) && (msg.find("GSM Mode:") == std::string::npos)) {
+                    msg.append("GSM Mode:\n");
+                } else if ((i.mIndex == INDEX_UMTS_BAND) && (msg.find("UMTS Mode:") == std::string::npos)) {
+                    msg.append("\nUMTS Mode:\n");
+                } else if ((i.mIndex >= INDEX_LTE_FDD_BAND) && (i.mIndex <= INDEX_LTE_BAND_256) && (msg.find("LTE Mode:") == std::string::npos)) {
+                    msg.append("\nLTE Mode:\n");
+                }
+
+                msg.append("....");
+                msg.append(i.mName);
+                msg.append("\n");
+            }
+        }
+        for (auto& i : mCdmaModeArray) {
+            if (i.mEnable && i.mCheck) {
+                if ((i.mIndex == INDEX_CDMA_BAND) && (msg.find("CDMA Mode:") == std::string::npos)) {
+                    msg.append("\nCDMA Mode: \n");
+                }
+                msg.append("....");
+                msg.append(i.mName);
+                msg.append("\n");
+            }
+        }
+        msg.append("done\n");
+        android::emResultNotify(msg.c_str());
+    }
+}
+
+static void setBandModeCdma(const long value) {
+    RLOGD("setCdmaBandMode: %d", value);
+    string msg = SET_COMMAND_CDMA + std::to_string(value);
+    sendATCommand(msg.c_str(), EVENT_SET_CDMA);
+}
+
+/**
+ * Set the selected modes.
+ *
+ * @param values the integers of mode values
+ * @return false means set failed or success
+ */
+static void setBandMode(std::vector<long> values) {
+    RLOGD("setBandMode values: %ld,%ld,%ld,%ld", values[0],values[1],values[2],values[3]);
+    if (values[0] > GSM_MAX_VALUE
+            || values[1] > UMTS_MAX_VALUE
+            || values[2] > LTE_MAX_VALUE
+            || values[3] > LTE_MAX_VALUE) {
+        android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+        RLOGD("setBandMode,just return");
+        return;
+    }
+
+    std::vector<std::string> modeString {SET_COMMAND + std::to_string(values[0]) + std::string(",") + std::to_string(values[1]), ""};
+    if (ModemCategory::isLteSupport()) {
+        modeString[0] += std::string(",") + std::to_string(values[2]) + std::string(",") + std::to_string(values[3]);
+        if (mIsLteExtend) {
+            for (int i = 4; i < INDEX_BAND_MAX - 1; i++) {
+                modeString[0] += std::string(",") + std::to_string(values[i]);
+            }
+        }
+    }
+    RLOGD("setGsmBandMode AT String: %s", modeString[0].c_str());
+    sendATCommand(modeString[0].c_str(), EVENT_SET_GSM);
+}
+
+static long getValFromBoxCdma() {
+    long value = 0;
+    for (auto& m : mCdmaModeArray) {
+        if (m.mCheck) {
+            value |= 1L << m.mBit;
+        }
+    }
+    return value;
+}
+
+/**
+ * Get the selected mode values.
+ *
+ * @return values from the selected boxes
+ */
+static std::vector<long> getValFromBox(bool judge) {
+    std::vector<long> values(INDEX_BAND_MAX,0);
+    std::vector<long> values_temp(INDEX_BAND_MAX,0);
+    for (auto& m : mModeArray) {
+        if (m.mCheck) {
+            values[m.mIndex] |= 1L << m.mBit;
+            values_temp[m.mIndex] |= 1L << m.mBit;
+        }
+    }
+
+    if (judge) {
+        // band64 to band256 belongs to lte fdd, so check null together
+        for (int i = INDEX_LTE_BAND_96; i <= INDEX_LTE_BAND_256; i++) {
+            values_temp[INDEX_LTE_FDD_BAND] = values_temp[INDEX_LTE_FDD_BAND] | values_temp[i];
+        }
+        // check FDD and TDD ,only all null is invalid
+        values_temp[INDEX_LTE_FDD_BAND] = values_temp[INDEX_LTE_FDD_BAND] | values_temp[INDEX_LTE_TDD_BAND];
+        values_temp[INDEX_LTE_TDD_BAND] = values_temp[INDEX_LTE_FDD_BAND];
+
+        // null select is not allowed.
+        if (values[0] == 0) {
+            values[0] = GSM_MAX_VALUE;
+        }
+        if (values[1] == 0) {
+            values[1] = UMTS_MAX_VALUE;
+        }
+        if (values_temp[2] == 0 && values_temp[3] == 0) {
+            values[2] = LTE_MAX_VALUE;
+            values[3] = LTE_MAX_VALUE;
+            RLOGD("lte not to null");
+        }
+    }
+    return values;
+}
+
+static void printSupportBand(int flag) {
+    RLOGD("printSupportBand, fgset(%d), count(%d), flag(%d)",fgset, count, flag);
+    if(fgset && (count == 0) && (flag == EVENT_QUERY_CURRENT)) {
+        RLOGD("printSupportBand start");
+        std::string msg;
+        for (auto& i : mModeArray) {
+            if (i.mEnable) {
+                if ((i.mIndex == INDEX_GSM_BAND) && (msg.find("GSM Mode:") == std::string::npos)) {
+                    msg.append("GSM Mode:\n");
+                } else if ((i.mIndex == INDEX_UMTS_BAND) && (msg.find("UMTS Mode:") == std::string::npos)) {
+                    msg.append("\nUMTS Mode:\n");
+                } else if ((i.mIndex >= INDEX_LTE_FDD_BAND) && (i.mIndex <= INDEX_LTE_BAND_256) && (msg.find("LTE Mode:") == std::string::npos)) {
+                    msg.append("\nLTE Mode:\n");
+                }
+
+                msg.append("....");
+                msg.append("(");
+                msg.append(std::to_string(i.mIndex));
+                msg.append(".");
+                msg.append(std::to_string(i.mBit));
+                msg.append("): ");
+                msg.append(i.mName);
+                msg.append("....");
+                msg.append(i.mCheck ? "true":"false");
+                msg.append("\n");
+            }
+        }
+        for (auto& i : mCdmaModeArray) {
+            if (i.mEnable) {
+                if ((i.mIndex == INDEX_CDMA_BAND) && (msg.find("CDMA Mode:") == std::string::npos)) {
+                    msg.append("\nCDMA Mode: \n");
+                }
+                msg.append("....");
+                msg.append("(");
+                msg.append(std::to_string(i.mIndex));
+                msg.append(".");
+                msg.append(std::to_string(i.mBit));
+                msg.append("): ");
+                msg.append(i.mName);
+                msg.append("....");
+                msg.append(i.mIndex ? "true":"false");
+                msg.append("\n");
+            }
+        }
+        msg.append("done\n");
+        android::emResultNotify(msg.c_str());
+    }
+}
+
+static void* setGsmBandMode(void* arg) {
+    setBandMode(gsmValues);
+    return NULL;
+}
+
+static void* setCdmaBandMode(void* arg) {
+    setBandModeCdma(cdmaValues);
+    return NULL;
+}
+
+static void emBandmodeAtCmdHandle(char* response, int responselen) {
+    RLOGD("emBandmodeAtCmdHandle, flag=%d, data=%s", mCurrentEmbandmodeFlag, response);
+    switch (mCurrentEmbandmodeFlag) {
+    case EVENT_QUERY_CURRENT_CDMA: {
+        if ((responselen > 0) && (response != NULL)) {
+            showBandModeCdma(response, EVENT_QUERY_CURRENT_CDMA);
+        } else {
+            android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+            RLOGD("don't support(%d)", EVENT_QUERY_CURRENT_CDMA);
+        }
+        BLOCK_WAKEUP();
+        break;
+    }
+    case EVENT_QUERY_SUPPORTED:
+    {
+        if ((responselen > 0) && (response != NULL)) {
+            showBandModeGsm(response, EVENT_QUERY_SUPPORTED);
+        } else {
+            android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+            RLOGD("don't support(%d)", EVENT_QUERY_SUPPORTED);
+        }
+        BLOCK_WAKEUP();
+        break;
+    }
+    case EVENT_QUERY_CURRENT:
+    {
+        if ((responselen > 0) && (response != NULL)) {
+            showBandModeGsm(response, EVENT_QUERY_CURRENT);
+        } else {
+            android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+            RLOGD("don't support(%d)", EVENT_QUERY_CURRENT);
+        }
+        printGetBand(EVENT_QUERY_CURRENT);
+        printSupportBand(EVENT_QUERY_CURRENT);
+        BLOCK_WAKEUP();
+        if(fgset && (count > 0)) {
+            for(auto& val : choose_vals) {
+                RLOGD("handle values: %s", val.c_str());
+                std::vector<std::string> out;
+                utils::tokenize(val, "=", out);
+                if(out.size() == 2) {
+                    std::vector<std::string> indexs;
+                    utils::tokenize(out[0], ".", indexs);
+                    if(indexs.size() == 2) {
+                        try {
+                            int index = std::stoi(indexs[0]);
+                            int bit = std::stoi(indexs[1]);
+                            bool check = std::stoi(out[1]) > 0 ? true : false;
+                            for (auto& i : mModeArray) {
+                                if((i.mIndex == index) && (i.mBit == bit)) {
+                                    i.mCheck = check;
+                                    RLOGD("set gsm band: lales=%s, index=%d, bit=%d, enable=%d, check=%d",
+                                            i.mName.c_str(),i.mIndex, i.mBit, i.mEnable, i.mCheck);
+                                }
+                            }
+                            for (auto& i : mCdmaModeArray) {
+                                if((i.mIndex == index) && (i.mBit == bit)) {
+                                    if((i.mIndex == index) && (i.mBit == bit)) {
+                                        i.mCheck = check;
+                                        RLOGD("set gsm band: lales=%s, index=%d, bit=%d, enable=%d, check=%d",
+                                                i.mName.c_str(),i.mIndex, i.mBit, i.mEnable, i.mCheck);
+                                    }
+                                }
+                            }
+                        } catch (const out_of_range &e) {
+                            RLOGD("out of range: %s", e.what());
+                        } catch (const invalid_argument &e) {
+                            RLOGD("invalid argument: %s", e.what());
+                        }
+                    }else {
+                        RLOGD("invalid parameters: %s", out[0].c_str());
+                        android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+                        return;
+                    }
+
+                } else {
+                    RLOGD("invalid parameters: %s", val.c_str());
+                    android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+                    return;
+                }
+            }
+            cdmaValues = getValFromBoxCdma();
+            gsmValues = getValFromBox(true);
+            pthread_t setBandMode_thread;
+            pthread_create(&setBandMode_thread,NULL, setGsmBandMode, NULL);
+        }
+        break;
+    }
+    case EVENT_SET_GSM:
+    {
+        BLOCK_WAKEUP();
+        if ((responselen > 0) && (response != NULL)) {
+            RLOGD("Set Gsm bandmode success: %s", response);
+            if ((mSimType == 0) && ModemCategory::isCdma() && (!utils::is90Modem())) {
+                pthread_t setBandMode_thread;
+                pthread_create(&setBandMode_thread,NULL, setCdmaBandMode, NULL);
+            } else {
+                RLOGD("don't support cdma, response");
+                android::emResultNotify(RET_STRING_BANDMODE_SUCCESS);
+            }
+        } else {
+            RLOGD("send gsm fail ");
+            android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+        }
+        break;
+    }
+    case EVENT_SET_CDMA:
+    {
+        BLOCK_WAKEUP();
+        if ((responselen > 0) && (response != NULL)) {
+            RLOGD("Set cdma bandmode success: %s", response);
+            android::emResultNotify(RET_STRING_BANDMODE_SUCCESS);
+        } else {
+            RLOGD("send cdma fail ");
+            android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+        }
+        break;
+    }
+    default:
+        break;
+    }
+}
+
+static void queryCurrentCdmaMode() {
+    if (utils::is93Modem()) {
+        //SAME_COMMAND_CDMA;
+        RLOGD("queryCurrentCdmaMode: %s", QUERY_CURRENT_COMMAND_CDMA.c_str());
+        sendATCommand(QUERY_CURRENT_COMMAND_CDMA.c_str(), EVENT_QUERY_CURRENT_CDMA);
+    } else {
+        android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+        RLOGD("don't support");
+    }
+}
+
+/**
+ * Query Modem supported band modes.
+ */
+static void querySupportMode() {
+    //SAME_COMMAND
+    RLOGD("querySupportMode AT String: %s", QUERY_SUPPORT_COMMAND.c_str());
+    sendATCommand(QUERY_SUPPORT_COMMAND.c_str(), EVENT_QUERY_SUPPORTED);
+}
+
+/**
+ * Query Modem is being used band modes.
+ */
+static void queryCurrentMode() {
+    //SAME_COMMAND
+    RLOGD("queryCurrentMode AT String: %s", QUERY_CURRENT_COMMAND.c_str());
+    sendATCommand(QUERY_CURRENT_COMMAND.c_str(), EVENT_QUERY_CURRENT);
+}
+
+static void initGsmArray() {
+    for (int i = 0; i < band_mode_gsm.size(); i++) {
+        mModeArray.emplace_back(band_mode_gsm[i], INDEX_GSM_BAND, GSM_BAND_BIT[i], false, false);
+    }
+}
+
+static void initLteArray() {
+    for (int i = 0; i < band_mode_lte_fdd.size(); i++) {
+        mModeArray.emplace_back(band_mode_lte_fdd[i], INDEX_LTE_FDD_BAND, i, false, false);
+    }
+    for (int i = 0; i < band_mode_lte_tdd.size(); i++) {
+        mModeArray.emplace_back(band_mode_lte_tdd[i], INDEX_LTE_TDD_BAND, i, false, false);
+    }
+    for (int i = 0; i < band_mode_lte_96.size(); i++) {
+        mModeArray.emplace_back(band_mode_lte_96[i], INDEX_LTE_BAND_96, i, false, false);
+    }
+    for (int i = 0; i < band_mode_lte_128.size(); i++) {
+        mModeArray.emplace_back(band_mode_lte_128[i], INDEX_LTE_BAND_128, i, false, false);
+    }
+    for (int i = 0; i < band_mode_lte_160.size(); i++) {
+        mModeArray.emplace_back(band_mode_lte_160[i], INDEX_LTE_BAND_160, i, false, false);
+    }
+    for (int i = 0; i < band_mode_lte_192.size(); i++) {
+        mModeArray.emplace_back(band_mode_lte_192[i], INDEX_LTE_BAND_192, i, false, false);
+    }
+    for (int i = 0; i < band_mode_lte_224.size(); i++) {
+        mModeArray.emplace_back(band_mode_lte_224[i], INDEX_LTE_BAND_224, i, false, false);
+    }
+    for (int i = 0; i < band_mode_lte_256.size(); i++) {
+        mModeArray.emplace_back(band_mode_lte_256[i], INDEX_LTE_BAND_256, i, false, false);
+    }
+}
+
+static void initTdscdmaArray() {
+    for (int i = 0; i < band_mode_tdscdma.size(); i++) {
+        mModeArray.emplace_back(band_mode_tdscdma[i], INDEX_UMTS_BAND, i, false, false);
+    }
+}
+
+static void initWcdmaArray() {
+    for (int i = 0; i < band_mode_wcdma.size(); i++) {
+        mModeArray.emplace_back(band_mode_wcdma[i], INDEX_UMTS_BAND, i, false, false);
+    }
+}
+
+static void initCdmaArray() {
+    for (int i = 0; i < band_mode_cdma.size(); i++) {
+        mCdmaModeArray.emplace_back(band_mode_cdma[i], INDEX_CDMA_BAND, i, false, false);
+    }
+}
+
+static void * emBandmodeThread(void* arg)
+{
+    mModeArray.clear();
+    mCdmaModeArray.clear();
+    initGsmArray();
+    int modemType = ModemCategory::getModemType();
+    if (modemType == TDSCDMA && ModemCategory::isCapabilitySim(mSimType)) {
+        initTdscdmaArray();
+        if (ModemCategory::isLteSupport()) {
+            initLteArray();
+        }
+    } else if (modemType == WCDMA && ModemCategory::isCapabilitySim(mSimType)) {
+        initWcdmaArray();
+        if (ModemCategory::isLteSupport()) {
+            initLteArray();
+        }
+    } else if (!(ModemCategory::isCapabilitySim(mSimType))) {
+        if (ModemCategory::checkViceSimCapability(mSimType, MtkRadioAccessFamily::RAF_UMTS)) {
+            initWcdmaArray();
+        }
+        if (ModemCategory::checkViceSimCapability(mSimType, MtkRadioAccessFamily::RAF_LTE)) {
+            if (ModemCategory::isLteSupport()) {
+                initLteArray();
+            }
+        }
+    }
+
+    if (mSimType == 0 && ModemCategory::isCdma() && !utils::is90Modem()) {
+        initCdmaArray();
+    }
+    if (ModemCategory::isCdma() && !utils::is90Modem() && (mSimType == 0)) {
+        queryCurrentCdmaMode();
+    }
+    querySupportMode();
+    queryCurrentMode();
+    pthread_exit(0);
+}
+
+//AT+EPBSE=gsm,umts,ltefdd,ltetdd
+int emBandmodeStart(int len,int *item,int multilen,char *value[])
+{
+    mSimType = get_default_sim_all_except_data();
+    RLOGD("emBandmodeStart called : simType:%d", mSimType);
+    //1. reset to default: select all supported bands: AT+EPBSE=255,63355
+    if(len < 1)
+    {
+        RLOGD("emBandmodeStart: please select mode to test: 0: get, 1: set ");
+        android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+        return -1;
+    }
+    if((item[0] > 1 ) || (item[0] < 0)){
+        RLOGD("emBandmodeStart: invalid parameter %d",item[0]);
+        android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+        return -1;
+    }
+    if(item[0] == 0){
+        fgset = false;
+    }else{
+        fgset = true;
+        count = multilen;
+        RLOGD("emBandmodeStart count = %d", count);
+        choose_vals.clear();
+        if(count > 0){
+            for(int i=0; i< count; i++) {
+                choose_vals.push_back(value[i]);
+            }
+        }
+    }
+    mCurrentEmbandmodeFlag = 0;
+    android::registerForATcmdResponse(emBandmodeAtCmdHandle);
+    pthread_t embandmode_thread;
+    pthread_create(&embandmode_thread,NULL, emBandmodeThread, NULL);
+    return (0);
+}
+#endif
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_c2kmodemsetting.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_c2kmodemsetting.cpp
new file mode 100644
index 0000000..e577c39
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_c2kmodemsetting.cpp
@@ -0,0 +1,134 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include <string>
+#include <vector>
+
+#include  "common.h"
+#include "em/em.h"
+#include "Radio_capability_switch_util.h"
+
+#if EM_MODE_SUPPORT
+
+#undef LOG_TAG
+#define LOG_TAG "EM_C2KMODEMSETTING"
+const int TIME_REG = 0;
+
+const static int MSG_SET_DISABLE_1X_TIME = 1;
+const static int MSG_SET_ENABLE_1X_TIME = 2;
+const static int MSG_QUERY_STATUS_1X_TIME = 3;
+
+int c2kmodemsetting_id = -1;
+//int c2kmodemsetting_option_cnt = -1;
+int c2kmodemsetting_option[8] = { 0 };
+
+int mCurrentC2KEmmodemSettingFlag = -1;
+static void sendATCommand(const char *cmd, int msg) {
+    mCurrentC2KEmmodemSettingFlag = msg;
+    emSendATCommand(cmd,Radio_capability_switch_util::get_main_capability_phone_id());
+    return;
+}
+
+static void set1XTime(int command, int msg) {
+    std::vector<std::string> cmdOri(3);
+    cmdOri[0] = "AT+ECREGTYPE=0," + std::to_string((command == 1 ? 1 : 0));
+    cmdOri[1] = "";
+    cmdOri[2] = "DESTRILD:C2K";
+    std::vector<std::string> cmds = getCdmaCmdArr(cmdOri);
+    std::string cmd;
+    for (auto s : cmds) {
+        cmd += s;
+    }
+    RLOGD("set1XTime AT command: %s", cmd);
+    sendATCommand(cmd.c_str(), msg);
+}
+
+static void emC2kModemSetingsAtCmdHandle(char*response, int responselen) {
+    switch (mCurrentC2KEmmodemSettingFlag) {
+    case MSG_SET_DISABLE_1X_TIME: {
+        if ((responselen > 0) && (response != NULL)) {
+            RLOGD("Disable_Time_REG successful");
+            emResultNotifyWithDone("Disable_Time_REG successful");
+        } else {
+            RLOGD("Disable_Time_REG failed.");
+            emResultNotifyWithDone("Disable_Time_REG failed.");
+        }
+        break;
+    }
+    case MSG_SET_ENABLE_1X_TIME: {
+        if ((responselen > 0) && (response != NULL)) {
+            RLOGD("Enable_Time_REG successful.");
+            emResultNotifyWithDone("Enable_Time_REG successful.");
+        } else {
+            RLOGD("Enable_Time_REG failed.");
+            emResultNotifyWithDone("Enable_Time_REG failed.");
+        }
+        break;
+    }
+    case MSG_QUERY_STATUS_1X_TIME:
+        break;
+    default:
+        break;
+    }
+}
+
+static void * emC2kModemSettingThread(void* arg) {
+    RLOGD("c2k Modem Setting: %d ", c2kmodemsetting_option[0]);
+    switch (c2kmodemsetting_id) {
+    case TIME_REG: {
+        set1XTime(c2kmodemsetting_option[0],
+                (c2kmodemsetting_option[0] ?
+                        MSG_SET_ENABLE_1X_TIME : MSG_SET_DISABLE_1X_TIME));
+        break;
+    }
+    default:
+        break;
+    }
+    pthread_exit(0);
+}
+
+int emC2kModemSettingStart(int argc, int multicnt, int *item) {
+    RLOGD("emC2kModemSettingStart called");
+    int idmapping[1] = { TIME_REG };
+    c2kmodemsetting_id = idmapping[item[0]];
+    c2kmodemsetting_option[0] = item[1];
+    android::registerForATcmdResponse(emC2kModemSetingsAtCmdHandle);
+    pthread_t emC2kModemSetting_thread;
+    pthread_create(&emC2kModemSetting_thread, NULL, emC2kModemSettingThread,
+            NULL);
+    return 0;
+}
+#endif /*EM_MODE_SUPPORT*/
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_cfu.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_cfu.cpp
new file mode 100644
index 0000000..7b382d8
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_cfu.cpp
@@ -0,0 +1,153 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include <vendor-ril/telephony/ril.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <cutils/jstring.h>
+#include <log/log.h>
+#include <unistd.h>
+#include <math.h>
+#include  "common.h"
+#include "em/em.h"
+#include "Radio_capability_switch_util.h"
+
+#if EM_MODE_SUPPORT
+
+#undef LOG_TAG
+#define LOG_TAG "EM_CFU"
+
+const int QUERY = 3;
+const int SET_DEFAULT = 0;
+const int SET_ON = 2;
+const int SET_OFF = 1;
+#define CFU_QUERY_CMD  "AT+ESSP?"
+#define CFU_SET_CMD  "AT+ESSP="
+int mCurrentEmcfuFlag = 0;
+int cfumode = -1;
+
+void  sendATCommand_ecfu(const char *cmd,int msg)
+{
+    mCurrentEmcfuFlag = msg;
+    emSendATCommand(cmd, Radio_capability_switch_util::get_main_capability_phone_id());
+    return ;
+}
+
+void emCfuAtCmdHandle(char*response, int responselen) {
+    switch (mCurrentEmcfuFlag) {
+        case QUERY:
+        {
+            //parse hspa mode.
+            if ((responselen > 0) && (response != NULL)) {
+                RLOGD("emCfuAtCmdHandle QUERY response: %s\n",response);
+            }
+            else {
+                RLOGD("send fail ");
+            }
+            android::unregisterNetwork();
+            android::emResultNotify(RET_STRING_CFU_SUCCESS);
+            break;
+        }
+        case SET_DEFAULT:
+        {
+            if ((responselen > 0) && (response != NULL)) {
+                RLOGD("Set default success: %s.\n",response);
+            }
+            else {
+                RLOGD("send fail ");
+            }
+            break;
+        }
+        case SET_ON:
+        {
+            if ((responselen > 0) && (response != NULL)) {
+                RLOGD("Set on success: %s.\n",response);
+            }
+            else {
+                RLOGD("send fail ");
+            }
+            break;
+        }
+        case SET_OFF:
+        {
+            if ((responselen > 0) && (response != NULL)) {
+                RLOGD("Set off success: %s.\n",response);
+            }
+            else {
+                RLOGD("send fail ");
+            }
+            break;
+        }
+        default:
+            break;
+    }
+}
+
+
+//create thread to send command
+void * emCfuThread(void* arg)
+{
+    char cmd_str[32] = {0};
+    sprintf(cmd_str,"%s%d", CFU_SET_CMD,cfumode);
+    sendATCommand_ecfu(cmd_str,cfumode);
+    sendATCommand_ecfu(CFU_QUERY_CMD,QUERY);
+    pthread_exit(0);
+}
+
+int emCfuStart(int argc, int *item)
+{
+    RLOGD("emCfuStart called");
+    if(argc < 1)
+    {
+        RLOGD("emCfuStart: please select mode to test: \
+                0: default, 1: set on 2: set off");
+        android::emResultNotify(RET_STRING_CFU_FAIL);
+        return -1;
+    }
+    if((item[0] > 2 ) || (item[0] < 0)){
+        RLOGD("emCfuStart: invalid parameter %d",item[0]);
+        android::emResultNotify(RET_STRING_CFU_FAIL);
+        return -1;
+    }
+    int cfumapping[3] = {SET_DEFAULT,SET_ON,SET_OFF};
+    mCurrentEmcfuFlag = 0;
+    cfumode = cfumapping[item[0]];
+    android::registerForATcmdResponse(emCfuAtCmdHandle);
+    pthread_t emcfu_thread;
+    pthread_create(&emcfu_thread,NULL, emCfuThread, NULL);
+    return (0);
+}
+
+#endif
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_el1_public_struct.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_el1_public_struct.h
new file mode 100644
index 0000000..1c44d29
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_el1_public_struct.h
@@ -0,0 +1,2026 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2005
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+#ifndef _EM_EL1_PUBLIC_STRUCT_H
+#define _EM_EL1_PUBLIC_STRUCT_H
+
+/* portable 8-bit unsigned integer */
+typedef unsigned char           kal_uint8;
+/* portable 8-bit signed integer */
+typedef signed char             kal_int8;
+/* portable 16-bit unsigned integer */
+typedef unsigned short int      kal_uint16;
+/* portable 16-bit signed integer */
+typedef signed short int        kal_int16;
+/* portable 32-bit unsigned integer */
+typedef unsigned int            kal_uint32;
+typedef signed int              kal_int32;
+typedef unsigned long long kal_uint64;
+typedef signed long long kal_int64;
+typedef unsigned char kal_bool;
+typedef kal_uint32 EARFCN;
+
+/* EL1 */
+#define RPT_LTE_RX_CC_MAX   4
+#define RPT_LTE_TX_CC_MAX   2
+#define LTE_MAX_DATA_BUF   30   // EL1 MDMI
+
+#define AGC_RX_ANT_NUM 2
+#define EM_OTDOA_MAX_NBR_CELL_LIST_NUM_TOTAL  3
+
+#define LOCAL_PARA_HDR \
+   kal_uint8 ref_count; \
+   kal_uint8 lp_reserved; \
+   kal_uint16 msg_len;
+
+typedef enum
+{
+    EM_RNTI_NONE                = 0,
+    EM_C_RNTI                   = 1,
+    EM_SPSC_RNTI                = 2,
+    EM_P_RNTI                   = 3,
+    EM_RA_RNTI                  = 4,
+    EM_TC_RNTI                  = 5,
+    EM_SI_RNTI                  = 6,
+    EM_TPC_PUSCH_RNTI           = 7,
+    EM_TPC_PUCCH_RNTI           = 8,
+    EM_M_RNTI                   = 9,
+    EM_RNTI_INVALID             = 255
+} em_dl_rnti_enum;
+
+typedef enum
+{
+   /*
+    * MP branches: please add "EM type id" in em_info_enum.h.
+    * Please remember to modify MD_COMMON\EM\em_info_enum.h for main TRUNK ex: LR11/LR12/UMOLY/UMOLYA
+    */
+          /* RR */
+          /* Begin of RR EM INFO Request enum */
+          RR_EM_CELL_SELECT_PARA_INFO = 0, RR_EM_INFO_BEGIN = RR_EM_CELL_SELECT_PARA_INFO,
+          RR_EM_CHANNEL_DESCR_INFO = 1,
+          RR_EM_CTRL_CHANNEL_DESCR_INFO = 2,
+          RR_EM_RACH_CTRL_PARA_INFO = 3,
+          RR_EM_LAI_INFO = 4,
+          RR_EM_RADIO_LINK_COUNTER_INFO = 5,
+          RR_EM_MEASUREMENT_REPORT_INFO = 6,
+          /* ZY : Temp solution : Cell allocation list*/
+          RR_EM_CA_LIST_INFO = 7,
+          /* RR new structure */
+          RR_EM_CONTROL_MSG_INFO = 8,
+          RR_EM_SI2Q_INFO_STRUCT_INFO = 9,
+          RR_EM_MI_INFO_STRUCT_INFO = 10,
+          RR_EM_BLK_INFO = 11,
+          RR_EM_TBF_INFO = 12,
+          RR_EM_GPRS_GENERAL_INFO = 13,
+          /* GAS MM EM INFO */
+          RRM_EM_FDD_IR_PARAMETER_STATUS_IND_STRUCT_INFO = 14,
+          RRM_EM_IR_RESELECT_STATUS_IND_STRUCT_INFO = 15,
+          RRM_EM_IR_3G_NEIGHBOR_MEAS_STATUS_IND_STRUCT_INFO = 16,
+          RRM_EM_IR_3G_NEIGHBOR_MEAS_INFO_IND_STRUCT_INFO = 17,
+          RRM_EM_IR_4G_NEIGHBOR_MEAS_STATUS_IND_STRUCT_INFO = 18,
+          RRM_EM_IR_4G_NEIGHBOR_MEAS_INFO_IND_STRUCT_INFO = 19,
+          RRM_EM_SERV_CELL_POWER_STATUS_IND_STRUCT_INFO = 20,
+          RRM_EM_IR_3G_NEIGHBOR_CELL_STATUS_IND_STRUCT_INFO = 21,
+          RRM_EM_IR_4G_NEIGHBOR_CELL_STATUS_IND_STRUCT_INFO = 22,
+          RRM_EM_TDD_IR_PARAMETER_STATUS_IND_STRUCT_INFO = 23,
+          RRM_EM_SUCCESS_RATE_KPI_INFO = 24,
+          RRM_EM_MT_T3126_TIMEOUT_INFO = 25,
+          RRM_EM_CS_RLF_INFO = 26,
+          RRM_EM_RR_STATE_INFO = 27,
+          RRM_EM_GAS_SEARCH_INFO = 28,
+          RRM_EM_DOWNLINK_SIGNALLING_COUNTER_INFO = 29,
+          RRM_EM_RACH_FAIL = 30,
+          RRM_EM_N200_EXP = 31,
+          RRM_EM_HO_FAIL = 32,
+          RRM_EM_OOS_IND = 33,
+          RR_EM_INFO_END = RR_EM_INFO_BEGIN + 49,
+
+          /*End of RR EM INFO Request enum*/
+
+          /* CC */
+          CC_EM_CHANNEL_INFO = 50,
+          CC_EM_CALL_INFO = 51,
+
+          /* SS */
+          SS_EM_INFO = 52,
+
+          /* MM */
+          MM_EM_INFO = 53,
+          /*EM ehancement for RR new structure*/
+          MMRR_EM_PLMN_INFO_STRUCT_INFO = 54,
+
+          /* UEM */
+          UEM_EM_BATTERY_INFO = 55,
+
+          /* gprs em begins */
+          GMM_EM_INFO = 56,
+       //   TCM_EM_EXT_PDP_INFO,
+       //   TCM_EM_INT_PDP_INFO,
+       //   TCM_EM_CONTEXT_INFO, //new
+       //   SNDCP_EM_INFO,
+          LLC_EM_INFO = 57,
+          /* PPP , removed because of no use*/
+          //PPP_EM_INFO,
+          SM_EM_INFO = 58,
+          EM_TCM_INFO_IND = 59,
+
+          MMRR_EM_PLMN_LIST_REQ_STRUCT_INFO = 60,
+          MMRR_EM_PLMN_LIST_CNF_STRUCT_INFO = 61,
+          MMRR_EM_PLMN_SEARCH_REQ_STRUCT_INFO = 62,
+          MMRR_EM_PLMN_SEARCH_CNF_STRUCT_INFO = 63,
+          MMRR_EM_HPLMN_LIST_INFO = 64,
+          MMRR_EM_OPLMN_LIST_INFO = 65,
+          MMRR_EM_STATIC_APPLMN_LIST_INFO = 66,
+          MMRR_EM_DYNAMIC_APPLMN_LIST_INFO = 67,
+
+           /* VT EM Display, 2007/11/30 */
+           /* VT owner comments VT EM enum is not needed in WR8 */
+           //VT_EM_CALL_STATE_INFO = 50, VT_EM_BEGIN = VT_EM_CALL_STATE_INFO,/* vt_em_call_state_choice */
+           //VT_EM_MASTER_SLAVE_STATUS_INFO,     /* vt_em_master_slave_status_choice */
+           //VT_EM_RETRANSMISSION_PROTOCOL_INFO, /* vt_em_retransmission_protocol_choice */
+           //VT_EM_INCOMING_AUDIO_CHANNEL_INFO,  /* vt_em_audio_channel_info_struct */
+           //VT_EM_OUTGOING_AUDIO_CHANNEL_INFO,  /* vt_em_audio_channel_info_struct */
+           //VT_EM_INCOMING_VIDEO_CHANNEL_INFO,  /* vt_em_video_channel_info_struct */
+           //VT_EM_OUTGOING_VIDEO_CHANNEL_INFO,  /* vt_em_video_channel_info_struct */
+           //VT_EM_ADM_MEM_MAX_USED_INFO,        /* kal_uint32 */
+           //VT_EM_STATISTIC_INFO,               /* vt_em_statistic_info_struct */
+           //VT_EM_ROUND_TRIP_DELAY_INFO,        /* kal_uint32 */
+           //VT_EM_INCOMING_XSRP_INFO,           /* vt_em_incoming_xSRP */
+           //VT_EM_OUTGOING_XSRP_INFO,           /* vt_em_outgoing_xSRP */
+           //VT_EM_END = VT_EM_OUTGOING_XSRP_INFO,
+
+          /**
+           * Gibran 20061228
+           * UAS MEME/CSCE measuremnt and cell status structure
+           */
+          MMRR_EM_PLMN_LOSS_INFO_STRUCT_INFO = 68,
+          MMRR_EM_PLMN_SEARCH_CNF_INFO_STRUCT_INFO = 69,
+          /* URR common Range 1, from enum 70 to 169.
+             it's used for both FDD and TDD */
+          FDD_EM_URR_3G_GENERAL_STATUS_IND = 70, URR_EM_INFO_BEGIN = FDD_EM_URR_3G_GENERAL_STATUS_IND,
+          /* Put 1st XXX_STATUS_IND_STRUCT_INFO in front of XXX_EM_INFO_BEGIN
+             in order to show enum_name in XXX_STATUS_IND_STRUCT_INFO not in XXX_EM_INFO_BEGIN. */
+
+          EM_SIBE_3G_SIB_IND_STRUCT_INFO = 71,
+          TDD_EM_URR_3G_GENERAL_STATUS_IND = 72,
+          FDD_EM_CSCE_SERV_CELL_IND_STRUCT_INFO = 75,
+          FDD_EM_CSCE_NEIGH_CELL_IND_STRUCT_INFO = 76,
+          FDD_EM_CSCE_R_STATUS_IND_STRUCT_INFO = 77,
+          FDD_EM_CSCE_H_STATUS_IND_STRUCT_INFO = 78,
+          FDD_EM_CSCE_APBCR_STATUS_IND_STRUCT_INFO = 79,
+          FDD_EM_CSCE_MEAS_RULE_STATUS_IND_STRUCT_INFO = 80,
+          FDD_EM_CSCE_MULTIPLE_PLMN_IND_STRUCT_INFO = 81,
+          TDD_EM_CSCE_SERV_CELL_IND_STRUCT_INFO = 82,
+          TDD_EM_CSCE_NEIGH_CELL_IND_STRUCT_INFO = 83,
+          TDD_EM_CSCE_R_STATUS_IND_STRUCT_INFO = 84,
+          TDD_EM_CSCE_H_STATUS_IND_STRUCT_INFO = 85,
+          TDD_EM_CSCE_APBCR_STATUS_IND_STRUCT_INFO = 86,
+          TDD_EM_CSCE_MEAS_RULE_STATUS_IND_STRUCT_INFO = 87,
+          TDD_EM_CSCE_MULTIPLE_PLMN_IND_STRUCT_INFO = 88,
+
+           /*SIM*/
+          EM_SIM_MONITOR_EVENT_INFO = 89,
+
+          EM_TDD_MEME_INFO_DCH_UMTS_CELL_INFO = 90, TDD_MEME_EM_INFO_BEGIN = EM_TDD_MEME_INFO_DCH_UMTS_CELL_INFO,
+          EM_TDD_MEME_INFO_DCH_GSM_CELL_INFO = 91,
+          EM_TDD_MEME_INFO_DCH_LTE_CELL_INFO = 92,
+          EM_TDD_MEME_INFO_EVENT_TYPE_1_PARAMETER_STRUCT_INFO = 93,
+          EM_TDD_MEME_INFO_EVENT_TYPE_2_PARAMETER_STRUCT_INFO = 94,
+          EM_TDD_MEME_INFO_EVENT_TYPE_3_PARAMETER_STRUCT_INFO =95,
+       //   EM_MEME_INFO_EVENT_TYPE_4_PARAMETER_STRUCT_INFO,
+       //   EM_MEME_INFO_EVENT_TYPE_5_PARAMETER_STRUCT_INFO,
+       //   EM_MEME_INFO_EVENT_TYPE_6_PARAMETER_STRUCT_INFO,
+       //   EM_MEME_INFO_DCH_H_SERVING_CELL_INFO,
+       //   EM_TDD_MEME_INFO_DCH_3G_BLER_INFO = 96,
+          EM_TDD_MEME_INFO_GSM_CELL_INFO =97, //for CMCC FT Tool
+          EM_TDD_MEME_INFO_LTE_CELL_INFO =98, //for CMCC FT Tool
+       //   EM_MEME_INFO_FACH_LTE_CELL_INFO = 100,
+          EM_TDD_MEME_INFO_REPORT_INFO = 99,
+          TDD_MEME_EM_INFO_END = TDD_MEME_EM_INFO_BEGIN + 15,
+
+          /* Call Information */
+          EM_CALL_INFO_IND = 106,
+
+          /* SIP Information */
+          EM_IMC_SIP_INFO_IND = 107,
+
+          MMRF_EM_MIPI_HW_INFO = 108,
+
+          EM_RRCE_TGPS_STATUS_IND= 110,
+          EM_SLCE_SRNCID_STATUS_IND= 111,
+
+          /* WO: 112 ~ 129 */
+          EM_WO_INFO_BEGIN = 112,
+          EM_WO_IKE_SRCPORT_INFO = EM_WO_INFO_BEGIN,
+          EM_WO_IKE_NATT_SRCPORT_INFO = 113,
+          EM_WO_IKE_DECRYPT_INFO_ADD = 114,
+          EM_WO_IKE_DECRYPT_INFO_DEL = 115,
+          EM_WO_ESP_DECRYPT_INFO_ADD = 116,
+          EM_WO_ESP_DECRYPT_INFO_DEL = 117,
+          EM_WO_DPD_INTERVAL_INFO = 118,
+          EM_WO_INFO_END = EM_WO_INFO_BEGIN + 17,
+
+          EM_UAS_3G_TDD128_HANDOVER_SEQUENCE_IND = 130,
+
+          EM_RRCE_3G4_REDIR_EVENT = 131,
+          EM_RRCE_KPI_STATUS_IND = 132,
+          TDD_EM_RRCE_CONN_STATUS_IND = 133,
+
+          /* SIM */
+          EM_SIM_APDU_INFO = 135,
+
+          EM_SLCE_PS_DATA_RATE_STATUS_IND = 140,
+          EM_RRCE_NW_PEER_MSG_INFO = 150,
+          EM_RRCE_RACH_FAIL_IND = 151,
+          EM_RRCE_MO_RLF_IND = 152,
+          EM_RRCE_3G3_HO_FAIL_IND = 153,
+          EM_RRCE_3G2_HO_FAIL_IND = 154,
+          EM_RRCE_DCH_STATE_CONFIGURATION_STATUS_IND = 155,
+          EM_RRCE_FACH_STATE_CONFIGURATION_STATUS_IND = 156,
+          EM_RRCE_CS_OVER_HSPA_STATUS_IND = 157,
+          EM_RRCE_3G_SECURITY_CONFIGURATION_INFO_IND = 158,
+          EM_RRCE_FD_CONFIGURATION_STATUS_IND = 159,
+          EM_RRCE_HSPA_CONFIG_IND = 160,   /* MOLY00100048, Jack Chu,  EM_RRCE_HSPA_CONFIG_IND == 160 */
+          EM_RRCE_RLF_IND = 161,  /* __ALPS02506878_SUPPORT__ */
+          EM_RRCE_3G_CELL_UARFCN_DL_UL_INFO_IND = 162,
+          URR_EM_INFO_END = EM_RRCE_3G_CELL_UARFCN_DL_UL_INFO_IND,
+
+          /* LBS: 163 ~ 169 */
+          EM_LBS_BEGIN = 163,
+          EM_LBS_GPS_OPEN_STATISTIC = EM_LBS_BEGIN,
+          EM_LBS_LR_STATISTIC = 164,
+          EM_LBS_AP_SETTING = 165,
+          EM_LBS_END = 169,
+
+          /* __UL1_EM_MODE__ */
+          UL1_EM_HS_DSCH_CONFIGURATION_INFO = 170, UL1_EM_INFO_BEGIN = UL1_EM_HS_DSCH_CONFIGURATION_INFO,
+          UL1_EM_EDCH_CONFIGURATION_INFO = 171,
+          UL1_EM_CPC_CONFIGURATION_INFO = 172,
+          UL1_EM_SECONDARY_HS_CONFIGURATION_STATUS_INFO = 173,
+          UL1_EM_PRIMARY_HS_DSCH_BLER_INFO = 174,
+          UL1_EM_SECONDARY_HS_DSCH_BLER_INFO = 175,
+          UL1_EM_EDCH_ACK_RATE_INFO = 176,   UL1_EM_INFO_END = UL1_EM_EDCH_ACK_RATE_INFO,  /* for backward compatibility */
+          UL1_EM_PRX_DRX_MEASUREMENT_INFO = 177,
+          /* HSDSCH info group  */
+          UL1_EM_HSPA_INFO_GROUP = 178,
+          UL1_EM_TAS_INFO = 179,
+          UL1_EM_RADIO_LINK_SYNC_STATUS = 180,
+          UL1_EM_UL1_RXD_STATUS = 181, /* already ported */
+          UL1_EM_UL1_RAS_INFO = 182,
+          UL1_EM_FS_UARFCN_INFO = 184,
+
+
+          /* __UL2_EM_MODE__ */
+          UL2_EM_ADM_POOL_STATUS_IND_STRUCT_INFO = 185, UL2_EM_INFO_BEGIN = UL2_EM_ADM_POOL_STATUS_IND_STRUCT_INFO,
+          UL2_EM_PS_DATA_RATE_STATUS_IND_STRUCT_INFO = 186,
+          UL2_EM_HSDSCH_RECONFIG_STATUS_IND_STRUCT_INFO = 187,
+          UL2_EM_URLC_EVENT_STATUS_IND_STRUCT_INFO = 188,
+          UL2_EM_3G_BLER_IND_STRUCT_INFO = 189,
+          UL2_EM_WCDMA_RLC_STATS_STRUCT_INFO = 190,
+          UL2_EM_URLC_LAYER_TPUT_INFO = 191,
+          /* UMAC new EM Arch */
+          /***HSUPA SI***/
+          UL2_EM_HSUPA_SI_IND_STRUCT_INFO = 192,
+          /***HSUPA SI***/
+
+          /* UMAC EM 2015 */
+          UL2_EM_UMAC_DCH_INFO = 193,
+          UL2_EM_UMAC_EDCH_INFO = 194,
+          UL2_EM_UMAC_HSDSCH_INFO = 195,
+          UL2_EM_URLC_ATT_RLC_STATISTICS_INFO = 196,
+          UL2_EM_URLC_ATT_RLC_RESET_INFO = 197,
+          UL2_EM_UMAC_PCH_CRC_ERR_INFO = 198,
+          UL2_EM_UMAC_PCH_INFO = 199,
+          UL2_EM_UMAC_LCHID_TRCH_MAPPING_INFO = 200,
+          UL2_EM_INFO_END = UL2_EM_UMAC_LCHID_TRCH_MAPPING_INFO,
+
+          /*ERRC_EM_MODE, here is the start of errc em info definition*/
+          ERRC_EM_MOB_MEAS_INTRARAT_INFO = 210, ERRC_EM_INFO_BEGIN = ERRC_EM_MOB_MEAS_INTRARAT_INFO,
+          ERRC_EM_MOB_MEAS_INTERRAT_UTRAN_INFO = 211,
+          ERRC_EM_MOB_MEAS_INTERRAT_GERAN_INFO = 212,
+          ERRC_EM_AUTOS_CSG_INFO = 213,
+          ERRC_EM_CARRS_EVENT_IND = 214,
+          ERRC_EM_SIB_EVENT_IND = 215,
+          ERRC_EM_MOB_EVENT_IND = 216,
+          ERRC_EM_SEC_PARAM = 217,
+          ERRC_EM_REEST_INFO = 218,
+          ERRC_EM_RECONF_INFO = 219,
+          ERRC_EM_RCM_SIM_STS_INFO = 220,
+          ERRC_EM_SYS_SIB_RX_STS_INFO = 221,
+          ERRC_EM_ERRC_STATE_IND = 222,
+          ERRC_EM_OVER_PROC_DELAY_WARNING = 223,
+          ERRC_EM_LTE_SUPPORTED_BAND_INFO = 224,
+          ERRC_EM_ERRC_KPI_INFO = 225,
+          ERRC_EM_ERRC_CONFIG_INFO = 226,
+
+          ERRC_EM_CONN_INFO = 227,
+
+          ERRC_EM_INFO_END = ERRC_EM_CONN_INFO,
+
+          /* __ESM_EM_MODE__ */
+          ESM_ESM_INFO = 228,
+          ESM_L4C_ESM_INFO = 229,
+
+          /* __EMM_EM_MODE__*/
+          EMM_EM_SEC_INFO = 230, EMM_EM_INFO_BEGIN = EMM_EM_SEC_INFO,
+          EMM_EM_PLMNSEL_INFO = 231,
+          EMM_EM_CONN_INFO = 232,
+          EMM_EM_NASMSG_INFO = 233,
+          EMM_EM_CALL_INFO = 234,
+          EMM_EM_REG_ATTACH_INFO = 235,
+          EMM_EM_REG_DETACH_INFO = 236,
+          EMM_EM_REG_TAU_INFO = 237,
+          EMM_EM_REG_COMMON_INFO = 238,
+          EMM_EM_SV_INFO = 239,
+          EMM_EM_RATBAND_INFO = 240,
+          EMM_EM_TIMERSRV_INFO = 241,
+          EMM_EM_USIMSRV_INFO = 242,
+          EMM_EM_NVMSRV_INFO = 243,
+          EMM_EM_INFO_END = EMM_EM_NVMSRV_INFO,
+
+          EMM_L4C_EMM_INFO = 244,
+
+          EM_EL2_OV_STATUS = 245,
+          EM_EL1_OV_STATUS = 246,
+          EM_QBM_STATUS = 247,
+          EM_UPCM_STATUS = 248,
+
+          /* EL1 */
+          EM_EL1_INFO = 249,
+
+          EM_CSR_STATUS_IND = 250,
+
+          RAC_EM_INFO = 251,
+
+          /* EL2 public status */
+          EM_EL2_PUB_STATUS = 252,
+
+          EMM_L4C_LAI_CHANGE_INFO = 253,
+
+          /*RATCM*/
+          RATCM_EM_23G_RAT_CHANGE_IND = 254, RATCM_EM_INFO_BEGIN = RATCM_EM_23G_RAT_CHANGE_IND,
+
+          EM_EL1_B3B39_INFO = 255,
+
+          RATCM_EM_INFO_END = RATCM_EM_INFO_BEGIN + 20,
+
+          /* L4C */
+          EM_L4C_RAT_CHANGE_IND = 275,
+
+          /* EMAC RACH */
+          EM_EMAC_RACH_TRIGGER = 276,
+          EM_EMAC_RACH_FINISH = 277,
+          EM_EMAC_MSG2_REPORT = 278,
+          EM_EMAC_MSG4_REPORT = 279,
+
+          /* EMAC 500MS */
+          EM_EMAC_OV_STATUS_500 = 280,
+
+          /* EMAC TIMER EXPIRE */
+          EM_EMAC_TIMER_EXPIRE = 281,
+
+          EM_L4C_MDMI_RAT_INFO_IND = 282,
+
+          /* EMAC CONFIG REPORT */
+          EM_EMAC_CONFIG_REPORT = 283,
+
+          /* MD EVENT INFO */
+          EM_L4C_MD_EVENT_INFO = 284,
+
+         /*EMAC RACH for Innowireless EM*/
+          EM_EMAC_RACH_SUCCESS = 285,
+          EM_EMAC_RACH_FAILURE = 286,
+
+          /* EMAC EMBMS */
+          EM_EMAC_EMBMS_REPORT = 287,
+
+          /* EMAC DL TBS REPORT */
+          EM_EMAC_DL_TBS_REPORT = 288,
+
+          /* EMM CSFB status */
+          EMM_L4C_CSFB_INFO = 289,
+
+          /* EL1 CIQ for ATT*/
+          EM_EL1_CIQ_RLF_STATUS_INFO        = 290, EM_EL1_CIQ_INFO_BEGIN = EM_EL1_CIQ_RLF_STATUS_INFO,
+          EM_EL1_CIQ_PUSCH_INFO             = 291,
+          EM_EL1_CIQ_INFO_END               = EM_EL1_CIQ_INFO_BEGIN + 10,
+
+          /* L4C EM to report ECSQ params */
+          EM_L4C_ECSQ_IND = 301,
+
+          /* IPCORE */
+          IPC_EM_UL_THROTTLE_STATUS = 326,
+
+          /*ERRC_EM_MODE, here is the start of errc em info definition of Range 2*/
+          ERRC_EM_SERV_IR_NEIGHBOR_INFO = 327, ERRC_EM_INFO_BEGIN_R2 = ERRC_EM_SERV_IR_NEIGHBOR_INFO,
+          ERRC_EM_IR_REDIR_EVENT = 328,
+          ERRC_EM_IRAT_MEAS_CFG = 329,
+          ERRC_EM_MOB_MEAS_CONFIG_INFO_IND = 330,
+          ERRC_EM_MOB_MEAS_REPORT_INFO_IND = 331,
+          ERRC_EM_MOB_MEAS_INTERRAT_C2K_INFO = 332,
+          ERRC_EM_LTE_RRC_STATE_IND = 333,
+          ERRC_EM_SERVING_INFO = 334,
+          ERRC_EM_PAGING_FAIL = 335,
+          ERRC_EM_RLF_EVENT = 336,
+          ERRC_EM_TIMER_EXPIRY_EVENT = 337,
+          ERRC_EM_HO_EVENT = 338,
+          ERRC_EM_ERRC_SYS_MIB_SIB_READEVENT_INFO = 339,
+          ERRC_EM_SRVCC_BSIC_INFO = 340,
+          ERRC_EM_MFROM_INFO = 341,
+          ERRC_EM_FEATURE_DETECTION = 342,
+          ERRC_EM_SEARCHING_STATE = 343,
+          ERRC_EM_CA_INFO = 344,
+          ERRC_EM_EUTRA_RRC_MESSAGE_S = 345,
+          ERRC_EM_EUTRA_RRC_MESSAGE_M = 346,
+          ERRC_EM_EUTRA_RRC_MESSAGE_L = 347,
+          ERRC_EM_LTE_BAND_TIME = 348,
+          ERRC_EM_REEST_BY_L2 = 349,
+          ERRC_EM_EL1_CONFIG_INFO = 350,
+          ERRC_EM_SRVCC_CELL_INFO = 351,
+          ERRC_EM_SRVCC_HO_FAIL_EVENT =352,
+          ERRC_EM_OOS_EVENT = 353,
+          ERRC_EM_CELL_BLACK_LIST_EVENT = 354,
+          ERRC_EM_INFO_END_R2 = ERRC_EM_CELL_BLACK_LIST_EVENT,
+          ERRC_EM_INFO_END_RESERVED = ERRC_EM_INFO_BEGIN_R2 + 30,
+
+          /* UPCM */
+          EM_UPCM_PS_TPUT_INFO = 358,
+
+          MM_EM_MTC_TIMER_INFO = 359,
+          MM_EM_LU_INFO = 360,
+          MM_EM_RAU_INFO = 361,
+
+          /* USIME capability */
+          USIME_EM_INFO_CAPABILITY = 362, USIME_EM_INFO_BEGIN = USIME_EM_INFO_CAPABILITY,
+          USIME_EM_INFO_END = USIME_EM_INFO_BEGIN + 30,
+
+          MM_EM_MT_CSFB_INFO = 393,
+          MM_EM_REG_REJ_INFO = 394,        // LU, Attach, RAU reject info
+          MM_EM_AUTH_REJ_INFO = 395,       // Auth reject info for MM/GMM
+          MM_EM_AS_FAIL_INFO = 396,        // AS fail info during REG proc
+
+          /* EL2 feature detection */
+          EM_EL2_FEATURE_DETECTION = 397,
+
+          MM_EM_CSFB_STATUS = 398,         // CSFB START /SUCCESSFUL /FAIL
+          MM_EM_MTCS_MTCSFB_STATUS = 399,  //MTCS MT CSFB FAILURES
+
+          /* FDD URR common Range 2, the range should be 400 ~ 599 */
+          /* FDD CSCE Range 2 */
+          FDD_CSCE_EM_INFO_BEGIN_R2 = 400, FDD_URR_EM_INFO_BEGIN_R2 = FDD_CSCE_EM_INFO_BEGIN_R2,
+          FDD_CSCE_EM_INFO_END_R2 = 449,
+          /* FDD RRCE Range 2 */
+          FDD_RRCE_EM_INFO_BEGIN_R2 = 450,
+          FDD_RRCE_EM_INFO_END_R2 = 499,
+          /* FDD MEME Range 2 */
+          EM_FDD_MEME_INFO_DCH_UMTS_CELL_INFO = 500, FDD_MEME_EM_INFO_BEGIN_R2 = EM_FDD_MEME_INFO_DCH_UMTS_CELL_INFO,
+          EM_FDD_MEME_INFO_DCH_GSM_CELL_INFO = 501,
+          EM_FDD_MEME_INFO_DCH_LTE_CELL_INFO = 502,
+          EM_FDD_MEME_INFO_DCH_H_SERVING_CELL_INFO = 503,
+          EM_FDD_MEME_INFO_DCH_3G_BLER_INFO = 504,
+          EM_FDD_MEME_INFO_FACH_LTE_CELL_INFO = 505,
+          EM_FDD_MEME_INFO_EVENT_TYPE_3_PARAMETER_INFO = 506,        // For NVIOT EM MeasCtrl E3x
+          EM_FDD_MEME_INFO_REPORT_INFO = 507,                        // For NVIOT EM MEasRpt E3x
+          FDD_MEME_EM_INFO_END_R2 = 549,
+
+          /* FDD SLCE Range 2 */
+          FDD_SLCE_EM_INFO_BEGIN_R2 = 550,
+          FDD_SLCE_EM_INFO_END_R2 = 559,
+
+          /* FDD SIBE Range 2 */
+          FDD_SIBE_EM_INFO_BEGIN_R2 = 560,
+          FDD_SIBE_EM_INFO_END_R2 = 569,
+
+          /* for other FDD URR modules, 569 ~ 599 */
+
+          FDD_URR_EM_INFO_END_R2 = 599,
+
+
+          /* VDM */
+          EM_VDM_CALL_INFO_IND = 601,
+
+          /* IMC */
+          IMC_EM_IPSEC_INFO_IND = 602, IMC_EM_INFO_BEGIN = IMC_EM_IPSEC_INFO_IND,
+          IMC_EM_IMC_INFO_IND = 603,
+          IMC_EM_BEARER_INFO_IND = 604,
+          IMC_EM_REG_INFO_IND = 605,
+          IMC_EM_SMS_INFO_IND = 606,
+          IMC_EM_CALL_INFO_IND = 607,
+          IMC_EM_CONF_INFO_IND = 608,
+          IMC_EM_SRVCC_INFO_IND = 609,
+          IMC_EM_PCSCF_INFO_IND = 610,
+          IMC_EM_MEDIA_INFO_IND = 611,
+          IMC_EM_CALL_DROP_IND = 613,
+          IMC_EM_INFO_END = IMC_EM_INFO_BEGIN + 20,
+
+          /* __EMM_EM_MODE__ Range 2, the range should be 625 ~ 629*/
+          EMM_EM_REG_EVENT_INFO = 625, EMM_EM_INFO_RANGE_2_BEGIN = EMM_EM_REG_EVENT_INFO,
+          EMM_EM_TIMER_EXPIRY_INFO = 626,
+          EMM_EM_EMM_STATE_INFO = 627,
+          EMM_EM_SEC_EVENT_INFO = 628,
+          EMM_EM_TIMERSRV_TIMER_START_INFO = 629,
+          EMM_EM_INFO_RANGE_2_END = EMM_EM_TIMERSRV_TIMER_START_INFO,
+
+          EM_SPEECH_INFO_BEGIN = 630,  EM_SPEECH_INFO_SPH_CODEC = EM_SPEECH_INFO_BEGIN,
+          EM_SPEECH_INFO_END = 649,
+
+          /* NWSEL */
+          NWSEL_EM_TIMER_INFO = 650,
+          NWSEL_EM_INFO_BEGIN = NWSEL_EM_TIMER_INFO,
+          NWSEL_EM_PLMN_LIST_REQ_INFO = 651,
+          NWSEL_EM_PLMN_LIST_CNF_INFO = 652,
+          NWSEL_EM_PLMN_SEARCH_REQ_INFO = 653,
+          NWSEL_EM_HPLMN_INFO_INFO = 654,
+          NWSEL_EM_OPLMN_INFO_INFO = 655,
+          NWSEL_EM_STATIC_APPLMN_INFO = 656,
+          NWSEL_EM_DYNAMIC_APPLMN_INFO = 657,
+          NWSEL_EM_EUTRAN_DISABLE_INFO = 658,
+          NWSEL_EM_INFO_END = NWSEL_EM_INFO_BEGIN+30,
+
+          /* Abnormal event for smart logging phase2 */
+          /* Naming format: EM_ABNORMAL_EVENT_(MOD)_(NAME) */
+          EM_ABNORMAL_EVENT_RAC_NO_SERVICE = 681,
+
+          /* LTECSR */
+          LTECSR_EM_RTP_CODEC = 682,
+          LTECSR_EM_RTP_PACKET_LOSS = 683,
+          LTECSR_EM_RTP_ONE_WAY_DELAY = 684,
+          LTECSR_EM_RTP_JITTER = 685,
+          LTECSR_EM_RTP_JITTER_BUFFER_DELAY = 686,
+          LTECSR_EM_RTP_OTA_MSG = 687,
+          LTECSR_EM_SESSION_STAT = 688,
+          LTECSR_EM_XMIT_PKT = 689,
+          LTECSR_EM_RECV_PKT = 690,
+          LTECSR_EM_XMIT_STAT = 691,
+          LTECSR_EM_RECV_STAT = 692,
+          LTECSR_EM_RTP_INFO = 693,
+          LTECSR_EM_RTCP_INFO = 694,
+          LTECSR_EM_RTP_EVENT = 695,
+
+          /* LPP 696 ~699 */
+          LPP_EM_MSG_STATUS_STATISTICS = 696,
+          LPP_EM_MSG_INFO = 697,
+          LPP_EM_INFO_END = 699,
+
+          /* TDD URR common Range 2, the range should be 700 ~ 899
+             before put TDD URR EM enum below, please make sure relative function already consider the enum range,
+             e.g. TDD_RRC_HandleEmUpdateReq() should cover enum 700 ~ 899. */
+          TDD_URR_EM_INFO_BEGIN_R2 = 700,
+          TDD_URR_EM_INFO_END_R2 = 749,
+
+          /* C2K: 750 ~ 899 */
+          EM_C2K_INFO_BEGIN = 750,
+
+          /* C2K EVDO L1 750~769 */
+          EM_EVL1_INFO_BEGIN = EM_C2K_INFO_BEGIN,
+          EM_EVL1_GENERAL_INFO = EM_EVL1_INFO_BEGIN,
+          EM_EVL1_TXAGC_POWER_INFO = 751,
+          EM_EVL1_CELL_SWITCH_INFO = 752,
+          EM_EVL1_RXAGC_INFO = 753,
+          EM_EVL1_AFC_INFO = 754,
+          EM_EVL1_MBP_SECTOR_INFO = 755,
+          EM_EVL1_FMP_FINGER_INFO = 756,
+          EM_EVL1_TIMING_TRACK_STATUS = 757,
+          EM_EVL1_SCH_STATUS = 758,
+          EM_EVL1_ACC_DATA_RATE_INFO = 759,
+          EM_EVL1_TRAFFIC_RRI_VALUE_INFO = 760,
+          EM_EVL1_FMP_SECTOR_INFO = 761,
+          EM_EVL1_SCH_PILOT_UPDATE_INFO = 762,
+          EM_EVL1_SCH_RESULT_INFO = 763,
+          EM_EVL1_INFO_END = EM_EVL1_INFO_BEGIN + 19,
+
+          /* XL1: 770 ~ 789 */
+          EM_XL1_INFO_BEGIN = 770,
+          EM_XL1_STATUS_INFO = EM_XL1_INFO_BEGIN,
+          EM_XL1_MEAS_INFO = 771,
+          EM_XL1_MAIN_RXAGC_INFO = 772,
+          EM_XL1_DIV_RXAGC_INFO = 773,
+          EM_XL1_RAKE_INFO = 774,
+          EM_XL1_CRC_INFO = 775,
+          EM_XL1_TX_PATH_INFO = 776,
+          EM_XL1_TX_AGC_INFO = 777,
+          EM_XL1_AFC_INFO = 778,
+          EM_XL1_MMAFC_INIT_FOE_INFO = 779,
+          EM_XL1_TAS_INFO = 780,
+          EM_XL1_TIMING_LOOP_INFO = 781,
+          EM_XL1_INFO_END = EM_XL1_INFO_BEGIN + 19,
+
+          /* HSC: 790 ~ 809 */
+          EM_C2K_HSC_INFO_BEGIN = 790,
+          EM_C2K_RTBA_CHANNEL_STATUS_INFO = EM_C2K_HSC_INFO_BEGIN,
+          EM_C2K_DO_SPAGE_STATE_INFO = 791,
+          EM_C2K_HSC_MPA_STATUS_INFO = 792,
+          EM_C2K_LL1A_STATE_MODE_INFO = 793,
+          EM_C2K_LL1A_STANDBY_GAP_INFO = 794,
+          EM_C2K_LL1A_ACTIVE_GAP_INFO = 795,
+          EM_C2K_HSC_INFO_END = EM_C2K_HSC_INFO_BEGIN + 19,
+
+          /* XL3: 810 ~ 824 */
+          EM_XL3_INFO_BEGIN = 810,
+          EM_XL3_CP_STATUS = EM_XL3_INFO_BEGIN,
+          EM_XL3_SLOTTED_MODE_INFO = 811,
+          EM_XL3_CP_EVENTS = 812,
+          EM_1XRTT_CALL_EVENTS = 813,
+          EM_C2K_RSVAS_INFO = 814,
+          EM_XL3_PAGING_INFO = 815,
+          EM_XL3_SET_INFO = 816,
+          EM_XL3_SYSTEM_SEARCH_INFO = 817,
+          EM_XL3_CALL_FAIL_REASON = 818,
+          EM_XL3_INFO_END = EM_XL3_INFO_BEGIN + 14,
+
+          /* EVL3: 825 ~ 839 */
+          EM_EVL3_INFO_BEGIN = 825,
+          EM_EVL3_STATE = EM_EVL3_INFO_BEGIN,
+          EM_EVL3_SERVING_CELL_INFO = 826,
+          EM_EVL3_SLOTTED_MODE_INFO = 827,
+          EM_EVL3_ACCESS_PROCEDURE_INFO = 828,
+          EM_EVL3_CP_EVENTS = 829,
+          EM_EVL3_SYSTEM_SEARCH_INFO = 830,
+          EM_EVL3_INFO_END = EM_EVL3_INFO_BEGIN + 14,
+
+          /* EVL2: 840~849 */
+          EM_EVL2_INFO_BEGIN = 840,
+          EM_EVL2_FWD_CHANNEL_INFO = EM_EVL2_INFO_BEGIN,
+          EM_EVL2_REV_TRAFFIC_INFO = 841,
+          EM_EVL2_ACCESS_STATE_INFO = 842,
+          EM_EVL2_RTM3_T2P_INFO = 843,
+          EM_EVL2_INFO_END = EM_EVL2_INFO_BEGIN + 9,
+
+          /* XL2 :850~859*/
+          EM_XL2_INFO_BEGIN = 850,
+          EM_XL2_REV_STATE  = EM_XL2_INFO_BEGIN,
+          EM_XL2_ACH_PROBE_INFO = 851,
+          EM_XL2_VOICE_RATE_INFO = 852,
+          EM_XL2_RLP_INFO = 853,
+          EM_XL2_PS_RATE_INFO = 854,
+          EM_XL2_SCH_ASSIGNED_RATE = 855,
+          EM_XL2_INFO_END = EM_XL2_INFO_BEGIN + 9,
+
+          /* C2K HLP: 860 ~ 879*/
+          EM_C2K_HLP_INFO_BEGIN = 860,
+          EM_C2K_HLP_TIMER_STATUS = EM_C2K_HLP_INFO_BEGIN,
+          EM_C2K_HLP_CAM_STATE = 861,
+          EM_C2K_HLP_NSPE_STATE = 862,
+          EM_C2K_HLP_PDN_STATUS = 863,
+          EM_C2K_HLP_PPPHA_STATUS = 864,
+          EM_C2K_HLP_PPP_STATUS = 865,
+          EM_C2K_HLP_RM_BUFQ_INFO = 866,
+          EM_C2K_HLP_UM_BUFQ_INFO = 867,
+          EM_C2K_HLP_PACKET_INFO = 868,
+          EM_C2K_HLP_ABNORMAL_EVENT_INFO = 869,
+          EM_C2K_HLP_INFO_END = EM_C2K_HLP_INFO_BEGIN + 19,
+
+          /* C2K_L4(CVAL): 880 ~ 899 */
+          EM_C2K_L4_INFO_BEGIN = 880,
+          EM_C2K_L4_RTT_RADIO_INFO = EM_C2K_L4_INFO_BEGIN,
+          EM_C2K_L4_RTT_INFO = 881,
+          EM_C2K_L4_RTT_SCH_INFO = 882,
+          EM_C2K_L4_RTT_STAT_INFO = 883,
+          EM_C2K_L4_RTT_SERVING_NEIGHBR_SET_INFO = 884,
+          EM_C2K_L4_EVDO_SERVING_INFO = 885,
+          EM_C2K_L4_EVDO_ACTIVE_SET_INFO = 886,
+          EM_C2K_L4_EVDO_CAND_SET_INFO = 887,
+          EM_C2K_L4_EVDO_NGHDR_SET_INFO = 888,
+          EM_C2K_L4_EVDO_FL_INFO = 889,
+          EM_C2K_L4_EVDO_RL_INFO = 890,
+          EM_C2K_L4_EVDO_STATE_INFO = 891,
+          EM_C2K_L4_SPRINT_XRTT_INFO = 892,
+          EM_C2K_L4_SPRINT_EVDO_INFO = 893,
+          EM_C2K_L4_INFO_END = 899,
+          EM_C2K_INFO_END = EM_C2K_L4_INFO_END,
+
+          /* GMSS: 900 ~ 919 */
+          GMSS_EM_INFO_BEGIN = 900,
+          GMSS_EM_WORLD_PHONE_INFO = GMSS_EM_INFO_BEGIN,
+          GMSS_EM_INFO_END = GMSS_EM_WORLD_PHONE_INFO+19,
+
+          /* EL1 MDMI for VzW*/
+          EM_EL1_STATUS_CSR_RPT_INFO        = 921, EM_EL1_MDMI_INFO_BEGIN = EM_EL1_STATUS_CSR_RPT_INFO,
+          EM_EL1_STATUS_SRV_MEAS_RPT_INFO   = 922,
+          EM_EL1_STATUS_PBCH_RPT_INFO       = 923,
+          EM_EL1_STATUS_PCFICH_RPT_INFO     = 924,
+          EM_EL1_STATUS_PDCCH_RPT_INFO      = 925,
+          EM_EL1_STATUS_PDSCH_RPT_INFO      = 926,
+          EM_EL1_STATUS_PHICH_RPT_INFO      = 927,
+          EM_EL1_STATUS_PMCH_RPT_INFO       = 928,
+          EM_EL1_STATUS_DCI_RPT_INFO        = 929,
+          EM_EL1_STATUS_PUCCH_RPT_INFO      = 930,
+          EM_EL1_STATUS_PUCCH_CSI_RPT_INFO  = 931,
+          EM_EL1_STATUS_PUSCH_RPT_INFO      = 932,
+          EM_EL1_STATUS_PUSCH_CSI_RPT_INFO  = 933,
+          EM_EL1_STATUS_SRS_RPT_INFO        = 934,
+          EM_EL1_STATUS_CELLTIME_RPT_INFO   = 935,
+          EM_EL1_STATUS_SR_CFG_INFO         = 936,
+          EM_EL1_STATUS_PRACH_INFO          = 937,
+          EM_EL1_STATUS_RACH_INFO           = 938,
+          EM_EL1_STATUS_PCH_INFO            = 939,
+          EM_EL1_STATUS_TA_INFO             = 940,
+          EM_EL1_STATUS_PHR_INFO            = 941,
+          EM_EL1_STATUS_DL_TPUT_INFO        = 942,
+          EM_EL1_STATUS_UL_TPUT_INFO        = 943,
+          EM_EL1_STATUS_CSR_INFO            = 944,
+          EM_EL1_MDMI_INFO_END              = EM_EL1_MDMI_INFO_BEGIN + 25,
+
+          /* EPDCP */
+          EM_EPDCP_DATA_INACTV_IND = 947,
+
+          /* GL1: 950 ~ 959 */
+          GL1_EM_TAS_INFO = 950,
+          GL1_EM_RXD_INFO = 951,
+
+          /* TDD L1 */
+          TDD_EM_L1_TAS_INFO = 960, TDD_EM_L1_INFO_BEGIN = TDD_EM_L1_TAS_INFO,
+          TDD_EM_L1_INFO_END = TDD_EM_L1_TAS_INFO + 4,
+
+          EMM_L4C_REJECT_INFO = 965,
+          EMM_L4C_TIMER_INFO = 966,
+          EMM_L4C_CALL_INFO = 967,
+
+          /*EL1*/
+          EM_EL1_STATUS_PDSCH_INFO = 970,
+
+          RAC_EM_NETWORK_TYPE_INFO = 971,
+
+          /* ERLC */
+          EM_ERLC_DATA_STALL = 972,
+
+          /* LTECSR Range 2, the range should be 975 ~ 979 */
+          LTECSR_EM_RTP_PERIODIC_RPT = 975,
+
+       /*================C2K_XCAL start====================*/
+         /* C2K XCAL related EMs, maximum 30 EMs supported. */
+         EM_C2K_XCAL_INFO_BEGIN = 980,
+         EM_C2K_XCAL_OTA_EVENT_INFO = EM_C2K_XCAL_INFO_BEGIN,
+         EM_C2K_XCAL_OTA_FDSCH_INFO = 981,
+         EM_C2K_XCAL_OTA_RDSCH_INFO = 982,
+         /* New C2K EMs should be added before  EM_C2K_XCAL_INFO_LAST, */
+         EM_C2K_XCAL_INFO_LAST = EM_C2K_XCAL_OTA_RDSCH_INFO,
+         EM_C2K_XCAL_INFO_END = EM_C2K_XCAL_INFO_BEGIN + 29,
+         /*================C2K_XCAL end====================*/
+
+          /* D2/DDM: 1016-1023 */
+          EM_DDM_INFO_BEGIN = 1016,
+          EM_DDM_W2LHO_EVENT_INFO = EM_DDM_INFO_BEGIN,
+          EM_DDM_L2WHO_EVENT_INFO = 1017,
+          EM_DDM_IP_INFO = 1020,
+          EM_DDM_LAST_ERROR_CODE_INFO = 1021,
+          EM_DDM_INFO_END = EM_DDM_INFO_BEGIN + 7, /* 1023 */
+
+   NUM_OF_EM_INFO,
+   INVALID_EM_INFO = 0x7fffffff //end tag force this enum 4 bytes, for alignment purpose. Don't remove
+   /*
+    * MP branches: please add "EM type id" in em_info_enum.h.
+    * Please remember to modify MD_COMMON\EM\em_info_enum.h for main TRUNK ex: LR11/LR12/UMOLY/UMOLYA
+    */
+} em_info_enum;
+
+typedef enum
+{
+    EM_TX_ANT_L_ANT    = 0, // L_ANT
+    EM_TX_ANT_U_ANT    = 1, // U_ANT
+    EM_TX_ANT_L_ANT_A  = 2, // L_ANT'
+    EM_TX_ANT_INVALID  = 0xFF
+} em_tx_ant_enum;
+
+
+typedef enum
+{
+    EM_TAS_VERSION_1_0     = 0,
+    EM_TAS_VERSION_2_0     = 1,
+    EM_TAS_VERSION_INVALID = 0xFF
+} em_tas_version_enum;
+
+
+typedef struct
+{
+    /* PWR info */
+    kal_int16  prach_tx_power_ave;
+    kal_int16  pucch_tx_power_ave;
+    kal_int16  pusch_tx_power_ave;
+    kal_int16  srs_tx_power_ave;
+
+    /* Tx report */
+    kal_int16  tm;
+    kal_int16  phr;
+    kal_int16  ta;
+
+    /* UL info */
+    kal_uint32 UL_Tput;
+    kal_int16  UL_Imcs;
+    kal_int16  UL_rb;
+    kal_int16  UL_block;
+    kal_int16  UL_bler;
+    kal_uint16 UL_retx_rate;
+
+   /* TAS info */
+    kal_int16   tx_ant;
+    kal_int8   UL_Mod;
+
+    /*RJIL requirement*/
+    kal_uint8   srs_bw_ave;
+    kal_int16   pucch_tx_power_ave_fmt[9]; //0:FMT1 1:FMT1A 2:FMT1B 3:FMT2 4:FMT2_extCP 5:FMT2A 6:FMT2B 7:FMT3 8:FMT1B_CS
+    kal_bool    hop_en;
+    kal_int8    puschPrb0;
+    kal_int8    puschPrb1;
+
+    /*Power scaling*/
+    kal_int16  pucch_tx_pwr;
+    kal_int16  pucch_tx_pwr_out;
+    kal_int16  pusch_tx_pwr;
+    kal_int16  pusch_tx_pwr_out;
+    kal_int16  ul_ca_pucch_tx_pwr_out;
+    kal_int16  ul_ca_pusch_tx_pwr_out;
+
+    /* TAS Info */
+    em_tx_ant_enum  tx_ant_type;
+    kal_int16       rsrp_l_ant;      // L_ANT: -255: disable, -140 ~ 18 (dBm)
+    kal_int16       rsrp_u_ant;      // U_ANT: -255: disable, -140 ~ 18 (dBm)
+    kal_int16       rsrp_l_ant_a;    // L_ANT' -255: disable, -140 ~ 18 (dBm)
+    kal_int16       tx_power;        // -50...33
+    kal_int16       el1_dat_scenario_index;
+
+    kal_uint16  ul_grant_cnt;
+    kal_uint16  cqi_req_cnt;
+    kal_int16   total_tx_power_ave;
+
+    /* PUCCH format statistics */
+    kal_uint16  pucch_f1_cnt;       // Standalone SR count
+    kal_uint16  pucch_f1a_cnt;      // Probable SR + 1 bit HARQ count
+    kal_uint16  pucch_f1b_cnt;      // Probable SR + 2 bit HARQ count
+    kal_uint16  pucch_f2_cnt;       // Standalone CSI over PUCCH count
+    kal_uint16  pucch_f2a_cnt;      // CSI + 1 bit HARQ count
+    kal_uint16  pucch_f2b_cnt;      // CSI + 2 bit HARQ count
+    kal_uint16  pucch_f2_ecp_cnt;   // CSI with extended CP
+    kal_uint16  pucch_f3_cnt;       // Format 3 count
+    kal_uint16  pucch_f1b_cs_cnt;   // Format 1b with CS count
+    kal_uint16  pucch_sr_cnt;       // Overall SR count
+
+    /* TITAN Info */
+    kal_int16   curr_fi;
+    kal_int16   curr_gi;
+    kal_int16   num_tpc_fi;
+    kal_int16   num_tpc_gi;
+    kal_int16   avg_ul_retx;
+
+    /* TAS Info */ // This is request by OPPO
+    kal_uint8   tas_status;         // TAS status: 0: disable/ 1: enable
+    kal_uint8   force_tx_ant;       // TAS force tx ant status: 0: disable/ 1: enable
+    kal_uint8   force_tx_idx;       // TAS force tx ann index: 0~7 according to antenna state
+
+    kal_int16   pcmax;
+} em_el1_ul_status_struct;
+
+typedef struct
+{
+    /* DL Qual indicator */
+    kal_int16  dl_rssi[2]; // -255: disable, -140 ~ 18 (dBm)
+    kal_int16  dl_rsrp[2]; // -255: disable, -140 ~ 18 (dBm)
+    kal_int16  dl_rsrq[2]; //
+    kal_int16  dl_sinr[2];
+    kal_int16  rsrp;
+    kal_int16  rsrq;
+    kal_int16  sinr;
+    kal_int16  rsSNR;
+
+    /* Rx report */
+    kal_int16  tm;
+    kal_int16  cqi_cw0;
+    kal_int16  cqi_cw1;
+    kal_int16  ri;
+
+    /* DL info */
+    kal_uint32 DL_Tput;
+    kal_uint32 DL_Tput_cw0;
+    kal_uint32 DL_Tput_cw1;
+    kal_int16  DL_Imcs;
+    kal_int16  DL_rb;
+    kal_int16  DL_block;
+    kal_int16  DL_bler;
+    kal_int8  DL_Mod0;
+    kal_int8  DL_Mod1;
+
+    /* MCH info */
+    kal_uint32 MCH_Tput;
+    kal_int16  MCH_block;
+    kal_int16  MCH_bler;
+
+    // PDSCH info
+    kal_uint16 pdsch_tc_rnti;
+    kal_uint16 pdsch_c_rnti;
+    kal_uint16 pdsch_sps_rnti;
+    kal_uint16 pdsch_avg_tbs;
+    kal_uint16 dl_grant_cnt;
+    kal_int8   dl_carrier_idx;
+    kal_int8   dl_mcs0;
+    kal_int8   dl_mcs1;
+    kal_int8   dl_pmi0;
+    kal_int8   dl_pmi1;  // Not used in 90 as well. Can be used to differentiate 1CW and 2CW scenario in future.
+
+    // PDCCH info
+    kal_int8   pdcch_dci;
+    kal_uint16 pdcch_agg_lv[4];
+    kal_uint16 pdcch_sps_rnti;
+    kal_uint16 pdcch_ra_rnti;
+    kal_uint16 tpc_pucch_rnti;
+    kal_uint16 tpc_pusch_rnti;
+    kal_uint16 pdcch_p_rnti;
+    kal_uint16 pdcch_si_rnti;
+
+    // For 93 KPI
+    kal_int16  kpi_DL_bler[2];
+
+    //For 91 Titan request
+    kal_int16  avg_dl_grant;
+    kal_int16  dl_sm_ratio;
+
+    /* MCH info */
+    kal_int16  MCH_sf_skip_cnt;
+
+    /* DL Qual indicator */
+    kal_int16  sir;
+
+    /* DL tb Number*/
+    kal_uint8   DL_TB;
+
+    /* rxpath_sum for RSRP/RSRQ/SNR as Mohamed' request */
+    kal_int16    rsrp_l1_rxpath_sum_dBm;     /*rx0 + rx1  RSRP dBm*/
+    kal_int16    rsrq_l1_rxpath_sum_dB;      /*rx0 + rx1  RSRQ dB*/
+    kal_int16    snr_l1_rxpath_sum_dB;       /*rx0 + rx1  SNR dB*/
+
+    // For LG
+    kal_int16  DL_bler_harq[15];
+    kal_int16  DL_rb_tb1;
+    kal_int16  DL_rb_tb2;
+
+    kal_uint8  rsrq_decimal;
+    // For AT&T
+    kal_uint16 DL_Mod_time[4];
+} em_el1_dl_status_struct;
+
+typedef struct
+{
+    /* TPC info */
+    kal_uint8 pa_mode[RPT_LTE_TX_CC_MAX];
+    kal_uint8 pa_idx[RPT_LTE_TX_CC_MAX];
+    kal_int16 pa_gain[RPT_LTE_TX_CC_MAX];
+    kal_uint8 temper_idx[RPT_LTE_TX_CC_MAX];  //temperature idx
+    kal_int16 temper_comp[RPT_LTE_TX_CC_MAX]; //temperature compensation power for PA
+    kal_int16 cmeas_rf[RPT_LTE_TX_CC_MAX];    //close loop compensation
+    kal_int16 ppa_dbm[RPT_LTE_TX_CC_MAX];     //DDPC report(antenna power)
+
+    /* RF info */
+    kal_int16 rf_gain_absolute[RPT_LTE_RX_CC_MAX][AGC_RX_ANT_NUM];
+
+    /* Power info */
+    kal_int16  mpr[RPT_LTE_TX_CC_MAX];
+    kal_int16  a_mpr[RPT_LTE_TX_CC_MAX];
+    kal_int16  p_cmax[RPT_LTE_TX_CC_MAX];
+    kal_int16 main_ant_sar[RPT_LTE_TX_CC_MAX]; // S(9,7)
+    kal_int16 div_ant_sar[RPT_LTE_TX_CC_MAX];  // S(9,7)
+
+    kal_int16 bb_gain[RPT_LTE_TX_CC_MAX];
+    kal_int16 rf_gain[RPT_LTE_TX_CC_MAX];     //PGA gain
+    kal_uint8 dc2dc_lvl[RPT_LTE_TX_CC_MAX];   //VP
+} em_el1_tpc_rf_status_struct;
+
+typedef struct
+{
+    /* DL info */
+    kal_int16  DL_block;
+    kal_int16  DL_nack_cnt;
+    kal_int16  DL_bler;
+    kal_uint8  fail_rate_ind;
+} em_el1_dl_pdsch_status_struct;
+
+typedef struct
+{
+    kal_uint16                         phyCellId;
+    kal_uint32                         earfcn;        /* [0..262143], 65535 is invalid to indicate ARFCN-ValueEUTRA-v9a0 present */
+    kal_int64                          rstd_microsec;
+}em_el1_mpc_otdoa_measured_nbr_cell_em_struct;
+
+
+typedef struct
+{
+    kal_uint8                           numMeasuredNbrCell;
+    em_el1_mpc_otdoa_measured_nbr_cell_em_struct  measuredNbrCell[EM_OTDOA_MAX_NBR_CELL_LIST_NUM_TOTAL];
+} em_el1_mpc_otdoa_struct;
+
+typedef struct
+{
+    /* cell info */
+    kal_uint8  band;
+    kal_uint8  ant_port;
+    kal_uint8  dl_bw;       // 100kHz
+    kal_uint8  ul_bw;       // 100kHz
+    kal_uint8  tdd_cfg;     // TDD: 0~6, FDD: 0xFF
+    kal_uint8  sp_cfg;      // TDD: 0~9, FDD: 0xFF
+    kal_uint8  tm;          // 0,1~9
+    kal_int8   ul_cc_idx;   //-1,0~(ul_cc_max-1)
+    kal_int16  pci;         // 0~503
+    EARFCN     earfcn;
+    EARFCN     ul_earfcn;
+    kal_uint16 dlFreq;      // 100kHz
+    kal_uint16 ulFreq;      // 100kHz
+    kal_bool   enable_64qam;
+    kal_uint8  ue_category;
+    kal_uint8  sr_period;   //ms
+    kal_uint8  main_ant_swap; // Main Antenna swap information
+    kal_uint8  rx_antenna_config;
+    kal_uint8  rx_div_status;
+    em_el1_mpc_otdoa_struct otdoa_info;
+    kal_uint8  dl_bw_rb;
+    kal_uint8  ul_bw_rb;
+    kal_uint32 dl_max_throughput;
+    kal_uint32 ul_max_throughput;
+} em_el1_cell_info_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum            em_info;
+    kal_uint8               dl_cc_count;
+    kal_uint8               ul_cc_count;
+    em_el1_cell_info_struct cell_info[RPT_LTE_RX_CC_MAX];
+    em_el1_dl_status_struct dl_info[RPT_LTE_RX_CC_MAX];
+    em_el1_ul_status_struct ul_info[RPT_LTE_TX_CC_MAX];
+    em_tas_version_enum     tas_version;
+    em_el1_tpc_rf_status_struct tpc_rf_info;
+} em_el1_status_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum            em_info;
+    em_el1_dl_pdsch_status_struct dl_info[RPT_LTE_RX_CC_MAX];
+} em_el1_status_pdsch_ind_struct;
+
+
+typedef enum
+{
+    EM_CRC_FAIL                 = 0,
+    EM_CRC_PASS                 = 1
+} em_dl_crc_enum;
+
+typedef enum
+{
+    EM_FDD                      = 0,
+    EM_TDD                      = 1
+} em_duplex_enum;
+
+typedef enum
+{
+    EM_COMMON_SPACE             = 0,
+    EM_UE_SPECIFIC_SPACE        = 1
+} em_dci_srch_space;
+
+typedef enum
+{
+    EM_PCC                      = 0,
+    EM_SCC1                     = 1,
+    EM_SCC2                     = 2
+} em_carrier_idx_enum;
+
+typedef enum
+{
+    EM_Bandwidth_1_4            = 1,
+    EM_Bandwidth_3              = 2,
+    EM_Bandwidth_5              = 3,
+    EM_Bandwidth_10             = 4,
+    EM_Bandwidth_15             = 5,
+    EM_Bandwidth_20             = 6
+} em_BandWidth_enum;
+
+typedef enum
+{
+    EM_CCE_AGG_LV1              = 0,
+    EM_CCE_AGG_LV2              = 1,
+    EM_CCE_AGG_LV4              = 2,
+    EM_CCE_AGG_LV8              = 3
+} em_cce_agg_lv_enum;
+
+typedef enum
+{
+    EM_PDCCH_FMT0               = 0,
+    EM_PDCCH_FMT1               = 1,
+    EM_PDCCH_FMT1A              = 2,
+    EM_PDCCH_FMT1B              = 3,
+    EM_PDCCH_FMT1C              = 4,
+    EM_PDCCH_FMT1D              = 5,
+    EM_PDCCH_FMT2               = 6,
+    EM_PDCCH_FMT2A              = 7,
+    EM_PDCCH_FMT2B              = 8,
+    EM_PDCCH_FMT2C              = 9,
+    EM_PDCCH_FMT2D              = 10,
+    EM_PDCCH_FMT3               = 11,
+    EM_PDCCH_FMT3A              = 12,
+    EM_PDCCH_FMT4               = 13,
+    EM_PDCCH_INVALID            = 255
+} em_pdcch_fmt_enum;
+
+typedef enum
+{
+    EM_DCI_FMT0                 = 0,
+    EM_DCI_FMT1                 = 1,
+    EM_DCI_FMT1A                = 2,
+    EM_DCI_FMT1B                = 3,
+    EM_DCI_FMT1C                = 4,
+    EM_DCI_FMT1D                = 5,
+    EM_DCI_FMT2                 = 6,
+    EM_DCI_FMT2A                = 7,
+    EM_DCI_FMT3                 = 8,
+    EM_DCI_FMT3A                = 9
+} em_dci_fmt_enum;
+
+typedef enum
+{
+    EM_dciSuc                   = 1,
+    EM_dciErr                   = 2
+} em_dci_stat_enum;
+
+typedef enum
+{
+    EM_PHICH_NACK               = 0,
+    EM_PHICH_ACK                = 1
+} em_phich_val_enum;
+
+typedef enum
+{
+    EM_PUCCH_FMT1               = 0,
+    EM_PUCCH_FMT1A              = 1,
+    EM_PUCCH_FMT1B              = 2,
+    EM_PUCCH_FMT2               = 3,
+    EM_PUCCH_FMT2A              = 4,
+    EM_PUCCH_FMT2B              = 5
+} em_pucch_fmt_enum;
+
+typedef enum
+{
+    EM_DL_TM_MODE_DISABLED      = 0,
+    EM_DL_TM_MODE_1             = 1,
+    EM_DL_TM_MODE_2             = 2,
+    EM_DL_TM_MODE_3             = 3,
+    EM_DL_TM_MODE_4             = 4,
+    EM_DL_TM_MODE_5             = 5,
+    EM_DL_TM_MODE_6             = 6,
+    EM_DL_TM_MODE_7             = 7,
+    EM_DL_TM_MODE_8             = 8,
+    EM_DL_TM_MODE_9             = 9,
+    EM_DL_TM_MODE_10            = 10,
+    EM_DL_TM_MODE_INVALID       = 255
+} em_dl_tm_mode_enum;
+
+typedef enum
+{
+    EM_mode10                   = 0,
+    EM_mode11                   = 1,
+    EM_mode20                   = 2,
+    EM_mode21                   = 3
+} em_pucch_rpt_mode_enum;
+
+typedef enum
+{
+    EM_subBandCqiFeedback       = 0,
+    EM_wideBandCqiPmiFeedback   = 1,
+    EM_riFeedback               = 2,
+    EM_widebandCqiFeedback      = 3
+} em_pucch_rpt_type_enum;
+
+typedef enum
+{
+    EM_UL_BPSK                  = 0,
+    EM_UL_QPSK                  = 1,
+    EM_UL_QAM16                 = 2,
+    EM_UL_QAM64                 = 3
+} em_pusch_mcs_enum;
+
+typedef enum
+{
+    EM_FREQ_HOP_DISABLED        = 0,
+    EM_FREQ_HOP_INTER_SF        = 1,
+    EM_FREQ_HOP_INTRA_INTER_SF  = 2,
+    EM_FREQ_HOP_INVALID         = 255
+} em_pusch_freq_hop_enum;
+
+typedef enum
+{
+    EM_semiPersistent           = 0,
+    EM_dynamic                  = 1,
+    EM_rachMsg3                 = 2
+} em_pusch_type_enum;
+
+typedef enum
+{
+    EM_modeAperiodicRm12        = 0,
+    EM_modeAperiodicRm20        = 1,
+    EM_modeAperiodicRm22        = 2,
+    EM_modeAperiodicRm30        = 3,
+    EM_modeAperiodicRm31        = 4
+} em_pusch_rpt_mode_enum;
+
+typedef enum
+{
+    EM_NoSrs                    = 0,
+    EM_UpPtsSymbol0             = 1,
+    EM_UpPtsSymbol1             = 2,
+    EM_BothUpPtsSymbols         = 3
+} em_srs_uppts_enum;
+
+typedef enum
+{
+    EM_SRS_Type0                = 0,
+    EM_SRS_Type1Dci0            = 1,
+    EM_SRS_Type1Dci1A2B2C       = 2,
+    EM_SRS_Type1Dci4            = 3
+} em_srs_trig_enum;
+
+typedef enum
+{
+    EM_CYCLE_320                = 0,
+    EM_CYCLE_640                = 1,
+    EM_CYCLE_1280               = 2,
+    EM_CYCLE_2560               = 3
+} em_paging_cyc_enum;
+
+typedef enum
+{
+    EM_fourT                    = 0,
+    EM_twoT                     = 1,
+    EM_oneT                     = 2,
+    EM_one2T                    = 3,
+    EM_one4T                    = 4,
+    EM_one8T                    = 5,
+    EM_one16T                   = 6,
+    EM_one32T                   = 7
+} em_drx_nb_enum;
+
+typedef enum
+{
+    EM_T310_STOP                = 0,
+    EM_T310_START               = 1,
+    EM_T310_EXPIRE              = 2,
+    EM_T310_INVALID             = 255
+} em_t310_status_enum;
+
+
+
+typedef enum
+{
+    EM_DL_QPSK                  = 0,
+    EM_DL_QAM16                 = 1,
+    EM_DL_QAM64                 = 2,
+    EM_DL_QAM256                = 3,
+    EM_DL_INVALID               = 255
+} em_dl_mod_enum;
+
+
+typedef struct
+{
+    kal_bool                        tbEn;
+    kal_uint8                       Imcs;
+    em_dl_mod_enum                  mcs;
+    kal_uint8                       rv;
+    kal_uint8                       ndi;
+    kal_uint8                       tbIndex;
+    kal_uint32                      tbsize;
+    kal_uint8                       dupPacket;
+    kal_bool                        harqComb;
+    //pdsch 3
+    em_dl_crc_enum                  tbCrc;
+    kal_uint16                      cbCrc;
+    kal_uint8                       cw_idx;
+    kal_uint8                       reRxNum;                        // 1~8
+    kal_uint16                      cbSizePlus;                     // 0~6168
+    kal_uint8                       numCbPlus;                      // 0~13
+    kal_uint8                       turboDecMaxIterNum;
+    kal_uint8                       turboDecIterNum;
+    kal_bool                        earlyEndAlgm;
+} em_PdschTb_struct;
+
+typedef struct
+{
+    kal_uint8                       numRBs;      //pdsch 1,2
+    kal_uint8                       numLayers;   //pdsch 2
+    kal_uint8                       numTBs;      //pdsch 2
+    kal_uint8                       harqId;      //pdsch 1,3
+    em_dl_rnti_enum                 rntiType;
+    kal_uint16                      rntiValue;
+    em_PdschTb_struct               PdschTb[2];
+} em_PdschRlt_struct;
+
+typedef struct
+{
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+    kal_uint16                      pci;
+
+    kal_uint8                       cc_idx;//pdsch 3
+    kal_uint8                       ueCat;//pdsch 3
+    kal_uint8                       tranMode;//pdsch 3
+    kal_uint8                       mimoRi;                     // num of tb
+    kal_uint8                       pmchId;                     // 0~255
+    kal_uint8                       areaId;                     // 0~255
+    em_PdschRlt_struct              PdschRlt[5];
+} el1_em_PdschRpt_struct;
+
+typedef struct
+{
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+    kal_uint16                      pci;
+    kal_uint8                       cc_idx;
+    kal_uint8                       ulDlCfg;                        // 0~6:TDD
+    //ltePhyPdcch 1
+    em_dl_rnti_enum                 rntiType[9];
+    em_cce_agg_lv_enum              cceAggLv[9];
+    kal_bool                        newDl[9];
+    em_dci_srch_space               srchSpace[9];                   // 0: common, 1: ue-specific
+    kal_uint16                      payloadSize[9];                 // pi/si/ra/c,tc,sps
+    kal_uint8                       spsType;                        // 1:rel, 2:acv, 3:cfg, 4:retx
+    //ltePhyPdcch 2
+    kal_uint8                       numDlTbs[9];                    // 0~3, number of DL TBs
+    //ltePhyPdcch 3
+    em_pdcch_fmt_enum               dciFormat[9];
+    kal_uint8                       strtCce[9];                     // 0~86
+    kal_bool                        dciStatus[9];
+} el1_em_PdcchRpt_struct;
+
+typedef struct
+{
+    //ltePhyPhich 1, 3
+    kal_bool                        phichEn;
+    em_phich_val_enum               phichRlt;
+    //ltePhyPhich 3
+    kal_uint8                       spreadCode;                     // 0~7
+    kal_uint8                       groupNum;                       // 0~31
+} em_PhichRlt_struct;
+
+typedef struct
+{
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+    kal_uint16                      pci;
+    em_carrier_idx_enum             cc_idx;
+    kal_uint8                       ulDlCfg;                        //0~6:TDD
+    em_PhichRlt_struct              phichRlt0;
+    em_PhichRlt_struct              phichRlt1;
+} el1_em_PhichRpt_struct;
+
+typedef struct
+{
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+    kal_uint16                      pci;
+    em_pdcch_fmt_enum               dciFormat[9];
+    em_pucch_fmt_enum               txFormat;
+    kal_uint8                       numAck;                         //0~2, number of Harq bits
+    kal_bool                        csiEn[RPT_LTE_RX_CC_MAX];
+    kal_uint8                       numCqi[RPT_LTE_RX_CC_MAX];
+    kal_int8                        pucchTpc[9];
+    kal_int16                       gi;
+    kal_uint8                       digitalGain;                    //0~255, PUCCH digital amplitude gain in dB
+    kal_int8                        txPower;
+    kal_int8                        ActualTxPower;
+    kal_uint8                       pathLoss;
+    kal_uint8                       startRbSlot0;                   //0~110
+    kal_uint8                       startRbSlot1;                   //0~110
+    kal_uint8                       dmrsSeqSlot0;                   //0~29
+    kal_uint8                       dmrsSeqSlot1;                   //0~29
+} em_el1_PucchRpt_struct;
+
+typedef struct
+{
+    kal_bool                        csiEn;
+    kal_uint8                       cc_idx;
+    em_dl_tm_mode_enum              csiTxMode;
+    em_pucch_rpt_mode_enum          csiRptMode;
+    em_pucch_rpt_type_enum          csiRptType;
+    //kal_uint8                       numCqi;
+    kal_uint8                       bpSize;                         //0~4
+    kal_uint8                       bpIndex;                        //0~4
+    kal_uint8                       sbNum;
+    kal_uint8                       ri;
+    kal_uint8                       cqiCw0;
+    kal_uint8                       cqiCw1;
+    kal_uint8                       wbPmi;
+} em_pucchCsiRpt_struct;
+
+typedef struct
+{
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+
+    em_pucchCsiRpt_struct           csiRpt[RPT_LTE_RX_CC_MAX];
+} em_el1_PucchCsiRpt_struct;
+
+typedef struct
+{
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+    kal_uint16                      pci;
+    em_pdcch_fmt_enum               dciFormat;                      // DCI format of the decoded PDCCH
+    kal_int8                        puschTpc;
+    em_pusch_type_enum              puschType;
+    kal_int16                       fi;
+    kal_uint8                       digitalGain;                    //0~255, PUSCH digital amplitude gain in dB
+    kal_int8                        txPower;
+    kal_int8                        ActualTxPower;
+    kal_uint8                       pathLoss;
+    kal_uint8                       rbNum;
+    em_pusch_mcs_enum               ModOrd;
+    kal_uint8                       harqId;
+    kal_uint16                      tbSize;
+    kal_uint8                       retxIndex;                      //1~8, HARQ retransmission number
+    em_pusch_freq_hop_enum          freqHop;
+    //kal_bool                        ackExists;
+    kal_uint8                       numAck;                         //0~7, length of ACK NACK bit
+    //kal_bool                        cqiExists[RPT_LTE_RX_CC_MAX];
+    kal_bool                        csiEn[RPT_LTE_RX_CC_MAX];
+    kal_uint8                       numCqi[RPT_LTE_RX_CC_MAX];      //0~66, length of CQI bit
+    //kal_bool                        riExists[RPT_LTE_RX_CC_MAX];
+    kal_uint8                       numRi[RPT_LTE_RX_CC_MAX];       //0~3, length of RI bit
+    kal_uint8                       startRbSlot0;                   //0~110
+    kal_uint8                       startRbSlot1;                   //0~110
+    kal_uint8                       dmrsSeqSlot0;                   //0~29
+    kal_uint8                       dmrsSeqSlot1;                   //0~29
+} em_el1_PuschRpt_struct;
+
+typedef struct
+{
+    kal_bool                        csiEn;
+    kal_uint8                       cc_idx;
+    em_dl_tm_mode_enum              csiTxMode;
+    em_pusch_rpt_mode_enum          csiRptMode;
+    kal_uint8                       sbNum;
+    kal_uint8                       ri;
+    kal_uint8                       wbCqiCw0;
+    kal_uint8                       wbCqiCw1;
+    kal_uint8                       sizeM;
+    kal_uint8                       snglWbPmi;
+    kal_uint8                       snglMbPmi;
+    kal_uint8                       sbCqiCw0[13];
+    kal_uint8                       sbCqiCw1[13];
+    kal_uint8                       mSbCqiCw0;
+    kal_uint8                       mSbCqiCw1;
+    kal_uint8                       sbSize;
+} em_puschCsiRpt_struct;
+
+typedef struct
+{
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+
+    em_puschCsiRpt_struct           csiRpt[RPT_LTE_RX_CC_MAX];
+} em_el1_PuschCsiRpt_struct;
+
+typedef struct
+{
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+    kal_uint16                      pci;
+    em_carrier_idx_enum             cc_idx;
+    kal_uint8                       cfi;
+} em_el1_PcfichRpt_struct;
+
+typedef struct
+{
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+    kal_uint16                      pci;
+    em_carrier_idx_enum             cc_idx;
+    kal_uint8                       pmchId;
+    kal_uint8                       areaId;
+    //kal_uint8                       numOfRB;
+    kal_uint8                       numRBs;
+    kal_uint8                       numLayers;
+    kal_uint8                       harqId;
+    kal_uint8                       rv;
+    kal_uint8                       ndi;
+    em_dl_crc_enum                  crcRlt;
+    em_dl_rnti_enum                 rntiType;
+    kal_uint8                       tbIndex;
+    kal_uint16                      tbSize;                         // bytes
+    kal_uint8                       Imcs;                           // 0~31
+    //kal_uint8                       numRBs;                         // 0~255 // TBD
+} em_el1_PmchRpt_struct;
+
+typedef struct
+{
+    kal_uint16                      strtSFN;
+    kal_uint8                       strtSubframe;
+    kal_uint32                      strtDlFrameTimeOffst;           // 0~307200, Ts units
+    kal_uint32                      strtUlFrameTimeOffst;           // 0~307200, Ts units
+    kal_uint32                      strtUlTimeAdv;                  // 0~307200, Ts units
+
+    kal_int16                       dlFrameTimeChng;                // -512~511
+    kal_int8                        ulFrameTimeChng;                //  -16~15
+    kal_int8                        timeAdvChng;                    // -128~127
+} em_el1_CellTime_struct;
+
+typedef struct
+{
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+    kal_uint16                      pci;
+    kal_int16                       rsrp;                           // -180~-30
+    kal_int16                       rsrp0;
+    kal_int16                       rsrp1;
+    kal_int16                       rsrq;                           //  -30~ 10
+    kal_int16                       rsrq0;
+    kal_int16                       rsrq1;
+    kal_int16                       rssi;                           // -110~-10
+    kal_int16                       rssi0;
+    kal_int16                       rssi1;
+    kal_int16                       sinr;                           //  -20~ 30
+    kal_int16                       sinr0;
+    kal_int16                       sinr1;
+    EARFCN                          earfcn;
+    kal_uint8                       priority;                       // 0~7, The priority of the layer that the cell resides on
+    kal_bool                        isIdleMode;
+    em_BandWidth_enum               Bandwidth;
+    em_carrier_idx_enum             CarrierType;
+} em_el1_SrvMeasRpt_struct;
+
+#if 0
+typedef struct
+{
+    kal_uint16                      sysFrameNumber;
+    kal_uint8                       subFrameNumber;
+    kal_uint8                       TranMode;
+} em_el1_TranMode_struct;
+
+typedef struct
+{
+    kal_uint16                      sysFrameNumber;
+    kal_uint8                       subFrameNumber;
+    kal_uint8                       mcs;                            // 0~31
+} em_el1_McsValue_struct;
+#endif
+
+
+typedef struct
+{
+    kal_bool                        ueSrsEn;
+    kal_bool                        cellSrsEn;
+    kal_uint8                       strtRb;
+    kal_uint8                       numRb;
+    kal_uint16                      zcRoot;                         // 1~1151
+    em_srs_uppts_enum               upPtsType;
+    //em_srs_trig_enum                srsTrigType;
+} em_srsTxParam_struct;
+
+typedef struct
+{
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+    kal_uint16                      pci;
+    em_carrier_idx_enum             carrierType;
+    em_duplex_enum                  duplexMode[RPT_LTE_RX_CC_MAX];
+    //ltePhyMeasurements 15
+    kal_int8                        srsTxPower;
+    kal_int16                       fi;
+    kal_uint8                       pathLoss;
+    kal_uint8                       srsTxBw;
+    kal_int8                        srsActualTxPower;
+    //ltePhyMeasurements 16
+    em_srs_trig_enum                srsTrigType;
+    kal_uint8                       cycShift;
+    kal_int8                        srsPwrOffst;                 // 0:p-srs,    1:a-srs
+    em_srsTxParam_struct            srsTxParam[2];                  // 0:symbol 1, 1:symbol 2
+} em_el1_SrsRpt_struct;
+
+typedef struct
+{
+    kal_uint8                       mcsIndex;
+    kal_uint8                       cqiRequest;
+    kal_uint8                       startRB[2];
+    kal_uint8                       numRB[2];
+    kal_uint8                       tbSizeIndex;
+    kal_uint8                       modType;
+    kal_bool                        freqHop;                        // 0: disable, 1: enable
+    kal_uint8                       ndi;
+    kal_uint8                       rv;
+    kal_int8                        tpcCmd;
+    kal_uint8                       dmrsCycShift;
+    kal_uint8                       timeToTx;
+} ul_grant_struct;
+
+typedef struct
+{
+    kal_uint16                      pci;
+    em_pdcch_fmt_enum               dlAssgnFmt[7];
+    kal_uint8                       numAck[7];                      // 0~2
+    kal_int8                        tpcCmd[7];
+} dl_assgn_struct;
+
+typedef struct
+{
+    em_duplex_enum                  duplexMode[RPT_LTE_RX_CC_MAX];
+
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+
+    kal_bool                        pdcchOrderVld[RPT_LTE_TX_CC_MAX];
+
+    kal_bool                        ulGrantVld[RPT_LTE_TX_CC_MAX];
+    ul_grant_struct                 ulGrantInfo[RPT_LTE_TX_CC_MAX];
+
+    kal_bool                        tpcVld;
+    em_pdcch_fmt_enum               tpcFmt[2];                      // 0: tpc-pucch, 1: tpc-pusch
+
+    kal_bool                        dlAssgnVld[RPT_LTE_RX_CC_MAX];                  // 2cc
+    dl_assgn_struct                 dlAssgnInfo[RPT_LTE_RX_CC_MAX];                 // 2/tc/spsc -rnti
+} em_el1_DciRpt_struct;
+
+typedef struct
+{
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+    //PSS result
+    kal_int16                       pssQualLev;
+    kal_uint16                      pssPeakPos;                     // 0~10000
+    kal_uint8                       pssIndex;                       // 0~2
+    //SSS result
+    kal_uint16                      pci;
+    kal_int16                       sssQualLev;
+    kal_uint16                      sssFrameBoundary;
+    kal_uint16                      sssCp;
+} em_el1_CsrRpt_struct;
+
+typedef struct
+{
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+    kal_uint16                      pci;
+    EARFCN                          earfcn;
+    kal_uint8                       dlBw;
+    kal_uint16                      payloadSize;
+    kal_uint16                      decSFN;
+    em_dl_crc_enum                  crcRlt;
+    kal_uint8                       numAnt;
+    kal_uint8                       txAntCfg;
+    kal_uint16                      sfnOffst;
+    kal_uint16                      freqOffst;                      // TBD
+    kal_uint16                      tx0Rx0Cir;                      // TBD
+} em_el1_PbchRpt_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    //lteMacKpis 7
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+    kal_uint8                       srPeriod;
+} em_el1_status_sr_cfg_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    //ltePhyPrach 1
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+    kal_int16                       rachTxPwr;
+    kal_uint16                      zadOffSeq;                      //0~837, ZadOFF Sequence Number
+    kal_uint8                       prachCfg;
+    kal_uint8                       preambleFmt;
+    em_duplex_enum                  duplexType;
+    kal_uint8                       maxTxMsg3;
+    kal_uint8                       rarWinSize;
+    kal_bool                        rachRlt;
+} em_el1_status_prach_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    //ltePhyMeasurements 5
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+    kal_uint32                      dlTputVal;
+    kal_uint32                      dlTputCw0;
+    kal_uint32                      dlTputCw1;
+} em_el1_status_dl_tput_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    //ltePhyMeasurements 6
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+    kal_uint32                      ulTputVal;
+} em_el1_status_ul_tput_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    el1_em_PdcchRpt_struct          PdcchRpt[LTE_MAX_DATA_BUF];
+    kal_uint16                      PdcchRpt_num;
+    kal_uint16                      Pdcch_num;
+} em_el1_status_pdcch_rpt_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    //ltePhyPdsch 1
+    el1_em_PdschRpt_struct          PdschRpt[LTE_MAX_DATA_BUF];
+    kal_uint16                      PdschRpt_num;
+    kal_uint16                      Pdsch_num;
+} em_el1_status_pdsch_rpt_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    //ltePhyPhich 1,3
+    el1_em_PhichRpt_struct          PhichRpt[LTE_MAX_DATA_BUF];
+    kal_uint16                      PhichRpt_num;
+} em_el1_status_phich_rpt_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    //ltePhyMeasurements 10, 11
+    em_el1_CsrRpt_struct            CsrRlt[LTE_MAX_DATA_BUF];
+    kal_uint8                       CsrRlt_num;
+} em_el1_status_csr_rpt_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    em_info;
+
+    //Carrier search information
+    EARFCN                          csr_earfcn;
+    kal_uint8                       csr_band;
+} em_el1_status_csr_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    //ltePhyMeasurements 1
+    em_el1_SrvMeasRpt_struct        SrvMeasRpt[LTE_MAX_DATA_BUF];
+    kal_int8                        SrvMeasRpt_num;
+} em_el1_status_srv_meas_rpt_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    //ltePhyPucch 1,3
+    em_el1_PucchRpt_struct          PucchRpt[LTE_MAX_DATA_BUF];
+    kal_uint8                       PucchRpt_num;
+} em_el1_status_pucch_rpt_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    //ltePhyPucch 4
+    em_el1_PucchCsiRpt_struct       PucchCsiRpt[LTE_MAX_DATA_BUF];
+    kal_uint8                       PucchCsiRpt_num;
+} em_el1_status_pucch_csi_rpt_ind_struct;
+
+
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    //ltePhyPusch 1,3
+    em_el1_PuschRpt_struct          PuschRpt[LTE_MAX_DATA_BUF];
+    kal_uint8                       PuschRpt_num;
+} em_el1_status_pusch_rpt_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    //ltePhyPusch 4
+    em_el1_PuschCsiRpt_struct       PuschCsiRpt[LTE_MAX_DATA_BUF];
+    kal_uint8                       PuschCsiRpt_num;
+} em_el1_status_pusch_csi_rpt_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    //ltePhyMeasurements 17
+    em_el1_DciRpt_struct            DciRpt[LTE_MAX_DATA_BUF];
+    kal_uint8                       DciRpt_num;
+} em_el1_status_dci_rpt_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    //ltePhyPmch 3
+    em_el1_PmchRpt_struct           PmchRpt[LTE_MAX_DATA_BUF];
+    kal_uint8                       PmchRpt_num;
+} em_el1_status_pmch_rpt_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    //ltePhyMeasurements 15, 16
+    em_el1_SrsRpt_struct            SrsRpt[LTE_MAX_DATA_BUF];
+    kal_uint8                       SrsRpt_num;
+} em_el1_status_srs_rpt_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    //ltePhyDebug 1
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+    kal_uint32                      strtDlFrmeTimeOffst;            // 0~307200, Ts units
+    kal_uint32                      strtUlFrameTimeOffst;           // 0~307200, Ts units
+    kal_uint32                      strtUlTimeAdv;                  // 0~307200, Ts units
+    kal_int16                       dlFrameTimeChng;                // -512~511
+    kal_int16                       ulFrameTimeChng;                //  -16~15
+    kal_int8                        timeAdvChng;                    // -128~127
+} em_el1_status_celltime_rpt_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    //ltePhyPcfich 3
+    em_el1_PcfichRpt_struct         PcfichRpt[LTE_MAX_DATA_BUF];
+    kal_uint8                       PcfichRpt_num;
+} em_el1_status_pcfich_rpt_ind_struct;
+
+typedef struct
+{
+    kal_uint8                       sequence;                       //    0~63, Preamble sequence index
+    kal_int8                        prachTxPower;                   // -112~23, PRACH tx power
+    kal_uint8                       duplexMode;
+} el1_em_msg1_rpt_struct;
+
+typedef struct
+{
+    kal_uint8                       mcs;
+    kal_uint8                       modType;
+    kal_uint8                       startRb;
+    kal_uint8                       numRb;
+    kal_uint8                       tbSizeIndex;
+} el1_em_msg3_rpt_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+
+    kal_bool                        msg1_valid;
+    el1_em_msg1_rpt_struct          msg1_rpt;
+    kal_bool                        msg3_valid;
+    el1_em_msg3_rpt_struct          msg3_rpt;
+} em_el1_status_rach_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    em_el1_PbchRpt_struct           PbchRpt[LTE_MAX_DATA_BUF];
+    kal_uint8                       PbchRpt_num;
+} em_el1_status_pbch_rpt_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    EARFCN                          earfcn;
+    kal_uint16                      pci;
+    em_paging_cyc_enum              pagCyc;
+    em_drx_nb_enum                  nb;
+    kal_uint16                      ueId;                           // IMSI mod 1024
+    kal_uint8                       drxFrameNumOffst;
+    kal_uint8                       drxSubframeNum;
+} em_el1_status_pch_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    //ltePhyMeasurements 7
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+    kal_int16                       ta_value;
+} em_el1_status_ta_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    mdmi_info;
+
+    //ltePhyMeasurements 8
+    kal_uint16                      SFN;
+    kal_uint8                       subframe;
+    kal_int8                        phr_value;                      // -23~40
+} em_el1_status_phr_ind_struct;
+
+// CIQ
+typedef struct
+{
+    kal_bool                        wb_rpt_valid;
+    kal_uint8                       sb_rpt_num;
+    kal_uint16                      wb_cqi_dist[16];
+    kal_uint16                      sb_cqi_dist[4][16];
+    kal_uint16                      ri_dist[5];
+    kal_uint16                      pmi_dist[16];
+} el1_em_csi_rpt_struct;
+
+
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    ciq_info;
+    kal_uint32              trig_time;
+    //LT13 - E-UTRA Radio Link Sync Status
+    em_t310_status_enum             t310_status;
+} em_el1_ciq_rlf_status_ind_struct;
+
+typedef struct
+{
+    LOCAL_PARA_HDR
+    em_info_enum                    ciq_info;
+    kal_uint32              trig_time;
+
+    //LT12 - E-UTRA PUSCH Transmission Status
+    kal_int16                       total_pwr;
+    kal_int16                       perRB_pwr;
+    kal_uint16                      count_pwr;
+    //CSI info
+    //TBD
+    el1_em_csi_rpt_struct       csi_rpt;
+} em_el1_ciq_pusch_ind_struct;
+
+
+
+
+#endif /* _EM_EL1_PUBLIC_STRUCT_H */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_hspa.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_hspa.cpp
new file mode 100644
index 0000000..3e9638a
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_hspa.cpp
@@ -0,0 +1,182 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include <vendor-ril/telephony/ril.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <cutils/jstring.h>
+#include <log/log.h>
+#include <unistd.h>
+#include <math.h>
+#include  "common.h"
+#include "em/em.h"
+#include "Radio_capability_switch_util.h"
+#include "WorldPhoneUtil.h"
+#include "../util/AtLine.h"
+#if EM_MODE_SUPPORT
+
+#undef LOG_TAG
+#define LOG_TAG "EM_HSPA"
+
+char *hspa_info_mode_array_td[] = {
+    "HSDPA off\n",
+    "HSDPA on\nHSUPA off\n",
+    "HSDPA on\nHSUPA on\n",
+    "HSDPA on\nHSUPA on\n",
+};
+
+char *hspa_info_mode_array_fd[] = {
+    "HSDPA off\n",
+    "HSDPA on\nHSUPA off\n",
+    "HSDPA on\nHSUPA on\nHSPA+ off\n",
+    "HSDPA on\nHSUPA on\nHSPA+ on\n",
+};
+
+const int EVENT_HSPA_INFO = 1;
+//const int EVENT_DC_HSPA_INFO = 2;
+const int EVENT_SET_HSPA = 3;
+#define QUERY_CMD "AT+EHSM?"
+#define SET_CMD "AT+EHSM="
+#define RESPONSE_CMD "+EHSM:"
+int mCurrentEmhspaFlag = 0;
+int hspamode = 0;
+
+void  sendATCommand_ehspa(const char *cmd,int msg)
+{
+    mCurrentEmhspaFlag = msg;
+    emSendATCommand(cmd, Radio_capability_switch_util::get_main_capability_phone_id());
+    return ;
+}
+
+void showHspa(int mode) {
+    RLOGD("showHspa, mode=%d", mode);
+    if (mode < 0 || mode >= 4) {
+        RLOGD("Modem return invalid mode: %d", mode);
+        android::emResultNotify(RET_STRING_HSPA_FAIL);
+        return;
+    }
+    if (WorldPhoneUtil::getModemType() == WorldPhoneUtil::MODEM_TD) {
+        android::emResultNotify(hspa_info_mode_array_td[mode]);
+    } else {
+        android::emResultNotify(hspa_info_mode_array_fd[mode]);
+    }
+}
+
+void parseHspaAtCmd(const char* line) {
+    if (strstr(line, RESPONSE_CMD) != NULL) {
+        AtLine* atLine = new AtLine(line, NULL);
+        int err;
+        atLine->atTokStart(&err);
+        if (err < 0) {
+            RLOGW("this is not a valid response string");
+            return;
+        }
+        int mode = atLine->atTokNextint(&err);
+        if (err < 0) {
+            RLOGW("parse rat fail");
+            return;
+        }
+        showHspa(mode);
+        delete atLine;
+    }
+}
+
+void emHspaAtCmdHandle(char*response, int responselen) {
+    switch (mCurrentEmhspaFlag) {
+        case EVENT_HSPA_INFO:
+        {
+            //parse hspa mode.
+            if ((responselen > 0) && (response != NULL)) {
+                RLOGD("EVENT_HSPA_INFO response: %s\n",response);
+                parseHspaAtCmd(response);
+            }
+            else {
+                android::emResultNotify(RET_STRING_HSPA_FAIL);
+                RLOGD("send fail ");
+            }
+            break;
+        }
+        case EVENT_SET_HSPA:
+        {
+            if ((responselen > 0) && (response != NULL)) {
+                RLOGD("EVENT_SET_HSPA success: %s.\n",response);
+            }
+            else {
+                RLOGD("send fail ");
+            }
+            break;
+        }
+        default:
+            break;
+    }
+}
+
+
+//create thread to send command
+void * emHspaThread(void* arg)
+{
+    char cmd_str[32] = {0};
+    //sprintf(cmd_str,"%s%d,0", SET_CMD,hspamode);
+    //sendATCommand_ehspa(cmd_str,EVENT_SET_HSPA);
+    sendATCommand_ehspa(QUERY_CMD,EVENT_HSPA_INFO);
+    android::unregisterNetwork();
+    //android::emResultNotify(RET_STRING_HSPA_SUCCESS);
+    pthread_exit(0);
+}
+
+int emHspaStart(int argc, int *item)
+{
+    RLOGD("emHspaStart called");
+    if(argc < 1)
+    {
+        RLOGD("emHspaStart: please select mode to test: \
+                0: off, 2: on");
+        android::emResultNotify(RET_STRING_HSPA_FAIL);
+        return -1;
+    }
+    if((item[0] > 1 ) || (item[0] < 0)){
+        RLOGD("emHspaStart: invalid parameter %d",item[0]);
+        android::emResultNotify(RET_STRING_HSPA_FAIL);
+        return -1;
+    }
+    //int modemapping[2] = {0,2};
+    mCurrentEmhspaFlag = 0;
+    //hspamode = modemapping[item[0]];
+    android::registerForATcmdResponse(emHspaAtCmdHandle);
+    pthread_t emhspa_thread;
+    pthread_create(&emhspa_thread,NULL, emHspaThread, NULL);
+    return (0);
+}
+#endif
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_ims.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_ims.cpp
new file mode 100644
index 0000000..048ffa9
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_ims.cpp
@@ -0,0 +1,167 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include <vendor-ril/telephony/ril.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <cutils/jstring.h>
+#include <log/log.h>
+#include <unistd.h>
+#include <math.h>
+#include  "common.h"
+#include "em/em.h"
+#include "Radio_capability_switch_util.h"
+
+#if EM_MODE_SUPPORT
+
+#undef LOG_TAG
+#define LOG_TAG "EM_IMS"
+
+const int MSG_QUERY = 0;
+const int MSG_SET = 1;
+int mCurrentEmimsFlag = 0;
+char mCurrentSettingLabel[32] = {0};
+char mCurrentSettingValue[32] = {0};
+bool fgImsRead = true;
+char retstring[128] = {0};
+
+void sendCommandSet(const char* name, char *value) {
+    mCurrentEmimsFlag = MSG_SET;
+    char cmd_str[64] = {0};
+    sprintf(cmd_str,"AT+ECFGSET=\"%s\",\"%s\"",name,value);
+    emSendATCommand(cmd_str, get_default_sim_all_except_data());
+}
+
+void sendCommandQuery(const char* name) {
+    mCurrentEmimsFlag = MSG_QUERY;
+    char cmd_str[64] = {0};
+    sprintf(cmd_str,"AT+ECFGGET=\"%s\"",name);
+    emSendATCommand(cmd_str,get_default_sim_all_except_data());
+}
+
+char * parseCommandResponse(char * data) {
+   RLOGD("raw data: %s",data);
+   return "";
+}
+
+void emImsAtCmdHandle(char*response, int responselen) {
+    switch (mCurrentEmimsFlag) {
+    case MSG_QUERY:
+    {
+        memset(retstring,0,sizeof(retstring));
+        if ((responselen > 0) && (response != NULL)) {
+            RLOGD("Query success for %s ", mCurrentSettingLabel);
+            RLOGD("%s",response);
+            sprintf(retstring,"%s %s",response,RET_STRING_IMS_SUCCESS);
+        }
+        else {
+            RLOGD("Query failed for %s ", mCurrentSettingLabel);
+            sprintf(retstring,"Query failed for %s %s",mCurrentSettingLabel,RET_STRING_IMS_FAIL);
+        }
+        android::unregisterNetwork();
+        android::emResultNotify(retstring);
+        break;
+    }
+    case MSG_SET:
+    {
+        memset(retstring,0,sizeof(retstring));
+        if ((responselen > 0) && (response != NULL)) {
+            sprintf(retstring,"Set %s=%s successful %s",mCurrentSettingLabel,mCurrentSettingValue,RET_STRING_IMS_SUCCESS);
+            RLOGD("Set successful.");
+        }
+        else {
+            sprintf(retstring,"Set %s=%s failed %s",mCurrentSettingLabel,mCurrentSettingValue,RET_STRING_IMS_FAIL);
+            RLOGD("Set failed.");
+        }
+        android::unregisterNetwork();
+        android::emResultNotify(retstring);
+        break;
+    }
+    default:
+        break;
+    }
+}
+
+
+//create thread to send command
+void * emImsThread(void* arg)
+{
+    if(fgImsRead){
+        sendCommandQuery(mCurrentSettingLabel);
+    }else{
+        sendCommandSet(mCurrentSettingLabel,mCurrentSettingValue);
+    }
+    pthread_exit(0);
+}
+
+int emImsStart(int argc, int *item,char *value)
+{
+    RLOGD("emImsStart called");
+     //init item[0] //common/call/xxx: item[1] property item[2] get/set
+    mCurrentEmimsFlag = 0;
+    if(argc < 3){
+        RLOGD("please select ims get or set : ims get xxx /ims set xxx xx");
+        return -1;
+    }
+    int classid = item[0];
+    int propertyid = item[1];
+    int operatorid = item[2];
+
+    em_arry_t *subarry = &(ims[classid].subarray[propertyid]);
+    RLOGD("IMS property name %s",subarry->name);
+    memset(mCurrentSettingLabel,0,sizeof(mCurrentSettingLabel));
+    switch(operatorid){
+        case 0://get
+        {
+            strncpy(mCurrentSettingLabel,subarry->name,strlen(subarry->name));
+            fgImsRead = true;
+            break;
+        }
+        case 1://set
+        {
+            strncpy(mCurrentSettingLabel,subarry->name,strlen(subarry->name));
+            strncpy(mCurrentSettingValue,value,strlen(value));
+            fgImsRead = false;
+            break;
+        }
+    }
+
+    android::registerForATcmdResponse(emImsAtCmdHandle);
+    pthread_t emimsthread;
+    pthread_create(&emimsthread,NULL, emImsThread, NULL);
+    return (0);
+}
+
+#endif
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_modemtest.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_modemtest.cpp
new file mode 100644
index 0000000..38b9497
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/em_modemtest.cpp
@@ -0,0 +1,464 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include <vendor-ril/telephony/ril.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <cutils/jstring.h>
+#include <log/log.h>
+#include <unistd.h>
+#include <math.h>
+#include <string>
+#include <vector>
+
+#include "Phone_utils.h"
+#include  "common.h"
+#include "em/em.h"
+#include "Radio_capability_switch_util.h"
+
+#if EM_MODE_SUPPORT
+
+#undef LOG_TAG
+#define LOG_TAG "EM_MODEMTEST"
+
+int mCurrentEmmodemtestFlag = -1; // at cmd handle flag
+
+const int MODEM_NONE = 0;
+const int MODEM_CTA = 1;
+const int MODEM_FTA = 2;
+const int MODEM_IOT = 3;
+const int MODEM_QUERY = 4;
+const int MODEM_OPERATOR = 5;
+const int MODEM_FACTORY = 6;
+const int MODEM_QUERY_CDMA = 7;
+const int MODEM_CDMA = 8;
+const int MODEM_QUERY_CLSC = 9;
+const int MODEM_CLSC = 10;
+
+int mCtaOption = 0;
+int mIotOption = 0;
+int mFtaOption = 0;
+int mOperatorOption = 0;
+int mFactoryOption = 0;
+int mCdmaOption = 0;
+
+int modem_id = -1;
+int modem_option_cnt = -1;
+int modem_option[8] = {0};
+
+static const int EVENT_QUERY_PREFERRED_TYPE_DONE = 1000;
+static const int EVENT_SET_PREFERRED_TYPE_DONE = 1001;
+static const int REBOOT_DIALOG = 2000;
+static const int NETWORK_TYPE = 3; //type 3 means GSM/WCDMA (auto mode) 0 means GSM/WCDMA (WCDMA preferred)
+
+static const int CMD_LENGTH = 6;
+static const int MODE_LENGTH = 3;
+
+//static const String PREFERENCE_GPRS = "com.mtk.GPRS";
+//static const String PREF_ATTACH_MODE = "ATTACH_MODE";
+//static const String PREF_ATTACH_MODE_SIM = "ATTACH_MODE_SIM";
+static const int ATTACH_MODE_ALWAYS = 1;
+static const int ATTACH_MODE_NOT_SPECIFY = -1;
+static const int DOCOMO_OPTION = 1 << 7;
+static const int SOFTBANK_OPTION = 1 << 8;
+//static const String PROP_TEST_CARD = "persist.sys.forcttestcard";
+//static const String PROP_TDD_TEST = "persist.sys.forcttddtest";
+
+static const int IPO_ENABLE = 1;
+static const int IPO_DISABLE = 0;
+
+static const int PCH_DATA_PREFER = 0;
+static const int PCH_CALL_PREFER = 1;
+
+static const int INDEX_SPIRENT = 1;
+static const int FLAG_UNLOCK = 0x200000;
+static const int FLAG_NOT_DETECT_CDMA_CARD = 0x100000;
+
+bool mModemFlag = false;
+int mCurrentMode = 0;
+int mCurrentCmdFlag = 0;
+
+void setCurrentTestFlag(int msg){
+    mCurrentEmmodemtestFlag = msg;
+    return ;
+}
+
+void  sendATCommand_modemtest(const char *cmd,int msg)
+{
+    setCurrentTestFlag(msg);
+    emSendATCommand(cmd, Radio_capability_switch_util::get_main_capability_phone_id());
+    return ;
+}
+
+static void sendATCommandCdma(std::string str, int message) {
+    std::vector<std::string> cmdOri(3);
+    cmdOri[0] = "AT+ECTM=" + str;
+    cmdOri[1] = "";
+    cmdOri[2] = "DESTRILD:C2K";
+    std::vector<std::string> cmds = getCdmaCmdArr(cmdOri);
+    std::string cmd;
+    for (auto s : cmds) {
+        cmd += s;
+    }
+    sendATCommand_modemtest(cmd.c_str(), message);
+    sendATCommand_modemtest("AT+RFSSYNC", -1);
+}
+
+void setCdmaOption() {
+    if (modem_option[0] == INDEX_SPIRENT) {
+        sendATCommandCdma("\"SPIRENT\"", MODEM_CDMA);
+    } else {
+        sendATCommandCdma("\"NONE\"", MODEM_CDMA);
+    }
+}
+void  sendATCommand_modemtest(const char *str,int flag,int msg)
+{
+    char cmd[32] = {0};
+    mCurrentCmdFlag = (mCurrentCmdFlag & 0xFF0000) | flag;
+    sprintf(cmd,"AT+EPCT=%s,%d",str,mCurrentCmdFlag);
+    setCurrentTestFlag(msg);
+    emSendATCommand(cmd,Radio_capability_switch_util::get_main_capability_phone_id());
+    return ;
+}
+
+int setPreferredNetworkType_modemtest(int type)
+{
+    RequestInfo *pRI_preferredNetType = creatRILInfoAndInit(RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, OTHER,
+            (RIL_SOCKET_ID)Radio_capability_switch_util::get_main_capability_phone_id());
+    android::Parcel p;
+    size_t pos =  p.dataPosition();
+    p.writeInt32(1);
+    p.writeInt32(type);
+    p.setDataPosition(pos);
+    pRI_preferredNetType->pCI->dispatchFunction(p, pRI_preferredNetType);
+    return 1;
+}
+void checkNetworkType() {
+    RLOGD("TcheckNetworkType");
+    RequestInfo *pRI_preferredNetType = creatRILInfoAndInit(RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE, OTHER,
+            (RIL_SOCKET_ID)Radio_capability_switch_util::get_main_capability_phone_id());
+    android::Parcel p;
+    pRI_preferredNetType->pCI->dispatchFunction(p, pRI_preferredNetType);
+}
+
+void handleQuery(char* data)
+{
+    if(strstr(data,"+EPCT:") != NULL){
+        char *p = strstr(data,",");
+        if(p != NULL){
+            char mode[3] = {0};
+            char flag[12] = {0};
+            strncpy(mode,p-1,1);
+            char *end = strstr(data,"OK");
+            if(end != NULL){
+                RLOGD("end %s ", end);
+                RLOGD("end len %d ", end - p -1);
+                strncpy(flag,p+1,end - p -1);
+                mCurrentCmdFlag = atoi(flag);
+            }
+            mCurrentMode = atoi(mode);
+            RLOGD("mCurrentMode %d mCurrentCmdFlag %d",mCurrentMode,mCurrentCmdFlag);
+        }
+    }
+    return;
+}
+const char *modem_test_cta_options[] = {
+    "Integrity Check",
+    "RLC TL1",
+    "K1297",
+    "SN Conflict",
+    "CF query",
+    "DLMN lock",
+    "Measurement open",
+    "Disable DPA",
+    "Intra CMR",
+};
+
+const char *modem_test_fta_options[] = {
+    "ANITE",
+    "CRTUG",
+    "CRTUW",
+    "ANRITSU",
+    "CMW500"
+};
+
+void setGprsTransferType(int type) {
+    int property = (type == PCH_DATA_PREFER ? 1 : 0);
+    RLOGD("Change persist.radio.gprs.prefer to %d" ,property);
+    //SystemProperties.set("persist.radio.gprs.prefer", property);
+    char cmd[32];
+    sprintf(cmd,"AT+EGTP=%d",type);
+    sendATCommand_modemtest(cmd,-1);
+    sprintf(cmd,"AT+EMPPCH=%d",type);
+    sendATCommand_modemtest(cmd,-1);
+    //sendATCMD
+}
+void attachOrDetachGprs() {
+    if ((mOperatorOption & DOCOMO_OPTION) != 0 || (mOperatorOption & SOFTBANK_OPTION) != 0) {
+        RLOGD("Attach GPRS for DoCoMo/Softband");
+        //SystemProperties.set("persist.radio.gprs.attach.type", "1");
+        char cmdStr[] = {"AT+EGTYPE=1,1"};
+        sendATCommand_modemtest(cmdStr,-1);
+    } else {
+        RLOGD("Dettach GPRS for DoCoMo/Softband");
+        //SystemProperties.set("persist.radio.gprs.attach.type", "0");
+        char cmdStr[] = {"AT+EGTYPE=0,1"};
+        sendATCommand_modemtest(cmdStr,-1);
+    }
+}
+void turnoffWCMAPreferred(){
+    if(mModemFlag){
+        setCurrentTestFlag(EVENT_SET_PREFERRED_TYPE_DONE);
+        setPreferredNetworkType_modemtest(NETWORK_TYPE);
+    }
+}
+int modemTestProcess(int id,int *whichButton, int ButtonCount)//from onCreate & onCreateDialog
+{
+    switch(id){
+    case REBOOT_DIALOG:
+    {
+        //hint do reboot
+        return 0;
+    }
+    case MODEM_NONE:
+    {
+        sendATCommand_modemtest("0", 0, MODEM_NONE);
+        if (mCurrentMode == MODEM_FTA) {
+            setGprsTransferType(PCH_CALL_PREFER);
+        }
+        break;
+    }
+    case MODEM_CTA:
+    {
+        mCtaOption = 0;
+        for(int i = 0; i < ButtonCount; i++){
+            mCtaOption += (1 << whichButton[i]);
+        }
+        turnoffWCMAPreferred();
+        sendATCommand_modemtest("1", mCtaOption, MODEM_CTA);
+        if (mCurrentMode == MODEM_FTA) {
+            setGprsTransferType(PCH_CALL_PREFER);
+        }
+        break;
+    }
+    case MODEM_FTA:
+    {
+        mFtaOption = 0;
+        for(int i = 0; i < ButtonCount; i++){
+            RLOGD("which button %d",whichButton[i]);
+            mFtaOption += (1 << whichButton[i]);
+        }
+        RLOGD("mFtaOption %x", mFtaOption);
+        turnoffWCMAPreferred();
+        sendATCommand_modemtest("2", mFtaOption, MODEM_FTA);
+        //enableIPO(false);
+        setGprsTransferType(PCH_DATA_PREFER);
+        break;
+    }
+    case MODEM_IOT:
+    {
+        mIotOption = 0;
+        for(int i = 0; i < ButtonCount; i++){
+            mIotOption += (1 << whichButton[i]);
+        }
+        sendATCommand_modemtest("3", mIotOption, MODEM_IOT);
+        if (mCurrentMode == MODEM_FTA) {
+            setGprsTransferType(PCH_CALL_PREFER);
+        }
+        break;
+    }
+    case MODEM_OPERATOR:
+    {
+        mOperatorOption = 0;
+        for(int i = 0; i < ButtonCount; i++){
+            mOperatorOption += (1 << whichButton[i]);
+        }
+        turnoffWCMAPreferred();
+        attachOrDetachGprs();
+        sendATCommand_modemtest("4", mOperatorOption, MODEM_OPERATOR);
+        if (mCurrentMode == MODEM_FTA) {
+            setGprsTransferType(PCH_CALL_PREFER);
+        }
+        break;
+    }
+    case MODEM_CDMA:
+        setCdmaOption();
+        break;
+    case MODEM_FACTORY:
+    {
+        turnoffWCMAPreferred();
+        sendATCommand_modemtest("5", 0, MODEM_FACTORY);
+        if (mCurrentMode == MODEM_FTA) {
+            setGprsTransferType(PCH_CALL_PREFER);
+        }
+        break;
+    }
+    }
+}
+
+const char * getToastString(int what) {
+    switch (what) {
+    case MODEM_NONE:
+        return "MODEM_NONE";
+    case MODEM_CTA:
+        return "MODEM_CTA";
+    case MODEM_FTA:
+        return "MODEM_FTA";
+    case MODEM_IOT:
+        return "MODEM_IOT";
+    case MODEM_OPERATOR:
+        return "MODEM_OPERATOR";
+    case MODEM_FACTORY:
+        return "MODEM_FACTORY";
+    case MODEM_CDMA:
+        return "MODEM_CDMA";
+    default:
+        return "";
+    }
+}
+
+void emModemtestAtCmdHandle(char*response, int responselen) {
+    switch (mCurrentEmmodemtestFlag) {
+        case MODEM_NONE:
+        case MODEM_CTA:
+        case MODEM_FTA:
+        case MODEM_IOT:
+        case MODEM_OPERATOR:
+        case MODEM_FACTORY:
+        case MODEM_CDMA:
+        {
+            if ((responselen > 0) && (response != NULL)) {
+                RLOGD("%s  AT cmd success. %s\n",getToastString(mCurrentEmmodemtestFlag),response);
+            }
+            else {
+                RLOGD("%s  AT cmd failed.\n",getToastString(mCurrentEmmodemtestFlag));
+            }
+            break;
+        }
+        case MODEM_QUERY:
+        {
+            if ((responselen > 0) && (response != NULL)) {
+                RLOGD("Query success. %s\n",response);
+                handleQuery(response);
+            }
+            else {
+                RLOGD("Query fail. ");
+            }
+            break;
+        }
+        case EVENT_QUERY_PREFERRED_TYPE_DONE:
+        {
+            if ((responselen > 0) && (response != NULL)) {
+                int type = -1;
+                //parse currect preferred type
+                type = atoi(response);
+                RLOGD("Get Preferred Type: %d ",type);
+                if (type == 0) {
+                    mModemFlag = true;
+                } else {
+                    mModemFlag = false;
+                }
+            }
+            else {
+                RLOGD("Query preferred type fail ");
+            }
+            break;
+        }
+        case EVENT_SET_PREFERRED_TYPE_DONE:
+        {
+            if ((responselen > 0) && (response != NULL)) {
+                RLOGD("Turn off WCDMA Preferred success\n");
+            }
+            else {
+                RLOGD("Turn off WCDMA Preferred Fail");
+            }
+            break;
+        }
+        default:
+            break;
+    }
+}
+
+void * emModemtestThread(void* arg)
+{
+    RLOGD("Modem Test: %s ",getToastString(modem_id));
+    modemTestProcess(modem_id,modem_option,modem_option_cnt);
+    android::unregisterNetwork();
+    android::emResultNotify(RET_STRING_MODEMTEST_SUCCESS);
+    pthread_exit(0);
+}
+
+int emModemtestStart(int argc, int multicnt,int *item)
+{
+    //item[0]: fta/cta/... item[1] count  item[2]..item[count+1] which part
+    RLOGD("emModemtestStart called");
+    if(argc < 1)
+    {
+        RLOGD("emModemtestStart: please select id to test: \
+            ");
+        android::emResultNotify(RET_STRING_MODEMTEST_FAIL);
+        return -1;
+    }
+    int idmapping[7] = {MODEM_NONE,MODEM_CTA,MODEM_FTA,MODEM_IOT,MODEM_FACTORY,MODEM_FACTORY, MODEM_CDMA};
+    modem_id = idmapping[item[0]];
+    modem_option_cnt = multicnt;
+    modem_option[0] = item[1];
+
+    for(int i = 0; i < modem_option_cnt ; i++){
+        modem_option[i+1] = item[2+i];
+    }
+    modem_option_cnt+=1;
+
+    RLOGD("emModemtestStart modem_option_cnt %d",modem_option_cnt);
+    mCtaOption = 0;
+    mIotOption = 0;
+    mFtaOption = 0;
+    mOperatorOption = 0;
+    mFactoryOption = 0;
+    mCdmaOption = 0;
+    mCurrentEmmodemtestFlag = 0;
+    android::registerForATcmdResponse(emModemtestAtCmdHandle);
+
+    if(modem_id != MODEM_CDMA) {
+        setCurrentTestFlag(EVENT_QUERY_PREFERRED_TYPE_DONE);
+        checkNetworkType();
+        sendATCommand_modemtest("AT+EPCT?",MODEM_QUERY);
+    }
+
+    pthread_t emmodemtest_thread;
+    pthread_create(&emmodemtest_thread,NULL, emModemtestThread, NULL);
+    return (0);
+}
+#endif
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/networkinfo/Content.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/networkinfo/Content.cpp
new file mode 100644
index 0000000..b351b6e
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/networkinfo/Content.cpp
@@ -0,0 +1,153 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include "Content.h"
+#include "../../util/utils.h"
+#include "../../util/ModemCategory.h"
+
+const bool Content::NEW_VALUE = true; //ChipSupport.getChip() >= ChipSupport.MTK_6735_SUPPORT;
+const bool Content::IS_MOLY = ModemCategory::isLteSupport();
+
+/* Item Index */
+constexpr int Content::CELL_INDEX;
+constexpr int Content::CHANNEL_INDEX;
+constexpr int Content::CTRL_INDEX;
+constexpr int Content::RACH_INDEX;
+constexpr int Content::LAI_INDEX;
+constexpr int Content::RADIO_INDEX;
+constexpr int Content::MEAS_INDEX;
+constexpr int Content::CA_INDEX;
+constexpr int Content::CONTROL_INDEX;
+constexpr int Content::SI2Q_INDEX;
+constexpr int Content::MI_INDEX;
+constexpr int Content::BLK_INDEX;
+constexpr int Content::TBF_INDEX;
+constexpr int Content::GPRS_INDEX;
+const int Content::SM_INFO_INDEX = IS_MOLY ? 58 : 63;
+constexpr int Content::URR_3G_GENERAL_INDEX;
+const int Content::MM_INFO_INDEX = NEW_VALUE ? 53 : 21;
+constexpr int Content::GMM_INFO_INDEX;
+const int Content::TCM_MMI_INDEX = NEW_VALUE ? 59 : 27;
+const int Content::CSCE_SERV_CELL_STATUS_INDEX = NEW_VALUE ? 75 : 47;
+const int Content::CSCE_NEIGH_CELL_STATUS_INDEX = NEW_VALUE ? 76 : 48;
+const int Content::CSCE_MULTIPLMN_INDEX = NEW_VALUE ? 81 : 52;
+const int Content::UMTS_CELL_STATUS_INDEX = NEW_VALUE ? 90 : 53;
+const int Content::PERIOD_IC_BLER_REPORT_INDEX = NEW_VALUE ? (IS_MOLY ? 97 : 99) : 62;
+const int Content::URR_UMTS_SRNC_INDEX = NEW_VALUE ? 111 : 64;
+const int Content::PSDATA_RATE_STATUS_INDEX = NEW_VALUE ? 140 : 65;
+const int Content::HSERV_CELL_INDEX = NEW_VALUE ? (IS_MOLY ? 96 : 98) : 61;
+const int Content::HANDOVER_SEQUENCE_INDEX = NEW_VALUE ? 130 : 65;
+const int Content::UL_ADM_POOL_STATUS_INDEX = NEW_VALUE ? 185 : 67;
+const int Content::UL_PSDATA_RATE_STATUS_INDEX = NEW_VALUE ? 186 : 68;
+const int Content::UL_HSDSCH_RECONFIG_STATUS_INDEX = NEW_VALUE ? 187 : 69;
+const int Content::UL_URLC_EVENT_STATUS_INDEX = NEW_VALUE ? 188 : 70;
+const int Content::UL_PERIOD_IC_BLER_REPORT_INDEX = NEW_VALUE ? 189 : 71;
+
+constexpr int Content::CDMA_INDEX_BASE;
+constexpr int Content::CDMA_1XRTT_RADIO_INDEX;
+constexpr int Content::CDMA_1XRTT_INFO_INDEX;
+constexpr int Content::CDMA_1XRTT_SCH_INFO_INDEX;
+constexpr int Content::CDMA_1XRTT_STATISTICS_INDEX;
+constexpr int Content::CDMA_1XRTT_SERVING_INDEX;
+constexpr int Content::CDMA_EVDO_SERVING_INFO_INDEX;
+constexpr int Content::CDMA_EVDO_ACTIVE_SET_INDEX;
+constexpr int Content::CDMA_EVDO_CANDICATE_SET_INDEX;
+constexpr int Content::CDMA_EVDO_NEIGHBOR_SET_INDEX;
+constexpr int Content::CDMA_EVDO_FL_INDEX;
+constexpr int Content::CDMA_EVDO_RL_INDEX;
+constexpr int Content::CDMA_EVDO_STATE_INDEX;
+constexpr int Content::CDMA_EVDO_FORCE_TX_ANT;
+
+// add for LGE
+const int Content::LLC_EM_INFO_INDEX = 57;
+constexpr int Content::UL1_EM_PRX_DRX_MEASURE_INFO_INDEX;
+const int Content::ERRC_EM_SEC_PARAM_INDEX = 217;
+const int Content::ERRC_EM_ERRC_STATE_INDEX = 222;
+const int Content::EMM_L4C_EMM_INFO_INDEX = 244;
+constexpr int Content::EL1TX_EM_TX_INFO_INDEX;
+const int Content::SLCE_VOICE_INDEX = NEW_VALUE ? (IS_MOLY ? 250 : 141) : 80;
+const int Content::SECURITY_CONFIGURATION_INDEX = NEW_VALUE ? (IS_MOLY ? 158 : 157) : 81;
+
+/* Item data size */
+const int Content::CELL_SEL_SIZE = 6;
+const int Content::CH_DSCR_SIZE = 340;
+const int Content::CTRL_CHAN_SIZE = 14;
+const int Content::RACH_CTRL_SIZE = 14;
+const int Content::LAI_INFO_SIZE = 28;
+const int Content::RADIO_LINK_SIZE = 16;
+const int Content::MEAS_REP_SIZE = 1384;
+const int Content::CAL_LIST_SIZE = 260;
+const int Content::CONTROL_MSG_SIZE = 4;
+const int Content::SI2Q_INFO_SIZE = 10;
+const int Content::MI_INFO_SIZE = 8;
+const int Content::BLK_INFO_SIZE = 80;
+const int Content::TBF_INFO_SIZE = 56;
+const int Content::GPRS_GEN_SIZE = 32;
+const int Content::URR_3G_GENERAL_SIZE = 12;
+
+// add for LGE
+const int Content::SLCE_VOICE_SIZE = 1 * 2;
+const int Content::SECURITY_CONFIGURATION_SIZE = 2 * 2;
+
+// LXO, stupid code..
+const int Content::SM_EM_INFO_SIZE = 2204 * 2;
+const int Content::M3G_MM_EMINFO_SIZE = 30 * 2;
+const int Content::GMM_EM_INFO_SIZE = 20 * 2;
+const int Content::M_3G_TCMMMI_INFO_SIZE = 7 * 2;
+const int Content::CSCE_SERV_CELL_STATUS_SIZE = 52 * 2;
+const int Content::CSCE_MULTI_PLMN_SIZE = 37 * 2;
+const int Content::UMTS_CELL_STATUS_SIZE = 772 * 2;
+const int Content::PERIOD_IC_BLER_REPORT_SIZE = 100 * 2;
+const int Content::URR_UMTS_SRNC_SIZE = 2 * 2;
+const int Content::SLCE_PS_DATA_RATE_STATUS_SIZE = 100 * 2;
+const int Content::MEME_HSERV_CELL_SIZE = 8 * 2;
+
+const int Content::HANDOVER_SEQUENCE_SIZE = 16 * 2; // alignment enabled
+const int Content::ADM_POOL_STATUS_SIZE = 32 * 2;
+const int Content::UL2_PSDATA_RATE_STATUS_SIZE = 8 * 2;
+const int Content::UL_HSDSCH_RECONFIG_STATUS_SIZE = 8 * 2;
+const int Content::URLC_EVENT_STATUS_SIZE = 18 * 2;
+const int Content::UL_PERIOD_IC_BLER_REPORT_SIZE = 100 * 2;
+
+const int Content::XGCSCE_NEIGH_CELL_STATUS_SIZE = 520 * 2;
+Content::Content() {
+    // TODO Auto-generated constructor stub
+
+}
+
+Content::~Content() {
+    // TODO Auto-generated destructor stub
+}
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/networkinfo/Content.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/networkinfo/Content.h
new file mode 100644
index 0000000..a027aec
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/networkinfo/Content.h
@@ -0,0 +1,152 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef SRC_EM_NETWORKINFO_CONTENT_H_
+#define SRC_EM_NETWORKINFO_CONTENT_H_
+
+class Content {
+public:
+    Content();
+    virtual ~Content();
+public:
+    static const bool NEW_VALUE;
+    static const bool IS_MOLY;
+
+    /* Item Index */
+    static constexpr int CELL_INDEX = 0;
+    static constexpr int CHANNEL_INDEX = 1;
+    static constexpr int CTRL_INDEX = 2;
+    static constexpr int RACH_INDEX = 3;
+    static constexpr int LAI_INDEX = 4;
+    static constexpr int RADIO_INDEX = 5;
+    static constexpr int MEAS_INDEX = 6;
+    static constexpr int CA_INDEX = 7;
+    static constexpr int CONTROL_INDEX = 8;
+    static constexpr int SI2Q_INDEX = 9;
+    static constexpr int MI_INDEX = 10;
+    static constexpr int BLK_INDEX = 11;
+    static constexpr int TBF_INDEX = 12;
+    static constexpr int GPRS_INDEX = 13;
+
+    static const int SM_INFO_INDEX;
+    static constexpr int URR_3G_GENERAL_INDEX = 70;
+    static const int MM_INFO_INDEX;
+    static constexpr int GMM_INFO_INDEX = 56;
+    static const int TCM_MMI_INDEX;
+    static const int CSCE_SERV_CELL_STATUS_INDEX;
+    static const int CSCE_NEIGH_CELL_STATUS_INDEX;
+    static const int CSCE_MULTIPLMN_INDEX;
+    static const int UMTS_CELL_STATUS_INDEX;
+    static const int PERIOD_IC_BLER_REPORT_INDEX;
+    static const int URR_UMTS_SRNC_INDEX;
+    static const int PSDATA_RATE_STATUS_INDEX;
+    static const int HSERV_CELL_INDEX;
+    static const int HANDOVER_SEQUENCE_INDEX;
+    static const int UL_ADM_POOL_STATUS_INDEX;
+    static const int UL_PSDATA_RATE_STATUS_INDEX;
+    static const int UL_HSDSCH_RECONFIG_STATUS_INDEX;
+    static const int UL_URLC_EVENT_STATUS_INDEX;
+    static const int UL_PERIOD_IC_BLER_REPORT_INDEX;
+
+    static constexpr int CDMA_INDEX_BASE = 300;
+    static constexpr int CDMA_1XRTT_RADIO_INDEX = CDMA_INDEX_BASE + 0;
+    static constexpr int CDMA_1XRTT_INFO_INDEX = CDMA_INDEX_BASE + 1;
+    static constexpr int CDMA_1XRTT_SCH_INFO_INDEX = CDMA_INDEX_BASE + 2;
+    static constexpr int CDMA_1XRTT_STATISTICS_INDEX = CDMA_INDEX_BASE + 3;
+    static constexpr int CDMA_1XRTT_SERVING_INDEX = CDMA_INDEX_BASE + 4;
+    static constexpr int CDMA_EVDO_SERVING_INFO_INDEX = CDMA_INDEX_BASE + 5;
+    static constexpr int CDMA_EVDO_ACTIVE_SET_INDEX = CDMA_INDEX_BASE + 6;
+    static constexpr int CDMA_EVDO_CANDICATE_SET_INDEX = CDMA_INDEX_BASE + 7;
+    static constexpr int CDMA_EVDO_NEIGHBOR_SET_INDEX = CDMA_INDEX_BASE + 8;
+    static constexpr int CDMA_EVDO_FL_INDEX = CDMA_INDEX_BASE + 9;
+    static constexpr int CDMA_EVDO_RL_INDEX = CDMA_INDEX_BASE + 10;
+    static constexpr int CDMA_EVDO_STATE_INDEX = CDMA_INDEX_BASE + 11;
+    static constexpr int CDMA_EVDO_FORCE_TX_ANT = CDMA_INDEX_BASE - 1;
+
+// add for LGE
+    static const int LLC_EM_INFO_INDEX;
+    static constexpr int UL1_EM_PRX_DRX_MEASURE_INFO_INDEX = 177;
+    static const int ERRC_EM_SEC_PARAM_INDEX;
+    static const int ERRC_EM_ERRC_STATE_INDEX;
+    static const int EMM_L4C_EMM_INFO_INDEX;
+    static constexpr int EL1TX_EM_TX_INFO_INDEX = 249;
+    static const int SLCE_VOICE_INDEX;
+    static const int SECURITY_CONFIGURATION_INDEX;
+
+/* Item data size */
+    static const int CELL_SEL_SIZE;
+    static const int CH_DSCR_SIZE;
+    static const int CTRL_CHAN_SIZE;
+    static const int RACH_CTRL_SIZE;
+    static const int LAI_INFO_SIZE;
+    static const int RADIO_LINK_SIZE;
+    static const int MEAS_REP_SIZE;
+    static const int CAL_LIST_SIZE;
+    static const int CONTROL_MSG_SIZE;
+    static const int SI2Q_INFO_SIZE;
+    static const int MI_INFO_SIZE;
+    static const int BLK_INFO_SIZE;
+    static const int TBF_INFO_SIZE;
+    static const int GPRS_GEN_SIZE;
+    static const int URR_3G_GENERAL_SIZE;
+
+// add for LGE
+    static const int SLCE_VOICE_SIZE;
+    static const int SECURITY_CONFIGURATION_SIZE;
+
+// LXO, stupid code..
+    static const int SM_EM_INFO_SIZE;
+    static const int M3G_MM_EMINFO_SIZE;
+    static const int GMM_EM_INFO_SIZE;
+    static const int M_3G_TCMMMI_INFO_SIZE;
+    static const int CSCE_SERV_CELL_STATUS_SIZE;
+    static const int CSCE_MULTI_PLMN_SIZE;
+    static const int UMTS_CELL_STATUS_SIZE;
+    static const int PERIOD_IC_BLER_REPORT_SIZE;
+    static const int URR_UMTS_SRNC_SIZE;
+    static const int SLCE_PS_DATA_RATE_STATUS_SIZE;
+    static const int MEME_HSERV_CELL_SIZE;
+
+    static const int HANDOVER_SEQUENCE_SIZE;
+    static const int ADM_POOL_STATUS_SIZE;
+    static const int UL2_PSDATA_RATE_STATUS_SIZE;
+    static const int UL_HSDSCH_RECONFIG_STATUS_SIZE;
+    static const int URLC_EVENT_STATUS_SIZE;
+    static const int UL_PERIOD_IC_BLER_REPORT_SIZE;
+
+    static const int XGCSCE_NEIGH_CELL_STATUS_SIZE;
+};
+
+#endif /* SRC_EM_NETWORKINFO_CONTENT_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/networkinfo/NetworkInfoUrcParser.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/networkinfo/NetworkInfoUrcParser.cpp
new file mode 100644
index 0000000..a9b3658
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/networkinfo/NetworkInfoUrcParser.cpp
@@ -0,0 +1,1737 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include <log/log.h>
+#include <stdexcept>
+#include "NetworkInfoUrcParser.h"
+#include "Content.h"
+#include "../../util/utils.h"
+#include "../../util/ModemCategory.h"
+
+#undef LOG_TAG
+#define LOG_TAG "EM_NetworkInfoUrcParser"
+
+const int NetworkInfoUrcParser::DATA_OFFSET_2 = 2;
+const int NetworkInfoUrcParser::DATA_OFFSET_4 = 4;
+const int NetworkInfoUrcParser::DATA_OFFSET_6 = 6;
+const int NetworkInfoUrcParser::DATA_OFFSET_8 = 8;
+const int NetworkInfoUrcParser::DATA_FORMAT = 16;
+const int NetworkInfoUrcParser::MAX_DATA_PER_LINE = 7;
+
+const int NetworkInfoUrcParser::TYPE_UINT8 = 0;
+const int NetworkInfoUrcParser::TYPE_UINT16 = 1;
+const int NetworkInfoUrcParser::TYPE_UINT32 = 2;
+const int NetworkInfoUrcParser::TYPE_INT8 = 3;
+const int NetworkInfoUrcParser::TYPE_INT16 = 4;
+const int NetworkInfoUrcParser::TYPE_INT32 = 5;
+const int NetworkInfoUrcParser::TYPE_LONG = 6;
+const int NetworkInfoUrcParser::TYPE_FLOAT = 7;
+const int NetworkInfoUrcParser::TYPE_ALIGNMENT = 8;
+const int NetworkInfoUrcParser::TYPE_STRING = 9;
+
+const bool NetworkInfoUrcParser::ALIGN_MENT_ENABLE = true;
+const bool NetworkInfoUrcParser::GPRS_MODE_ENABLE = true;
+const bool NetworkInfoUrcParser::AMR_SUPPORT_ENABLE = true;
+const bool NetworkInfoUrcParser::FWPNC_LAI_INFO_ENABLE = false;
+const bool NetworkInfoUrcParser::UMTS_R8 = true;
+const bool NetworkInfoUrcParser::WISDOM_EM = true;
+const bool NetworkInfoUrcParser::ADVANCED_EM = true;
+const bool NetworkInfoUrcParser::IS_MOLY = Content::IS_MOLY;
+
+const int NetworkInfoUrcParser::MODEM_FDD = 1;
+const int NetworkInfoUrcParser::MODEM_TD = 2;
+
+NetworkInfoUrcParser::NetworkInfoUrcParser() {
+    // TODO Auto-generated constructor stub
+
+}
+
+NetworkInfoUrcParser::~NetworkInfoUrcParser() {
+    // TODO Auto-generated destructor stub
+}
+
+std::string NetworkInfoUrcParser::get3GUl2EmPsDataRateStatusIndStruct() {
+    parseElement(TYPE_UINT16, "rx_mac_data_rate:");
+    parseElement(TYPE_UINT16, "rx_pdcp_data_rate:");
+    parseElement(TYPE_UINT16, "tx_mac_data_rate:");
+    parseElement(TYPE_UINT16, "tx_pdcp_data_rate:");
+    return mResult;
+}
+std::string NetworkInfoUrcParser::get3Gul2EmHsdschReconfigStatusIndStruct(){
+    for (int i = 0; i < 8; i++) {
+        parseElement(TYPE_UINT8, std::string("reconfig_info") + std::to_string(i) + std::string(":"));
+    }
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::get3GUl2EmUrlcEventStatusIndStruct(){
+    parseElement(TYPE_INT8, "rb_id:");
+    parseElement(TYPE_UINT8, "rlc_action:");
+    parseElement(TYPE_UINT8, "rb_info:--- \nis_srb:");
+    parseElement(TYPE_UINT8, "cn_domain:");
+    parseElement(TYPE_UINT8, "rlc_info:--- \nrlc_mode:");
+    parseElement(TYPE_UINT8, "direction:");
+    parseElement(TYPE_UINT16, "rlc_parameter:--- \npdu_Size:");
+    parseElement(TYPE_UINT16, "tx_window_size:");
+    parseElement(TYPE_UINT16, "rx_window_size:");
+    parseElement(TYPE_UINT8, "discard_mode:");
+    parseElement(TYPE_UINT16, "discard_value:");
+    parseElement(TYPE_UINT8, "flush_data_indicator:");
+    parseElement(TYPE_UINT8, "reset_cause:");
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::get3GUl2EmPeriodicBlerReportInd(){
+    parseElement(TYPE_UINT8, "num_trch:");
+    parseElement(TYPE_ALIGNMENT, "");
+    mResult.append("TrCHBler:--------");
+    for (int i = 0; i < 8; i++) {
+        parseElement(TYPE_UINT8, std::string("TrCHId") + std::to_string(i) + std::string(":"));
+        parseElement(TYPE_UINT32, std::string("TotalCRC") + std::to_string(i) + std::string(":"));
+        parseElement(TYPE_UINT32, std::string("BadCRC")  + std::to_string(i) + std::string(":"));
+    }
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::get3GUl2EmAdmPoolStatusIndStruct() {
+    mResult.append("[dl_adm_poll_info:-----]\n");
+    for (int i = 0; i < 4; i++) {
+        parseElement(TYPE_UINT16, std::string("max_usage_kbytes") + std::to_string(i) + std::string(":"));
+        parseElement(TYPE_UINT16, std::string("avg_usage_kbytes") + std::to_string(i) + std::string(":"));
+    }
+    mResult.append("[ul_adm_poll_info:-----]\n");
+    for (int i = 0; i < 4; i++) {
+        parseElement(TYPE_UINT16, std::string("max_usage_kbytes") + std::to_string(i) + std::string(":"));
+        parseElement(TYPE_UINT16, std::string("avg_usage_kbytes") + std::to_string(i) + std::string(":"));
+    }
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::get3GCsceEMServCellSStatusInd(bool isTdd) {
+    if (!IS_MOLY) {
+        parseElement(TYPE_UINT8, "ref_count:");
+        parseElement(TYPE_UINT16, "msg_len");
+    }
+    parseElement(TYPE_UINT8, "cell_idx: ");
+    parseElement(TYPE_UINT16, "uarfacn_DL: ");
+    parseElement(TYPE_UINT16, "psc: ");
+    parseElement(TYPE_UINT8, "is_s_criteria_satisfied: ");
+    parseElement(TYPE_INT8, "qQualmin: ");
+    parseElement(TYPE_INT8, "qRxlevmin: ");
+    parseElement(TYPE_INT32, "srxlev: ");
+    parseElement(TYPE_INT32, "spual: ");
+    parseElement(TYPE_LONG, "rscp: ");
+    if (!isTdd) {
+        parseElement(TYPE_FLOAT, "ec_no: ");
+    }
+    parseElement(TYPE_UINT16, "cycle_len: ");
+    if (!isTdd) {
+        parseElement(TYPE_UINT8, "quality_measure: ");
+    }
+    parseElement(TYPE_UINT8, "band: ");
+    parseElement(TYPE_INT32, "rssi: ");
+    parseElement(TYPE_UINT32, "cell_identity: ");
+    if (UMTS_R8) {
+        parseElement(TYPE_UINT32, "csg_id: ");
+        parseElement(TYPE_UINT8, "apbcr_priority: ");
+        parseElement(TYPE_UINT8, "sprio_search1: ");
+        parseElement(TYPE_UINT8, "sprio_search2: ");
+        parseElement(TYPE_UINT8, "threshserv_low: ");
+        if (IS_MOLY) {
+            parseElement(TYPE_UINT8, "threshserv_low2: ");
+        }
+    }
+    if (!isTdd) {
+        parseElement(TYPE_UINT8, "multi_plmn_count: ");
+        for (int i = 0; i < 6; i++) {
+            parseElement(TYPE_UINT8, std::string("multi_plmn_id[") + std::to_string(i) + std::string("].mcc: "), 3);
+            parseElement(TYPE_UINT8, std::string("multi_plmn_id[") + std::to_string(i) + std::string("].mnc: "), 3);
+        }
+
+        int lacValid = readIntegerFromByte();
+        if (lacValid != 0) {
+            parseElement(TYPE_UINT16, "lac: ");
+        } else {
+            mResult.append("lac: invalid\n");
+            mOffset += DATA_OFFSET_4;
+        }
+
+        int racValid = readIntegerFromByte();
+        if (racValid != 0) {
+            parseElement(TYPE_UINT8, "rac: ");
+        } else {
+            mResult.append("rac: invalid\n");
+            mOffset += DATA_OFFSET_2;
+        }
+
+        int uraValid = readIntegerFromByte();
+        if (uraValid != 0) {
+            parseElement(TYPE_UINT8, "num_ura_id: ");
+            for (int i = 0; i < 8; i++) {
+                int numBits = readIntegerFromByte();
+                if (numBits == 1) {
+                    parseElement(TYPE_UINT8, std::string("uraIdentity[") + std::to_string(i) + std::string("]: "));
+                    mOffset += DATA_OFFSET_2; // skip high byte
+                } else {
+                    parseElement(TYPE_UINT8, std::string("uraIdentity[") + std::to_string(i) + std::string("]: "), 2);
+                }
+            }
+        } else {
+            mResult.append("ura: invalid\n");
+        }
+    }
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::getxGCsceEMNeighCellSStatusIndStructSize(bool isTdd) {
+    if (!IS_MOLY) {
+        parseElement(TYPE_UINT8, "ref_count:");
+        parseElement(TYPE_UINT16, "msg_len");
+    }
+    parseElement(TYPE_UINT8, "neigh_cell_count:");
+    parseElement(TYPE_UINT8, "operation:");
+    std::string xgType = getValueFromByte(mRawString, mOffset, false);
+    parseElement(TYPE_UINT8, "RAT_type:");
+    parseElement(TYPE_ALIGNMENT, "");
+
+    if (xgType == std::string("1")) {
+        mResult.append("----GSM_neigh_cells----\n");
+        for (int i = 0; i < 16; i++) {
+            parseElement(TYPE_UINT8, std::string("cellidx") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_UINT16, "arfcn");
+            parseElement(TYPE_UINT8, std::string("bsic") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_UINT8, std::string("is_bsic_verified") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_UINT8, std::string("is_s_criteria_saticified") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_UINT8, std::string("freq_band") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_INT8, std::string("qRxlevmin") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_INT32, std::string("srxlev") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_INT32, std::string("rssi") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_INT8, std::string("apbcr_priority") + std::to_string(i)+ std::string(":"));
+            parseElement(TYPE_UINT8, std::string("threshx_high") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_UINT8, std::string("threshx_low") + std::to_string(i)+ std::string(":"));
+            if (IS_MOLY) {
+                parseElement(TYPE_UINT8, std::string("threshx_high2") + std::to_string(i) + std::string(":"));
+                parseElement(TYPE_UINT8, std::string("threshx_low2") + std::to_string(i) + std::string(":"));
+            }
+            parseElement(TYPE_ALIGNMENT, "");
+        }
+    } else if (xgType == std::string("2")) {
+        mResult.append("----LTE_neigh_cells----\n");
+        for (int i = 0; i < 16; i++) {
+            parseElement(TYPE_UINT16, "earfcn");
+            parseElement(TYPE_UINT16, std::string("pci") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_INT32, std::string("rsrp") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_INT32, std::string("rsrq") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_INT32, std::string("Treselection") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_INT8, std::string("apbcr_priority") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_INT16, std::string("qRxlevmin") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_INT8, std::string("qQualMinEUTRA") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_UINT8, std::string("threshx_high") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_UINT8, std::string("threshx_low") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_UINT8, std::string("threshx_high2") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_UINT8, std::string("threshx_low2") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_ALIGNMENT, "");
+        }
+    } else {
+        mResult.append("----3G_neigh_cells----\n");
+        for (int i = 0; i < 16; i++) {
+            parseElement(TYPE_UINT8, std::string("cellidx") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_UINT16, std::string("arfcn_DL"));
+            parseElement(TYPE_UINT16, std::string("psc"));
+            parseElement(TYPE_UINT8, std::string("is_s_criteria_saticified") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_INT8, std::string("qQualmin") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_INT8, std::string("qRxlevmin") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_INT32, std::string("srxlev") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_INT32, std::string("squal") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_LONG, "rscp: ");
+            parseElement(TYPE_INT32, std::string("ec_no") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_INT8, std::string("apbcr_priority") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_UINT8, std::string("threshx_high") + std::to_string(i) + std::string(":"));
+            parseElement(TYPE_UINT8, std::string("threshx_low") + std::to_string(i) + std::string(":"));
+            if (IS_MOLY) {
+                parseElement(TYPE_UINT8, std::string("threshx_high2") + std::to_string(i) + std::string(":"));
+                parseElement(TYPE_UINT8, std::string("threshx_low2") + std::to_string(i) + std::string(":"));
+            }
+            if (!isTdd) {
+                parseElement(TYPE_UINT32, std::string("cell_identity") + std::to_string(i) + std::string(":"));
+                int plmnValid = readIntegerFromByte();
+                if (plmnValid != 0) {
+                    parseElement(TYPE_UINT8, std::string("multi_plmn_count: "));
+                    for (int j = 0; j < 6; j++) {
+                        parseElement(TYPE_UINT8, std::string("multi_plmn_id[") + std::to_string(j) + std::string("].mcc: "), 3);
+                        parseElement(TYPE_UINT8, std::string("multi_plmn_id[") + std::to_string(j) + std::string("].mnc: "), 3);
+                    }
+                } else {
+                    mOffset += 37 * 2; // skip plmn data
+                }
+
+                int lacValid = readIntegerFromByte();
+                if (lacValid != 0) {
+                    parseElement(TYPE_UINT16, "lac: ");
+                } else {
+                    mResult.append("lac: invalid\n");
+                    mOffset += DATA_OFFSET_6;
+                }
+
+                int racValid = readIntegerFromByte();
+                if (racValid != 0) {
+                    parseElement(TYPE_UINT8, "rac: ");
+                } else {
+                    mResult.append("rac: invalid\n");
+                    mOffset += DATA_OFFSET_2;
+                }
+
+                int uraValid = readIntegerFromByte();
+                if (uraValid != 0) {
+                    parseElement(TYPE_UINT8, "num_ura_id: ");
+                    for (int j = 0; j < 8; j++) {
+                        int numBits = readIntegerFromByte();
+                        if (numBits == 1) {
+                            parseElement(TYPE_UINT8, std::string("uraIdentity[") + std::to_string(j) + std::string("]: "));
+                            mOffset += DATA_OFFSET_2; // skip high byte
+                        } else {
+                            parseElement(TYPE_UINT8, std::string("uraIdentity[") + std::to_string(j) + std::string("]: "), 2);
+                        }
+                    }
+                } else {
+                    mOffset += 25 * 2; // skip ura data
+                    mResult.append("ura: invalid\n");
+                }
+            }
+            parseElement(TYPE_ALIGNMENT, "");
+        }
+    }
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::getValueFrom4Byte(std::string data, int start, bool sig) {
+    if (data.length() < start + DATA_OFFSET_8) {
+        return std::string("0");
+    }
+    try {
+        std::string byte1 = data.substr(start, start + DATA_OFFSET_2);
+        std::string byte2 = data.substr(start + DATA_OFFSET_2, start + DATA_OFFSET_4);
+        std::string byte3 = data.substr(start + DATA_OFFSET_4, start + DATA_OFFSET_6);
+        std::string byte4 = data.substr(start + DATA_OFFSET_6, start + DATA_OFFSET_8);
+        std::string reverse = byte4 + byte3 + byte2 + byte1;
+        if (sig) {
+            long lg = std::stol(reverse,0, DATA_FORMAT);
+            int i = (int) lg;
+            return std::to_string(i);
+        } else {
+            return std::to_string(std::stol(reverse,0, DATA_FORMAT));
+        }
+    } catch (const std::out_of_range &e) {
+        RLOGD("out of range: %s, line: %s", e.what(), __LINE__);
+        return std::string("Error.");
+    } catch (const std::invalid_argument &e) {
+        RLOGD("invalid argument: %s, line: %s", e.what(), __LINE__);
+        return std::string("Error.");
+    }
+}
+std::string NetworkInfoUrcParser::oneBlockFrom4Byte(std::string label, std::string data, int start,bool sig, int dataLength) {
+    std::string block(label);
+    for (int i = 0; i < dataLength; i++) {
+        if (dataLength > MAX_DATA_PER_LINE && 0 == i % MAX_DATA_PER_LINE) {
+            block += std::string("\n");
+        }
+        block += getValueFrom4Byte(data, start, sig);
+        start += DATA_OFFSET_8;
+        if (i != dataLength - 1) {
+            block += std::string(", ");
+        }
+    }
+    return block + std::string("\n");
+}
+
+std::string NetworkInfoUrcParser::getValueFrom2Byte(std::string data, int start, bool sig) {
+    if (data.length() < start + DATA_OFFSET_4) {
+        return std::string("0");
+    }
+    try {
+        std::string low = data.substr(start, start + DATA_OFFSET_2);
+        std::string high = data.substr(start + DATA_OFFSET_2, start + DATA_OFFSET_4);
+        std::string reverse = high + low;
+        if (sig) {
+            int i = std::stoi(reverse,0, DATA_FORMAT);
+            int16_t s = (int16_t) i;
+            return std::to_string(s);
+        } else {
+            return std::to_string(std::stoi(reverse,0, DATA_FORMAT));
+        }
+    } catch (const std::out_of_range &e) {
+        RLOGD("out of range: %s, line: %s", e.what(), __LINE__);
+        return std::string("Error.");
+    } catch (const std::invalid_argument &e) {
+        RLOGD("invalid argument: %s, line: %s", e.what(), __LINE__);
+        return std::string("Error.");
+    }
+}
+
+std::string NetworkInfoUrcParser::oneBlockFrom2Byte(std::string label, std::string data, int start,bool sig, int dataLength) {
+    std::string block(label);
+    for (int i = 0; i < dataLength; i++) {
+        if ((dataLength > MAX_DATA_PER_LINE) && (0 == i % MAX_DATA_PER_LINE)) {
+            block += std::string("\n");
+        }
+        block += getValueFrom2Byte(data, start, sig);
+        start += DATA_OFFSET_4;
+        if (i != dataLength - 1) {
+            block += std::string(", ");
+        }
+    }
+    return block + std::string("\n");
+}
+
+std::string NetworkInfoUrcParser::getValueFromByte(std::string data, int start, bool sig) {
+    if (data.length() < start + DATA_OFFSET_2) {
+        return std::string("0");
+    }
+    try {
+        std::string sub = data.substr(start, start + DATA_OFFSET_2);
+        if (sig) {
+            int16_t s = std::stoi(sub, 0, DATA_FORMAT);
+            int8_t b = (int8_t) s;
+            return std::to_string(b); //???
+        } else {
+            return std::to_string(std::stoi(sub, 0, DATA_FORMAT));
+        }
+    } catch (const std::out_of_range &e) {
+        RLOGD("out of range: %s, line: %s", e.what(), __LINE__);
+        return std::string("Error.");
+    } catch (const std::invalid_argument &e) {
+        RLOGD("invalid argument: %s, line: %s", e.what(), __LINE__);
+        return std::string("Error.");
+    }
+}
+
+std::string NetworkInfoUrcParser::oneBlockFromByte(std::string label, std::string data, int start,bool sig, int dataLength) {
+    std::string block(label);
+    for (int i = 0; i < dataLength; i++) {
+        if (dataLength > MAX_DATA_PER_LINE && 0 == i % MAX_DATA_PER_LINE) {
+            block += "\n";
+        }
+        block.append(getValueFromByte(data, start, sig));
+        start += DATA_OFFSET_2;
+        if (i != dataLength - 1) {
+            block += std::string(", ");
+        }
+    }
+    return block + std::string("\n");
+}
+
+std::string NetworkInfoUrcParser::parseElement(int type, std::string label, int count){
+    std::string value("");
+    switch (type) {
+    case TYPE_UINT8:
+    {
+        value = oneBlockFromByte(label, mRawString, mOffset, false, count);
+        mOffset += 2 * count;
+        break;
+    }
+    case TYPE_UINT16:
+    {
+        if (ALIGN_MENT_ENABLE) {
+            mOffset = (mOffset + 3) & ~3;
+        }
+        value = oneBlockFrom2Byte(label, mRawString, mOffset, false, count);
+        mOffset += 4 * count;
+        break;
+    }
+    case TYPE_UINT32:
+    {
+        if (ALIGN_MENT_ENABLE) {
+            mOffset = (mOffset + 7) & ~7;
+        }
+        value = oneBlockFrom4Byte(label, mRawString, mOffset, false, count);
+        mOffset += 8 * count;
+        break;
+    }
+    case TYPE_INT8:
+    {
+        value = oneBlockFromByte(label, mRawString, mOffset, true, count);
+        mOffset += 2 * count;
+        break;
+    }
+    case TYPE_INT16:
+    {
+        if (ALIGN_MENT_ENABLE) {
+            mOffset = (mOffset + 3) & ~3;
+        }
+        value = oneBlockFrom2Byte(label, mRawString, mOffset, true, count);
+        mOffset += 4 * count;
+        break;
+    }
+    case TYPE_INT32:
+    {
+        if (ALIGN_MENT_ENABLE) {
+            mOffset = (mOffset + 7) & ~7;
+        }
+        value = oneBlockFrom4Byte(label, mRawString, mOffset, true, count);
+        mOffset += 8 * count;
+        break;
+    }
+    case TYPE_LONG:
+    {
+        if (ALIGN_MENT_ENABLE) {
+            mOffset = (mOffset + 7) & ~7;
+        }
+        std::string strRscp = getValueFrom4Byte(mRawString, mOffset, true);
+        long rscp = 0;
+        try {
+            rscp = std::stol(strRscp) / 4096;
+        } catch (const std::out_of_range &e) {
+            RLOGD("out of range: %s, line: %s", e.what(), __LINE__);
+        } catch (const std::invalid_argument &e) {
+            RLOGD("invalid argument: %s, line: %s", e.what(), __LINE__);
+        }
+        value = label + std::to_string(rscp) + std::string("\n");
+        mOffset += 8;
+        break;
+    }
+    case TYPE_FLOAT:
+    {
+        if (ALIGN_MENT_ENABLE) {
+            mOffset = (mOffset + 7) & ~7;
+        }
+        std::string strEcno = getValueFrom4Byte(mRawString, mOffset, true);
+        float ecno = 0;
+        try {
+            ecno = std::stof(strEcno) / 4096;
+        } catch (const std::out_of_range &e) {
+            RLOGD("out of range: %s, line: %s", e.what(), __LINE__);
+        } catch (const std::invalid_argument &e) {
+            RLOGD("invalid argument: %s, line: %s", e.what(), __LINE__);
+        }
+        value = label + std::to_string(ecno) + std::string("\n");
+        mOffset += 8;
+        break;
+    }
+    case TYPE_STRING:
+    {
+        value = label;
+        for (int i = 0; i < count; i++) {
+            std::string str = getValueFromByte(mRawString, mOffset, false);
+            mOffset += 2;
+            try {
+                short s = std::stoi(str);
+                value.push_back((char) s); //???
+            } catch (const std::out_of_range &e) {
+                RLOGD("out of range: %s, line: %s", e.what(), __LINE__);
+                break;
+            } catch (const std::invalid_argument &e) {
+                RLOGD("invalid argument: %s, line: %s", e.what(), __LINE__);
+                break;
+            }
+        }
+        value += std::string("\n");
+        break;
+    }
+    case TYPE_ALIGNMENT:
+    {
+        if (ALIGN_MENT_ENABLE) {
+            mOffset = (mOffset + 7) & ~7;
+        }
+        break;
+    }
+    default:
+        break;
+    }
+    mResult.append(value);
+    return value;
+}
+
+std::string NetworkInfoUrcParser::parseElement(int type, std::string label) {
+    return parseElement(type, label, 1);
+}
+
+std::string NetworkInfoUrcParser::getCellSelInfo() {
+    parseElement(TYPE_UINT8, "crh: ");
+    parseElement(TYPE_UINT8, "ms_txpwr: ");
+    parseElement(TYPE_UINT8, "rxlev_access_min: ");
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::getChDscrInfo() {
+    parseElement(TYPE_UINT8,  "channel_type: ");
+    parseElement(TYPE_UINT8,  "tn: ");
+    parseElement(TYPE_UINT8,  "tsc: ");
+    parseElement(TYPE_UINT8,  "hopping_flag: ");
+    parseElement(TYPE_UINT8,  "maio: ");
+    parseElement(TYPE_UINT8,  "hsn: ");
+    parseElement(TYPE_UINT8,  "num_of_carriers: ");
+    parseElement(TYPE_UINT16, "arfcn:", 64);
+    parseElement(TYPE_INT8,   "is_BCCH_arfcn_valid: ");
+    parseElement(TYPE_UINT16, "BCCH_arfcn: ");
+    parseElement(TYPE_UINT8,  "cipher_algo: ");
+    parseElement(TYPE_UINT8,  "imeisv_digit: ", 16);
+    parseElement(TYPE_UINT8,  "channel_mode: ");
+    if (AMR_SUPPORT_ENABLE) {
+        parseElement(TYPE_INT8,  "amr_valid: ");
+        parseElement(TYPE_UINT8, "mr_ver: ");
+        parseElement(TYPE_INT8,  "nscb: ");
+        parseElement(TYPE_INT8,  "icmi: ");
+        parseElement(TYPE_UINT8, "start_codec_mode: ");
+        parseElement(TYPE_UINT8, "acs: ");
+        parseElement(TYPE_UINT8, "threshold:", 3);
+        parseElement(TYPE_UINT8, "hysteresis:", 3);
+    }
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::getRACHCtrlInfo() {
+    parseElement(TYPE_UINT8, "max_retrans: ");
+    parseElement(TYPE_UINT8, "tx_integer: ");
+    parseElement(TYPE_UINT8, "cba: ");
+    parseElement(TYPE_UINT8, "re: ");
+    parseElement(TYPE_UINT8, "acc_class:", 2);
+    parseElement(TYPE_INT8,  "CB_supported: ");
+    return mResult;
+}
+
+
+std::string NetworkInfoUrcParser::getLAIInfo() {
+    parseElement(TYPE_UINT8, "mcc:", 3);
+    parseElement(TYPE_UINT8, "mnc:", 3);
+    parseElement(TYPE_UINT8, "lac:", 2);
+    parseElement(TYPE_UINT16, "cell_id: ");
+    parseElement(TYPE_UINT8, "nc_info_index: ");
+    parseElement(TYPE_UINT8, "rac: ");
+    parseElement(TYPE_UINT8, "nmo: ");
+    parseElement(TYPE_UINT8, "supported_Band: ");
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::getRadioLinkInfo() {
+    parseElement(TYPE_UINT16, "max_value: ");
+    parseElement(TYPE_INT16, "current_value: ");
+    parseElement(TYPE_UINT8, "dtx_ind: ");
+    parseElement(TYPE_UINT8, "dtx_used: ");
+    parseElement(TYPE_INT8, "is_dsf: ");
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::getMeasRepInfo() {
+    parseElement(TYPE_UINT8, "rr_state: ");
+    if (IS_MOLY) {
+        parseElement(TYPE_UINT8, "meas_mode: ");
+    }
+    parseElement(TYPE_UINT16, "serving_arfcn: ");
+    parseElement(TYPE_UINT8, "serving_bsic: ");
+    parseElement(TYPE_UINT8, "serving_current_band: ");
+    parseElement(TYPE_UINT8, "serv_gprs_supported: ");
+    parseElement(TYPE_INT16, "serv_rla_in_quarter_dbm: ");
+    if (IS_MOLY) {
+        parseElement(TYPE_UINT8, "serv_rla_reported_value: ");
+    }
+    parseElement(TYPE_INT8, "is_serv_BCCH_rla_valid: ");
+    parseElement(TYPE_INT16, "serv_BCCH_rla_in_dedi_state: ");
+    parseElement(TYPE_UINT8, "quality: ");
+    parseElement(TYPE_INT8, "gprs_pbcch_present: ");
+    parseElement(TYPE_INT8, "gprs_c31_c32_enable: ");
+    if (!IS_MOLY) {
+        parseElement(TYPE_INT16, "c31:", 32);
+    }
+    parseElement(TYPE_INT16, "c1_serv_cell: ");
+    parseElement(TYPE_INT16, "c2_serv_cell: ");
+    parseElement(TYPE_INT16, "c31_serv_cell: ");
+    parseElement(TYPE_UINT8, "num_of_carriers: ");
+    parseElement(TYPE_UINT16, "nc_arfcn:", 32);
+    parseElement(TYPE_INT16, "rla_in_quarter_dbm:", 32);
+    if (IS_MOLY) {
+        parseElement(TYPE_UINT8, "rla_in_reported_value: ", 32);
+    }
+    parseElement(TYPE_UINT8, "nc_info_status:", 32);
+    parseElement(TYPE_UINT8, "nc_bsic:", 32);
+    parseElement(TYPE_INT32, "frame_offset:", 32);
+    parseElement(TYPE_INT32, "ebit_offset:", 32);
+    parseElement(TYPE_INT16, "c1:", 32);
+    parseElement(TYPE_INT16, "c2:", 32);
+    if (IS_MOLY) {
+        parseElement(TYPE_INT16, "c31:", 32);
+    }
+    parseElement(TYPE_UINT8, "multiband_report: ");
+    parseElement(TYPE_UINT8, "timing_advance: ");
+    parseElement(TYPE_INT16, "tx_power_level: ");
+    parseElement(TYPE_INT16, "serv_rla_full_value_in_quater_dbm: ");
+    parseElement(TYPE_UINT8, "nco: ");
+    parseElement(TYPE_UINT8, "rxqual_sub: ");
+    parseElement(TYPE_UINT8, "rxqual_full: ");
+    parseElement(TYPE_INT16, "using_tx_power_in_dbm: ");
+    parseElement(TYPE_INT8, "amr_info_valid: ");
+    parseElement(TYPE_UINT8, "cmr_cmc_cmiu_cmid: ");
+    parseElement(TYPE_UINT8, "c_i: ");
+    parseElement(TYPE_UINT16, "icm: ");
+    parseElement(TYPE_UINT16, "acs: ");
+    parseElement(TYPE_INT8, "dl_dtx_used: ");
+    if (FWPNC_LAI_INFO_ENABLE) {
+        parseElement(TYPE_UINT8, "num_of_nc_lai: ");
+        mResult.append("nc_lai:\n");
+        for (int i = 0; i < 6; i++) {
+            parseElement(TYPE_UINT8, std::string("nc_lai[") + std::to_string(i) + std::string("]:\n") + std::string("mcc:"), 3);
+            parseElement(TYPE_UINT8, "mnc:", 3);
+            parseElement(TYPE_UINT8, "lac:", 2);
+            parseElement(TYPE_UINT16, "cell_id: ");
+            parseElement(TYPE_UINT8, "nc_info_index: ");
+        }
+    }
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::getCaListInfo() {
+    parseElement(TYPE_UINT8, "valid: ");
+    parseElement(TYPE_UINT8, "number_of_channels: ");
+    parseElement(TYPE_UINT16, "arfcn_list:", 64);
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::getControlMsgInfo() {
+    parseElement(TYPE_UINT8, "msg_type: ");
+    parseElement(TYPE_UINT8, "rr_cause: ");
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::getSI2QInfo() {
+    parseElement(TYPE_INT8, "present: ");
+    parseElement(TYPE_UINT8, "no_of_instance: ");
+    parseElement(TYPE_INT8, "emr_report: ");
+    parseElement(TYPE_INT8, "pemr_report: ");
+    parseElement(TYPE_INT8, "umts_parameter_exist: ");
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::getMIInfo() {
+    parseElement(TYPE_INT8, "present: ");
+    parseElement(TYPE_UINT8, "no_of_instance: ");
+    parseElement(TYPE_INT8, "emr_report: ");
+    parseElement(TYPE_INT8, "umts_parameter_exist: ");
+    return mResult;
+}
+
+
+std::string NetworkInfoUrcParser::getBLKInfo() {
+    parseElement(TYPE_UINT8, "ul_coding_scheme: ");
+    parseElement(TYPE_UINT8, "ul_cv: ");
+    parseElement(TYPE_UINT8, "ul_tlli: ");
+    parseElement(TYPE_UINT16, "ul_bsn1: ");
+    if (GPRS_MODE_ENABLE) {
+        parseElement(TYPE_UINT16, "ul_bsn2: ");
+        parseElement(TYPE_UINT8, "ul_cps: ");
+        parseElement(TYPE_UINT8, "ul_rsb: ");
+        parseElement(TYPE_UINT8, "ul_spb: ");
+    }
+    parseElement(TYPE_UINT8, "dl_c_value_in_rx_level: ");
+    parseElement(TYPE_UINT8, "dl_rxqual: ");
+    parseElement(TYPE_UINT8, "dl_sign_var: ");
+    parseElement(TYPE_UINT8, "dl_coding_scheme: ");
+    parseElement(TYPE_UINT8, "dl_fbi: ");
+    parseElement(TYPE_UINT16, "dl_bsn1: ");
+    if (GPRS_MODE_ENABLE) {
+        parseElement(TYPE_UINT16, "dl_bsn2: ");
+        parseElement(TYPE_UINT8, "dl_cps: ");
+        parseElement(TYPE_UINT8, "dl_gmsk_mean_bep_lev: ");
+        parseElement(TYPE_UINT8, "dl_8psk_mean_bep_lev: ");
+        parseElement(TYPE_UINT8, "dl_tn_mean_bep_lev:", 8);
+    }
+    parseElement(TYPE_UINT8, "dl_tn_interference_lev:", 8);
+    return mResult;
+}
+
+
+std::string NetworkInfoUrcParser::getTBFInfo() {
+    parseElement(TYPE_UINT8, "tbf_mode: ");
+    parseElement(TYPE_UINT8, "ul_tbf_status: ");
+    parseElement(TYPE_UINT8, "ul_rel_cause: ");
+    parseElement(TYPE_UINT8, "ul_ts_allocation: ");
+    parseElement(TYPE_UINT8, "ul_rlc_mode: ");
+    parseElement(TYPE_UINT8, "ul_mac_mode: ");
+    parseElement(TYPE_UINT16, "number_rlc_octect: ");
+    parseElement(TYPE_UINT8, "ul_tfi: ");
+    parseElement(TYPE_UINT8, "ul_granularity: ");
+    parseElement(TYPE_UINT8, "ul_usf: ");
+    parseElement(TYPE_UINT8, "ul_tai: ");
+    parseElement(TYPE_UINT16, "ul_tqi: ");
+    parseElement(TYPE_UINT16, "ul_window_size: ");
+    parseElement(TYPE_UINT8, "dl_tbf_status: ");
+    parseElement(TYPE_UINT8, "dl_rel_cause: ");
+    parseElement(TYPE_UINT8, "dl_ts_allocation: ");
+    parseElement(TYPE_UINT8, "dl_rlc_mode: ");
+    parseElement(TYPE_UINT8, "dl_mac_mode: ");
+    parseElement(TYPE_UINT8, "dl_tfi: ");
+    parseElement(TYPE_UINT8, "dl_tai: ");
+    parseElement(TYPE_UINT16, "dl_window_size: ");
+    if (GPRS_MODE_ENABLE) {
+        parseElement(TYPE_UINT8, "dl_out_of_memory: ");
+    }
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::getGPRSGenInfo() {
+    parseElement(TYPE_UINT32, "t3192: ");
+    parseElement(TYPE_UINT32, "t3168: ");
+    parseElement(TYPE_UINT8, "rp: ");
+    parseElement(TYPE_UINT8, "gprs_support: ");
+    parseElement(TYPE_UINT8, "egprs_support: ");
+    parseElement(TYPE_UINT8, "sgsn_r: ");
+    parseElement(TYPE_UINT8, "pfc_support: ");
+    parseElement(TYPE_UINT8, "epcr_support: ");
+    parseElement(TYPE_UINT8, "bep_period: ");
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::get3GGeneralInfo() {
+    if (getValueFromByte(mRawString, mOffset, false).compare("255") == 0) {
+        // "FF" means Invalid service_status
+        mResult.append("service_status:\n");
+        mOffset += 2;
+    } else {
+        parseElement(TYPE_UINT8, "service_status: ");
+    }
+
+    if (getValueFromByte(mRawString, mOffset, false).compare("255") == 0) {
+        // "FF" means Invalid umts_rrc_state
+        mResult.append("umts_rrc_state:\n");
+        mOffset += 2;
+    } else {
+        parseElement(TYPE_UINT8, "umts_rrc_state: ");
+    }
+
+    if (getValueFrom2Byte(mRawString, mOffset, false).compare("65535") == 0) {
+        // "FFFF" means Invalid uarfcn_DL
+        mResult.append("uarfcn_DL:\n");
+        mOffset += 4;
+    } else {
+        parseElement(TYPE_UINT16, "uarfcn_DL: ");
+    }
+
+    if (getValueFrom2Byte(mRawString, mOffset, false).compare("65535") == 0) {
+        // "FFFF" means Invalid psc
+        mResult.append("psc:\n");
+        mOffset += 4;
+    } else {
+        parseElement(TYPE_UINT16, "psc: ");
+    }
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::getSlceVoiceInfo() {
+    if (IS_MOLY) {
+        parseElement(TYPE_UINT8, "ULAMRType: ");
+        parseElement(TYPE_UINT8, "DLAMRType: ");
+    } else {
+        parseElement(TYPE_UINT8, "voice: ");
+    }
+    return mResult;
+}
+
+
+std::string NetworkInfoUrcParser::getSecurityConfigInfo() {
+    parseElement(TYPE_UINT8, "Ciphering Algorithm: ");
+    parseElement(TYPE_UINT8, "Integrity Algorithm: ");
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::get3GMmEmInfo() {
+    parseElement(TYPE_UINT8, "t3212: ");
+    parseElement(TYPE_UINT8, "ATT_flag: ");
+    parseElement(TYPE_UINT8, "MM_reject_cause: ");
+    parseElement(TYPE_UINT8, "MM_state: ");
+    parseElement(TYPE_UINT8, "MCC:", 3);
+    parseElement(TYPE_UINT8, "MNC:", 3);
+    parseElement(TYPE_UINT8, "LOC:", 2);
+    parseElement(TYPE_UINT8, "rac: ");
+    parseElement(TYPE_UINT8, "TMSI:", 4);
+    parseElement(TYPE_UINT8, "is_t3212_running:");
+    parseElement(TYPE_UINT16, "t3212_timer_value:");
+    parseElement(TYPE_UINT16, "t3212_passed_time:");
+    parseElement(TYPE_UINT8, "common_access_class: ");
+    parseElement(TYPE_UINT8, "cs_access_class: ");
+    parseElement(TYPE_UINT8, "ps_access_class: ");
+    mOffset += DATA_OFFSET_8;
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::getSmEmInfo() {
+    parseElement(TYPE_UINT8, "num_of_active_pdp_context: ");
+    parseElement(TYPE_ALIGNMENT, "");
+    for (int i = 0; i < 11; i++) {
+        mResult.append("--------------------\n");
+        mResult.append(std::string("pdp[") + std::to_string(i) + std::string("]:\n"));
+        parseElement(TYPE_UINT8, "pdp_index: ");
+        parseElement(TYPE_UINT8, "nsapi: ");
+        if (IS_MOLY) {
+            parseElement(TYPE_UINT8, "ti_value: ");
+        }
+        parseElement(TYPE_UINT8, "pdp_context_status: ");
+        if (IS_MOLY) {
+            parseElement(TYPE_UINT8, "context_type: ");
+            parseElement(TYPE_UINT8, "initiated_by: ");
+            parseElement(TYPE_UINT8, "pdp_addr_type: ");
+        }
+        parseElement(TYPE_UINT8, "ip:", 16);
+        parseElement(TYPE_UINT16, "sdu_size:");
+        parseElement(TYPE_STRING, "apn: ", 100);
+        parseElement(TYPE_UINT8, "sm_cause: ");
+        if (IS_MOLY) {
+            mOffset += 249 * 2;
+        } else {
+            mOffset += 77 * 2; // Skip the rest 77 bytes
+        }
+    }
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::getGmmEmInfo() {
+    parseElement(TYPE_UINT16, "ready_timer: ");
+    parseElement(TYPE_UINT16, "rau_timer: ");
+    parseElement(TYPE_UINT8, "ms_state: ");
+    parseElement(TYPE_INT8, "is_rau_timer_running: ");
+    parseElement(TYPE_UINT16, "rau_timer_passed_time: ");
+    parseElement(TYPE_UINT8, "attach_req_mobile_identity: ");
+    if (WISDOM_EM && ADVANCED_EM) {
+        parseElement(TYPE_UINT8, "ptmsi: ", 4);
+        parseElement(TYPE_UINT8, "attach_rej_cause: ");
+        parseElement(TYPE_UINT8, "rau_rej_cause: ");
+        parseElement(TYPE_UINT8, "gprs_update_status: ");
+        parseElement(TYPE_UINT8, "cipher_algo: ");
+        parseElement(TYPE_UINT8, "attach_type: ");
+        parseElement(TYPE_UINT8, "gmm_state: ");
+        parseElement(TYPE_UINT8, "gprs_attach_status: ");
+    }
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::get3GTcmMmiEmInfo() {
+    parseElement(TYPE_UINT8, "num_of_valid_entries: ");
+    for (int i = 0; i < 3; i++) {
+        parseElement(TYPE_UINT8, std::string("nsapi") + std::to_string(i) + std::string(":"));
+        parseElement(TYPE_UINT8, std::string("data_speed_value") + std::to_string(i) + std::string(":"));
+    }
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::get3GCsceEmInfoMultiPlmn() {
+    parseElement(TYPE_UINT8, "multi_plmn_count: ");
+    for (int i = 0; i < 6; i++) {
+        parseElement(TYPE_UINT8, std::string("mcc1_") + std::to_string(i) + std::string(":"));
+        parseElement(TYPE_UINT8, std::string("mcc2_") + std::to_string(i) + std::string(":"));
+        parseElement(TYPE_UINT8, std::string("mcc3_") + std::to_string(i) + std::string(":"));
+        parseElement(TYPE_UINT8, std::string("mnc1_") + std::to_string(i) + std::string(":"));
+        parseElement(TYPE_UINT8, std::string("mnc2_") + std::to_string(i) + std::string(":"));
+        parseElement(TYPE_UINT8, std::string("mnc3_") + std::to_string(i) + std::string(":"));
+    }
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::get3GMemeEmInfoUmtsCellStatus() {
+    parseElement(TYPE_INT8, "tx_power: ");
+    parseElement(TYPE_UINT8, "num_cells: ");
+    parseElement(TYPE_ALIGNMENT, "");
+    for (int i = 0; i < 32; i++) {
+        mResult.append("--------------------\n");
+        mResult.append(std::string("umts_cell_list[") + std::to_string(i) + std::string("]:\n"));
+        parseElement(TYPE_UINT16, "UARFCN: ");
+        parseElement(TYPE_UINT16, "PSC: ");
+        parseElement(TYPE_INT32, "RSCP: ");
+        parseElement(TYPE_INT32, "ECNO: ");
+        parseElement(TYPE_UINT8, "cell_type: ");
+        parseElement(TYPE_UINT8, "Band: ");
+        parseElement(TYPE_INT32, "RSSI: ");
+        parseElement(TYPE_UINT32, "Cell_identity: ");
+
+        int validity = readIntegerFromByte();
+        int lacValid = validity & 0x01;
+        int racValid = validity & 0x02;
+        int uraValid = validity & 0x04;
+
+        parseElement(TYPE_UINT8, "num_plmn_id: ");
+        for (int j = 0; j < 6; j++) {
+            parseElement(TYPE_UINT16, std::string("plmn_id_list[") + std::to_string(j) + std::string("].mcc: "));
+            parseElement(TYPE_UINT16, std::string("plmn_id_list[") + std::to_string(j) + std::string("].mnc: "));
+        }
+
+        if (lacValid != 0) {
+            parseElement(TYPE_UINT16, "lac: ");
+        } else {
+            mResult.append("lac: invalid\n");
+            mOffset += DATA_OFFSET_4;
+        }
+
+        if (racValid != 0) {
+            parseElement(TYPE_UINT8, "rac: ");
+        } else {
+            mResult.append("rac: invalid\n");
+            mOffset += DATA_OFFSET_2;
+        }
+
+        if (uraValid != 0) {
+            parseElement(TYPE_UINT8, "num_ura_id: ");
+            for (int j = 0; j < 8; j++) {
+                int numBits = readIntegerFromByte();
+                if (numBits == 1) {
+                    parseElement(TYPE_UINT8, std::string("uraIdentity[") + std::to_string(j) + std::string("]: "));
+                    mOffset += DATA_OFFSET_2; // skip high byte
+                } else {
+                    parseElement(TYPE_UINT8, std::string("uraIdentity[") + std::to_string(j) + std::string("]: "), 2);
+                }
+            }
+            mOffset += DATA_OFFSET_4;
+        } else {
+            mResult.append("ura: invalid\n");
+            mOffset += 27 * 2;
+        }
+    }
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::get3GMemeEmPeriodicBlerReportInd() {
+    parseElement(TYPE_UINT8, "num_trch: ");
+    for (int i = 0; i < 8; i++) {
+        parseElement(TYPE_ALIGNMENT, "");
+        parseElement(TYPE_UINT8, std::string("TrCHId") + std::to_string(i) + std::string(":"));
+        parseElement(TYPE_UINT32, std::string("TotalCRC") + std::to_string(i) + std::string(":"));
+        parseElement(TYPE_UINT32, std::string("BadCRC") + std::to_string(i) + std::string(":"));
+    }
+    return mResult;
+}
+
+
+std::string NetworkInfoUrcParser::get3GUrrUmtsSrncId() {
+    parseElement(TYPE_UINT16, "srnc: ");
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::get3GSlceEmPsDataRateStatusInd() {
+    parseElement(TYPE_UINT8, "ps_number: ");
+    parseElement(TYPE_ALIGNMENT, "");
+    for (int i = 0; i < 8; i++) {
+        parseElement(TYPE_UINT8, std::string("RAB_ID") + std::to_string(i) + std::string(":"));
+        parseElement(TYPE_INT8, std::string("RB_UD") + std::to_string(i) + std::string(":"));
+        parseElement(TYPE_UINT32, std::string("DL_rate") + std::to_string(i) + std::string(":"));
+        parseElement(TYPE_UINT32, std::string("UL_rate") + std::to_string(i) + std::string(":"));
+    }
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::get3GMemeEmInfoHServCellInd() {
+    parseElement(TYPE_UINT16, "HSDSCH_Serving_UARFCN: ");
+    parseElement(TYPE_UINT16, "HSDSCH_Serving_PSC: ");
+    parseElement(TYPE_UINT16, "EDCH_Serving_UARFCN: ");
+    parseElement(TYPE_UINT16, "EDCH_Serving_PSC: ");
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::get3GHandoverSequenceIndStuct() {
+    parseElement(TYPE_UINT8, "service_status: ");
+    parseElement(TYPE_ALIGNMENT, "");
+    parseElement(TYPE_UINT16, "[old_cell_info:-----]\nprimary_uarfcn_DL: ");
+    parseElement(TYPE_UINT16, "working_uarfcn: ");
+    parseElement(TYPE_UINT16, "physicalCellId: ");
+    parseElement(TYPE_UINT16, "[target_cell_info:-----]\nprimary_uarfcn_DL: ");
+    parseElement(TYPE_UINT16, "working_uarfcn: ");
+    parseElement(TYPE_UINT16, "physicalCellId: ");
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::getCtrlchanInfo() {
+    parseElement(TYPE_UINT8, "mscr: ");
+    parseElement(TYPE_UINT8, "att: ");
+    parseElement(TYPE_UINT8, "bs_ag_blks_res: ");
+    parseElement(TYPE_UINT8, "ccch_conf: ");
+    parseElement(TYPE_UINT8, "cbq2: ");
+    parseElement(TYPE_UINT8, "bs_pa_mfrms: ");
+    parseElement(TYPE_UINT8, "t3212: ");
+    return mResult;
+}
+
+std::string NetworkInfoUrcParser::parseInfo(int type, std::string info, int simType) {
+    RLOGD("NetworkInfo ------ Type is: %d, simtype: %d",type, simType);
+    RLOGD("NetworkInfo ------ Data is:\n");
+    RLOGD("%s\n",info.c_str());
+    RLOGD("NetworkInfo ---------------------------");
+    mRawString = info;
+    mResult = "";
+    mOffset = 0;
+
+    switch (type) {
+    case Content::CELL_INDEX:
+        return getCellSelInfo();
+    case Content::CHANNEL_INDEX:
+        return getChDscrInfo();
+    case Content::CTRL_INDEX:
+        return getCtrlchanInfo();
+    case Content::RACH_INDEX:
+        return getRACHCtrlInfo();
+    case Content::LAI_INDEX:
+        return getLAIInfo();
+    case Content::RADIO_INDEX:
+        return getRadioLinkInfo();
+    case Content::MEAS_INDEX:
+        return getMeasRepInfo();
+    case Content::CA_INDEX:
+        return getCaListInfo();
+    case Content::CONTROL_INDEX:
+        return getControlMsgInfo();
+    case Content::SI2Q_INDEX:
+        return getSI2QInfo();
+    case Content::MI_INDEX:
+        return getMIInfo();
+    case Content::BLK_INDEX:
+        return getBLKInfo();
+    case Content::TBF_INDEX:
+        return getTBFInfo();
+    case Content::GPRS_INDEX:
+        return getGPRSGenInfo();
+    case Content::URR_3G_GENERAL_INDEX:
+        return get3GGeneralInfo();
+    case Content::GMM_INFO_INDEX:
+        return getGmmEmInfo();
+    default:
+        break;
+    }
+
+    if (type == Content::SM_INFO_INDEX) {
+        return getSmEmInfo();
+    } else if (type == Content::SLCE_VOICE_INDEX) {
+        return getSlceVoiceInfo();
+    } else if (type == Content::SECURITY_CONFIGURATION_INDEX) {
+        return getSecurityConfigInfo();
+    } else if (type == Content::MM_INFO_INDEX) {
+        return get3GMmEmInfo();
+    } else if (type == Content::TCM_MMI_INDEX) {
+        return get3GTcmMmiEmInfo();
+    } else if (type == Content::CSCE_MULTIPLMN_INDEX) {
+        return get3GCsceEmInfoMultiPlmn();
+    } else if (type == Content::PERIOD_IC_BLER_REPORT_INDEX) {
+        return get3GMemeEmPeriodicBlerReportInd();
+    } else if (type == Content::URR_UMTS_SRNC_INDEX) {
+        return get3GUrrUmtsSrncId();
+    } else if (type == Content::HSERV_CELL_INDEX) {
+        return get3GMemeEmInfoHServCellInd();
+    } else if (type == Content::CSCE_NEIGH_CELL_STATUS_INDEX) {
+        return getxGCsceEMNeighCellSStatusIndStructSize(
+                ModemCategory::getModemType() == MODEM_TD);
+    } else if (type == Content::CSCE_SERV_CELL_STATUS_INDEX) {
+        return get3GCsceEMServCellSStatusInd(
+                ModemCategory::getModemType() == MODEM_TD);
+    }
+
+    if (ModemCategory::getModemType() == MODEM_FDD) {
+        if (type == Content::UMTS_CELL_STATUS_INDEX) {
+            return get3GMemeEmInfoUmtsCellStatus();
+        } else if (type == Content::PSDATA_RATE_STATUS_INDEX) {
+            return get3GSlceEmPsDataRateStatusInd();
+        }
+    } else if (ModemCategory::getModemType() == MODEM_TD) {
+        if (type == Content::HANDOVER_SEQUENCE_INDEX) {
+            return get3GHandoverSequenceIndStuct();
+        } else if (type == Content::UL_ADM_POOL_STATUS_INDEX) {
+            return get3GUl2EmAdmPoolStatusIndStruct();
+        } else if (type == Content::UL_PSDATA_RATE_STATUS_INDEX) {
+            return get3GUl2EmPsDataRateStatusIndStruct();
+        } else if (type == Content::UL_HSDSCH_RECONFIG_STATUS_INDEX) {
+            return get3Gul2EmHsdschReconfigStatusIndStruct();
+        } else if (type == Content::UL_URLC_EVENT_STATUS_INDEX) {
+            return get3GUl2EmUrlcEventStatusIndStruct();
+        } else if (type == Content::UL_PERIOD_IC_BLER_REPORT_INDEX) {
+            return get3GUl2EmPeriodicBlerReportInd();
+        }
+    }
+
+    return "";
+}
+
+int NetworkInfoUrcParser::readIntegerFromByte() {
+    if (mRawString.length() < mOffset + 2) {
+        mOffset += 2;
+        return 0;
+    }
+    std::string str = mRawString.substr(mOffset, mOffset + 2);
+    mOffset += 2;
+    int ret = 0;
+    try {
+        ret = std::stoi(str,0, 16);
+    } catch (const std::out_of_range &e) {
+        RLOGD("out of range: %s, line: %s", e.what(), __LINE__);
+        ret = 0;
+    } catch (const std::invalid_argument &e) {
+        RLOGD("invalid argument: %s, line: %s", e.what(), __LINE__);
+        ret = 0;
+    }
+    return ret;
+}
+
+int NetworkInfoUrcParser::readIntegerFrom2Byte() {
+    if (mRawString.length() < mOffset + DATA_OFFSET_4) {
+        mOffset += 4;
+        return 0;
+    }
+    try {
+        std::string low = mRawString.substr(mOffset, mOffset + DATA_OFFSET_2);
+        std::string high = mRawString.substr(mOffset + DATA_OFFSET_2, mOffset + DATA_OFFSET_4);
+        std::string reverse = high + low;
+        mOffset += 4;
+        int i = std::stoi(reverse,0, DATA_FORMAT);
+        int16_t s = (int16_t) i;
+        return s;
+    } catch (const std::out_of_range &e) {
+        RLOGD("out of range: %s, line: %s", e.what(), __LINE__);
+        return 0;
+    } catch (const std::invalid_argument &e) {
+        RLOGD("invalid argument: %s, line: %s", e.what(), __LINE__);
+        return 0;
+    }
+}
+
+std::string NetworkInfoUrcParser::decodeMcc(int value){
+    value += 111;
+    if (value % 10 == 0) {
+        value -= 10;
+    }
+    if ((value / 10) % 10 == 0) {
+        value -= 100;
+    }
+    if ((value / 100) % 10 == 0) {
+        value -= 1000;
+    }
+    return (std::string("000") + std::to_string(value)).substr(std::to_string(value).length());
+}
+
+std::string NetworkInfoUrcParser::decodeMnc(int value){
+    value += 11;
+    if (value % 10 == 0) {
+        value -= 10;
+    }
+    if ((value / 10) % 10 == 0) {
+        value -= 100;
+    }
+    return (std::string("00") + std::to_string(value)).substr(std::to_string(value).length());
+}
+
+std::vector<std::string> NetworkInfoUrcParser::parseSecurityStatus(int type, std::string info) {
+    std::vector<std::string> m2gCipher {"No Ciphering", "A5/1", "A5/2", "A5/3", "A5/4", "A5/5", "A5/6", "A5/7"};
+    std::vector<std::string> m2gGprs {"No Ciphering", "GEA1", "GEA2", "GEA3"};
+    std::vector<std::string> m3gCipher {"No Ciphering", "UEA0", "UEA1", "", "UEA2"};
+    std::vector<std::string> m3gIntegrity {"No Integrity", "UIA1", "UIA2"};
+    std::vector<std::string> m4gEnasCipher {"EEA0(NULL)", "EEA1(SNOW3G)", "EEA2(AES)", "EEA3(ZUC)"};
+    std::vector<std::string> m4gEnasIntegrity {"EIA0(NULL)", "EIA1(SNOW3G)", "EIA2(AES)", "EIA3(ZUC)"};
+    std::vector<std::string> m4gErrcCipher{"EEA0(NULL)", "EEA1(SNOW3G)", "EEA2(AES)", "EEA3(ZUC)"};
+    std::vector<std::string> m4gErrcIntegrity {"EIA0(NULL)", "EIA1(SNOW3G)", "EIA2(AES)", "EIA3(ZUC)"};
+
+    std::vector<std::string> ret {"---", "---"};
+    if (info.empty()) {
+        return ret;
+    }
+    RLOGD("NetworkInfo ------ Type is: %d", type);
+    RLOGD("NetworkInfo ------ Data is:\n");
+    RLOGD("%s\n", info.c_str());
+    RLOGD("NetworkInfo ---------------------------");
+    mRawString = info;
+    mResult.clear();
+    mOffset = 0;
+    int cipherAlgo;
+    int integrityAlgo;
+
+    if (type == Content::CHANNEL_INDEX) {
+        mOffset += 140 * 2;
+        cipherAlgo = readIntegerFromByte();
+        if (cipherAlgo >= 0 && cipherAlgo < m2gCipher.size()) {
+            ret[0] = m2gCipher[cipherAlgo];
+        }
+    } else if (type == Content::LLC_EM_INFO_INDEX) {
+        mOffset += 32 * 2;
+        cipherAlgo = readIntegerFromByte();
+        if (cipherAlgo >= 0 && cipherAlgo < m2gGprs.size()) {
+            ret[0] = m2gGprs[cipherAlgo];
+        }
+    } else if (type == Content::SECURITY_CONFIGURATION_INDEX) {
+        cipherAlgo = readIntegerFromByte();
+        integrityAlgo = readIntegerFromByte();
+        if (cipherAlgo >= 0 && cipherAlgo < m3gCipher.size()) {
+            ret[0] = m3gCipher[cipherAlgo];
+        }
+        if (integrityAlgo >= 0 && integrityAlgo < m3gIntegrity.size()) {
+            ret[1] = m3gIntegrity[integrityAlgo];
+        }
+    } else if (type == Content::ERRC_EM_SEC_PARAM_INDEX) {
+        mOffset += 2 * 2;
+        integrityAlgo = readIntegerFromByte();
+        cipherAlgo = readIntegerFromByte();
+        if (cipherAlgo >= 0 && cipherAlgo < m4gErrcCipher.size()) {
+            ret[0] = m4gErrcCipher[cipherAlgo];
+        } else if (cipherAlgo == 0xFF) {
+            ret[0] = "N/A";
+        }
+        if (integrityAlgo >= 0 && integrityAlgo < m4gErrcIntegrity.size()) {
+            ret[1] = m4gErrcIntegrity[integrityAlgo];
+        } else if (integrityAlgo == 0xFF) {
+            ret[1] = "N/A";
+        }
+    } else if (type == Content::EMM_L4C_EMM_INFO_INDEX) {
+        mOffset += 89 * 2;
+        integrityAlgo = readIntegerFromByte();
+        cipherAlgo = readIntegerFromByte();
+        if (cipherAlgo >= 0 && cipherAlgo < m4gEnasCipher.size()) {
+            ret[0] = m4gEnasCipher[cipherAlgo];
+        } else if (cipherAlgo == 0xFF) {
+            ret[0] = "N/A";
+        }
+        if (integrityAlgo >= 0 && integrityAlgo < m4gEnasIntegrity.size()) {
+            ret[1] = m4gEnasIntegrity[integrityAlgo];
+        } else if (integrityAlgo == 0xFF) {
+            ret[1] = "N/A";
+        }
+    } else if (type == Content::ERRC_EM_ERRC_STATE_INDEX) {
+        ret[0] = getValueFromByte(mRawString, mOffset, false);
+    }
+    return ret;
+}
+
+std::vector<std::string> NetworkInfoUrcParser::parseAntennaDiversity(int type, std::string info) {
+    std::vector<std::string> ret;
+    if (info.empty()) {
+        return ret;
+    }
+    RLOGD("NetworkInfo ------ Type is: %d", type);
+    RLOGD("NetworkInfo ------ Data is:\n");
+    RLOGD("%s\n",info.c_str());
+    RLOGD("NetworkInfo ---------------------------");
+    mRawString = info;
+    mResult.clear();
+    mOffset = 0;
+
+    switch (type) {
+    case Content::EL1TX_EM_TX_INFO_INDEX:
+    {
+        int band = readIntegerFromByte();
+        if (band == 0) {
+            return ret;
+        }
+        mOffset += 15 * 2;
+        int rsrp0 = readIntegerFrom2Byte();
+        int rsrp1 = readIntegerFrom2Byte();
+        int rssi0 = readIntegerFrom2Byte();
+        int rssi1 = readIntegerFrom2Byte();
+        int snr0 = readIntegerFrom2Byte();
+        int snr1 = readIntegerFrom2Byte();
+        int rsrp = readIntegerFrom2Byte();
+        int rsrq = readIntegerFrom2Byte();
+        int snr = readIntegerFrom2Byte();
+        ret = {std::to_string(rsrp0), std::to_string(rsrq), std::to_string(rssi0),
+                std::to_string(snr0), std::to_string(rsrp1), std::to_string(rsrq),
+                std::to_string(rssi1), std::to_string(snr1), std::to_string(rsrp),
+                std::to_string(rsrq), std::to_string(rssi0 > rssi1 ? rssi0 : rssi1),
+                std::to_string(snr)};
+        break;
+    }
+    case Content::UL1_EM_PRX_DRX_MEASURE_INFO_INDEX:
+    {
+        int rscp0 = readIntegerFrom2Byte();
+        int rscp1 = readIntegerFrom2Byte();
+        int pssi0 = readIntegerFrom2Byte();
+        int pssi1 = readIntegerFrom2Byte();
+        ret = {std::to_string(rscp0), std::to_string(pssi0),
+                std::to_string(rscp1), std::to_string(pssi1),
+                std::to_string(rscp0 > rscp1 ? rscp0 : rscp1),
+                std::to_string(pssi0 > pssi1 ? pssi0 : pssi1)};
+        break;
+    }
+    default:
+        break;
+    }
+    return ret;
+}
+
+std::vector<std::vector<std::string>> NetworkInfoUrcParser::parseCdmaInfo(int type, std::string info) {
+    RLOGD("NetworkInfo ------ Type is: %d", type);
+    RLOGD("NetworkInfo ------ Data is:\n");
+    RLOGD("%s\n", info.c_str());
+    RLOGD("NetworkInfo ---------------------------");
+    mRawString = info;
+    utils::tokenize(info,',',mRawValues);
+    mOffset = 1;
+    mType = type;
+
+    switch (type) {
+    case Content::CDMA_1XRTT_RADIO_INDEX:
+        mLabels = {"Channel",
+        "bandClass",
+        "pilotPN",
+        "rxPower_main(dbm)",
+        "rxPower_div(dbm)",
+        "txPower",
+        "tx_Ant",
+        "FER"};
+        break;
+    case Content::CDMA_1XRTT_INFO_INDEX:
+        mLabels = {"cpState",
+        "Calibration",
+        "RfFileMajorVersion",
+        "RfFileMinorVersion",
+        "RfFileValueVersion",
+        "RfFileCustVersion",
+        "sid",
+        "nid",
+        "sysDetIndication",
+        "regZone",
+        "baseLat",
+        "baseLong",
+        "networkPrefSCI",
+        "qpchMode",
+        "mcc",
+        "imsi_11_12",
+        "currentPacketZoneID",
+        "serviceOption",
+        "T_ADD",
+        "T_DROP",
+        "T_COMP",
+        "T_tDROP"};
+        break;
+    case Content::CDMA_1XRTT_SCH_INFO_INDEX:
+        mLabels = {"ForSchMux",
+        "ForSchRc",
+        "ForSchStatus",
+        "ForSchDuration(20ms)",
+        "ForSchRate",
+        "RevSchMux",
+        "RevSchRc",
+        "RevSchStatus",
+        "RevSchDuration(20ms)",
+        "RevSchRate"};
+        break;
+    case Content::CDMA_1XRTT_STATISTICS_INDEX:
+        mLabels = {"total_msg",
+        "error_msg",
+        "acc_1",
+        "acc_2",
+        "acc_8",
+        "dpchloss_count",
+        "dtchloss_count",
+        "idelHO_count",
+        "hardHO_count",
+        "interFreqIdleHO_count",
+        "silentRetryTimeout_count",
+        "T40_count",
+        "T41_count"};
+        break;
+    case Content::CDMA_1XRTT_SERVING_INDEX:
+        mLabels = {"pilotPN",
+        "pilotEcIo",
+        "pilotPhase"};
+        break;
+    case Content::CDMA_EVDO_SERVING_INFO_INDEX:
+        mLabels = {"Band",
+        "Channel",
+        "PilotPN",
+        "PhySubtype",
+        "RSSI_main(dbm)",
+        "RSSI_div(dbm)",
+        "tx_Ant",
+        "SectorID",
+        "SubnetMask",
+        "ColorCode",
+        "UATI",
+        "PilotInc",
+        "ActiveSetWindow",
+        "NeighborSetWindow",
+        "RemainSetWindow",
+        "PilotAdd",
+        "PilotDrop",
+        "PilotDropTimer"};
+        break;
+    case Content::CDMA_EVDO_ACTIVE_SET_INDEX:
+        mLabels = {"PilotPN",
+        "PilotEcIo",
+        "DRC Cover"};
+        break;
+    case Content::CDMA_EVDO_CANDICATE_SET_INDEX:
+        mLabels = {"band",
+        "channel",
+        "pilotPN",
+        "pilotEcIo"};
+        break;
+    case Content::CDMA_EVDO_NEIGHBOR_SET_INDEX:
+        mLabels = {"band",
+        "channel",
+        "pilotPN",
+        "pilotEcIo"};
+        break;
+    case Content::CDMA_EVDO_FL_INDEX:
+        mLabels = {"C/I",
+        "DRC average value",
+        "FTC crc error count",
+        "FTC total count",
+        "Sync crc error ratio"};
+        break;
+    case Content::CDMA_EVDO_RL_INDEX:
+        mLabels = {"Average tbsize",
+        "RTC retransmit count",
+        "RTC transmit total count",
+        "TX power",
+        "pilot power",
+        "RAB=1 ratio"};
+        break;
+    case Content::CDMA_EVDO_STATE_INDEX:
+        mLabels = {"Session State",
+        "AT State",
+        "ALMP State",
+        "Init State",
+        "Idle State",
+        "Overhead State",
+        "Connected State",
+        "Route Update State"};
+        break;
+    default:
+        break;
+    }
+
+    switch (type) {
+    case Content::CDMA_1XRTT_SERVING_INDEX:
+        return parse1xRttServing();
+    case Content::CDMA_EVDO_ACTIVE_SET_INDEX:
+    case Content::CDMA_EVDO_CANDICATE_SET_INDEX:
+    case Content::CDMA_EVDO_NEIGHBOR_SET_INDEX:
+        return parseCellInfo();
+    default:
+        return parseCommonCdmaInfo();
+    }
+}
+
+std::vector<std::vector<std::string>> NetworkInfoUrcParser::parseCommonCdmaInfo() {
+    std::vector<std::vector<std::string>> ret;
+    for (int i = 0; i < mLabels.size(); i++) {
+        ret.push_back(std::vector<std::string> {mLabels[i], nextValue()});
+    }
+    return ret;
+}
+
+std::vector<std::vector<std::string>> NetworkInfoUrcParser::parseCellInfo() {
+    std::vector<std::vector<std::string>> ret;
+    ret.push_back(mLabels);
+    int columns = mLabels.size();
+    int rows = 0;
+    mColumn = -1;
+    try {
+        rows = std::stoi(nextValue());
+    } catch (const std::out_of_range &e) {
+        RLOGD("out of range: %s, line: %s", e.what(), __LINE__);
+        return ret;;
+    } catch (const std::invalid_argument &e) {
+        RLOGD("invalid argument: %s, line: %s", e.what(), __LINE__);
+        return ret;
+    }
+    for (int i = 0; i < rows; i++) {
+        std::vector<std::string> entry;
+        for (int j = 0; j < columns; j++) {
+            mColumn = j;
+            entry.push_back(nextValue());
+        }
+        ret.push_back(entry);
+    }
+    return ret;
+}
+
+std::vector<std::vector<std::string>> NetworkInfoUrcParser::parse1xRttServing() {
+    std::vector<std::vector<std::string>> ret;
+    ret.push_back(std::vector<std::string> {"Active Set"});
+    std::vector<std::vector<std::string>> active = parseCellInfo();
+    ret.insert(ret.end(), active.begin(), active.end());;
+    ret.push_back(std::vector<std::string> {"Candicate Set"});
+    std::vector<std::vector<std::string>> candicate = parseCellInfo();
+    ret.insert(ret.end(), candicate.begin(), candicate.end());;
+    ret.push_back(std::vector<std::string> {"Neighbor Set"});
+    std::vector<std::vector<std::string>> neighbor = parseCellInfo();
+    ret.insert(ret.end(), neighbor.begin(), neighbor.end());;
+    return ret;
+}
+
+std::string NetworkInfoUrcParser::nextValue() {
+    int index = mOffset;
+    mOffset++;
+    if (mRawValues.empty() || mRawValues.size() <= index) {
+        return "";
+    }
+
+    std::string rawValue = mRawValues[index];
+    int value = 0;
+    try {
+        value = std::stoi(rawValue);
+    } catch (const std::out_of_range &e) {
+        RLOGD("out of range: %s, line: %s", e.what(), __LINE__);
+        return rawValue;
+    } catch (const std::invalid_argument &e) {
+        RLOGD("invalid argument: %s, line: %s", e.what(), __LINE__);
+        return rawValue;
+    }
+
+    std::vector<std::string> array;
+    switch (mType) {
+        case Content::CDMA_1XRTT_INFO_INDEX:
+        switch (index) {
+        case 1:
+            array = {"CP_DISABLED", "CP_SYS_DETERMINATION", "CP_PILOT_ACQUISITION",
+                    "CP_SYNC_ACQUISITION", "CP_TIMING_CHANGE", "CP_IDLE", "CP_UPDATE_OHD_INFO",
+                    "CP_PAGE_RESPONSE", "CP_ORD_MSG_RESP", "CP_ORIGINATION",
+                    "CP_REGISTRATION", "CP_MSG_TRANSMISSION", "CP_TC_INIT",
+                    "CP_TC_WAIT_ORDER", "CP_TC_WAIT_ANSWER", "CP_TC_CONVERSATION",
+                    "CP_TC_RELEASE", "CP_NST", "CP_FROZEN",
+                    "CP_TC_FROZEN"};
+            break;
+        case 2:
+            array = {"TRUE", "FALSE", "Unknown"};
+            break;
+        case 14:
+            array = {"FALSE", "TRUE"};
+            break;
+        case 15:
+            return decodeMcc(value);
+        case 16:
+            return decodeMnc(value);
+        case 19:
+        case 20:
+            return utils::format("%.1f", (float) value / -2);
+        case 22:
+            return std::to_string(value / 10);
+        default:
+            break;
+        }
+        break;
+    case Content::CDMA_1XRTT_SCH_INFO_INDEX:
+        switch (index) {
+        case 1: // for_sch_mux
+        case 6: // rev_sch_mux
+            return utils::format("0x%x", value);
+        case 4: // ForSchDuration
+        case 9: // RevSchDuration
+            if (value == 15) {
+                return "Infinite";
+            }
+            break;
+        default:
+            break;
+        }
+        break;
+    case Content::CDMA_1XRTT_SERVING_INDEX:
+        if (mColumn == 1) {
+            return utils::format("%.1f", (float) value / -2);
+        }
+        break;
+    case Content::CDMA_EVDO_SERVING_INFO_INDEX:
+        switch (index) {
+        case 5: // rssi
+        case 6:
+            return utils::format("%.2f", (float) value / 128);
+        case 15: // t_add
+        case 16: // t_drop
+            return utils::format("%.1f", (float) value / -2);
+        default:
+            break;
+        }
+        break;
+    case Content::CDMA_EVDO_ACTIVE_SET_INDEX:
+        if (mColumn == 1) {
+            return utils::format("%.2f", (float) value / 8);
+        }
+        break;
+    case Content::CDMA_EVDO_CANDICATE_SET_INDEX:
+    case Content::CDMA_EVDO_NEIGHBOR_SET_INDEX:
+        if (mColumn == 3) {
+            return utils::format("%.2f", (float) value / 8);
+        }
+        break;
+    case Content::CDMA_EVDO_FL_INDEX:
+        switch (index) {
+        case 1:
+            return utils::format("%.2f", (float) value / 64);
+        default:
+            break;
+        }
+        break;
+    case Content::CDMA_EVDO_RL_INDEX:
+        switch (index) {
+        case 4:
+        case 5:
+            return utils::format("%.2f", (float) value / 128);
+        default:
+            break;
+        }
+        break;
+    case Content::CDMA_EVDO_STATE_INDEX:
+        switch (index) {
+        case 1:
+            array = {"NEW_SESSION", "ALIVE_SESSION", "PRIOR_SESSION",
+                    "OPENED_SESSION"};
+            break;
+        case 2:
+            array = {"AT_PWROFF", "AT_INACTIVE", "AT_PILOTACQ", "AT_SYNC",
+                    "AT_IDLE", "AT_ACCESS", "AT_CONNECTED"};
+            break;
+        case 3:
+            array = {"ALMP_INIT_STATE", "ALMP_IDLE_STATE", "ALMP_CONN_SETUP_STATE",
+                    "ALMP_CONNECTED_STATE"};
+            break;
+        case 4:
+            array = {"INSP_INACTIVE_STATE", "INSP_NETWORK_DET_STATE",
+                    "INSP_PILOT_ACQ_STATE", "INSP_SYNC_STATE", "INSP_TIMING_CHANGE_STATE",
+                    "INSP_WFR_1XASSTST_STATE"};
+            break;
+        case 5:
+            array = {"IDP_INACTIVE_ST", "IDP_MONITOR_ST", "IDP_SLEEP_ST",
+                    "IDP_CONN_SETUP_ST", "IDP_FREEZE_PENDING_ST", "IDP_FREEZE_ST",
+                    "IDP_CONN_FROZEN_ST", "IDP_STATE_MAX"};
+            break;
+        case 6:
+            array = {"OMP_INACTIVE_ST", "OMP_ACTIVE_ST", "OMP_STATE_MAX"};
+            break;
+        case 7:
+            array = {"CSP_INACTIVE_STATE", "CSP_CLOSING_STATE", "CSP_OPEN_STATE"};
+            break;
+        case 8:
+            array = {"RUP_INACTIVE", "RUP_IDLE", "RUP_CONNECTED",
+                    "RUP_IRAT_MEASUREMENT", "RUP_INVALID"};
+            break;
+        default:
+            break;
+        }
+        break;
+    default:
+        break;
+    }
+
+    if ((!array.empty()) && (value >= 0) && (value < array.size())) {
+        return array[value];
+    }
+    return rawValue;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/networkinfo/NetworkInfoUrcParser.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/networkinfo/NetworkInfoUrcParser.h
new file mode 100644
index 0000000..9842497
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/networkinfo/NetworkInfoUrcParser.h
@@ -0,0 +1,328 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef SRC_EM_NETWORKINFO_NETWORKINFOURCPARSER_H_
+#define SRC_EM_NETWORKINFO_NETWORKINFOURCPARSER_H_
+
+#include <string>
+#include <vector>
+class NetworkInfoUrcParser {
+public:
+    NetworkInfoUrcParser();
+    virtual ~NetworkInfoUrcParser();
+private:
+    static const int DATA_OFFSET_2;
+    static const int DATA_OFFSET_4;
+    static const int DATA_OFFSET_6;
+    static const int DATA_OFFSET_8;
+    static const int DATA_FORMAT;
+    static const int MAX_DATA_PER_LINE;
+
+    static const int TYPE_UINT8;
+    static const int TYPE_UINT16;
+    static const int TYPE_UINT32;
+    static const int TYPE_INT8;
+    static const int TYPE_INT16;
+    static const int TYPE_INT32;
+    static const int TYPE_LONG;
+    static const int TYPE_FLOAT;
+    static const int TYPE_ALIGNMENT;
+    static const int TYPE_STRING;
+
+    static const bool ALIGN_MENT_ENABLE;
+    static const bool GPRS_MODE_ENABLE;
+    static const bool AMR_SUPPORT_ENABLE;
+    static const bool FWPNC_LAI_INFO_ENABLE;
+    static const bool UMTS_R8;
+    static const bool WISDOM_EM;
+    static const bool ADVANCED_EM;
+    static const bool IS_MOLY;
+
+    static const int MODEM_FDD;
+    static const int MODEM_TD;
+
+    std::string mRawString;
+    std::string mResult;
+    int mOffset;
+    std::vector<std::string> mRawValues;
+    std::vector<std::string>  mLabels;
+    int mColumn;
+    int mType;
+private:
+    /**
+     * @param data
+     *            the value of the bit
+     * @param start
+     *            the integer of the start position
+     * @param signed
+     *            the boolean of the signed is false
+     * @return the value of the String for every item
+     */
+    std::string getValueFrom4Byte(std::string data, int start, bool sig);
+    /**
+     * @param data
+     *            the String of the network item information
+     * @param start
+     *            the value of the network item start position bit
+     * @param dataLength
+     *            the block total bit
+     * @param signed
+     *            the define value is false
+     * @return the block value to display
+     */
+    std::string oneBlockFrom4Byte(std::string label, std::string data, int start,bool sig, int dataLength);
+    /**
+     * @param data
+     *            the value of the bit
+     * @param start
+     *            the integer of the start position
+     * @param signed
+     *            the boolean of the signed is false
+     * @return the value of the String for every item
+     */
+    std::string getValueFrom2Byte(std::string data, int start, bool sig);
+    /**
+     * @param data
+     *            the String of the network item information
+     * @param start
+     *            the value of the network item start position bit
+     * @param dataLength
+     *            the block total bit
+     * @param signed
+     *            the define value is false
+     * @return the block value to display
+     */
+    std::string oneBlockFrom2Byte(std::string label, std::string data, int start,bool sig, int dataLength);
+    /**
+     * @param data
+     *            the value of the bit
+     * @param start
+     *            the integer of the start position
+     * @param signed
+     *            the boolean of the signed is false
+     * @return the value of the String for every item
+     */
+    std::string getValueFromByte(std::string data, int start, bool sig);
+    /**
+     * @param data
+     *            the String of the network item information
+     * @param start
+     *            the value of the network item start position bit
+     * @param dataLength
+     *            the block total bit
+     * @param signed
+     *            the define value is false
+     * @return the block value to display
+     */
+    std::string oneBlockFromByte(std::string label, std::string data, int start,bool sig, int dataLength);
+    std::string parseElement(int type, std::string label);
+    std::string parseElement(int type, std::string label, int count);
+    int readIntegerFromByte();
+    int readIntegerFrom2Byte();
+    /*
+     * Modem will encode mcc/mnc before sending to AP, so decode it.
+     * Encoding algorithm:
+     * Suppose MCC is "abc", then encoded MCC will be:
+     * 100 * (a == 0 ? 10 : a) + 10 * (b == 0 ? 10 : b) + (c == 0 ? 10 : c) - 111;
+     * Suppose MNC is "ab", then encoded MNC will be:
+     * 10 * (a == 0 ? 10 : a) + (b == 0 ? 10 : b) - 11;
+     */
+    std::string decodeMcc(int value);
+    std::string decodeMnc(int value);
+    std::vector<std::vector<std::string>> parseCommonCdmaInfo();
+    std::vector<std::vector<std::string>> parseCellInfo();
+    std::vector<std::vector<std::string>> parse1xRttServing();
+    std::string nextValue();
+
+public:
+    /**
+     * @param type
+     *            the integer of the network item to view
+     * @return the value of the network item to display
+     */
+    std::string parseInfo(int type, std::string info, int simType);
+    /**
+     * @return the cellSel information (rr_em_cell_select_para_info_struct)
+     */
+    std::string getCellSelInfo();
+    /**
+     * @return the ChDscr information (rr_em_channel_descr_info_struct)
+     */
+    std::string getChDscrInfo();
+    /**
+     * @return the RACHCtrl information (rr_em_rach_ctrl_para_info_struct)
+     */
+    std::string getRACHCtrlInfo();
+    /**
+     * @return the LAI information
+     */
+    std::string getLAIInfo();
+    /**
+     * @return the Radio Link information (rr_em_radio_link_counter_info_struct)
+     */
+    std::string getRadioLinkInfo();
+    /**
+     * @return the MeasRep information (rr_em_measurement_report_info_struct)
+     */
+    std::string getMeasRepInfo();
+    /**
+     * @return the Calist information (rr_em_ca_list_info_struct)
+     */
+    std::string getCaListInfo();
+    /**
+     * @return the ControlMsg information (rr_em_control_msg_info_struct)
+     */
+    std::string getControlMsgInfo();
+    /**
+     * @return the SI2Q information (rr_em_si2q_info_struct)
+     */
+    std::string getSI2QInfo();
+    /**
+     * @return the MI information (rr_em_mi_info_struct)
+     */
+    std::string getMIInfo();
+    /**
+     * @return the BLK information (rr_em_blk_info_struct)
+     */
+    std::string getBLKInfo();
+    /**
+     * @return the TBF information (rr_em_tbf_status_struct)
+     */
+    std::string getTBFInfo();
+    /**
+     * @return the GPRS GEN information (rr_em_gprs_general_info_struct)
+     */
+    std::string getGPRSGenInfo();
+    std::string get3GGeneralInfo();
+    /**
+     * @return the slce voice information
+     */
+    std::string getSlceVoiceInfo();
+    /**
+     * @return the slce voice information
+     */
+    std::string getSecurityConfigInfo();
+    /**
+     * @return the 3G memory information (mm_em_info_struct)
+     */
+    std::string get3GMmEmInfo();
+    std::string getSmEmInfo();
+    std::string getGmmEmInfo();
+    /**
+     * @return the 3G Tcm information (tcm_mmi_em_info_struct)
+     */
+    std::string get3GTcmMmiEmInfo();
+    /**
+     * @return the 3G CsceEMServCellSStatusInd information (csce_em_serv_cell_s_status_ind_struct)
+     */
+    std::string get3GCsceEMServCellSStatusInd(bool isTdd);
+    /**
+     * @return the 3G CsceEmInfoMultiPlmn information (csce_em_info_multiple_plmn_struct)
+     */
+    std::string get3GCsceEmInfoMultiPlmn();
+
+    /**
+     * @return the 3G MemeEmInfoUmtsCellStatus information (meme_em_info_umts_cell_status_struct)
+     */
+    std::string get3GMemeEmInfoUmtsCellStatus();
+    /**
+     * @return the 3G MemeEmPeriodicBlerReport information (ul2_em_periodic_bler_report_ind)
+     */
+    std::string get3GMemeEmPeriodicBlerReportInd();
+    /**
+     * @return the 3G UrrUmtsSrnc information (urr_umts_srnc_id_struct)
+     */
+    std::string get3GUrrUmtsSrncId();
+    /**
+     * @return the 3G SlceEmPsDataRateStatus information (slce_em_ps_data_rate_status_ind_struct)
+     */
+    std::string get3GSlceEmPsDataRateStatusInd();
+    /**
+     * @return the 3G MemeEmInfoHServCell information (meme_em_info_h_serving_cell_ind_struct)
+     */
+    std::string get3GMemeEmInfoHServCellInd();
+    /**
+     * @return the 3G HandoverSequence information (uas_em_handover_status)
+     */
+    std::string get3GHandoverSequenceIndStuct();
+    /**
+     * @return the Control channel information (rr_em_ctrl_channel_descr_info_struct)
+     */
+    std::string getCtrlchanInfo();
+    /**
+     * @return the 3G Ul2EmAdmPoolStatus information (ul2_em_adm_pool_status_ind_struct)
+     */
+    std::string get3GUl2EmAdmPoolStatusIndStruct();
+    /**
+     * @param isTdd
+     *            is tdd or not
+     *
+     * @return the 3G CsceEMNeighCellSStatus information (csce_em_neigh_cell_s_status_ind_struct)
+     */
+    std::string getxGCsceEMNeighCellSStatusIndStructSize(bool isTdd);
+
+    /**
+     * @return the 3G Ul2EmPsDataRateStatus information (ul2_em_ps_data_rate_status_ind_struct)
+     */
+    std::string get3GUl2EmPsDataRateStatusIndStruct();
+    /**
+     * @return the 3G ul2EmHsdschReconfigStatus information
+     *         (ul2_em_hsdsch_reconfig_status_ind_struct)
+     */
+    std::string get3Gul2EmHsdschReconfigStatusIndStruct();
+    /**
+     * @return the 3G Ul2EmUrlcEventStatus information (ul2_em_urlc_event_status_ind_struct)
+     */
+    std::string get3GUl2EmUrlcEventStatusIndStruct();
+    /**
+     * @return the 3G Ul2EmPeriodicBlerReport information (ul2_em_periodic_bler_report_ind)
+     */
+    std::string get3GUl2EmPeriodicBlerReportInd();
+    std::vector<std::string> parseSecurityStatus(int type, std::string info);
+    std::vector<std::string> parseAntennaDiversity(int type, std::string info);
+    /**
+     * Parse CDMA info.
+     *
+     * @param type
+     *            info type
+     * @param info
+     *            info content
+     * @return formated info
+     */
+    std::vector<std::vector<std::string>> parseCdmaInfo(int type, std::string info);
+
+};
+
+#endif /* SRC_EM_NETWORKINFO_NETWORKINFOURCPARSER_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseRatInfo.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseRatInfo.cpp
new file mode 100644
index 0000000..d9d3629
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseRatInfo.cpp
@@ -0,0 +1,182 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include <string>
+using namespace std;
+
+#include "rfdesense/RfDesenseRatInfo.h"
+#include "rfdesense/RfDesenseTxTest.h"
+
+RfDesenseRatInfo::RfDesenseRatInfo() {
+    // TODO Auto-generated constructor stub
+
+}
+
+RfDesenseRatInfo::~RfDesenseRatInfo() {
+    // TODO Auto-generated destructor stub
+}
+
+std::string RfDesenseRatInfo::getRatName() {
+    return RatName;
+}
+
+void RfDesenseRatInfo::setRatName(std::string mRatname) {
+    if (!mRatname.empty()) {
+        RatName = mRatname;
+    }
+}
+
+bool RfDesenseRatInfo::getRatCheckState() {
+    return RatCheckState;
+}
+
+void RfDesenseRatInfo::setRatCheckState(bool mRatCheckState) {
+    RatCheckState = mRatCheckState;
+}
+
+bool RfDesenseRatInfo::getRatSendState() {
+    return RatSendState;
+}
+
+void RfDesenseRatInfo::setRatSendState(bool mRatSendState) {
+    RatSendState = mRatSendState;
+}
+
+std::string RfDesenseRatInfo::getRatCmdStart() {
+    return RatCmdStart;
+}
+
+void RfDesenseRatInfo::setRatCmdStart(std::string mRatCmdStart) {
+    if (!mRatCmdStart.empty()) {
+        RatCmdStart = mRatCmdStart;
+    }
+}
+
+std::string RfDesenseRatInfo::getRatCmdStop() {
+    return RatCmdStop;
+}
+
+void RfDesenseRatInfo::setRatCmdStop(std::string mRatCmdStop) {
+    if (!mRatCmdStop.empty()) {
+        RatCmdStop = mRatCmdStop;
+    }
+}
+
+std::string RfDesenseRatInfo::getRatCmdSwitch() {
+    return RatCmdSwitch;
+}
+
+void RfDesenseRatInfo::setRatCmdSwitch(std::string mRatCmdSwitch) {
+    RatCmdSwitch = mRatCmdSwitch;
+}
+
+std::string RfDesenseRatInfo::getRatCmdPowerRead() {
+    return RatCmdPowerRead;
+}
+
+void RfDesenseRatInfo::setRatCmdLteBwRb(int ratCmdLteBw, int ratCmdLteRb) {
+    if (ratCmdLteBw == -1) {
+        RatCmdLteBw = DEFAULT_BAND_WIDTH;
+    } else {
+        RatCmdLteBw = ratCmdLteBw;
+    }
+    if (ratCmdLteRb == -1) {
+        RatCmdLteRb = DEFAULT_VRB_LENGTH;
+    } else {
+        RatCmdLteRb = ratCmdLteRb;
+    }
+}
+
+void RfDesenseRatInfo::setRatCmdStart(std::string rat, int channel, int power,
+        int band) {
+    std::string command = "";
+    if (0 == rat.compare(RfDesenseTxTest::mRatName[0])) {  //GSM
+        command = std::string("AT+ERFTX=2,1,") + std::to_string(channel) + ","
+                + std::to_string(4100) + "," + std::to_string(band) + ","
+                + std::to_string(0) + "," + std::to_string(power) + ","
+                + std::to_string(0);
+    } else if (0 == rat.compare(RfDesenseTxTest::mRatName[1])) {    //TDSCDMA
+        command = std::string("AT+ERFTX=0,0,") + std::to_string(band) + ","
+                + std::to_string(channel) + "," + std::to_string(power);
+    } else if (0 == rat.compare(RfDesenseTxTest::mRatName[2])) {    //WCDMA
+        command = std::string("AT+ERFTX=0,0,") + std::to_string(band) + ","
+                + std::to_string(channel) + "," + std::to_string(power);
+    } else if (0 == rat.compare(RfDesenseTxTest::mRatName[3])) {    //LTE(FDD)
+        command = std::string("AT+ERFTX=6,0,2,") + std::to_string(band) + ","
+                + std::to_string(RatCmdLteBw) + "," + std::to_string(channel)
+                + ",1,0,0,0," + std::to_string(RatCmdLteRb) + "," + "0,"
+                + std::to_string(power);
+    } else if (0 == rat.compare(RfDesenseTxTest::mRatName[4])) {    //LTE(TDD)
+        command = std::string("AT+ERFTX=6,0,2,") + std::to_string(band) + ","
+                + std::to_string(RatCmdLteBw) + "," + std::to_string(channel)
+                + ",0,0,0,0," + std::to_string(RatCmdLteRb) + "," + "0,"
+                + std::to_string(power);
+    } else if (0 == rat.compare(RfDesenseTxTest::mRatName[5])) {    //CDMA(EVDO)
+        command = std::string("AT+ERFTX=13,4,") + std::to_string(channel) + ","
+                + std::to_string(band) + "," + std::to_string(power);
+    } else if (0 == rat.compare(RfDesenseTxTest::mRatName[6])) {    //CDMA(1x)
+        command = std::string("AT+ECRFTX=1,") + std::to_string(channel) + ","
+                + std::to_string(band) + "," + std::to_string(power) + ",0";
+    }
+    RatCmdStart = command;
+}
+
+void RfDesenseRatInfo::setRatPowerRead(std::string mRatCmdPowerRead) {
+    RatCmdPowerRead = mRatCmdPowerRead;
+}
+
+std::string RfDesenseRatInfo::getRatband() {
+    return Ratband;
+}
+
+void RfDesenseRatInfo::setRatband(std::string ratband) {
+    Ratband = ratband;
+}
+
+std::string RfDesenseRatInfo::getRatPowerSet() {
+    return RatPowerSet;
+}
+
+void RfDesenseRatInfo::setRatPowerSet(std::string ratPowerSet) {
+    RatPowerSet = ratPowerSet;
+}
+
+int RfDesenseRatInfo::getRatTxtimes() {
+    return RatTxtimes;
+}
+
+void RfDesenseRatInfo::setRatTxtimes(int ratTxtimes) {
+    RatTxtimes = ratTxtimes;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseRatInfo.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseRatInfo.h
new file mode 100644
index 0000000..5bc106f
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseRatInfo.h
@@ -0,0 +1,84 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef RFDESENSERATINFO_H_
+#define RFDESENSERATINFO_H_
+
+#include <string>
+class RfDesenseRatInfo {
+public:
+    const int DEFAULT_BAND_WIDTH = 3;
+    const int DEFAULT_VRB_LENGTH = 1;
+    RfDesenseRatInfo();
+    virtual ~RfDesenseRatInfo();
+    std::string getRatName();
+    void setRatName(std::string mRatname);
+    bool getRatCheckState();
+    void setRatCheckState(bool mRatCheckState);
+    bool getRatSendState();
+    void setRatSendState(bool mRatSendState);
+    std::string getRatCmdStart();
+    void setRatCmdStart(std::string mRatCmdStart);
+    std::string getRatCmdStop();
+    void setRatCmdStop(std::string mRatCmdStop);
+    std::string getRatCmdSwitch();
+    void setRatCmdSwitch(std::string mRatCmdSwitch);
+    std::string getRatCmdPowerRead();
+    void setRatCmdLteBwRb(int ratCmdLteBw, int ratCmdLteRb);
+    void setRatCmdStart(std::string rat, int channel, int power, int band);
+    void setRatPowerRead(std::string mRatCmdPowerRead);
+    std::string getRatband();
+    void setRatband(std::string ratband);
+    std::string getRatPowerSet();
+    void setRatPowerSet(std::string ratPowerSet);
+    int getRatTxtimes();
+    void setRatTxtimes(int ratTxtimes);
+private:
+    std::string RatName;
+    std::string RatCmdStart;
+    std::string RatCmdStop;
+    std::string Ratband;
+    std::string RatPowerSet;
+    std::string RatCmdSwitch;
+    std::string RatCmdPowerRead;
+    bool RatCheckState;
+    bool RatSendState;
+
+    int RatCmdLteRb;
+    int RatCmdLteBw;
+    int RatTxtimes;
+};
+
+#endif /* RFDESENSERATINFO_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTest.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTest.cpp
new file mode 100644
index 0000000..94afa42
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTest.cpp
@@ -0,0 +1,48 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include <memory>
+
+#include "rfdesense/RfDesenseTxTest.h"
+#include "em/em.h"
+
+static RfDesenseTxTest* mTx = NULL;
+int emRfDesenseStart(int len,int *item,int multilen,char *value[]) {
+    if(!mTx) {
+        mTx = RfDesenseTxTest::getInstance();
+    }
+    mTx->emRfDesenseStart(len,item, multilen, value);
+    return 0;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTest.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTest.cpp
new file mode 100644
index 0000000..26759a1
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTest.cpp
@@ -0,0 +1,1233 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include "rfdesense/RfDesenseTxTest.h"
+
+#include <memory>
+#include <list>
+#include <regex>
+#include <cmath>
+#include <string>
+#include <cstdarg>
+#include <cstring>
+
+#include <vendor-ril/telephony/ril.h>
+
+#include  "common.h"
+#include "em.h"
+#include "rfdesense/RfDesenseTxTestCdma.h"
+#include "rfdesense/RfDesenseTxTestGsm.h"
+#include "rfdesense/RfDesenseTxTestLte.h"
+#include "rfdesense/RfDesenseTxTestTd.h"
+#include "util/log_extra.h"
+#include "util/utils.h"
+
+#undef LOG_TAG
+#define LOG_TAG "EM_RfDesenseTxTest"
+
+RfDesenseTxTest* RfDesenseTxTest::m_instance = NULL;
+std::mutex RfDesenseTxTest::mMutex;
+
+const int RfDesenseTxTest::STATE_NONE = 0;
+const int RfDesenseTxTest::STATE_STARTED = 1;
+const int RfDesenseTxTest::STATE_STOPPED = 2;
+
+const int RfDesenseTxTest::MSG_START_TX = 1;
+const int RfDesenseTxTest::MSG_NEXT_RAT = 4;
+const int RfDesenseTxTest::MSG_READ_POWER = 10;
+const int RfDesenseTxTest::MSG_EWMPOLICY_TDSCDMA = 12;
+const int RfDesenseTxTest::MSG_EWMPOLICY_WCDMA = 13;
+const int RfDesenseTxTest::MSG_ECSRA = 14;
+const int RfDesenseTxTest::MSG_SWITCH_RAT_DONE = 15;
+
+int RfDesenseTxTest::mState = STATE_NONE;
+
+long RfDesenseTxTest::mTestDuration = 10;
+long RfDesenseTxTest::mTestCount = 1;
+long RfDesenseTxTest::mTestDurationSended = 0;
+long RfDesenseTxTest::mTestCountSended = 0;
+long RfDesenseTxTest::mCheckLimit = 2;
+long RfDesenseTxTest::mReadbackInterval = 5;
+
+const std::string RfDesenseTxTest::KEY_GSM_ATCMD = "gsm_at_cmd";
+const std::string RfDesenseTxTest::KEY_TDSCDMA_ATCMD = "tdscdma_at_cmd";
+const std::string RfDesenseTxTest::KEY_WCDMA_ATCMD = "wcdma_at_cmd";
+const std::string RfDesenseTxTest::KEY_LTE_FDD_ATCMD = "lte_fdd_at_cmd";
+const std::string RfDesenseTxTest::KEY_LTE_TDD_ATCMD = "lte_tdd_at_cmd";
+const std::string RfDesenseTxTest::KEY_CDMA_1X_ATCMD = "cdma_at_cmd";
+const std::string RfDesenseTxTest::KEY_CDMA_EVDO_ATCMD = "cdma_evdo_at_cmd";
+const std::string RfDesenseTxTest::KEY_TEST_DURATION = "test_duration";
+const std::string RfDesenseTxTest::KEY_TEST_COUNT = "test_count";
+const std::string RfDesenseTxTest::KEY_CHECK_LIMIT = "check_limit";
+const std::string RfDesenseTxTest::KEY_READBACK_INTREVAL = "readback_interval";
+
+const std::string RfDesenseTxTest::DEFAULT_GSM_ATCMD =
+            "AT+ERFTX=2,1,190,4100,128,0,5,0";
+const std::string RfDesenseTxTest::DEFAULT_TDSCDMA_ATCMD = "AT+ERFTX=0,0,1,10087,24";
+const std::string RfDesenseTxTest::DEFAULT_WCDMA_ATCMD = "AT+ERFTX=0,0,1,9750,23";
+const std::string RfDesenseTxTest::DEFAULT_LTE_FDD_ATCMD =
+            "AT+ERFTX=6,0,1,3,3,17475,1,0,0,0,1,0,23";
+const std::string RfDesenseTxTest::DEFAULT_LTE_TDD_ATCMD =
+            "AT+ERFTX=6,0,1,38,3,25950,0,0,0,0,1,0,23";
+const std::string RfDesenseTxTest::DEFAULT_CDMA_EVDO_ATCMD = "AT+ERFTX=13,4,384,0,83";
+const std::string RfDesenseTxTest::DEFAULT_CDMA_1X_ATCMD = "AT+ECRFTX=1,384,0,83,0";
+
+const std::string RfDesenseTxTest::DEFAULT_CDMA_EVDO_ATCMD_93before =
+            "AT+ERFTX=1,384,0,83,1";
+
+const std::vector<std::string> RfDesenseTxTest::mRatName = { "GSM", "TDSCDMA", "WCDMA",
+            "LTE(FDD)", "LTE(TDD)", "CDMA(EVDO)", "CDMA(1X)" };
+std::vector<std::string> RfDesenseTxTest::mRatCmdStart = { DEFAULT_GSM_ATCMD,
+            DEFAULT_TDSCDMA_ATCMD, DEFAULT_WCDMA_ATCMD, DEFAULT_LTE_FDD_ATCMD,
+            DEFAULT_LTE_TDD_ATCMD, DEFAULT_CDMA_EVDO_ATCMD,
+            DEFAULT_CDMA_1X_ATCMD };
+
+std::vector<std::string> RfDesenseTxTest::mRatCmdStop = { "AT+ERFTX=2,0",
+            "AT+ERFTX=0,1", "AT+ERFTX=0,1", "AT+ERFTX=6,0,0", "AT+ERFTX=6,0,0",
+            "AT+ERFTX=13,5", "AT+ECRFTX=0" };
+
+ std::vector<std::string> RfDesenseTxTest::mRatCmdSwitch = { "AT+ERAT=0", "AT+ERAT=1",
+            "AT+ERAT=1", "AT+ERAT=6,4", "AT+ERAT=6,4", "AT+ERAT=7,64",
+            "AT+ERAT=7,32" };
+
+std::vector<std::string> RfDesenseTxTest::mRatCmdPowerRead = { "", "AT+ERFTX=0,3",
+            "AT+ERFTX=0,3", "AT+ERFTX=6,1", "AT+ERFTX=6,1", "AT+ERFTX=13,3",
+            "AT+ERFTX=13,3" };
+std::vector<std::string> RfDesenseTxTest::mRatBand = { "19", "1", "1", "3", "38", "0", "0" };
+std::vector<std::string> RfDesenseTxTest::mRatPowerSet = { "19", "10", "24", "23", "23", "23", "23" };
+std::vector<bool> RfDesenseTxTest::mRatCheck = {false, false,false,false,false,false,false};
+std::vector<bool> RfDesenseTxTest::mSendState = {false, false,false,false,false,false,false};
+std::string RfDesenseTxTest::str_msg = "";
+bool RfDesenseTxTest::trm_flag = false;
+int RfDesenseTxTest::phone_id = 0;
+
+void RfDesenseTxTest::rf_send_at_cmd(std::string cmd, int flag){
+    mCurrentFlag = flag;
+    emSendATCommand(cmd.c_str(),phone_id);
+}
+
+//create thread to send command
+void RfDesenseTxTest::emRfDesenseThread(int id) {
+    mState = STATE_STARTED;
+    int operatorid = id;
+    LOG_D(LOG_TAG, "emRfDesenseThread: operatorid(%d)", operatorid);
+    switch (operatorid) {
+        case 0:{
+            if (trm_flag) {
+                LOG_D(LOG_TAG, "wait modem reset done");
+                std::this_thread::sleep_for(std::chrono::milliseconds(1000*5));
+                trm_flag = false;
+            }
+            if(isRadioOn((RIL_SOCKET_ID)phone_id)) {
+                LOG_D(LOG_TAG, "radio already on");
+                mIsModemEnabled = false;
+                emRadioStateOn();
+            } else {
+                while(!isRadioOn((RIL_SOCKET_ID)phone_id)) {
+                    LOG_D(LOG_TAG, "radio isn't on");
+                    std::this_thread::sleep_for(std::chrono::milliseconds(200));
+                }
+                //turnOnRf();
+                LOG_D(LOG_TAG, "radio on again");
+                registerRadioOn(m_instance);
+                mIsModemEnabled = false;
+            }
+            break;
+        }
+    }
+}
+
+void RfDesenseTxTest::emRadioStateOn(){
+    if (mIsModemEnabled == true) {
+        LOG_D(LOG_TAG, "mIsModemEnabled is true, just return");
+        return;
+    }
+    mIsModemEnabled = true;
+    LOG_D(LOG_TAG, "turn on rf succeed");
+    if (mState == STATE_STARTED) {
+        mCurrectRatInfo = getCurrectRatInfo();
+        if (mCurrectRatInfo
+                && !mCurrectRatInfo->getRatCmdSwitch().empty()) {
+            LOG_D(LOG_TAG, "switch rat(%s)",mCurrectRatInfo->getRatCmdSwitch().c_str());
+            //unregisterRadioOn();
+            rf_send_at_cmd(mCurrectRatInfo->getRatCmdSwitch(), MSG_SWITCH_RAT_DONE);
+        } else {
+            LOG_D(LOG_TAG, "mCurrectRatInfo == null");
+        }
+    }
+}
+
+void RfDesenseTxTest::emRadioStateOfforNotAvailable() {
+    //unregisterRadioOffOrNotAvailable();
+    if (mIsModemNotEnabled == true) {
+        LOG_D(LOG_TAG, "mIsModemNotEnabled is true, just return");
+        return;
+    }
+    mIsModemNotEnabled = true;
+    LOG_D(LOG_TAG, "turn off rf succeed...");
+    if (mCurrectRatInfo) {
+        mCurrectRatInfo->setRatSendState(true);
+        rf_send_at_cmd(mCurrectRatInfo->getRatCmdStart(), MSG_START_TX);
+        LOG_D(LOG_TAG, "send: %s  %s",mCurrectRatInfo->getRatName().c_str() ,mCurrectRatInfo->getRatCmdStart().c_str());
+    } else {
+        LOG_D(LOG_TAG, "mCurrectRatInfo == null");
+    }
+}
+
+void RfDesenseTxTest::emOemHookRaw(int value, int slot_id){
+    if(slot_id != phone_id) {
+        LOG_W(LOG_TAG, "slot_id = %d, main_slot: %d", slot_id, phone_id);
+        //return;
+    }
+    LOG_D(LOG_TAG, "Readback tx power = %d", value);
+    std::string result = "";
+    std::string rat = "";
+    std::lock_guard<std::mutex> guard(mMutex);
+    m_rawUrc = true;
+    m_condVar.notify_one();
+    float getPower = value / 8.0f;
+    if (std::abs(std::stoi(mCurrectRatInfo->getRatPowerSet()) -
+            getPower) > mCheckLimit) {
+        result = "failed\n";
+    } else {
+        result = "succeed\n";
+    }
+
+    std::string s = std::string("Start TX:\n")
+            + std::string("Rat(band)          ") + std::string("Power_Set   ")
+            + std::string("Power_Get    ") + std::string("Result\n");
+    rat = utils::format("%-20s %-15s %-10s",
+            (mCurrectRatInfo->getRatName()+ "(b" + mCurrectRatInfo->getRatband() + ")").c_str(),
+            mCurrectRatInfo->getRatPowerSet().c_str(),
+            std::to_string(getPower).c_str()
+    );
+    std::string ret;
+    if (!result.compare("failed\n")) {
+        ret = utils::format("%10s", result.c_str());
+    } else {
+        ret = utils::format("%10s", result.c_str());
+    }
+    str_msg += s + rat + ret;
+
+}
+
+void RfDesenseTxTest::tx_stop() {
+    LOG_D(LOG_TAG,"tx_stop");
+    std::unique_lock<std::mutex> mlock(mMutex);
+    m_condVar.wait(mlock,[this]{return m_rawUrc;});
+    txTestStop(MSG_NEXT_RAT);
+}
+
+void RfDesenseTxTest::init() {
+    mRequestHandleThread = new RequestHandleThread(this);
+    mRequestHandleThread->run();
+}
+
+RfDesenseTxTest::RfDesenseTxTest() {
+    initRatList();
+}
+
+RfDesenseTxTest::~RfDesenseTxTest() {
+    LOG_D(LOG_TAG, "RfDesenseTxTest destroyed");
+}
+
+void RfDesenseTxTest::txTestStop(int what) {
+    if (mCurrectRatInfo) {
+        rf_send_at_cmd(mCurrectRatInfo->getRatCmdStop(), what);
+        LOG_D(LOG_TAG, "stop: %s %s", mCurrectRatInfo->getRatName().c_str(), mCurrectRatInfo->getRatCmdStop().c_str());
+    } else {
+        LOG_D(LOG_TAG, "mCurrectRatInfo is null");
+        mState = STATE_STOPPED;
+        for (int i = 0; i < mRatList.size(); i++) {
+            mRatList[i]->setRatSendState(false);
+            mRatList[i]->setRatCheckState(false);
+        }
+    }
+}
+
+void RfDesenseTxTest::deInit() {
+
+}
+
+RfDesenseTxTest* RfDesenseTxTest::getInstance() {
+    if(!m_instance) {
+        mMutex.lock();
+        if(!m_instance) {
+            m_instance = new RfDesenseTxTest();
+            m_instance->init();
+        }
+        mMutex.unlock();
+    }
+    return m_instance;
+}
+
+// Method implements of RequestHandleThread
+RfDesenseTxTest::RequestHandleThread::RequestHandleThread(RfDesenseTxTest* tx) : m_looper(NULL) {
+    mTx = tx;
+    LOG_D(LOG_TAG, "RequestHandleThread created");
+}
+
+RfDesenseTxTest::RequestHandleThread::~RequestHandleThread() {
+    mTx = NULL;
+    LOG_D(LOG_TAG, "RequestHandleThread destroyed");
+}
+
+bool RfDesenseTxTest::RequestHandleThread::threadLoop() {
+    LOG_D(LOG_TAG, "RequestHandleThread threadLoop");
+    // start message loop
+    m_looper = Looper::prepare(0);
+    int result;
+    do {
+        result = m_looper->pollAll(-1);
+        LOG_D(LOG_TAG, "RequestHandleThread threadLoop, pull message result = %d", result);
+    } while (result == Looper::POLL_WAKE || result == Looper::POLL_CALLBACK);
+    return true;
+}
+
+sp<Looper> RfDesenseTxTest::RequestHandleThread::getLooper() {
+    return m_looper;
+}
+
+RfDesenseTxTest::RfRequestMessage::RfRequestMessage(RfDesenseTxTest* tx) : mTx(tx),mMsgType(0),
+        response(""),responselen(0), slot(0), e(RIL_E_SUCCESS) {
+}
+
+RfDesenseTxTest::RfRequestMessage::~RfRequestMessage() {
+    LOG_D(LOG_TAG, "RequestHandleThread destroyed");
+}
+
+void RfDesenseTxTest::RfRequestMessage::sendMessage(int delayms) {
+    LOG_D(LOG_TAG, "RfDesenseTxTest::RfRequestMessage, sendMessage delayms=%d", delayms);
+    if(mTx != NULL) {
+        mTx->sendMessage(this, delayms);
+    } else {
+        LOG_D(LOG_TAG, "RfDesenseTxTest::RfRequestHandler mTx is null");
+    }
+}
+
+void RfDesenseTxTest::RfRequestHandler::sendMessage(sp<RfRequestMessage> msg, int delayms) {
+    LOG_D(LOG_TAG, "RfDesenseTxTest::RfRequestHandler, sendMessage msg what=%d delayms=%d", msg->mMsgType, delayms);
+    this->mMsg = msg;
+    if(mTx != NULL) {
+        mTx->sendMessage(mMsg, delayms);
+    } else {
+        LOG_D(LOG_TAG, "RfDesenseTxTest::RfRequestHandler mTx is null");
+    }
+}
+
+RfDesenseTxTest::RfRequestHandler:: ~RfRequestHandler() {
+    mTx = NULL;
+    LOG_D(LOG_TAG, "RfRequestHandler destroyed");
+}
+
+void RfDesenseTxTest::handle_request(string response,int responselen,int slot, RIL_Errno e) {
+    sp<RfRequestMessage> msg = new RfRequestMessage(this);
+    msg->mMsgType = mCurrentFlag;
+    msg->response = response;
+    msg->responselen = responselen;
+    msg->slot = slot;
+    msg->e = e;
+    if(mCurrentFlag == MSG_READ_POWER) {
+        sendMessage(msg, 2*1000);
+    } else {
+        sendMessage(msg, 1000);
+    }
+}
+
+sp<RfDesenseTxTest::RfRequestHandler> RfDesenseTxTest::sendMessage(sp<RfRequestMessage> msg, int delayms) {
+    LOG_D(LOG_TAG, "sendMessage msg token=%d delayms=%d", msg->mMsgType, delayms);
+    sp<RfRequestHandler> handler = new RfRequestHandler(this);
+    handler->mMsg = msg;
+    if(mRequestHandleThread.get()) {
+        sp<Looper> looper = mRequestHandleThread->getLooper();
+        if(looper.get()) {
+            if (delayms > 0) {
+                looper->sendMessageDelayed(ms2ns(delayms),handler, handler->m_dummyMsg);
+            } else {
+                looper->sendMessage(handler, handler->m_dummyMsg);
+            }
+        } else {
+            LOG_D(LOG_TAG, "looper fail");
+        }
+    } else {
+        LOG_D(LOG_TAG, "mRequestHandleThread fail");
+    }
+
+    return handler;
+}
+
+void RfDesenseTxTest::emRfDesenseAtCmdHandle(sp<RfRequestMessage> msg){
+    LOG_D(LOG_TAG, "emRfDesenseAtCmdHandle, type: %d", msg->mMsgType);
+    int responselen = msg->responselen;
+    std::string response = msg->response;
+    switch (msg->mMsgType) {
+    case MSG_SWITCH_RAT_DONE: {
+        if (msg->e == RIL_E_SUCCESS) {
+            LOG_D(LOG_TAG, "switch rat succeed");
+            if (mCurrectRatInfo->getRatName() == mRatName[1]) { // tdscdma
+                LOG_D(LOG_TAG, "end AT+EWMPOLICY=0");
+                rf_send_at_cmd("AT+EWMPOLICY=0", MSG_EWMPOLICY_TDSCDMA);
+            } else if (mCurrectRatInfo->getRatName() == mRatName[2]) { // wcdma
+                LOG_D(LOG_TAG,  "send AT+EWMPOLICY=0");
+                rf_send_at_cmd("AT+EWMPOLICY=0", MSG_EWMPOLICY_WCDMA);
+            } else { // other rat
+                registerRadioOffOrNotAvailable(m_instance);
+                turnOffRf();
+            }
+        } else {
+            LOG_D(LOG_TAG, "switch rat failed");
+            emResultNotifyWithDone(mCurrectRatInfo->getRatName() + " switch rat failed\n");
+        }
+        break;
+    }
+    case MSG_EWMPOLICY_TDSCDMA: {
+        LOG_D(LOG_TAG, "AT+EWMPOLICY=0 send succeed");
+        LOG_D(LOG_TAG, "send AT+ECSRA=2,0,1,0,1,0 ...");
+        rf_send_at_cmd("AT+ECSRA=2,0,1,0,1,0", MSG_ECSRA);
+        break;
+    }
+    case MSG_EWMPOLICY_WCDMA: {
+        LOG_D(LOG_TAG, "AT+EWMPOLICY=0 send succeed");
+        LOG_D(LOG_TAG, "send AT+ECSRA=2,1,0,1,1,0 ...");
+        rf_send_at_cmd("AT+ECSRA=2,1,0,1,1,0", MSG_ECSRA);
+        break;
+    }
+    case MSG_ECSRA: {
+        LOG_D(LOG_TAG, "AT+ECSRA send succeed");
+        turnOffRf();
+        break;
+    }
+    case MSG_START_TX:{
+        if (msg->e == RIL_E_SUCCESS) {
+            LOG_D(LOG_TAG, "start cmd ok");
+            if (utils::is93Modem() && mCurrectRatInfo && !mCurrectRatInfo->getRatCmdPowerRead().empty()) {
+                LOG_D(LOG_TAG,"start read cmd: %s", mCurrectRatInfo->getRatCmdPowerRead().c_str());
+                rf_send_at_cmd(mCurrectRatInfo->getRatCmdPowerRead(), MSG_READ_POWER);
+            } else {
+                LOG_D(LOG_TAG, "don't read");
+                txTestStop(MSG_NEXT_RAT);
+            }
+        } else {
+            LOG_D(LOG_TAG, "start cmd failed");
+            emResultNotifyWithDone(mCurrectRatInfo->getRatName() + " start cmd failed\n");
+        }
+        break;
+    }
+    case MSG_READ_POWER:{
+        mTestDurationSended += mReadbackInterval;
+        if (mTestDurationSended >= mTestDuration) {
+            if (msg->e == RIL_E_SUCCESS) {
+                LOG_D(LOG_TAG, "read tx power succeed");
+                if(m_rawUrc){
+                    txTestStop(MSG_NEXT_RAT);
+                    m_rawUrc = false;
+                } else {
+                   std::thread thread_stop(&RfDesenseTxTest::tx_stop, m_instance);
+                   thread_stop.detach();
+                }
+            } else {
+                LOG_D(LOG_TAG, "read tx power failed");
+                emResultNotifyWithDone(mCurrectRatInfo->getRatName() + " read tx power failed\n");
+            }
+            mTestDurationSended = 0;
+        } else {
+            if (utils::is93Modem() && mCurrectRatInfo && !mCurrectRatInfo->getRatCmdPowerRead().empty()) {
+                LOG_D(LOG_TAG,"(sencond)start read cmd: %s", mCurrectRatInfo->getRatCmdPowerRead().c_str());
+                rf_send_at_cmd(mCurrectRatInfo->getRatCmdPowerRead(),  MSG_READ_POWER);
+            } else {
+                LOG_D(LOG_TAG,"(sencond)start read cmd fail");
+            }
+        }
+        break;
+    }
+    case MSG_NEXT_RAT: {
+        if (msg->e == RIL_E_SUCCESS) {
+            std::string rat = mCurrectRatInfo->getRatName();
+            LOG_D(LOG_TAG, "stop(%s) cmd ok", rat.c_str());
+            mCurrectRatInfo = getCurrectRatInfo();
+            if (mCurrectRatInfo) {
+                LOG_D(LOG_TAG, "error, mCurrectRatInfo should null ");
+            }
+            emResultNotifyWithDone(str_msg + "send all rat done\n");
+            str_msg = "";
+            mState = STATE_STOPPED;
+            for (int i = 0; i < mRatList.size(); i++) {
+                mRatList[i]->setRatSendState(false);
+                mRatList[i]->setRatCheckState(false);
+            }
+//            if(rat == mRatName[1] || rat == mRatName[2]) {
+//                if(utils::is93Modem()){
+//                    utils::mtk_property_set("vendor.ril.mux.report.case", "2");
+//                    utils::mtk_property_set("vendor.ril.muxreport", "1");
+//                }else {
+//                    emSendATCommand("AT+CFUN=1,1");
+//                }
+//                trm_flag = true;
+//            } else {
+//                turnOnRf();
+//            }
+            turnOnRf();
+            trm_flag = true;
+            unregister_response_oem_hook_raw();
+            unregisterOnUnsolOemHookRaw();
+        } else {
+            LOG_D(LOG_TAG, "stop cmd failed");
+            emResultNotifyWithDone(mCurrectRatInfo->getRatName() + " stop cmd failed \n");
+        }
+        break;
+    }
+    default:
+        break;
+    }
+}
+
+void RfDesenseTxTest::RfRequestHandler::handleMessage(const Message& message) {
+    LOG_D(LOG_TAG, "handleMessage msg->mMsgType: %d", mMsg->mMsgType);
+    if(mTx != NULL) {
+        mTx->emRfDesenseAtCmdHandle(mMsg);
+    } else {
+        LOG_D(LOG_TAG, "handleMessage mTx is null");
+    }
+}
+
+void RfDesenseTxTest::handle_gsm_para(const std::string& name, int last_pos,
+        const std::string& sub_name) {
+    bool flag = false;
+    std::shared_ptr<RfDesenseTxTestGsm> gsm =
+            RfDesenseTxTestGsm::get_instance();
+    if (name == rfdesense_gsm_sub[INDEX_GSM_SUB_BAND].name) {
+        flag = gsm->set_band(last_pos);
+    } else if (name == rfdesense_gsm_sub[INDEX_GSM_SUB_CHANNEL].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            gsm->show_channel();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = gsm->set_channel(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    } else if (name == rfdesense_gsm_sub[INDEX_GSM_SUB_POWER].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            gsm->show_power();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = gsm->set_power(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    } else if (name == rfdesense_gsm_sub[INDEX_GSM_SUB_AFC].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            gsm->show_afc();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = gsm->set_afc(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    } else if (name == rfdesense_gsm_sub[INDEX_GSM_SUB_TSC].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            gsm->show_tsc();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = gsm->set_tsc(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    } else if (name == rfdesense_gsm_sub[INDEX_GSM_SUB_PATTERN].name) {
+        flag = gsm->set_pattern(last_pos);
+    }
+
+    if (flag) {
+        mRatList[INDEX_GSM]->setRatCmdStart(gsm->get_command());
+        mRatList[INDEX_GSM]->setRatband(gsm->get_band());
+        mRatList[INDEX_GSM]->setRatPowerSet(gsm->get_power());
+        save(INDEX_GSM);
+    }
+}
+
+void RfDesenseTxTest::handle_tdscdma_para(const std::string& name, int last_pos,
+        const std::string& sub_name) {
+    //"TDSCDMA"
+    bool flag = false;
+    std::shared_ptr<RfDesenseTxTestTd> tdscdma = std::make_shared<
+            RfDesenseTxTestTd>(utils::MODEM_TDSCDMA);
+    if (name == rfdesense_tdscdma_sub[INDEX_3G_SUB_BAND].name) {
+        flag = tdscdma->set_band(last_pos);
+    } else if (name == rfdesense_tdscdma_sub[INDEX_3G_SUB_CHANNEL].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            tdscdma->show_channel();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = tdscdma->set_channel(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    } else if (name == rfdesense_tdscdma_sub[INDEX_3G_SUB_POWER].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            tdscdma->show_power();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = tdscdma->set_power(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    } else {
+        LOG_D(LOG_TAG, "logic error");
+    }
+
+    if (flag) {
+        mRatList[INDEX_TDSCDMA]->setRatCmdStart(tdscdma->get_command());
+        mRatList[INDEX_TDSCDMA]->setRatband(tdscdma->get_band());
+        mRatList[INDEX_TDSCDMA]->setRatPowerSet(tdscdma->get_power());
+        save(INDEX_TDSCDMA);
+    }
+}
+
+void RfDesenseTxTest::handle_wcdma_para(const std::string& name, int last_pos,
+        const std::string& sub_name) {
+    //"WCDMA"
+    bool flag = false;
+    std::shared_ptr<RfDesenseTxTestTd> wcdma = std::make_shared<
+            RfDesenseTxTestTd>(utils::MODEM_WCDMA);
+    if (name == rfdesense_wcdma_sub[INDEX_3G_SUB_BAND].name) {
+        flag = wcdma->set_band(last_pos);
+    } else if (name == rfdesense_wcdma_sub[INDEX_3G_SUB_CHANNEL].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            wcdma->show_channel();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = wcdma->set_channel(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    } else if (name == rfdesense_wcdma_sub[INDEX_3G_SUB_POWER].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            wcdma->show_power();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = wcdma->set_power(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    } else {
+        LOG_D(LOG_TAG, "logic error");
+    }
+
+    if (flag) {
+        mRatList[INDEX_WCDMA]->setRatCmdStart(wcdma->get_command());
+        mRatList[INDEX_WCDMA]->setRatband(wcdma->get_band());
+        mRatList[INDEX_WCDMA]->setRatPowerSet(wcdma->get_power());
+        save(INDEX_WCDMA);
+    }
+}
+
+void RfDesenseTxTest::handle_lte_fdd_para(const std::string& name, int last_pos,
+        const std::string& sub_name) {
+    //LTE(FDD)
+    bool flag = false;
+    std::shared_ptr<RfDesenseTxTestLte> fdd = std::make_shared<
+            RfDesenseTxTestLte>(utils::MODEM_LTE_FDD);
+    if (name == rfdesense_fdd_sub[INDEX_FDD_SUB_MODE].name) {
+        flag = fdd->set_mode(last_pos);
+    } else if (name == rfdesense_fdd_sub[INDEX_FDD_SUB_BAND].name) {
+        flag = fdd->set_band(last_pos);
+    } else if (name == rfdesense_fdd_sub[INDEX_FDD_SUB_BANDWITH].name) {
+        flag = fdd->set_bandwith(last_pos);
+    } else if (name == rfdesense_fdd_sub[INDEX_FDD_SUB_FREQ].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            fdd->show_freq();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = fdd->set_freq(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    } else if (name == rfdesense_fdd_sub[INDEX_FDD_SUB_START].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            fdd->show_start();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = fdd->set_start(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    } else if (name == rfdesense_fdd_sub[INDEX_FDD_SUB_LENGTH].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            fdd->show_length();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = fdd->set_length(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    } else if (name == rfdesense_fdd_sub[INDEX_FDD_SUB_MCS].name) {
+        flag = fdd->set_mcs(last_pos);
+    } else if (name == rfdesense_fdd_sub[INDEX_FDD_SUB_POWER].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            fdd->show_power();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = fdd->set_power(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    } else {
+        LOG_D(LOG_TAG, "error");
+    }
+
+    if (flag) {
+        mRatList[INDEX_LTE_FDD]->setRatCmdStart(fdd->get_command());
+        mRatList[INDEX_LTE_FDD]->setRatband(fdd->get_band());
+        mRatList[INDEX_LTE_FDD]->setRatPowerSet(fdd->get_power());
+        save(INDEX_LTE_FDD);
+    }
+}
+
+void RfDesenseTxTest::handle_lte_tdd_para(const std::string& name, int last_pos,
+        const std::string& sub_name) {
+    //LTE(TDD)
+    bool flag = false;
+    std::shared_ptr<RfDesenseTxTestLte> tdd = std::make_shared<
+            RfDesenseTxTestLte>(utils::MODEM_LTE_TDD);
+    if (name == rfdesense_tdd_sub[INDEX_TDD_SUB_MODE].name) {
+        flag = tdd->set_mode(last_pos);
+    } else if (name == rfdesense_tdd_sub[INDEX_TDD_SUB_BAND].name) {
+        flag = tdd->set_band(last_pos);
+    } else if (name == rfdesense_tdd_sub[INDEX_TDD_SUB_BANDWIDTH].name) {
+        flag = tdd->set_bandwith(last_pos);
+    } else if (name == rfdesense_tdd_sub[INDEX_TDD_SUB_FREQ].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            tdd->show_freq();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = tdd->set_freq(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    } else if (name == rfdesense_tdd_sub[INDEX_TDD_SUB_CONFIG].name) {
+        flag = tdd->set_tdd_config(last_pos);
+    } else if (name == rfdesense_tdd_sub[INDEX_TDD_SUB_SPECIAL].name) {
+        flag = tdd->set_tdd_special(last_pos);
+    } else if (name == rfdesense_tdd_sub[INDEX_TDD_SUB_START].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            tdd->show_start();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = tdd->set_start(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    } else if (name == rfdesense_tdd_sub[INDEX_TDD_SUB_LENGTH].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            tdd->show_length();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = tdd->set_length(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    } else if (name == rfdesense_tdd_sub[INDEX_TDD_SUB_MCS].name) {
+        flag = tdd->set_mcs(last_pos);
+    } else if (name == rfdesense_tdd_sub[INDEX_TDD_SUB_POWER].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            tdd->show_power();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = tdd->set_power(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    } else {
+        LOG_D(LOG_TAG, "error");
+    }
+
+    if (flag) {
+        mRatList[INDEX_LTE_TDD]->setRatCmdStart(tdd->get_command());
+        mRatList[INDEX_LTE_TDD]->setRatband(tdd->get_band());
+        mRatList[INDEX_LTE_TDD]->setRatPowerSet(tdd->get_power());
+        save(INDEX_LTE_TDD);
+    }
+}
+
+void RfDesenseTxTest::handle_cdma_evdo_para(const std::string& name,
+        int last_pos, const std::string& sub_name) {
+    //CDMA(EVDO)
+    bool flag = false;
+    std::shared_ptr<RfDesenseTxTestCdma> evdo = std::make_shared<
+            RfDesenseTxTestCdma>(utils::MODEM_CDMA_EVDO);
+    if (name == rfdesense_cdma_sub[INDEX_CDMA_SUB_BAND].name) {
+        flag = evdo->set_band(last_pos);
+    } else if (name == rfdesense_cdma_sub[INDEX_CDMA_SUB_CHANNEL].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            evdo->show_channel();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = evdo->set_channel(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    } else if (name == rfdesense_cdma_sub[INDEX_CDMA_SUB_MODULATION].name) {
+        flag = evdo->set_modulation(last_pos);
+    } else if (name == rfdesense_cdma_sub[INDEX_CDMA_SUB_POWER].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            evdo->show_power();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = evdo->set_power(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    }
+
+    if (flag) {
+        mRatList[INDEX_CDMA_EVDO]->setRatCmdStart(evdo->get_command());
+        mRatList[INDEX_CDMA_EVDO]->setRatband(evdo->get_band());
+        mRatList[INDEX_CDMA_EVDO]->setRatPowerSet(evdo->get_power());
+        save(INDEX_CDMA_EVDO);
+    }
+}
+
+void RfDesenseTxTest::handle_cdma_1X_para(const std::string& name, int last_pos,
+        const std::string& sub_name) {
+    //CDMA(1X)
+    bool flag = false;
+    std::shared_ptr<RfDesenseTxTestCdma> cdma_1x = std::make_shared<
+            RfDesenseTxTestCdma>(utils::MODEM_CDMA_1X);
+    if (name == rfdesense_cdma_sub[INDEX_CDMA_SUB_BAND].name) {
+        flag = cdma_1x->set_band(last_pos);
+    } else if (name == rfdesense_cdma_sub[INDEX_CDMA_SUB_CHANNEL].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            cdma_1x->show_channel();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = cdma_1x->set_channel(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    } else if (name == rfdesense_cdma_sub[INDEX_CDMA_SUB_MODULATION].name) {
+        flag = cdma_1x->set_modulation(last_pos);
+    } else if (name == rfdesense_cdma_sub[INDEX_CDMA_SUB_POWER].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            cdma_1x->show_power();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = cdma_1x->set_power(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+        }
+    }
+
+    if (flag) {
+        mRatList[INDEX_CDMA_1X]->setRatCmdStart(cdma_1x->get_command());
+        mRatList[INDEX_CDMA_1X]->setRatband(cdma_1x->get_band());
+        mRatList[INDEX_CDMA_1X]->setRatPowerSet(cdma_1x->get_power());
+        save(INDEX_CDMA_1X);
+    }
+}
+
+bool RfDesenseTxTest::handle_show_default(const std::string& standard) {
+    //show default
+    if (standard == sub_tx_test[INDEX_GSM].name) {
+        //"GSM"
+        std::shared_ptr<RfDesenseTxTestGsm> gsm =
+                RfDesenseTxTestGsm::get_instance();
+        gsm->show_default();
+    } else if (standard == sub_tx_test[INDEX_TDSCDMA].name) {
+        //"TDSCDMA"
+        std::shared_ptr<RfDesenseTxTestTd> tdscdma = std::make_shared<
+                RfDesenseTxTestTd>(utils::MODEM_TDSCDMA);
+        tdscdma->show_default();
+    } else if (standard == sub_tx_test[INDEX_WCDMA].name) {
+        //"WCDMA"
+        std::shared_ptr<RfDesenseTxTestTd> wcdma = std::make_shared<
+                RfDesenseTxTestTd>(utils::MODEM_WCDMA);
+        wcdma->show_default();
+    } else if (standard == sub_tx_test[INDEX_LTE_FDD].name) {
+        //LTE(FDD)
+        std::shared_ptr<RfDesenseTxTestLte> fdd = std::make_shared<
+                RfDesenseTxTestLte>(utils::MODEM_LTE_FDD);
+        fdd->show_default();
+    } else if (standard == sub_tx_test[INDEX_LTE_TDD].name) {
+        //LTE(TDD)
+        std::shared_ptr<RfDesenseTxTestLte> tdd = std::make_shared<
+                RfDesenseTxTestLte>(utils::MODEM_LTE_TDD);
+        tdd->show_default();
+    } else if ((standard == sub_tx_test[INDEX_CDMA_EVDO].name)
+            && utils::isC2KSupport()) {
+        //CDMA(EVDO)
+        std::shared_ptr<RfDesenseTxTestCdma> evdo = std::make_shared<
+                RfDesenseTxTestCdma>(utils::MODEM_CDMA_EVDO);
+        evdo->show_default();
+    } else if ((standard == sub_tx_test[INDEX_CDMA_1X].name)
+            && utils::isC2KSupport()) {
+        //CDMA(1X)
+        std::shared_ptr<RfDesenseTxTestCdma> cdma_1x = std::make_shared<
+                RfDesenseTxTestCdma>(utils::MODEM_CDMA_1X);
+        cdma_1x->show_default();
+    } else {
+        LOG_D(LOG_TAG, "invaild INPUT");
+        return false;
+    }
+    return true;
+}
+
+bool RfDesenseTxTest::handle_para(int len, int classid, int propertyid,int operatorid, const std::string& standard, int* item) {
+    if (len < 5) {
+        LOG_D(LOG_TAG, "logic error");
+        return false;
+    }
+    LOG_D(LOG_TAG, "len: %d, classid: %d, propertyid: %d, operatorid: %d, standard: %s", len, classid,propertyid, operatorid, standard.c_str());
+    int name_pos = item[3];
+    int last_pos = item[4];
+    std::string name =
+            desense_test[classid].subarray[propertyid].subarray[operatorid].subarray[name_pos].name;
+    std::string sub_name =
+            desense_test[classid].subarray[propertyid].subarray[operatorid].subarray[name_pos].subarray[last_pos].name;
+    LOG_D(LOG_TAG, "name_pos: %d, last_pos: %d, name: %s, sub_name: %s", name_pos, last_pos,name.c_str(), sub_name.c_str());
+    if (standard == sub_tx_test[INDEX_GSM].name) {
+        //"GSM"
+        handle_gsm_para(name, last_pos, sub_name);
+    } else if (standard == sub_tx_test[INDEX_TDSCDMA].name) {
+        //"TDSCDMA"
+        handle_tdscdma_para(name, last_pos, sub_name);
+    } else if (standard == sub_tx_test[INDEX_WCDMA].name) {
+        //"WCDMA"
+        handle_wcdma_para(name, last_pos, sub_name);
+    } else if (standard == sub_tx_test[INDEX_LTE_FDD].name) {
+        //LTE(FDD)
+        handle_lte_fdd_para(name, last_pos, sub_name);
+    } else if (standard == sub_tx_test[INDEX_LTE_TDD].name) {
+        //LTE(TDD)
+        handle_lte_tdd_para(name, last_pos, sub_name);
+    } else if ((standard == sub_tx_test[INDEX_CDMA_EVDO].name)
+            && utils::isC2KSupport()) {
+        //CDMA(EVDO)
+        handle_cdma_evdo_para(name, last_pos, sub_name);
+    } else if ((standard == sub_tx_test[INDEX_CDMA_1X].name)
+            && utils::isC2KSupport()) {
+        //CDMA(1X)
+        handle_cdma_1X_para(name, last_pos, sub_name);
+    } else {
+        LOG_D(LOG_TAG, "invaild INPUT");
+        return false;
+    }
+    return true;
+}
+
+bool RfDesenseTxTest::handle_start(const std::string& standard) {
+    //start
+    mState = STATE_STARTED;
+    if (standard == sub_tx_test[INDEX_GSM].name) {
+        //"GSM"
+        mRatList[INDEX_GSM]->setRatCheckState(true);
+    } else if (standard == sub_tx_test[INDEX_TDSCDMA].name) {
+        //"TDSCDMA"
+        mRatList[INDEX_TDSCDMA]->setRatCheckState(true);
+    } else if (standard == sub_tx_test[INDEX_WCDMA].name) {
+        //"WCDMA"
+        mRatList[INDEX_WCDMA]->setRatCheckState(true);
+    } else if (standard == sub_tx_test[INDEX_LTE_FDD].name) {
+        //LTE(FDD)
+        mRatList[INDEX_LTE_FDD]->setRatCheckState(true);
+    } else if (standard == sub_tx_test[INDEX_LTE_TDD].name) {
+        //LTE(TDD)
+        mRatList[INDEX_LTE_TDD]->setRatCheckState(true);
+    } else if ((standard == sub_tx_test[INDEX_CDMA_EVDO].name)
+            && utils::isC2KSupport()) {
+        //CDMA(EVDO)
+        mRatList[INDEX_CDMA_EVDO]->setRatCheckState(true);
+    } else if ((standard == sub_tx_test[INDEX_CDMA_1X].name)
+            && utils::isC2KSupport()) {
+        //CDMA(1X)
+        mRatList[INDEX_CDMA_1X]->setRatCheckState(true);
+    } else {
+        LOG_D(LOG_TAG, "invaild INPUT");
+        return false;
+    }
+    return true;
+}
+
+int RfDesenseTxTest::emRfDesenseStart(int len,int *item,int multilen,char *value[]) {
+    LOG_D(LOG_TAG,"emRfDesenseStart called");
+    update_rat();
+    if (len < 3) {
+        LOG_D(LOG_TAG, "please select redesense get or set");
+        return -1;
+    }
+    int classid = item[0];
+    int propertyid = item[1];
+    int operatorid = item[2];
+    mCurrentSettingsValues.clear();
+    for(int i = 0; i < multilen; i++ ) {
+        mCurrentSettingsValues.push_back(value[i]);
+        LOG_D(LOG_TAG, "value[%d]: %s", i, value[i]);
+    }
+    LOG_D(LOG_TAG, "mCurrentSettingsValues size: " + mCurrentSettingsValues.size());
+    em_arry_t *subarry = &(desense_test[classid].subarray[propertyid]);
+    std::string standard = subarry->name;
+    LOG_D(LOG_TAG,"rfdesense property name: %s, operatorid: %d",subarry->name, operatorid);
+    switch (operatorid) {
+        case 0: { //start
+            str_msg = "";
+            if(!handle_start(standard)) return -1;
+            //emEnableRadio(false);
+            registerOnUnsolOemHookRaw(m_instance);
+            register_response_oem_hook_raw(m_instance);
+            std::thread thread_start(&RfDesenseTxTest::emRfDesenseThread, m_instance, operatorid);
+            thread_start.detach();
+            break;
+        }
+        case 1: {
+            if(!handle_para(len, classid, propertyid, operatorid, standard, item)) return -1;
+            break;
+        }
+        case 2: { //show default
+            if(!handle_show_default(standard)) return -1;
+            break;
+        }
+        default:
+            LOG_D(LOG_TAG, "logic eror ");
+            return -1;
+    }
+    return (0);
+}
+
+std::shared_ptr<RfDesenseRatInfo> RfDesenseTxTest::getCurrectRatInfo() {
+    int index;
+    for (index = 0; index < mRatList.size(); index++) {
+         if (mRatList[index]->getRatCheckState()) {
+             if (mRatList[index]->getRatSendState()) {
+                 continue;
+             }
+             mCurrectRatInfo = mRatList[index];
+             break;
+         }
+     }
+     return mCurrectRatInfo;
+}
+
+void RfDesenseTxTest::turnOffRf(){
+    LOG_D(LOG_TAG, "turn off rf....");
+    mIsModemNotEnabled = false;
+    emEnableRadio(false, phone_id);
+    if(utils::is_support_dsds()){
+        emEnableRadio(false, phone_id == 0? 1:0);
+    }
+}
+
+void RfDesenseTxTest::turnOnRf() {
+    LOG_D(LOG_TAG, "turn on rf....");
+    mIsModemEnabled = false;
+    emEnableRadio(true, phone_id);
+    if(utils::is_support_dsds()){
+        emEnableRadio(true, phone_id == 0? 1:0);
+    }
+}
+
+void RfDesenseTxTest::initRatList() {
+    phone_id = Radio_capability_switch_util::get_main_capability_phone_id();
+    mState = STATE_NONE;
+    if(!utils::is93Modem()){
+        mRatCmdStart[5] = DEFAULT_CDMA_EVDO_ATCMD_93before;
+        mRatCmdStop[5] = "AT+ECRFTX=0";
+    }
+
+    if(utils::is90Modem()) {
+        mRatCmdSwitch[5] = "AT^PREFMODE=4";
+        mRatCmdSwitch[6] = "AT^EIRATMODE=2";
+    }
+    for (int i = 0; i < mRatName.size(); i++) {
+        std::shared_ptr<RfDesenseRatInfo> Info = std::make_shared<RfDesenseRatInfo>();
+        Info->setRatName(mRatName[i]);
+        Info->setRatCmdStart(mRatCmdStart[i]);
+        Info->setRatCmdStop(mRatCmdStop[i]);
+        Info->setRatCmdSwitch(mRatCmdSwitch[i]);
+        Info->setRatPowerRead(mRatCmdPowerRead[i]);
+        Info->setRatband(mRatBand[i]);
+        Info->setRatPowerSet(mRatPowerSet[i]);
+        Info->setRatCheckState(false);
+        Info->setRatSendState(false);
+        mRatList.push_back(Info);
+        if(!(utils::isC2KSupport())){
+            if (i == 4) {
+                break;
+            }
+        }
+    }
+}
+
+void RfDesenseTxTest::update_rat() {
+    for(int i=0; i < mRatList.size(); i++){
+        mRatList[i]->setRatName(mRatName[i]);
+        mRatList[i]->setRatCmdStart(mRatCmdStart[i]);
+        mRatList[i]->setRatCmdStop(mRatCmdStop[i]);
+        mRatList[i]->setRatCmdSwitch(mRatCmdSwitch[i]);
+        mRatList[i]->setRatPowerRead(mRatCmdPowerRead[i]);
+        mRatList[i]->setRatband(mRatBand[i]);
+        mRatList[i]->setRatPowerSet(mRatPowerSet[i]);
+        mRatList[i]->setRatCheckState(false);
+        mRatList[i]->setRatSendState(false);
+        if(!(utils::isC2KSupport())){
+            if (i == 4) {
+                break;
+            }
+        }
+    }
+}
+void RfDesenseTxTest::save(int index) {
+    mRatCmdStart[index] = mRatList[index]->getRatCmdStart();
+    mRatBand[index] = mRatList[index]->getRatband();
+    mRatPowerSet[index] = mRatList[index]->getRatPowerSet();
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTest.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTest.h
new file mode 100644
index 0000000..5f9d0b2
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTest.h
@@ -0,0 +1,257 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef RFDESENSETXTEST_H_
+#define RFDESENSETXTEST_H_
+
+#include <string>
+#include <vector>
+#include <memory>
+#include <mutex>
+#include <thread>
+#include <condition_variable>
+#include <vendor-ril/telephony/ril.h>
+#include <utils/Looper.h>
+#include <utils/Thread.h>
+#include <utils/RefBase.h>
+
+using namespace std;
+using ::android::Looper;
+using ::android::Thread;
+using ::android::MessageHandler;
+using ::android::Message;
+using ::android::sp;
+using ::android::RefBase;
+
+#include "rfdesense/RfDesenseRatInfo.h"
+#include "Radio_capability_switch_util.h"
+
+class RfDesenseTxTest: public android::RefBase {
+public:
+    RfDesenseTxTest();
+    virtual ~RfDesenseTxTest();
+    static RfDesenseTxTest* getInstance();
+    int emRfDesenseStart(int len,int *item,int multilen,char *value[]);
+    void emRadioStateOn();
+    void emRadioStateOfforNotAvailable();
+    void emOemHookRaw(int value, int slot_id);
+    void emRfDesenseAtCmdHandle(char*response, int responselen);
+    static const int STATE_NONE;
+    static const int STATE_STARTED;
+    static const int STATE_STOPPED;
+
+    static const int MSG_START_TX;
+    static const int MSG_NEXT_RAT;
+    static const int MSG_READ_POWER;
+    static const int MSG_EWMPOLICY_TDSCDMA;
+    static const int MSG_EWMPOLICY_WCDMA;
+    static const int MSG_ECSRA;
+    static const int MSG_SWITCH_RAT_DONE;
+
+    static const std::string KEY_GSM_ATCMD;
+    static const std::string KEY_TDSCDMA_ATCMD;
+    static const std::string KEY_WCDMA_ATCMD;
+    static const std::string KEY_LTE_FDD_ATCMD;
+    static const std::string KEY_LTE_TDD_ATCMD;
+    static const std::string KEY_CDMA_1X_ATCMD;
+    static const std::string KEY_CDMA_EVDO_ATCMD;
+    static const std::string KEY_TEST_DURATION;
+    static const std::string KEY_TEST_COUNT;
+    static const std::string KEY_CHECK_LIMIT;
+    static const std::string KEY_READBACK_INTREVAL;
+
+    static const std::string DEFAULT_GSM_ATCMD;
+    static const std::string DEFAULT_TDSCDMA_ATCMD;
+    static const std::string DEFAULT_WCDMA_ATCMD;
+    static const std::string DEFAULT_LTE_FDD_ATCMD;
+    static const std::string DEFAULT_LTE_TDD_ATCMD;
+    static const std::string DEFAULT_CDMA_EVDO_ATCMD;
+    static const std::string DEFAULT_CDMA_1X_ATCMD;
+    static const std::string DEFAULT_CDMA_EVDO_ATCMD_93before;
+    static const std::vector<std::string> mRatName;
+    static std::vector<std::string> mRatCmdStart;
+    static std::vector<std::string> mRatCmdStop;
+    static std::vector<std::string> mRatCmdSwitch;
+    static std::vector<std::string> mRatCmdPowerRead;
+    static std::vector<std::string> mRatBand;
+    static std::vector<std::string> mRatPowerSet;
+    static std::vector<bool> mRatCheck;
+    static std::vector<bool> mSendState;
+    static long mTestDuration;
+    static long mTestCount;
+    static long mTestDurationSended;
+    static long mTestCountSended;
+    static long mCheckLimit;
+    static long mReadbackInterval;
+    std::vector<std::shared_ptr<RfDesenseRatInfo>> mRatList;
+    std::shared_ptr<RfDesenseRatInfo> mCurrectRatInfo;
+
+    const int MSG_QUERY = 0;
+    const int MSG_SET = 1;
+    int mCurrentFlag = 0;
+    std::vector<std::string> mCurrentSettingsValues;
+    static const int INDEX_GSM = 0;
+    static const int INDEX_TDSCDMA = 1;
+    static const int INDEX_WCDMA = 2;
+    static const int INDEX_LTE_FDD = 3;
+    static const int INDEX_LTE_TDD = 4;
+    static const int INDEX_CDMA_EVDO = 5;
+    static const int INDEX_CDMA_1X = 6;
+
+    static constexpr int INDEX_GSM_SUB_BAND = 0;
+    static constexpr int INDEX_GSM_SUB_CHANNEL = 1;
+    static constexpr int INDEX_GSM_SUB_POWER = 2;
+    static constexpr int INDEX_GSM_SUB_AFC = 3;
+    static constexpr int INDEX_GSM_SUB_TSC = 4 ;
+    static constexpr int INDEX_GSM_SUB_PATTERN = 5;
+
+    static constexpr int INDEX_3G_SUB_BAND = 0;
+    static constexpr int INDEX_3G_SUB_CHANNEL = 1;
+    static constexpr int INDEX_3G_SUB_POWER = 2;
+
+    static constexpr int INDEX_CDMA_SUB_BAND = 0;
+    static constexpr int INDEX_CDMA_SUB_MODULATION = 1;
+    static constexpr int INDEX_CDMA_SUB_CHANNEL = 2;
+    static constexpr int INDEX_CDMA_SUB_POWER = 3;
+
+    static constexpr int INDEX_FDD_SUB_MODE = 0;
+    static constexpr int INDEX_FDD_SUB_BAND = 1;
+    static constexpr int INDEX_FDD_SUB_BANDWITH = 2;
+    static constexpr int INDEX_FDD_SUB_FREQ = 3;
+    static constexpr int INDEX_FDD_SUB_START = 4;
+    static constexpr int INDEX_FDD_SUB_LENGTH = 5;
+    static constexpr int INDEX_FDD_SUB_MCS = 6;
+    static constexpr int INDEX_FDD_SUB_POWER = 7;
+
+    static constexpr int INDEX_TDD_SUB_MODE = 0;
+    static constexpr int INDEX_TDD_SUB_BAND = 1;
+    static constexpr int INDEX_TDD_SUB_BANDWIDTH = 2;
+    static constexpr int INDEX_TDD_SUB_FREQ = 3;
+    static constexpr int INDEX_TDD_SUB_CONFIG = 4;
+    static constexpr int INDEX_TDD_SUB_SPECIAL = 5;
+    static constexpr int INDEX_TDD_SUB_START = 6;
+    static constexpr int INDEX_TDD_SUB_LENGTH = 7;
+    static constexpr int INDEX_TDD_SUB_MCS = 8;
+    static constexpr int INDEX_TDD_SUB_POWER = 9;
+
+    class RequestHandleThread: public Thread {
+    public:
+        RequestHandleThread(RfDesenseTxTest* tx);
+        virtual ~RequestHandleThread();
+        sp<Looper> getLooper();
+
+    protected:
+        RfDesenseTxTest* mTx;
+        virtual bool threadLoop();
+    private:
+        sp<Looper> m_looper;
+    };
+
+    class RfRequestMessage: public RefBase {
+    public:
+        RfRequestMessage(RfDesenseTxTest* tx);
+        virtual ~RfRequestMessage();
+        void sendMessage(int delayms);
+    public:
+        int mMsgType;
+        string response;
+        int responselen;
+        int slot;
+        RIL_Errno e;
+    private:
+        RfDesenseTxTest* mTx;
+    };
+
+    class RfRequestHandler: public MessageHandler {
+    public:
+        RfRequestHandler(RfDesenseTxTest* tx): mTx(tx){}
+        virtual ~RfRequestHandler();
+
+    public:
+        void sendMessage(sp<RfRequestMessage> msg, int delayms);
+        void handleMessage(const Message& message);
+        sp<RfRequestMessage> mMsg;
+        // dummy message that makes handler happy
+        Message m_dummyMsg;
+    private:
+        RfDesenseTxTest* mTx;
+    };
+
+public:
+    void emRfDesenseAtCmdHandle(sp<RfRequestMessage> msg);
+    sp<RequestHandleThread> mRequestHandleThread;
+    sp<RfRequestHandler> mRfRequestHandler;
+    // send message to request handler
+    sp<RfRequestHandler> sendMessage(sp<RfRequestMessage> msg, int delayms);
+    void handle_request(string response,int responselen,int slot, RIL_Errno e);
+
+private:
+    std::shared_ptr<RfDesenseRatInfo> getCurrectRatInfo();
+    void update_rat();
+    void tx_stop();
+    void turnOffRf();
+    void turnOnRf();
+    void emRfDesenseThread(int id);
+    void rf_send_at_cmd(std::string cmd, int flag);
+    void save(int index);
+    void txTestStop(int what);
+    static RfDesenseTxTest* m_instance;
+    static std::mutex mMutex;
+    static bool trm_flag;
+    std::condition_variable m_condVar;
+    bool m_rawUrc = false;
+    void initRatList();
+    void handle_gsm_para(const std::string& name, int last_pos,const std::string& sub_name);
+    void handle_tdscdma_para(const std::string& name, int last_pos,const std::string& sub_name);
+    void handle_wcdma_para(const std::string& name, int last_pos,const std::string& sub_name);
+    void handle_lte_fdd_para(const std::string& name, int last_pos,const std::string& sub_name);
+    void handle_lte_tdd_para(const std::string& name, int last_pos,const std::string& sub_name);
+    void handle_cdma_evdo_para(const std::string& name, int last_pos,const std::string& sub_name);
+    void handle_cdma_1X_para(const std::string& name, int last_pos,const std::string& sub_name);
+    bool handle_show_default(const std::string& standard);
+    bool handle_para(int len, int classid, int propertyid, int operatorid,const std::string& standard, int* item);
+    bool handle_start(const std::string& standard);
+
+    static int mState;
+    static std::string str_msg;
+    static int phone_id;
+    bool mIsModemEnabled = true;
+    bool mIsModemNotEnabled = true;
+private:
+    void init();
+    void deInit();
+};
+
+#endif /* RFDESENSETXTEST_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestBase.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestBase.cpp
new file mode 100644
index 0000000..1faa8ae
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestBase.cpp
@@ -0,0 +1,58 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include "rfdesense/RfDesenseTxTestBase.h"
+
+#include "util/log_extra.h"
+
+#undef LOG_TAG
+#define LOG_TAG "EM_RfDesenseTxTestBase"
+
+const int RfDesenseTxTestBase::CHANNEL_DEFAULT = 0;
+const int RfDesenseTxTestBase::CHANNEL_MIN = 1;
+const int RfDesenseTxTestBase::CHANNEL_MAX = 2;
+const int RfDesenseTxTestBase::CHANNEL_MIN2 = 3;
+const int RfDesenseTxTestBase::CHANNEL_MAX2 = 4;
+const int RfDesenseTxTestBase::POWER_DEFAULT = 5;
+const int RfDesenseTxTestBase::POWER_MIN = 6;
+const int RfDesenseTxTestBase::POWER_MAX = 7;
+
+RfDesenseTxTestBase::RfDesenseTxTestBase() {
+    // TODO Auto-generated constructor stub
+
+}
+
+RfDesenseTxTestBase::~RfDesenseTxTestBase() {
+    // TODO Auto-generated destructor stub
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestBase.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestBase.h
new file mode 100644
index 0000000..94b08de
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestBase.h
@@ -0,0 +1,57 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef RFDESENSETXTESTBASE_H_
+#define RFDESENSETXTESTBASE_H_
+
+#include <string>
+#include <vector>
+
+class RfDesenseTxTestBase {
+public:
+    RfDesenseTxTestBase();
+    virtual ~RfDesenseTxTestBase();
+public:
+    static const int CHANNEL_DEFAULT;
+    static const int CHANNEL_MIN;
+    static const int CHANNEL_MAX;
+    static const int CHANNEL_MIN2;
+    static const int CHANNEL_MAX2;
+    static const int POWER_DEFAULT;
+    static const int POWER_MIN;
+    static const int POWER_MAX;
+};
+
+#endif /* RFDESENSETXTESTBASE_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestCdma.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestCdma.cpp
new file mode 100644
index 0000000..b9fc283
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestCdma.cpp
@@ -0,0 +1,225 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include <algorithm>
+#include <iterator>
+#include <stdexcept>
+
+#include "rfdesense/RfDesenseTxTestCdma.h"
+#include "rfdesense/RfDesenseTxTestBase.h"
+#include "util/log_extra.h"
+#include "em.h"
+
+#undef LOG_TAG
+#define LOG_TAG "EM_RfDesenseTxTestCdma"
+
+const int RfDesenseTxTestCdma::INDEX_BAND = 0;
+const int RfDesenseTxTestCdma::INDEX_CHANNEL = 1;
+const int RfDesenseTxTestCdma::INDEX_POWER = 2;
+const int RfDesenseTxTestCdma::INDEX_MODULATION = 3;
+std::string RfDesenseTxTestCdma::band = "";
+std::string RfDesenseTxTestCdma::channel = "";
+std::string RfDesenseTxTestCdma::power = "";
+std::string RfDesenseTxTestCdma::modulation = "";
+std::map<int, std::string> RfDesenseTxTestCdma::evdo_values = {{INDEX_BAND, "0"},{INDEX_CHANNEL, "384"},{INDEX_POWER, "23"}, {INDEX_MODULATION, "1"}};
+std::map<int, std::string> RfDesenseTxTestCdma::cdma_1x_values = {{INDEX_BAND, "0"},{INDEX_CHANNEL, "384"},{INDEX_POWER, "23"}, {INDEX_MODULATION, "0"}};
+
+RfDesenseTxTestCdma::RfDesenseTxTestCdma(int type) {
+    modem_type = type;
+    std::map<int, std::string> tmp;
+    switch(modem_type){
+        case utils::MODEM_CDMA_EVDO:{
+            tmp = evdo_values;
+            break;
+        }
+        case utils::MODEM_CDMA_1X:{
+            tmp = cdma_1x_values;
+            break;
+        }
+        default:
+            break;
+    }
+    if(!tmp.empty()) {
+        band = tmp[INDEX_BAND];
+        channel = tmp[INDEX_CHANNEL];
+        power = tmp [INDEX_POWER];
+        modulation = tmp[INDEX_MODULATION];
+    }
+
+}
+
+void RfDesenseTxTestCdma::show_default() {
+    std::string str;
+    int index = std::stoi(band);
+    std::string modem;
+    if(modem_type == utils::MODEM_CDMA_EVDO) {
+        modem = "CDMA(EVDO) ";
+    } else if(modem_type == utils::MODEM_CDMA_1X){
+        modem = "CDMA(1X) ";
+    }
+    str = modem + "parameters: Band: "
+            + std::string(rfdesense_cdma_band[index].name)
+            + ", modulation: "
+            + (std::stoi(modulation) == 0 ?
+                    std::string("1x") : std::string("EVDO"))
+            + ", Channel(ARFCN): " + channel + ", Power Level(dBm): " + power;
+    emResultNotifyWithDone(str);
+}
+
+RfDesenseTxTestCdma::~RfDesenseTxTestCdma() {
+    // TODO Auto-generated destructor stub
+}
+std::string RfDesenseTxTestCdma::modemTypeToString(int type) {
+    switch(modem_type){
+        case utils::MODEM_CDMA_EVDO:
+            return "CDMA(EVD)";
+        case utils::MODEM_CDMA_1X:
+            return "CDMA(1X)";
+        default:
+            return "UNKNOWN";
+    }
+}
+
+std::string RfDesenseTxTestCdma::get_command(){
+    int tx_power = 0;
+    if (!power.empty()) {
+        tx_power = std::stoi(power) + 60;
+    }
+
+    if (modem_type == utils::MODEM_CDMA_1X) {
+        command = "AT+ECRFTX=1," + channel + "," + band + ","
+                + std::to_string(tx_power)
+                + ","
+                + (modulation == "1" ? "0" : "1");
+    } else if(modem_type == utils::MODEM_CDMA_EVDO) {
+        command = "AT+ERFTX=13,4," + channel + "," + band + ","
+                + std::to_string(tx_power);
+    }
+    return command;
+}
+
+std::string RfDesenseTxTestCdma::get_band(){
+    return band;
+}
+
+std::string RfDesenseTxTestCdma::get_power(){
+    return power;
+}
+
+bool RfDesenseTxTestCdma::set_band(int value){
+    std::string s;
+    if(value < 0 || value > 15) {
+        s = utils::format("band(%d) is out of range", value);
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "band(%d) is out of range", value);
+        return false;
+    }
+    band = std::to_string(value);
+    if(modem_type == utils::MODEM_CDMA_EVDO) {
+        evdo_values[INDEX_BAND] = band;
+    } else if(modem_type == utils::MODEM_CDMA_1X) {
+        cdma_1x_values[INDEX_BAND] = band;
+    } else {
+        s = utils::format("modem(%s) is invalid", modemTypeToString(modem_type));
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "modem(%s) is invalid", modemTypeToString(modem_type));
+        return false;
+    }
+    em_result_notify_ok("band: " + std::string(rfdesense_cdma_band[value].name));
+    return true;
+}
+
+bool RfDesenseTxTestCdma::set_modulation(int value){
+    if (value != 0 && value != 1) {
+        LOG_D(LOG_TAG, "set_modulation value(%d) is out of range",value);
+        return false;
+    }
+    modulation = std::to_string(value);
+    if(modem_type == utils::MODEM_CDMA_EVDO) {
+        evdo_values[INDEX_MODULATION] = modulation;
+    } else if(modem_type == utils::MODEM_CDMA_1X) {
+        cdma_1x_values[INDEX_MODULATION] = modulation;
+    } else {
+        std::string s;
+        s = utils::format("modem(%s) is invalid", modemTypeToString(modem_type));
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "modem(%s) is invalid", modemTypeToString(modem_type));
+        return false;
+    }
+    em_result_notify_ok("modulation: " + (value == 0 ?std::string("1x") : std::string("EVDO")));
+    return true;
+}
+
+bool RfDesenseTxTestCdma::set_channel(std::string str){
+    channel = str;
+    if(modem_type == utils::MODEM_CDMA_EVDO) {
+        evdo_values[INDEX_CHANNEL] = channel;
+    } else if(modem_type == utils::MODEM_CDMA_1X) {
+        cdma_1x_values[INDEX_CHANNEL] = channel;
+    } else {
+        std::string s;
+        s = utils::format("modem(%s) is invalid", modemTypeToString(modem_type));
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "modem(%s) is invalid", modemTypeToString(modem_type));
+        return false;
+    }
+    em_result_notify_ok("channel: " + channel);
+    return true;
+}
+
+bool RfDesenseTxTestCdma::set_power(std::string str){
+    power = str;
+    if(modem_type == utils::MODEM_CDMA_EVDO) {
+        evdo_values[INDEX_POWER] = power;
+    } else if(modem_type == utils::MODEM_CDMA_1X) {
+        cdma_1x_values[INDEX_POWER] = power;
+    } else {
+        std::string s;
+        s = utils::format("modem(%s) is invalid", modemTypeToString(modem_type));
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "modem(%s) is invalid", modemTypeToString(modem_type));
+        return false;
+    }
+    em_result_notify_ok("power: " + power);
+    return true;
+}
+
+void RfDesenseTxTestCdma::show_channel(){
+    emResultNotifyWithDone("Channel(ARFCN): " + channel);
+}
+
+void RfDesenseTxTestCdma::show_power(){
+    emResultNotifyWithDone("Power level(dBm): " + power);
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestCdma.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestCdma.h
new file mode 100644
index 0000000..26cc2ff
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestCdma.h
@@ -0,0 +1,77 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef RFDESENSETXTESTCDMA_H_
+#define RFDESENSETXTESTCDMA_H_
+
+#include <vector>
+#include <string>
+#include <map>
+
+#include "util/utils.h"
+
+class RfDesenseTxTestCdma {
+public:
+    bool init(std::vector<std::string> v);
+    std::string get_command();
+    std::string get_band();
+    std::string get_power();
+    bool set_band(int value);
+    bool set_modulation(int value);
+    bool set_channel(std::string str);
+    bool set_power(std::string str);
+    void show_channel();
+    void show_power();
+    RfDesenseTxTestCdma(int type);
+    void show_default();
+    virtual ~RfDesenseTxTestCdma();
+private:
+    static const int INDEX_BAND;
+    static const int INDEX_CHANNEL;
+    static const int INDEX_POWER;
+    static const int INDEX_MODULATION;
+    int modem_type = utils::MODEM_UNKNOWN;
+    static std::string band;
+    static std::string channel;
+    static std::string power;
+    static std::string modulation;
+    static std::map<int, std::string> evdo_values;
+    static std::map<int, std::string> cdma_1x_values;
+    bool check_band(std::string band);
+    std::string command;
+    std::string modemTypeToString(int type);
+};
+
+#endif /* RFDESENSETXTESTCDMA_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestGsm.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestGsm.cpp
new file mode 100644
index 0000000..793e99f
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestGsm.cpp
@@ -0,0 +1,305 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include "rfdesense/RfDesenseTxTestGsm.h"
+
+#include <algorithm>
+#include <iterator>
+#include <stdexcept>
+
+#include "em.h"
+#include "rfdesense/RfDesenseTxTestBase.h"
+#include "util/log_extra.h"
+#include "util/utils.h"
+
+#undef LOG_TAG
+#define LOG_TAG "EM_RfDesenseTxTestGsm"
+const int RfDesenseTxTestGsm::INDEX_BAND = 0;
+const int RfDesenseTxTestGsm::INDEX_CHANNEL = 1;
+const int RfDesenseTxTestGsm::INDEX_POWER = 2;
+const int RfDesenseTxTestGsm::INDEX_AFC = 3;
+const int RfDesenseTxTestGsm::INDEX_TSC = 4;
+const int RfDesenseTxTestGsm::INDEX_PATTERN = 5;
+std::string RfDesenseTxTestGsm::band = "128";
+std::string RfDesenseTxTestGsm::channel ="190";
+std::string RfDesenseTxTestGsm::power = "5";
+std::string RfDesenseTxTestGsm::afc = "4100";
+std::string RfDesenseTxTestGsm::tsc = "0";
+std::string RfDesenseTxTestGsm::pattern = "0";
+
+const std::vector<std::string> RfDesenseTxTestGsm::band_values = {"128","1", "2", "4", "8", "16"};
+const std::vector<std::vector<std::string>> RfDesenseTxTestGsm::gsm_gmsk_limits = {
+        {"190","128","251","128","251","5","5","19"},
+        {"63","1","124","1","124","5","5","19"},
+        {"62","0","124","975","1023","5","5","19"},
+        {"61","0","124","955","1023","5","5","19"},
+        {"700","512","885","512","885","0","0","15"},
+        {"661","512","810","512","885","0","0","15"}};
+
+std::shared_ptr<RfDesenseTxTestGsm> RfDesenseTxTestGsm::m_instance;
+std::mutex RfDesenseTxTestGsm::mutex;
+
+RfDesenseTxTestGsm::RfDesenseTxTestGsm() {
+
+}
+
+RfDesenseTxTestGsm::~RfDesenseTxTestGsm() {
+    // TODO Auto-generated destructor stub
+}
+
+std::shared_ptr<RfDesenseTxTestGsm> RfDesenseTxTestGsm::get_instance() {
+    if(!m_instance) {
+        mutex.lock();
+        if(!m_instance) {
+            m_instance = std::make_shared<RfDesenseTxTestGsm>();
+        }
+        mutex.unlock();
+    }
+    return m_instance;
+}
+
+std::string RfDesenseTxTestGsm::get_command() {
+    std::string command = "AT+ERFTX=2,1," + channel + "," + afc + "," + band + "," + tsc + "," + power + "," + pattern;
+    LOG_D(LOG_TAG, "GSM command: %s\n", command.c_str());
+    return command;
+}
+
+std::string RfDesenseTxTestGsm::get_band(){
+    return band;
+}
+
+std::string RfDesenseTxTestGsm::get_power(){
+    return power;
+}
+
+bool RfDesenseTxTestGsm::set_band(int value) {
+    LOG_D(LOG_TAG, "values: %d", value);
+    if (value < 0 || value >=  band_values.size()) {
+        std::string s = utils::format("value(%d) is out of range\n", value);
+        LOG_D(LOG_TAG, s.c_str());
+        em_result_notify_fail(s);
+        return false;
+    }
+    this->band = band_values[value];
+    em_result_notify_ok("band: " + std::string(rfdesense_gsm_band[value].name));
+    return true;
+}
+
+bool RfDesenseTxTestGsm::set_pattern(int value) {
+    LOG_D(LOG_TAG, "values: %d", value);
+    if(value < 0 || value > 6) {
+        std::string s = utils::format("pattern(%s) is invalid, range is [0,6]\n" , pattern.c_str());
+        LOG_D(LOG_TAG, s.c_str());
+        em_result_notify_fail(s);
+        return false;
+    }
+    this->pattern = std::to_string(value);
+    em_result_notify_ok("pattern: " + std::string(rfdesense_gsm_pattern[value].name));
+    return true;
+}
+
+bool RfDesenseTxTestGsm::set_channel(std::string value){
+    int index = utils::find_index(band_values, band);
+    if(check_channel(index,value)) {
+        channel = value;
+        em_result_notify_ok("channel: " + channel);
+        return true;
+    }
+    return false;
+}
+
+bool RfDesenseTxTestGsm::set_power(std::string value){
+    int index = utils::find_index(band_values, band);
+    if(check_power(index, value)) {
+        power = value;
+        em_result_notify_ok("power: " + power);
+        return true;
+    }
+    return false;
+}
+bool RfDesenseTxTestGsm::set_afc(std::string value){
+    LOG_D(LOG_TAG,"set_afc: %s", value);
+    if(check_afc(value)){
+        afc = value;
+        em_result_notify_ok("afc: " + afc);
+        return true;
+    }
+    return false;
+}
+
+bool RfDesenseTxTestGsm::set_tsc(std::string value){
+    if(check_tsc(value)) {
+        tsc = value;
+        em_result_notify_ok("tsc: " + tsc);
+        return true;
+    }
+    return false;
+}
+
+bool RfDesenseTxTestGsm::check_channel(int index, std::string channel) {
+    std::string s;
+    if(index >= gsm_gmsk_limits.size()) {
+        s = utils::format("check_channel,index(%d) is invalid", index);
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_channel,index(%d) is invalid", index);
+        return false;
+    }
+    int value = -1;
+    try {
+        value = std::stoi(channel);
+    } catch (std::invalid_argument &err) {
+        s = utils::format("check_channel,channel(%s) is invalid, reason: %s", channel.c_str(), err.what());
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_channel,channel(%s) is invalid, reason: %s", channel.c_str(), err.what());
+        return false;
+    }
+    step = 1;
+    std::vector<std::string> limits = gsm_gmsk_limits[index];
+    min = std::stoi(limits[RfDesenseTxTestBase::CHANNEL_MIN]);
+    max =  std::stoi(limits[RfDesenseTxTestBase::CHANNEL_MAX]);
+    min2 =  std::stoi(limits[RfDesenseTxTestBase::CHANNEL_MIN2]);
+    max2 =  std::stoi(limits[RfDesenseTxTestBase::CHANNEL_MAX2]);
+    if ((value < min || value > max) && (value < min2 || value > max2)) {
+        s = utils::format("check_channel,channel(%s) is invalid, range is [%d, %d] or [%d, %d]" , channel.c_str(), min, max, min2, max2);
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_channel,channel(%s) is invalid, range is [%d, %d] or [%d, %d]" , channel.c_str(), min, max, min2, max2);
+        return false;
+    }
+    return true;
+}
+
+bool RfDesenseTxTestGsm::check_power(int index ,std::string power) {
+    std::string s;
+    if(index >= gsm_gmsk_limits.size()) {
+        s = utils::format("check_power,index(%d) is invalid", index);
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_power,index(%d) is invalid", index);
+        return false;
+    }
+    int value = -1;
+    try {
+        value = std::stoi(power);
+    } catch (std::invalid_argument &err) {
+        s = utils::format("check_power,power(%s) is invalid, reason: %s", power.c_str(), err.what());
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_power,power(%s) is invalid, reason: %s", power.c_str(), err.what());
+        return false;
+    }
+    step = 1;
+    std::vector<std::string> limits = gsm_gmsk_limits[index];
+    min = std::stoi(limits[RfDesenseTxTestBase::POWER_MIN]);
+    max =  std::stoi(limits[RfDesenseTxTestBase::POWER_MAX]);
+    if (value < min || value > max) {
+        s = utils::format("check_power,power(%s) is invalid, range is [%d, %d]" , power.c_str(), min, max);
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_power,power(%s) is invalid, range is [%d, %d]" , power.c_str(), min, max);
+        return false;
+    }
+    return true;
+}
+
+bool RfDesenseTxTestGsm::check_afc(std::string afc) {
+    std::string s;
+    int value = -1;
+    try {
+        value = std::stoi(afc);
+    } catch (std::invalid_argument &err) {
+        s = utils::format("check_afc, afc(%s) is invalid, reason: %s", afc.c_str(), err.what());
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_afc, afc(%s) is invalid, reason: %s", afc.c_str(), err.what());
+        return false;
+    }
+    if(value < 0 || value > 8191) {
+        em_result_notify_fail("check_afc,afc(%s) is invalid, range is (0,8191)");
+        LOG_D(LOG_TAG, "check_afc,afc(%s) is invalid, range is (0,8191)" , afc.c_str());
+        return false;
+    }
+    return true;
+}
+
+bool RfDesenseTxTestGsm::check_tsc(std::string tsc){
+    std::string s;
+    int value = -1;
+    try {
+        value = std::stoi(tsc);
+    } catch (std::invalid_argument &err) {
+        s = utils::format("check_tsc, tsc(%s) is invalid, reason: %s", tsc.c_str(), err.what());
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_tsc, tsc(%s) is invalid, reason: %s", tsc.c_str(), err.what());
+        return false;
+    }
+    if(value < 0 || value > 7) {
+        em_result_notify_fail("check_tsc, tsc(%s) is invalid, range is [0,7]");
+        LOG_D(LOG_TAG, "check_tsc, tsc(%s) is invalid, range is [0,7]" , tsc.c_str());
+        return false;
+    }
+    return true;
+}
+
+bool RfDesenseTxTestGsm::check_pattern(std::string pattern) {
+    int value = -1;
+    try {
+        value = std::stoi(pattern);
+    } catch (std::invalid_argument &err) {
+        LOG_D(LOG_TAG, "check_pattern, pattern(%s) is invalid, reason: %s\n", pattern.c_str(), err.what());
+        return false;
+    }
+    if(value < 0 || value > 6) {
+        LOG_D(LOG_TAG, "check_pattern, pattern(%s) is invalid, range is [0,6]\n" , pattern.c_str());
+        return false;
+    }
+    return true;
+}
+
+void RfDesenseTxTestGsm::show_default() {
+    int band_index = utils::find_index(band_values, band);
+    int pattern_index = std::stoi(pattern);
+    std::string temp = "GSM parameter: Band: " + std::string(rfdesense_gsm_band[band_index].name) +
+            ", Channel(ARFCN): " + channel + ", Power Level: " + power + ", AFC: " + afc + ", TSC: " + tsc +
+            ", PATTERN: " + std::string(rfdesense_gsm_pattern[pattern_index].name);
+    emResultNotifyWithDone(temp);
+}
+
+void RfDesenseTxTestGsm::show_channel(){
+    emResultNotifyWithDone("Channel(ARFCN): " + channel);
+}
+void RfDesenseTxTestGsm::show_power(){
+    emResultNotifyWithDone("Power Level: " + power);
+}
+void RfDesenseTxTestGsm::show_afc(){
+    emResultNotifyWithDone("AFC: " + afc);
+}
+void RfDesenseTxTestGsm::show_tsc(){
+    emResultNotifyWithDone("TSC: " + tsc);
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestGsm.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestGsm.h
new file mode 100644
index 0000000..0963e49
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestGsm.h
@@ -0,0 +1,93 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef RFDESENSETXTESTGSM_H_
+#define RFDESENSETXTESTGSM_H_
+
+#include <string>
+#include <vector>
+#include <memory>
+#include <mutex>
+
+class RfDesenseTxTestGsm {
+public:
+    std::string get_command();
+    std::string get_band();
+    std::string get_power();
+    bool set_band(int value);
+    bool set_pattern(int value);
+    bool set_channel(std::string value);
+    bool set_power(std::string value);
+    bool set_afc(std::string value);
+    bool set_tsc(std::string value);
+    void show_default();
+    void show_channel();
+    void show_power();
+    void show_afc();
+    void show_tsc();
+    RfDesenseTxTestGsm();
+    virtual ~RfDesenseTxTestGsm();
+    static std::shared_ptr<RfDesenseTxTestGsm> get_instance();
+private:
+    static std::shared_ptr<RfDesenseTxTestGsm> m_instance;
+    static std::mutex mutex;
+    int min = -1;
+    int max = -1;
+    int min2 = -1;
+    int max2 = -1;
+    int step = 1;
+    static const int INDEX_BAND;
+    static const int INDEX_CHANNEL;
+    static const int INDEX_POWER;
+    static const int INDEX_AFC;
+    static const int INDEX_TSC;
+    static const int INDEX_PATTERN;
+    static std::string band;
+    static std::string channel;
+    static std::string power;
+    static std::string afc;
+    static std::string tsc;
+    static std::string pattern;
+    std::string command;
+    bool check_channel(int index, std::string channel);
+    bool check_power(int index, std::string power);
+    bool check_afc(std::string afc);
+    bool check_tsc(std::string tsc);
+    bool check_pattern(std::string pattern);
+    static const std::vector<std::string> band_values;
+    static const std::vector<std::vector<std::string>> gsm_gmsk_limits;
+};
+
+#endif /* RFDESENSETXTESTGSM_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestLte.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestLte.cpp
new file mode 100644
index 0000000..56c6275
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestLte.cpp
@@ -0,0 +1,614 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include "rfdesense/RfDesenseTxTestLte.h"
+
+#include <algorithm>
+#include <iterator>
+#include <stdexcept>
+
+#include "rfdesense/RfDesenseTxTestBase.h"
+#include "util/log_extra.h"
+#include "em.h"
+
+#undef LOG_TAG
+#define LOG_TAG "EM_RfDesenseTxTestLte"
+
+const int RfDesenseTxTestLte::INDEX_BAND = 0;
+const int RfDesenseTxTestLte::INDEX_BAND_WIDTH = 1;
+const int RfDesenseTxTestLte::INDEX_FREQ = 2;
+const int RfDesenseTxTestLte::INDEX_VRB_START = 3;
+const int RfDesenseTxTestLte::INDEX_VRB_LENGTH = 4;
+const int RfDesenseTxTestLte::INDEX_MCS = 5;
+const int RfDesenseTxTestLte::INDEX_POWER = 6;
+const int RfDesenseTxTestLte::INDEX_MODE = 7;
+const int RfDesenseTxTestLte::INDEX_TDD_CONFIG = 8;
+const int RfDesenseTxTestLte::INDEX_TDD_SPECIAL = 9;
+std::string RfDesenseTxTestLte::band="";
+std::string RfDesenseTxTestLte::band_width="";
+std::string RfDesenseTxTestLte::freq="";
+std::string RfDesenseTxTestLte::tdd_config="";
+std::string RfDesenseTxTestLte::tdd_special="";
+std::string RfDesenseTxTestLte::vrb_start="";
+std::string RfDesenseTxTestLte::vrb_length="";
+std::string RfDesenseTxTestLte::mcs="";
+std::string RfDesenseTxTestLte::power="";
+std::string RfDesenseTxTestLte::mode="";
+
+const std::vector<std::string> RfDesenseTxTestLte::band_fdd = {"1","2","3","4","5","6","7","8","9","10","11","12",
+            "13","14","19","20","21","22","23","24","25","26","27","28","29","30","31","66"};
+const std::vector<std::string> RfDesenseTxTestLte::band_tdd = {"33","34","35","36","37","38","39","40","41","42","43","44"};
+const std::vector<std::vector<std::string>> RfDesenseTxTestLte::fdd_freq_limits = {
+            {"19200","19800"},
+            {"18500","19100"},
+            {"17100","17850"},
+            {"17100","17550"},
+            {"8240","8490"},
+            {"8300","8400"},
+            {"25000","25700"},
+            {"8800","9150"},
+            {"17499","17849"},
+            {"17100","17700"},
+            {"14279","14479"},
+            {"6990","7160"},
+            {"7770","7870 "},
+            {"7880","7980"},
+            {"0","0"},
+            {"0","0"},
+            {"7040","7160"},
+            {"8150","8300"},
+            {"8300","8450"},
+            {"8320","8620"},
+            {"14479","14629"},
+            {"34100","34900"},
+            {"20000","20200"},
+            {"16265","16605"},
+            {"18500","19150"},
+            {"8140","8490 "},
+            {"8070","8240"},
+            {"7030","7480"},
+            {"0","0"},
+            {"23050","23150"},
+            {"4525","4575"},
+            {"17100","17800"}
+    };
+
+const std::vector<std::vector<std::string>> RfDesenseTxTestLte::tdd_freq_limits = {
+            {"19000","19200"},
+            {"20100","20250"},
+            {"18500","19100"},
+            {"19300","19900"},
+            {"19100","19300"},
+            {"25700","26200"},
+            {"18800","19200"},
+            {"23000","24000"},
+            {"24960","26900"},
+            {"34000","36000"},
+            {"36000","38000"}
+    };
+
+std::map<int, std::string> RfDesenseTxTestLte::lte_fdd_values = { { INDEX_BAND,
+        "3" }, { INDEX_BAND_WIDTH, "3" }, { INDEX_FREQ, "17475" }, { INDEX_VRB_START, "0" }, {
+                INDEX_VRB_LENGTH, "1" }, { INDEX_MCS, "0" }, { INDEX_POWER, "23" }, { INDEX_MODE,
+        "1" }, { INDEX_TDD_CONFIG, "0" }, { INDEX_TDD_SPECIAL, "0" }, };
+std::map<int, std::string> RfDesenseTxTestLte::lte_tdd_valuse= { { INDEX_BAND,
+        "38" }, { INDEX_BAND_WIDTH, "3" }, { INDEX_FREQ, "25950" }, { INDEX_VRB_START, "0" }, {
+                INDEX_VRB_LENGTH, "1" }, { INDEX_MCS, "0" }, { INDEX_POWER, "23" }, { INDEX_MODE,
+        "1" }, { INDEX_TDD_CONFIG, "0" }, { INDEX_TDD_SPECIAL, "0" }, };
+
+RfDesenseTxTestLte::RfDesenseTxTestLte(int type) {
+    modem_type = type;
+    std::map<int, std::string> tmp;
+    if(modem_type == utils::MODEM_LTE_FDD){
+        tmp = lte_fdd_values;
+    } else if(modem_type == utils::MODEM_LTE_TDD) {
+        tmp = lte_tdd_valuse;
+    }
+    LOG_D(LOG_TAG, "modem_type: %d", modem_type);
+    if(!tmp.empty()) {
+        band = tmp[INDEX_BAND];
+        band_width = tmp[INDEX_BAND_WIDTH];
+        freq = tmp[INDEX_FREQ];
+        tdd_config = tmp[INDEX_TDD_CONFIG];
+        tdd_special = tmp[INDEX_TDD_SPECIAL];
+        vrb_start = tmp[INDEX_VRB_START];
+        vrb_length = tmp[INDEX_VRB_LENGTH];
+        mcs = tmp[INDEX_MCS];
+        power = tmp[INDEX_POWER];
+        mode = tmp[INDEX_MODE];
+    }
+
+}
+
+void RfDesenseTxTestLte::show_default() {
+    std::string str;
+    std::string band_width_tmp(rfdesense_lte_bandwidth[std::stoi(band_width)].name);
+    std::string mcs_tmp(rfdesense_lte_mcs[std::stoi(mcs)].name);
+    std::string duplex;
+    if (modem_type == utils::MODEM_LTE_FDD) {
+        duplex = "LTE(fdd) ";
+    } else if (modem_type == utils::MODEM_LTE_FDD) {
+        duplex = "LTE(tdd) ";
+    }
+    str = duplex + "mode: "
+            + (std::stoi(mode) == 0 ?
+                    std::string("single tone") :
+                    std::string("modulation signal")) + ", Band: " + band
+            + ", UL Bandwidth: " + band_width_tmp + ", UL Freq(100kHz): " + freq
+            + ", TDD Config index: " + tdd_config
+            + ", TDD Special SF Config Index: " + tdd_special
+            + ", VRB Start(0~99): " + vrb_start + ", VRB Length(1~100): "
+            + vrb_length + ", MCS: " + mcs_tmp + ", Power Level(dBm)(-50-23): "
+            + power;
+    emResultNotifyWithDone(str);
+}
+
+RfDesenseTxTestLte::~RfDesenseTxTestLte() {
+    // TODO Auto-generated destructor stub
+}
+std::string RfDesenseTxTestLte::modemTypeToString(int type) {
+    switch(modem_type){
+        case utils::MODEM_LTE_FDD:
+            return "LTE(FDD)";
+        case utils::MODEM_LTE_TDD:
+            return "LTE(TDD)";
+        default:
+            return "UNKNOWN";
+    }
+}
+
+std::string RfDesenseTxTestLte::get_command() {
+    std::string atcmd = "";
+    if(utils::is93Modem() && (mode == "0")){
+        atcmd = "AT+ERFTX=6,0,2,";
+    } else {
+        atcmd = "AT+ERFTX=6,0,1,";
+    }
+    command = band + "," + band_width  + ","
+            + freq + ","
+            + (modem_type == utils::MODEM_LTE_TDD ? "0" : "1") + ","
+#if 0
+            + (modem_type == utils::MODEM_LTE_TDD ? tdd_config : "0") + ","
+            + (modem_type == utils::MODEM_LTE_TDD ? tdd_special : "0") + ","
+#endif
+            + tdd_config + ","
+            + tdd_special + ","
+            + vrb_start + ","
+            + vrb_length + ","
+            + mcs + ","
+            + power;
+    LOG_D(LOG_TAG, "modem_type(%) command: %s", modemTypeToString(modem_type), command);
+    return command;
+
+}
+std::string RfDesenseTxTestLte::get_band() {
+    return band;
+}
+std::string RfDesenseTxTestLte::get_power() {
+    return power;
+}
+
+bool RfDesenseTxTestLte::check_band(std::string band) {
+    std::vector<std::string> band_values;
+    if(modem_type == utils::MODEM_LTE_TDD){
+        band_values = band_tdd;
+    } else if(modem_type == utils::MODEM_LTE_FDD) {
+        band_values = band_fdd;
+    } else {
+        LOG_D(LOG_TAG, "check_band(): modem type (%s) isn't right", modemTypeToString(modem_type));
+        return false;
+    }
+
+    auto is_band_find = std::find(band_values.begin(), band_values.end(), band); //band
+    int band_index = -1;
+    if(is_band_find != band_values.end()) {
+        band_index = std::distance(band_values.begin(), is_band_find);
+        LOG_D(LOG_TAG, "checks: band_index: %d, band: %s", band_index, band.c_str());
+    } else {
+        LOG_D(LOG_TAG, "band value(%s) isn't invalid", band.c_str());
+        return false;
+    }
+    return true;
+}
+
+bool RfDesenseTxTestLte::check_band_width(std::string band_width) {
+    int value = -1;
+    try {
+        value = std::stoi(band_width);
+    } catch (std::invalid_argument &err) {
+        LOG_D(LOG_TAG, "check_band_width,check_band_width(%s) is invalid, reason: %s", band_width.c_str(), err.what());
+        return false;
+    }
+    if (value < 0 || value > 5) {
+        LOG_D(LOG_TAG, "check_band_width value range is [%d, %d], input value is %d", 0, 5, value);
+        return false;
+    }
+    return true;
+}
+
+bool RfDesenseTxTestLte::check_freq(std::string freq) {
+    return true;
+}
+
+bool RfDesenseTxTestLte::check_tdd_config(std::string config) {
+    int value = -1;
+    try {
+        value = std::stoi(config);
+    } catch (std::invalid_argument &err) {
+        LOG_D(LOG_TAG, "check_tdd_config,check_tdd_config(%s) is invalid, reason: %s", config.c_str(), err.what());
+        return false;
+    }
+    if(modem_type == utils::MODEM_LTE_TDD){
+        if(value < 0 || value >6){
+            LOG_D(LOG_TAG, "check_tdd_config value range is [%d, %d], input value is %d", 0, 6, value);
+            return false;
+        }
+    } else if(modem_type == utils::MODEM_LTE_FDD) {
+        if(value != 0) {
+            return false;
+        }
+    } else {
+        LOG_D(LOG_TAG, "check_tdd_config(): modem type (%s) isn't right", modemTypeToString(modem_type));
+        return false;
+    }
+    return true;
+}
+
+bool RfDesenseTxTestLte::check_tdd_special(std::string special) {
+    int value = -1;
+    try {
+        value = std::stoi(special);
+    } catch (std::invalid_argument &err) {
+        LOG_D(LOG_TAG, "check_tdd_special,check_tdd_config(%s) is invalid, reason: %s", special.c_str(), err.what());
+        return false;
+    }
+    if(modem_type == utils::MODEM_LTE_TDD){
+        if(value < 0 || value >9){
+            LOG_D(LOG_TAG, "check_tdd_special value range is [%d, %d], input value is %d", 0, 9, value);
+            return false;
+        }
+    } else if(modem_type == utils::MODEM_LTE_FDD) {
+        if(value != 0) {
+            return false;
+        }
+    } else {
+        LOG_D(LOG_TAG, "check_tdd_special(): modem type (%s) isn't right", modemTypeToString(modem_type));
+        return false;
+    }
+    return true;
+}
+
+bool RfDesenseTxTestLte::check_vrb_start(std::string start) {
+    std::string s;
+    int value = -1;
+    try {
+        value = std::stoi(start);
+    } catch (std::invalid_argument &err) {
+        s = utils::format("check_vrb_start,check_vrb_start(%s) is invalid, reason: %s", start.c_str(), err.what());
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_vrb_start,check_vrb_start(%s) is invalid, reason: %s", start.c_str(), err.what());
+        return false;
+    }
+    if (value < 0 || value > 99) {
+        s = utils::format("check_vrb_start value range is [%d, %d], input value is %d", 0, 9, value);
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_vrb_start value range is [%d, %d], input value is %d", 0, 9, value);
+        return false;
+    }
+    return true;
+}
+
+bool RfDesenseTxTestLte::check_vrb_length(std::string length) {
+    std::string s;
+    int value = -1;
+    try {
+        value = std::stoi(length);
+    } catch (std::invalid_argument &err) {
+        s = utils::format("check_vrb_length,check_vrb_length(%s) is invalid, reason: %s", length.c_str(), err.what());
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_vrb_length,check_vrb_length(%s) is invalid, reason: %s", length.c_str(), err.what());
+        return false;
+    }
+    if (value < 1  || value > 100) {
+        s = utils::format("check_vrb_length value range is [%d, %d], input value is %d", 1, 100, value);
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_vrb_length value range is [%d, %d], input value is %d", 1, 100, value);
+        return false;
+    }
+    return true;
+}
+
+bool RfDesenseTxTestLte::check_mcs(std::string mcs) {
+    int value = -1;
+    try {
+        value = std::stoi(mcs);
+    } catch (std::invalid_argument &err) {
+        LOG_D(LOG_TAG, "check_mcs,check_mcs(%s) is invalid, reason: %s", mcs.c_str(), err.what());
+        return false;
+    }
+    if (value < 0 || value > 2) {
+        LOG_D(LOG_TAG, "check_mcs value range is [%d, %d], input value is %d", 0, 2, value);
+        return false;
+    }
+    return true;
+}
+
+bool RfDesenseTxTestLte::check_power(std::string power) {
+    std::string s;
+    int value = -1;
+    try {
+        value = std::stoi(power);
+    } catch (std::invalid_argument &err) {
+        s = utils::format("check_power,check_power(%s) is invalid, reason: %s", power.c_str(), err.what());
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_power,check_power(%s) is invalid, reason: %s", power.c_str(), err.what());
+        return false;
+    }
+    if (value < -50 || value > 23) {
+        s = utils::format("check_power value range is [%d, %d], input value is %d", -50, 23, value);
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_power value range is [%d, %d], input value is %d", -50, 23, value);
+        return false;
+    }
+    return true;
+}
+
+bool RfDesenseTxTestLte::check_mode(std::string mode) {
+    int value = -1;
+    try {
+        value = std::stoi(mode);
+    } catch (std::invalid_argument &err) {
+        LOG_D(LOG_TAG, "check_tone,check_tone(%s) is invalid, reason: %s", mode.c_str(), err.what());
+        return false;
+    }
+    if (value == 0 || value == 1) {
+        LOG_D(LOG_TAG, "check_mode value range is %d or %d, input value is %d", 0, 1, mode);
+        return false;
+    }
+    return true;
+}
+
+bool RfDesenseTxTestLte::set_mode(int value){
+    std::string s;
+    if(value !=0 && value != 1) {
+        s = utils::format("set_mode: value(%d) is out of range", value);
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "set_mode: value(%d) is out of range", value);
+        return false;
+    }
+    mode = std::to_string(value);
+    if(modem_type == utils::MODEM_LTE_FDD){
+        lte_fdd_values[INDEX_MODE] = mode;
+    } else if(modem_type == utils::MODEM_LTE_TDD) {
+        lte_tdd_valuse[INDEX_MODE] = mode;
+    } else {
+        em_result_notify_fail("set_mode error");
+        LOG_D(LOG_TAG, "set_mode error");
+        return false;
+    }
+    em_result_notify_ok("mode: " + (value == 0 ?
+            std::string("single tone") :
+            std::string("modulation signal")));
+    return true;
+}
+
+bool RfDesenseTxTestLte::set_band(int value){
+    std::string s;
+    std::vector<std::string> band_values;
+    if(modem_type == utils::MODEM_LTE_TDD){
+        band_values = band_tdd;
+    } else if(modem_type == utils::MODEM_LTE_FDD) {
+        band_values = band_fdd;
+    } else {
+        s = utils::format("check_band(): modem type (%s) isn't right", modemTypeToString(modem_type));
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_band(): modem type (%s) isn't right", modemTypeToString(modem_type));
+        return false;
+    }
+    if(value < 0 || value >= band_values.size()){
+        s = utils::format("set_band: value(%d) is out of range", value);
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "set_band: value(%d) is out of range", value);
+        return false;
+    }
+    band = band_values[value];
+    if(modem_type == utils::MODEM_LTE_TDD){
+        lte_tdd_valuse[INDEX_BAND] = band;
+    } else if(modem_type == utils::MODEM_LTE_FDD) {
+        lte_fdd_values[INDEX_BAND] = band;
+    } else {
+        s = utils::format("check_band(): modem type (%s) isn't right", modemTypeToString(modem_type));
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_band(): modem type (%s) isn't right", modemTypeToString(modem_type));
+        return false;
+    }
+    em_result_notify_ok("band: " + band);
+    return true;
+}
+
+bool RfDesenseTxTestLte::set_bandwith(int value){
+    std::string s;
+    if (value < 0 || value > 5) {
+        s = utils::format("check_band_width value range is [%d, %d], input value is %d", 0, 5, value);
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_band_width value range is [%d, %d], input value is %d", 0, 5, value);
+        return false;
+    }
+    band_width = std::to_string(value);
+    if(modem_type == utils::MODEM_LTE_FDD){
+        lte_fdd_values[INDEX_BAND_WIDTH] = band_width;
+    } else if(modem_type == utils::MODEM_LTE_TDD) {
+        lte_tdd_valuse[INDEX_BAND_WIDTH] = band_width;
+    } else {
+        em_result_notify_fail("set_bandwith error");
+        LOG_D(LOG_TAG, "set_bandwith error");
+        return false;
+    }
+    em_result_notify_ok(std::string("band_width: ") + rfdesense_lte_bandwidth[value].name);
+    return true;
+}
+
+bool RfDesenseTxTestLte::set_freq(std::string str){
+    freq = str;
+    if(modem_type == utils::MODEM_LTE_FDD){
+        lte_fdd_values[INDEX_FREQ] = freq;
+    } else if(modem_type == utils::MODEM_LTE_TDD) {
+        lte_tdd_valuse[INDEX_FREQ] = freq;
+    } else {
+        em_result_notify_fail("set_freq error");
+        LOG_D(LOG_TAG, "set_freq error");
+        return false;
+    }
+    em_result_notify_ok("freq: " + freq);
+    return true;
+
+}
+
+bool RfDesenseTxTestLte::set_tdd_config(int value){
+    if(modem_type == utils::MODEM_LTE_TDD){
+        if(value < 0 || value >6){
+            std::string s;
+            s = utils::format("check_tdd_config value range is [%d, %d], input value is %d", 0, 6, value);
+            em_result_notify_fail(s);
+            LOG_D(LOG_TAG, "check_tdd_config value range is [%d, %d], input value is %d", 0, 6, value);
+            return false;
+        }
+        tdd_config = std::to_string(value);
+        lte_tdd_valuse[INDEX_TDD_CONFIG] = tdd_config;
+    }
+    em_result_notify_ok("tdd_config: " + tdd_config);
+    return true;
+}
+
+bool RfDesenseTxTestLte::set_tdd_special(int value){
+    if(modem_type == utils::MODEM_LTE_TDD){
+        if(value < 0 || value >9){
+            std::string s;
+            s = utils::format("check_tdd_special value range is [%d, %d], input value is %d", 0, 9, value);
+            em_result_notify_fail(s);
+            LOG_D(LOG_TAG, "check_tdd_special value range is [%d, %d], input value is %d", 0, 9, value);
+            return false;
+        }
+        tdd_special = std::to_string(value);
+        lte_tdd_valuse[INDEX_TDD_SPECIAL] = tdd_special;
+    }
+    em_result_notify_ok("tdd_special: " + tdd_special);
+    return true;
+}
+
+bool RfDesenseTxTestLte::set_start(std::string str){
+    if(!check_vrb_start(str)) return false;
+    vrb_start = str;
+    if(modem_type == utils::MODEM_LTE_FDD){
+        lte_fdd_values[INDEX_VRB_START] = vrb_start;
+    } else if(modem_type == utils::MODEM_LTE_TDD) {
+        lte_tdd_valuse[INDEX_VRB_START] = vrb_start;
+    } else {
+        em_result_notify_fail("set_start error");
+        LOG_D(LOG_TAG, "set_start error");
+        return false;
+    }
+    em_result_notify_ok("vrb_start: " + vrb_start);
+    return true;
+
+}
+
+bool RfDesenseTxTestLte::set_length(std::string str){
+    if(!check_vrb_length(str)) return false;
+    vrb_length = str;
+    if(modem_type == utils::MODEM_LTE_FDD){
+        lte_fdd_values[INDEX_VRB_LENGTH] = vrb_length;
+    } else if(modem_type == utils::MODEM_LTE_TDD) {
+        lte_tdd_valuse[INDEX_VRB_LENGTH] = vrb_length;
+    } else {
+        em_result_notify_fail("set_start error");
+        LOG_D(LOG_TAG, "set_length error");
+        return false;
+    }
+    em_result_notify_ok("vrb_length: " + vrb_length);
+    return true;
+}
+
+bool RfDesenseTxTestLte::set_power(std::string str){
+    if(!check_power(str)) return false;
+    power = str;
+    if(modem_type == utils::MODEM_LTE_FDD){
+        lte_fdd_values[INDEX_POWER] = power;
+    } else if(modem_type == utils::MODEM_LTE_TDD) {
+        lte_tdd_valuse[INDEX_POWER] = power;
+    } else {
+        em_result_notify_fail("set_start error");
+        LOG_D(LOG_TAG, "set_power error");
+        return false;
+    }
+    em_result_notify_ok("power: " + power);
+    return true;
+}
+bool RfDesenseTxTestLte::set_mcs(int value) {
+    if (value < 0 || value > 2) {
+        std::string s;
+        s = utils::format("check_mcs value range is [%d, %d], input value is %d", 0, 2, value);
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_mcs value range is [%d, %d], input value is %d", 0, 2, value);
+        return false;
+    }
+    mcs = std::to_string(value);
+    if(modem_type == utils::MODEM_LTE_FDD){
+        lte_fdd_values[INDEX_MCS] = mcs;;
+    } else if(modem_type == utils::MODEM_LTE_TDD) {
+        lte_tdd_valuse[INDEX_MCS] = mcs;;
+    } else {
+        em_result_notify_fail("set_start error");
+        LOG_D(LOG_TAG, "set_mcs error");
+        return false;
+    }
+    em_result_notify_ok(std::string("mcs: ") + rfdesense_lte_mcs[value].name);
+    return true;
+}
+
+void RfDesenseTxTestLte::show_freq(){
+    emResultNotifyWithDone("UL Freq(100kHZ): " + freq);
+}
+
+void RfDesenseTxTestLte::show_start(){
+    emResultNotifyWithDone("VRB Start(0~99): " + vrb_start);
+}
+
+void RfDesenseTxTestLte::show_length(){
+    emResultNotifyWithDone("VRB Length(1~100): " + vrb_length);
+}
+
+void RfDesenseTxTestLte::show_power(){
+    emResultNotifyWithDone("Power Level(dBm)(-50~23): " + power);
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestLte.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestLte.h
new file mode 100644
index 0000000..8b0f53a
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestLte.h
@@ -0,0 +1,110 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef RFDESENSETXTESTLTE_H_
+#define RFDESENSETXTESTLTE_H_
+
+#include <string>
+#include <vector>
+#include <map>
+
+#include "util/utils.h"
+
+class RfDesenseTxTestLte {
+public:
+    RfDesenseTxTestLte(int type);
+    virtual ~RfDesenseTxTestLte();
+    void show_default();
+    std::string get_command();
+    std::string get_band();
+    std::string get_power();
+    bool set_mode(int value);
+    bool set_band(int value);
+    bool set_bandwith(int value);
+    bool set_freq(std::string str);
+    bool set_tdd_config(int value);
+    bool set_tdd_special(int value);
+    bool set_start(std::string str);
+    bool set_length(std::string str);
+    bool set_mcs(int value);
+    bool set_power(std::string str);
+    void show_freq();
+    void show_start();
+    void show_length();
+    void show_power();
+private:
+    bool check_band(std::string band);
+    bool check_band_width(std::string band_width);
+    bool check_freq(std::string freq);
+    bool check_tdd_config(std::string config);
+    bool check_tdd_special(std::string special);
+    bool check_vrb_start(std::string start);
+    bool check_vrb_length(std::string length);
+    bool check_mcs(std::string mcs);
+    bool check_power(std::string power);
+    bool check_mode(std::string mode);
+    std::string modemTypeToString(int type);
+
+    std::string command;
+    static const int INDEX_BAND;
+    static const int INDEX_BAND_WIDTH;
+    static const int INDEX_FREQ;
+    static const int INDEX_VRB_START;
+    static const int INDEX_VRB_LENGTH;
+    static const int INDEX_MCS;
+    static const int INDEX_POWER;
+    static const int INDEX_MODE;
+    static const int INDEX_TDD_CONFIG;
+    static const int INDEX_TDD_SPECIAL;
+    static std::string band;
+    static std::string band_width;
+    static std::string freq;
+    static std::string tdd_config;
+    static std::string tdd_special;
+    static std::string vrb_start;
+    static std::string vrb_length;
+    static std::string mcs;
+    static std::string power;
+    static std::string mode;
+    static std::map<int, std::string> lte_fdd_values;
+    static std::map<int, std::string> lte_tdd_valuse;
+    int modem_type = utils::MODEM_UNKNOWN;
+    static const std::vector<std::string> band_fdd;
+    static const std::vector<std::string> band_tdd;
+    static const std::vector<std::vector<std::string>> fdd_freq_limits;
+    static const std::vector<std::vector<std::string>> tdd_freq_limits;
+};
+
+#endif /* RFDESENSETXTESTLTE_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestTd.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestTd.cpp
new file mode 100644
index 0000000..f945a71
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestTd.cpp
@@ -0,0 +1,331 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include "rfdesense/RfDesenseTxTestTd.h"
+
+#include <algorithm>
+#include <iterator>
+#include <stdexcept>
+
+#include "em.h"
+#include "rfdesense/RfDesenseTxTestBase.h"
+#include "util/log_extra.h"
+
+#undef LOG_TAG
+#define LOG_TAG "EM_RfDesenseTxTestTd"
+const int RfDesenseTxTestTd::INDEX_BAND = 0;
+const int RfDesenseTxTestTd::INDEX_CHANNEL = 1;
+const int RfDesenseTxTestTd::INDEX_POWER = 2;
+std::string RfDesenseTxTestTd::band = "";
+std::string RfDesenseTxTestTd::channel= "";
+std::string RfDesenseTxTestTd::power= "";
+const std::vector<std::string> RfDesenseTxTestTd::tdscdma_band_values = {"1","6"};
+const std::vector<std::vector<std::string>> RfDesenseTxTestTd::tdscdma_limits = {
+            {"10087","10054","10121","10054","10121","24","10","24"},
+            {"9500","9404","9596","9404","9596","24","10","24"}};
+const std::vector<std::string> RfDesenseTxTestTd::wcdma_band_values = {"1","2","3","4","5","6","7","8","9","10","11","12","13","14","19","20","21","22"};
+const std::vector<std::vector<std::string>> RfDesenseTxTestTd::wcdma_limits = {
+            {"9750","9612","9888","9612","9888","23","-55","24"},
+            {"9262","9262","9538","12","287","23","-55","24"},
+            {"937","937","1288","937","1288","23","-55","24"},
+            {"1312","1312","1513","1662","1862","23","-55","24"},
+            {"4132","4132","4233","782","862","23","-55","24"},
+            {"4162","4162","4188","812","837","23","-55","24"},
+            {"2012","2012","2338","2362","2687","23","-55","24"},
+            {"2712","2712","2863","2712","2863","23","-55","24"},
+            {"8762","8762","8912","8762","8912","23","-55","24"},
+            {"2887","2887","3163","3187","3462","23","-55","24"},
+            {"3487","3487","3562","3487","3562","23","-55","24"},
+            {"3617","3617","3678","3707","3767","23","-55","24"},
+            {"3792","3792","3818","3842","3867","23","-55","24"},
+            {"3892","3892","3918","3942","3967","23","-55","24"},
+            {"312","312","363","387","437","23","-55","24"},
+            {"4287","4287","4413","4287","4413","23","-55","24"},
+            {"462","462","512","462","512","23","-55","24"},
+            {"4437","4437","4813","4437","4813","23","-55","24"}};
+std::map<int, std::string> RfDesenseTxTestTd::tdscdam_values = {{INDEX_BAND, "1"},{INDEX_CHANNEL, "10087"},{INDEX_POWER, "24"}};
+std::map<int, std::string> RfDesenseTxTestTd::wcdma_values = {{INDEX_BAND, "1"},{INDEX_CHANNEL, "9750"},{INDEX_POWER, "23"}};
+
+RfDesenseTxTestTd::RfDesenseTxTestTd(int modemType) {
+    this->modem_type = modemType;
+    if(modem_type == utils::MODEM_TDSCDMA){
+        band = tdscdam_values[INDEX_BAND];
+        channel = tdscdam_values[INDEX_CHANNEL];
+        power = tdscdam_values[INDEX_POWER];
+    } else if(modem_type == utils::MODEM_WCDMA) {
+        band = wcdma_values[INDEX_BAND];
+        channel = wcdma_values[INDEX_CHANNEL];
+        power = wcdma_values[INDEX_POWER];
+    }
+}
+
+RfDesenseTxTestTd::~RfDesenseTxTestTd() {
+    // TODO Auto-generated destructor stub
+}
+
+std::string RfDesenseTxTestTd::modemTypeToString(int type) {
+    switch(modem_type){
+        case utils::MODEM_TDSCDMA:
+            return "TDSCDMA";
+        case utils::MODEM_WCDMA:
+            return "MODEM_WCDMA";
+        default:
+            return "UNKNOWN";
+    }
+}
+
+std::string RfDesenseTxTestTd::get_command() {
+    std::string command = "AT+ERFTX=0,0," + band + "," + channel + "," + power;
+    LOG_D(LOG_TAG, "GSM command: %s", command.c_str());
+    return command;
+}
+
+std::string RfDesenseTxTestTd::get_band(){
+    return band;
+}
+
+std::string RfDesenseTxTestTd::get_power(){
+    return power;
+}
+
+bool RfDesenseTxTestTd::check_channel(int index, std::string channel) {
+    std::string s;
+    std::vector<std::vector<std::string>> limits;
+    if(modem_type == utils::MODEM_TDSCDMA){
+        limits = tdscdma_limits;
+    } else if(modem_type == utils::MODEM_WCDMA) {
+        limits = wcdma_limits;
+    } else {
+        s = utils::format("check_channel(): modem type (%s) isn't right", modemTypeToString(modem_type));
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_channel(): modem type (%s) isn't right", modemTypeToString(modem_type));
+        return false;
+    }
+
+    if(index >= limits.size()) {
+        s = utils::format("check_channel,index(%d) is invalid", index);
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_channel,index(%d) is invalid", index);
+        return false;
+    }
+    int value = -1;
+    try {
+        value = std::stoi(channel);
+    } catch (std::invalid_argument &err) {
+        s = utils::format("check_channel,channel(%s) is invalid, reason: %s", channel.c_str(), err.what());
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_channel,channel(%s) is invalid, reason: %s", channel.c_str(), err.what());
+        return false;
+    }
+    step = 1;
+    std::vector<std::string> limit = limits[index];
+    min = std::stoi(limit[RfDesenseTxTestBase::CHANNEL_MIN]);
+    max =  std::stoi(limit[RfDesenseTxTestBase::CHANNEL_MAX]);
+    min2 =  std::stoi(limit[RfDesenseTxTestBase::CHANNEL_MIN2]);
+    max2 =  std::stoi(limit[RfDesenseTxTestBase::CHANNEL_MAX2]);
+    if ((value < min || value > max) && (value < min2 || value > max2)) {
+        s = utils::format("check_channel,channel(%s) is invalid, range is [%d, %d] or [%d, %d]" , channel.c_str(), min, max, min2, max2);
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_channel,channel(%s) is invalid, range is [%d, %d] or [%d, %d]" , channel.c_str(), min, max, min2, max2);
+        return false;
+    }
+    return true;
+}
+
+bool RfDesenseTxTestTd::check_power(int index ,std::string power) {
+    std::string s;
+    std::vector<std::vector<std::string>> limits;
+    if(modem_type == utils::MODEM_TDSCDMA){
+        limits = tdscdma_limits;
+    } else if(modem_type == utils::MODEM_WCDMA) {
+        limits = wcdma_limits;
+    } else {
+        s = utils::format("check_power(): modem type (%s) isn't right", modemTypeToString(modem_type));
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_power(): modem type (%s) isn't right", modemTypeToString(modem_type));
+        return false;
+    }
+    if(index >= limits.size()) {
+        s = utils::format("check_power,index(%d) is invalid", index);
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_power,index(%d) is invalid", index);
+        return false;
+    }
+    int value = -1;
+    try {
+        value = std::stoi(power);
+    } catch (std::invalid_argument &err) {
+        s = utils::format("check_power,power(%s) is invalid, reason: %s", power.c_str(), err.what());
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_power,power(%s) is invalid, reason: %s", power.c_str(), err.what());
+        return false;
+    }
+    step = 1;
+    std::vector<std::string> limit = limits[index];
+    min = std::stoi(limit[RfDesenseTxTestBase::POWER_MIN]);
+    max =  std::stoi(limit[RfDesenseTxTestBase::POWER_MAX]);
+    if (value < min || value > max) {
+        s = utils::format("check_power,power(%s) is invalid, range is [%d, %d]" , power.c_str(), min, max);
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "check_power,power(%s) is invalid, range is [%d, %d]" , power.c_str(), min, max);
+        return false;
+    }
+    if (step != 1 && (value - min) % step != 0) {
+        return false;
+    }
+    return true;
+}
+
+void RfDesenseTxTestTd::show_default() {
+    std::string temp;
+    if(modem_type == utils::MODEM_TDSCDMA){
+        int band_index = utils::find_index(tdscdma_band_values, band);
+        temp = "TDSCDMA parameters: Band: " + std::string(rfdesense_tdscdma_band[band_index].name) +
+            ", Channel(ARFCN): " + channel + ", Power Level(dBm): " + power;
+    } else if(modem_type == utils::MODEM_WCDMA) {
+        int band_index = utils::find_index(wcdma_band_values, band);
+        temp = "WCDMA parameters: Band: " + std::string(rfdesense_wcdma_band[band_index].name) +
+            ", Channel(ARFCN): " + channel + ", Power Level(dBm): " + power;
+    }
+    if(!temp.empty()) {
+        emResultNotifyWithDone(temp);
+    } else {
+        em_result_notify_fail("show_default");
+        LOG_D(LOG_TAG, "temp is null ");
+    }
+}
+
+bool RfDesenseTxTestTd::set_band(int value) {
+    std::string s;
+    std::vector<std::string> band_values;
+    if(modem_type == utils::MODEM_TDSCDMA){
+        band_values = tdscdma_band_values;
+    } else if(modem_type == utils::MODEM_WCDMA) {
+        band_values = wcdma_band_values;
+    } else {
+        s = utils::format("set_band(): modem type (%s) isn't right", modemTypeToString(modem_type));
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "set_band(): modem type (%s) isn't right", modemTypeToString(modem_type));
+        return false;
+    }
+    if(value < 0 || value >= band_values.size()) {
+        s = utils::format("set band(). value(%d) is out of range", value);
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "set band(). value(%d) is out of range", value);
+        return false;
+    }
+    band = band_values[value];
+    if(modem_type == utils::MODEM_TDSCDMA){
+        tdscdam_values[INDEX_BAND] = band;
+    } else if(modem_type == utils::MODEM_WCDMA) {
+        wcdma_values[INDEX_BAND] = band;
+    }
+    std::string temp;
+    if(modem_type == utils::MODEM_TDSCDMA){
+        em_result_notify_ok(std::string("band: ") + rfdesense_tdscdma_band[value].name);
+    } else if(modem_type == utils::MODEM_WCDMA) {
+        em_result_notify_ok(std::string("band: ") + rfdesense_wcdma_band[value].name);
+    }
+    return true;
+}
+
+bool RfDesenseTxTestTd::set_channel(std::string str) {
+    std::string s;
+    std::vector<std::string> band_values;
+    if(modem_type == utils::MODEM_TDSCDMA){
+        band_values = tdscdma_band_values;
+    } else if(modem_type == utils::MODEM_WCDMA) {
+        band_values = wcdma_band_values;
+    } else {
+        s = utils::format("set_channel(): modem type (%s) isn't right", modemTypeToString(modem_type));
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "set_channel(): modem type (%s) isn't right", modemTypeToString(modem_type));
+        return false;
+    }
+    int index = utils::find_index(band_values, band);
+    if(index < 0 ) {
+        s = utils::format("set_channel(%s) isn't invalid", band.c_str());
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "set_channel(%s) isn't invalid", band.c_str());
+        return false;
+    }
+    if(!check_channel(index, str)) return false;
+    channel = str;
+    if(modem_type == utils::MODEM_TDSCDMA){
+        tdscdam_values[INDEX_CHANNEL] = channel;
+    } else if(modem_type == utils::MODEM_WCDMA) {
+        wcdma_values[INDEX_CHANNEL] = channel;
+    }
+    em_result_notify_ok("channel: " + channel);
+    return true;
+}
+
+bool RfDesenseTxTestTd::set_power(std::string str) {
+    std::string s;
+    std::vector<std::string> band_values;
+    if(modem_type == utils::MODEM_TDSCDMA){
+        band_values = tdscdma_band_values;
+    } else if(modem_type == utils::MODEM_WCDMA) {
+        band_values = wcdma_band_values;
+    } else {
+        s = utils::format("set_power(): modem type (%s) isn't right", modemTypeToString(modem_type));
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "set_power(): modem type (%s) isn't right", modemTypeToString(modem_type));
+        return false;
+    }
+    int index = utils::find_index(band_values, band);
+    if(index < 0 ) {
+        s = utils::format("set_power(%s) isn't invalid", band.c_str());
+        em_result_notify_fail(s);
+        LOG_D(LOG_TAG, "set_power(%s) isn't invalid", band.c_str());
+        return false;
+    }
+    if(!check_power(index, str)) return false;
+    power = str;
+    if(modem_type == utils::MODEM_TDSCDMA){
+        tdscdam_values[INDEX_POWER] = str;
+    } else if(modem_type == utils::MODEM_WCDMA) {
+        wcdma_values[INDEX_POWER] = str;
+    }
+    em_result_notify_ok("power: " + power);
+    return true;
+}
+
+void RfDesenseTxTestTd::show_channel() {
+    emResultNotifyWithDone("Channel(UarfCN): " + channel);
+}
+
+void RfDesenseTxTestTd::show_power() {
+    emResultNotifyWithDone("Power Level(dBm): " + power);
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestTd.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestTd.h
new file mode 100644
index 0000000..e00508c
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/em/rfdesense/RfDesenseTxTestTd.h
@@ -0,0 +1,87 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef RFDESENSETXTESTTD_H_
+#define RFDESENSETXTESTTD_H_
+
+#include <string>
+#include <vector>
+#include <map>
+
+#include "util/utils.h"
+#include "rfdesense/RfDesenseTxTestBase.h"
+
+
+class RfDesenseTxTestTd {
+public:
+    std::string get_command();
+    std::string get_band();
+    std::string get_power();
+    bool set_band(int value);
+    bool set_channel(std::string str);
+    bool set_power(std::string str);
+    void show_channel();
+    void show_power();
+    RfDesenseTxTestTd(int modemType);
+    void show_default();
+    virtual ~RfDesenseTxTestTd();
+private:
+    //static std::shared_ptr<RfDesenseTxTestTd> m_instance;
+    int modem_type = utils::MODEM_UNKNOWN;
+    int min = -1;
+    int max = -1;
+    int min2 = -1;
+    int max2 = -1;
+    int step = 1;
+    static const int INDEX_BAND;
+    static const int INDEX_CHANNEL;
+    static const int INDEX_POWER;
+    static std::string band;
+    static std::string channel;
+    static std::string power;
+    std::string command;
+    static std::map<int, std::string> tdscdam_values;
+    static std::map<int, std::string> wcdma_values;
+    static const std::vector<std::string> tdscdma_band_values;
+    static const std::vector<std::vector<std::string>> tdscdma_limits;
+    static const std::vector<std::string> wcdma_band_values;
+    static const std::vector<std::vector<std::string>> wcdma_limits;
+    bool checks(std::vector<std::string> v);
+    bool check_channel(int index, std::string channel);
+    bool check_power(int index, std::string power);
+    std::string modemTypeToString(int type);
+};
+
+#endif /* RFDESENSETXTESTTD_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/lynq_call.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/lynq_call.cpp
new file mode 100644
index 0000000..90175a7
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/lynq_call.cpp
@@ -0,0 +1,976 @@
+#include <dlfcn.h>
+#include <string.h>
+#include <stdint.h>
+#include <signal.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include "lynq_common.h"
+#include "lynq_call.h"
+#include <vendor-ril/telephony/ril.h>
+#include <stateManager/stateManager.h>
+#include <cutils/jstring.h>
+
+//#include "Parcel.h"
+
+//#include <sys/time.h>
+//#include <time.h>
+
+//#include <vendor-ril/mtk-rilproxy/atchannel.h>
+#undef LOG_TAG
+#define LOG_TAG "LYNQ_CALL"
+
+//rita add @2020.7.8 for add call api
+//mobiletek @2020.11.10 add api statemanager
+int timer_count=0;
+enum {EXIT ,CHECK}status_call;
+callInfoLink * callInfoLinkhead =NULL;
+
+int call_Info_Init()
+{
+    callInfoLinkhead=create_callInfoLink();
+    if(callInfoLinkhead==NULL)
+    {
+        RLOGD("init call  info fail,maybe malloc fail!");
+        return -1;
+    }
+    return 0;
+}
+void sigalrm_handler(int sig)
+{
+        timer_count++;
+        printf("timer signal.. %d\n", timer_count);
+}
+void updateCallBackInfo(lynqCallList *message,lynq_call_list *calllsit)
+{
+    message->call_id=calllsit->callid;
+    message->call_state=(lynqCallState)calllsit->callState;
+    message->toa=calllsit->toa;
+    message->addr = calllsit->addr;
+    //memcpy(message->addr, calllsit->addr, strlen(calllsit->addr)+1);
+    return;
+}
+void showCallList(lynq_call_list *calllsit)
+{
+    if (calllsit==NULL)
+    {
+        RLOGD("the call list is null");
+        return;
+    }
+    LYINFLOG("lynq token is %d\n",calllsit->token);
+    LYINFLOG("lynq callid is %d\n",calllsit->callid);
+    LYINFLOG("lynq toa is %d\n",calllsit->toa);
+    LYINFLOG("lynq addr is %s\n",calllsit->addr);
+    LYINFLOG("lynq callstate is %d\n",calllsit->callState);
+    LYINFLOG("lynq lynq_error is %d\n",calllsit->lynq_error);
+    LYINFLOG("lynq isMT is %d\n",calllsit->isMT);
+    LYINFLOG("lynq serflen is %d\n",calllsit->selflen);
+    return;
+}
+void checkCallInfo(lynqCallList *message,const char *UserPhonyNum,int32_t token)
+{
+    int resplen=0;
+    int time_call =100;//10 s.
+    callInfoLink *temp;
+    enum{RUN,EXIT}state;
+    state=RUN;
+    while(time_call--)
+    {
+        millli_sleep_with_restart(100);
+        temp=callInfoLinkhead;
+        if (temp != NULL)
+        {
+            do
+            {
+                LYDBGLOG("[%s][%d][%s]token=%x Error_tok=%d,request is %d\n",__FUNCTION__, __LINE__,__FILE__,
+                temp->token, temp->Error_tok,temp->request);
+                //RLOGD("token=%x Error_tok=%d", p->token, p->Error_tok,p->request);
+                switch (temp->request)
+                {
+                    case RIL_REQUEST_DIAL:
+                    {
+                        if(temp->Error_tok==RIL_E_GENERIC_FAILURE)
+                        {
+                            message->call_state=LYNQ_CALL_DACTIVE;
+                            message->base.e = temp->Error_tok;
+                            return;
+                        }
+                        if((temp->calllist_tok==NULL)||(temp->calllist_tok[0]==NULL))
+                        {
+                            RLOGD("call list is null");
+                            state=EXIT;
+                            break;
+                         }
+                        resplen=temp->calllist_tok[0]->selflen;
+                        //printf("----resplen %d----\n",resplen);
+                        for(int i=0;i<resplen;i++)
+                        {
+                            printf("temp->token %x,input token is %x\n",temp->token,token);
+                            if((temp->token==token)&&(temp->calllist_tok[i]->callState==2))
+                            {
+                                //showCallList(temp->calllist_tok[i]);//for test
+                                if(strcmp(temp->calllist_tok[i]->addr, UserPhonyNum)==0)
+                                {
+                                    updateCallBackInfo(message,temp->calllist_tok[i]);
+                                    state=EXIT;
+                                    return;
+                                }
+                            }
+                            /*
+                            if(temp->calllist_tok[i]->lynq_error==RIL_E_GENERIC_FAILURE)
+                            {
+                                printf("RIL_E_GENERIC_FAILURE\n");
+                                state=EXIT;
+                                break;
+                            }*/
+                         }
+                        break;
+                    }
+                    case RIL_REQUEST_ANSWER:
+                    {
+                        if(temp->Error_tok==RIL_E_GENERIC_FAILURE)
+                        {
+                            printf("RIL_E_GENERIC_FAILURE\n");
+                            message->call_state=LYNQ_CALL_INCOMING;
+                            message->base.e = temp->Error_tok;
+                            return;
+                        }
+                        if((temp->calllist_tok==NULL)||(temp->calllist_tok[0]==NULL))
+                        {
+                            RLOGD("call list is null");
+                            state=EXIT;
+                            break;
+                         }
+                        resplen=temp->calllist_tok[0]->selflen;
+                        //printf("----resplen %d----\n",resplen);
+                        for(int i=0;i<resplen;i++)
+                        {
+                            printf("temp->token %x,input token is %x\n",temp->token,token);
+                            if((temp->token==token)&&(temp->calllist_tok[i]->isMT==1)
+                                &&(temp->calllist_tok[i]->callState==0))
+                            {
+                                showCallList(temp->calllist_tok[i]);//for test
+                                updateCallBackInfo(message,temp->calllist_tok[i]);
+                                state=EXIT;
+                                return;
+                            }
+                         }
+                        time_call=time_call-5;
+                        break;
+                    }
+                    default:
+                        break;
+                    }
+                
+                temp = temp->next;
+            }
+            while ((temp != NULL)&&(state==RUN));
+        }
+        else
+        {
+            RLOGD("call info link head is null");
+            continue;
+        }
+    }
+    printf("time_call is %d \n",time_call);
+    if(time_call<0)
+    {
+        message->call_state=LYNQ_CALL_DACTIVE;
+        message->base.e = -1;
+    }
+    return ;
+}
+static char *strdupReadString(Parcel &p) {
+    size_t stringlen;
+    const char16_t *s16;
+
+    s16 = p.readString16Inplace(&stringlen);
+
+    return strndup16to8(s16, stringlen);
+}
+static lynq_call_list ** parcelToCallList(Parcel &p,int &len)
+{
+    int num = 0;
+    int uusPresent;
+    lynq_call_list **pCallLists = NULL;
+    lynq_call_list *pCallList = NULL;
+    int32_t res;
+    p.setDataPosition(0);
+    if (p.dataAvail() > 0) 
+    {
+        p.readInt32(&num);
+        len=num;
+        pCallLists = (lynq_call_list **) calloc(1, sizeof(lynq_call_list *) * num);
+        memset(pCallLists,0,sizeof(lynq_call_list *) * num);
+        for (int i = 0; i < num; i++) 
+        {
+            pCallList = (lynq_call_list *) calloc(1, sizeof(lynq_call_list));
+            memset(pCallList,0,sizeof(lynq_call_list));
+            pCallLists[i] = pCallList;
+            p.readInt32(&res);
+            pCallLists[i]->callState = (RIL_CallState) res;
+            p.readInt32(&pCallLists[i]->callid);
+            p.readInt32(&pCallLists[i]->toa);
+            p.readInt32(&res);
+            pCallLists[i]->isMpty = (uint8_t) res;
+            p.readInt32(&res);
+            pCallLists[i]->isMT = (uint8_t) res;
+            pCallLists[i]->addr = strdupReadString(p);
+            pCallLists[i]->selflen = num;
+        }
+    }
+    return pCallLists;
+}
+static void updateCallLists(const char *UserPhonyNum,lynqCallList *message,lynqQueue * node,int time)
+{
+    int resplen=0;
+    int time_call =time;
+    lynq_call_list ** call_list=NULL;
+    if(node ==NULL)
+    {
+        LYDBGLOG("update call lists node is null!");
+        return;
+    }
+    while(time_call--)
+    {
+        millli_sleep_with_restart(10);
+        switch (node->request)
+        {
+            case RIL_REQUEST_DIAL:
+            {
+                call_list = parcelToCallList(node->parcel, resplen);
+                if(call_list==NULL)
+                {
+                    LYDBGLOG("call lists is null");
+                    break;
+                 }
+                for(int i=0;i<resplen;i++)
+                {
+                    if(call_list[i]->callState==2)
+                    {
+                        //showCallList(call_list[i]);//for test
+                        if(strcmp(call_list[i]->addr, UserPhonyNum)==0)
+                        {
+                            updateCallBackInfo(message,call_list[i]);
+                            return;
+                        }
+                    }
+                }
+                break;
+            }
+            case RIL_REQUEST_ANSWER:
+            {
+                call_list = parcelToCallList(node->parcel, resplen);
+                if(call_list==NULL)
+                {
+                    LYDBGLOG("incoming call lists is null");
+                    break;
+                 }
+                if(node->t_Errno==RIL_E_GENERIC_FAILURE)
+                {
+                    for(int i=0;i<resplen;i++)
+                    {
+                        if(call_list[i]->isMT==1)
+                        {
+                            message->call_state=(lynqCallState)call_list[i]->callState;
+                            break;
+                        }
+                    }
+                    message->base.e = node->t_Errno;
+                    return;
+                }
+                for(int i=0;i<resplen;i++)
+                {
+                    if((call_list[i]->isMT==1)&&(call_list[i]->callState==RIL_CALL_ACTIVE))
+                    {
+                        //showCallList(call_list[i]);//for test
+                        updateCallBackInfo(message,call_list[i]);
+                        return;
+                    }
+                }
+                break;
+            }
+            case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND:
+            case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE:
+            case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND:
+            {
+                call_list = parcelToCallList(node->parcel, resplen);
+                if(call_list==NULL)
+                {
+                    LYDBGLOG("[%s] call lists is null\n",__FUNCTION__);
+                    break;
+                }
+                for(int i =0;i<resplen;i++)
+                {
+                    if(call_list[i]->callState==RIL_CALL_ACTIVE)
+                    {
+                        //showCallList(call_list[i]);//for test
+                        updateCallBackInfo(message,call_list[i]);
+                        return;
+                    }
+                }
+                break;
+            }
+            case RIL_REQUEST_CONFERENCE:
+            {
+                call_list = parcelToCallList(node->parcel, resplen);
+                if(call_list==NULL)
+                {
+                    LYDBGLOG("call lists is null");
+                    break;
+                }
+                for(int i =0;i<resplen;i++)
+                {
+                    if((call_list[i]->callState==RIL_CALL_ACTIVE)&&(call_list[i]->isMpty !=0))
+                    {
+                        //showCallList(call_list[i]);//for test
+                        updateCallBackInfo(message,call_list[i]);
+                        return;
+                    }
+                }
+                break;
+            }
+            default:
+                break;
+            }
+    }
+    LYDBGLOG("[%S] time_call is %d \n",__FUNCTION__,time_call);
+    if(time_call<0)
+    {
+        message->call_state=LYNQ_CALL_DACTIVE;
+        message->base.e = -1;
+    }
+    return ;
+
+}
+void checkParcelCallInfo(lynqCallList *message,const char *UserPhonyNum,int32_t token,int time)
+{
+    int resplen=0;
+    int time_call =time;
+    lynqQueue *temp=NULL;
+    //enum{RUN,EXIT}state;
+    //state=RUN;
+    message->base.e=-1;
+    printf("checkCallInfo start\n");
+    lynq_call_list ** call_list=NULL;
+    lynqQueue * node = NULL;
+    while(time_call--)
+    {
+        millli_sleep_with_restart(10);
+        temp=LynqQueueHead;
+        if (temp != NULL)
+        {
+            node = searchTokeninQueue(token, temp);
+            if(node ==NULL)
+            {
+                RLOGD("can not find token %x in this queue",token);
+                continue;
+            }
+            message->base.e = node->t_Errno;
+            /*if(node->t_Errno==RIL_E_GENERIC_FAILURE)
+            {
+                RLOGD("RIL_E_GENERIC_FAILURE");
+                return;
+            }
+            */
+            //printf("token=%x Error_tok=%d,request is %d\n", node->token, node->t_Errno,node->request);
+            switch (node->request)
+            {
+                case RIL_REQUEST_DIAL:
+                {
+                    if(node->t_Errno==RIL_E_GENERIC_FAILURE)
+                    {
+                        RLOGD("RIL_E_GENERIC_FAILURE");
+                        message->call_state=LYNQ_CALL_DACTIVE;
+                        message->base.e = node->t_Errno;
+                        return;
+                    }
+                    call_list = parcelToCallList(node->parcel, resplen);
+                    if(call_list==NULL)
+                    {
+                        RLOGD("call lists is null");
+                        break;
+                     }
+                    //printf("----resplen %d----\n",resplen);
+                    for(int i=0;i<resplen;i++)
+                    {
+                        printf("temp->token %x,input token is %x\n",node->token,token);
+                        if((node->token==token)&&(call_list[i]->callState==2))
+                        {
+                            //showCallList(call_list[i]);//for test
+                            if(strcmp(call_list[i]->addr, UserPhonyNum)==0)
+                            {
+                                updateCallBackInfo(message,call_list[i]);
+                                return;
+                            }
+                        }
+                     }
+                    break;
+                }
+                case RIL_REQUEST_ANSWER:
+                {
+                    call_list = parcelToCallList(node->parcel, resplen);
+                    if(call_list==NULL)
+                    {
+                        RLOGD("incoming call lists is null");
+                        break;
+                     }
+                    if(node->t_Errno==RIL_E_GENERIC_FAILURE)
+                    {
+                        RLOGD("RIL_E_GENERIC_FAILURE");
+                        for(int i=0;i<resplen;i++)
+                        {
+                            if(call_list[i]->isMT==1)
+                            {
+                                message->call_state=(lynqCallState)call_list[i]->callState;
+                                break;
+                            }
+                        }
+                        message->base.e = node->t_Errno;
+                        return;
+                    }
+                    //printf("----resplen %d----\n",resplen);
+                    for(int i=0;i<resplen;i++)
+                    {
+                        printf("temp->token %x,input token is %x\n",node->token,token);
+                        if((call_list[i]->isMT==1)&&(call_list[i]->callState==0))
+                        {
+                            showCallList(call_list[i]);//for test
+                            updateCallBackInfo(message,call_list[i]);
+                            return;
+                        }
+                     }
+                    break;
+                }
+                case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND:
+                {
+                    call_list = parcelToCallList(node->parcel, resplen);
+                    if(call_list==NULL)
+                    {
+                        RLOGD("call lists is null");
+                        break;
+                    }
+                    if(node->t_Errno==RIL_E_GENERIC_FAILURE)
+                    {
+                        RLOGD("RIL_E_GENERIC_FAILURE");
+                        message->base.e = node->t_Errno;
+                        return;
+                    }
+                    //printf("----resplen %d----\n",resplen);
+                    if(resplen == 1)
+                    {
+                        showCallList(call_list[0]);//for test
+                        message->call_id=call_list[0]->callid;
+                        message->call_state=(lynqCallState)call_list[0]->callState;
+                        message->toa=call_list[0]->toa;
+                        message->addr = call_list[0]->addr;
+                        //updateCallBackInfo(message,call_list[0]);
+                        message->base.e = node->t_Errno;
+                        //printf("message->call_state is %d\n",message->call_state);
+                        //printf("test pass\n");
+                        return;
+                    }
+                    break;
+                }
+                default:
+                    break;
+                }
+
+        }
+        else
+        {
+            RLOGD("call info link head is null");
+            continue;
+        }
+    }
+    printf("time_call is %d \n",time_call);
+    if(time_call<0)
+    {
+        message->call_state=LYNQ_CALL_DACTIVE;
+        message->base.e = -1;
+    }
+    return ;
+}
+
+
+int lynq_call_old(RIL_Dial *pRilDail)//function:dial;address:callnumber,clir:0 is default value,uusInfo:NULL or Pointer to User-User Signaling Information
+{
+    int lenth;
+    char *argv[MAX_LEN] = {};
+    char indexStr[MAX_QUEST_LEN] = "";
+    char uusType[MAX_QUEST_LEN] = "";
+    char uusDcs[MAX_QUEST_LEN] = "";
+    char uusLength[MAX_QUEST_LEN] = "";
+    
+    sprintf(indexStr, "%d", pRilDail->clir);
+
+    argv[0] = "RIL_REQUEST_DIAL";
+    argv[1] = pRilDail->address;
+    argv[2] = indexStr;
+    
+    if(pRilDail->uusInfo)
+    {
+        //printf("=========>[%s,%d],uusInfo exist!!!\n",__FUNCTION__,__LINE__);
+        sprintf(uusType,"%d",pRilDail->uusInfo->uusType);
+        sprintf(uusDcs,"%d",pRilDail->uusInfo->uusDcs);
+        sprintf(uusLength,"%d",pRilDail->uusInfo->uusLength);
+    
+        argv[3] = uusType;
+        argv[4] = uusDcs;
+        argv[5] = uusLength;
+        argv[6] = pRilDail->uusInfo->uusData;
+        lenth = 7;
+    }
+    else
+    {
+        //printf("=========>[%s,%d],uusInfo is NULL!!!\n",__FUNCTION__,__LINE__);
+        lenth = 3;
+    }
+    
+    return android::getRequestData(argv, lenth);
+}
+int lynq_call(const char *addr,lynqCallList* msg)//function:dial;address:callnumber,clir:0 is default value,uusInfo:NULL or Pointer to User-User Signaling Information
+{
+    int32_t token=0;
+    int resplen=0;
+    RIL_Errno err=-1;
+    lynqQueue *node = NULL;
+    const char *argv[MAX_LEN]={};
+    char indexStr[MAX_QUEST_LEN] = "";
+    argv[0] = "RIL_REQUEST_DIAL";
+    if(addr==NULL)
+    {
+        RLOGD("addr is null!");
+        LYDBGLOG("addr is null!\n");
+        msg->call_state=LYNQ_CALL_DACTIVE;
+        msg->base.e = -1;
+        return 0;
+    }
+    argv[1] = addr;
+    argv[2]= "0";
+    if(token = android::getRequestData(argv, 3))
+    {
+        msg->base.token=token;
+        msg->base.request=RIL_REQUEST_DIAL;
+        node = commonUpdateEstatus(token,500, err);//wait 5s
+        msg->base.e = err;
+        if(err !=RIL_E_SUCCESS)
+        {
+            LYDBGLOG("lynq_call error code is %d!",err);
+            msg->call_state=LYNQ_CALL_DACTIVE;
+            lynqDeQueue(token);
+            return token;
+        }
+        updateCallLists(addr,msg,node,9000);//wait 90s
+        //setCallStatus(LYNQ_CALL_ON);
+        lynqDeQueue(token);
+    }
+    return token;
+}
+int lynq_call_answer(lynqCallList* msg)//function:answer a call
+{
+    int lenth;
+    int32_t token=0;
+    int resplen=0;
+    RIL_Errno err=-1;
+    lynqQueue *node = NULL;
+    char requestStr[MAX_LEN] = {"RIL_REQUEST_ANSWER"};
+    if(LYNQ_CALL_OFF==getCallStatus())
+    {
+        msg->base.request = RIL_REQUEST_HANGUP;
+        msg->base.token=token;
+        msg->base.e=LYNQ_E_CONFLICT;//logic conflict,if must
+        return token;
+    }
+    if(token=lynqNoneParame(requestStr))
+    {
+        msg->base.token=token;
+        msg->base.request=RIL_REQUEST_ANSWER;
+        node = commonUpdateEstatus(token,500, err);
+        msg->base.e = err;
+        if(err !=RIL_E_SUCCESS)
+        {
+            LYDBGLOG("lynq_call_answer error code is %d!",err);
+            msg->call_state=LYNQ_CALL_DACTIVE;
+            lynqDeQueue(token);
+            return token;
+        }
+        updateCallLists(NULL,msg,node,200);
+        lynqDeQueue(token);
+    }
+    return token;
+}
+
+int lynq_call_hang_up(const int callId,lynqBase *base)//function:hang up a call
+{
+    char *argv[MAX_LEN] = {};
+    char indexStr[MAX_QUEST_LEN] = "";
+    int32_t token=0;
+    int status = 0;
+    RIL_Errno err=-1;
+    lynqQueue * node = NULL;
+    sprintf(indexStr, "%d", callId);
+    argv[0] = "RIL_REQUEST_HANGUP";
+    argv[1] = indexStr;
+    if(LYNQ_CALL_OFF==getCallStatus())
+    {
+        base->request = RIL_REQUEST_HANGUP;
+        base->token=token;
+        base->e=LYNQ_E_CONFLICT;//logic conflict,if must
+        return token;
+    }
+    if(token = android::getRequestData(argv, 2))
+    {
+        base->request = RIL_REQUEST_HANGUP;
+        base->token=token;
+        node = commonUpdateEstatus(token,500,err);
+        base->e=err;
+        lynqDeQueue(token);
+    }
+    return token;
+}
+
+int lynq_reject_call(lynqBase *base)//function:hang up all call or reject call
+{
+    char requestStr[MAX_LEN] = {"RIL_REQUEST_UDUB"};
+    int32_t token=0;
+    int status = 0;
+    RIL_Errno err=-1;
+    lynqQueue * node = NULL;
+    if(LYNQ_CALL_OFF==getCallStatus())
+    {
+        base->request = RIL_REQUEST_UDUB;
+        base->token=token;
+        base->e=LYNQ_E_CONFLICT;//logic conflict,if must
+        return token;
+    }
+    if(token =lynqNoneParame(requestStr))
+    {
+        base->request = RIL_REQUEST_UDUB;
+        base->token=token;
+        node = commonUpdateEstatus(token,500,err);
+        base->e=err;
+        lynqDeQueue(token);
+    }
+    return token;
+}
+
+int lynq_set_auto_answercall(int mode,int *status)// 1:enable,0:disable
+{
+    char *argv[MAX_LEN] = {};
+    char modeStr[MAX_QUEST_LEN] = "";
+    int32_t token=0;
+    sprintf(modeStr, "%d", mode);
+    argv[0] = "RIL_REQUEST_AUTO_ANSWER";
+    argv[1] = modeStr;
+    token = android::getRequestData(argv, 2);
+    *status = autoAnswerMode;
+    return token;
+}
+
+int lynq_get_mute_status(int *status) 
+{
+    char *argv[MAX_LEN] = {};
+    int32_t token;
+    char enableStr[MAX_QUEST_LEN] = "";
+    ///sprintf(enableStr, "%d", enable);
+    argv[0] = "RIL_REQUEST_GET_MUTE";
+    //argv[1] = enableStr;
+    *status = android::specialRequestController(argv, 1,&token);
+    return token;
+
+}
+int lynq_get_mute_mic(int *status) // 1:enable  0:disable
+{
+    char *argv[MAX_LEN] = {};
+    int32_t token;
+    char enableStr[MAX_QUEST_LEN] = "";
+    argv[0] = "RIL_REQUEST_GET_MUTE";
+    *status = android::specialRequestController(argv, 1,&token);
+    return 0;
+}
+int lynq_set_mute_mic(const int enable,int *status) // 1:enable  0:disable
+{
+    char *argv[MAX_LEN] = {};
+    int32_t token;
+    char enableStr[MAX_QUEST_LEN] = "";
+    sprintf(enableStr, "%d", enable);
+    argv[0] = "RIL_REQUEST_SET_MUTE";
+    argv[1] = enableStr;
+    int ret = android::specialRequestController(argv, 2,&token);
+    if(ret)
+    {
+        LYDBGLOG("set mute failed !!");
+        *status = -1;
+        return token;
+    }
+    lynq_get_mute_mic(status);
+    *status = (enable>0)?1:0;
+    return token;
+}
+
+int lynq_set_DTMF(const char callnum,lynqBase *base)//callnum:  0-9,*,#
+{
+    char *argv[MAX_LEN] = {};
+    char callnumStr[MAX_QUEST_LEN] = "";
+    int32_t token=0;
+    //int status = 0;
+    RIL_Errno err=-1;
+    lynqQueue * node = NULL;
+    if(LYNQ_CALL_OFF==getCallStatus())
+    {
+        base->request = RIL_REQUEST_DTMF;
+        base->token=token;
+        base->e=LYNQ_E_CONFLICT;//logic conflict,if must
+        return token;
+    }
+    if (INDEX_IS_NUMBER(callnum) || (callnum == '#') || (callnum == '*'))
+    {
+        sprintf(callnumStr, "%c", callnum);
+        argv[0] = "RIL_REQUEST_DTMF";
+        argv[1] = callnumStr;
+        if(token =android::getRequestData(argv, 2))
+        {
+            base->request = RIL_REQUEST_DTMF;
+            base->token=token;
+            node = commonUpdateEstatus(token,500,err);
+            base->e=err;
+            lynqDeQueue(token);
+        }
+        return token;
+    }
+    else
+    {
+        base->e=err;
+        LYERRLOG("[%s][%d][%s] invalid parameter!!! \n",__FUNCTION__,__LINE__,__FILE__);
+        return -1;
+    }
+}
+int lynq_set_DTMF_volume(const int         volume)//volume : 0 to 36
+{
+    char *argv[MAX_LEN] = {};
+    char volumeStr[MAX_QUEST_LEN] = "";
+
+    if((volume<=36) && (volume>=0))
+    {
+        argv[0] = "RIL_REQUEST_SET_DTMF_VOLUME";
+        sprintf(volumeStr, "%d", volume);
+        argv[1] = volumeStr;
+
+        return  android::getRequestData(argv, 2);
+    }
+    else{
+        LYERRLOG("[%s][%d][%s] invalid parameter!!! \n",__FUNCTION__,__LINE__,__FILE__);
+        return -1;
+    }
+}
+
+int lynq_do_multi_conference(lynqCallList *msg)
+{
+    int32_t token=0;
+    int resplen=0;
+    RIL_Errno err=-1;
+    lynqQueue * node = NULL;
+    char requestStr[MAX_LEN] = {"RIL_REQUEST_CONFERENCE"};
+    if(LYNQ_CALL_OFF==getCallStatus())
+    {
+        msg->base.request = RIL_REQUEST_CONFERENCE;
+        msg->base.token=token;
+        msg->base.e=LYNQ_E_CONFLICT;//logic conflict,if must
+        return token;
+    }
+    if(token =lynqNoneParame(requestStr))
+    {
+        msg->base.request=RIL_REQUEST_CONFERENCE;
+        msg->base.token=token;
+        node = commonUpdateEstatus(token,500,err);
+        msg->base.e = err;
+        if(err !=RIL_E_SUCCESS)
+        {
+            LYDBGLOG("[%s] error code is %d!",__FUNCTION__,err);
+            lynqDeQueue(token);
+            return token;
+        }
+        updateCallLists(NULL,msg,node,200);
+        lynqDeQueue(token);
+    }
+    return token;
+}
+
+int lynq_othercall_hold(const int callindex,lynqBase *base)//other select call turn hold
+{
+    int32_t token=0;
+    int resplen=0;
+    RIL_Errno err=-1;
+    lynqQueue * node = NULL;
+    char *argv[MAX_LEN] = {};
+    char callindexStr[MAX_QUEST_LEN] = "";
+    sprintf(callindexStr, "%d", callindex);
+    argv[0] = "RIL_REQUEST_SEPARATE_CONNECTION";
+    argv[1] = callindexStr;
+    if(LYNQ_CALL_OFF==getCallStatus())
+    {
+        base->request = RIL_REQUEST_SEPARATE_CONNECTION;
+        base->token=token;
+        base->e=LYNQ_E_CONFLICT;//logic conflict,if must
+        return token;
+    }
+    if(token = android::getRequestData(argv, 2))
+    {
+        base->request=RIL_REQUEST_SEPARATE_CONNECTION;
+        base->token=token;
+        node = commonUpdateEstatus(token,500,err);
+        base->e = err;
+        lynqDeQueue(token);
+    }
+    return token;
+}
+
+int lynq_hangup_wating_for_call(lynqCallList *msg)
+{
+    int lenth;
+    int32_t token=0;
+    int resplen=0;
+    RIL_Errno err=-1;
+    lynqQueue * node = NULL;
+    //status_call = CHECK;
+    char requestStr[MAX_LEN] = {"RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND"};
+    if(LYNQ_CALL_OFF==getCallStatus())
+    {
+        msg->base.request = RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND;
+        msg->base.token=token;
+        msg->base.e=LYNQ_E_CONFLICT;//logic conflict,if must
+        return token;
+    }
+    //token=lynqNoneParame(requestStr);
+    //msg->base.token=token;
+    //msg->base.request=RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND;
+    if(token =lynqNoneParame(requestStr))
+    {
+        msg->base.request=RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND;
+        msg->base.token=token;
+        node = commonUpdateEstatus(token,500,err);
+        msg->base.e = err;
+        if(err !=RIL_E_SUCCESS)
+        {
+            LYDBGLOG("[%s] error code is %d!",__FUNCTION__,err);
+            lynqDeQueue(token);
+            return token;
+        }
+        updateCallLists(NULL,msg,node,200);
+        lynqDeQueue(token);
+    }
+    return token;
+}
+
+int lynq_hangup_foreground_resume_background(lynqCallList *msg)
+{
+    int32_t token=0;
+    int resplen=0;
+    RIL_Errno err=-1;
+    lynqQueue * node = NULL;
+    char requestStr[MAX_LEN] = {"RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND"};
+    if(LYNQ_CALL_OFF==getCallStatus())
+    {
+        msg->base.request = RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND;
+        msg->base.token=token;
+        msg->base.e=LYNQ_E_CONFLICT;//logic conflict,if must
+        return token;
+    }
+    if(token =lynqNoneParame(requestStr))
+    {
+        msg->base.request=RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND;
+        msg->base.token=token;
+        node = commonUpdateEstatus(token,500,err);
+        msg->base.e = err;
+        if(err !=RIL_E_SUCCESS)
+        {
+            LYDBGLOG("[%s] error code is %d!",__FUNCTION__,err);
+            lynqDeQueue(token);
+            return token;
+        }
+        updateCallLists(NULL,msg,node,200);
+        lynqDeQueue(token);
+    }
+    return token;
+}
+
+int lynq_switch_hold_and_active_call(lynqCallList *msg)
+{
+    int32_t token=0;
+    int resplen=0;
+    RIL_Errno err=-1;
+    lynqQueue * node = NULL;
+    char requestStr[MAX_LEN] = {"RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE"};
+    if(LYNQ_CALL_OFF==getCallStatus())
+    {
+        msg->base.request = RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE;
+        msg->base.token=token;
+        msg->base.e=LYNQ_E_CONFLICT;//logic conflict,if must
+        return token;
+    }
+    if(token =lynqNoneParame(requestStr))
+    {
+        msg->base.request=RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE;
+        msg->base.token=token;
+        node = commonUpdateEstatus(token,500,err);
+        msg->base.e = err;
+        if(err !=RIL_E_SUCCESS)
+        {
+            LYDBGLOG("[%s] error code is %d!",__FUNCTION__,err);
+            lynqDeQueue(token);
+            return token;
+        }
+        updateCallLists(NULL,msg,node,200);
+        lynqDeQueue(token);
+    }
+    return token;
+} 
+//AT< +CEER.
+int lynq_get_last_call_fail_cause(lynqLastCallFailCause *msg)
+{
+    int32_t token;
+    int time=500;
+    RIL_Errno err = -1;
+    int num=0;
+    int res=0;
+    lynqQueue * node = NULL;
+    lynqQueue * temp = NULL;
+    char requestStr[MAX_LEN] = {"RIL_REQUEST_LAST_CALL_FAIL_CAUSE"};
+    if(token = lynqNoneParame(requestStr))
+    {
+        msg->base.token = token;
+        msg->base.request = RIL_REQUEST_LAST_CALL_FAIL_CAUSE;
+        node = commonUpdateEstatus(token,time,err);
+        msg->base.e=err;
+        if(err !=RIL_E_SUCCESS)
+        {
+            LYDBGLOG("[%s] error code is %d!",__FUNCTION__,err);
+            lynqDeQueue(token);
+            return token;
+        }
+        if(node)
+        {
+            node->parcel.setDataPosition(0);
+            if (node->parcel.dataAvail() > 0)
+            {
+                node->parcel.readInt32(&num);
+                node->parcel.readInt32(&res);
+                msg->cause_code = (RIL_LastCallFailCause)res;
+                char * vendor_cause = strdupReadString(node->parcel);
+                memcpy(msg->vendor_cause,vendor_cause,strlen(vendor_cause)+1);
+                msg->base.e = node->t_Errno;
+                lynqDeQueue(token);
+                return token;
+            }
+        }
+    }
+    msg->cause_code = -1;
+    msg->base.e=-1;
+    lynqDeQueue(token);
+}
+/*
+void lynq_incoming_call_cb(RIL_SOCKET_ID soc_id,int index, char * addr, RIL_CallState state, int toa)
+{
+    printf("[SIM%d]index is %d,addr is %s,state is %d,toa is %d\n",soc_id,index,addr,state,toa);
+}
+*/
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/lynq_common.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/lynq_common.cpp
new file mode 100644
index 0000000..b782780
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/lynq_common.cpp
@@ -0,0 +1,264 @@
+#include "lynq_common.h"
+#include <liblog/lynq_deflog.h>
+#include <sys/time.h>
+#include "Phone_utils.h"
+#undef LOG_TAG
+#define LOG_TAG "LYNQ_COMMON"
+void set_timer(int it_interval_sec, int it_interval_usec,int it_value_sec,int it_value_usec)
+{
+    struct itimerval itv, oldtv;
+    itv.it_interval.tv_sec = it_interval_sec;
+    itv.it_interval.tv_usec = it_interval_usec;
+    itv.it_value.tv_sec = it_value_sec;
+    itv.it_value.tv_usec = it_value_usec;
+    setitimer(ITIMER_REAL, &itv, &oldtv);
+}
+ 
+int sleep_with_restart(int second) {
+    int left = second;
+    while (left > 0) 
+    { 
+       left = sleep(left);
+    }
+    return 0;
+}
+int millli_sleep_with_restart(int millisecond)
+{
+    int left = millisecond*1000;
+    while (left > 0) 
+    { 
+        left = usleep(left);
+    }
+
+    return 0;
+}
+ int lynqNoneParame(const char *requestStr){
+    char *argv[MAX_LEN];
+    int32_t token;
+    char *mRequestStr=new char[MAX_LEN];
+    strcpy(mRequestStr, requestStr);
+    argv[0] = mRequestStr;
+    token=android::getRequestData(argv, 1);
+    delete mRequestStr;
+    return token;
+}
+
+int lynqIntParame(const char *requestStr,int parame){
+    char *argv[MAX_LEN];
+    char indexStr[MAX_QUEST_LEN] = {0};
+    char *mRequestStr=new char[MAX_LEN];
+    strcpy(mRequestStr, requestStr);
+    sprintf(indexStr, "%d", parame);
+    LYINFLOG("lynqIntParame,indexStr:%s,parame:%d\n", indexStr,parame);
+    argv[0] = mRequestStr;
+    argv[1] = indexStr;
+    return  android::getRequestData(argv, 2);
+}
+
+int lynqStringParame(const char *requestStr,const char *parameString){
+    char *mRequestStr=new char[MAX_LEN];
+    char *mParameString=new char[MAX_LEN];
+    char *argv[MAX_LEN];
+    strcpy(mRequestStr, requestStr);
+    strcpy(mParameString, parameString);
+    argv[0] = mRequestStr;
+    argv[1] = mParameString;
+    return  android::getRequestData(argv, 2);
+
+}
+int triggerRequest(int request)
+{
+    int32_t token;
+    switch (request)
+    {
+        case RIL_REQUEST_GET_SIM_STATUS:
+        {
+            token = lynqNoneParame("RIL_REQUEST_GET_SIM_STATUS");
+            break;
+        }
+    }
+    return 0;
+}
+int advanceCheckError(RIL_Errno err)
+{
+    RIL_Errno tempe = 0;
+    RIL_CardState cardState =0;
+    Service_State serviceState= 0;
+    RIL_SOCKET_ID soc_id = (RIL_SOCKET_ID)Phone_utils::get_enable_sim_for_dsss();
+    switch(err)
+    {
+        case RIL_E_GENERIC_FAILURE:
+        {
+            cardState = getSimState(soc_id);
+            switch(cardState)
+            {
+                case 0:
+                {
+                    tempe = RIL_E_SIM_ABSENT;
+                    return tempe;
+                    //break;
+                }
+                case 2:
+                {
+                    tempe = LYNQ_E_CARDSTATE_ERROR;
+                    return tempe;
+                    //break;
+                }
+                default:
+                    break;
+            }
+            serviceState = get_reg_voice_service_state(RIL_REQUEST_VOICE_REGISTRATION_STATE, soc_id);
+            switch(serviceState)
+            {
+                case 1:
+                {
+                    tempe = LYNQ_E_STATE_OUT_OF_SERVICE;
+                    return tempe;
+                    //break;
+                }
+                case 2:
+                {
+                    tempe = LYNQ_E_STATE_EMERGENCY_ONLY;
+                    return tempe;
+                    //break;
+                }
+                case 3:
+                {
+                    tempe = LYNQ_E_STATE_POWER_OFF;
+                    return tempe;
+                    //break;
+                }
+                default:
+                    break;
+            }
+            tempe = err;
+            break;
+        }
+        default:
+            tempe = err;
+            break;
+    }
+    LYDBGLOG("[advanceCheckError] temp error is %d\n",tempe);
+    return tempe;
+}
+int strUpper(char * str)
+{
+    int i=0;
+    while(1)
+    {
+        if(str[i]=='\0')
+        {
+            break;
+        }
+        if(str[i]>='a'&&str[i]<='z')
+        {
+             //printf("str %c\n",str[i]-32);
+             str[i]=str[i]-32;
+        }
+        i++;
+    }
+    return 0;
+}
+lynqQueue *commonFindParcelmsg(const int32_t token,const int time,RIL_Errno&e)
+{
+    int timeCount = time;
+    int num=0;
+    lynqQueue *node = NULL;
+    lynqQueue *temp =NULL;
+    while(timeCount--)
+    {
+         millli_sleep_with_restart(10);
+         temp=LynqQueueHead;
+         if(temp==NULL)
+         {
+             LYDBGLOG("Queue head is NULL, maybe malloc fail!\n");
+             continue;
+         }
+         node = searchTokeninQueue(token, temp);
+         if(node ==NULL)
+         {
+             LYDBGLOG("can not find token %x\n",token);
+             e=-1;
+             return NULL;
+         }
+         if(node->t_Errno!=RIL_E_SUCCESS)
+         {
+             LYDBGLOG("get fail, the error code is %d\n",node->t_Errno);
+             e = advanceCheckError(node->t_Errno);
+             //e=node->t_Errno;
+             return NULL;
+         }
+         else
+         {
+            node->parcel.setDataPosition(0);
+            if (node->parcel.dataAvail() > 0) 
+            {
+                e=node->t_Errno;
+                //pNode=node;
+                return node;
+             }
+             else
+             {
+               continue;
+             }
+         }
+    }
+    //printf("timeCount is %d\n",timeCount);
+    if(timeCount<0)
+    {
+        LYDBGLOG("time out,can not find message!\n");
+        e=LYNQ_E_TIME_OUT;
+    }
+    return NULL;
+
+}
+lynqQueue *commonUpdateEstatus(const int32_t token,const int time,RIL_Errno&e)
+{
+    int timeCount = time;
+    int num=0;
+    lynqQueue *node = NULL;
+    lynqQueue *temp =NULL;
+    while(timeCount--)
+    {
+         millli_sleep_with_restart(10);
+         temp=LynqQueueHead;
+         if(temp==NULL)
+         {
+             LYDBGLOG("Queue head is NULL, maybe malloc fail!\n");
+             continue;
+         }
+         node = searchTokeninQueue(token, temp);
+         if(node ==NULL)
+         {
+             RLOGD("can not find token %x\n",token);
+             e=-1;
+             return NULL;
+         }
+         if(node->t_Errno!=RIL_E_SUCCESS)
+         {
+             LYDBGLOG("get fail, the error code is %d\n",node->t_Errno);
+             e = advanceCheckError(node->t_Errno);
+             //e=node->t_Errno;
+             return node;
+         }
+         else
+         {
+            if (node->E_status==1) 
+            {
+                e=node->t_Errno;
+                return node;
+            }
+            else
+            {
+               continue;
+            }
+         }
+    }
+    //printf("timeCount is %d\n",timeCount);
+    if(timeCount<0)
+    {
+        LYDBGLOG("time out,can not find message!\n");
+        e=LYNQ_E_TIME_OUT;
+    }
+    return NULL;
+}
\ No newline at end of file
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/lynq_common.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/lynq_common.h
new file mode 100644
index 0000000..070c536
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/lynq_common.h
@@ -0,0 +1,59 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <log/log.h>
+#include <stdint.h>
+#include <unistd.h>
+#include "common.h"
+#include <stateManager/stateManager.h>
+#include <liblog/lynq_deflog.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+int lynqNoneParame(const char *requestStr);
+int lynqIntParame(const char *requestStr,int parame);
+int lynqStringParame(const char *requestStr,const char*serviceNumber);
+void set_timer(int it_interval_sec, int it_interval_usec,int it_value_sec,int it_value_usec);
+int millli_sleep_with_restart(int millisecond);
+int sleep_with_restart(int second);
+int strUpper(char * str);
+lynqQueue *commonFindParcelmsg(const int32_t token,const int time,RIL_Errno&e);
+lynqQueue *commonUpdateEstatus(const int32_t token,const int time,RIL_Errno&e);
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/lynq_data.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/lynq_data.cpp
new file mode 100644
index 0000000..66043ec
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/lynq_data.cpp
@@ -0,0 +1,254 @@
+#include "common.h"
+#include "lynq_common.h"
+#include "lynq_data.h"
+#include "lynq_network.h"
+#include "stateManager/stateManager.h"
+#include <string.h>
+#include <stdlib.h>
+#undef LOG_TAG
+#define LOG_TAG "LYNQ_DATA"
+#define DATA_CALL_LIST_MAX 10
+//ww add @2020.7.23 for add Data api
+
+void copyDataCallList(LYNQ_Data_Call_Response_v11 *newMsg,const RIL_Data_Call_Response_v11 oldMsg);
+
+RIL_Data_Call_Response_v11 *
+checkParcelDataCallInfo(dataCallMsg* msg,int32_t token,int time)
+{
+    int time_sim =time;
+    int num;
+    lynqQueue *node = NULL;
+    lynqQueue *temp =NULL;
+    RIL_Data_Call_Response_v11 *list = NULL;
+    while(time_sim--)
+    {
+         millli_sleep_with_restart(10);
+         temp=LynqQueueHead;
+         if(temp==NULL)
+         {
+             LYDBGLOG("Queue head is NULL, maybe malloc fail!");
+             continue;
+         }
+         node = searchTokeninQueue(token, temp);
+         if(node ==NULL)
+         {
+            return NULL;
+         }
+         if(node->t_Errno!=RIL_E_SUCCESS)
+         {
+             LYDBGLOG("get data call list fail, the error code is %d",node->t_Errno);
+             msg->e=node->t_Errno;
+             return NULL;
+         }
+         else
+         {
+            node->parcel.setDataPosition(0);
+            if (node->parcel.dataAvail() > 0) 
+            {
+
+                node->parcel.readInt32(&num);
+                list = (RIL_Data_Call_Response_v11 *) calloc(1, sizeof(RIL_Data_Call_Response_v11) * num);
+                for(int i =0;i<num;i++)
+                {
+                    node->parcel.readInt32(&list[i].status);
+                    node->parcel.readInt32(&list[i].suggestedRetryTime);
+                    node->parcel.readInt32(&list[i].cid);
+                    node->parcel.readInt32(&list[i].active);
+                    list[i].type = lynqStrdupReadString(node->parcel);
+                    list[i].ifname = lynqStrdupReadString(node->parcel);
+                    list[i].addresses = lynqStrdupReadString(node->parcel);
+                    list[i].dnses = lynqStrdupReadString(node->parcel);
+                    list[i].gateways = lynqStrdupReadString(node->parcel);
+                    list[i].pcscf = lynqStrdupReadString(node->parcel);
+                    node->parcel.readInt32(&list[i].mtu);
+
+                }
+                msg->e=node->t_Errno;
+                msg->status = 0;
+                msg->num = num;
+                return list;
+             }
+             else
+             {
+               continue;
+             }
+         }
+    }
+    //printf("time_sim is %d\n",time_sim);
+    return NULL;
+}
+//enable_data.sh 
+int lynq_data_enable_data(int* PdnState) 
+{
+    char* mdata_apn[MAX_STRING_LEN];
+    int param_num=8;
+    int res=-1;
+    int32_t token=0;
+    int32_t tokenTemp=0;
+    RIL_Data_Call_Response_v11 *list = NULL;
+    dataCallMsg msg;
+    msg.e=-1;
+    msg.num=-1;
+    msg.status=-1;
+    //lynq_query_network_selection_mode();
+    token = lynqNoneParame("RIL_REQUEST_SETUP_DATA_CALL");
+    millli_sleep_with_restart(150);
+    tokenTemp = lynqNoneParame("RIL_REQUEST_DATA_CALL_LIST");
+    list = checkParcelDataCallInfo(&msg,tokenTemp,100);
+    if(list==NULL)
+    {
+        *PdnState = -1;
+    }
+    else
+    {
+        *PdnState = 0;
+        for (int i = 0; i < msg.num; i++) 
+        {
+            free(list[i].type);
+            free(list[i].ifname);
+            free(list[i].addresses);
+            free(list[i].dnses);
+            free(list[i].gateways);
+            free(list[i].pcscf);
+        }
+        free(list);
+    }
+    lynqDeQueue(tokenTemp);
+    return token;
+}
+
+//disable_data.sh
+int lynq_data_dectivate_data_call(int *PdnState)
+{
+    //printf("ww--lynq_data_dectivate_data_call--111\r\n");
+    int32_t token=0;
+    int32_t tokenTemp=0;
+    RIL_Data_Call_Response_v11 *list = NULL;
+    dataCallMsg msg;
+    token = lynqNoneParame("RIL_REQUEST_DEACTIVATE_DATA_CALL");
+    //millli_sleep_with_restart(100);
+    tokenTemp = lynqNoneParame("RIL_REQUEST_DATA_CALL_LIST");
+    list = checkParcelDataCallInfo(&msg,tokenTemp,100);
+    if(list==NULL)
+    {
+        *PdnState = 0;
+    }
+    else
+    {
+        *PdnState = -1;
+        for (int i = 0; i < msg.num; i++) 
+        {
+            free(list[i].type);
+            free(list[i].ifname);
+            free(list[i].addresses);
+            free(list[i].dnses);
+            free(list[i].gateways);
+            free(list[i].pcscf);
+        }
+        free(list);
+    }
+    lynqDeQueue(tokenTemp);
+    return token;
+}
+//the max of data call list number is 10;
+int lynq_get_data_call_list(LYNQ_Data_Call_Response_v11 **dataCallList,const int listNum,int *realNum)
+{
+    if(listNum>DATA_CALL_LIST_MAX)
+    {
+        LYDBGLOG("the list number is more than 10");
+        return -1;
+    }
+    int32_t token=0;
+    RIL_Data_Call_Response_v11 *list = NULL;
+    dataCallMsg msg;
+    token = lynqNoneParame("RIL_REQUEST_DATA_CALL_LIST");
+    list = checkParcelDataCallInfo(&msg,token,100);
+    if(list==NULL)
+    {
+        //dataCallList=NULL;
+        return token;
+    }
+    if(listNum<msg.num)
+    {
+        msg.num=listNum;
+        LYDBGLOG("listNum<msg.num!");
+    }
+    *realNum=msg.num;
+    //dataCallList = (RIL_Data_Call_Response_v11 *) calloc(1, sizeof(RIL_Data_Call_Response_v11) * msg.num);
+    for(int i=0;i<msg.num;i++)
+    {
+        copyDataCallList(dataCallList[i], list[i]);
+    }
+    for (int i = 0; i < msg.num; i++) 
+    {
+        free(list[i].type);
+        free(list[i].ifname);
+        free(list[i].addresses);
+        free(list[i].dnses);
+        free(list[i].gateways);
+        free(list[i].pcscf);
+    }
+    free(list);
+    lynqDeQueue(token);
+    /*
+    for(int i=0;i<msg.num;i++)
+    {
+        printf("test status is %d\n",dataCallList[i]->status);
+        printf("test suggested is %d\n",dataCallList[i]->suggestedRetryTime);
+        printf("test cid is %d\n",dataCallList[i]->cid);
+        printf("test active is %d\n",dataCallList[i]->active);
+        printf("test mtu is %d\n",dataCallList[i]->mtu);
+        printf("test string is %s\n",dataCallList[i]->type);
+        printf("test string is %s\n",dataCallList[i]->ifname);
+        printf("test string is %s\n",dataCallList[i]->addresses);
+        printf("test string is %s\n",dataCallList[i]->dnses);
+        printf("test string is %s\n",dataCallList[i]->gateways);
+        printf("test string is %s\n",dataCallList[i]->pcscf);
+    }
+    */
+    /*
+    for(int i=0;i<msg.num;i++)
+    {
+        printf("test status is %d\n",dataCallList[i].status);
+        printf("test suggested is %d\n",dataCallList[i].suggestedRetryTime);
+        printf("test cid is %d\n",dataCallList[i].cid);
+        printf("test active is %d\n",dataCallList[i].active);
+        printf("test mtu is %d\n",dataCallList[i].mtu);
+        printf("test string is %s\n",dataCallList[i].type);
+        printf("test string is %s\n",dataCallList[i].ifname);
+        printf("test string is %s\n",dataCallList[i].addresses);
+        printf("test string is %s\n",dataCallList[i].dnses);
+        printf("test string is %s\n",dataCallList[i].gateways);
+        printf("test string is %s\n",dataCallList[i].pcscf);
+    }
+    */
+    return token;
+
+}
+void copyDataCallList(LYNQ_Data_Call_Response_v11 *newMsg,const RIL_Data_Call_Response_v11 oldMsg)
+{
+    newMsg->status = oldMsg.status;
+    LYDBGLOG("test dataCallList status is %d,list status is %d\n",newMsg->status,oldMsg.status);
+    newMsg->suggestedRetryTime = oldMsg.suggestedRetryTime;
+    LYDBGLOG("test %d\n",oldMsg.suggestedRetryTime);
+    newMsg->cid = oldMsg.cid;
+    LYDBGLOG("test %d\n",oldMsg.cid);
+    newMsg->active = oldMsg.active;
+    LYDBGLOG("test %d\n",oldMsg.active);
+    newMsg->mtu = oldMsg.mtu;
+    LYDBGLOG("test %d\n",oldMsg.mtu);
+    memcpy(newMsg->type,oldMsg.type,strlen(oldMsg.type)+1);
+    LYDBGLOG("test string is %s\n",oldMsg.type);
+    memcpy(newMsg->ifname,oldMsg.ifname,strlen(oldMsg.ifname)+1);
+    LYDBGLOG("test string is %s\n",oldMsg.ifname);
+    memcpy(newMsg->addresses,oldMsg.addresses,strlen(oldMsg.addresses)+1);
+    LYDBGLOG("test string is %s\n",oldMsg.addresses);
+    memcpy(newMsg->dnses,oldMsg.dnses,strlen(oldMsg.dnses)+1);
+    LYDBGLOG("test string is %s\n",oldMsg.dnses);
+    memcpy(newMsg->gateways,oldMsg.gateways,strlen(oldMsg.gateways)+1);
+    LYDBGLOG("test string is %s\n",oldMsg.gateways);
+    memcpy(newMsg->pcscf,oldMsg.pcscf,strlen(oldMsg.pcscf)+1);
+    LYDBGLOG("test string is %s\n",oldMsg.pcscf);
+
+}
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/lynq_network.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/lynq_network.cpp
new file mode 100644
index 0000000..8ba3149
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/lynq_network.cpp
@@ -0,0 +1,744 @@
+//#include "common.h"
+#include "lynq_common.h"
+#include "lynq_network.h"
+//#include <stateManager/stateManager.h>
+#define CELL_LIST_MAX 10
+#undef LOG_TAG
+#define LOG_TAG "LYNQ_NETWORK"
+
+//moblietek add @2020.12.for add Network api
+int copyCellInfoList(Parcel &p,cellInfoList *cellinfo)
+{
+    int32_t v=0;
+    int64_t v6=0;
+    int32_t num = 0;
+    p.readInt32(&v);
+    cellinfo->cellinfo.cellInfoType = RIL_CellInfoType(v);
+    p.readInt32(&cellinfo->cellinfo.registered);
+    p.readInt32(&v);
+    cellinfo->cellinfo.timeStampType = RIL_TimeStampType(v);
+    p.readInt64(&v6);
+    cellinfo->cellinfo.timeStamp = v6;
+    switch(cellinfo->cellinfo.cellInfoType) {
+        case RIL_CELL_INFO_TYPE_GSM: {
+            p.readInt32(&cellinfo->cellinfo.CellInfo.gsm.cellIdentityGsm.mcc);
+            p.readInt32(&cellinfo->cellinfo.CellInfo.gsm.cellIdentityGsm.mnc);
+            p.readInt32(&cellinfo->cellinfo.CellInfo.gsm.cellIdentityGsm.lac);
+            p.readInt32(&cellinfo->cellinfo.CellInfo.gsm.cellIdentityGsm.cid);
+            p.readInt32(&cellinfo->cellinfo.CellInfo.gsm.signalStrengthGsm.signalStrength);
+            p.readInt32(&cellinfo->cellinfo.CellInfo.gsm.signalStrengthGsm.bitErrorRate);
+            p.readInt32(&cellinfo->cellinfo.CellInfo.gsm.signalStrengthGsm.timingAdvance);
+            break;
+        }
+        case RIL_CELL_INFO_TYPE_WCDMA: {
+            p.readInt32(&cellinfo->cellinfo.CellInfo.wcdma.cellIdentityWcdma.mcc);
+            p.readInt32(&cellinfo->cellinfo.CellInfo.wcdma.cellIdentityWcdma.mnc);
+            p.readInt32(&cellinfo->cellinfo.CellInfo.wcdma.cellIdentityWcdma.lac);
+            p.readInt32(&cellinfo->cellinfo.CellInfo.wcdma.cellIdentityWcdma.cid);
+            p.readInt32(&cellinfo->cellinfo.CellInfo.wcdma.cellIdentityWcdma.psc);
+            p.readInt32(&cellinfo->cellinfo.CellInfo.wcdma.signalStrengthWcdma.signalStrength);
+            p.readInt32(&cellinfo->cellinfo.CellInfo.wcdma.signalStrengthWcdma.bitErrorRate);
+            break;
+        }
+        case RIL_CELL_INFO_TYPE_CDMA: {
+            p.readInt32(&cellinfo->cellinfo.CellInfo.cdma.cellIdentityCdma.networkId);
+            p.readInt32(&cellinfo->cellinfo.CellInfo.cdma.cellIdentityCdma.systemId);
+            p.readInt32(&cellinfo->cellinfo.CellInfo.cdma.cellIdentityCdma.basestationId);
+            p.readInt32(&cellinfo->cellinfo.CellInfo.cdma.cellIdentityCdma.longitude);
+            p.readInt32(&cellinfo->cellinfo.CellInfo.cdma.cellIdentityCdma.latitude);
+            p.readInt32(&cellinfo->cellinfo.CellInfo.cdma.signalStrengthCdma.dbm);
+            p.readInt32(&cellinfo->cellinfo.CellInfo.cdma.signalStrengthCdma.ecio);
+            p.readInt32(&cellinfo->cellinfo.CellInfo.cdma.signalStrengthEvdo.dbm);
+            p.readInt32(&cellinfo->cellinfo.CellInfo.cdma.signalStrengthEvdo.ecio);
+            p.readInt32(&cellinfo->cellinfo.CellInfo.cdma.signalStrengthEvdo.signalNoiseRatio);
+
+            break;
+        }
+        case RIL_CELL_INFO_TYPE_LTE: {
+            p.readInt32(&cellinfo->cellinfo.CellInfo.lte.cellIdentityLte.mcc);
+            p.readInt32(&cellinfo->cellinfo.CellInfo.lte.cellIdentityLte.mnc);
+            p.readInt32(&cellinfo->cellinfo.CellInfo.lte.cellIdentityLte.ci);
+            p.readInt32(&cellinfo->cellinfo.CellInfo.lte.cellIdentityLte.pci);
+            p.readInt32(&cellinfo->cellinfo.CellInfo.lte.cellIdentityLte.tac);
+            p.readInt32(&cellinfo->cellinfo.CellInfo.lte.signalStrengthLte.signalStrength);
+            p.readInt32(&cellinfo->cellinfo.CellInfo.lte.signalStrengthLte.rsrp);
+            p.readInt32(&cellinfo->cellinfo.CellInfo.lte.signalStrengthLte.rsrq);
+            p.readInt32(&cellinfo->cellinfo.CellInfo.lte.signalStrengthLte.rssnr);
+            p.readInt32(&cellinfo->cellinfo.CellInfo.lte.signalStrengthLte.cqi);
+            p.readInt32(&cellinfo->cellinfo.CellInfo.lte.signalStrengthLte.timingAdvance);
+            break;
+        }
+        case RIL_CELL_INFO_TYPE_TD_SCDMA: {
+            p.readInt32(&cellinfo->cellinfo.CellInfo.tdscdma.cellIdentityTdscdma.mcc);
+            p.readInt32(&cellinfo->cellinfo.CellInfo.tdscdma.cellIdentityTdscdma.mnc);
+            p.readInt32(&cellinfo->cellinfo.CellInfo.tdscdma.cellIdentityTdscdma.lac);
+            p.readInt32(&cellinfo->cellinfo.CellInfo.tdscdma.cellIdentityTdscdma.cid);
+            p.readInt32(&cellinfo->cellinfo.CellInfo.tdscdma.cellIdentityTdscdma.cpid);
+            p.readInt32(&cellinfo->cellinfo.CellInfo.tdscdma.signalStrengthTdscdma.rscp);
+            break;
+        }
+    }
+    return 0;
+}
+int checkRespErrno(const int32_t token,const int time,RIL_Errno & err)
+{
+    int time_net = time;
+    int status=0;
+    lynqQueue *node = NULL;
+    lynqQueue *temp =NULL;
+    while(time_net--)
+    {
+        millli_sleep_with_restart(10);
+        temp=LynqQueueHead;
+        if(temp==NULL)
+        {
+            LYDBGLOG("[%s][%d][%s] Queue head is NULL, maybe malloc fail!\n",__FUNCTION__,__LINE__,__FILE__);
+            continue;
+        }
+        node = searchTokeninQueue(token, temp);
+        if(node ==NULL)
+        {
+            LYDBGLOG("[%s][%d][%s] can not find token %x\n",__FUNCTION__,__LINE__,__FILE__,token);
+            err=-1;
+            return -1;
+        }
+        node->parcel.setDataPosition(0);
+        if (node->parcel.dataAvail() > 0) 
+        {
+            node->parcel.readInt32(&status);
+            LYDBGLOG("[%s][%d][%s] message number is %d\n",__FUNCTION__,__LINE__,__FILE__,status);
+            if(status!=0)
+            {
+                if(node->t_Errno!=RIL_E_SUCCESS)
+                {
+                    LYDBGLOG("[%s][%d][%s] get err success,but the event is fail,the error code is %d\n",__FUNCTION__,__LINE__,__FILE__,node->t_Errno);
+                    err=node->t_Errno;
+                    return -1;
+                }
+                else
+                {
+                    LYDBGLOG("[%s][%d][%s] get success, the error code is %d",__FUNCTION__,__LINE__,__FILE__,node->t_Errno);
+                    err=node->t_Errno;
+                    return 0;
+                }
+            }
+         }
+         else
+         {
+           continue;
+         }
+    }
+    if(time_net<0)
+    {
+        LYDBGLOG("[%s][%d][%s] time out,can not find network selection mode  message!",__FUNCTION__,__LINE__,__FILE__);
+        err=-1;
+    }
+    return -1;
+}
+int checkNetworkSelectionMode(const int32_t token,const int time,networkSelecttionMode *netselMode)
+{
+    int time_net = time;
+    int num=0;
+    //int status =0;
+    Parcel parcel;
+    RIL_Errno err;
+    lynqQueue *node = NULL;
+    lynqQueue *temp =NULL;
+    node = commonFindParcelmsg(token,time,err);
+    if(node!=NULL)
+    {
+        node->parcel.readInt32(&num);
+        LYDBGLOG("[%s][%d][%s] message number is %d",__FUNCTION__,__LINE__,__FILE__,num);
+        node->parcel.readInt32(&netselMode->mode);
+        netselMode->base.e=err;
+        return 0;
+    }
+    netselMode->base.e=err;
+    return -1;
+}
+int updateRegStateInfo(int32_t request,int32_t token,registrationStateInfo *regStateInfo)
+{
+    RIL_Errno err;
+    Parcel parcel;
+    int res = 0;
+    int num=0;
+    lynqQueue *node=NULL;
+    regStateInfo->base.request=request;
+    regStateInfo->base.token = token;
+    switch(request)
+    {
+        case RIL_REQUEST_VOICE_REGISTRATION_STATE:
+        {
+            node = commonFindParcelmsg(token, 500,err);
+            if (node != NULL)
+            {
+                node->parcel.setDataPosition(0);
+                node->parcel.readInt32(&num);
+                LYDBGLOG("[RIL_REQUEST_DATA_REGISTRATION_STATE] the num is %d\n",num);
+                if(num==15)
+                {
+                    regStateInfo->regState = atoi(lynqStrdupReadString(node->parcel));
+                    lynqStrdupReadString(node->parcel);
+                    lynqStrdupReadString(node->parcel);
+                    regStateInfo->netType =atoi( lynqStrdupReadString(node->parcel));
+                }
+            }
+            regStateInfo->base.e=err;
+            break;
+        }
+        case RIL_REQUEST_DATA_REGISTRATION_STATE:
+        {
+            node = commonFindParcelmsg(token, 500,err);
+            if (node != NULL)
+            {
+                node->parcel.setDataPosition(0);
+                node->parcel.readInt32(&num);
+                //char * temp=NULL;
+                LYDBGLOG("[RIL_REQUEST_DATA_REGISTRATION_STATE] the num is %d\n",num);
+                if(num==11)
+                {
+                    regStateInfo->regState = atoi(lynqStrdupReadString(node->parcel));
+                    regStateInfo->LAC = lynqStrdupReadString(node->parcel);
+                    regStateInfo->CID = lynqStrdupReadString(node->parcel);
+                    regStateInfo->netType =atoi( lynqStrdupReadString(node->parcel));
+                }
+            }
+            regStateInfo->base.e=err;
+            break;
+        }
+        case RIL_REQUEST_IMS_REGISTRATION_STATE:
+        {
+            node = commonFindParcelmsg(token, 500,err);
+            if (node != NULL)
+            {
+                node->parcel.setDataPosition(0);
+                node->parcel.readInt32(&num);
+                //char * temp=NULL;
+                LYDBGLOG("[RIL_REQUEST_DATA_REGISTRATION_STATE] the num is %d\n",num);
+                if(num==2)
+                {
+                    node->parcel.readInt32(&regStateInfo->imsRegState);
+                    node->parcel.readInt32(&res);
+                    regStateInfo->radioTechFam = (RIL_RadioTechnologyFamily)res;
+                }
+            }
+            regStateInfo->base.e=err;
+            break;
+        }
+        default:
+            break;
+    }
+	return 0;
+}
+int lynq_query_operater(operatorInfo * currentOperator)
+{
+    int32_t token = 0;
+    int time_net =100;
+    int num=0;
+    lynqQueue *node = NULL;
+    RIL_Errno err = -1;
+    char requestStr[MAX_LEN] = {"RIL_REQUEST_OPERATOR"};
+    if(token = lynqNoneParame(requestStr))
+    {
+        currentOperator->base.request = RIL_REQUEST_OPERATOR;
+        currentOperator->base.token=token;
+        node = commonUpdateEstatus(token, time_net, err);
+        currentOperator->base.e = err;
+        if(err!=RIL_E_SUCCESS)
+        {
+            currentOperator->OperatorFN = NULL;
+            currentOperator->OperatorSH = NULL;
+            currentOperator->MccMnc = NULL;
+            lynqDeQueue(token);
+            return token;
+        }
+        node->parcel.setDataPosition(0);
+        if (node->parcel.dataAvail() > 0) 
+        {
+            node->parcel.readInt32(&num);
+            LYDBGLOG("[%s][%d][%s] Message number is %d",__FUNCTION__,__LINE__,__FILE__,num);
+            if(num == 3)
+            {
+                currentOperator->OperatorFN = lynqStrdupReadString(node->parcel);
+                currentOperator->OperatorSH = lynqStrdupReadString(node->parcel);
+                currentOperator->MccMnc = lynqStrdupReadString(node->parcel);
+            }
+        }
+        lynqDeQueue(token);
+    }
+    return token;
+}
+
+int lynq_query_network_selection_mode(networkSelecttionMode *netselMode)
+{
+    int32_t token=0;
+    int time_net = 100;//1s
+    //int num=0;
+    //lynqQueue *node = NULL;
+    //lynqQueue *temp =NULL;
+    char requestStr[MAX_LEN] = {"RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE"};
+    token=lynqNoneParame(requestStr);
+    netselMode->base.token=token;
+    netselMode->base.request=RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE;
+    checkNetworkSelectionMode(token,time_net,netselMode);
+    lynqDeQueue(token);
+    return token;
+}
+int lynq_set_network_selection_mode(const char *mode,const char* mccmnc,lynqBase *base)//0:auto selection 1:manual selection
+{
+    const char *argv[MAX_LEN] = {};
+    int32_t token=0;
+    RIL_Errno err;
+    lynqQueue * node = NULL;
+    int time_net = 100;//1s
+    char mccmncStr[MAX_QUEST_LEN] = "";
+    if(!strcmp(mode,"Auto"))
+    {
+        //printf("--------->[%s,%d] Auto!!! \n",__FUNCTION__,__LINE__);
+        argv[0] = "RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC";
+        argv[1] = "Auto";
+        if(token = android::getRequestData(argv, 1))
+        {
+            base->request=RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC;
+            base->token = token;
+            node = commonFindParcelmsg(token,time_net,err);
+            base->e=err;
+            lynqDeQueue(token);
+        }
+        return token;
+    }else if(!strcmp(mode,"Manual")){
+        //printf("--------->[%s,%d] manual,mccmnc=%d \n",__FUNCTION__,__LINE__,mccmnc);
+        //sprintf(mccmncStr, "%d", mccmnc);
+        argv[0] = "RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL";
+        argv[1] = mccmnc;
+        //argv[2] = mccmnc;
+        if(token = android::getRequestData(argv, 2))
+        {
+            base->request=RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL;
+            base->token = token;
+            node = commonFindParcelmsg(token,time_net,err);
+            base->e=err;
+            lynqDeQueue(token);
+        }
+        return token;
+    }
+}
+
+int lynq_query_available_network(availableNetwork *availNet)
+{
+    int32_t token;
+    char requestStr[MAX_LEN] = {"RIL_REQUEST_QUERY_AVAILABLE_NETWORKS"};
+    int time_net =6000;//60second
+    int num=0;//the number of available network data
+    int range = 0;/*response is const char ** that should be an array of n*4 strings, where "range" is the number of available networks*/
+    RIL_Errno err = -1;
+    lynqQueue *node = NULL;
+    lynqQueue *temp =NULL;
+    if(token = lynqNoneParame(requestStr))
+    {
+        availNet->base.request = RIL_REQUEST_OPERATOR;
+        availNet->base.token=token;
+        node = commonFindParcelmsg(token, time_net, err);
+        availNet->base.e=err;
+        if (node !=NULL)
+        {
+            node->parcel.readInt32(&num);
+            LYDBGLOG("[%s][%d] message number is %d\n",__FUNCTION__,__LINE__,num);
+            if((num/4)>0 &&(num%4)==0)//Integer multiples of 4
+            {
+                range = num/4;
+                /*Temporary plan.the real situation should be for(int i=0;i<range;i++)*/
+                availNet->OperatorFN = lynqStrdupReadString(node->parcel);
+                availNet->OperatorSH = lynqStrdupReadString(node->parcel);
+                availNet->MccMnc = lynqStrdupReadString(node->parcel);
+                availNet->NetStatus = lynqStrdupReadString(node->parcel);
+            }
+            else
+            {
+                if(num/4>0)
+                {
+                    availNet->OperatorFN = lynqStrdupReadString(node->parcel);
+                    availNet->OperatorSH = lynqStrdupReadString(node->parcel);
+                    availNet->MccMnc = lynqStrdupReadString(node->parcel);
+                    availNet->NetStatus = lynqStrdupReadString(node->parcel);
+                }
+            }
+        }
+        lynqDeQueue(token);
+    }
+    return 0;
+}
+
+//network state
+int lynq_query_registration_state(const char *type,registrationStateInfo *regStateInfo)//type:vioce/data/ims
+{
+    char requestStr[MAX_LEN]="";
+    int32_t request=0;
+    int32_t token=0;
+    char str[10];
+    if (strlen(type)>10)
+    {
+        LYERRLOG("[%s]the parameter is inavaliable !\n",__FUNCTION__);
+        return -1;
+    }
+    memcpy(str,type,strlen(type)+1);
+    strUpper(str);
+    //printf("upper str is %s\n",str);
+    if(!strcmp(str,"VOICE")){
+        strcpy(requestStr,"RIL_REQUEST_VOICE_REGISTRATION_STATE");
+        request=RIL_REQUEST_VOICE_REGISTRATION_STATE;
+    }else if(!strcmp(str,"DATA")){
+        strcpy(requestStr,"RIL_REQUEST_DATA_REGISTRATION_STATE");
+        request= RIL_REQUEST_DATA_REGISTRATION_STATE;
+    }else if(!strcmp(str,"IMS")){
+        strcpy(requestStr,"RIL_REQUEST_IMS_REGISTRATION_STATE");
+        request = RIL_REQUEST_IMS_REGISTRATION_STATE;
+    }else{    
+        LYERRLOG("[%s,%d] query ims registration state about voice, data, and ims!!! \n",__FUNCTION__,__LINE__);
+        return -1;
+    }
+    token = lynqNoneParame(requestStr);
+    updateRegStateInfo(request,token,regStateInfo);
+    lynqDeQueue(token);
+    return token;
+}
+//preferred network
+int lynq_query_prefferred_networktype(prefferredNetworkType * preNetType)
+{
+    int32_t token=0;
+    lynqQueue *node =NULL;
+    RIL_Errno err=-1;
+    int num =0;
+    int res = 0;
+    char requestStr[MAX_LEN] = {"RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE"};
+    token = lynqNoneParame(requestStr);
+    preNetType->base.request = RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE;
+    preNetType->base.token=token;
+    node = commonFindParcelmsg(token, 500, err);
+    if (node !=NULL)
+    {
+        node->parcel.readInt32(&num);
+        node->parcel.readInt32(&res);
+        preNetType->pnt=res;
+    }
+    preNetType->base.e=err;
+    lynqDeQueue(token);
+    return token;
+}
+
+int lynq_set_prefferred_networktype(const int preffertype,lynqBase * base)//preffertype:0~22
+{
+    char *argv[MAX_LEN] = {};
+    char preffertypeStr[MAX_QUEST_LEN] = "";
+    int32_t token=0;
+    int status = 0;
+    RIL_Errno err=-1;
+    lynqQueue * node = NULL;
+
+    sprintf(preffertypeStr, "%d", preffertype);
+    argv[0] = "RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE";
+    argv[1] = preffertypeStr;
+    if(token = android::getRequestData(argv, 2))
+    {
+        base->request = RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE;
+        base->token=token;
+        node = commonFindParcelmsg(token,500,err);
+        base->e=err;
+        lynqDeQueue(token);
+    }
+    return token;
+}
+
+//cell info
+int lynq_query_cell_info(cellInfoList ** cellinfo,const int listNum,int *realNum)
+{
+    int32_t token = 0;
+    lynqQueue *node = NULL;
+    RIL_Errno err = -1;
+    int num = 0;
+    *realNum = 0;
+    if(listNum>CELL_LIST_MAX)
+    {
+        LYERRLOG("the list number is more than 10\n");
+        return -1;
+    }
+    char requestStr[MAX_LEN] = {"RIL_REQUEST_GET_CELL_INFO_LIST"};
+    if(token = lynqNoneParame(requestStr))
+    {
+        cellinfo[0]->base.request=RIL_REQUEST_GET_CELL_INFO_LIST;
+        cellinfo[0]->base.token = token;
+        //node = commonFindParcelmsg(token,500,err);
+        if(node = commonFindParcelmsg(token,500,err))
+        {
+            node->parcel.readInt32(&num);
+            if (listNum<num)
+            {
+                num=listNum;
+                LYDBGLOG("[%s,%d]listNum<num!",__FUNCTION__,__LINE__);
+            }
+            *realNum = num;
+            for(int i = 0;i<num;i++)
+            {
+                copyCellInfoList(node->parcel,cellinfo[i]);
+                //cellinfo[i]->base.request=RIL_REQUEST_GET_CELL_INFO_LIST;
+                //cellinfo[i]->base.token = token;
+            }
+        }
+        cellinfo[0]->base.e=err;
+        lynqDeQueue(token);
+    }
+    cellinfo[0]->base.e=err;
+    return token;
+}
+
+int lynq_set_unsol_cell_info_listrate(const int rate,lynqBase * base) //rate:0<=rate<=0x7fffffff, minimum time in milliseconds
+{
+    int32_t token=0;
+    char *argv[MAX_LEN] = {};
+    char rateStr[MAX_QUEST_LEN] = "";
+    int status = 0;
+    RIL_Errno err=-1;
+    lynqQueue * node = NULL;
+    sprintf(rateStr, "%d", rate);
+    argv[0] = "RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE";
+    argv[1] = rateStr;
+    if(token = android::getRequestData(argv, 2))
+    {
+        base->request = RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE;
+        base->token=token;
+        node = commonFindParcelmsg(token,500,err);
+        base->e=err;
+        lynqDeQueue(token);
+    }
+    return token;
+}
+
+int lynq_query_neighboring_cellids(neighboringCellIDs **neiCeIDs,const int listNum,int *realNum)
+{
+    int32_t token = 0;
+    lynqQueue *node = NULL;
+    RIL_Errno err = -1;
+    int num = 0;
+    int res=0;
+    *realNum = 0;
+    if(listNum>CELL_LIST_MAX)
+    {
+        LYERRLOG("the list number is more than 10\n");
+        return -1;
+    }
+    char requestStr[MAX_LEN] = {"RIL_REQUEST_GET_NEIGHBORING_CELL_IDS"};
+    if(token = lynqNoneParame(requestStr))
+    {
+        neiCeIDs[0]->base.request=RIL_REQUEST_GET_NEIGHBORING_CELL_IDS;
+        neiCeIDs[0]->base.token = token;
+        //node = commonFindParcelmsg(token,500,err);
+        if(node = commonFindParcelmsg(token,500,err))
+        {
+            node->parcel.readInt32(&num);
+            if (listNum<num)
+            {
+                num=listNum;
+                LYDBGLOG("[%s,%d]listNum<num!",__FUNCTION__,__LINE__);
+            }
+            *realNum = num;
+            for(int i = 0;i<num;i++)
+            {
+                neiCeIDs[i]->cid = lynqStrdupReadString(node->parcel);
+                node->parcel.readInt32(&res);
+                neiCeIDs[i]->rssi = res;
+            }
+        }
+        neiCeIDs[0]->base.e=err;
+        lynqDeQueue(token);
+    }
+    neiCeIDs[0]->base.e=err;
+    return token;
+}
+
+//band mode
+int lynq_set_band_mode(const int bandmode,lynqBase *base)//bandmode:0~18
+{
+    char *argv[MAX_LEN] = {};
+    int32_t token=0;
+    char bandmodeStr[MAX_QUEST_LEN] = "";
+    int status = 0;
+    RIL_Errno err=-1;
+    lynqQueue * node = NULL;
+    sprintf(bandmodeStr, "%d", bandmode);
+    argv[0] = "RIL_REQUEST_SET_BAND_MODE";
+    argv[1] = bandmodeStr;
+    token = android::getRequestData(argv, 2);
+    base->request=RIL_REQUEST_SET_BAND_MODE;
+    base->token = token;
+    node = commonFindParcelmsg(token,1000,err);
+    base->e=err;
+    lynqDeQueue(token);
+    return token;
+}
+
+int lynq_query_available_bandmode(availableBandMode*availBanMode)
+{
+    int32_t token = 0;
+    RIL_Errno err=-1;
+    lynqQueue * node = NULL;
+    int num = 0;
+    int res = 0;
+    char requestStr[MAX_LEN] = {"RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE"};
+    token = lynqNoneParame(requestStr);
+    availBanMode->base.request = RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE;
+    availBanMode->base.token = token;
+    node = commonFindParcelmsg(token,500,err);
+    for(int i = 0;i<20;i++)
+    {
+        availBanMode->bandmode[i]=0;
+    }
+    if (node!=NULL)
+    {
+        node->parcel.readInt32(&num);
+        availBanMode->bandmode[0]=num;
+        LYDBGLOG("[%s] available band mode num is %d\n",__FUNCTION__,num);
+        for(int i=1;i<=num;i++)
+        {
+            node->parcel.readInt32(&res);
+            availBanMode->bandmode[i]=res;
+        }
+    }
+    availBanMode->base.e=err;
+    lynqDeQueue(token);
+    return 0;
+}
+
+//radio power  
+int lynq_radio_on(const int data,lynqBase *base)//0:off  other:on
+{
+    char *argv[MAX_LEN] = {};
+    char dataStr[MAX_QUEST_LEN] = "";
+    int32_t token = 0;
+    lynqQueue *node = NULL;
+    RIL_Errno err=-1;
+    sprintf(dataStr, "%d", data);
+    argv[0] = "RIL_REQUEST_RADIO_POWER";
+    argv[1] = dataStr;
+    if(token = android::getRequestData(argv, 2))
+    {
+        base->request=RIL_REQUEST_RADIO_POWER;
+        base->token = token;
+        node = commonFindParcelmsg(token,500,err);
+        base->e=err;
+        lynqDeQueue(token);
+    }
+    return token;
+}
+
+//radio tech
+int lynq_query_radio_tech(radioTechnology *radioTech)
+{
+    char requestStr[MAX_LEN] = {"RIL_REQUEST_VOICE_RADIO_TECH"};
+    int32_t token=0;
+    RIL_Errno err=-1;
+    lynqQueue *node =NULL;
+    int num = 0;
+    int res = 0;
+    token = lynqNoneParame(requestStr);
+    radioTech->base.request = RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE;
+    radioTech->base.token=token;
+    node = commonFindParcelmsg(token, 500, err);
+    if (node !=NULL)
+    {
+        node->parcel.readInt32(&num);
+        node->parcel.readInt32(&res);
+        radioTech->radioTech=res;
+    }
+    radioTech->base.e=err;
+    lynqDeQueue(token);
+    return token;
+}
+
+//signal strength
+int lynq_solicited_signal_strength(solicitedSignalStrength *solSigStren)
+{
+    char requestStr[MAX_LEN] = {"RIL_REQUEST_SIGNAL_STRENGTH"};
+    int32_t token=0;
+    RIL_Errno err=-1;
+    lynqQueue *node =NULL;
+    int num = 0;
+    int res = 0;
+    token = lynqNoneParame(requestStr);
+    solSigStren->base.request = RIL_REQUEST_SIGNAL_STRENGTH;
+    solSigStren->base.token=token;
+    node = commonFindParcelmsg(token, 500, err);
+    solSigStren->base.e=err;
+    if (node !=NULL)
+    {
+        node->parcel.readInt32(&num);
+        if(num ==0)
+        {
+            LYDBGLOG("[%s] the signal strength is null!\n",__FUNCTION__);
+            if(err==RIL_E_SUCCESS)
+            {
+                solSigStren->base.e=-1;
+            }
+            lynqDeQueue(token);
+            return token;
+        }
+        node->parcel.readInt32(&solSigStren->signalStrength.GW_SignalStrength.signalStrength);
+        node->parcel.readInt32(&solSigStren->signalStrength.GW_SignalStrength.bitErrorRate);
+        node->parcel.readInt32(&solSigStren->signalStrength.GW_SignalStrength.timingAdvance);
+        node->parcel.readInt32(&solSigStren->signalStrength.CDMA_SignalStrength.dbm);
+        node->parcel.readInt32(&solSigStren->signalStrength.CDMA_SignalStrength.ecio);
+        node->parcel.readInt32(&solSigStren->signalStrength.EVDO_SignalStrength.dbm);
+        node->parcel.readInt32(&solSigStren->signalStrength.EVDO_SignalStrength.ecio);
+        node->parcel.readInt32(&solSigStren->signalStrength.EVDO_SignalStrength.signalNoiseRatio);
+        node->parcel.readInt32(&solSigStren->signalStrength.LTE_SignalStrength.signalStrength);
+        node->parcel.readInt32(&solSigStren->signalStrength.LTE_SignalStrength.rsrp);
+        node->parcel.readInt32(&solSigStren->signalStrength.LTE_SignalStrength.rsrq);
+        node->parcel.readInt32(&solSigStren->signalStrength.LTE_SignalStrength.rssnr);
+        node->parcel.readInt32(&solSigStren->signalStrength.LTE_SignalStrength.cqi);
+        node->parcel.readInt32(&solSigStren->signalStrength.LTE_SignalStrength.timingAdvance);
+        node->parcel.readInt32(&solSigStren->signalStrength.TD_SCDMA_SignalStrength.signalStrength);
+        node->parcel.readInt32(&solSigStren->signalStrength.TD_SCDMA_SignalStrength.bitErrorRate);
+        node->parcel.readInt32(&solSigStren->signalStrength.TD_SCDMA_SignalStrength.rscp);
+        node->parcel.readInt32(&solSigStren->signalStrength.WCDMA_SignalStrength.signalStrength);
+        node->parcel.readInt32(&solSigStren->signalStrength.WCDMA_SignalStrength.bitErrorRate);
+        node->parcel.readInt32(&solSigStren->signalStrength.WCDMA_SignalStrength.rscp);
+        node->parcel.readInt32(&solSigStren->signalStrength.WCDMA_SignalStrength.ecno);
+    }
+    lynqDeQueue(token);
+    return token;
+
+}
+
+//modem
+int lynq_modem_on(const int data,lynqBase *base)//data: 0:off,other:on
+{
+    char *argv[MAX_LEN] = {};
+    char dataStr[MAX_QUEST_LEN] = "";
+    argv[0] = data == 0 ? "RIL_REQUEST_MODEM_POWEROFF" : "RIL_REQUEST_MODEM_POWERON" ;
+    sprintf(dataStr, "%d", data);
+    argv[1] = dataStr;
+    int32_t token = 0;
+    lynqQueue *node = NULL;
+    RIL_Errno err=-1;
+    if(token = android::getRequestData(argv, 2))
+    {
+        base->request=(data == 0 ? RIL_REQUEST_MODEM_POWEROFF:RIL_REQUEST_MODEM_POWERON );
+        base->token = token;
+        node = commonFindParcelmsg(token,500,err);
+        base->e=err;
+        lynqDeQueue(token);
+    }
+    return token;
+}
+
+#if 0
+int  lynq_enter_network_depersonalization(char *code)//code:network/depersonalization code
+{
+    char *argv[MAX_LEN] = {};
+    char dataStr[MAX_QUEST_LEN] = "";
+    
+    argv[0] = "RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION"; 
+    argv[1] = code;
+    
+    return  android::getRequestData(argv, 2);
+}
+#endif
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/lynq_sim.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/lynq_sim.cpp
new file mode 100644
index 0000000..57baf99
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/lynq_sim.cpp
@@ -0,0 +1,377 @@
+/*============================================================================= 
+#     FileName: lynq_sim.cpp
+#     Desc: about SIM API
+#     Author: mobiletek 
+#     Version: V1.0
+#     LastChange: 2020-07-29 
+#     History: 
+=============================================================================*/
+#include <dlfcn.h>
+#include <string.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include "lynq_common.h"
+#include "lynq_sim.h"
+#include <stateManager/stateManager.h>
+
+#undef LOG_TAG
+#define LOG_TAG "LYNQ_SIM"
+simInfoLink *simInfoLinkHead=NULL;
+
+
+/*Initialize SIM infomation queue for lynq_sim API.*/
+int init_sim()
+{
+    simInfoLinkHead=createSimInfoLink();
+    if(simInfoLinkHead==NULL)
+    {
+        RLOGD("init sim info link head fail!");
+        return -1;
+    }
+    RLOGD("init sim info link head success!");
+    millli_sleep_with_restart(300);//The premise of obtaining imsi is that aid_ptr has been obtained
+    return 0;
+
+}
+simStatus *parceToSimInfo(Parcel &p,int &len)
+{
+    int32_t res;
+    int num=0;
+    simStatus *msg=(simStatus *)malloc(sizeof(simStatus));
+    p.setDataPosition(0);
+    if (p.dataAvail() > 0) 
+    {
+        p.readInt32(&res);
+        msg->card_status = (RIL_CardState)res;
+        p.readInt32(&num);
+        len = num;
+        LYDBGLOG("[%s] num is%d\n ",__FUNCTION__,num);
+        for (int i = 0; i < num; i++) //for future.
+        {
+            p.readInt32(&res);
+            msg->card_type = (RIL_AppType)res;
+            p.readInt32(&res);
+            msg->pin_state = (RIL_PinState)res;
+        }
+        return msg;
+    }
+   return NULL;
+}
+int checkParcelSimInfo(simStatus *msg,int32_t token)
+{
+    int time_sim =300;//3 s.
+    enum{RUN,EXIT}state;
+    state=RUN;
+    int length=0;
+    lynqQueue *node=NULL;
+    simStatus *temp=NULL;
+    while(time_sim--)
+    {
+         millli_sleep_with_restart(10);
+         node=LynqQueueHead;
+         if(node==NULL)
+         {
+             LYDBGLOG("[%s][%d][%s] Queue head is NULL, maybe malloc fail!",__FUNCTION__,__LINE__,__FILE__);
+             continue;
+         }
+         node = searchTokeninQueue(token, node);
+         if(node ==NULL)
+         {
+             msg->card_status=-1;
+             msg->card_type=-1;
+             msg->pin_state=-1;
+             msg->base.e=-1;
+            return -1;
+         }
+         if(node->t_Errno!=RIL_E_SUCCESS)
+         {
+             RLOGD("get sim status fail, the error code is %d",node->t_Errno);
+             msg->base.e=node->t_Errno;
+             msg->card_status=-1;
+             msg->card_type=-1;
+             msg->pin_state=-1;
+             return -1;
+         }
+         else
+         {
+             temp = parceToSimInfo(node->parcel,length);
+             if(temp ==NULL )
+             {
+                 continue;
+             }
+             else
+             {
+                  msg->card_status=temp->card_status;
+                  msg->card_type=temp->card_type;
+                  msg->pin_state=temp->pin_state;
+                  msg->base.e=node->t_Errno;
+                  free(temp);
+                  temp=NULL;
+                  return 0;
+             }
+         }
+    }
+    printf("time_sim is %d\n",time_sim);
+    msg->base.e=-1;
+    msg->card_status=-1;
+    msg->card_type=-1;
+    msg->pin_state=-1;
+    return -1;
+}
+/*return 0:success ,1:fail*/
+int checkSimInfo(simStatus *msg,int32_t token)
+{
+    int time_sim =300;//3 s.
+    enum{RUN,EXIT}state;
+    state=RUN;
+    printf("check sim Info start\n");
+    simInfoLink *temp;
+    while(time_sim--)
+    {
+     millli_sleep_with_restart(10);
+     temp=simInfoLinkHead;
+     if(temp==NULL)
+     {
+         RLOGD("sim info link head is NULL, maybe malloc fail!");
+         continue;
+     }
+     do
+     {
+       if((temp->simInfoLen!=0)&&(temp->token==token))
+       {
+           if(temp->Error_tok!=RIL_E_SUCCESS)
+           {
+               RLOGD("get sim status fail, the error code is %d",temp->Error_tok);
+               msg->base.e=temp->Error_tok;
+               msg->card_status=-1;
+               msg->card_type=-1;
+               msg->pin_state=-1;
+               return 1;
+           }
+           else
+           {
+              msg->card_status=temp->card_status;
+              msg->card_type=temp->card_type;
+              msg->pin_state=temp->pin_state;
+              msg->base.e=temp->Error_tok;
+              return 0;
+           }
+         }
+       temp=temp->next;
+     }while(temp!=NULL);
+    }
+    printf("time_sim is %d\n",time_sim);
+    msg->card_status=-1;
+    msg->card_type=-1;
+    msg->pin_state=-1;
+    msg->base.e=-1;
+    return 0;
+}
+/*return 0:success ,1:fail*/
+int checkParcelImsiInfo(simImsi *msg,int32_t token)
+{
+    int time_sim =300;//3 s.
+    enum{RUN,EXIT}state;
+    int num;
+    state=RUN;
+    printf("check IMSI Info start\n");
+    lynqQueue *node = NULL;
+    lynqQueue *temp =NULL;
+    while(time_sim--)
+    {
+         millli_sleep_with_restart(10);
+         temp=LynqQueueHead;
+         if(temp==NULL)
+         {
+             RLOGD("sim info link head is NULL, maybe malloc fail!");
+             continue;
+         }
+         node = searchTokeninQueue(token, temp);
+         if(node ==NULL)
+         {
+            memset(msg->imsi,0,sizeof(msg->imsi));
+            msg->base.e=-1;
+            return -1;
+         }
+         if(node->t_Errno!=RIL_E_SUCCESS)
+         {
+             RLOGD("get sim status fail, the error code is %d",node->t_Errno);
+             msg->base.e=node->t_Errno;
+             memset(msg->imsi,0,sizeof(msg->imsi));
+             return -1;
+         }
+         else
+         {
+            node->parcel.setDataPosition(0);
+            if (node->parcel.dataAvail() > 0) 
+            {
+
+                node->parcel.readInt32(&num);
+                for(int i =0;i<num;i++)
+                {
+                   char * str=lynqStrdupReadString(node->parcel);
+                   memcpy(msg->imsi,str,strlen(str)+1);
+                   msg->base.e=node->t_Errno;
+                }
+                return 0;
+             }
+             else
+             {
+               continue;
+             }
+         }
+    }
+    printf("time_sim is %d\n",time_sim);
+    msg->base.e=-1;
+    memset(msg->imsi,0,sizeof(msg->imsi));
+    return 0;
+}
+int checkImsiInfo(simImsi *msg,int32_t token)
+{
+    int time_sim =300;//3 s.
+    enum{RUN,EXIT}state;
+    state=RUN;
+    printf("check IMEI Info start\n");
+    simInfoLink *temp;
+    while(time_sim--)
+    {
+     millli_sleep_with_restart(10);
+     temp=simInfoLinkHead;
+     if(temp==NULL)
+     {
+         RLOGD("sim info link head is NULL, maybe malloc fail!");
+         continue;
+     }
+     do
+     {
+       if((temp->simInfoLen!=0)&&(temp->token==token))
+       {
+           if(temp->Error_tok!=RIL_E_SUCCESS)
+           {
+               RLOGD("get sim status fail, the error code is %d",temp->Error_tok);
+               msg->base.e=temp->Error_tok;
+               //msg->imsi = NULL;
+               memset(msg->imsi,0,sizeof(msg->imsi));
+               msg->base.token=token;
+               return 1;
+           }
+           else
+           {
+              msg->base.e=temp->Error_tok;
+              memcpy(msg->imsi,temp->imsi,strlen(temp->imsi)+1);
+              //msg->imsi = temp->imsi;
+              msg->base.token=token;
+              return 0;
+           }
+         }
+       temp=temp->next;
+     }while(temp!=NULL);
+    }
+    memset(msg->imsi,0,sizeof(msg->imsi));
+    //msg->imsi = NULL;
+    msg->base.token=token;
+    msg->base.e=-1;
+    return 0;
+}
+
+int lynq_set_default_sim_all(int sim_id)  //sim_id  0 ro 1
+{
+  const char requestStr[MAX_LEN] = {"SET_DEFAULT_SIM_ALL"};
+  return lynqIntParame(requestStr,sim_id);
+}
+/*If you need to use any API under lynq_sim, you mustfirst call the init_sim() function to initialize these functions.*/
+int lynq_get_sim_status(simStatus *msg)
+{
+    int32_t token=0;
+    int length=0;
+    lynqQueue *node = NULL;
+    int timeout = 500; //timeout is 5s.
+    RIL_Errno err = -1;
+    simStatus *temp =NULL;
+    const char requestStr[MAX_LEN] = {"RIL_REQUEST_GET_SIM_STATUS"};
+    if(token = lynqNoneParame(requestStr))
+    {
+        msg->base.token=token;
+        msg->base.request = RIL_REQUEST_GET_SIM_STATUS;
+        node = commonUpdateEstatus(token,timeout,err);
+        msg->base.e = err;
+        if(err != RIL_E_SUCCESS)
+        {
+            LYDBGLOG("[%s] error code is %d!",__FUNCTION__,err);
+            msg->card_status=-1;
+            msg->card_type=-1;
+            msg->pin_state=-1;
+            lynqDeQueue(token);
+            return token;
+        }
+        if(node)
+        {
+            temp = parceToSimInfo(node->parcel,length);
+            if(length ==0)//it means sim card absent
+            {
+                msg->card_status = 0;
+                msg->card_type = 0;
+                msg->pin_state = 0;
+            }
+            else
+            {
+                msg->card_status=temp->card_status;
+                msg->card_type=temp->card_type;
+                msg->pin_state=temp->pin_state;
+            }
+            free(temp);
+            temp = NULL;
+        }
+        lynqDeQueue(token);
+    }
+    return token;
+}
+/*AT> AT+CIMI     AT< IMSI*/
+int lynq_get_sim_status_ext(int sim_id )
+{
+    RLOGD("lynq_get_sim_status_ext,sim_id:%d",sim_id);
+    return getSimState(sim_id);
+}
+int lynq_get_imsi(simImsi * msg)
+{
+    int32_t token = 0;
+    lynqQueue *node = NULL;
+    int timeout = 500; //timeout is 5s.
+    RIL_Errno err = -1;
+    int num = 0;
+    //memset(msg,0,sizeof(simImsi));
+    const char requestStr[MAX_LEN] = {"RIL_REQUEST_GET_IMSI"};
+    if(token = lynqNoneParame(requestStr))
+    {
+        msg->base.request = RIL_REQUEST_GET_IMSI;
+        msg->base.token = token;
+        node = commonUpdateEstatus(token,timeout,err);
+        msg->base.e = err;
+        if(err != RIL_E_SUCCESS)
+        {
+            LYDBGLOG("[%s] error code is %d!",__FUNCTION__,err);
+            memset(msg->imsi,0,sizeof(msg->imsi));
+            lynqDeQueue(token);
+            return token;
+        }
+        if(node)
+        {
+            node->parcel.setDataPosition(0);
+            if (node->parcel.dataAvail() > 0) 
+            {
+                node->parcel.readInt32(&num);
+                for(int i =0;i<num;i++)//for DSDS.
+                {
+                   char * str=lynqStrdupReadString(node->parcel);
+                   memcpy(msg->imsi,str,strlen(str)+1);
+                }
+             }
+        }
+        lynqDeQueue(token);
+    }
+    return token;
+}
+
+
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/main.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/main.cpp
new file mode 100644
index 0000000..690cf3f
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/main.cpp
@@ -0,0 +1,152 @@
+/*
+*  Copyright (C) 2014 MediaTek Inc.
+*
+*  Modification based on code covered by the below mentioned copyright
+*  and/or permission notice(s).
+*/
+
+/* 
+**
+** Copyright 2006 The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <string.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <vendor-ril/telephony/ril.h>
+#include <log/log.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include "stateManager/stateManager.h"
+#include "common.h"
+#include <lib_tele.h>
+#include <lynq_call.h>
+#include <lynq_sms.h>
+
+extern "C" void RIL_register (const RIL_RadioFunctions *callbacks);
+
+extern "C" void RIL_onRequestComplete(RIL_Token t, RIL_Errno e,
+                           void *response, size_t responselen);
+
+
+#if defined(ANDROID_MULTI_SIM)
+extern "C" void RIL_onUnsolicitedResponse(int unsolResponse, const void *data,
+                                size_t datalen, RIL_SOCKET_ID socket_id);
+#else
+extern "C" void RIL_onUnsolicitedResponse(int unsolResponse, const void *data,
+                                size_t datalen);
+#endif
+
+#undef LOG_TAG
+#define LOG_TAG "DEMO_MAIN"
+//static const struct RIL_Cb *mRIL_Cb = NULL;
+requestResponse mRequestCb = NULL;
+unsolicitedResponse mUnsolicitedCb = NULL;
+static user_cb *lynq_Cb=NULL;
+static struct RIL_Env s_rilEnv = {
+    RIL_onRequestComplete,
+    RIL_onUnsolicitedResponse,
+    NULL
+};
+/*
+ void lynqRegisterRequestResponse(user_cb * cb){
+    lynq_cb = cb;
+    return ;
+}
+*/
+void lynqRegisterUnsolicitedResponse(user_cb * cb){
+    lynq_Cb = cb;
+    return ;
+}
+static void lynqOnUnsolicitedResponseCallback(int unsolResponse,char *response,int responselen) {
+}
+void  lynq_ril_init()
+{
+    int lock_file = open("/tmp/tel_demo_single_proc.lock", O_CREAT|O_RDWR, 0666);
+    int rc = flock(lock_file,LOCK_EX|LOCK_NB);
+    if(rc) {
+        if(EWOULDBLOCK == errno) {
+            printf("Error: cannot restart the telephony app repeatedly\n");
+            RLOGD("Error: cannot restart the telephony app repeatedly");
+            exit(0);
+        }
+    }
+#ifdef BASELIB_DIR_LIB64
+    const char *rilLibPath = "/lib64/libvendor-ril.so";
+#else
+    const char *rilLibPath = "/lib/libvendor-ril.so";
+#endif
+    void *dlHandle;
+    const RIL_RadioFunctions *(*rilInit)(const struct RIL_Env *, int, char **);
+
+    const RIL_RadioFunctions *funcs;
+
+    RLOGD("**RIL Daemon Started**");
+    android::registerOnUnsolicitedResponse(lynq_Cb);
+    //prctl(PR_SET_NAME,(unsigned long)"demo_main_thread");
+    dlHandle = dlopen(rilLibPath, RTLD_NOW);
+
+    if (dlHandle == NULL) {
+        RLOGE("dlopen failed: %s", dlerror());
+        exit(EXIT_FAILURE);
+    }
+
+    android::RIL_startEventLoop();
+    //android::startATCILoop();
+    //android::startPMLoop();
+    //android::startWakupLoop();
+
+    rilInit =
+        (const RIL_RadioFunctions *(*)(const struct RIL_Env *, int, char **))
+        dlsym(dlHandle, "RIL_Init");
+
+    if (rilInit == NULL) {
+        RLOGE("RIL_Init not defined or exported in %s", rilLibPath);
+        exit(EXIT_FAILURE);
+    }
+
+    dlerror(); // Clear any previous dlerror
+    RLOGD("start rilInit");
+    funcs = rilInit(&s_rilEnv, 0, NULL);;
+    RLOGD("start RIL_register");
+    RIL_register(funcs);
+    if(lynqApiInit()!=0)
+    {
+        RLOGD("lynq api init fail");
+        exit(0);
+    }
+   // android::registerForAppResponse(lynqResponseCallback);
+   // android::registerOnUnsolicitedResponse(lynqOnUnsolicitedResponseCallback);
+   // android::startGdbusLoop();
+    RLOGD("RIL_Init RIL_register completed");
+    printf("DemoApp launch done!\n");
+    //while (true) {
+        //sleep(UINT32_MAX);
+    //}
+    close(lock_file);
+}
+int lynq_waitToRcvCmd(char **data, int lenth)
+{
+    printf("--------->[%s,%d] \n",__FUNCTION__,__LINE__);
+    android::getRequestData(data,lenth);
+    
+    return 0;
+}
\ No newline at end of file
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/makefile b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/makefile
new file mode 100644
index 0000000..95e5882
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/makefile
@@ -0,0 +1,147 @@
+SHELL = /bin/sh
+RM = rm -f
+
+LOCAL_CFLAGS := -Wall \
+                -std=gnu++14 \
+                -g -Os \
+                -flto \
+                -DRIL_SHLIB \
+                -DATCI_PARSE \
+                -DKEEP_ALIVE \
+                -DECALL_SUPPORT \
+                -fpermissive \
+
+$(warning ################# C2K support: $(RAT_CONFIG_C2K_SUPPORT) $(CXX))
+ifeq ($(strip $(RAT_CONFIG_C2K_SUPPORT)), yes)
+    LOCAL_CFLAGS += -DC2K_SUPPORT
+
+endif
+
+ifeq ($(strip $(MTK_MULTI_SIM_SUPPORT)), dsds)
+    LOCAL_CFLAGS += -DANDROID_SIM_COUNT_2 \
+                     -DANDROID_MULTI_SIM \
+                     -DMODE_DSDS
+endif
+
+ifeq ($(strip $(MTK_MULTI_SIM_SUPPORT)), dsss)
+    LOCAL_CFLAGS += -DMODE_DSSS
+endif
+
+
+ifeq ($(strip $(TARGET_PLATFORM)), mt2731)
+$(warning ################# TARGET_PLATFORM_MT2731)
+    LOCAL_CFLAGS += -DTARGET_PLATFORM_MT2731 \
+                    -DMD_93_SUPPORT
+else ifeq ($(strip $(TARGET_PLATFORM)), mt2635)
+$(warning ################# TARGET_PLATFORM_MT2635)
+    LOCAL_CFLAGS += -DTARGET_PLATFORM_MT2635 \
+                    -DMD_90_SUPPORT
+endif
+
+ifeq ($(strip $(TARGET_PLATFORM)), mt2735)
+LOCAL_CFLAGS += -DTARGET_PLATFORM_MT2735
+LOCAL_CFLAGS += -DBASELIB_DIR_LIB64
+endif
+
+LOCAL_PATH   = .
+
+LOCAL_C_INCLUDES = \
+  -I. \
+  -I$(LOCAL_PATH)/data \
+   -I$(LOCAL_PATH)/util \
+  -I$(LOCAL_PATH)/em/rfdesense \
+  -I$(LOCAL_PATH)/em \
+  -I$(LOCAL_PATH)/sms \
+  -I$(LOCAL_PATH)/sms/cdma \
+  -I$(LOCAL_PATH)/sms/gsm \
+  -I$(LOCAL_PATH)/atci \
+  -I$(LOCAL_PATH)/../include/libtel \
+  -I$(LOCAL_PATH)/stateManager \
+  -I$(LOCAL_PATH)/ecall/ \
+  -I$(LOCAL_PATH)/ecall/gost \
+  -I$(LOCAL_PATH)/ecall/gost/utils \
+  -I$(LOCAL_PATH)/ecall/gost/sslp \
+  -I$(LOCAL_PATH)/ecall/gost/sslp/auth \
+  -I$(LOCAL_PATH)/ecall/gost/sslp/firmware \
+  -I$(LOCAL_PATH)/ecall/gost/sslp/commands \
+  -I$(LOCAL_PATH)/ecall/gost/sslp/ecall \
+  -I$(LOCAL_PATH)/ecall/gost/sslp/teledata \
+  -I$(ROOT)$(includedir)/logger \
+  -I$(ROOT)$(includedir)/liblog \
+  -I$(ROOT)$(includedir)/vendor-ril \
+  -I$(ROOT)$(includedir)/gstreamer-1.0 \
+  -I$(ROOT)$(includedir)/glib-2.0 \
+  -I$(ROOT)$(libdir)/glib-2.0/include \
+  -I$(ROOT)$(libdir)/gstreamer-1.0/include\
+  -I$(ROOT)$(includedir)/dbus-1.0 \
+  -I$(ROOT)$(libdir)/dbus-1.0/include \
+
+
+LOCAL_LIBS := \
+    -L. \
+    -ldl \
+    -lrt \
+    -lstdc++ \
+    -llog \
+    -llynq-log \
+    -lcutils \
+    -lutils \
+    -lpower \
+    -lbinder \
+    -lpthread \
+    -lmtk_audio_mixer_ctrl \
+    -lasound \
+    -lpal \
+    -lgstreamer-1.0 \
+    -lglib-2.0 \
+    -lgstbase-1.0 \
+    -lgstreamer-1.0 \
+    -lgobject-2.0 \
+    -lgio-2.0 \
+    -ldtmf \
+    -lapn \
+    -ldbus-1 \
+
+ifeq ($(strip $(TARGET_PLATFORM)), mt2735)
+LOCAL_LIBS += -luciwrapper
+else
+LOCAL_LIBS += -lsncfg
+endif
+
+
+SOURCES = $(wildcard util/*.cpp *.cpp ecall/*.cpp ecall/gost/*.cpp ecall/gost/utils/*.cpp ecall/gost/sslp/*.cpp ecall/gost/sslp/auth/*.cpp ecall/gost/sslp/firmware/*.cpp ecall/gost/sslp/commands/*.cpp ecall/gost/sslp/ecall/*.cpp ecall/gost/sslp/teledata/*.cpp data/*.cpp  em/rfdesense/*.cpp em/networkinfo/*.cpp em/*.cpp sms/*.cpp sms/gsm/*.cpp sms/cdma/*.cpp atci/*.cpp stateManager/*.cpp)
+
+EXECUTABLE = liblynq-tele-ril.so
+
+OBJECTS=$(SOURCES:.cpp=.o)
+
+
+.PHONY: build clean install pack_rootfs 
+
+all: build
+
+$(EXECUTABLE): $(OBJECTS)
+	$(CXX) -shared -Wl,--no-undefined $(OBJECTS) $(LOCAL_LIBS) $(LOCAL_CFLAGS) $(LOCAL_C_INCLUDES) -o $@
+
+%.o : %.cpp
+	$(CXX) $(LOCAL_C_INCLUDES) $(LOCAL_CFLAGS) $(LOCAL_LIBS) -o $@ -c $<
+
+build:  $(EXECUTABLE)
+	$(warning ########## build $(EXECUTABLE)  ##########)
+
+install:
+	mkdir -p $(ROOT)$(base_libdir)/
+	install $(EXECUTABLE) $(ROOT)$(base_libdir)/
+	mkdir -p $(ROOT)$(includedir)/$(NAME)/sdk
+
+pack_rootfs:
+	mkdir -p $(PACK_INITRAMFS_TO)$(base_libdir)/
+	cp -af $(EXECUTABLE) $(PACK_INITRAMFS_TO)$(base_libdir)/
+	$(CROSS)strip $(PACK_INITRAMFS_TO)$(base_libdir)/$(EXECUTABLE)
+	mkdir -p $(PACK_TO)$(base_libdir)/
+	cp -af $(EXECUTABLE) $(PACK_TO)$(base_libdir)/
+	$(CROSS)strip $(PACK_TO)$(base_libdir)/$(EXECUTABLE)
+
+.PHONY: clean
+clean:
+	$(RM) $(OBJECTS) $(EXECUTABLE)
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/mtk_ril_commands.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/mtk_ril_commands.h
new file mode 100644
index 0000000..f514bce
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/mtk_ril_commands.h
@@ -0,0 +1,100 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+{ RIL_REQUEST_SET_TRM, dispatchInts, responseVoid},
+{ RIL_REQUEST_SET_IMS_ENABLE,dispatchInts,responseVoid},
+//eCall
+#ifdef ECALL_SUPPORT
+{ RIL_REQUEST_ECALL_FAST_MAKE_ECALL,dispatchFastEcall,responseVoid},
+{ RIL_REQUEST_ECALL_SET_IVS,dispatchInts,responseVoid},
+{ RIL_REQUEST_ECALL_SET_MSD,dispatchSetMsd,responseVoid},
+{ RIL_REQUEST_ECALL_SET_PSAP,dispatchInts,responseVoid},
+{ RIL_REQUEST_ECALL_IVS_PUSH_MSD,dispatchVoid,responseVoid},
+{ RIL_REQUEST_ECALL_PSAP_PULL_MSD,dispatchVoid,responseVoid},
+{ RIL_REQUEST_ECALL_SET_TEST_NUM,dispatchEcallRecord,responseVoid},
+{ RIL_REQUEST_ECALL_SET_RECONF_NUM,dispatchEcallRecord,responseVoid},
+{ RIL_REQUEST_ECALL_MAKE_ECALL,dispatchInts,responseVoid},
+{ RIL_REQUEST_ECALL_RESET_IVS,dispatchVoid,responseVoid},
+{ RIL_REQUEST_ECALL_CTRL_SEQUENCE,dispatchStrings,responseVoid},
+{ RIL_REQUEST_ECALL_SET_PRI,dispatchInts,responseVoid},
+{ RIL_REQUEST_ECALL_SET_NAD_DEREGISTRATION_TIME,dispatchInts,responseVoid},
+{ RIL_REQUEST_ECALL_SET_REGISTRATION_STATE,dispatchInts,responseVoid},
+#endif /*ECALL_SUPPORT*/
+//cc
+{ RIL_REQUEST_HANGUP_ALL, dispatchVoid, responseVoid},
+{ RIL_REQUEST_FORCE_RELEASE_CALL, dispatchInts, responseVoid},
+{ RIL_REQUEST_EMERGENCY_DIAL,dispatchDial,responseVoid},
+{ RIL_REQUEST_SET_ECC_SERVICE_CATEGORY,dispatchInts,responseVoid},
+{ RIL_REQUEST_SET_ECC_LIST,dispatchStrings,responseVoid},
+//AT Cmd
+{ RIL_REQUEST_AT_COMMAND_WITH_PROXY,dispatchString,responseString},
+//SS Command
+{ RIL_REQUEST_SET_CLIP, dispatchInts, responseVoid},
+{ RIL_REQUEST_GET_COLP, dispatchVoid, responseInts},
+{ RIL_REQUEST_SET_COLP, dispatchInts, responseVoid},
+{ RIL_REQUEST_GET_COLR, dispatchVoid, responseInts},
+{ RIL_REQUEST_SEND_USSI, dispatchStrings, responseVoid},
+{ RIL_REQUEST_CANCEL_USSI, dispatchVoid, responseVoid},
+//IMS conference call  //need confirm
+{ RIL_REQUEST_ADD_IMS_CONFERENCE_CALL_MEMBER,dispatchStrings,responseVoid},
+{ RIL_REQUEST_REMOVE_IMS_CONFERENCE_CALL_MEMBER,dispatchStrings,responseVoid},
+{ RIL_REQUEST_CONFERENCE_DIAL,dispatchStrings,responseVoid},
+{ RIL_REQUEST_DIAL_WITH_SIP_URI,dispatchString,responseVoid},
+{ RIL_REQUEST_HOLD_CALL,dispatchInts,responseVoid},
+{ RIL_REQUEST_RESUME_CALL,dispatchInts,responseVoid},
+//MODEM
+{ RIL_REQUEST_MODEM_POWEROFF,dispatchVoid,responseVoid},
+{ RIL_REQUEST_MODEM_POWERON,dispatchVoid,responseVoid},
+//SIM
+{ RIL_REQUEST_QUERY_ICCID, dispatchVoid, responseString},
+//Keepalive
+#ifdef KEEP_ALIVE
+{ RIL_REQUEST_START_KEEPALIVE_PRO,dispatchStartKeepalivePro,responseInts},
+{ RIL_REQUEST_STOP_KEEPALIVE_PRO,dispatchInts,responseVoid},
+{RIL_REQUEST_SYNC_DATA_SETTINGS_TO_MD, dispatchInts, responseVoid },
+#endif  /*KEEP_ALIVE*/
+{RIL_REQUEST_GET_SMS_SIM_MEM_STATUS, dispatchVoid, responseSmsSimMemStatus},
+{RIL_REQUEST_SET_ECC_NUM, dispatchStrings, responseVoid },
+{RIL_REQUEST_GET_ECC_NUM, dispatchVoid, responseVoid },
+{RIL_REQUEST_SET_IMSCFG, dispatchInts, responseVoid},
+{RIL_REQUEST_REPORT_AIRPLANE_MODE, dispatchInts, responseVoid},
+{RIL_REQUEST_QUERY_AVAILABLE_NETWORKS_WITH_ACT, dispatchVoid, responseStrings },
+{RIL_REQUEST_GSM_GET_BROADCAST_LANGUAGE, dispatchVoid, responseString },
+{RIL_REQUEST_GSM_SET_BROADCAST_LANGUAGE, dispatchString, responseVoid },
+//SIM
+#ifdef TARGET_PLATFORM_MT2731
+{RIL_REQUEST_QUERY_SIM_RETRY_COUNT, dispatchVoid, responseInts },
+#endif
+{RIL_REQUEST_QUERY_EID, dispatchVoid, responseString },
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/mtk_ril_unsol_commands.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/mtk_ril_unsol_commands.h
new file mode 100644
index 0000000..de50775
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/mtk_ril_unsol_commands.h
@@ -0,0 +1,52 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+{ RIL_UNSOL_MAL_AT_INFO, responseString, WAKE_PARTIAL},
+{ RIL_UNSOL_ECONF_SRVCC_INDICATION, responseInts, WAKE_PARTIAL},
+{ RIL_UNSOL_ECONF_RESULT_INDICATION, responseStrings, WAKE_PARTIAL},
+#ifdef ECALL_SUPPORT
+{ RIL_UNSOL_ECALL_MSDHACK, responseInts, WAKE_PARTIAL},
+{ RIL_UNSOL_ECALL_INDICATIONS, responseEcallStatus, WAKE_PARTIAL},
+#endif /*ECALL_SUPPORT*/
+{RIL_UNSOL_TX_POWER, responseInts, WAKE_PARTIAL},
+{RIL_UNSOL_NETWORK_INFO, responseStrings, WAKE_PARTIAL},
+//Keepalive
+#ifdef KEEP_ALIVE
+{ RIL_UNSOL_KEEPALIVE_STATUS_PRO,responseInts, WAKE_PARTIAL},
+#endif  /*KEEP_ALIVE*/
+{RIL_UNSOL_ON_USSI, responseStrings, WAKE_PARTIAL},
+{ RIL_UNSOL_ECC_NUM,responseString, WAKE_PARTIAL},
+{RIL_UNSOL_SIP_CALL_PROGRESS_INDICATOR, responseStrings, WAKE_PARTIAL},
+{RIL_UNSOL_CALL_INFO_INDICATION, responseStrings, WAKE_PARTIAL},
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/network.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/network.cpp
new file mode 100644
index 0000000..639f4c6
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/network.cpp
@@ -0,0 +1,420 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include <alloca.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <cutils/jstring.h>
+#include <log/log.h>
+
+#include "common.h"
+#include "network.h"
+
+#undef LOG_TAG
+#define LOG_TAG "DEMO_NETWORK"
+
+//if signal_strength_printf isn't 0, open signal strength printf log.
+//otherwise close.
+int signal_strength_printf = 0;
+
+int getSignalStrength (int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    android::Parcel p;
+
+    if(1 != argc)
+    {
+        free(pRI);
+        RLOGD("getSignalStrength param num should be 0");
+        return 0;
+    }
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+int getOperator (int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    android::Parcel p;
+
+    if (1 != argc) {
+        free(pRI);
+        RLOGD("getOperator param num should be 0");
+        return 0;
+    }
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+int getNetworkSelectionMode (int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    android::Parcel p;
+
+    if (1 != argc) {
+        free(pRI);
+        RLOGD("getNetworkSelectionMode param num should be 0");
+        return 0;
+    }
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+int setNetworkSelectionModeAutomatic (int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    android::Parcel p;
+
+    if (1 != argc) {
+        free(pRI);
+        RLOGD("setNetworkSelectionModeAutomatic param num should be 0");
+        return 0;
+    }
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+int setNetworkSelectionModeManual(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    android::Parcel p;
+    size_t pos =  p.dataPosition();
+
+    writeStringToParcel(p, (const char *)argv[1]);
+
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+int getAvailableNetworks (int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    android::Parcel p;
+
+    if (1 != argc) {
+        free(pRI);
+        RLOGD("getAvailableNetworks param num should be 0");
+        return 0;
+    }
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+int getVoiceRegistrationState (int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    android::Parcel p;
+
+    if (1 != argc) {
+        free(pRI);
+        RLOGD("getVoiceRegistrationState param num should be 0");
+        return 0;
+    }
+
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+int getDataRegistrationState (int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    android::Parcel p;
+
+    if(1 != argc)
+    {
+        free(pRI);
+        RLOGD("getVoiceRegistrationState param num should be 0");
+        return -1;
+    }
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+int getImsRegistrationState (int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    android::Parcel p;
+
+    if(1 != argc)
+    {
+        free(pRI);
+        RLOGD("getImsRegistrationState param num should be 0");
+        return -1;
+    }
+
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+int getPreferredNetworkType (int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    android::Parcel p;
+
+    if(1 != argc)
+    {
+        free(pRI);
+        RLOGD("getPreferredNetworkType param num should be 0");
+        return 0;
+        //TBD check;
+    }
+
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+int setPreferredNetworkType(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    android::Parcel p;
+    size_t pos =  p.dataPosition();
+    p.writeInt32(1);
+    p.writeInt32(atoi(argv[1]));
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+    update_preferred_network_type(atoi(argv[1]), socket_id);
+    return 0;
+}
+
+int setLocationUpdates(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    android::Parcel p;
+    size_t pos =  p.dataPosition();
+    p.writeInt32(1);
+    p.writeInt32(atoi(argv[1])? 1 : 0);
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+int getCellInfoList (int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    android::Parcel p;
+
+    if (1 != argc) {
+        free(pRI);
+        RLOGD("getCellInfoList param num should be 0");
+        return 0;
+    }
+
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+int setCellInfoListRate(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    android::Parcel p;
+    size_t pos =  p.dataPosition();
+    p.writeInt32(1);
+    p.writeInt32(atoi(argv[1]));
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+int getNeighboringCids (int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    android::Parcel p;
+
+    if (1 != argc) {
+        free(pRI);
+        RLOGD("getNeighboringCids param num should be 0");
+        return 0;
+    }
+
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+int setBandMode (int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    android::Parcel p;
+    size_t pos =  p.dataPosition();
+    p.writeInt32(1);
+    p.writeInt32(atoi(argv[1]));
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+int queryAvailableBandMode (int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    android::Parcel p;
+
+    if (1 != argc) {
+        free(pRI);
+        RLOGD("queryAvailableBandMode param num should be 0");
+        return 0;
+    }
+
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+int setRadioPower (int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    android::Parcel p;
+    size_t pos =  p.dataPosition();
+    p.writeInt32(1);
+    p.writeInt32(atoi(argv[1])? 1 : 0);
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+int getVoiceRadioTechnology (int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    android::Parcel p;
+
+    if (1 != argc) {
+        free(pRI);
+        RLOGD("getNeighboringCids param num should be 0");
+        return 0;
+    }
+
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+//RIL_REQUEST_SET_RADIO_CAPABILITY
+int setRadioCapability(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    if(7 != argc)
+    {
+        RLOGD("setRadioCapability param should be lost!");
+        return 0;
+    }
+    android::Parcel p;
+    size_t pos =  p.dataPosition();
+
+    //version
+    p.writeInt32(atoi(argv[1]));
+    //session
+    p.writeInt32(atoi(argv[2]));
+    //phase
+    p.writeInt32(atoi(argv[3]));
+    //rat
+    p.writeInt32(atoi(argv[4]));
+    //logicalModemUuid
+    writeStringToParcel(p,(const char *) argv[5]);
+    //status
+    p.writeInt32(atoi(argv[6]));
+
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+//RIL_REQUEST_GET_RADIO_CAPABILITY
+int getRadioCapability(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+
+    if(1 != argc)
+    {
+        free(pRI);
+        RLOGD("getRadioCapability param num should be 0");
+        return 0;
+    }
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+int updateSignalPrintf(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    signal_strength_printf=atoi(argv[1]);
+    printf("\nthe signal strength printf log will %s\n", signal_strength_printf == 0 ? "close" : "open");
+    free(pRI);
+}
+//RIL_REQUEST_MODEM_POWEROFF
+int setModemPowerOFF (int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    android::Parcel p;
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+//RIL_REQUEST_MODEM_POWERON
+int setModemPowerON (int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    android::Parcel p;
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+//RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION
+int supplyNetworkDepersonalization(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if(argc != 2)
+    {
+        free(pRI);
+        RLOGD("the peremeters numbers isn't right , so return");
+        return -1;
+    }
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    p.writeInt32(1);
+    writeStringToParcel(p, argv[1]);
+    p.setDataPosition(pos);
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+//RIL_REQUEST_REPORT_AIRPLANE_MODE
+int setReportAirplaneMode(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if(argc != 2) {
+      RLOGW("parameter is invalid");
+      free(pRI);
+      return 0;
+    }
+
+    int state = (atoi(argv[1])!= 0) ? 1 : 0;
+
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    p.writeInt32(1);
+    p.writeInt32(state);
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+//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
+*
+*((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”
+*((const char **)response)[n+4] is lac
+*((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;
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/network.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/network.h
new file mode 100644
index 0000000..19387fd
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/network.h
@@ -0,0 +1,71 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#ifndef __RIL_NETWORK__
+#define __RIL_NETWORK__
+#include  <vendor-ril/telephony/ril.h>
+#include  "common.h"
+
+extern int signal_strength_printf;
+int getSignalStrength(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int getOperator(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int getNetworkSelectionMode(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setNetworkSelectionModeAutomatic(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setNetworkSelectionModeManual(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int getAvailableNetworks(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int getVoiceRegistrationState(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int getDataRegistrationState (int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int getImsRegistrationState (int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int getPreferredNetworkType (int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setPreferredNetworkType(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setLocationUpdates(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int getCellInfoList (int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setCellInfoListRate(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int getNeighboringCids (int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setBandMode (int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int queryAvailableBandMode (int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setRadioPower (int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int getVoiceRadioTechnology (int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setRadioCapability(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int getRadioCapability(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int updateSignalPrintf(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setModemPowerOFF(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setModemPowerON (int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int supplyNetworkDepersonalization(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setReportAirplaneMode(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int getAvailableNetworksWithAct(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+#endif
+
+
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/powerManager.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/powerManager.cpp
new file mode 100644
index 0000000..efa8f6d
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/powerManager.cpp
@@ -0,0 +1,506 @@
+/*
+* 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) 2017. 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.
+*/
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <log/log.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string>
+#include <vector>
+#include <sys/time.h>
+#include <sys/select.h>
+#include <vector>
+#include <deque>
+#include <iterator>
+#include <algorithm>
+
+#include "common.h"
+#include "powerManager.h"
+#include "util/utils.h"
+#include "stateManager/stateManager.h"
+#include  <vendor-ril/telephony/ril.h>
+
+#undef DEMOAPP_SOCKET_NAME
+#define DEMOAPP_SOCKET_NAME "/tmp/socket-demoapp"
+#define SOCKET_BUF_SIZE 1024
+#define MAX_CLIENT_SIZE 30
+#undef LOG_TAG
+#define LOG_TAG "DEMO_powermanager"
+int cli_socket[MAX_CLIENT_SIZE];
+std::vector<int> keepalive_start;
+std::vector<int> Keepalive_stop;
+
+//global variable
+static pthread_mutex_t s_WakeupMutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t s_WakeupCond = PTHREAD_COND_INITIALIZER;
+//marco define
+#define LIST_LOCK()  pthread_mutex_lock(&s_WakeupMutex)
+#define LIST_UNLOCK() pthread_mutex_unlock(&s_WakeupMutex)
+#define WAITLIST() pthread_cond_wait(&s_WakeupCond,&s_WakeupMutex)
+#define WAKEUPLIST() pthread_cond_signal(&s_WakeupCond)
+#define WAKEUPREASONPATH "/sys/power/spm/wakeup_reason"
+//#define WAKEUPSTATUS "/sys/power/suspend_status"
+
+static std::deque<std::string> wakeup_reasons;
+
+std::string read_wakeup_reason() {
+    if(access(WAKEUPREASONPATH, R_OK) == -1) {
+        RLOGD("read_wakeup_reason, %s cann't read(%s),just return", WAKEUPREASONPATH, strerror(errno));
+        return "";
+    }
+
+    int fd;
+    fd = open(WAKEUPREASONPATH , O_RDONLY);
+    if(fd == -1) {
+        RLOGD("read_wakeup_reason, open %s fail(%s),just return", WAKEUPREASONPATH, strerror(errno));
+        return "";
+    }
+
+    ssize_t len;
+    char buf[50]={0};
+    std::string reason("");
+    len = read(fd, buf,sizeof(buf) -1);
+    if(len == -1) {
+        RLOGD("read_wakeup_reason, read %s fail(%s),just return", WAKEUPREASONPATH, strerror(errno));
+        reason="";
+        goto fail;
+    }
+    RLOGD("read_wakeup_reason is %s", buf);
+    reason = buf;
+fail:
+    close(fd);
+    return reason;
+}
+
+void write_wakeup_reason(std::string reason) {
+    int fd;
+    ssize_t len;
+    if(reason.empty()) {
+        RLOGD("write_wakeup_reason is empty, just return");
+        return;
+    }
+    std::string save = read_wakeup_reason();
+    if(save == reason) {
+        RLOGD("write_wakeup_reason is same, just return");
+//        return; //don't need return, handle initial reason equal to first write reason.
+    }
+    RLOGD("write_wakeup_reason: %s", reason.c_str());
+    if(access(WAKEUPREASONPATH, W_OK) == -1) {
+        RLOGD("write_wakeup_reason, %s cann't write(%s), just return", WAKEUPREASONPATH, strerror(errno));
+        return ;
+    }
+    fd = open(WAKEUPREASONPATH , O_WRONLY);
+    if(fd == -1) {
+        RLOGD("write_wakeup_reason, open %s fail(%s), just return", WAKEUPREASONPATH,strerror(errno));
+        return ;
+    }
+    len = write(fd, reason.c_str(), reason.size());
+    if(len == -1) {
+        RLOGD("write_wakeup_reason, write %s fail(%s)", WAKEUPREASONPATH,strerror(errno));
+    }
+    close(fd);
+}
+
+void *wakeup_reason_loop(void *param)
+{
+    std::string reason("");
+    RLOGD("wakeup_reason_loop start");
+
+    prctl(PR_SET_NAME,(unsigned long)"demo_wakeup_reason_loop");
+
+    LIST_LOCK();
+    wakeup_reasons.clear();
+    LIST_UNLOCK();
+
+    for(;;){
+
+        LIST_LOCK();
+        if(wakeup_reasons.empty()) {    //if blank list  then wait
+            RLOGD("wakeup reason list is empty ,then wait!");
+            while(wakeup_reasons.empty()){
+                WAITLIST();
+            }
+        }
+        reason = wakeup_reasons.front();
+        wakeup_reasons.pop_front();
+        LIST_UNLOCK();
+        write_wakeup_reason(reason);
+    }
+    return 0;
+}
+
+void handle_wakeup_reason(int requestCode) {
+    RLOGD("handle_wakeup_reason %s:", android::requestToString(requestCode));
+    std::string reason("");
+    switch (requestCode){
+    //CCIF_CALL
+    case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:
+    case RIL_UNSOL_CALL_RING:
+    case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE:
+    case RIL_UNSOL_RINGBACK_TONE:
+    case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE:
+    case RIL_UNSOL_SRVCC_STATE_NOTIFY:
+    case RIL_UNSOL_ECONF_SRVCC_INDICATION:
+    case RIL_UNSOL_ECONF_RESULT_INDICATION:
+    case RIL_UNSOL_CRSS_NOTIFICATION:
+    case RIL_UNSOL_INCOMING_CALL_INDICATION:
+    case RIL_UNSOL_CALL_INFO_INDICATION:
+    case RIL_UNSOL_SUPP_SVC_NOTIFICATION:
+    {
+        reason = "CCIF_CALL";
+        break;
+    }
+    //CCIF_NW
+    case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED:
+    case RIL_UNSOL_NITZ_TIME_RECEIVED:
+    case RIL_UNSOL_SIGNAL_STRENGTH:
+    case RIL_UNSOL_RESTRICTED_STATE_CHANGED:
+    case RIL_UNSOL_CELL_INFO_LIST:
+    case RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED:
+    {
+        reason = "CCIF_NW";
+        break;
+    }
+    //CCIF_Message
+    case RIL_UNSOL_RESPONSE_NEW_SMS:
+    case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT:
+    case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM:
+    case RIL_UNSOL_SIM_SMS_STORAGE_FULL:
+    case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS:
+    case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS:
+    case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL:
+    case RIL_UNSOL_SMS_READY_NOTIFICATION:
+    case RIL_UNSOL_ON_USSD:
+    {
+        reason = "CCIF_MESSAGE";
+        break;
+    }
+    //CCIF_Other
+    case RIL_UNSOL_DATA_CALL_LIST_CHANGED:
+    case RIL_UNSOL_ECALL_MSDHACK:
+    case RIL_UNSOL_SIM_REFRESH:
+    case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED:
+    case RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED:
+    case RIL_UNSOL_STK_SESSION_END:
+    case RIL_UNSOL_STK_PROACTIVE_COMMAND:
+    case RIL_UNSOL_STK_EVENT_NOTIFY:
+    case RIL_UNSOL_STK_CALL_SETUP:
+    case RIL_UNSOL_STK_BIP_PROACTIVE_COMMAND:
+    case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
+    case RIL_UNSOL_RIL_CONNECTED:
+    case RIL_UNSOL_RADIO_CAPABILITY:
+    {
+        reason = "CCIF_OTHER";
+        break;
+    }
+    default:
+        RLOGD("handle_wakeup_reason no wakeup reason, just return");
+        return;
+    }
+    if(reason.empty()) {
+        RLOGE("handle_wakeup_reason error , reason is empty, return");
+        return;
+    }
+    LIST_LOCK();
+    wakeup_reasons.push_back(reason);
+    WAKEUPLIST();
+    LIST_UNLOCK();
+}
+
+int demo_open_socket(const char *path)
+{
+    RLOGD("demo_open_socket");
+    int sd;
+    int res;
+    struct sockaddr_un addr;
+
+    sd = socket(AF_UNIX, SOCK_STREAM, 0);
+    if (sd < 0) {
+        RLOGE("socket error: %s", strerror(errno));
+        return sd;
+    }
+
+    if(remove(path) == -1 && errno != ENOENT)
+    {
+        RLOGD("remove-%s, remove error: %s", path, strerror(errno));
+    }
+
+    memset(&addr, 0, sizeof(struct sockaddr_un));
+    addr.sun_family = AF_UNIX;
+    strncpy(addr.sun_path, path, sizeof(addr.sun_path)-1);
+
+    res = bind(sd, (struct sockaddr*)&addr, sizeof(struct sockaddr_un));
+    if (res != 0) {
+        RLOGE("bind error: %s\n", strerror(errno));
+        goto error;
+    }
+
+    res = listen(sd, 8);
+    if (res != 0) {
+        RLOGE("listen error: %s\n", strerror(errno));
+        goto error;
+    }
+    return sd;
+error:
+    if (sd >=0)
+        close(sd);
+    return -1;
+}
+
+int send_data(int sockfd, const char *buf, int len) {
+    int ret = 0;
+    int cur_pos = 0;
+
+    if (sockfd <= 0)
+        return 0;
+
+    while(cur_pos < len) {
+        ret = send(sockfd, &buf[cur_pos], len - cur_pos, MSG_DONTWAIT);
+        if (ret == len - cur_pos)
+            break;
+
+        if (ret <= 0) {
+            RLOGE("SOCKET ERROR errno:%d,%s", errno, strerror(errno));
+            if (errno == EAGAIN || errno == EINTR)
+            {
+                RLOGD("send to internet buffer full, wait(10ms)");
+                usleep(10000);
+                continue;
+            }
+            if (errno == ECONNRESET || errno == EPIPE)
+            {
+                sockfd = -1;
+                RLOGD("buffer client connect is reset");
+            }
+            break;
+        } else
+            cur_pos += ret;
+    }
+
+    return ret;
+}
+
+void sendSmsMsg(RIL_SOCKET_ID soc_id)
+{
+    char *msg = "sms_on";
+    for (int i = 0 ; i < MAX_CLIENT_SIZE; i++) {
+        if(cli_socket[i] > 0 ) {
+            auto it_start = std::find(keepalive_start.begin(), keepalive_start.end(), cli_socket[i]);
+            auto it_stop = std::find(Keepalive_stop.begin(), Keepalive_stop.end(), cli_socket[i]);
+            if(it_start == std::end(keepalive_start) && it_stop == std::end(Keepalive_stop)) {
+                RLOGD("sendSmsMsg(%d): %s", cli_socket[i], msg);
+                send_data(cli_socket[i], msg, strlen(msg));
+            }
+        }
+    }
+}
+
+void sendCallMsg(bool call_on)
+{
+    char* on = "call_on";
+    char* off = "call_off";
+    char *msg = call_on ? on : off;
+    for (int i = 0 ; i < MAX_CLIENT_SIZE; i++) {
+        if(cli_socket[i] > 0 ) {
+            auto it_start = std::find(keepalive_start.begin(), keepalive_start.end(), cli_socket[i]);
+            auto it_stop = std::find(Keepalive_stop.begin(), Keepalive_stop.end(), cli_socket[i]);
+            if(it_start == std::end(keepalive_start) && it_stop == std::end(Keepalive_stop)) {
+                RLOGD("sendSmsMsg(%d): %s", cli_socket[i], msg);
+                send_data(cli_socket[i], msg, strlen(msg));
+            }
+        }
+    }
+}
+
+void sendKeepAlive(const char* msg)
+{
+    std::string str(msg);
+    if (str.find("RIL_REQUEST_START_KEEPALIVE_PRO") != std::string::npos) {
+        for (auto it : keepalive_start) {
+            RLOGD("sendKeepAlive response(RIL_REQUEST_START_KEEPALIVE_PRO(%d)): %s",it, msg);
+            send_data(it, msg, strlen(msg));
+        }
+    }
+
+    if (str.find("RIL_REQUEST_STOP_KEEPALIVE_PRO") != std::string::npos) {
+        for (auto it : Keepalive_stop) {
+            RLOGD("sendKeepAlive response(RIL_REQUEST_STOP_KEEPALIVE_PRO(%d)): %s", it, msg);
+            send_data(it, msg, strlen(msg));
+        }
+    }
+
+    if (str.find("RIL_UNSOL_KEEPALIVE_STATUS_PRO") != std::string::npos) {
+        for (auto it : keepalive_start) {
+            RLOGD("sendKeepAlive notify((start)RIL_UNSOL_KEEPALIVE_STATUS_PRO(%d)): %s", it, msg);
+            send_data(it, msg, strlen(msg));
+        }
+        for (auto it : Keepalive_stop) {
+            RLOGD("sendKeepAlive notify((stop)RIL_UNSOL_KEEPALIVE_STATUS_PRO(%d)): %s", it, msg);
+            send_data(it, msg, strlen(msg));
+        }
+    }
+}
+
+#define SOCKET_ZERO   0
+#define SOCKET_SUCC   1
+#define SOCKET_FAIL  -1
+
+void dispatch_cmd(int fd, char* msg) {
+    RLOGD("dispatch_cmd: %s", msg);
+    std::vector<std::string> v;
+    utils::tokenize(std::string(msg),',',v);
+    int i = 0;
+    for(auto s: v) {
+        RLOGD("%d:%s",i, s.c_str());
+        i++;
+    }
+    if(v.size() != 10 && v.size() != 2) {
+        RLOGE("transfer parameters num is wrong: %d", v.size());
+        return ;
+    }
+    int id = get_default_sim_data();
+    if(v[0] == std::string("RIL_REQUEST_START_KEEPALIVE_PRO")) {
+        keepalive_start.push_back(fd);
+        RLOGD("[SIM%d]start keepalive", id);
+        RequestInfo *info = creatRILInfoAndInit(RIL_REQUEST_START_KEEPALIVE_PRO, OTHER, (RIL_SOCKET_ID)id);
+        char* argv[10] = {0};
+        for(int i=0; i< v.size() && i < 10; i++){
+            argv[i] = const_cast<char*>(v[i].c_str());
+        }
+        startKeepAlivePro(v.size(), argv, (RIL_SOCKET_ID)id, info);
+    } else if(v[0] == std::string("RIL_REQUEST_STOP_KEEPALIVE_PRO")) {
+        Keepalive_stop.push_back(fd);
+        RLOGD("[SIM%d]stop keepalive", id);
+        RequestInfo *info = creatRILInfoAndInit(RIL_REQUEST_STOP_KEEPALIVE_PRO, OTHER, (RIL_SOCKET_ID)id);
+        char* argv[2] = {0};
+        for(int i=0; i< v.size() && i < 2; i++){
+            argv[i] = const_cast<char*>(v[i].c_str());
+        }
+        stopKeepAlivePro(v.size(), argv, (RIL_SOCKET_ID)id, info);
+    } else {
+        RLOGD("dispatch_cmd(%s) error", v[0].c_str());
+    }
+}
+
+void eraseSocket(std::vector<int> &v, int sd) {
+    auto it = std::find(v.begin(), v.end(), sd);
+    if (it != std::end(v)) {
+        v.erase(it);
+    }
+}
+
+void *StartPMSocket(void *param)
+{
+    RLOGD("StartPMSocket start");
+    char buf[SOCKET_BUF_SIZE] = {0};
+    int max_fd;
+    fd_set readfds;
+    for (int i=0; i < MAX_CLIENT_SIZE; i++) {
+        cli_socket[i] = 0;
+    }
+    int ssd = -1;
+    struct sockaddr_un addr;
+    socklen_t socke_len;
+
+    ssd = demo_open_socket(DEMOAPP_SOCKET_NAME);
+    if(ssd < 0)
+    {
+        RLOGE("ssd < 0, just return");
+        return NULL;
+    }
+
+    while (true) {
+        FD_ZERO(&readfds);
+        FD_SET(ssd, &readfds);
+        max_fd = ssd;
+        for(int i = 0; i < MAX_CLIENT_SIZE; i++) {
+            int sd = cli_socket[i];
+            if(sd > 0) {
+                FD_SET(sd, &readfds);
+            }
+            if(sd > max_fd) {
+                max_fd = sd;
+            }
+        }
+        int act_fd_num = select(max_fd +1, &readfds, NULL, NULL, NULL);
+        if(act_fd_num < 0 && (errno != EINTR)) {
+            RLOGE("select error");
+        }
+        if(FD_ISSET(ssd, &readfds)) {
+            int cli_soc = accept(ssd, (struct sockaddr*)&addr, &socke_len);
+            if (cli_soc < 0)
+            {
+                RLOGE("accept error: %s", strerror(errno));
+                close(cli_soc);
+                return NULL;
+            }
+            RLOGD("Accept a client , client id is %d", cli_soc);
+            //TBD send sometings.
+            for(int i = 0; i < MAX_CLIENT_SIZE; i++) {
+                if(cli_socket[i] == 0) {
+                    cli_socket[i] = cli_soc;
+                    RLOGD("add new socket %d", cli_soc);
+                    break;
+                }
+            }
+        }
+        for(int i = 0; i < MAX_CLIENT_SIZE; i++) {
+            int sd = cli_socket[i];
+            if(FD_ISSET(sd, &readfds)) {
+                memset(buf, 0, sizeof(buf));
+                int ret = recv(sd, buf,SOCKET_BUF_SIZE, 0);
+                if (ret < 0) {
+                    RLOGE("data_recv select error, ret=%d, error=%s(%d),fd=%d", ret, strerror(errno), errno, sd);
+                } else if (ret == SOCKET_ZERO) {
+                    RLOGE("data_recv recv error, maybe client socket closed, ret=%d, error=%s(%d),fd=%d", ret, strerror(errno), errno, sd);
+                    close(sd);
+                    cli_socket[i] = 0;
+                    eraseSocket(keepalive_start,sd);
+                    eraseSocket(Keepalive_stop,sd);
+                } else {
+                    buf[ret] = '\0';
+                    dispatch_cmd(sd, buf);
+                }
+            }
+        }
+    }
+    RLOGD("start PowerManager Done");
+    return 0;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/powerManager.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/powerManager.h
new file mode 100644
index 0000000..c54d61d
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/powerManager.h
@@ -0,0 +1,49 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef __POWERMANAGER__
+#define __POWERMANAGER__
+
+void *StartPMSocket(void *param);
+void sendCallMsg(bool call_on);
+void sendSmsMsg(RIL_SOCKET_ID soc_id);
+void handle_wakeup_reason(int requestCode);
+void *wakeup_reason_loop(void *param);
+
+#ifdef KEEP_ALIVE
+void sendKeepAlive(const char* msg);
+#endif /*KEEP_ALIVE*/
+
+#endif
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/resp_timeout.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/resp_timeout.cpp
new file mode 100644
index 0000000..f93a65e
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/resp_timeout.cpp
@@ -0,0 +1,103 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include <glib.h>
+#include <vendor-ril/telephony/ril.h>
+#include <stdio.h>
+#include <log/log.h>
+
+#undef LOG_TAG
+#define LOG_TAG "DEMO_RESP_TIMEOUT"
+
+static GSource *g_resp_source[2];
+static GMutex mutex;
+static bool tag[2] = {false,false};
+static char* name[2] = {"one_minutes_timesout_0","ont_minutes_timesout_1"};
+
+extern void ARspRequest (int request, RIL_SOCKET_ID socket_id);
+
+static gboolean resp_cb(gpointer data) {
+  RLOGD("execute response command: RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM");
+  ARspRequest(RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM, (RIL_SOCKET_ID)(GPOINTER_TO_INT (data)));
+  return G_SOURCE_REMOVE;
+}
+
+static gpointer start_timeout_func(gpointer data) {
+  RLOGD("start_timeout_func");
+  GMainContext *ctx;
+  GMainLoop *loop;
+
+  ctx = g_main_context_new ();
+  loop = g_main_loop_new (ctx, FALSE);
+  int slot = GPOINTER_TO_INT(data);
+  g_resp_source[slot] = g_timeout_source_new (1000*60); //one minutes
+  g_source_set_callback (g_resp_source[slot], resp_cb, data, NULL);
+  g_source_attach (g_resp_source[slot], ctx);
+  g_source_unref (g_resp_source[slot]);
+
+  g_main_loop_run (loop);
+
+  RLOGD("release loop and context");
+  g_main_loop_unref (loop);
+  g_main_context_unref (ctx);
+  return NULL;
+}
+
+void setup_timeout(int slot_id) {
+  RLOGD("setup_timeout");
+  g_mutex_lock(&mutex);
+  gpointer result;
+  GThread *thread;
+  GError *error = NULL;
+
+  thread = g_thread_try_new (name[slot_id], start_timeout_func, GINT_TO_POINTER (slot_id), &error);
+  tag[slot_id] = true;
+  g_mutex_unlock(&mutex);
+  g_thread_unref (thread);
+}
+
+void clear_timeout(int slot_id) {
+  RLOGD("stop timeout configuration");
+  g_mutex_lock(&mutex);
+  if (tag[slot_id])
+  {
+    tag[slot_id] = false;
+    if (!g_source_is_destroyed(g_resp_source[slot_id]))
+    {
+      g_source_destroy(g_resp_source[slot_id]);
+    }
+  }
+  g_mutex_unlock(&mutex);
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/resp_timeout.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/resp_timeout.h
new file mode 100644
index 0000000..31b30bf
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/resp_timeout.h
@@ -0,0 +1,42 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef TEL_DEMO_SRC_RESP_TIMEOUT_H_
+#define TEL_DEMO_SRC_RESP_TIMEOUT_H_
+
+void setup_timeout(int slot_id);
+void clear_timeout(int slot_id);
+
+#endif /* TEL_DEMO_SRC_RESP_TIMEOUT_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ril.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ril.cpp
new file mode 100644
index 0000000..8358333
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ril.cpp
@@ -0,0 +1,6357 @@
+/*
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+#include<sys/types.h>
+#include<sys/socket.h>
+#include<unistd.h>
+#include<netinet/in.h>
+#include<arpa/inet.h>
+#include<netdb.h>
+#include<signal.h>
+#include <log/log.h>
+#include <hardware_legacy/power.h>
+#include <vendor-ril/telephony/ril.h>
+#include <telephony/ril_cdma_sms.h>
+#include <cutils/jstring.h>
+#include <telephony/record_stream.h>
+#include <utils/SystemClock.h>
+#include <pthread.h>
+#include <binder/Parcel.h>
+#include <cutils/jstring.h>
+#include <sys/types.h>
+#include <limits.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <time.h>
+#include <errno.h>
+#include <assert.h>
+#include <ctype.h>
+#include <alloca.h>
+#include <sys/un.h>
+#include <assert.h>
+#include <netinet/in.h>
+#include <atomic>
+
+#include "utils/String8.h"
+#include "ss.h"
+#include "sim.h"
+#include "common.h"
+#include "cc.h"
+#include "network.h"
+#include "stk.h"
+#include "utils.h"
+
+#include "atci/ATCI.h"
+#include "data/data.h"
+#include "data/data_gdbus.h"
+#include "ecall/eCall.h"
+#include "em/em.h"
+#include "sms/sms.h"
+#include "sms/cdma/sms_pdu_cdma.h"
+#include "stateManager/stateManager.h"
+#include "Phone_utils.h"
+#include "utils.h"
+#include "Radio_capability_switch_util.h"
+
+#define LOG_TAG "DEMO_RIL"
+
+lynqQueue * LynqQueueHead=NULL;
+
+extern void ARspRequest (int request, RIL_SOCKET_ID socket_id);
+extern void responseDispatch();
+extern void intRspList();
+user_cb * s_Env=NULL;
+
+namespace android {
+extern "C" void
+RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen);
+
+#define SERVER_PORT 8000
+#define BUFFER_SIZE 8192
+#define MAX_ARGS 101
+#define BLOCK_LOCK() pthread_mutex_lock(&s_BlockMutex)
+#define BLOCK_UNLOCK() pthread_mutex_unlock(&s_BlockMutex)
+#define BLOCK_WAIT(a) pthread_cond_timedwait(&s_BlockCond, &s_BlockMutex,(a))
+#define BLOCK_WAKEUP() pthread_cond_broadcast(&s_BlockCond)
+#define SPECIA_BLOCK_LOCK() pthread_mutex_lock(&s_SpecialBlock)
+#define SPECIA_BLOCK_UNLOCK() pthread_mutex_unlock(&s_SpecialBlock)
+#define SPECIA_BLOCK_WAIT(a) pthread_cond_timedwait(&s_SpeciaBlockCond, &s_SpecialBlock,(a))
+#define SPECIA_BLOCK_WAKEUP() pthread_cond_signal(&s_SpeciaBlockCond)
+
+static int s_started = 0;
+static int s_responseDispatch = 0;
+static int s_isConnected[2] = {0,0}; //connect to modem;
+static pthread_mutex_t s_InitMutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t s_InitCond = PTHREAD_COND_INITIALIZER;
+
+static pthread_mutex_t s_BlockMutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t s_BlockCond = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t s_SpecialBlock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t s_SpeciaBlockCond = PTHREAD_COND_INITIALIZER;
+
+int requestOneByOne = 0;
+int server_socket_fd;
+int enable_syslog = 1;
+int enable_bt_resp = 0;
+int wakeup_token = -1;
+struct sockaddr_in client_addr;
+
+#define ANDROID_WAKE_LOCK_NAME "radio-interface"
+
+// Basically: memset buffers that the client library
+// shouldn't be using anymore in an attempt to find
+// memory usage issues sooner.
+#define MEMSET_FREED 1
+
+#define NUM_ELEMS(a)     (sizeof (a) / sizeof (a)[0])
+
+#define MIN(a,b) ((a)<(b) ? (a) : (b))
+
+/* Constants for response types */
+#define RESPONSE_SOLICITED 0
+#define RESPONSE_UNSOLICITED 1
+
+/* Negative values for private RIL errno's */
+#define RIL_ERRNO_INVALID_RESPONSE -1
+
+// request, response, and unsolicited msg print macro
+#define PRINTBUF_SIZE 8096
+
+// Enable verbose logging
+#define VDBG 0
+
+// Enable RILC log
+#define RILC_LOG 1
+
+#define BUF_LEN 2048
+
+#if RILC_LOG
+    static char printBuf[PRINTBUF_SIZE];
+    static char tempPrintBuf[PRINTBUF_SIZE];
+    #define startRequest           sprintf(printBuf, "(")
+    #define closeRequest           sprintf(printBuf, "%s)", printBuf)
+    #define printRequest(token, req) if(enable_syslog) {         \
+        RLOGD("[%x]> %s %s", token, requestToString(req), printBuf);} else {\
+        printf("[%x]> %s %s\n", token, requestToString(req), printBuf);}
+
+    #define startResponse           sprintf(printBuf, "%s {", printBuf)
+    #define closeResponse           sprintf(printBuf, "%s}", printBuf)
+    #define printResponse            if(enable_syslog) { \
+                                    RLOGD("%s", printBuf); } else { \
+                                    printf("%s\n", printBuf);}
+
+    #define clearPrintBuf           printBuf[0] = 0
+    #define removeLastChar          printBuf[strlen(printBuf)-1] = 0
+    #define appendPrintBuf(x...)    snprintf(tempPrintBuf, PRINTBUF_SIZE, x); \
+                                    snprintf(printBuf, PRINTBUF_SIZE, "%s", tempPrintBuf)
+#endif
+
+enum WakeType {DONT_WAKE, WAKE_PARTIAL};
+
+#if 0
+typedef struct {
+    int requestNumber;
+    void (*dispatchFunction) (Parcel &p, struct RequestInfo *pRI);
+    int(*responseFunction) (Parcel &p, void *response, size_t responselen);
+} CommandInfo;
+#endif
+
+typedef struct {
+    int requestNumber;
+    int (*responseFunction) (Parcel &p, void *response, size_t responselen);
+    WakeType wakeType;
+} UnsolResponseInfo;
+
+#if 0
+typedef struct RequestInfo {
+    int32_t token;      //this is not RIL_Token
+    CommandInfo *pCI;
+    struct RequestInfo *p_next;
+    char cancelled;
+    char local;         // responses to local commands do not go back to command process
+    RIL_SOCKET_ID socket_id;
+} RequestInfo;
+
+typedef struct UserCallbackInfo {
+    RIL_TimedCallback p_callback;
+    void *userParam;
+    struct ril_event event;
+    struct UserCallbackInfo *p_next;
+} UserCallbackInfo;
+#endif
+
+const char *requestToString(int request);
+const char * failCauseToString(RIL_Errno);
+const char * callStateToString(RIL_CallState);
+
+RIL_RadioFunctions s_callbacks = {0, NULL, NULL, NULL, NULL, NULL};
+int s_registerCalled = 0;
+
+static pthread_t s_tid_dispatch;
+
+static const struct timeval TIMEVAL_WAKE_TIMEOUT = {1,0};
+
+#if EM_MODE_SUPPORT
+netwokInfoNotify networkCb = NULL;
+atCmdResponse atResponseCb = NULL;
+#endif
+
+appResponse appResponseCb = NULL;
+appOnUnsolicitedResponse appOnUnsolicitedResponseCb = NULL;
+
+
+static pthread_mutex_t s_startupMutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t s_startupCond = PTHREAD_COND_INITIALIZER;
+static void *s_lastNITZTimeData = NULL;
+static size_t s_lastNITZTimeDataSize;
+
+/*******************************************************************/
+static int sendResponse (Parcel &p, RIL_SOCKET_ID socket_id);
+
+static void dispatchVoid (Parcel& p, RequestInfo *pRI);
+static void dispatchString (Parcel& p, RequestInfo *pRI);
+static void dispatchStrings (Parcel& p, RequestInfo *pRI);
+static void dispatchInts (Parcel& p, RequestInfo *pRI);
+static void dispatchDial (Parcel& p, RequestInfo *pRI);
+static void dispatchSIM_IO (Parcel& p, RequestInfo *pRI);
+static void dispatchSIM_APDU (Parcel& p, RequestInfo *pRI);
+static void dispatchCallForward(Parcel& p, RequestInfo *pRI);
+static void dispatchRaw(Parcel& p, RequestInfo *pRI);
+static void dispatchSmsWrite (Parcel &p, RequestInfo *pRI);
+static void dispatchDataCall (Parcel& p, RequestInfo *pRI);
+static void dispatchSetInitialAttachApn (Parcel& p, RequestInfo *pRI);;
+static void dispatchCdmaSms(Parcel &p, RequestInfo *pRI);
+static void dispatchImsSms(Parcel &p, RequestInfo *pRI);
+static void dispatchImsCdmaSms(Parcel &p, RequestInfo *pRI, uint8_t retry, int32_t messageRef);
+static void dispatchImsGsmSms(Parcel &p, RequestInfo *pRI, uint8_t retry, int32_t messageRef);
+static void dispatchCdmaSmsAck(Parcel &p, RequestInfo *pRI);
+static void dispatchGsmBrSmsCnf(Parcel &p, RequestInfo *pRI);
+static void dispatchCdmaBrSmsCnf(Parcel &p, RequestInfo *pRI);
+static void dispatchRilCdmaSmsWriteArgs(Parcel &p, RequestInfo *pRI);
+static void dispatchNVReadItem(Parcel &p, RequestInfo *pRI);
+static void dispatchNVWriteItem(Parcel &p, RequestInfo *pRI);
+static void dispatchUiccSubscripton(Parcel &p, RequestInfo *pRI);
+static void dispatchSimAuthentication(Parcel &p, RequestInfo *pRI);
+static void dispatchDataProfile(Parcel &p, RequestInfo *pRI);
+static void dispatchRadioCapability(Parcel &p, RequestInfo *pRI);
+static int responseInts(Parcel &p, void *response, size_t responselen);
+static int responseFailCause(Parcel &p, void *response, size_t responselen);
+static int responseStrings(Parcel &p, void *response, size_t responselen);
+static int responseString(Parcel &p, void *response, size_t responselen);
+static int responseVoid(Parcel &p, void *response, size_t responselen);
+static int responseCallList(Parcel &p, void *response, size_t responselen);
+static int responseSMS(Parcel &p, void *response, size_t responselen);
+static int responseSIM_IO(Parcel &p, void *response, size_t responselen);
+static int responseCallForwards(Parcel &p, void *response, size_t responselen);
+static int responseDataCallList(Parcel &p, void *response, size_t responselen);
+static int responseSetupDataCall(Parcel &p, void *response, size_t responselen);
+static int responseRaw(Parcel &p, void *response, size_t responselen);
+static int responseSsn(Parcel &p, void *response, size_t responselen);
+static int responseSimStatus(Parcel &p, void *response, size_t responselen);
+static int responseGsmBrSmsCnf(Parcel &p, void *response, size_t responselen);
+static int responseCdmaBrSmsCnf(Parcel &p, void *response, size_t responselen);
+static int responseCdmaSms(Parcel &p, void *response, size_t responselen);
+static int responseCellList(Parcel &p, void *response, size_t responselen);
+static int responseCdmaInformationRecords(Parcel &p,void *response, size_t responselen);
+static int responseRilSignalStrength(Parcel &p,void *response, size_t responselen);
+static int responseCallRing(Parcel &p, void *response, size_t responselen);
+static int responseCdmaSignalInfoRecord(Parcel &p,void *response, size_t responselen);
+static int responseCdmaCallWaiting(Parcel &p,void *response, size_t responselen);
+static int responseSimRefresh(Parcel &p, void *response, size_t responselen);
+static int responseCellInfoList(Parcel &p, void *response, size_t responselen);
+static int responseHardwareConfig(Parcel &p, void *response, size_t responselen);
+static int responseDcRtInfo(Parcel &p, void *response, size_t responselen);
+static int responseRadioCapability(Parcel &p, void *response, size_t responselen);
+static int responseSSData(Parcel &p, void *response, size_t responselen);
+static int responseLceStatus(Parcel &p, void *response, size_t responselen);
+static int responseLceData(Parcel &p, void *response, size_t responselen);
+static int responseActivityData(Parcel &p, void *response, size_t responselen);
+static int responseSmsSimMemStatus(Parcel &p, void *response, size_t responselen);
+#ifdef ECALL_SUPPORT
+static void dispatchFastEcall (Parcel& p, RequestInfo *pRI);
+static int responseEcallStatus(Parcel &p, void *response, size_t responselen);
+static void dispatchSetMsd (Parcel &p, RequestInfo *pRI);
+static void dispatchEcallRecord (Parcel &p, RequestInfo *pRI);
+#endif /*ECALL_SUPPORT*/
+#ifdef KEEP_ALIVE
+static void dispatchStartKeepalivePro(Parcel &p, RequestInfo *pRI);
+#endif /*KEEP_ALIVE*/
+static int decodeVoiceRadioTechnology (RIL_RadioState radioState);
+static int decodeCdmaSubscriptionSource (RIL_RadioState radioState);
+static RIL_RadioState processRadioState(RIL_RadioState newRadioState);
+
+static bool isServiceTypeCfQuery(RIL_SsServiceType serType, RIL_SsRequestType reqType);
+
+static int onSupports (int requestCode);
+static UnsolResponseInfo* find_mtk_unsol_command(int request);
+static int com_quit(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+static int enableSyslog(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+static int enableBTResponse(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+static void updateIccCardState(RIL_SOCKET_ID soc_id);
+static void initCoditions();
+
+static int SendRespToClient(const void *data, size_t dataSize);
+static void speciaRequest_wakeup();
+static void speciaRequest_wait();
+void processUnsolicited (Parcel &p, int type);
+void processSolicited (Parcel &p, int type);
+
+void printInputArgs(int argc, char** argv) ;
+void initRequestInfo(RequestInfo *pRI, int  request, int mode, RIL_SOCKET_ID soc_id);
+void getVoiceAndDataRegistrationState(RIL_SOCKET_ID soc_id);
+const int waitResponse(int token);
+
+#ifdef RIL_SHLIB
+#if defined(ANDROID_MULTI_SIM)
+extern "C" void RIL_onUnsolicitedResponse(int unsolResponse, const void *data,
+                                size_t datalen, RIL_SOCKET_ID socket_id);
+#else
+extern "C" void RIL_onUnsolicitedResponse(int unsolResponse, const void *data,
+                                size_t datalen);
+#endif
+#endif
+
+#if defined(ANDROID_MULTI_SIM)
+#define RIL_UNSOL_RESPONSE(a, b, c, d) RIL_onUnsolicitedResponse((a), (b), (c), (d))
+#define CALL_ONREQUEST(a, b, c, d, e) s_callbacks.onRequest((a), (b), (c), (d), (e))
+#define CALL_ONSTATEREQUEST(a) s_callbacks.onStateRequest(a)
+#else
+#define RIL_UNSOL_RESPONSE(a, b, c, d) RIL_onUnsolicitedResponse((a), (b), (c))
+#define CALL_ONREQUEST(a, b, c, d, e) s_callbacks.onRequest((a), (b), (c), (d))
+#define CALL_ONSTATEREQUEST(a) s_callbacks.onStateRequest()
+#endif
+
+
+/** Index == requestNumber */
+static CommandInfo s_commands[] = {
+#include "ril_commands.h"
+};
+
+static UnsolResponseInfo s_unsolResponses[] = {
+#include "ril_unsol_commands.h"
+};
+
+COMMAND commands[] = {
+#include "commands.h"
+};
+
+static CommandInfo mtk_s_command[] = {
+#include "mtk_ril_commands.h"
+};
+
+static UnsolResponseInfo s_mtk_unsolResponses[] = {
+#include "mtk_ril_unsol_commands.h"
+};
+
+char respStr[PRINTBUF_SIZE]={0};
+
+/* For older RILs that do not support new commands RIL_REQUEST_VOICE_RADIO_TECH and
+   RIL_UNSOL_VOICE_RADIO_TECH_CHANGED messages, decode the voice radio tech from
+   radio state message and store it. Every time there is a change in Radio State
+   check to see if voice radio tech changes and notify telephony
+ */
+int voiceRadioTech = -1;
+
+/* For older RILs that do not support new commands RIL_REQUEST_GET_CDMA_SUBSCRIPTION_SOURCE
+   and RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED messages, decode the subscription
+   source from radio state and store it. Every time there is a change in Radio State
+   check to see if subscription source changed and notify telephony
+ */
+int cdmaSubscriptionSource = -1;
+
+/* For older RILs that do not send RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, decode the
+   SIM/RUIM state from radio state and store it. Every time there is a change in Radio State,
+   check to see if SIM/RUIM status changed and notify telephony
+ */
+int simRuimStatus = -1;
+
+
+static char *
+strdupReadString(Parcel &p) {
+    size_t stringlen;
+    const char16_t *s16;
+
+    s16 = p.readString16Inplace(&stringlen);
+
+    return strndup16to8(s16, stringlen);
+}
+
+static status_t
+readStringFromParcelInplace(Parcel &p, char *str, size_t maxLen) {
+    size_t s16Len;
+    const char16_t *s16;
+
+    s16 = p.readString16Inplace(&s16Len);
+    if (s16 == NULL) {
+        return NO_MEMORY;
+    }
+    size_t strLen = strnlen16to8(s16, s16Len);
+    if ((strLen + 1) > maxLen) {
+        return NO_MEMORY;
+    }
+    if (strncpy16to8(str, s16, strLen) == NULL) {
+        return NO_MEMORY;
+    } else {
+        return NO_ERROR;
+    }
+}
+
+/*static*/ void writeStringToParcel(Parcel &p, const char *s) {
+    char16_t *s16;
+    size_t s16_len;
+    s16 = strdup8to16(s, &s16_len);
+    p.writeString16(s16, s16_len);
+    free(s16);
+}
+
+
+static void
+memsetString (char *s) {
+    if (s != NULL) {
+        memset (s, 0, strlen(s));
+    }
+}
+
+
+static void
+invalidCommandBlock (RequestInfo *pRI) {
+    RLOGE("invalid command block for token %d request %s",
+                pRI->token, requestToString(pRI->pCI->requestNumber));
+}
+
+/** Callee expects NULL */
+static void
+dispatchVoid (Parcel& p, RequestInfo *pRI) {
+    clearPrintBuf;
+    printRequest(pRI->token, pRI->pCI->requestNumber);
+    CALL_ONREQUEST(pRI->pCI->requestNumber, NULL, 0, pRI, pRI->socket_id);
+}
+
+/** Callee expects const char * */
+static void
+dispatchString (Parcel& p, RequestInfo *pRI) {
+    status_t status;
+    size_t datalen;
+    size_t stringlen;
+    char *string8 = NULL;
+
+    string8 = strdupReadString(p);
+
+    startRequest;
+    appendPrintBuf("%s%s", printBuf, string8);
+    closeRequest;
+    printRequest(pRI->token, pRI->pCI->requestNumber);
+
+    CALL_ONREQUEST(pRI->pCI->requestNumber, string8,
+                       sizeof(char *), pRI, pRI->socket_id);
+
+#ifdef MEMSET_FREED
+    memsetString(string8);
+#endif
+
+    free(string8);
+    return;
+invalid:
+    invalidCommandBlock(pRI);
+    return;
+}
+
+/** Callee expects const char ** */
+static void
+dispatchStrings (Parcel &p, RequestInfo *pRI) {
+    int32_t countStrings;
+    status_t status;
+    size_t datalen;
+    char **pStrings;
+
+    status = p.readInt32 (&countStrings);
+
+    if (status != NO_ERROR) {
+        goto invalid;
+    }
+
+    startRequest;
+    if (countStrings == 0) {
+        // just some non-null pointer
+        pStrings = (char **)alloca(sizeof(char *));
+        datalen = 0;
+    } else if (((int)countStrings) == -1) {
+        pStrings = NULL;
+        datalen = 0;
+    } else {
+        datalen = sizeof(char *) * countStrings;
+
+        pStrings = (char **)alloca(datalen);
+
+        for (int i = 0 ; i < countStrings ; i++) {
+            pStrings[i] = strdupReadString(p);
+            appendPrintBuf("%s%s,", printBuf, pStrings[i]);
+        }
+    }
+    removeLastChar;
+    closeRequest;
+    printRequest(pRI->token, pRI->pCI->requestNumber);
+
+    CALL_ONREQUEST(pRI->pCI->requestNumber, pStrings, datalen, pRI, pRI->socket_id);
+
+    if (pStrings != NULL) {
+        for (int i = 0 ; i < countStrings ; i++) {
+#ifdef MEMSET_FREED
+            memsetString (pStrings[i]);
+#endif
+            free(pStrings[i]);
+        }
+
+#ifdef MEMSET_FREED
+        memset(pStrings, 0, datalen);
+#endif
+    }
+
+    return;
+invalid:
+    invalidCommandBlock(pRI);
+    return;
+}
+
+/** Callee expects const int * */
+static void
+dispatchInts (Parcel &p, RequestInfo *pRI) {
+    int32_t count;
+    status_t status;
+    size_t datalen;
+    int *pInts;
+
+    status = p.readInt32 (&count);
+
+    if (status != NO_ERROR || count == 0) {
+        goto invalid;
+    }
+
+    datalen = sizeof(int) * count;
+    pInts = (int *)alloca(datalen);
+
+    startRequest;
+    for (int i = 0 ; i < count ; i++) {
+        int32_t t;
+
+        status = p.readInt32(&t);
+        pInts[i] = (int)t;
+        appendPrintBuf("%s%d,", printBuf, t);
+
+        if (status != NO_ERROR) {
+            goto invalid;
+        }
+   }
+   removeLastChar;
+   closeRequest;
+   printRequest(pRI->token, pRI->pCI->requestNumber);
+
+   CALL_ONREQUEST(pRI->pCI->requestNumber, const_cast<int *>(pInts),
+                       datalen, pRI, pRI->socket_id);
+
+#ifdef MEMSET_FREED
+    memset(pInts, 0, datalen);
+#endif
+
+    return;
+invalid:
+    invalidCommandBlock(pRI);
+    return;
+}
+
+
+/**
+ * Callee expects const RIL_SMS_WriteArgs *
+ * Payload is:
+ *   int32_t status
+ *   String pdu
+ */
+static void
+dispatchSmsWrite (Parcel &p, RequestInfo *pRI) {
+    RIL_SMS_WriteArgs args;
+    int32_t t;
+    status_t status;
+
+    RLOGD("dispatchSmsWrite");
+    memset (&args, 0, sizeof(args));
+
+    status = p.readInt32(&t);
+    args.status = (int)t;
+
+    args.pdu = strdupReadString(p);
+
+    if (status != NO_ERROR || args.pdu == NULL) {
+        goto invalid;
+    }
+
+    args.smsc = strdupReadString(p);
+
+    startRequest;
+    appendPrintBuf("%s%d,%s,smsc=%s", printBuf, args.status,
+        (char*)args.pdu,  (char*)args.smsc);
+    closeRequest;
+    printRequest(pRI->token, pRI->pCI->requestNumber);
+
+    CALL_ONREQUEST(pRI->pCI->requestNumber, &args, sizeof(args), pRI, pRI->socket_id);
+
+#ifdef MEMSET_FREED
+    memsetString (args.pdu);
+#endif
+
+    free (args.pdu);
+    free (args.smsc);
+#ifdef MEMSET_FREED
+    memset(&args, 0, sizeof(args));
+#endif
+
+    return;
+invalid:
+    invalidCommandBlock(pRI);
+    return;
+}
+
+/**
+ * Callee expects const RIL_Dial *
+ * Payload is:
+ *   String address
+ *   int32_t clir
+ */
+static void
+dispatchDial (Parcel &p, RequestInfo *pRI) {
+    RIL_Dial dial;
+    RIL_UUS_Info uusInfo;
+    int32_t sizeOfDial;
+    int32_t t;
+    int32_t uusPresent;
+    status_t status;
+
+    RLOGD("dispatchDial");
+    memset (&dial, 0, sizeof(dial));
+
+    dial.address = strdupReadString(p);
+
+    status = p.readInt32(&t);
+    dial.clir = (int)t;
+
+    if (status != NO_ERROR || dial.address == NULL) {
+        goto invalid;
+    }
+
+    if (s_callbacks.version < 3) { // Remove when partners upgrade to version 3
+        uusPresent = 0;
+        sizeOfDial = sizeof(dial) - sizeof(RIL_UUS_Info *);
+    } else {
+        status = p.readInt32(&uusPresent);
+
+        if (status != NO_ERROR) {
+            goto invalid;
+        }
+
+        if (uusPresent == 0) {
+            dial.uusInfo = NULL;
+        } else {
+            int32_t len;
+
+            memset(&uusInfo, 0, sizeof(RIL_UUS_Info));
+
+            status = p.readInt32(&t);
+            uusInfo.uusType = (RIL_UUS_Type) t;
+
+            status = p.readInt32(&t);
+            uusInfo.uusDcs = (RIL_UUS_DCS) t;
+
+            status = p.readInt32(&len);
+            if (status != NO_ERROR) {
+                goto invalid;
+            }
+
+            // The java code writes -1 for null arrays
+            if (((int) len) == -1) {
+                uusInfo.uusData = NULL;
+                len = 0;
+            } else {
+                uusInfo.uusData = (char*) p.readInplace(len);
+            }
+
+            uusInfo.uusLength = len;
+            dial.uusInfo = &uusInfo;
+        }
+        sizeOfDial = sizeof(dial);
+    }
+
+    startRequest;
+    appendPrintBuf("%snum=%s,clir=%d", printBuf, dial.address, dial.clir);
+    if (uusPresent) {
+        appendPrintBuf("%s,uusType=%d,uusDcs=%d,uusLen=%d", printBuf,
+                dial.uusInfo->uusType, dial.uusInfo->uusDcs,
+                dial.uusInfo->uusLength);
+    }
+
+    closeRequest;
+    printRequest(pRI->token, pRI->pCI->requestNumber);
+
+    CALL_ONREQUEST(pRI->pCI->requestNumber, &dial, sizeOfDial, pRI, pRI->socket_id);
+
+#ifdef MEMSET_FREED
+    memsetString (dial.address);
+#endif
+
+    free (dial.address);
+
+#ifdef MEMSET_FREED
+    memset(&uusInfo, 0, sizeof(RIL_UUS_Info));
+    memset(&dial, 0, sizeof(dial));
+#endif
+
+    return;
+invalid:
+    invalidCommandBlock(pRI);
+    return;
+}
+
+/**
+ * Callee expects const RIL_SIM_IO *
+ * Payload is:
+ *   int32_t command
+ *   int32_t fileid
+ *   String path
+ *   int32_t p1, p2, p3
+ *   String data
+ *   String pin2
+ *   String aidPtr
+ */
+static void
+dispatchSIM_IO (Parcel &p, RequestInfo *pRI) {
+    union RIL_SIM_IO {
+        RIL_SIM_IO_v6 v6;
+        RIL_SIM_IO_v5 v5;
+    } simIO;
+
+    int32_t t;
+    int size;
+    status_t status;
+
+#if VDBG
+    RLOGD("dispatchSIM_IO");
+#endif
+    memset (&simIO, 0, sizeof(simIO));
+
+    // note we only check status at the end
+
+    status = p.readInt32(&t);
+    simIO.v6.command = (int)t;
+
+    status = p.readInt32(&t);
+    simIO.v6.fileid = (int)t;
+
+    simIO.v6.path = strdupReadString(p);
+
+    status = p.readInt32(&t);
+    simIO.v6.p1 = (int)t;
+
+    status = p.readInt32(&t);
+    simIO.v6.p2 = (int)t;
+
+    status = p.readInt32(&t);
+    simIO.v6.p3 = (int)t;
+
+    simIO.v6.data = strdupReadString(p);
+    simIO.v6.pin2 = strdupReadString(p);
+    simIO.v6.aidPtr = strdupReadString(p);
+
+    startRequest;
+    appendPrintBuf("%scmd=0x%X,efid=0x%X,path=%s,%d,%d,%d,%s,pin2=%s,aid=%s", printBuf,
+        simIO.v6.command, simIO.v6.fileid, (char*)simIO.v6.path,
+        simIO.v6.p1, simIO.v6.p2, simIO.v6.p3,
+        (char*)simIO.v6.data,  (char*)simIO.v6.pin2, simIO.v6.aidPtr);
+    closeRequest;
+    printRequest(pRI->token, pRI->pCI->requestNumber);
+
+    if (status != NO_ERROR) {
+        goto invalid;
+    }
+
+    size = (s_callbacks.version < 6) ? sizeof(simIO.v5) : sizeof(simIO.v6);
+    CALL_ONREQUEST(pRI->pCI->requestNumber, &simIO, size, pRI, pRI->socket_id);
+
+#ifdef MEMSET_FREED
+    memsetString (simIO.v6.path);
+    memsetString (simIO.v6.data);
+    memsetString (simIO.v6.pin2);
+    memsetString (simIO.v6.aidPtr);
+#endif
+
+    free (simIO.v6.path);
+    free (simIO.v6.data);
+    free (simIO.v6.pin2);
+    free (simIO.v6.aidPtr);
+
+#ifdef MEMSET_FREED
+    memset(&simIO, 0, sizeof(simIO));
+#endif
+
+    return;
+invalid:
+    invalidCommandBlock(pRI);
+    return;
+}
+
+/**
+ * Callee expects const RIL_SIM_APDU *
+ * Payload is:
+ *   int32_t sessionid
+ *   int32_t cla
+ *   int32_t instruction
+ *   int32_t p1, p2, p3
+ *   String data
+ */
+static void
+dispatchSIM_APDU (Parcel &p, RequestInfo *pRI) {
+    int32_t t;
+    status_t status;
+    RIL_SIM_APDU apdu;
+
+#if VDBG
+    RLOGD("dispatchSIM_APDU");
+#endif
+    memset (&apdu, 0, sizeof(RIL_SIM_APDU));
+
+    // Note we only check status at the end. Any single failure leads to
+    // subsequent reads filing.
+    status = p.readInt32(&t);
+    apdu.sessionid = (int)t;
+
+    status = p.readInt32(&t);
+    apdu.cla = (int)t;
+
+    status = p.readInt32(&t);
+    apdu.instruction = (int)t;
+
+    status = p.readInt32(&t);
+    apdu.p1 = (int)t;
+
+    status = p.readInt32(&t);
+    apdu.p2 = (int)t;
+
+    status = p.readInt32(&t);
+    apdu.p3 = (int)t;
+
+    apdu.data = strdupReadString(p);
+
+    startRequest;
+    appendPrintBuf("%ssessionid=%d,cla=%d,ins=%d,p1=%d,p2=%d,p3=%d,data=%s",
+        printBuf, apdu.sessionid, apdu.cla, apdu.instruction, apdu.p1, apdu.p2,
+        apdu.p3, (char*)apdu.data);
+    closeRequest;
+    printRequest(pRI->token, pRI->pCI->requestNumber);
+
+    if (status != NO_ERROR) {
+        goto invalid;
+    }
+
+    CALL_ONREQUEST(pRI->pCI->requestNumber, &apdu, sizeof(RIL_SIM_APDU), pRI, pRI->socket_id);
+
+#ifdef MEMSET_FREED
+    memsetString(apdu.data);
+#endif
+    free(apdu.data);
+
+#ifdef MEMSET_FREED
+    memset(&apdu, 0, sizeof(RIL_SIM_APDU));
+#endif
+
+    return;
+invalid:
+    invalidCommandBlock(pRI);
+    return;
+}
+
+
+/**
+ * Callee expects const RIL_CallForwardInfo *
+ * Payload is:
+ *  int32_t status/action
+ *  int32_t reason
+ *  int32_t serviceCode
+ *  int32_t toa
+ *  String number  (0 length -> null)
+ *  int32_t timeSeconds
+ */
+static void
+dispatchCallForward(Parcel &p, RequestInfo *pRI) {
+    RIL_CallForwardInfo cff;
+    int32_t t;
+    status_t status;
+
+    RLOGD("dispatchCallForward");
+    memset (&cff, 0, sizeof(cff));
+
+    // note we only check status at the end
+
+    status = p.readInt32(&t);
+    cff.status = (int)t;
+
+    status = p.readInt32(&t);
+    cff.reason = (int)t;
+
+    status = p.readInt32(&t);
+    cff.serviceClass = (int)t;
+
+    status = p.readInt32(&t);
+    cff.toa = (int)t;
+
+    cff.number = strdupReadString(p);
+
+    status = p.readInt32(&t);
+    cff.timeSeconds = (int)t;
+
+    if (status != NO_ERROR) {
+        goto invalid;
+    }
+
+    // special case: number 0-length fields is null
+
+    if (cff.number != NULL && strlen (cff.number) == 0) {
+        cff.number = NULL;
+    }
+
+    startRequest;
+    appendPrintBuf("%sstat=%d,reason=%d,serv=%d,toa=%d,%s,tout=%d", printBuf,
+        cff.status, cff.reason, cff.serviceClass, cff.toa,
+        (char*)cff.number, cff.timeSeconds);
+    closeRequest;
+    printRequest(pRI->token, pRI->pCI->requestNumber);
+
+    CALL_ONREQUEST(pRI->pCI->requestNumber, &cff, sizeof(cff), pRI, pRI->socket_id);
+
+#ifdef MEMSET_FREED
+    memsetString(cff.number);
+#endif
+
+    free (cff.number);
+
+#ifdef MEMSET_FREED
+    memset(&cff, 0, sizeof(cff));
+#endif
+
+    return;
+invalid:
+    invalidCommandBlock(pRI);
+    return;
+}
+
+
+static void
+dispatchRaw(Parcel &p, RequestInfo *pRI) {
+    int32_t len;
+    status_t status;
+    const void *data;
+
+    status = p.readInt32(&len);
+
+    if (status != NO_ERROR) {
+        goto invalid;
+    }
+
+    // The java code writes -1 for null arrays
+    if (((int)len) == -1) {
+        data = NULL;
+        len = 0;
+    }
+
+    data = p.readInplace(len);
+
+    startRequest;
+    appendPrintBuf("%sraw_size=%d", printBuf, len);
+    closeRequest;
+    printRequest(pRI->token, pRI->pCI->requestNumber);
+
+    CALL_ONREQUEST(pRI->pCI->requestNumber, const_cast<void *>(data), len, pRI, pRI->socket_id);
+
+    return;
+invalid:
+    invalidCommandBlock(pRI);
+    return;
+}
+
+static status_t
+constructCdmaSms(Parcel &p, RequestInfo *pRI, RIL_CDMA_SMS_Message& rcsm) {
+    int32_t  t;
+    uint8_t ut;
+    status_t status;
+    int32_t digitCount;
+    int digitLimit;
+
+    memset(&rcsm, 0, sizeof(rcsm));
+
+    status = p.readInt32(&t);
+    rcsm.uTeleserviceID = (int) t;
+
+    status = p.read(&ut,sizeof(ut));
+    rcsm.bIsServicePresent = (uint8_t) ut;
+
+    status = p.readInt32(&t);
+    rcsm.uServicecategory = (int) t;
+
+    status = p.readInt32(&t);
+    rcsm.sAddress.digit_mode = (RIL_CDMA_SMS_DigitMode) t;
+
+    status = p.readInt32(&t);
+    rcsm.sAddress.number_mode = (RIL_CDMA_SMS_NumberMode) t;
+
+    status = p.readInt32(&t);
+    rcsm.sAddress.number_type = (RIL_CDMA_SMS_NumberType) t;
+
+    status = p.readInt32(&t);
+    rcsm.sAddress.number_plan = (RIL_CDMA_SMS_NumberPlan) t;
+
+    status = p.read(&ut,sizeof(ut));
+    rcsm.sAddress.number_of_digits= (uint8_t) ut;
+
+    digitLimit= MIN((rcsm.sAddress.number_of_digits), RIL_CDMA_SMS_ADDRESS_MAX);
+    for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
+        status = p.read(&ut,sizeof(ut));
+        rcsm.sAddress.digits[digitCount] = (uint8_t) ut;
+    }
+
+    status = p.readInt32(&t);
+    rcsm.sSubAddress.subaddressType = (RIL_CDMA_SMS_SubaddressType) t;
+
+    status = p.read(&ut,sizeof(ut));
+    rcsm.sSubAddress.odd = (uint8_t) ut;
+
+    status = p.read(&ut,sizeof(ut));
+    rcsm.sSubAddress.number_of_digits = (uint8_t) ut;
+
+    digitLimit= MIN((rcsm.sSubAddress.number_of_digits), RIL_CDMA_SMS_SUBADDRESS_MAX);
+    for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
+        status = p.read(&ut,sizeof(ut));
+        rcsm.sSubAddress.digits[digitCount] = (uint8_t) ut;
+    }
+
+    status = p.readInt32(&t);
+    rcsm.uBearerDataLen = (int) t;
+
+    digitLimit= MIN((rcsm.uBearerDataLen), RIL_CDMA_SMS_BEARER_DATA_MAX);
+    for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
+        status = p.read(&ut, sizeof(ut));
+        rcsm.aBearerData[digitCount] = (uint8_t) ut;
+    }
+
+    if (status != NO_ERROR) {
+        return status;
+    }
+
+    startRequest;
+    appendPrintBuf("%suTeleserviceID=%d, bIsServicePresent=%d, uServicecategory=%d, \
+            sAddress.digit_mode=%d, sAddress.Number_mode=%d, sAddress.number_type=%d, ",
+            printBuf, rcsm.uTeleserviceID,rcsm.bIsServicePresent,rcsm.uServicecategory,
+            rcsm.sAddress.digit_mode, rcsm.sAddress.number_mode,rcsm.sAddress.number_type);
+    closeRequest;
+
+    printRequest(pRI->token, pRI->pCI->requestNumber);
+
+    return status;
+}
+
+static void
+dispatchCdmaSms(Parcel &p, RequestInfo *pRI) {
+    RIL_CDMA_SMS_Message rcsm;
+
+    RLOGD("dispatchCdmaSms");
+    if (NO_ERROR != constructCdmaSms(p, pRI, rcsm)) {
+        goto invalid;
+    }
+
+    CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsm, sizeof(rcsm),pRI, pRI->socket_id);
+
+#ifdef MEMSET_FREED
+    memset(&rcsm, 0, sizeof(rcsm));
+#endif
+
+    return;
+
+invalid:
+    invalidCommandBlock(pRI);
+    return;
+}
+
+static void
+dispatchImsCdmaSms(Parcel &p, RequestInfo *pRI, uint8_t retry, int32_t messageRef) {
+    RIL_IMS_SMS_Message rism;
+    RIL_CDMA_SMS_Message rcsm;
+
+    RLOGD("dispatchImsCdmaSms: retry=%d, messageRef=%d", retry, messageRef);
+
+    if (NO_ERROR != constructCdmaSms(p, pRI, rcsm)) {
+        goto invalid;
+    }
+    memset(&rism, 0, sizeof(rism));
+    rism.tech = RADIO_TECH_3GPP2;
+    rism.retry = retry;
+    rism.messageRef = messageRef;
+    rism.message.cdmaMessage = &rcsm;
+
+    CALL_ONREQUEST(pRI->pCI->requestNumber, &rism,
+            sizeof(RIL_RadioTechnologyFamily)+sizeof(uint8_t)+sizeof(int32_t)
+            +sizeof(rcsm),pRI, pRI->socket_id);
+
+#ifdef MEMSET_FREED
+    memset(&rcsm, 0, sizeof(rcsm));
+    memset(&rism, 0, sizeof(rism));
+#endif
+
+    return;
+
+invalid:
+    invalidCommandBlock(pRI);
+    return;
+}
+
+static void
+dispatchImsGsmSms(Parcel &p, RequestInfo *pRI, uint8_t retry, int32_t messageRef) {
+    RIL_IMS_SMS_Message rism;
+    int32_t countStrings;
+    status_t status;
+    size_t datalen;
+    char **pStrings;
+    RLOGD("dispatchImsGsmSms: retry=%d, messageRef=%d", retry, messageRef);
+
+    status = p.readInt32 (&countStrings);
+
+    if (status != NO_ERROR) {
+        goto invalid;
+    }
+
+    memset(&rism, 0, sizeof(rism));
+    rism.tech = RADIO_TECH_3GPP;
+    rism.retry = retry;
+    rism.messageRef = messageRef;
+
+    startRequest;
+    appendPrintBuf("%stech=%d, retry=%d, messageRef=%d, ", printBuf,
+                    (int)rism.tech, (int)rism.retry, rism.messageRef);
+    if (countStrings == 0) {
+        // just some non-null pointer
+        pStrings = (char **)alloca(sizeof(char *));
+        datalen = 0;
+    } else if (((int)countStrings) == -1) {
+        pStrings = NULL;
+        datalen = 0;
+    } else {
+        datalen = sizeof(char *) * countStrings;
+
+        pStrings = (char **)alloca(datalen);
+
+        for (int i = 0 ; i < countStrings ; i++) {
+            pStrings[i] = strdupReadString(p);
+            appendPrintBuf("%s%s,", printBuf, pStrings[i]);
+        }
+    }
+    removeLastChar;
+    closeRequest;
+    printRequest(pRI->token, pRI->pCI->requestNumber);
+
+    rism.message.gsmMessage = pStrings;
+    CALL_ONREQUEST(pRI->pCI->requestNumber, &rism,
+            sizeof(RIL_RadioTechnologyFamily)+sizeof(uint8_t)+sizeof(int32_t)
+            +datalen, pRI, pRI->socket_id);
+
+    if (pStrings != NULL) {
+        for (int i = 0 ; i < countStrings ; i++) {
+#ifdef MEMSET_FREED
+            memsetString (pStrings[i]);
+#endif
+            free(pStrings[i]);
+        }
+
+#ifdef MEMSET_FREED
+        memset(pStrings, 0, datalen);
+#endif
+    }
+
+#ifdef MEMSET_FREED
+    memset(&rism, 0, sizeof(rism));
+#endif
+    return;
+invalid:
+    ALOGE("dispatchImsGsmSms invalid block");
+    invalidCommandBlock(pRI);
+    return;
+}
+
+static void
+dispatchImsSms(Parcel &p, RequestInfo *pRI) {
+    int32_t  t;
+    status_t status = p.readInt32(&t);
+    RIL_RadioTechnologyFamily format;
+    uint8_t retry;
+    int32_t messageRef;
+
+    RLOGD("dispatchImsSms");
+    if (status != NO_ERROR) {
+        goto invalid;
+    }
+    format = (RIL_RadioTechnologyFamily) t;
+
+    // read retry field
+    status = p.read(&retry,sizeof(retry));
+    if (status != NO_ERROR) {
+        goto invalid;
+    }
+    // read messageRef field
+    status = p.read(&messageRef,sizeof(messageRef));
+    if (status != NO_ERROR) {
+        goto invalid;
+    }
+
+    if (RADIO_TECH_3GPP == format) {
+        dispatchImsGsmSms(p, pRI, retry, messageRef);
+    } else if (RADIO_TECH_3GPP2 == format) {
+        dispatchImsCdmaSms(p, pRI, retry, messageRef);
+    } else {
+        ALOGE("requestImsSendSMS invalid format value =%d", format);
+    }
+
+    return;
+
+invalid:
+    invalidCommandBlock(pRI);
+    return;
+}
+
+static void
+dispatchCdmaSmsAck(Parcel &p, RequestInfo *pRI) {
+    RIL_CDMA_SMS_Ack rcsa;
+    int32_t  t;
+    status_t status;
+    int32_t digitCount;
+
+    RLOGD("dispatchCdmaSmsAck");
+    memset(&rcsa, 0, sizeof(rcsa));
+
+    status = p.readInt32(&t);
+    rcsa.uErrorClass = (RIL_CDMA_SMS_ErrorClass) t;
+
+    status = p.readInt32(&t);
+    rcsa.uSMSCauseCode = (int) t;
+
+    if (status != NO_ERROR) {
+        goto invalid;
+    }
+
+    startRequest;
+    appendPrintBuf("%suErrorClass=%d, uTLStatus=%d, ",
+            printBuf, rcsa.uErrorClass, rcsa.uSMSCauseCode);
+    closeRequest;
+
+    printRequest(pRI->token, pRI->pCI->requestNumber);
+
+    CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsa, sizeof(rcsa),pRI, pRI->socket_id);
+
+#ifdef MEMSET_FREED
+    memset(&rcsa, 0, sizeof(rcsa));
+#endif
+
+    return;
+
+invalid:
+    invalidCommandBlock(pRI);
+    return;
+}
+
+static void
+dispatchGsmBrSmsCnf(Parcel &p, RequestInfo *pRI) {
+    int32_t t;
+    status_t status;
+    int32_t num;
+
+    status = p.readInt32(&num);
+    if (status != NO_ERROR) {
+        goto invalid;
+    }
+
+    {
+        RIL_GSM_BroadcastSmsConfigInfo gsmBci[num];
+        RIL_GSM_BroadcastSmsConfigInfo *gsmBciPtrs[num];
+
+        startRequest;
+        for (int i = 0 ; i < num ; i++ ) {
+            gsmBciPtrs[i] = &gsmBci[i];
+
+            status = p.readInt32(&t);
+            gsmBci[i].fromServiceId = (int) t;
+
+            status = p.readInt32(&t);
+            gsmBci[i].toServiceId = (int) t;
+
+            status = p.readInt32(&t);
+            gsmBci[i].fromCodeScheme = (int) t;
+
+            status = p.readInt32(&t);
+            gsmBci[i].toCodeScheme = (int) t;
+
+            status = p.readInt32(&t);
+            gsmBci[i].selected = (uint8_t) t;
+
+            appendPrintBuf("%s [%d: fromServiceId=%d, toServiceId =%d, \
+                  fromCodeScheme=%d, toCodeScheme=%d, selected =%d]", printBuf, i,
+                  gsmBci[i].fromServiceId, gsmBci[i].toServiceId,
+                  gsmBci[i].fromCodeScheme, gsmBci[i].toCodeScheme,
+                  gsmBci[i].selected);
+        }
+        closeRequest;
+
+        if (status != NO_ERROR) {
+            goto invalid;
+        }
+
+        printRequest(pRI->token, pRI->pCI->requestNumber);
+
+        CALL_ONREQUEST(pRI->pCI->requestNumber,
+                              gsmBciPtrs,
+                              num * sizeof(RIL_GSM_BroadcastSmsConfigInfo *),
+                              pRI, pRI->socket_id);
+
+#ifdef MEMSET_FREED
+        memset(gsmBci, 0, num * sizeof(RIL_GSM_BroadcastSmsConfigInfo));
+        memset(gsmBciPtrs, 0, num * sizeof(RIL_GSM_BroadcastSmsConfigInfo *));
+#endif
+    }
+
+    return;
+
+invalid:
+    invalidCommandBlock(pRI);
+    return;
+}
+
+static void
+dispatchCdmaBrSmsCnf(Parcel &p, RequestInfo *pRI) {
+    int32_t t;
+    status_t status;
+    int32_t num;
+
+    status = p.readInt32(&num);
+    if (status != NO_ERROR) {
+        goto invalid;
+    }
+
+    {
+        RIL_CDMA_BroadcastSmsConfigInfo cdmaBci[num];
+        RIL_CDMA_BroadcastSmsConfigInfo *cdmaBciPtrs[num];
+
+        startRequest;
+        for (int i = 0 ; i < num ; i++ ) {
+            cdmaBciPtrs[i] = &cdmaBci[i];
+
+            status = p.readInt32(&t);
+            cdmaBci[i].service_category = (int) t;
+
+            status = p.readInt32(&t);
+            cdmaBci[i].language = (int) t;
+
+            status = p.readInt32(&t);
+            cdmaBci[i].selected = (uint8_t) t;
+
+            appendPrintBuf("%s [%d: service_category=%d, language =%d, \
+                  entries.bSelected =%d]", printBuf, i, cdmaBci[i].service_category,
+                  cdmaBci[i].language, cdmaBci[i].selected);
+        }
+        closeRequest;
+
+        if (status != NO_ERROR) {
+            goto invalid;
+        }
+        printRequest(pRI->token, pRI->pCI->requestNumber);
+        CALL_ONREQUEST(pRI->pCI->requestNumber,
+                              cdmaBciPtrs,
+                              num * sizeof(RIL_CDMA_BroadcastSmsConfigInfo *),
+                              pRI, pRI->socket_id);
+
+#ifdef MEMSET_FREED
+        memset(cdmaBci, 0, num * sizeof(RIL_CDMA_BroadcastSmsConfigInfo));
+        memset(cdmaBciPtrs, 0, num * sizeof(RIL_CDMA_BroadcastSmsConfigInfo *));
+#endif
+    }
+
+    return;
+
+invalid:
+    invalidCommandBlock(pRI);
+    return;
+}
+
+static void dispatchRilCdmaSmsWriteArgs(Parcel &p, RequestInfo *pRI) {
+    RIL_CDMA_SMS_WriteArgs rcsw;
+    int32_t  t;
+    uint32_t ut;
+    uint8_t  uct;
+    status_t status;
+    int32_t  digitCount;
+    int32_t  digitLimit;
+
+    memset(&rcsw, 0, sizeof(rcsw));
+
+    status = p.readInt32(&t);
+    rcsw.status = t;
+
+    status = p.readInt32(&t);
+    rcsw.message.uTeleserviceID = (int) t;
+
+    status = p.read(&uct,sizeof(uct));
+    rcsw.message.bIsServicePresent = (uint8_t) uct;
+
+    status = p.readInt32(&t);
+    rcsw.message.uServicecategory = (int) t;
+
+    status = p.readInt32(&t);
+    rcsw.message.sAddress.digit_mode = (RIL_CDMA_SMS_DigitMode) t;
+
+    status = p.readInt32(&t);
+    rcsw.message.sAddress.number_mode = (RIL_CDMA_SMS_NumberMode) t;
+
+    status = p.readInt32(&t);
+    rcsw.message.sAddress.number_type = (RIL_CDMA_SMS_NumberType) t;
+
+    status = p.readInt32(&t);
+    rcsw.message.sAddress.number_plan = (RIL_CDMA_SMS_NumberPlan) t;
+
+    status = p.read(&uct,sizeof(uct));
+    rcsw.message.sAddress.number_of_digits = (uint8_t) uct;
+
+    digitLimit = MIN((rcsw.message.sAddress.number_of_digits), RIL_CDMA_SMS_ADDRESS_MAX);
+
+    for(digitCount = 0 ; digitCount < digitLimit; digitCount ++) {
+        status = p.read(&uct,sizeof(uct));
+        rcsw.message.sAddress.digits[digitCount] = (uint8_t) uct;
+    }
+
+    status = p.readInt32(&t);
+    rcsw.message.sSubAddress.subaddressType = (RIL_CDMA_SMS_SubaddressType) t;
+
+    status = p.read(&uct,sizeof(uct));
+    rcsw.message.sSubAddress.odd = (uint8_t) uct;
+
+    status = p.read(&uct,sizeof(uct));
+    rcsw.message.sSubAddress.number_of_digits = (uint8_t) uct;
+
+    digitLimit = MIN((rcsw.message.sSubAddress.number_of_digits), RIL_CDMA_SMS_SUBADDRESS_MAX);
+
+    for(digitCount = 0 ; digitCount < digitLimit; digitCount ++) {
+        status = p.read(&uct,sizeof(uct));
+        rcsw.message.sSubAddress.digits[digitCount] = (uint8_t) uct;
+    }
+
+    status = p.readInt32(&t);
+    rcsw.message.uBearerDataLen = (int) t;
+
+    digitLimit = MIN((rcsw.message.uBearerDataLen), RIL_CDMA_SMS_BEARER_DATA_MAX);
+
+    for(digitCount = 0 ; digitCount < digitLimit; digitCount ++) {
+        status = p.read(&uct, sizeof(uct));
+        rcsw.message.aBearerData[digitCount] = (uint8_t) uct;
+    }
+
+    if (status != NO_ERROR) {
+        goto invalid;
+    }
+
+    startRequest;
+    appendPrintBuf("%sstatus=%d, message.uTeleserviceID=%d, message.bIsServicePresent=%d, \
+            message.uServicecategory=%d, message.sAddress.digit_mode=%d, \
+            message.sAddress.number_mode=%d, \
+            message.sAddress.number_type=%d, ",
+            printBuf, rcsw.status, rcsw.message.uTeleserviceID, rcsw.message.bIsServicePresent,
+            rcsw.message.uServicecategory, rcsw.message.sAddress.digit_mode,
+            rcsw.message.sAddress.number_mode,
+            rcsw.message.sAddress.number_type);
+    closeRequest;
+
+    printRequest(pRI->token, pRI->pCI->requestNumber);
+
+    CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsw, sizeof(rcsw),pRI, pRI->socket_id);
+
+#ifdef MEMSET_FREED
+    memset(&rcsw, 0, sizeof(rcsw));
+#endif
+
+    return;
+
+invalid:
+    invalidCommandBlock(pRI);
+    return;
+
+}
+
+// For backwards compatibility in RIL_REQUEST_SETUP_DATA_CALL.
+// Version 4 of the RIL interface adds a new PDP type parameter to support
+// IPv6 and dual-stack PDP contexts. When dealing with a previous version of
+// RIL, remove the parameter from the request.
+static void dispatchDataCall(Parcel& p, RequestInfo *pRI) {
+    // In RIL v3, REQUEST_SETUP_DATA_CALL takes 6 parameters.
+    const int numParamsRilV3 = 6;
+
+    // The first bytes of the RIL parcel contain the request number and the
+    // serial number - see processCommandBuffer(). Copy them over too.
+    int pos = p.dataPosition();
+
+    int numParams = p.readInt32();
+    if (s_callbacks.version < 4 && numParams > numParamsRilV3) {
+/*      Parcel p2;
+      p2.appendFrom(&p, 0, pos);
+      p2.writeInt32(numParamsRilV3);
+      for(int i = 0; i < numParamsRilV3; i++) {
+        p2.writeString16(p.readString16());
+      }
+      p2.setDataPosition(pos);
+      dispatchStrings(p2, pRI);*/
+    } else {
+      p.setDataPosition(pos);
+      dispatchStrings(p, pRI);
+    }
+}
+
+static void dispatchSetInitialAttachApn(Parcel &p, RequestInfo *pRI)
+{
+    RIL_InitialAttachApn pf;
+    int32_t  t;
+    status_t status;
+
+    memset(&pf, 0, sizeof(pf));
+
+    pf.apn = strdupReadString(p);
+    pf.protocol = strdupReadString(p);
+
+    status = p.readInt32(&t);
+    pf.authtype = (int) t;
+
+    pf.username = strdupReadString(p);
+    pf.password = strdupReadString(p);
+
+    startRequest;
+    appendPrintBuf("%sapn=%s, protocol=%s, authtype=%d, username=%s, password=%s",
+            printBuf, pf.apn, pf.protocol, pf.authtype, pf.username, pf.password);
+    closeRequest;
+    printRequest(pRI->token, pRI->pCI->requestNumber);
+
+    if (status != NO_ERROR) {
+        goto invalid;
+    }
+    CALL_ONREQUEST(pRI->pCI->requestNumber, &pf, sizeof(pf), pRI, pRI->socket_id);
+
+#ifdef MEMSET_FREED
+    memsetString(pf.apn);
+    memsetString(pf.protocol);
+    memsetString(pf.username);
+    memsetString(pf.password);
+#endif
+
+    free(pf.apn);
+    free(pf.protocol);
+    free(pf.username);
+    free(pf.password);
+
+#ifdef MEMSET_FREED
+    memset(&pf, 0, sizeof(pf));
+#endif
+
+    return;
+invalid:
+    invalidCommandBlock(pRI);
+    return;
+}
+
+static void dispatchNVReadItem(Parcel &p, RequestInfo *pRI) {
+    RIL_NV_ReadItem nvri;
+    int32_t  t;
+    status_t status;
+
+    memset(&nvri, 0, sizeof(nvri));
+
+    status = p.readInt32(&t);
+    nvri.itemID = (RIL_NV_Item) t;
+
+    if (status != NO_ERROR) {
+        goto invalid;
+    }
+
+    startRequest;
+    appendPrintBuf("%snvri.itemID=%d, ", printBuf, nvri.itemID);
+    closeRequest;
+
+    printRequest(pRI->token, pRI->pCI->requestNumber);
+
+    CALL_ONREQUEST(pRI->pCI->requestNumber, &nvri, sizeof(nvri), pRI, pRI->socket_id);
+
+#ifdef MEMSET_FREED
+    memset(&nvri, 0, sizeof(nvri));
+#endif
+
+    return;
+
+invalid:
+    invalidCommandBlock(pRI);
+    return;
+}
+
+static void dispatchNVWriteItem(Parcel &p, RequestInfo *pRI) {
+    RIL_NV_WriteItem nvwi;
+    int32_t  t;
+    status_t status;
+
+    memset(&nvwi, 0, sizeof(nvwi));
+
+    status = p.readInt32(&t);
+    nvwi.itemID = (RIL_NV_Item) t;
+
+    nvwi.value = strdupReadString(p);
+
+    if (status != NO_ERROR || nvwi.value == NULL) {
+        goto invalid;
+    }
+
+    startRequest;
+    appendPrintBuf("%snvwi.itemID=%d, value=%s, ", printBuf, nvwi.itemID,
+            nvwi.value);
+    closeRequest;
+
+    printRequest(pRI->token, pRI->pCI->requestNumber);
+
+    CALL_ONREQUEST(pRI->pCI->requestNumber, &nvwi, sizeof(nvwi), pRI, pRI->socket_id);
+
+#ifdef MEMSET_FREED
+    memsetString(nvwi.value);
+#endif
+
+    free(nvwi.value);
+
+#ifdef MEMSET_FREED
+    memset(&nvwi, 0, sizeof(nvwi));
+#endif
+
+    return;
+
+invalid:
+    invalidCommandBlock(pRI);
+    return;
+}
+
+
+static void dispatchUiccSubscripton(Parcel &p, RequestInfo *pRI) {
+    RIL_SelectUiccSub uicc_sub;
+    status_t status;
+    int32_t  t;
+    memset(&uicc_sub, 0, sizeof(uicc_sub));
+
+    status = p.readInt32(&t);
+    if (status != NO_ERROR) {
+        goto invalid;
+    }
+    uicc_sub.slot = (int) t;
+
+    status = p.readInt32(&t);
+    if (status != NO_ERROR) {
+        goto invalid;
+    }
+    uicc_sub.app_index = (int) t;
+
+    status = p.readInt32(&t);
+    if (status != NO_ERROR) {
+        goto invalid;
+    }
+    uicc_sub.sub_type = (RIL_SubscriptionType) t;
+
+    status = p.readInt32(&t);
+    if (status != NO_ERROR) {
+        goto invalid;
+    }
+    uicc_sub.act_status = (RIL_UiccSubActStatus) t;
+
+    startRequest;
+    appendPrintBuf("slot=%d, app_index=%d, act_status = %d", uicc_sub.slot, uicc_sub.app_index,
+            uicc_sub.act_status);
+    RLOGD("dispatchUiccSubscription, slot=%d, app_index=%d, act_status = %d", uicc_sub.slot,
+            uicc_sub.app_index, uicc_sub.act_status);
+    closeRequest;
+    printRequest(pRI->token, pRI->pCI->requestNumber);
+
+    CALL_ONREQUEST(pRI->pCI->requestNumber, &uicc_sub, sizeof(uicc_sub), pRI, pRI->socket_id);
+
+#ifdef MEMSET_FREED
+    memset(&uicc_sub, 0, sizeof(uicc_sub));
+#endif
+    return;
+
+invalid:
+    invalidCommandBlock(pRI);
+    return;
+}
+
+static void dispatchSimAuthentication(Parcel &p, RequestInfo *pRI)
+{
+    RIL_SimAuthentication pf;
+    int32_t  t;
+    status_t status;
+
+    memset(&pf, 0, sizeof(pf));
+
+    status = p.readInt32(&t);
+    pf.authContext = (int) t;
+    pf.authData = strdupReadString(p);
+    pf.aid = strdupReadString(p);
+
+    startRequest;
+    appendPrintBuf("authContext=%s, authData=%s, aid=%s", pf.authContext, pf.authData, pf.aid);
+    closeRequest;
+    printRequest(pRI->token, pRI->pCI->requestNumber);
+
+    if (status != NO_ERROR) {
+        goto invalid;
+    }
+    CALL_ONREQUEST(pRI->pCI->requestNumber, &pf, sizeof(pf), pRI, pRI->socket_id);
+
+#ifdef MEMSET_FREED
+    memsetString(pf.authData);
+    memsetString(pf.aid);
+#endif
+
+    free(pf.authData);
+    free(pf.aid);
+
+#ifdef MEMSET_FREED
+    memset(&pf, 0, sizeof(pf));
+#endif
+
+    return;
+invalid:
+    invalidCommandBlock(pRI);
+    return;
+}
+
+static void dispatchDataProfile(Parcel &p, RequestInfo *pRI) {
+    int32_t t;
+    status_t status;
+    int32_t num;
+
+    status = p.readInt32(&num);
+    if (status != NO_ERROR) {
+        goto invalid;
+    }
+
+    {
+        RIL_DataProfileInfo dataProfiles[num];
+        RIL_DataProfileInfo *dataProfilePtrs[num];
+
+        startRequest;
+        for (int i = 0 ; i < num ; i++ ) {
+            dataProfilePtrs[i] = &dataProfiles[i];
+
+            status = p.readInt32(&t);
+            dataProfiles[i].profileId = (int) t;
+
+            dataProfiles[i].apn = strdupReadString(p);
+            dataProfiles[i].protocol = strdupReadString(p);
+            status = p.readInt32(&t);
+            dataProfiles[i].authType = (int) t;
+
+            dataProfiles[i].user = strdupReadString(p);
+            dataProfiles[i].password = strdupReadString(p);
+
+            status = p.readInt32(&t);
+            dataProfiles[i].type = (int) t;
+
+            status = p.readInt32(&t);
+            dataProfiles[i].maxConnsTime = (int) t;
+            status = p.readInt32(&t);
+            dataProfiles[i].maxConns = (int) t;
+            status = p.readInt32(&t);
+            dataProfiles[i].waitTime = (int) t;
+
+            status = p.readInt32(&t);
+            dataProfiles[i].enabled = (int) t;
+
+            appendPrintBuf("%s [%d: profileId=%d, apn =%s, protocol =%s, authType =%d, \
+                  user =%s, password =%s, type =%d, maxConnsTime =%d, maxConns =%d, \
+                  waitTime =%d, enabled =%d]", printBuf, i, dataProfiles[i].profileId,
+                  dataProfiles[i].apn, dataProfiles[i].protocol, dataProfiles[i].authType,
+                  dataProfiles[i].user, dataProfiles[i].password, dataProfiles[i].type,
+                  dataProfiles[i].maxConnsTime, dataProfiles[i].maxConns,
+                  dataProfiles[i].waitTime, dataProfiles[i].enabled);
+            RLOGD("[%d: profileId=%d, apn =%s, protocol =%s, authType =%d, \
+user =%s, password =%s, type =%d, maxConnsTime =%d, maxConns =%d, \
+waitTime =%d, enabled =%d]", i, dataProfiles[i].profileId,
+                  dataProfiles[i].apn, dataProfiles[i].protocol, dataProfiles[i].authType,
+                  dataProfiles[i].user, dataProfiles[i].password, dataProfiles[i].type,
+                  dataProfiles[i].maxConnsTime, dataProfiles[i].maxConns,
+                  dataProfiles[i].waitTime, dataProfiles[i].enabled);
+        }
+        closeRequest;
+        printRequest(pRI->token, pRI->pCI->requestNumber);
+
+        if (status != NO_ERROR) {
+            goto invalid;
+        }
+        CALL_ONREQUEST(pRI->pCI->requestNumber,
+                              dataProfilePtrs,
+                              num * sizeof(RIL_DataProfileInfo *),
+                              pRI, pRI->socket_id);
+        for(int i = 0; i< num; i++) {
+            free(dataProfiles[i].apn);
+            free(dataProfiles[i].protocol);
+            free(dataProfiles[i].user);
+            free(dataProfiles[i].password);
+        }
+#ifdef MEMSET_FREED
+        memset(dataProfiles, 0, num * sizeof(RIL_DataProfileInfo));
+        memset(dataProfilePtrs, 0, num * sizeof(RIL_DataProfileInfo *));
+#endif
+    }
+
+    return;
+
+invalid:
+    invalidCommandBlock(pRI);
+    return;
+}
+
+static void dispatchRadioCapability(Parcel &p, RequestInfo *pRI){
+    RIL_RadioCapability rc;
+    int32_t t;
+    status_t status;
+
+    memset (&rc, 0, sizeof(RIL_RadioCapability));
+
+    status = p.readInt32(&t);
+    rc.version = (int)t;
+    if (status != NO_ERROR) {
+        goto invalid;
+    }
+
+    status = p.readInt32(&t);
+    rc.session= (int)t;
+    if (status != NO_ERROR) {
+        goto invalid;
+    }
+
+    status = p.readInt32(&t);
+    rc.phase= (int)t;
+    if (status != NO_ERROR) {
+        goto invalid;
+    }
+
+    status = p.readInt32(&t);
+    rc.rat = (int)t;
+    if (status != NO_ERROR) {
+        goto invalid;
+    }
+
+    status = readStringFromParcelInplace(p, rc.logicalModemUuid, sizeof(rc.logicalModemUuid));
+    if (status != NO_ERROR) {
+        goto invalid;
+    }
+
+    status = p.readInt32(&t);
+    rc.status = (int)t;
+
+    if (status != NO_ERROR) {
+        goto invalid;
+    }
+
+    startRequest;
+    appendPrintBuf("%s [version:%d, session:%d, phase:%d, rat:%d, logicalModemUuid:%s, status:%d",
+            printBuf, rc.version, rc.session, rc.phase, rc.rat, rc.logicalModemUuid, rc.status);
+
+    closeRequest;
+    printRequest(pRI->token, pRI->pCI->requestNumber);
+
+    CALL_ONREQUEST(pRI->pCI->requestNumber,
+                &rc,
+                sizeof(RIL_RadioCapability),
+                pRI, pRI->socket_id);
+    return;
+invalid:
+    invalidCommandBlock(pRI);
+    return;
+}
+
+#if 0
+static int
+blockingWrite(int fd, const void *buffer, size_t len) {
+    size_t writeOffset = 0;
+    const uint8_t *toWrite;
+
+    toWrite = (const uint8_t *)buffer;
+
+    while (writeOffset < len) {
+        ssize_t written;
+        do {
+            written = write (fd, toWrite + writeOffset,
+                                len - writeOffset);
+        } while (written < 0 && ((errno == EINTR) || (errno == EAGAIN)));
+
+        if (written >= 0) {
+            writeOffset += written;
+        } else {   // written < 0
+            RLOGE ("RIL Response: unexpected error on write errno:%d", errno);
+            close(fd);
+            return -1;
+        }
+    }
+#if VDBG
+    RLOGE("RIL Response bytes written:%d", writeOffset);
+#endif
+    return 0;
+}
+
+static int
+sendResponseRaw (const void *data, size_t dataSize, RIL_SOCKET_ID socket_id) {
+    int fd = s_ril_param_socket.fdCommand;
+    int ret;
+    uint32_t header;
+    pthread_mutex_t * writeMutexHook = &s_writeMutex;
+
+#if VDBG
+    RLOGE("Send Response to %s", rilSocketIdToString(socket_id));
+#endif
+
+#if (SIM_COUNT >= 2)
+    if (socket_id == RIL_SOCKET_2) {
+        fd = s_ril_param_socket2.fdCommand;
+        writeMutexHook = &s_writeMutex_socket2;
+    }
+#if (SIM_COUNT >= 3)
+    else if (socket_id == RIL_SOCKET_3) {
+        fd = s_ril_param_socket3.fdCommand;
+        writeMutexHook = &s_writeMutex_socket3;
+    }
+#endif
+#if (SIM_COUNT >= 4)
+    else if (socket_id == RIL_SOCKET_4) {
+        fd = s_ril_param_socket4.fdCommand;
+        writeMutexHook = &s_writeMutex_socket4;
+    }
+#endif
+#endif
+    if (fd < 0) {
+        return -1;
+    }
+
+    if (dataSize > MAX_COMMAND_BYTES) {
+        RLOGE("RIL: packet larger than %u (%u)",
+                MAX_COMMAND_BYTES, (unsigned int )dataSize);
+
+        return -1;
+    }
+
+    pthread_mutex_lock(writeMutexHook);
+
+    header = htonl(dataSize);
+
+    ret = blockingWrite(fd, (void *)&header, sizeof(header));
+
+    if (ret < 0) {
+        pthread_mutex_unlock(writeMutexHook);
+        return ret;
+    }
+
+    ret = blockingWrite(fd, data, dataSize);
+
+    if (ret < 0) {
+        pthread_mutex_unlock(writeMutexHook);
+        return ret;
+    }
+
+    pthread_mutex_unlock(writeMutexHook);
+
+    return 0;
+}
+
+static int
+sendResponse (Parcel &p, RIL_SOCKET_ID socket_id) {
+    printResponse;
+    return sendResponseRaw(p.data(), p.dataSize(), socket_id);
+}
+#endif
+
+/** response is an int* pointing to an array of ints */
+
+static int
+responseInts(Parcel &p, void *response, size_t responselen) {
+    int numInts;
+
+    if (response == NULL && responselen != 0) {
+        RLOGE("invalid response: NULL");
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+    if (responselen % sizeof(int) != 0) {
+        RLOGE("responseInts: invalid response length %d expected multiple of %d\n",
+            (int)responselen, (int)sizeof(int));
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    int *p_int = (int *) response;
+
+    numInts = responselen / sizeof(int);
+    p.writeInt32 (numInts);
+
+    /* each int*/
+    startResponse;
+    for (int i = 0 ; i < numInts ; i++) {
+        appendPrintBuf("%s%d,", printBuf, p_int[i]);
+        p.writeInt32(p_int[i]);
+    }
+    removeLastChar;
+    closeResponse;
+
+    return 0;
+}
+
+// Response is an int or RIL_LastCallFailCauseInfo.
+// Currently, only Shamu plans to use RIL_LastCallFailCauseInfo.
+// TODO(yjl): Let all implementations use RIL_LastCallFailCauseInfo.
+static int responseFailCause(Parcel &p, void *response, size_t responselen) {
+    if (response == NULL && responselen != 0) {
+        RLOGE("invalid response: NULL");
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    if (responselen == sizeof(int)) {
+      startResponse;
+      int *p_int = (int *) response;
+      appendPrintBuf("%s%d,", printBuf, p_int[0]);
+      p.writeInt32(p_int[0]);
+      removeLastChar;
+      closeResponse;
+    } else if (responselen == sizeof(RIL_LastCallFailCauseInfo)) {
+      startResponse;
+      RIL_LastCallFailCauseInfo *p_fail_cause_info = (RIL_LastCallFailCauseInfo *) response;
+      appendPrintBuf("%s[cause_code=%d,vendor_cause=%s]", printBuf, p_fail_cause_info->cause_code,
+                     p_fail_cause_info->vendor_cause);
+      p.writeInt32(p_fail_cause_info->cause_code);
+      writeStringToParcel(p, p_fail_cause_info->vendor_cause);
+      removeLastChar;
+      closeResponse;
+    } else {
+      RLOGE("responseFailCause: invalid response length %d expected an int or "
+            "RIL_LastCallFailCauseInfo", (int)responselen);
+      return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    return 0;
+}
+
+/** response is a char **, pointing to an array of char *'s
+    The parcel will begin with the version */
+static int responseStringsWithVersion(int version, Parcel &p, void *response, size_t responselen) {
+    p.writeInt32(version);
+    return responseStrings(p, response, responselen);
+}
+
+/** response is a char **, pointing to an array of char *'s */
+static int responseStrings(Parcel &p, void *response, size_t responselen) {
+    int numStrings;
+
+    if (response == NULL && responselen != 0) {
+        RLOGE("invalid response: NULL");
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+    if (responselen % sizeof(char *) != 0) {
+        RLOGE("responseStrings: invalid response length %d expected multiple of %d\n",
+            (int)responselen, (int)sizeof(char *));
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    if (response == NULL) {
+        p.writeInt32 (0);
+    } else {
+        char **p_cur = (char **) response;
+
+        numStrings = responselen / sizeof(char *);
+        p.writeInt32 (numStrings);
+
+        /* each string*/
+        startResponse;
+        for (int i = 0 ; i < numStrings ; i++) {
+            appendPrintBuf("%s%s,", printBuf, (char*)p_cur[i]);
+            writeStringToParcel (p, p_cur[i]);
+        }
+        removeLastChar;
+        closeResponse;
+    }
+    return 0;
+}
+
+
+/**
+ * NULL strings are accepted
+ * FIXME currently ignores responselen
+ */
+static int responseString(Parcel &p, void *response, size_t responselen) {
+    /* one string only */
+    startResponse;
+    appendPrintBuf("%s%s", printBuf, (char*)response);
+    closeResponse;
+
+    writeStringToParcel(p, (const char *)response);
+    return 0;
+}
+
+static int responseVoid(Parcel &p, void *response, size_t responselen) {
+    startResponse;
+    removeLastChar;
+    return 0;
+}
+
+static int responseCallList(Parcel &p, void *response, size_t responselen) {
+    int num;
+
+    if (response == NULL && responselen != 0) {
+        RLOGE("invalid response: NULL");
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    if (responselen % sizeof (RIL_Call *) != 0) {
+        RLOGE("responseCallList: invalid response length %d expected multiple of %d\n",
+            (int)responselen, (int)sizeof (RIL_Call *));
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    startResponse;
+    /* number of call info's */
+    num = responselen / sizeof(RIL_Call *);
+    p.writeInt32(num);
+    for (int i = 0 ; i < num ; i++) {
+        RIL_Call *p_cur = ((RIL_Call **) response)[i];
+        /* each call info */
+        p.writeInt32(p_cur->state);
+        p.writeInt32(p_cur->index);
+        p.writeInt32(p_cur->toa);
+        p.writeInt32(p_cur->isMpty);
+        p.writeInt32(p_cur->isMT);
+        p.writeInt32(p_cur->als);
+        p.writeInt32(p_cur->isVoice);
+        p.writeInt32(p_cur->isVoicePrivacy);
+        writeStringToParcel(p, p_cur->number);
+        p.writeInt32(p_cur->numberPresentation);
+        writeStringToParcel(p, p_cur->name);
+        p.writeInt32(p_cur->namePresentation);
+        // Remove when partners upgrade to version 3
+        if ((s_callbacks.version < 3) || (p_cur->uusInfo == NULL || p_cur->uusInfo->uusData == NULL)) {
+            p.writeInt32(0); /* UUS Information is absent */
+        } else {
+            RIL_UUS_Info *uusInfo = p_cur->uusInfo;
+            p.writeInt32(1); /* UUS Information is present */
+            p.writeInt32(uusInfo->uusType);
+            p.writeInt32(uusInfo->uusDcs);
+            p.writeInt32(uusInfo->uusLength);
+            p.write(uusInfo->uusData, uusInfo->uusLength);
+        }
+        appendPrintBuf("%s[id=%d,%s,toa=%d,",
+            printBuf,
+            p_cur->index,
+            callStateToString(p_cur->state),
+            p_cur->toa);
+#if 0
+        appendPrintBuf("%s%s,%s,als=%d,%s,%s,",
+            printBuf,
+            (p_cur->isMpty)?"conf":"norm",
+            (p_cur->isMT)?"mt":"mo",
+            p_cur->als,
+            (p_cur->isVoice)?"voc":"nonvoc",
+            (p_cur->isVoicePrivacy)?"evp":"noevp");
+        appendPrintBuf("%s%s,cli=%d,name='%s',%d]",
+            printBuf,
+            p_cur->number,
+            p_cur->numberPresentation,
+            p_cur->name,
+            p_cur->namePresentation);
+#endif
+        if(p_cur->isMT&&(p_cur->state!=RIL_CALL_ACTIVE)) {
+            printf("[EVENT][MT_CALL] phone number is %s\n",p_cur->number);
+            RIL_SOCKET_ID soc_id = (RIL_SOCKET_ID)Phone_utils::get_enable_sim_for_dsss();
+            if(s_Env)
+            {
+                //printf("test incoming call start\n");
+                s_Env->incoming_call_cb(soc_id,p_cur->index,p_cur->number,p_cur->state,p_cur->toa);
+                s_callStatus=LYNQ_CALL_ON;
+                //printf("test incoming call end\n");
+            }
+        }
+    }
+    removeLastChar;
+    closeResponse;
+
+    return 0;
+}
+
+static int responseSMS(Parcel &p, void *response, size_t responselen) {
+    if (response == NULL) {
+        RLOGE("invalid response: NULL");
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    if (responselen != sizeof (RIL_SMS_Response) ) {
+        RLOGE("invalid response length %d expected %d",
+                (int)responselen, (int)sizeof (RIL_SMS_Response));
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    RIL_SMS_Response *p_cur = (RIL_SMS_Response *) response;
+
+    p.writeInt32(p_cur->messageRef);
+    writeStringToParcel(p, p_cur->ackPDU);
+    p.writeInt32(p_cur->errorCode);
+
+    startResponse;
+    appendPrintBuf("%s%d,%s,%d", printBuf, p_cur->messageRef,
+        (char*)p_cur->ackPDU, p_cur->errorCode);
+    closeResponse;
+    bool ifResend;
+    if(isGostEcall())
+    {
+        if(p_cur->errorCode == 0)
+        {
+            //delete MSD
+            gostDelSaveSmsData();
+            //no resend
+            ifResend = false;
+        }
+        else
+        {
+            //resend MSD
+            ifResend = true;
+        }
+        gostEcallResendMsd(ifResend);
+    }
+    return 0;
+}
+
+static int responseDataCallListV4(Parcel &p, void *response, size_t responselen)
+{
+    if (response == NULL && responselen != 0) {
+        RLOGE("invalid response: NULL");
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    if (responselen % sizeof(RIL_Data_Call_Response_v4) != 0) {
+        RLOGE("responseDataCallListV4: invalid response length %d expected multiple of %d",
+                (int)responselen, (int)sizeof(RIL_Data_Call_Response_v4));
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    // Write version
+    p.writeInt32(4);
+
+    int num = responselen / sizeof(RIL_Data_Call_Response_v4);
+    p.writeInt32(num);
+
+    RIL_Data_Call_Response_v4 *p_cur = (RIL_Data_Call_Response_v4 *) response;
+    startResponse;
+    int i;
+    for (i = 0; i < num; i++) {
+        p.writeInt32(p_cur[i].cid);
+        p.writeInt32(p_cur[i].active);
+        writeStringToParcel(p, p_cur[i].type);
+        // apn is not used, so don't send.
+        writeStringToParcel(p, p_cur[i].address);
+        appendPrintBuf("%s[cid=%d,%s,%s,%s],", printBuf,
+            p_cur[i].cid,
+            (p_cur[i].active==0)?"down":"up",
+            (char*)p_cur[i].type,
+            (char*)p_cur[i].address);
+    }
+    removeLastChar;
+    closeResponse;
+
+    return 0;
+}
+
+static int responseDataCallListV6(Parcel &p, void *response, size_t responselen)
+{
+    if (response == NULL && responselen != 0) {
+        RLOGE("invalid response: NULL");
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    if (responselen % sizeof(RIL_Data_Call_Response_v6) != 0) {
+        RLOGE("responseDataCallListV6: invalid response length %d expected multiple of %d",
+                (int)responselen, (int)sizeof(RIL_Data_Call_Response_v6));
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    // Write version
+    p.writeInt32(6);
+
+    int num = responselen / sizeof(RIL_Data_Call_Response_v6);
+    p.writeInt32(num);
+
+    RIL_Data_Call_Response_v6 *p_cur = (RIL_Data_Call_Response_v6 *) response;
+    startResponse;
+    int i;
+    for (i = 0; i < num; i++) {
+        p.writeInt32((int)p_cur[i].status);
+        p.writeInt32(p_cur[i].suggestedRetryTime);
+        p.writeInt32(p_cur[i].cid);
+        p.writeInt32(p_cur[i].active);
+        writeStringToParcel(p, p_cur[i].type);
+        writeStringToParcel(p, p_cur[i].ifname);
+        writeStringToParcel(p, p_cur[i].addresses);
+        writeStringToParcel(p, p_cur[i].dnses);
+        writeStringToParcel(p, p_cur[i].gateways);
+        appendPrintBuf("%s[status=%d,retry=%d,cid=%d,%s,%s,%s,%s,%s,%s],", printBuf,
+            p_cur[i].status,
+            p_cur[i].suggestedRetryTime,
+            p_cur[i].cid,
+            (p_cur[i].active==0)?"down":"up",
+            (char*)p_cur[i].type,
+            (char*)p_cur[i].ifname,
+            (char*)p_cur[i].addresses,
+            (char*)p_cur[i].dnses,
+            (char*)p_cur[i].gateways);
+    }
+    removeLastChar;
+    closeResponse;
+    return 0;
+}
+
+static int responseDataCallListV9(Parcel &p, void *response, size_t responselen)
+{
+    if (response == NULL && responselen != 0) {
+        RLOGE("invalid response: NULL");
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    if (responselen % sizeof(RIL_Data_Call_Response_v9) != 0) {
+        RLOGE("responseDataCallListV9: invalid response length %d expected multiple of %d",
+                (int)responselen, (int)sizeof(RIL_Data_Call_Response_v9));
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    // Write version
+    p.writeInt32(10);
+
+    int num = responselen / sizeof(RIL_Data_Call_Response_v9);
+    p.writeInt32(num);
+
+    RIL_Data_Call_Response_v9 *p_cur = (RIL_Data_Call_Response_v9 *) response;
+    startResponse;
+    int i;
+    for (i = 0; i < num; i++) {
+        p.writeInt32((int)p_cur[i].status);
+        p.writeInt32(p_cur[i].suggestedRetryTime);
+        p.writeInt32(p_cur[i].cid);
+        p.writeInt32(p_cur[i].active);
+        writeStringToParcel(p, p_cur[i].type);
+        writeStringToParcel(p, p_cur[i].ifname);
+        writeStringToParcel(p, p_cur[i].addresses);
+        writeStringToParcel(p, p_cur[i].dnses);
+        writeStringToParcel(p, p_cur[i].gateways);
+        writeStringToParcel(p, p_cur[i].pcscf);
+        appendPrintBuf("%s[status=%d,retry=%d,cid=%d,%s,%s,%s,%s,%s,%s,%s],", printBuf,
+            p_cur[i].status,
+            p_cur[i].suggestedRetryTime,
+            p_cur[i].cid,
+            (p_cur[i].active==0)?"down":"up",
+            (char*)p_cur[i].type,
+            (char*)p_cur[i].ifname,
+            (char*)p_cur[i].addresses,
+            (char*)p_cur[i].dnses,
+            (char*)p_cur[i].gateways,
+            (char*)p_cur[i].pcscf);
+    }
+    removeLastChar;
+    closeResponse;
+
+    return 0;
+}
+
+
+static int responseDataCallList(Parcel &p, void *response, size_t responselen)
+{
+    if (s_callbacks.version < 5) {
+        RLOGD("responseDataCallList: v4");
+        return responseDataCallListV4(p, response, responselen);
+    } else if (responselen % sizeof(RIL_Data_Call_Response_v6) == 0) {
+        return responseDataCallListV6(p, response, responselen);
+    } else if (responselen % sizeof(RIL_Data_Call_Response_v9) == 0) {
+        return responseDataCallListV9(p, response, responselen);
+    } else {
+        if (response == NULL && responselen != 0) {
+            RLOGE("invalid response: NULL");
+            return RIL_ERRNO_INVALID_RESPONSE;
+        }
+
+        if (responselen % sizeof(RIL_Data_Call_Response_v11) != 0) {
+            RLOGE("invalid response length %d expected multiple of %d",
+                    (int)responselen, (int)sizeof(RIL_Data_Call_Response_v11));
+            return RIL_ERRNO_INVALID_RESPONSE;
+        }
+
+        // Write version
+        p.writeInt32(11);
+
+        int num = responselen / sizeof(RIL_Data_Call_Response_v11);
+        p.writeInt32(num);
+
+        RIL_Data_Call_Response_v11 *p_cur = (RIL_Data_Call_Response_v11 *) response;
+        startResponse;
+        int i;
+        for (i = 0; i < num; i++) {
+            p.writeInt32((int)p_cur[i].status);
+            p.writeInt32(p_cur[i].suggestedRetryTime);
+            p.writeInt32(p_cur[i].cid);
+            p.writeInt32(p_cur[i].active);
+            writeStringToParcel(p, p_cur[i].type);
+            writeStringToParcel(p, p_cur[i].ifname);
+            writeStringToParcel(p, p_cur[i].addresses);
+            writeStringToParcel(p, p_cur[i].dnses);
+            writeStringToParcel(p, p_cur[i].gateways);
+            writeStringToParcel(p, p_cur[i].pcscf);
+            p.writeInt32(p_cur[i].mtu);
+            appendPrintBuf("%s[status=%d,retry=%d,cid=%d,%s,%s,%s,%s,%s,%s,%s,mtu=%d],", printBuf,
+                p_cur[i].status,
+                p_cur[i].suggestedRetryTime,
+                p_cur[i].cid,
+                (p_cur[i].active==0)?"down":"up",
+                (char*)p_cur[i].type,
+                (char*)p_cur[i].ifname,
+                (char*)p_cur[i].addresses,
+                (char*)p_cur[i].dnses,
+                (char*)p_cur[i].gateways,
+                (char*)p_cur[i].pcscf,
+                p_cur[i].mtu);
+        }
+        removeLastChar;
+        closeResponse;
+    }
+
+    return 0;
+}
+
+static int responseSetupDataCall(Parcel &p, void *response, size_t responselen)
+{
+    if (s_callbacks.version < 5) {
+        return responseStringsWithVersion(s_callbacks.version, p, response, responselen);
+    } else {
+        return responseDataCallList(p, response, responselen);
+    }
+}
+
+static int responseRaw(Parcel &p, void *response, size_t responselen) {
+    if (response == NULL && responselen != 0) {
+        RLOGE("invalid response: NULL with responselen != 0");
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    // The java code reads -1 size as null byte array
+    if (response == NULL) {
+        p.writeInt32(-1);
+    } else {
+        p.writeInt32(responselen);
+        p.write(response, responselen);
+    }
+
+    startResponse;
+    appendPrintBuf("%slen=%d,%s", printBuf, responselen, (char*)response);
+    closeResponse;
+    return 0;
+}
+
+
+static int responseSIM_IO(Parcel &p, void *response, size_t responselen) {
+    if (response == NULL) {
+        RLOGE("invalid response: NULL");
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    if (responselen != sizeof (RIL_SIM_IO_Response) ) {
+        RLOGE("invalid response length was %d expected %d",
+                (int)responselen, (int)sizeof (RIL_SIM_IO_Response));
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    RIL_SIM_IO_Response *p_cur = (RIL_SIM_IO_Response *) response;
+    p.writeInt32(p_cur->sw1);
+    p.writeInt32(p_cur->sw2);
+    writeStringToParcel(p, p_cur->simResponse);
+
+    startResponse;
+    appendPrintBuf("%ssw1=0x%X,sw2=0x%X,%s", printBuf, p_cur->sw1, p_cur->sw2,
+        (char*)p_cur->simResponse);
+    closeResponse;
+
+
+    return 0;
+}
+
+static int responseCallForwards(Parcel &p, void *response, size_t responselen) {
+    int num;
+
+    if (response == NULL && responselen != 0) {
+        RLOGE("invalid response: NULL");
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    if (responselen % sizeof(RIL_CallForwardInfo *) != 0) {
+        RLOGE("responseCallForwards: invalid response length %d expected multiple of %d",
+                (int)responselen, (int)sizeof(RIL_CallForwardInfo *));
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    /* number of call info's */
+    num = responselen / sizeof(RIL_CallForwardInfo *);
+    p.writeInt32(num);
+
+    startResponse;
+    for (int i = 0 ; i < num ; i++) {
+        RIL_CallForwardInfo *p_cur = ((RIL_CallForwardInfo **) response)[i];
+
+        p.writeInt32(p_cur->status);
+        p.writeInt32(p_cur->reason);
+        p.writeInt32(p_cur->serviceClass);
+        p.writeInt32(p_cur->toa);
+        writeStringToParcel(p, p_cur->number);
+        p.writeInt32(p_cur->timeSeconds);
+        appendPrintBuf("%s[%s,reason=%d,cls=%d,toa=%d,%s,tout=%d],", printBuf,
+            (p_cur->status==1)?"enable":"disable",
+            p_cur->reason, p_cur->serviceClass, p_cur->toa,
+            (char*)p_cur->number,
+            p_cur->timeSeconds);
+    }
+    removeLastChar;
+    closeResponse;
+
+    return 0;
+}
+
+static int responseSsn(Parcel &p, void *response, size_t responselen) {
+    if (response == NULL) {
+        RLOGE("invalid response: NULL");
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    if (responselen != sizeof(RIL_SuppSvcNotification)) {
+        RLOGE("invalid response length was %d expected %d",
+                (int)responselen, (int)sizeof (RIL_SuppSvcNotification));
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    RIL_SuppSvcNotification *p_cur = (RIL_SuppSvcNotification *) response;
+    p.writeInt32(p_cur->notificationType);
+    p.writeInt32(p_cur->code);
+    p.writeInt32(p_cur->index);
+    p.writeInt32(p_cur->type);
+    writeStringToParcel(p, p_cur->number);
+
+    startResponse;
+    appendPrintBuf("%s%s,code=%d,id=%d,type=%d,%s", printBuf,
+        (p_cur->notificationType==0)?"mo":"mt",
+         p_cur->code, p_cur->index, p_cur->type,
+        (char*)p_cur->number);
+    closeResponse;
+
+    return 0;
+}
+
+static int responseCellList(Parcel &p, void *response, size_t responselen) {
+    int num;
+
+    if (response == NULL && responselen != 0) {
+        RLOGE("invalid response: NULL");
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    if (responselen % sizeof (RIL_NeighboringCell *) != 0) {
+        RLOGE("responseCellList: invalid response length %d expected multiple of %d\n",
+            (int)responselen, (int)sizeof (RIL_NeighboringCell *));
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    startResponse;
+    /* number of records */
+    num = responselen / sizeof(RIL_NeighboringCell *);
+    p.writeInt32(num);
+
+    for (int i = 0 ; i < num ; i++) {
+        RIL_NeighboringCell *p_cur = ((RIL_NeighboringCell **) response)[i];
+
+        p.writeInt32(p_cur->rssi);
+        writeStringToParcel (p, p_cur->cid);
+
+        appendPrintBuf("%s[cid=%s,rssi=%d],", printBuf,
+            p_cur->cid, p_cur->rssi);
+    }
+    removeLastChar;
+    closeResponse;
+
+    return 0;
+}
+
+/**
+ * Marshall the signalInfoRecord into the parcel if it exists.
+ */
+static void marshallSignalInfoRecord(Parcel &p,
+            RIL_CDMA_SignalInfoRecord &p_signalInfoRecord) {
+    p.writeInt32(p_signalInfoRecord.isPresent);
+    p.writeInt32(p_signalInfoRecord.signalType);
+    p.writeInt32(p_signalInfoRecord.alertPitch);
+    p.writeInt32(p_signalInfoRecord.signal);
+}
+
+static int responseCdmaInformationRecords(Parcel &p,
+            void *response, size_t responselen) {
+    int num;
+    char* string8 = NULL;
+    int buffer_lenght;
+    RIL_CDMA_InformationRecord *infoRec;
+
+    if (response == NULL && responselen != 0) {
+        RLOGE("invalid response: NULL");
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    if (responselen != sizeof (RIL_CDMA_InformationRecords)) {
+        RLOGE("responseCdmaInformationRecords: invalid response length %d expected multiple of %d\n",
+            (int)responselen, (int)sizeof (RIL_CDMA_InformationRecords *));
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    RIL_CDMA_InformationRecords *p_cur =
+                             (RIL_CDMA_InformationRecords *) response;
+    num = MIN(p_cur->numberOfInfoRecs, RIL_CDMA_MAX_NUMBER_OF_INFO_RECS);
+
+    startResponse;
+    p.writeInt32(num);
+
+    for (int i = 0 ; i < num ; i++) {
+        infoRec = &p_cur->infoRec[i];
+        p.writeInt32(infoRec->name);
+        switch (infoRec->name) {
+            case RIL_CDMA_DISPLAY_INFO_REC:
+            case RIL_CDMA_EXTENDED_DISPLAY_INFO_REC:
+                if (infoRec->rec.display.alpha_len >
+                                         CDMA_ALPHA_INFO_BUFFER_LENGTH) {
+                    RLOGE("invalid display info response length %d \
+                          expected not more than %d\n",
+                         (int)infoRec->rec.display.alpha_len,
+                         CDMA_ALPHA_INFO_BUFFER_LENGTH);
+                    return RIL_ERRNO_INVALID_RESPONSE;
+                }
+                string8 = (char*) malloc((infoRec->rec.display.alpha_len + 1)
+                                                             * sizeof(char) );
+                for (int i = 0 ; i < infoRec->rec.display.alpha_len ; i++) {
+                    string8[i] = infoRec->rec.display.alpha_buf[i];
+                }
+                string8[(int)infoRec->rec.display.alpha_len] = '\0';
+                writeStringToParcel(p, (const char*)string8);
+                free(string8);
+                string8 = NULL;
+                break;
+            case RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC:
+            case RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC:
+            case RIL_CDMA_CONNECTED_NUMBER_INFO_REC:
+                if (infoRec->rec.number.len > CDMA_NUMBER_INFO_BUFFER_LENGTH) {
+                    RLOGE("invalid display info response length %d \
+                          expected not more than %d\n",
+                         (int)infoRec->rec.number.len,
+                         CDMA_NUMBER_INFO_BUFFER_LENGTH);
+                    return RIL_ERRNO_INVALID_RESPONSE;
+                }
+                string8 = (char*) malloc((infoRec->rec.number.len + 1)
+                                                             * sizeof(char) );
+                for (int i = 0 ; i < infoRec->rec.number.len; i++) {
+                    string8[i] = infoRec->rec.number.buf[i];
+                }
+                string8[(int)infoRec->rec.number.len] = '\0';
+                writeStringToParcel(p, (const char*)string8);
+                free(string8);
+                string8 = NULL;
+                p.writeInt32(infoRec->rec.number.number_type);
+                p.writeInt32(infoRec->rec.number.number_plan);
+                p.writeInt32(infoRec->rec.number.pi);
+                p.writeInt32(infoRec->rec.number.si);
+                break;
+            case RIL_CDMA_SIGNAL_INFO_REC:
+                p.writeInt32(infoRec->rec.signal.isPresent);
+                p.writeInt32(infoRec->rec.signal.signalType);
+                p.writeInt32(infoRec->rec.signal.alertPitch);
+                p.writeInt32(infoRec->rec.signal.signal);
+
+                appendPrintBuf("%sisPresent=%X, signalType=%X, \
+                                alertPitch=%X, signal=%X, ",
+                   printBuf, (int)infoRec->rec.signal.isPresent,
+                   (int)infoRec->rec.signal.signalType,
+                   (int)infoRec->rec.signal.alertPitch,
+                   (int)infoRec->rec.signal.signal);
+                removeLastChar;
+                break;
+            case RIL_CDMA_REDIRECTING_NUMBER_INFO_REC:
+                if (infoRec->rec.redir.redirectingNumber.len >
+                                              CDMA_NUMBER_INFO_BUFFER_LENGTH) {
+                    RLOGE("invalid display info response length %d \
+                          expected not more than %d\n",
+                         (int)infoRec->rec.redir.redirectingNumber.len,
+                         CDMA_NUMBER_INFO_BUFFER_LENGTH);
+                    return RIL_ERRNO_INVALID_RESPONSE;
+                }
+                string8 = (char*) malloc((infoRec->rec.redir.redirectingNumber
+                                          .len + 1) * sizeof(char) );
+                for (int i = 0;
+                         i < infoRec->rec.redir.redirectingNumber.len;
+                         i++) {
+                    string8[i] = infoRec->rec.redir.redirectingNumber.buf[i];
+                }
+                string8[(int)infoRec->rec.redir.redirectingNumber.len] = '\0';
+                writeStringToParcel(p, (const char*)string8);
+                free(string8);
+                string8 = NULL;
+                p.writeInt32(infoRec->rec.redir.redirectingNumber.number_type);
+                p.writeInt32(infoRec->rec.redir.redirectingNumber.number_plan);
+                p.writeInt32(infoRec->rec.redir.redirectingNumber.pi);
+                p.writeInt32(infoRec->rec.redir.redirectingNumber.si);
+                p.writeInt32(infoRec->rec.redir.redirectingReason);
+                break;
+            case RIL_CDMA_LINE_CONTROL_INFO_REC:
+                p.writeInt32(infoRec->rec.lineCtrl.lineCtrlPolarityIncluded);
+                p.writeInt32(infoRec->rec.lineCtrl.lineCtrlToggle);
+                p.writeInt32(infoRec->rec.lineCtrl.lineCtrlReverse);
+                p.writeInt32(infoRec->rec.lineCtrl.lineCtrlPowerDenial);
+
+                appendPrintBuf("%slineCtrlPolarityIncluded=%d, \
+                                lineCtrlToggle=%d, lineCtrlReverse=%d, \
+                                lineCtrlPowerDenial=%d, ", printBuf,
+                       (int)infoRec->rec.lineCtrl.lineCtrlPolarityIncluded,
+                       (int)infoRec->rec.lineCtrl.lineCtrlToggle,
+                       (int)infoRec->rec.lineCtrl.lineCtrlReverse,
+                       (int)infoRec->rec.lineCtrl.lineCtrlPowerDenial);
+                removeLastChar;
+                break;
+            case RIL_CDMA_T53_CLIR_INFO_REC:
+                p.writeInt32((int)(infoRec->rec.clir.cause));
+
+                appendPrintBuf("%scause%d", printBuf, infoRec->rec.clir.cause);
+                removeLastChar;
+                break;
+            case RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC:
+                p.writeInt32(infoRec->rec.audioCtrl.upLink);
+                p.writeInt32(infoRec->rec.audioCtrl.downLink);
+
+                appendPrintBuf("%supLink=%d, downLink=%d, ", printBuf,
+                        infoRec->rec.audioCtrl.upLink,
+                        infoRec->rec.audioCtrl.downLink);
+                removeLastChar;
+                break;
+            case RIL_CDMA_T53_RELEASE_INFO_REC:
+                // TODO(Moto): See David Krause, he has the answer:)
+                RLOGE("RIL_CDMA_T53_RELEASE_INFO_REC: return INVALID_RESPONSE");
+                return RIL_ERRNO_INVALID_RESPONSE;
+            default:
+                RLOGE("Incorrect name value");
+                return RIL_ERRNO_INVALID_RESPONSE;
+        }
+    }
+    closeResponse;
+
+    return 0;
+}
+
+static int responseRilSignalStrength(Parcel &p,
+                    void *response, size_t responselen) {
+    if (response == NULL && responselen != 0) {
+        RLOGE("invalid response: NULL");
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    if (responselen >= sizeof (RIL_SignalStrength_v5)) {
+        RIL_SignalStrength_v10 *p_cur = ((RIL_SignalStrength_v10 *) response);
+
+        p.writeInt32(p_cur->GW_SignalStrength.signalStrength);
+        p.writeInt32(p_cur->GW_SignalStrength.bitErrorRate);
+        p.writeInt32(p_cur->GW_SignalStrength.timingAdvance);
+        p.writeInt32(p_cur->CDMA_SignalStrength.dbm);
+        p.writeInt32(p_cur->CDMA_SignalStrength.ecio);
+        p.writeInt32(p_cur->EVDO_SignalStrength.dbm);
+        p.writeInt32(p_cur->EVDO_SignalStrength.ecio);
+        p.writeInt32(p_cur->EVDO_SignalStrength.signalNoiseRatio);
+        p.writeInt32(p_cur->LTE_SignalStrength.signalStrength);
+        p.writeInt32(p_cur->LTE_SignalStrength.rsrp);
+        p.writeInt32(p_cur->LTE_SignalStrength.rsrq);
+        p.writeInt32(p_cur->LTE_SignalStrength.rssnr);
+        p.writeInt32(p_cur->LTE_SignalStrength.cqi);
+        p.writeInt32(p_cur->LTE_SignalStrength.timingAdvance);
+        p.writeInt32(p_cur->TD_SCDMA_SignalStrength.signalStrength);
+        p.writeInt32(p_cur->TD_SCDMA_SignalStrength.bitErrorRate);
+        p.writeInt32(p_cur->TD_SCDMA_SignalStrength.rscp);
+        p.writeInt32(p_cur->WCDMA_SignalStrength.signalStrength);
+        p.writeInt32(p_cur->WCDMA_SignalStrength.bitErrorRate);
+        p.writeInt32(p_cur->WCDMA_SignalStrength.rscp);
+        p.writeInt32(p_cur->WCDMA_SignalStrength.ecno);
+
+        startResponse;
+        appendPrintBuf("%s[GW_SS.signalStrength=%d,GW_SS.bitErrorRate=%d,GW_SS.timingAdvance=%d,\
+                CDMA_SS.dbm=%d,CDMA_SS.ecio=%d,\
+                EVDO_SS.dbm=%d,EVDO_SS.ecio=%d,EVDO_SS.signalNoiseRatio=%d,\
+                LTE_SS.signalStrength=%d,LTE_SS.rsrp=%d,LTE_SS.rsrq=%d,LTE_SS.rssnr=%d,LTE_SS.cqi=%d,LTE_SS.timingAdvance=%d,\
+                TDSCDMA_SS.signalStrength=%d,TDSCDMA_SS.bitErrorRate=%d,TDSCDMA_SS.rscp=%d,\
+                WCDMA_SS.signalStrength=%d,WCDMA_SS.bitErrorRate=%d,WCDMA_SS.rscp=%d,WCDMA_SS.ecno=%d]",
+                printBuf,
+                p_cur->GW_SignalStrength.signalStrength,
+                p_cur->GW_SignalStrength.bitErrorRate,
+                p_cur->GW_SignalStrength.timingAdvance,
+                p_cur->CDMA_SignalStrength.dbm,
+                p_cur->CDMA_SignalStrength.ecio,
+                p_cur->EVDO_SignalStrength.dbm,
+                p_cur->EVDO_SignalStrength.ecio,
+                p_cur->EVDO_SignalStrength.signalNoiseRatio,
+                p_cur->LTE_SignalStrength.signalStrength,
+                p_cur->LTE_SignalStrength.rsrp,
+                p_cur->LTE_SignalStrength.rsrq,
+                p_cur->LTE_SignalStrength.rssnr,
+                p_cur->LTE_SignalStrength.cqi,
+                p_cur->LTE_SignalStrength.timingAdvance,
+                p_cur->TD_SCDMA_SignalStrength.signalStrength,
+                p_cur->TD_SCDMA_SignalStrength.bitErrorRate,
+                p_cur->TD_SCDMA_SignalStrength.rscp,
+                p_cur->WCDMA_SignalStrength.signalStrength,
+                p_cur->WCDMA_SignalStrength.bitErrorRate,
+                p_cur->WCDMA_SignalStrength.rscp,
+                p_cur->WCDMA_SignalStrength.ecno);
+        closeResponse;
+
+        if (signal_strength_printf != 0) {
+            printf(
+                    "\n\n[QUERY][SIGNAL]\nsignalStrength=%d,\nbitErrorRate=%d,\nLTE_SS.signalStrength=%d,\n"
+                            "LTE_SS.rsrp=%d,\nLTE_SS.rsrq=%d,\nLTE_SS.rssnr=%d,\nLTE_SS.cqi=%d\n\n",
+                    p_cur->GW_SignalStrength.signalStrength,
+                    p_cur->GW_SignalStrength.bitErrorRate,
+                    p_cur->LTE_SignalStrength.signalStrength,
+                    p_cur->LTE_SignalStrength.rsrp,
+                    p_cur->LTE_SignalStrength.rsrq,
+                    p_cur->LTE_SignalStrength.rssnr,
+                    p_cur->LTE_SignalStrength.cqi);
+        }
+    } else {
+        RLOGE("invalid response length");
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    return 0;
+}
+
+static int responseCallRing(Parcel &p, void *response, size_t responselen) {
+    if ((response == NULL) || (responselen == 0)) {
+        return responseVoid(p, response, responselen);
+    } else {
+        return responseCdmaSignalInfoRecord(p, response, responselen);
+    }
+}
+
+static int responseCdmaSignalInfoRecord(Parcel &p, void *response, size_t responselen) {
+    if (response == NULL || responselen == 0) {
+        RLOGE("invalid response: NULL");
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    if (responselen != sizeof (RIL_CDMA_SignalInfoRecord)) {
+        RLOGE("invalid response length %d expected sizeof (RIL_CDMA_SignalInfoRecord) of %d\n",
+            (int)responselen, (int)sizeof (RIL_CDMA_SignalInfoRecord));
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    startResponse;
+
+    RIL_CDMA_SignalInfoRecord *p_cur = ((RIL_CDMA_SignalInfoRecord *) response);
+    marshallSignalInfoRecord(p, *p_cur);
+
+    appendPrintBuf("%s[isPresent=%d,signalType=%d,alertPitch=%d\
+              signal=%d]",
+              printBuf,
+              p_cur->isPresent,
+              p_cur->signalType,
+              p_cur->alertPitch,
+              p_cur->signal);
+
+    closeResponse;
+    return 0;
+}
+
+static int responseCdmaCallWaiting(Parcel &p, void *response,
+            size_t responselen) {
+    if (response == NULL && responselen != 0) {
+        RLOGE("invalid response: NULL");
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    if (responselen < sizeof(RIL_CDMA_CallWaiting_v6)) {
+        RLOGW("Upgrade to ril version %d\n", RIL_VERSION);
+    }
+
+    RIL_CDMA_CallWaiting_v6 *p_cur = ((RIL_CDMA_CallWaiting_v6 *) response);
+
+    writeStringToParcel(p, p_cur->number);
+    p.writeInt32(p_cur->numberPresentation);
+    writeStringToParcel(p, p_cur->name);
+    marshallSignalInfoRecord(p, p_cur->signalInfoRecord);
+
+    if (responselen >= sizeof(RIL_CDMA_CallWaiting_v6)) {
+        p.writeInt32(p_cur->number_type);
+        p.writeInt32(p_cur->number_plan);
+    } else {
+        p.writeInt32(0);
+        p.writeInt32(0);
+    }
+
+    printf("[EVENT][MT_CALL] phone number is %s\n",p_cur->number);
+    startResponse;
+    appendPrintBuf("%snumber=%s,numberPresentation=%d, name=%s,\
+            signalInfoRecord[isPresent=%d,signalType=%d,alertPitch=%d\
+            signal=%d,number_type=%d,number_plan=%d]",
+            printBuf,
+            p_cur->number,
+            p_cur->numberPresentation,
+            p_cur->name,
+            p_cur->signalInfoRecord.isPresent,
+            p_cur->signalInfoRecord.signalType,
+            p_cur->signalInfoRecord.alertPitch,
+            p_cur->signalInfoRecord.signal,
+            p_cur->number_type,
+            p_cur->number_plan);
+    closeResponse;
+
+    return 0;
+}
+
+static int responseSimRefresh(Parcel &p, void *response, size_t responselen) {
+    if (response == NULL && responselen != 0) {
+        RLOGE("responseSimRefresh: invalid response: NULL");
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    startResponse;
+    if (s_callbacks.version == 7) {
+        RIL_SimRefreshResponse_v7 *p_cur = ((RIL_SimRefreshResponse_v7 *) response);
+        p.writeInt32(p_cur->result);
+        p.writeInt32(p_cur->ef_id);
+        writeStringToParcel(p, p_cur->aid);
+
+        appendPrintBuf("%sresult=%d, ef_id=%d, aid=%s",
+                printBuf,
+                p_cur->result,
+                p_cur->ef_id,
+                p_cur->aid);
+    } else {
+        int *p_cur = ((int *) response);
+        p.writeInt32(p_cur[0]);
+        p.writeInt32(p_cur[1]);
+        writeStringToParcel(p, NULL);
+
+        appendPrintBuf("%sresult=%d, ef_id=%d",
+                printBuf,
+                p_cur[0],
+                p_cur[1]);
+    }
+    closeResponse;
+
+    return 0;
+}
+
+static int responseCellInfoList(Parcel &p, void *response, size_t responselen)
+{
+    if (response == NULL && responselen != 0) {
+        RLOGE("invalid response: NULL");
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    if (responselen % sizeof(RIL_CellInfo) != 0) {
+        RLOGE("responseCellInfoList: invalid response length %d expected multiple of %d",
+                (int)responselen, (int)sizeof(RIL_CellInfo));
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    int num = responselen / sizeof(RIL_CellInfo);
+    p.writeInt32(num);
+
+    RIL_CellInfo *p_cur = (RIL_CellInfo *) response;
+    startResponse;
+    int i;
+    for (i = 0; i < num; i++) {
+        appendPrintBuf("%s[%d: type=%d,registered=%d,timeStampType=%d,timeStamp=%lld", printBuf, i,
+            p_cur->cellInfoType, p_cur->registered, p_cur->timeStampType, p_cur->timeStamp);
+        p.writeInt32((int)p_cur->cellInfoType);
+        p.writeInt32(p_cur->registered);
+        p.writeInt32(p_cur->timeStampType);
+        p.writeInt64(p_cur->timeStamp);
+        switch(p_cur->cellInfoType) {
+            case RIL_CELL_INFO_TYPE_GSM: {
+                appendPrintBuf("%s GSM id: mcc=%d,mnc=%d,lac=%d,cid=%d,", printBuf,
+                    p_cur->CellInfo.gsm.cellIdentityGsm.mcc,
+                    p_cur->CellInfo.gsm.cellIdentityGsm.mnc,
+                    p_cur->CellInfo.gsm.cellIdentityGsm.lac,
+                    p_cur->CellInfo.gsm.cellIdentityGsm.cid);
+                appendPrintBuf("%s gsmSS: ss=%d,ber=%d],", printBuf,
+                    p_cur->CellInfo.gsm.signalStrengthGsm.signalStrength,
+                    p_cur->CellInfo.gsm.signalStrengthGsm.bitErrorRate);
+
+                p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.mcc);
+                p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.mnc);
+                p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.lac);
+                p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.cid);
+                p.writeInt32(p_cur->CellInfo.gsm.signalStrengthGsm.signalStrength);
+                p.writeInt32(p_cur->CellInfo.gsm.signalStrengthGsm.bitErrorRate);
+                break;
+            }
+            case RIL_CELL_INFO_TYPE_WCDMA: {
+                appendPrintBuf("%s WCDMA id: mcc=%d,mnc=%d,lac=%d,cid=%d,psc=%d,", printBuf,
+                    p_cur->CellInfo.wcdma.cellIdentityWcdma.mcc,
+                    p_cur->CellInfo.wcdma.cellIdentityWcdma.mnc,
+                    p_cur->CellInfo.wcdma.cellIdentityWcdma.lac,
+                    p_cur->CellInfo.wcdma.cellIdentityWcdma.cid,
+                    p_cur->CellInfo.wcdma.cellIdentityWcdma.psc);
+                appendPrintBuf("%s wcdmaSS: ss=%d,ber=%d],", printBuf,
+                    p_cur->CellInfo.wcdma.signalStrengthWcdma.signalStrength,
+                    p_cur->CellInfo.wcdma.signalStrengthWcdma.bitErrorRate);
+
+                p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.mcc);
+                p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.mnc);
+                p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.lac);
+                p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.cid);
+                p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.psc);
+                p.writeInt32(p_cur->CellInfo.wcdma.signalStrengthWcdma.signalStrength);
+                p.writeInt32(p_cur->CellInfo.wcdma.signalStrengthWcdma.bitErrorRate);
+                break;
+            }
+            case RIL_CELL_INFO_TYPE_CDMA: {
+                appendPrintBuf("%s CDMA id: nId=%d,sId=%d,bsId=%d,long=%d,lat=%d", printBuf,
+                    p_cur->CellInfo.cdma.cellIdentityCdma.networkId,
+                    p_cur->CellInfo.cdma.cellIdentityCdma.systemId,
+                    p_cur->CellInfo.cdma.cellIdentityCdma.basestationId,
+                    p_cur->CellInfo.cdma.cellIdentityCdma.longitude,
+                    p_cur->CellInfo.cdma.cellIdentityCdma.latitude);
+
+                p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.networkId);
+                p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.systemId);
+                p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.basestationId);
+                p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.longitude);
+                p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.latitude);
+
+                appendPrintBuf("%s cdmaSS: dbm=%d ecio=%d evdoSS: dbm=%d,ecio=%d,snr=%d", printBuf,
+                    p_cur->CellInfo.cdma.signalStrengthCdma.dbm,
+                    p_cur->CellInfo.cdma.signalStrengthCdma.ecio,
+                    p_cur->CellInfo.cdma.signalStrengthEvdo.dbm,
+                    p_cur->CellInfo.cdma.signalStrengthEvdo.ecio,
+                    p_cur->CellInfo.cdma.signalStrengthEvdo.signalNoiseRatio);
+
+                p.writeInt32(p_cur->CellInfo.cdma.signalStrengthCdma.dbm);
+                p.writeInt32(p_cur->CellInfo.cdma.signalStrengthCdma.ecio);
+                p.writeInt32(p_cur->CellInfo.cdma.signalStrengthEvdo.dbm);
+                p.writeInt32(p_cur->CellInfo.cdma.signalStrengthEvdo.ecio);
+                p.writeInt32(p_cur->CellInfo.cdma.signalStrengthEvdo.signalNoiseRatio);
+                break;
+            }
+            case RIL_CELL_INFO_TYPE_LTE: {
+                appendPrintBuf("%s LTE id: mcc=%d,mnc=%d,ci=%d,pci=%d,tac=%d", printBuf,
+                    p_cur->CellInfo.lte.cellIdentityLte.mcc,
+                    p_cur->CellInfo.lte.cellIdentityLte.mnc,
+                    p_cur->CellInfo.lte.cellIdentityLte.ci,
+                    p_cur->CellInfo.lte.cellIdentityLte.pci,
+                    p_cur->CellInfo.lte.cellIdentityLte.tac);
+
+                p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.mcc);
+                p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.mnc);
+                p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.ci);
+                p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.pci);
+                p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.tac);
+
+                appendPrintBuf("%s lteSS: ss=%d,rsrp=%d,rsrq=%d,rssnr=%d,cqi=%d,ta=%d", printBuf,
+                    p_cur->CellInfo.lte.signalStrengthLte.signalStrength,
+                    p_cur->CellInfo.lte.signalStrengthLte.rsrp,
+                    p_cur->CellInfo.lte.signalStrengthLte.rsrq,
+                    p_cur->CellInfo.lte.signalStrengthLte.rssnr,
+                    p_cur->CellInfo.lte.signalStrengthLte.cqi,
+                    p_cur->CellInfo.lte.signalStrengthLte.timingAdvance);
+                p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.signalStrength);
+                p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.rsrp);
+                p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.rsrq);
+                p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.rssnr);
+                p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.cqi);
+                p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.timingAdvance);
+                break;
+            }
+            case RIL_CELL_INFO_TYPE_TD_SCDMA: {
+                appendPrintBuf("%s TDSCDMA id: mcc=%d,mnc=%d,lac=%d,cid=%d,cpid=%d,", printBuf,
+                    p_cur->CellInfo.tdscdma.cellIdentityTdscdma.mcc,
+                    p_cur->CellInfo.tdscdma.cellIdentityTdscdma.mnc,
+                    p_cur->CellInfo.tdscdma.cellIdentityTdscdma.lac,
+                    p_cur->CellInfo.tdscdma.cellIdentityTdscdma.cid,
+                    p_cur->CellInfo.tdscdma.cellIdentityTdscdma.cpid);
+                appendPrintBuf("%s tdscdmaSS: rscp=%d],", printBuf,
+                    p_cur->CellInfo.tdscdma.signalStrengthTdscdma.rscp);
+
+                p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.mcc);
+                p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.mnc);
+                p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.lac);
+                p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.cid);
+                p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.cpid);
+                p.writeInt32(p_cur->CellInfo.tdscdma.signalStrengthTdscdma.rscp);
+                break;
+            }
+        }
+        p_cur += 1;
+    }
+    removeLastChar;
+    closeResponse;
+
+    return 0;
+}
+
+static int responseHardwareConfig(Parcel &p, void *response, size_t responselen)
+{
+   if (response == NULL && responselen != 0) {
+       RLOGE("invalid response: NULL");
+       return RIL_ERRNO_INVALID_RESPONSE;
+   }
+
+   if (responselen % sizeof(RIL_HardwareConfig) != 0) {
+       RLOGE("responseHardwareConfig: invalid response length %d expected multiple of %d",
+          (int)responselen, (int)sizeof(RIL_HardwareConfig));
+       return RIL_ERRNO_INVALID_RESPONSE;
+   }
+
+   int num = responselen / sizeof(RIL_HardwareConfig);
+   int i;
+   RIL_HardwareConfig *p_cur = (RIL_HardwareConfig *) response;
+
+   p.writeInt32(num);
+
+   startResponse;
+   for (i = 0; i < num; i++) {
+      switch (p_cur[i].type) {
+         case RIL_HARDWARE_CONFIG_MODEM: {
+            writeStringToParcel(p, p_cur[i].uuid);
+            p.writeInt32((int)p_cur[i].state);
+            p.writeInt32(p_cur[i].cfg.modem.rat);
+            p.writeInt32(p_cur[i].cfg.modem.maxVoice);
+            p.writeInt32(p_cur[i].cfg.modem.maxData);
+            p.writeInt32(p_cur[i].cfg.modem.maxStandby);
+
+            appendPrintBuf("%s modem: uuid=%s,state=%d,rat=%08x,maxV=%d,maxD=%d,maxS=%d", printBuf,
+               p_cur[i].uuid, (int)p_cur[i].state, p_cur[i].cfg.modem.rat,
+               p_cur[i].cfg.modem.maxVoice, p_cur[i].cfg.modem.maxData, p_cur[i].cfg.modem.maxStandby);
+            break;
+         }
+         case RIL_HARDWARE_CONFIG_SIM: {
+            writeStringToParcel(p, p_cur[i].uuid);
+            p.writeInt32((int)p_cur[i].state);
+            writeStringToParcel(p, p_cur[i].cfg.sim.modemUuid);
+
+            appendPrintBuf("%s sim: uuid=%s,state=%d,modem-uuid=%s", printBuf,
+               p_cur[i].uuid, (int)p_cur[i].state, p_cur[i].cfg.sim.modemUuid);
+            break;
+         }
+      }
+   }
+   removeLastChar;
+   closeResponse;
+   return 0;
+}
+
+static int responseRadioCapability(Parcel &p, void *response, size_t responselen) {
+    if (response == NULL) {
+        RLOGE("invalid response: NULL");
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    if (responselen != sizeof (RIL_RadioCapability) ) {
+        RLOGE("invalid response length was %d expected %d",
+                (int)responselen, (int)sizeof (RIL_SIM_IO_Response));
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    RIL_RadioCapability *p_cur = (RIL_RadioCapability *) response;
+    p.writeInt32(p_cur->version);
+    p.writeInt32(p_cur->session);
+    p.writeInt32(p_cur->phase);
+    p.writeInt32(p_cur->rat);
+    writeStringToParcel(p, p_cur->logicalModemUuid);
+    p.writeInt32(p_cur->status);
+
+    startResponse;
+    appendPrintBuf("%s[version=%d,session=%d,phase=%d,\
+            rat=%d,logicalModemUuid=%s,status=%d]",
+            printBuf,
+            p_cur->version,
+            p_cur->session,
+            p_cur->phase,
+            p_cur->rat,
+            p_cur->logicalModemUuid,
+            p_cur->status);
+    closeResponse;
+    return 0;
+}
+
+static int responseSSData(Parcel &p, void *response, size_t responselen) {
+    RLOGD("In responseSSData");
+    int num;
+
+    if (response == NULL && responselen != 0) {
+        RLOGE("invalid response length was %d expected %d",
+                (int)responselen, (int)sizeof (RIL_SIM_IO_Response));
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    if (responselen != sizeof(RIL_StkCcUnsolSsResponse)) {
+        RLOGE("invalid response length %d, expected %d",
+               (int)responselen, (int)sizeof(RIL_StkCcUnsolSsResponse));
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    startResponse;
+    RIL_StkCcUnsolSsResponse *p_cur = (RIL_StkCcUnsolSsResponse *) response;
+    p.writeInt32(p_cur->serviceType);
+    p.writeInt32(p_cur->requestType);
+    p.writeInt32(p_cur->teleserviceType);
+    p.writeInt32(p_cur->serviceClass);
+    p.writeInt32(p_cur->result);
+
+    if (isServiceTypeCfQuery(p_cur->serviceType, p_cur->requestType)) {
+        RLOGD("responseSSData CF type, num of Cf elements %d", p_cur->cfData.numValidIndexes);
+        if (p_cur->cfData.numValidIndexes > NUM_SERVICE_CLASSES) {
+            RLOGE("numValidIndexes is greater than max value %d, "
+                  "truncating it to max value", NUM_SERVICE_CLASSES);
+            p_cur->cfData.numValidIndexes = NUM_SERVICE_CLASSES;
+        }
+        /* number of call info's */
+        p.writeInt32(p_cur->cfData.numValidIndexes);
+
+        for (int i = 0; i < p_cur->cfData.numValidIndexes; i++) {
+             RIL_CallForwardInfo cf = p_cur->cfData.cfInfo[i];
+
+             p.writeInt32(cf.status);
+             p.writeInt32(cf.reason);
+             p.writeInt32(cf.serviceClass);
+             p.writeInt32(cf.toa);
+             writeStringToParcel(p, cf.number);
+             p.writeInt32(cf.timeSeconds);
+             appendPrintBuf("%s[%s,reason=%d,cls=%d,toa=%d,%s,tout=%d],", printBuf,
+                 (cf.status==1)?"enable":"disable", cf.reason, cf.serviceClass, cf.toa,
+                  (char*)cf.number, cf.timeSeconds);
+             RLOGD("Data: %d,reason=%d,cls=%d,toa=%d,num=%s,tout=%d],", cf.status,
+                  cf.reason, cf.serviceClass, cf.toa, (char*)cf.number, cf.timeSeconds);
+        }
+    } else {
+        p.writeInt32 (SS_INFO_MAX);
+
+        /* each int*/
+        for (int i = 0; i < SS_INFO_MAX; i++) {
+             appendPrintBuf("%s%d,", printBuf, p_cur->ssInfo[i]);
+             RLOGD("Data: %d",p_cur->ssInfo[i]);
+             p.writeInt32(p_cur->ssInfo[i]);
+        }
+    }
+    removeLastChar;
+    closeResponse;
+
+    return 0;
+}
+
+static bool isServiceTypeCfQuery(RIL_SsServiceType serType, RIL_SsRequestType reqType) {
+    if ((reqType == SS_INTERROGATION) &&
+        (serType == SS_CFU ||
+         serType == SS_CF_BUSY ||
+         serType == SS_CF_NO_REPLY ||
+         serType == SS_CF_NOT_REACHABLE ||
+         serType == SS_CF_ALL ||
+         serType == SS_CF_ALL_CONDITIONAL)) {
+        return true;
+    }
+    return false;
+}
+
+static void sendSimStatusAppInfo(Parcel &p, int num_apps, RIL_AppStatus appStatus[]) {
+        p.writeInt32(num_apps);
+        startResponse;
+        for (int i = 0; i < num_apps; i++) {
+            p.writeInt32(appStatus[i].app_type);
+            p.writeInt32(appStatus[i].app_state);
+            p.writeInt32(appStatus[i].perso_substate);
+            writeStringToParcel(p, (const char*)(appStatus[i].aid_ptr));
+            writeStringToParcel(p, (const char*)
+                                          (appStatus[i].app_label_ptr));
+            p.writeInt32(appStatus[i].pin1_replaced);
+            p.writeInt32(appStatus[i].pin1);
+            p.writeInt32(appStatus[i].pin2);
+            appendPrintBuf("%s[app_type=%d,app_state=%d,perso_substate=%d,\
+                    aid_ptr=%s,app_label_ptr=%s,pin1_replaced=%d,pin1=%d,pin2=%d],",
+                    printBuf,
+                    appStatus[i].app_type,
+                    appStatus[i].app_state,
+                    appStatus[i].perso_substate,
+                    appStatus[i].aid_ptr,
+                    appStatus[i].app_label_ptr,
+                    appStatus[i].pin1_replaced,
+                    appStatus[i].pin1,
+                    appStatus[i].pin2);
+        }
+        closeResponse;
+}
+
+static int responseSimStatus(Parcel &p, void *response, size_t responselen) {
+    int i;
+
+    if (response == NULL && responselen != 0) {
+        RLOGE("invalid response: NULL");
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    RLOGD("responselen: %d, v6: %d, v5: %d", responselen, sizeof (RIL_CardStatus_v6),sizeof (RIL_CardStatus_v5));
+    if (responselen == sizeof (RIL_CardStatus_v6)) {
+        RIL_CardStatus_v6 *p_cur = ((RIL_CardStatus_v6 *) response);
+        p.writeInt32(p_cur->card_state);
+        p.writeInt32(p_cur->universal_pin_state);
+        p.writeInt32(p_cur->gsm_umts_subscription_app_index);
+        p.writeInt32(p_cur->cdma_subscription_app_index);
+        p.writeInt32(p_cur->ims_subscription_app_index);
+
+        sendSimStatusAppInfo(p, p_cur->num_applications, p_cur->applications);
+    } else if (responselen == sizeof (RIL_CardStatus_v5)) {
+        RIL_CardStatus_v5 *p_cur = ((RIL_CardStatus_v5 *) response);
+
+        p.writeInt32(p_cur->card_state);
+        p.writeInt32(p_cur->universal_pin_state);
+        p.writeInt32(p_cur->gsm_umts_subscription_app_index);
+        p.writeInt32(p_cur->cdma_subscription_app_index);
+        p.writeInt32(-1);
+
+        sendSimStatusAppInfo(p, p_cur->num_applications, p_cur->applications);
+    } else {
+        RLOGE("responseSimStatus: A RilCardStatus_v6 or _v5 expected\n");
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    return 0;
+}
+
+static int responseGsmBrSmsCnf(Parcel &p, void *response, size_t responselen) {
+    int num = responselen / sizeof(RIL_GSM_BroadcastSmsConfigInfo *);
+    p.writeInt32(num);
+
+    startResponse;
+    RIL_GSM_BroadcastSmsConfigInfo **p_cur =
+                (RIL_GSM_BroadcastSmsConfigInfo **) response;
+    for (int i = 0; i < num; i++) {
+        p.writeInt32(p_cur[i]->fromServiceId);
+        p.writeInt32(p_cur[i]->toServiceId);
+        p.writeInt32(p_cur[i]->fromCodeScheme);
+        p.writeInt32(p_cur[i]->toCodeScheme);
+        p.writeInt32(p_cur[i]->selected);
+
+        appendPrintBuf("%s [%d: fromServiceId=%d, toServiceId=%d, \
+                fromCodeScheme=%d, toCodeScheme=%d, selected =%d]",
+                printBuf, i, p_cur[i]->fromServiceId, p_cur[i]->toServiceId,
+                p_cur[i]->fromCodeScheme, p_cur[i]->toCodeScheme,
+                p_cur[i]->selected);
+    }
+    closeResponse;
+
+    return 0;
+}
+
+static int responseCdmaBrSmsCnf(Parcel &p, void *response, size_t responselen) {
+    RIL_CDMA_BroadcastSmsConfigInfo **p_cur =
+               (RIL_CDMA_BroadcastSmsConfigInfo **) response;
+
+    int num = responselen / sizeof (RIL_CDMA_BroadcastSmsConfigInfo *);
+    p.writeInt32(num);
+
+    startResponse;
+    for (int i = 0 ; i < num ; i++ ) {
+        p.writeInt32(p_cur[i]->service_category);
+        p.writeInt32(p_cur[i]->language);
+        p.writeInt32(p_cur[i]->selected);
+
+        appendPrintBuf("%s [%d: srvice_category=%d, language =%d, \
+              selected =%d], ",
+              printBuf, i, p_cur[i]->service_category, p_cur[i]->language,
+              p_cur[i]->selected);
+    }
+    closeResponse;
+
+    return 0;
+}
+
+static int responseCdmaSms(Parcel &p, void *response, size_t responselen) {
+    int num;
+    int digitCount;
+    int digitLimit;
+    uint8_t uct;
+    void* dest;
+
+    RLOGD("Inside responseCdmaSms");
+
+    if (response == NULL && responselen != 0) {
+        RLOGE("invalid response: NULL");
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    if (responselen != sizeof(RIL_CDMA_SMS_Message)) {
+        RLOGE("invalid response length was %d expected %d",
+                (int)responselen, (int)sizeof(RIL_CDMA_SMS_Message));
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    RIL_CDMA_SMS_Message *p_cur = (RIL_CDMA_SMS_Message *) response;
+    p.writeInt32(p_cur->uTeleserviceID);
+    p.write(&(p_cur->bIsServicePresent),sizeof(uct));
+    p.writeInt32(p_cur->uServicecategory);
+    p.writeInt32(p_cur->sAddress.digit_mode);
+    p.writeInt32(p_cur->sAddress.number_mode);
+    p.writeInt32(p_cur->sAddress.number_type);
+    p.writeInt32(p_cur->sAddress.number_plan);
+    RLOGD("MT CDMA SMS: sAddress.number_plan = %d", p_cur->sAddress.number_plan);
+    p.write(&(p_cur->sAddress.number_of_digits), sizeof(uct));
+    RLOGD("MT CDMA SMS: sAddress.number_of_digits = %d", p_cur->sAddress.number_of_digits);
+    digitLimit= MIN((p_cur->sAddress.number_of_digits), RIL_CDMA_SMS_ADDRESS_MAX);
+    String8 str(""), temp;
+    for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
+        p.write(&(p_cur->sAddress.digits[digitCount]),sizeof(uct));
+        temp = String8::format("%d,", p_cur->sAddress.digits[digitCount]);
+        str.append(temp);
+    }
+    RLOGD("MT CDMA SMS: sAddress.digits: {%s}", str.isEmpty()? "" : str.string());
+
+    p.writeInt32(p_cur->sSubAddress.subaddressType);
+    RLOGD("MT CDMA SMS: sSubAddress.subaddressType = %d", p_cur->sSubAddress.subaddressType);
+    p.write(&(p_cur->sSubAddress.odd),sizeof(uct));
+    RLOGD("MT CDMA SMS: sSubAddress.odd = %d", p_cur->sSubAddress.odd);
+    p.write(&(p_cur->sSubAddress.number_of_digits),sizeof(uct));
+    RLOGD("MT CDMA SMS: sSubAddress.number_of_digits = %d", p_cur->sSubAddress.number_of_digits);
+    digitLimit= MIN((p_cur->sSubAddress.number_of_digits), RIL_CDMA_SMS_SUBADDRESS_MAX);
+    str.clear();
+    temp.clear();
+    for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
+        p.write(&(p_cur->sSubAddress.digits[digitCount]),sizeof(uct));
+        temp = String8::format("%d,", p_cur->sSubAddress.digits[digitCount]);
+        str.append(temp);
+    }
+    RLOGD("MT CDMA SMS: sSubAddress.digits: {%s}", str.isEmpty() ? "" : str.string());
+
+    digitLimit= MIN((p_cur->uBearerDataLen), RIL_CDMA_SMS_BEARER_DATA_MAX);
+    RLOGD("MT CDMA SMS: uBearerDataLen = %d", p_cur->uBearerDataLen);
+    p.writeInt32(p_cur->uBearerDataLen);
+    str.clear();
+    temp.clear();
+    for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
+       p.write(&(p_cur->aBearerData[digitCount]), sizeof(uct));
+       temp = String8::format("%d,", p_cur->aBearerData[digitCount]);
+       str.append(temp);
+    }
+    RLOGD("MT CDMA SMS: aBearerData: {%s}", str.isEmpty() ? "" : str.string());
+
+    startResponse;
+    appendPrintBuf("%suTeleserviceID=%d, bIsServicePresent=%d, uServicecategory=%d, \
+            sAddress.digit_mode=%d, sAddress.number_mode=%d, sAddress.number_type=%d, ",
+            printBuf, p_cur->uTeleserviceID,p_cur->bIsServicePresent,p_cur->uServicecategory,
+            p_cur->sAddress.digit_mode, p_cur->sAddress.number_mode,p_cur->sAddress.number_type);
+    closeResponse;
+    resposeCdmaSms(p_cur);
+    return 0;
+}
+
+static int responseDcRtInfo(Parcel &p, void *response, size_t responselen)
+{
+    int num = responselen / sizeof(RIL_DcRtInfo);
+    if ((responselen % sizeof(RIL_DcRtInfo) != 0) || (num != 1)) {
+        RLOGE("responseDcRtInfo: invalid response length %d expected multiple of %d",
+                (int)responselen, (int)sizeof(RIL_DcRtInfo));
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    startResponse;
+    RIL_DcRtInfo *pDcRtInfo = (RIL_DcRtInfo *)response;
+    p.writeInt64(pDcRtInfo->time);
+    p.writeInt32(pDcRtInfo->powerState);
+    appendPrintBuf("%s[time=%d,powerState=%d]", printBuf,
+        pDcRtInfo->time,
+        pDcRtInfo->powerState);
+    closeResponse;
+
+    return 0;
+}
+
+static int responseLceStatus(Parcel &p, void *response, size_t responselen) {
+  if (response == NULL || responselen != sizeof(RIL_LceStatusInfo)) {
+    if (response == NULL) {
+      RLOGE("invalid response: NULL");
+    }
+    else {
+      RLOGE("responseLceStatus: invalid response length %d expecting len: %d",
+            sizeof(RIL_LceStatusInfo), responselen);
+    }
+    return RIL_ERRNO_INVALID_RESPONSE;
+  }
+
+  RIL_LceStatusInfo *p_cur = (RIL_LceStatusInfo *)response;
+  p.write((void *)p_cur, 1);  // p_cur->lce_status takes one byte.
+  p.writeInt32(p_cur->actual_interval_ms);
+
+  startResponse;
+  appendPrintBuf("LCE Status: %d, actual_interval_ms: %d",
+                 p_cur->lce_status, p_cur->actual_interval_ms);
+  closeResponse;
+
+  return 0;
+}
+
+static int responseLceData(Parcel &p, void *response, size_t responselen) {
+  if (response == NULL || responselen != sizeof(RIL_LceDataInfo)) {
+    if (response == NULL) {
+      RLOGE("invalid response: NULL");
+    }
+    else {
+      RLOGE("responseLceData: invalid response length %d expecting len: %d",
+            sizeof(RIL_LceDataInfo), responselen);
+    }
+    return RIL_ERRNO_INVALID_RESPONSE;
+  }
+
+  RIL_LceDataInfo *p_cur = (RIL_LceDataInfo *)response;
+  p.writeInt32(p_cur->last_hop_capacity_kbps);
+
+  /* p_cur->confidence_level and p_cur->lce_suspended take 1 byte each.*/
+  p.write((void *)&(p_cur->confidence_level), 1);
+  p.write((void *)&(p_cur->lce_suspended), 1);
+
+  startResponse;
+  appendPrintBuf("LCE info received: capacity %d confidence level %d and suspended %d",
+                  p_cur->last_hop_capacity_kbps, p_cur->confidence_level,
+                  p_cur->lce_suspended);
+  closeResponse;
+
+  return 0;
+}
+
+static int responseActivityData(Parcel &p, void *response, size_t responselen) {
+  if (response == NULL || responselen != sizeof(RIL_ActivityStatsInfo)) {
+    if (response == NULL) {
+      RLOGE("invalid response: NULL");
+    }
+    else {
+      RLOGE("responseActivityData: invalid response length %d expecting len: %d",
+            sizeof(RIL_ActivityStatsInfo), responselen);
+    }
+    return RIL_ERRNO_INVALID_RESPONSE;
+  }
+
+  RIL_ActivityStatsInfo *p_cur = (RIL_ActivityStatsInfo *)response;
+  p.writeInt32(p_cur->sleep_mode_time_ms);
+  p.writeInt32(p_cur->idle_mode_time_ms);
+  for(int i = 0; i < RIL_NUM_TX_POWER_LEVELS; i++) {
+    p.writeInt32(p_cur->tx_mode_time_ms[i]);
+  }
+  p.writeInt32(p_cur->rx_mode_time_ms);
+
+  startResponse;
+  appendPrintBuf("Modem activity info received: sleep_mode_time_ms %d idle_mode_time_ms %d tx_mode_time_ms %d %d %d %d %d and rx_mode_time_ms %d",
+                  p_cur->sleep_mode_time_ms, p_cur->idle_mode_time_ms, p_cur->tx_mode_time_ms[0],
+                  p_cur->tx_mode_time_ms[1], p_cur->tx_mode_time_ms[2], p_cur->tx_mode_time_ms[3],
+                  p_cur->tx_mode_time_ms[4], p_cur->rx_mode_time_ms);
+   closeResponse;
+
+  return 0;
+}
+
+static int responseSmsSimMemStatus(Parcel &p, void *response, size_t responselen) {
+    printf("=============%s\n", __FUNCTION__);
+    if (response == NULL) {
+        RLOGE("invalid response: NULL");
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    if (responselen != sizeof (RIL_SMS_Memory_Status) ) {
+        RLOGE("invalid response length %d expected %d",
+                (int)responselen, (int)sizeof (RIL_SMS_Memory_Status));
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
+
+    RIL_SMS_Memory_Status *p_cur = (RIL_SMS_Memory_Status *) response;
+
+    p.writeInt32(p_cur->used);
+    p.writeInt32(p_cur->total);
+
+    startResponse;
+    appendPrintBuf("%s%d,%d", printBuf, p_cur->used, p_cur->total);
+    closeResponse;
+
+    printf("%s%d,%d\n", printBuf, p_cur->used, p_cur->total);
+    RLOGE("===========================%s%d,%d", printBuf, p_cur->used, p_cur->total);
+    return 0;
+}
+
+void RIL_startEventLoop(void);
+extern "C" void
+RIL_register (const RIL_RadioFunctions *callbacks) {
+    if (callbacks == NULL) {
+        RLOGE("RIL_register: RIL_RadioFunctions * null");
+        return;
+    }
+#if 0
+    if (callbacks->version < RIL_VERSION_MIN) {
+        RLOGE("RIL_register: version %d is to old, min version is %d",
+             callbacks->version, RIL_VERSION_MIN);
+        return;
+    }
+    if (callbacks->version > RIL_VERSION) {
+        RLOGE("RIL_register: version %d is too new, max version is %d",
+             callbacks->version, RIL_VERSION);
+        return;
+    }
+#endif
+    RLOGE("RIL_register: RIL version %d", callbacks->version);
+
+    if (s_registerCalled > 0) {
+        RLOGE("RIL_register has been called more than once. "
+                "Subsequent call ignored");
+        return;
+    }
+
+    memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions));
+
+    s_registerCalled = 1;
+
+    pthread_mutex_lock(&s_InitMutex);
+    if(utils::is_support_dsds()) {
+        while (s_isConnected[0] == 0 || s_isConnected[1] == 0) {
+          pthread_cond_wait(&s_InitCond, &s_InitMutex);
+        }
+    } else {
+        while (s_isConnected[0] == 0 && s_isConnected[1] == 0) {
+          pthread_cond_wait(&s_InitCond, &s_InitMutex);
+        }
+    }
+    pthread_mutex_unlock(&s_InitMutex);
+    initCoditions();
+    // New rild impl calls RIL_startEventLoop() first
+    // old standalone impl wants it here.
+
+   // if (s_started == 0) {
+    //    RIL_startEventLoop();
+   // }
+
+}
+
+#if 0
+static int
+checkAndDequeueRequestInfo(struct RequestInfo *pRI) {
+    int ret = 0;
+    /* Hook for current context
+       pendingRequestsMutextHook refer to &s_pendingRequestsMutex */
+    pthread_mutex_t* pendingRequestsMutexHook = &s_pendingRequestsMutex;
+    /* pendingRequestsHook refer to &s_pendingRequests */
+    RequestInfo ** pendingRequestsHook = &s_pendingRequests;
+
+    if (pRI == NULL) {
+        return 0;
+    }
+
+#if (SIM_COUNT >= 2)
+    if (pRI->socket_id == RIL_SOCKET_2) {
+        pendingRequestsMutexHook = &s_pendingRequestsMutex_socket2;
+        pendingRequestsHook = &s_pendingRequests_socket2;
+    }
+#if (SIM_COUNT >= 3)
+        if (pRI->socket_id == RIL_SOCKET_3) {
+            pendingRequestsMutexHook = &s_pendingRequestsMutex_socket3;
+            pendingRequestsHook = &s_pendingRequests_socket3;
+        }
+#endif
+#if (SIM_COUNT >= 4)
+    if (pRI->socket_id == RIL_SOCKET_4) {
+        pendingRequestsMutexHook = &s_pendingRequestsMutex_socket4;
+        pendingRequestsHook = &s_pendingRequests_socket4;
+    }
+#endif
+#endif
+    pthread_mutex_lock(pendingRequestsMutexHook);
+
+    for(RequestInfo **ppCur = pendingRequestsHook
+        ; *ppCur != NULL
+        ; ppCur = &((*ppCur)->p_next)
+    ) {
+        if (pRI == *ppCur) {
+            ret = 1;
+
+            *ppCur = (*ppCur)->p_next;
+            break;
+        }
+    }
+
+    pthread_mutex_unlock(pendingRequestsMutexHook);
+
+    return ret;
+}
+
+#endif
+
+char add_token_func(char *desbuf,char *buf,int token,int number)
+{
+    char *p = NULL, *q = buf, *res=NULL;
+    char tmpbuf[BUF_LEN] = "";
+    char parse_buf[BUF_LEN] = "";
+    char buf_value[BUF_LEN] = "";
+
+    if(p = strstr(buf, "{["))
+    {    
+        strncpy(parse_buf, buf, strlen(buf)-1);
+        strncpy(tmpbuf, parse_buf, p-q);
+        
+        if(res = strstr(tmpbuf, "<"))
+        {
+            strncpy(buf_value, p+2, strlen(p+2)-1);
+            sprintf(desbuf, " +%s:%d,%d,%s", res+2, token, number, buf_value);
+        }
+        else{
+            sprintf(desbuf, "%s %d,%d,%s",tmpbuf, token, number, p+2);
+        }
+    }
+    else if((p = strstr(buf, "}")) && (p = strstr(buf, "{")))
+    {
+        strncpy(parse_buf,buf,strlen(buf)-1);
+        strncpy(tmpbuf, parse_buf, p-q);
+        if(res = strstr(tmpbuf, "<"))
+        {
+            strncpy(buf_value, p+1, strlen(p+1)-1);
+            sprintf(desbuf, " +%s:%d,%d,%s", res+2, token, number, buf_value);
+        }
+        else{
+            sprintf(desbuf, "%stoken=%d,number=%d,%s", tmpbuf, token,number, p+1);
+        }
+
+    }
+    else if(p = strstr(buf, "}")){
+        strncpy(tmpbuf, buf, p-q);
+        if(res = strstr(tmpbuf, "<"))
+        {
+            sprintf(desbuf, " +%s:%d,%d,%s clear current calls", res+2, token, number, buf_value);
+        }
+        else{
+            sprintf(desbuf, "%s{token=%d,number=%d%s", tmpbuf, token, number, p);
+        }
+    }
+    else if(p = strstr(buf, "fails by")){
+        sprintf(desbuf, " +error cause: %s", p+9);
+    }
+    else
+    { 
+        if(p = strstr(buf, "<"))
+        {
+            sprintf(desbuf, " +%s", p+1);
+        }
+        else{    
+            strncpy(desbuf, buf, strlen(buf));
+        }
+    }
+    return 0;
+}
+extern "C" void
+RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen) {
+    RequestInfo *pRI;
+    int ret;
+    //int fd = s_ril_param_socket.fdCommand;
+    size_t errorOffset;
+    RIL_SOCKET_ID socket_id = RIL_SOCKET_1;
+
+    pRI = (RequestInfo *)t;
+    RLOGD("RIL_onRequestComplete,start,e:%d",e);
+    //char desbuf[BUF_LEN] = "";
+#if 0
+    if (!checkAndDequeueRequestInfo(pRI)) {
+        RLOGE ("RIL_onRequestComplete: invalid RIL_Token");
+        return;
+    }
+#endif
+
+    socket_id = pRI->socket_id;
+#if 0
+#if (SIM_COUNT >= 2)
+    if (socket_id == RIL_SOCKET_2) {
+        fd = s_ril_param_socket2.fdCommand;
+    }
+#if (SIM_COUNT >= 3)
+        if (socket_id == RIL_SOCKET_3) {
+            fd = s_ril_param_socket3.fdCommand;
+        }
+#endif
+#if (SIM_COUNT >= 4)
+    if (socket_id == RIL_SOCKET_4) {
+        fd = s_ril_param_socket4.fdCommand;
+    }
+#endif
+#endif
+#endif
+#if VDBG
+    RLOGD("RequestComplete, %s", rilSocketIdToString(socket_id));
+#endif
+
+    if (pRI->local > 0) {
+        // Locally issued command...void only!
+        // response does not go back up the command socket
+        RLOGD("C[locl]< %s", requestToString(pRI->pCI->requestNumber));
+
+        goto done;
+    }
+
+    appendPrintBuf("[%x][SIM%d]< %s", pRI->token,socket_id,requestToString(pRI->pCI->requestNumber));
+    /* mobiletek add*/
+    LYNQ_DispatchResponse(pRI->pCI->requestNumber,pRI->token,e,NULL,response,responselen);
+    //LYNQ_DispatchRequest(pRI->pCI->requestNumber,pRI->token,e,pCallList,response,responselen);
+    /*mobiletek end*/
+    if (pRI->cancelled == 0) {
+        Parcel p;
+
+        p.writeInt32 (RESPONSE_SOLICITED);
+        p.writeInt32 (pRI->pCI->requestNumber);
+        errorOffset = p.dataPosition();
+
+        p.writeInt32 (e);
+
+        if (response != NULL) {
+            // there is a response payload, no matter success or not.
+            ret = pRI->pCI->responseFunction(p, response, responselen);
+
+            /* if an error occurred, rewind and mark it */
+            if (ret != 0) {
+                RLOGE ("responseFunction error, ret %d", ret);
+                p.setDataPosition(errorOffset);
+                p.writeInt32 (ret);
+            }
+            switch (pRI->pCI->requestNumber) {
+               case RIL_REQUEST_QUERY_FACILITY_LOCK:
+               {
+                   int numInts = responselen / sizeof(int);
+                   if(numInts > 0) {
+                       int *p_int = (int *) response;
+                       RLOGD("RIL_REQUEST_QUERY_FACILITY_LOCK: %s", (p_int[0] != 0 ? "PIN enable" : "PIN1 disable"));
+                   } else {
+                       RLOGD("RIL_REQUEST_QUERY_FACILITY_LOCK response numInts: %d", numInts);
+                   }
+                   break;
+               }
+               case RIL_REQUEST_IMS_REGISTRATION_STATE:
+               {
+                   int numInts = responselen / sizeof(int);
+                   if(numInts > 0) {
+                       int *p_int = (int *) response;
+                       printf("[SIM%d][QUERY][REG_STATUS] IMS is %s\n", socket_id, (p_int[0] == 0 ? "Not registered" : "Registered"));
+                   } else {
+                       RLOGD("RIL_REQUEST_IMS_REGISTRATION_STATE response numInts: %d", numInts);
+                   }
+                   break;
+               }
+               case RIL_REQUEST_VOICE_REGISTRATION_STATE:
+               {
+                   char **p_cur = (char **) response;
+                   int numStrings = responselen / sizeof(char *);
+                   update_reg_voice_service_state(RIL_REQUEST_VOICE_REGISTRATION_STATE, (char *)p_cur[0], socket_id, pRI->token);
+                   int tempVal=0;
+                   memset(respStr,0,sizeof(respStr));
+                   tempVal = atoi((char *)p_cur[0]);
+                   if(tempVal == 1 || tempVal==5){
+                       sprintf(respStr,"[SIM%d]%s register is in service!",socket_id +1, respStr);
+                   }else{
+                       sprintf(respStr,"[SIM%d]%s register is not in service!",socket_id +1, respStr);
+                   }
+                   if(numStrings >=4 && p_cur[3] != NULL)
+                   {
+                       update_reg_voice_radio_tech(RIL_REQUEST_VOICE_REGISTRATION_STATE, atoi((char *)p_cur[3]), socket_id, pRI->token);
+                       tempVal = atoi((char *)p_cur[3]);
+                       if(tempVal == RADIO_TECH_LTE){//4G
+                           sprintf(respStr,"%s radioTech is 4G!",respStr);
+                       } else if( tempVal == RADIO_TECH_GSM ||
+                                  tempVal == RADIO_TECH_GPRS ||
+                                  tempVal == RADIO_TECH_EDGE ||
+                                  tempVal == RADIO_TECH_IS95A ||
+                                  tempVal == RADIO_TECH_IS95B ||
+                                  tempVal == RADIO_TECH_1xRTT) { //2G
+                           sprintf(respStr,"%s radioTech is 2G!",respStr);
+                       } else if( tempVal == RADIO_TECH_UMTS ||
+                                  tempVal == RADIO_TECH_HSDPA ||
+                                  tempVal == RADIO_TECH_HSUPA ||
+                                  tempVal == RADIO_TECH_HSPA ||
+                                  tempVal == RADIO_TECH_EHRPD ||
+                                  tempVal == RADIO_TECH_HSPAP ||
+                                  tempVal == RADIO_TECH_TD_SCDMA ||
+                                  tempVal == RADIO_TECH_EVDO_0 ||
+                                  tempVal == RADIO_TECH_EVDO_A ||
+                                  tempVal == RADIO_TECH_EVDO_B) { //3G
+                           sprintf(respStr,"%s radioTech is 3G!",respStr);
+                       } else { //unknown
+                           sprintf(respStr,"%s radioTech is unkown!",respStr);
+                       }
+                   }
+                   sprintf(respStr,"%s\n",respStr);
+                   break;
+               }
+               case RIL_REQUEST_DATA_REGISTRATION_STATE:
+               {
+                   char **p_cur = (char **) response;
+                   int numStrings = responselen / sizeof(char *);
+                   update_reg_data_service_state(RIL_REQUEST_DATA_REGISTRATION_STATE, (char *)p_cur[0], socket_id, pRI->token);
+                   if(numStrings >=4 && p_cur[3] != NULL)
+                   {
+                       update_reg_data_radio_tech(RIL_REQUEST_DATA_REGISTRATION_STATE, atoi((char *)p_cur[3]), socket_id, pRI->token);
+                   }
+                   break;
+               }
+               case RIL_REQUEST_GET_CURRENT_CALLS:
+               {
+                   update_call_state(response,responselen, socket_id);
+                   int num = responselen / sizeof(RIL_Call *);
+                   speechonoff(num);
+                   printf("%s\n", printBuf);
+                   /*****mobiletek-add*****/
+                   //add_token_func(desbuf,printBuf,pRI->token,pRI->pCI->requestNumber);
+                   //appResponseCb(pRI->token,e,desbuf);
+                   updateAsyncData(t,e,response,responselen,LynqQueueHead);
+                   /*****mobiletek-end*****/
+                   break;
+               }
+               case RIL_REQUEST_SETUP_DATA_CALL:
+               {
+                   int num = responselen / sizeof(RIL_Data_Call_Response_v6);
+                   RIL_Data_Call_Response_v6 *p_cur = (RIL_Data_Call_Response_v6 *) response;
+                   updateRILDataCallResponsev6(num,p_cur);
+                   break;
+               }
+               case RIL_REQUEST_GET_SIM_STATUS:
+               {
+                   if (responselen == sizeof (RIL_CardStatus_v6)) {
+                       RIL_CardStatus_v6 *p_cur = ((RIL_CardStatus_v6 *) response);
+                       updateCardStatusV6(p_cur, socket_id);
+                   }
+                   break;
+               }
+               case RIL_REQUEST_VOICE_RADIO_TECH:
+               {
+                   update_voice_radio_tech(((int *) response)[0], socket_id);
+                   break;
+               }
+               case RIL_REQUEST_GET_RADIO_CAPABILITY:
+               {
+                   update_radio_capa((RIL_RadioCapability *) response, socket_id);
+                   break;
+               }
+               case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE:
+               {
+                   update_preferred_network_type(((int *) response)[0], socket_id);
+                   break;
+               }
+               case RIL_REQUEST_DELETE_SMS_ON_SIM:
+               {
+                   setSimSmsStorageFullFlag(false);
+                   break;
+               }
+               case RIL_REQUEST_SEND_SMS:
+               case RIL_REQUEST_SEND_SMS_EXPECT_MORE:
+               case RIL_REQUEST_IMS_SEND_SMS:
+               {
+                   //for auto save sms to sim    
+                   sendStatusWriteSmsToSim(socket_id);
+                   break;
+               }
+               case RIL_REQUEST_ECALL_SET_REGISTRATION_STATE:
+               {
+                   int numInts = responselen / sizeof(int);
+                   if(numInts > 0) {
+                       int *p_int = (int *) response;
+                       RLOGD("RIL_REQUEST_ECALL_SET_REGISTRATION_STATE: %d", p_int[0]);
+                       if(p_int[0] == ECALL_DEREGISTRATION)
+                       {
+                            gostSetInNeedRegister(true);
+                       }
+
+                   } else {
+                       RLOGD("RIL_REQUEST_ECALL_SET_REGISTRATION_STATE response numInts: %d", numInts);
+                   }
+                   break;
+               }
+               default:
+                   break;
+               }
+        }
+
+        if (e != RIL_E_SUCCESS) {
+            appendPrintBuf("%s fails by %s", printBuf, failCauseToString(e));
+        }
+
+        if ((pRI->token & RIL_TOKEN_MARK) == RIL_TOKEN_MARK) {
+            printf("%s\n", printBuf ? printBuf : "unkonwn");
+        } else if (((pRI->pCI->requestNumber == RIL_REQUEST_DEVICE_IDENTITY)
+                || (pRI->pCI->requestNumber == RIL_REQUEST_OEM_HOOK_RAW))
+                && (pRI->token & INIT_TOKEN_MARK) == INIT_TOKEN_MARK) {
+            printf("%s\n", printBuf ? printBuf : "unkonwn");
+            if (pRI->pCI->requestNumber == RIL_REQUEST_DEVICE_IDENTITY) {
+                if (e != RIL_E_SUCCESS) {
+                    printf(
+                            "*******************************************\n*** NOTICE: IMEI don't wirite in slot%d ***\n*******************************************\n",
+                            socket_id);
+                }
+            }
+        }
+
+#if 0
+        if (fd < 0) {
+            RLOGD ("RIL onRequestComplete: Command channel closed");
+        }
+#endif
+        sendResponse(p, socket_id);
+    }
+#if ATCI_ENABLE_RESPONSE
+    if((pRI->token & ATCI_TOKEN_MARK) == ATCI_TOKEN_MARK)  //ATCI_Rsp
+    {
+        int error;
+        memset(Respose_buf, 0, sizeof(Respose_buf));
+        if(e != RIL_E_SUCCESS)
+            error = 1;  //fail
+        else
+            error = 0;  //ok
+        ATCIResponse(pRI->token,error,Respose_buf, pRI->pCI->requestNumber);
+    }
+#endif
+    if(pRI->pCI->requestNumber == RIL_REQUEST_VOICE_REGISTRATION_STATE && (pRI->token & RIL_TOKEN_MARK) == RIL_TOKEN_MARK){
+        int len_s = sendto(server_socket_fd,respStr,strlen(respStr),0,(struct sockaddr *)&client_addr,sizeof(client_addr));
+    }
+    RLOGW("RIL_onRequestComplete %s end!",requestToString(pRI->pCI->requestNumber));
+    if((pRI->token&BLOCK_MARK) == BLOCK_MARK) {
+       //need wakeup dispatch function
+        BLOCK_LOCK();
+        wakeup_token = pRI->token;
+        RLOGW("RIL_onRequestComplete wakeup, token is %x!",wakeup_token);
+        BLOCK_WAKEUP();
+        BLOCK_UNLOCK();
+    }
+    switch (pRI->pCI->requestNumber) {
+        case RIL_REQUEST_RADIO_POWER:
+            speciaRequest_wakeup();
+            break;
+        case RIL_REQUEST_SET_RADIO_CAPABILITY:
+        {
+            if(utils::is_support_dsds()) {
+                for (int id = 0; id < SIM_COUNT; id++) {
+                    ARspRequest(RIL_REQUEST_ALLOW_DATA, (RIL_SOCKET_ID)id);
+                }
+            }
+            break;
+        }
+        case RIL_REQUEST_ALLOW_DATA:
+        {
+            if(utils::is_support_dsds() && isNeedConnect() && get_default_sim_data() == socket_id) {
+                RLOGD("recreate PDN with sim switch");
+                resetConnect();
+                setupDataCall(0, NULL, (RIL_SOCKET_ID)0, NULL);
+            }
+            break;
+        }
+#ifdef KEEP_ALIVE
+        case RIL_REQUEST_START_KEEPALIVE_PRO:
+        case RIL_REQUEST_STOP_KEEPALIVE_PRO:
+        {
+            handleKeepAliveResponse(pRI->pCI->requestNumber, response, responselen, socket_id, (e != RIL_E_SUCCESS));
+            break;
+        }
+#endif /*KEEP_ALIVE*/
+        case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC:
+        {
+            if(e == RIL_E_SUCCESS)
+            {
+                 gostSetInNeedRegister(false);
+                 gostFastEcallFlgSet(false);
+            }
+            else
+            {
+                 gostNetworkSelectionSet(socket_id);
+            }
+            break;
+        }
+    default:
+        break;
+    }
+done:
+    free(pRI);
+}
+
+
+static void
+grabPartialWakeLock() {
+    acquire_wake_lock(PARTIAL_WAKE_LOCK, ANDROID_WAKE_LOCK_NAME);
+}
+
+static void
+releaseWakeLock() {
+    release_wake_lock(ANDROID_WAKE_LOCK_NAME);
+}
+
+
+static int
+decodeVoiceRadioTechnology (RIL_RadioState radioState) {
+    switch (radioState) {
+        case RADIO_STATE_SIM_NOT_READY:
+        case RADIO_STATE_SIM_LOCKED_OR_ABSENT:
+        case RADIO_STATE_SIM_READY:
+            return RADIO_TECH_UMTS;
+
+        case RADIO_STATE_RUIM_NOT_READY:
+        case RADIO_STATE_RUIM_READY:
+        case RADIO_STATE_RUIM_LOCKED_OR_ABSENT:
+        case RADIO_STATE_NV_NOT_READY:
+        case RADIO_STATE_NV_READY:
+            return RADIO_TECH_1xRTT;
+
+        default:
+            RLOGD("decodeVoiceRadioTechnology: Invoked with incorrect RadioState");
+            return -1;
+    }
+}
+
+static int
+decodeCdmaSubscriptionSource (RIL_RadioState radioState) {
+    switch (radioState) {
+        case RADIO_STATE_SIM_NOT_READY:
+        case RADIO_STATE_SIM_LOCKED_OR_ABSENT:
+        case RADIO_STATE_SIM_READY:
+        case RADIO_STATE_RUIM_NOT_READY:
+        case RADIO_STATE_RUIM_READY:
+        case RADIO_STATE_RUIM_LOCKED_OR_ABSENT:
+            return CDMA_SUBSCRIPTION_SOURCE_RUIM_SIM;
+
+        case RADIO_STATE_NV_NOT_READY:
+        case RADIO_STATE_NV_READY:
+            return CDMA_SUBSCRIPTION_SOURCE_NV;
+
+        default:
+            RLOGD("decodeCdmaSubscriptionSource: Invoked with incorrect RadioState");
+            return -1;
+    }
+}
+
+static int
+decodeSimStatus (RIL_RadioState radioState) {
+   switch (radioState) {
+       case RADIO_STATE_SIM_NOT_READY:
+       case RADIO_STATE_RUIM_NOT_READY:
+       case RADIO_STATE_NV_NOT_READY:
+       case RADIO_STATE_NV_READY:
+           return -1;
+       case RADIO_STATE_SIM_LOCKED_OR_ABSENT:
+       case RADIO_STATE_SIM_READY:
+       case RADIO_STATE_RUIM_READY:
+       case RADIO_STATE_RUIM_LOCKED_OR_ABSENT:
+           return radioState;
+       default:
+           RLOGD("decodeSimStatus: Invoked with incorrect RadioState");
+           return -1;
+   }
+}
+
+static bool is3gpp2(int radioTech) {
+    switch (radioTech) {
+        case RADIO_TECH_IS95A:
+        case RADIO_TECH_IS95B:
+        case RADIO_TECH_1xRTT:
+        case RADIO_TECH_EVDO_0:
+        case RADIO_TECH_EVDO_A:
+        case RADIO_TECH_EVDO_B:
+        case RADIO_TECH_EHRPD:
+            return true;
+        default:
+            return false;
+    }
+}
+
+/* If RIL sends SIM states or RUIM states, store the voice radio
+ * technology and subscription source information so that they can be
+ * returned when telephony framework requests them
+ */
+static RIL_RadioState
+processRadioState(RIL_RadioState newRadioState, RIL_SOCKET_ID socket_id) {
+
+    if((newRadioState > RADIO_STATE_UNAVAILABLE) && (newRadioState < RADIO_STATE_ON)) {
+        int newVoiceRadioTech;
+        int newCdmaSubscriptionSource;
+        int newSimStatus;
+
+        /* This is old RIL. Decode Subscription source and Voice Radio Technology
+           from Radio State and send change notifications if there has been a change */
+        newVoiceRadioTech = decodeVoiceRadioTechnology(newRadioState);
+        if(newVoiceRadioTech != voiceRadioTech) {
+            voiceRadioTech = newVoiceRadioTech;
+            RIL_UNSOL_RESPONSE(RIL_UNSOL_VOICE_RADIO_TECH_CHANGED,
+                        &voiceRadioTech, sizeof(voiceRadioTech), socket_id);
+        }
+        if(is3gpp2(newVoiceRadioTech)) {
+            newCdmaSubscriptionSource = decodeCdmaSubscriptionSource(newRadioState);
+            if(newCdmaSubscriptionSource != cdmaSubscriptionSource) {
+                cdmaSubscriptionSource = newCdmaSubscriptionSource;
+                RIL_UNSOL_RESPONSE(RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED,
+                        &cdmaSubscriptionSource, sizeof(cdmaSubscriptionSource), socket_id);
+            }
+        }
+        newSimStatus = decodeSimStatus(newRadioState);
+        if(newSimStatus != simRuimStatus) {
+            simRuimStatus = newSimStatus;
+            RIL_UNSOL_RESPONSE(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, NULL, 0, socket_id);
+        }
+
+        /* Send RADIO_ON to telephony */
+        newRadioState = RADIO_STATE_ON;
+    }
+
+    return newRadioState;
+}
+
+
+#if defined(ANDROID_MULTI_SIM)
+extern "C"
+void RIL_onUnsolicitedResponse(int unsolResponse, const void *data,
+                                size_t datalen, RIL_SOCKET_ID socket_id)
+#else
+extern "C"
+void RIL_onUnsolicitedResponse(int unsolResponse, const void *data,
+                                size_t datalen)
+#endif
+{
+    int unsolResponseIndex;
+    int ret;
+    int64_t timeReceived = 0;
+    bool shouldScheduleTimeout = false;
+    RIL_RadioState newState;
+    RIL_SOCKET_ID soc_id = (RIL_SOCKET_ID)Phone_utils::get_enable_sim_for_dsss();
+
+#if defined(ANDROID_MULTI_SIM)
+    soc_id = socket_id;
+#endif
+
+    handle_wakeup_reason(unsolResponse);
+
+    if (s_registerCalled == 0) {
+        // Ignore RIL_onUnsolicitedResponse before RIL_register
+        RLOGW("RIL_onUnsolicitedResponse called before RIL_register");
+        return;
+    }
+    if(onSupports(unsolResponse) == 0)
+    {
+        RLOGE("unsupported unsolicited response code %d", unsolResponse);
+        return;
+    }
+
+#ifdef TARGET_PLATFORM_MT2635
+    //Reset modem, exit DemoApp.
+    if(unsolResponse==RIL_UNSOL_MAL_RESTART ) {
+        RLOGD("Modem Reset, Exit DemoApp!");
+        printf("Modem Reset, Exit DemoApp!\n");
+        speechonoff(0);
+        mixer_reset_set(1);
+        com_quit(0,NULL,soc_id,NULL);
+    }
+#endif
+    if (unsolResponse < RIL_UNSOL_VENDOR_BASE) {
+        unsolResponseIndex = unsolResponse - RIL_UNSOL_RESPONSE_BASE;
+    }
+#if 0
+    WakeType wakeType;
+    if (unsolResponse >= RIL_UNSOL_VENDOR_BASE) {
+        //unsolResponseIndex = unsolResponse - RIL_UNSOL_VENDOR_BASE;
+        wakeType = WAKE_PARTIAL;
+    } else {
+        unsolResponseIndex = unsolResponse - RIL_UNSOL_RESPONSE_BASE;
+        wakeType = s_unsolResponses[unsolResponseIndex].wakeType;
+    }
+
+    // Grab a wake lock if needed for this reponse,
+    // as we exit we'll either release it immediately
+    // or set a timer to release it later.
+    switch (wakeType) {
+        case WAKE_PARTIAL:
+            grabPartialWakeLock();
+            shouldScheduleTimeout = false;
+        break;
+
+        case DONT_WAKE:
+        default:
+            // No wake lock is grabed so don't set timeout
+            shouldScheduleTimeout = false;
+            break;
+    }
+
+    // Mark the time this was received, doing this
+    // after grabing the wakelock incase getting
+    // the elapsedRealTime might cause us to goto
+    // sleep.
+    if (unsolResponse == RIL_UNSOL_NITZ_TIME_RECEIVED) {
+        timeReceived = elapsedRealtime();
+    }
+#endif
+    appendPrintBuf("[UNSL][SIM%d]< %s", soc_id, requestToString(unsolResponse));
+
+    Parcel p;
+
+    p.writeInt32 (RESPONSE_UNSOLICITED);
+    p.writeInt32 (unsolResponse);
+
+    if (unsolResponse >= RIL_UNSOL_VENDOR_BASE) {
+        UnsolResponseInfo* unsolRspInof = find_mtk_unsol_command(unsolResponse);
+        if(unsolRspInof == NULL){
+            RLOGE("no unsolicited response function -- %d", unsolResponse);
+            return;
+        } else {
+            ret = unsolRspInof->responseFunction(p,const_cast<void*>(data),datalen);
+        }
+    } else {
+        ret = s_unsolResponses[unsolResponseIndex].responseFunction(p, const_cast<void*>(data), datalen);
+    }
+    if (ret != 0) {
+        // Problem with the response. Don't continue;
+        goto error_exit;
+    }
+
+    // some things get more payload
+    switch(unsolResponse) {
+        case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
+            newState = CALL_ONSTATEREQUEST(soc_id);
+            p.writeInt32(newState);
+            appendPrintBuf("%s {%s}", printBuf,
+                radioStateToString(CALL_ONSTATEREQUEST(soc_id)));
+        break;
+
+#if 0
+        case RIL_UNSOL_NITZ_TIME_RECEIVED:
+            // Store the time that this was received so the
+            // handler of this message can account for
+            // the time it takes to arrive and process. In
+            // particular the system has been known to sleep
+            // before this message can be processed.
+            p.writeInt64(timeReceived);
+        break;
+#endif
+    }
+
+#if VDBG
+    RLOGI("%s UNSOLICITED: %s length:%d", rilSocketIdToString(soc_id), requestToString(unsolResponse), p.dataSize());
+#endif
+    ret = sendResponse(p, soc_id);
+
+//unsol trigger other things.
+    switch(unsolResponse) {
+    case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:
+        ARspRequest(RIL_REQUEST_GET_CURRENT_CALLS, soc_id);
+        break;
+    case RIL_UNSOL_CALL_RING:
+        callRing(soc_id);
+        break;
+    case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED:
+        updateIccCardState(soc_id);
+        break;
+    case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED:
+        getVoiceAndDataRegistrationState(soc_id);
+        break;
+    case RIL_UNSOL_RESPONSE_NEW_SMS:
+        responseNewSMS((const char*)data, datalen,soc_id,unsolResponse);
+		unreadStatusWriteSMSToSim((const char*)data, datalen, soc_id);
+        sendSMSACK(soc_id);
+        break;
+    case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT:
+        sendSMSACK(soc_id);
+        break;
+    case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
+        updateRadioStatus(newState,soc_id);
+        break;
+    case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS:
+    {
+        ARspRequest(RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE, soc_id);
+        break;
+    }
+    case RIL_UNSOL_STK_PROACTIVE_COMMAND:
+    {
+          RLOGD("STk proactive command raw date: %s, length: %d", (char*)data, datalen);
+          handleStkCommand((char*)data, datalen,soc_id);
+          break;
+    }
+    case RIL_UNSOL_RIL_CONNECTED:
+    {
+          RLOGD("vendor-ril socket(%d) connect start", soc_id);
+          pthread_mutex_lock(&s_InitMutex);
+          s_isConnected[soc_id] = 1;
+          if(utils::is_support_dsds()) {
+              if (s_isConnected[0] == 1 && s_isConnected[1] == 1) {
+                  pthread_cond_broadcast(&s_InitCond);
+              }
+          } else {
+              if (s_isConnected[0] == 1 || s_isConnected[1] == 1) {
+                  pthread_cond_broadcast(&s_InitCond);
+              }
+          }
+          pthread_mutex_unlock(&s_InitMutex);
+          RLOGD("vendor-ril socket(%d) connect end", soc_id);
+          break;
+    }
+    case RIL_UNSOL_TX_POWER: {
+        int *p_int = (int *) data;
+        int numInts = datalen / sizeof(int);
+        if (numInts > 1)  {
+            m_RfDesense->emOemHookRaw(p_int[1],soc_id);
+        } else {
+            m_RfDesense->emOemHookRaw(0, soc_id);
+        }
+        break;
+    }
+    case RIL_UNSOL_NETWORK_INFO: {
+        if(networkCb){
+            //TBD
+            char **p_cur = (char **) data;
+            char *ctype = (char*)p_cur[0];
+            int type = atoi(ctype);
+            char *data = (char*)p_cur[1];
+            RLOGD("ctype %s type %d data %s\n",ctype,type,data);
+            networkCb(type,data);
+        }
+        break;
+    }
+    case RIL_UNSOL_DATA_CALL_LIST_CHANGED:
+    {
+        int num = datalen / sizeof(RIL_Data_Call_Response_v6);
+        RIL_Data_Call_Response_v6 *p_cur = (RIL_Data_Call_Response_v6 *) data;
+        handleUnsolDataCalllistChange(num,p_cur);
+        break;
+    }
+    case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED:
+    {
+        update_voice_radio_tech(((int *) data)[0], soc_id);
+        break;
+    }
+    case RIL_UNSOL_RADIO_CAPABILITY:
+    {
+        update_radio_capa((RIL_RadioCapability *) data, soc_id);
+        //Proxy_controller::getInstance()->handle_message_notify((RIL_RadioCapability *) data, soc_id);
+        break;
+    }
+    case RIL_UNSOL_CDMA_CALL_WAITING:
+    {
+        autoAnswerForCdma(soc_id);
+        break;
+    }
+    case RIL_UNSOL_NITZ_TIME_RECEIVED:
+    {
+        updateSystemTime(data, datalen);
+        break;
+    }
+    case RIL_UNSOL_ECALL_INDICATIONS:
+    {
+        handleEcallIndication(data, datalen, soc_id);
+        break;
+    }
+#ifdef KEEP_ALIVE
+    case RIL_UNSOL_KEEPALIVE_STATUS_PRO:
+    {
+        handleKeepAliveResponse(unsolResponse, data, datalen, soc_id, false);
+        break;
+    }
+#endif /*KEEP_ALIVE*/
+    case RIL_UNSOL_SIM_SMS_STORAGE_FULL:
+    {
+        setSimSmsStorageFullFlag(true);
+        break;
+    }
+    case RIL_UNSOL_SIP_CALL_PROGRESS_INDICATOR:
+    {
+        handleUnsolSipCallProgressInd(data, datalen);
+        break;
+    }
+    case RIL_UNSOL_ECC_NUM:
+    {
+        handleECCNumResponse(data, datalen,soc_id);
+        break;
+    }
+    case RIL_UNSOL_CALL_INFO_INDICATION:
+    {
+        handleUnsolCallInfoInd(data, datalen, soc_id);
+        break;
+    }
+    case RIL_UNSOL_RINGBACK_TONE:
+    {
+        handleRingbackTone(data, datalen, soc_id);
+        break;
+    }
+    default:
+        break;
+    }
+#if 0
+    if (ret != 0 && unsolResponse == RIL_UNSOL_NITZ_TIME_RECEIVED) {
+
+        // Unfortunately, NITZ time is not poll/update like everything
+        // else in the system. So, if the upstream client isn't connected,
+        // keep a copy of the last NITZ response (with receive time noted
+        // above) around so we can deliver it when it is connected
+
+        if (s_lastNITZTimeData != NULL) {
+            free (s_lastNITZTimeData);
+            s_lastNITZTimeData = NULL;
+        }
+
+        s_lastNITZTimeData = malloc(p.dataSize());
+        s_lastNITZTimeDataSize = p.dataSize();
+        memcpy(s_lastNITZTimeData, p.data(), p.dataSize());
+    }
+
+#endif
+    // Normal exit
+    return;
+
+error_exit:
+    RLOGD("unsol handle fail");
+#if 0
+    if (shouldScheduleTimeout) {
+        releaseWakeLock();
+    }
+#endif
+}
+
+extern "C" void
+RIL_requestTimedCallback (RIL_TimedCallback callback, void *param,
+                                const struct timeval *relativeTime) {
+}
+
+const char *
+failCauseToString(RIL_Errno e) {
+    switch(e) {
+        case RIL_E_SUCCESS: return "E_SUCCESS";
+        case RIL_E_RADIO_NOT_AVAILABLE: return "E_RADIO_NOT_AVAILABLE";
+        case RIL_E_GENERIC_FAILURE: return "E_GENERIC_FAILURE";
+        case RIL_E_PASSWORD_INCORRECT: return "E_PASSWORD_INCORRECT";
+        case RIL_E_SIM_PIN2: return "E_SIM_PIN2";
+        case RIL_E_SIM_PUK2: return "E_SIM_PUK2";
+        case RIL_E_REQUEST_NOT_SUPPORTED: return "E_REQUEST_NOT_SUPPORTED";
+        case RIL_E_CANCELLED: return "E_CANCELLED";
+        case RIL_E_OP_NOT_ALLOWED_DURING_VOICE_CALL: return "E_OP_NOT_ALLOWED_DURING_VOICE_CALL";
+        case RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW: return "E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW";
+        case RIL_E_SMS_SEND_FAIL_RETRY: return "E_SMS_SEND_FAIL_RETRY";
+        case RIL_E_SIM_ABSENT:return "E_SIM_ABSENT";
+        case RIL_E_ILLEGAL_SIM_OR_ME:return "E_ILLEGAL_SIM_OR_ME";
+#ifdef FEATURE_MULTIMODE_ANDROID
+        case RIL_E_SUBSCRIPTION_NOT_AVAILABLE:return "E_SUBSCRIPTION_NOT_AVAILABLE";
+        case RIL_E_MODE_NOT_SUPPORTED:return "E_MODE_NOT_SUPPORTED";
+#endif
+        case RIL_E_SIM_MEM_FULL: return "E_SIM_MEM_FULL";
+        default: return "<unknown error>";
+    }
+}
+
+const char *
+callStateToString(RIL_CallState s) {
+    switch(s) {
+        case RIL_CALL_ACTIVE : return "ACTIVE";
+        case RIL_CALL_HOLDING: return "HOLDING";
+        case RIL_CALL_DIALING: return "DIALING";
+        case RIL_CALL_ALERTING: return "ALERTING";
+        case RIL_CALL_INCOMING: return "INCOMING";
+        case RIL_CALL_WAITING: return "WAITING";
+        default: return "<unknown state>";
+    }
+}
+
+const char *
+requestToString(int request) {
+/*
+ cat libs/telephony/ril_commands.h \
+ | egrep "^ *{RIL_" \
+ | sed -re 's/\{RIL_([^,]+),[^,]+,([^}]+).+/case RIL_\1: return "\1";/'
+
+
+ cat libs/telephony/ril_unsol_commands.h \
+ | egrep "^ *{RIL_" \
+ | sed -re 's/\{RIL_([^,]+),([^}]+).+/case RIL_\1: return "\1";/'
+
+*/
+    switch(request) {
+        case RIL_REQUEST_GET_SIM_STATUS: return "GET_SIM_STATUS";
+        case RIL_REQUEST_ENTER_SIM_PIN: return "ENTER_SIM_PIN";
+        case RIL_REQUEST_ENTER_SIM_PUK: return "ENTER_SIM_PUK";
+        case RIL_REQUEST_ENTER_SIM_PIN2: return "ENTER_SIM_PIN2";
+        case RIL_REQUEST_ENTER_SIM_PUK2: return "ENTER_SIM_PUK2";
+        case RIL_REQUEST_CHANGE_SIM_PIN: return "CHANGE_SIM_PIN";
+        case RIL_REQUEST_CHANGE_SIM_PIN2: return "CHANGE_SIM_PIN2";
+        case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION: return "ENTER_NETWORK_DEPERSONALIZATION";
+        case RIL_REQUEST_GET_CURRENT_CALLS: return "GET_CURRENT_CALLS";
+        case RIL_REQUEST_DIAL: return "DIAL";
+        case RIL_REQUEST_GET_IMSI: return "GET_IMSI";
+        case RIL_REQUEST_HANGUP: return "HANGUP";
+        case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: return "HANGUP_WAITING_OR_BACKGROUND";
+        case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: return "HANGUP_FOREGROUND_RESUME_BACKGROUND";
+        case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: return "SWITCH_WAITING_OR_HOLDING_AND_ACTIVE";
+        case RIL_REQUEST_CONFERENCE: return "CONFERENCE";
+        case RIL_REQUEST_UDUB: return "UDUB";
+        case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: return "LAST_CALL_FAIL_CAUSE";
+        case RIL_REQUEST_SIGNAL_STRENGTH: return "SIGNAL_STRENGTH";
+        case RIL_REQUEST_VOICE_REGISTRATION_STATE: return "VOICE_REGISTRATION_STATE";
+        case RIL_REQUEST_DATA_REGISTRATION_STATE: return "DATA_REGISTRATION_STATE";
+        case RIL_REQUEST_OPERATOR: return "OPERATOR";
+        case RIL_REQUEST_RADIO_POWER: return "RADIO_POWER";
+        case RIL_REQUEST_DTMF: return "DTMF";
+        case RIL_REQUEST_SEND_SMS: return "SEND_SMS";
+        case RIL_REQUEST_SEND_SMS_EXPECT_MORE: return "SEND_SMS_EXPECT_MORE";
+        case RIL_REQUEST_SETUP_DATA_CALL: return "SETUP_DATA_CALL";
+        case RIL_REQUEST_SIM_IO: return "SIM_IO";
+        case RIL_REQUEST_SEND_USSD: return "SEND_USSD";
+        case RIL_REQUEST_CANCEL_USSD: return "CANCEL_USSD";
+        case RIL_REQUEST_GET_CLIR: return "GET_CLIR";
+        case RIL_REQUEST_SET_CLIR: return "SET_CLIR";
+        case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS: return "QUERY_CALL_FORWARD_STATUS";
+        case RIL_REQUEST_SET_CALL_FORWARD: return "SET_CALL_FORWARD";
+        case RIL_REQUEST_QUERY_CALL_WAITING: return "QUERY_CALL_WAITING";
+        case RIL_REQUEST_SET_CALL_WAITING: return "SET_CALL_WAITING";
+        case RIL_REQUEST_SMS_ACKNOWLEDGE: return "SMS_ACKNOWLEDGE";
+        case RIL_REQUEST_GET_IMEI: return "GET_IMEI";
+        case RIL_REQUEST_GET_IMEISV: return "GET_IMEISV";
+        case RIL_REQUEST_ANSWER: return "ANSWER";
+        case RIL_REQUEST_DEACTIVATE_DATA_CALL: return "DEACTIVATE_DATA_CALL";
+        case RIL_REQUEST_QUERY_FACILITY_LOCK: return "QUERY_FACILITY_LOCK";
+        case RIL_REQUEST_SET_FACILITY_LOCK: return "SET_FACILITY_LOCK";
+        case RIL_REQUEST_CHANGE_BARRING_PASSWORD: return "CHANGE_BARRING_PASSWORD";
+        case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: return "QUERY_NETWORK_SELECTION_MODE";
+        case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: return "SET_NETWORK_SELECTION_AUTOMATIC";
+        case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: return "SET_NETWORK_SELECTION_MANUAL";
+        case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS : return "QUERY_AVAILABLE_NETWORKS ";
+        case RIL_REQUEST_DTMF_START: return "DTMF_START";
+        case RIL_REQUEST_DTMF_STOP: return "DTMF_STOP";
+        case RIL_REQUEST_BASEBAND_VERSION: return "BASEBAND_VERSION";
+        case RIL_REQUEST_SEPARATE_CONNECTION: return "SEPARATE_CONNECTION";
+        case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: return "SET_PREFERRED_NETWORK_TYPE";
+        case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: return "GET_PREFERRED_NETWORK_TYPE";
+        case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: return "GET_NEIGHBORING_CELL_IDS";
+        case RIL_REQUEST_SET_MUTE: return "SET_MUTE";
+        case RIL_REQUEST_GET_MUTE: return "GET_MUTE";
+        case RIL_REQUEST_QUERY_CLIP: return "QUERY_CLIP";
+        case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE: return "LAST_DATA_CALL_FAIL_CAUSE";
+        case RIL_REQUEST_DATA_CALL_LIST: return "DATA_CALL_LIST";
+        case RIL_REQUEST_RESET_RADIO: return "RESET_RADIO";
+        case RIL_REQUEST_OEM_HOOK_RAW: return "OEM_HOOK_RAW";
+        case RIL_REQUEST_OEM_HOOK_STRINGS: return "OEM_HOOK_STRINGS";
+        case RIL_REQUEST_SET_BAND_MODE: return "SET_BAND_MODE";
+        case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: return "QUERY_AVAILABLE_BAND_MODE";
+        case RIL_REQUEST_STK_GET_PROFILE: return "STK_GET_PROFILE";
+        case RIL_REQUEST_STK_SET_PROFILE: return "STK_SET_PROFILE";
+        case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: return "STK_SEND_ENVELOPE_COMMAND";
+        case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: return "STK_SEND_TERMINAL_RESPONSE";
+        case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: return "STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM";
+        case RIL_REQUEST_SCREEN_STATE: return "SCREEN_STATE";
+        case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: return "EXPLICIT_CALL_TRANSFER";
+        case RIL_REQUEST_SET_LOCATION_UPDATES: return "SET_LOCATION_UPDATES";
+        case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE:return"CDMA_SET_SUBSCRIPTION_SOURCE";
+        case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE:return"CDMA_SET_ROAMING_PREFERENCE";
+        case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE:return"CDMA_QUERY_ROAMING_PREFERENCE";
+        case RIL_REQUEST_SET_TTY_MODE:return"SET_TTY_MODE";
+        case RIL_REQUEST_QUERY_TTY_MODE:return"QUERY_TTY_MODE";
+        case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE:return"CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE";
+        case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE:return"CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE";
+        case RIL_REQUEST_CDMA_FLASH:return"CDMA_FLASH";
+        case RIL_REQUEST_CDMA_BURST_DTMF:return"CDMA_BURST_DTMF";
+        case RIL_REQUEST_CDMA_SEND_SMS:return"CDMA_SEND_SMS";
+        case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE:return"CDMA_SMS_ACKNOWLEDGE";
+        case RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG:return"GSM_GET_BROADCAST_SMS_CONFIG";
+        case RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG:return"GSM_SET_BROADCAST_SMS_CONFIG";
+        case RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION:return "GSM_SMS_BROADCAST_ACTIVATION";
+        case RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG:return "CDMA_GET_BROADCAST_SMS_CONFIG";
+        case RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG:return "CDMA_SET_BROADCAST_SMS_CONFIG";
+        case RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION:return "CDMA_SMS_BROADCAST_ACTIVATION";
+        case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY: return"CDMA_VALIDATE_AND_WRITE_AKEY";
+        case RIL_REQUEST_CDMA_SUBSCRIPTION: return"CDMA_SUBSCRIPTION";
+        case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM: return "CDMA_WRITE_SMS_TO_RUIM";
+        case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM: return "CDMA_DELETE_SMS_ON_RUIM";
+        case RIL_REQUEST_DEVICE_IDENTITY: return "DEVICE_IDENTITY";
+        case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: return "EXIT_EMERGENCY_CALLBACK_MODE";
+        case RIL_REQUEST_GET_SMSC_ADDRESS: return "GET_SMSC_ADDRESS";
+        case RIL_REQUEST_SET_SMSC_ADDRESS: return "SET_SMSC_ADDRESS";
+        case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: return "REPORT_SMS_MEMORY_STATUS";
+        case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: return "REPORT_STK_SERVICE_IS_RUNNING";
+        case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: return "CDMA_GET_SUBSCRIPTION_SOURCE";
+        case RIL_REQUEST_ISIM_AUTHENTICATION: return "ISIM_AUTHENTICATION";
+        case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU: return "RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU";
+        case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS: return "RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS";
+        case RIL_REQUEST_VOICE_RADIO_TECH: return "VOICE_RADIO_TECH";
+        case RIL_REQUEST_GET_CELL_INFO_LIST: return"GET_CELL_INFO_LIST";
+        case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE: return"SET_UNSOL_CELL_INFO_LIST_RATE";
+        case RIL_REQUEST_SET_INITIAL_ATTACH_APN: return "RIL_REQUEST_SET_INITIAL_ATTACH_APN";
+        case RIL_REQUEST_IMS_REGISTRATION_STATE: return "IMS_REGISTRATION_STATE";
+        case RIL_REQUEST_IMS_SEND_SMS: return "IMS_SEND_SMS";
+        case RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC: return "SIM_TRANSMIT_APDU_BASIC";
+        case RIL_REQUEST_SIM_OPEN_CHANNEL: return "SIM_OPEN_CHANNEL";
+        case RIL_REQUEST_SIM_CLOSE_CHANNEL: return "SIM_CLOSE_CHANNEL";
+        case RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL: return "SIM_TRANSMIT_APDU_CHANNEL";
+        case RIL_REQUEST_GET_RADIO_CAPABILITY: return "RIL_REQUEST_GET_RADIO_CAPABILITY";
+        case RIL_REQUEST_SET_RADIO_CAPABILITY: return "RIL_REQUEST_SET_RADIO_CAPABILITY";
+        case RIL_REQUEST_SET_UICC_SUBSCRIPTION: return "SET_UICC_SUBSCRIPTION";
+        case RIL_REQUEST_ALLOW_DATA: return "ALLOW_DATA";
+        case RIL_REQUEST_GET_HARDWARE_CONFIG: return "GET_HARDWARE_CONFIG";
+        case RIL_REQUEST_SIM_AUTHENTICATION: return "SIM_AUTHENTICATION";
+        case RIL_REQUEST_GET_DC_RT_INFO: return "GET_DC_RT_INFO";
+        case RIL_REQUEST_SET_DC_RT_INFO_RATE: return "SET_DC_RT_INFO_RATE";
+        case RIL_REQUEST_SET_DATA_PROFILE: return "SET_DATA_PROFILE";
+        case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: return "UNSOL_RESPONSE_RADIO_STATE_CHANGED";
+        case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: return "UNSOL_RESPONSE_CALL_STATE_CHANGED";
+        case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: return "UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED";
+        case RIL_UNSOL_RESPONSE_NEW_SMS: return "UNSOL_RESPONSE_NEW_SMS";
+        case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: return "UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT";
+        case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: return "UNSOL_RESPONSE_NEW_SMS_ON_SIM";
+        case RIL_UNSOL_ON_USSD: return "UNSOL_ON_USSD";
+        case RIL_UNSOL_ON_USSD_REQUEST: return "UNSOL_ON_USSD_REQUEST(obsolete)";
+        case RIL_UNSOL_NITZ_TIME_RECEIVED: return "UNSOL_NITZ_TIME_RECEIVED";
+        case RIL_UNSOL_SIGNAL_STRENGTH: return "UNSOL_SIGNAL_STRENGTH";
+        case RIL_UNSOL_STK_SESSION_END: return "UNSOL_STK_SESSION_END";
+        case RIL_UNSOL_STK_PROACTIVE_COMMAND: return "UNSOL_STK_PROACTIVE_COMMAND";
+        case RIL_UNSOL_STK_EVENT_NOTIFY: return "UNSOL_STK_EVENT_NOTIFY";
+        case RIL_UNSOL_STK_CALL_SETUP: return "UNSOL_STK_CALL_SETUP";
+        case RIL_UNSOL_SIM_SMS_STORAGE_FULL: return "UNSOL_SIM_SMS_STORAGE_FUL";
+        case RIL_UNSOL_SIM_REFRESH: return "UNSOL_SIM_REFRESH";
+        case RIL_UNSOL_DATA_CALL_LIST_CHANGED: return "UNSOL_DATA_CALL_LIST_CHANGED";
+        case RIL_UNSOL_CALL_RING: return "UNSOL_CALL_RING";
+        case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: return "UNSOL_RESPONSE_SIM_STATUS_CHANGED";
+        case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: return "UNSOL_NEW_CDMA_SMS";
+        case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: return "UNSOL_NEW_BROADCAST_SMS";
+        case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL: return "UNSOL_CDMA_RUIM_SMS_STORAGE_FULL";
+        case RIL_UNSOL_RESTRICTED_STATE_CHANGED: return "UNSOL_RESTRICTED_STATE_CHANGED";
+        case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: return "UNSOL_ENTER_EMERGENCY_CALLBACK_MODE";
+        case RIL_UNSOL_CDMA_CALL_WAITING: return "UNSOL_CDMA_CALL_WAITING";
+        case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: return "UNSOL_CDMA_OTA_PROVISION_STATUS";
+        case RIL_UNSOL_CDMA_INFO_REC: return "UNSOL_CDMA_INFO_REC";
+        case RIL_UNSOL_OEM_HOOK_RAW: return "UNSOL_OEM_HOOK_RAW";
+        case RIL_UNSOL_RINGBACK_TONE: return "UNSOL_RINGBACK_TONE";
+        case RIL_UNSOL_RESEND_INCALL_MUTE: return "UNSOL_RESEND_INCALL_MUTE";
+        case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED: return "UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED";
+        case RIL_UNSOL_CDMA_PRL_CHANGED: return "UNSOL_CDMA_PRL_CHANGED";
+        case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: return "UNSOL_EXIT_EMERGENCY_CALLBACK_MODE";
+        case RIL_UNSOL_RIL_CONNECTED: return "UNSOL_RIL_CONNECTED";
+        case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED: return "UNSOL_VOICE_RADIO_TECH_CHANGED";
+        case RIL_UNSOL_CELL_INFO_LIST: return "UNSOL_CELL_INFO_LIST";
+        case RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED: return "RESPONSE_IMS_NETWORK_STATE_CHANGED";
+        case RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED: return "UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED";
+        case RIL_UNSOL_SRVCC_STATE_NOTIFY: return "UNSOL_SRVCC_STATE_NOTIFY";
+        case RIL_UNSOL_HARDWARE_CONFIG_CHANGED: return "HARDWARE_CONFIG_CHANGED";
+        case RIL_UNSOL_DC_RT_INFO_CHANGED: return "UNSOL_DC_RT_INFO_CHANGED";
+        case RIL_REQUEST_SHUTDOWN: return "SHUTDOWN";
+        case RIL_UNSOL_RADIO_CAPABILITY: return "RIL_UNSOL_RADIO_CAPABILITY";
+        case RIL_REQUEST_SET_TRM: return "RIL_REQUEST_SET_TRM";
+        case RIL_REQUEST_SET_IMS_ENABLE:return "RIL_REQUEST_SET_IMS_ENABLE";
+        case RIL_REQUEST_SET_AUDIO_PATH: return "SET_AUDIO_PATH";
+        case RIL_REQUEST_HANGUP_ALL: return "HANGUP_ALL";
+        case RIL_REQUEST_FORCE_RELEASE_CALL: return "FORCE_RELEASE_CALL";
+        case RIL_REQUEST_EMERGENCY_DIAL: return "RIL_REQUEST_EMERGENCY_DIAL";
+        case RIL_REQUEST_SET_ECC_SERVICE_CATEGORY: return "RIL_REQUEST_SET_ECC_SERVICE_CATEGORY";
+        case RIL_REQUEST_SET_ECC_LIST: return "RIL_REQUEST_SET_ECC_LIST";
+        case RIL_REQUEST_AT_COMMAND_WITH_PROXY: return "AT_COMMAND_WITH_PROXY";
+        case RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION: return "RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION";
+        case RIL_REQUEST_SET_CLIP: return "RIL_REQUEST_SET_CLIP";
+        case RIL_REQUEST_GET_COLP: return "RIL_REQUEST_GET_COLP";
+        case RIL_REQUEST_SET_COLP: return "RIL_REQUEST_SET_COLP";
+        case RIL_REQUEST_GET_COLR: return "RIL_REQUEST_GET_COLR";
+        case RIL_REQUEST_ADD_IMS_CONFERENCE_CALL_MEMBER: return "ADD_IMS_CONFERENCE_CALL_MEMBER";
+        case RIL_REQUEST_REMOVE_IMS_CONFERENCE_CALL_MEMBER: return "REMOVE_IMS_CONFERENCE_CALL_MEMBER";
+        case RIL_REQUEST_CONFERENCE_DIAL: return "CONFERENCE_DIAL";
+        case RIL_REQUEST_DIAL_WITH_SIP_URI: return "DIAL_WITH_SIP_URI";
+        case RIL_REQUEST_HOLD_CALL: return "HOLD_CALL";
+        case RIL_REQUEST_RESUME_CALL: return "RESUME_CALL";
+        case RIL_UNSOL_ECONF_SRVCC_INDICATION : return "ECONF_SRVCC_INDICATION";
+        case RIL_UNSOL_ECONF_RESULT_INDICATION : return "ECONF_RESULT_INDICATION";
+        case RIL_UNSOL_MAL_AT_INFO : return "UNSOL_MAL_AT_INFO";
+        case RIL_REQUEST_MODEM_POWEROFF: return "MODEM_POWEROFF";
+        case RIL_REQUEST_MODEM_POWERON: return "MODEM_POWERON";
+        case RIL_REQUEST_WRITE_SMS_TO_SIM: return "WRITE_SMS_TO_SIM";
+        case RIL_REQUEST_QUERY_ICCID: return "RIL_REQUEST_QUERY_ICCID";
+        case RIL_UNSOL_TX_POWER: return "RIL_UNSOL_TX_POWER";
+        case RIL_UNSOL_NETWORK_INFO: return "RIL_UNSOL_NETWORK_INFO";
+        case RIL_REQUEST_DELETE_SMS_ON_SIM: return "DELETE_SMS_ON_SIM";
+        case RIL_REQUEST_SET_IMSCFG: return "RIL_REQUEST_SET_IMSCFG";
+#ifdef ECALL_SUPPORT
+        case RIL_REQUEST_ECALL_FAST_MAKE_ECALL: return "ECALL_FAST_MAKE_ECALL";
+        case RIL_REQUEST_ECALL_SET_IVS: return "RIL_REQUEST_ECALL_SET_IVS";
+        case RIL_REQUEST_ECALL_SET_PSAP: return "RIL_REQUEST_ECALL_SET_PSAP";
+        case RIL_REQUEST_ECALL_MAKE_ECALL: return "RIL_REQUEST_ECALL_MAKE_ECALL";
+        case RIL_REQUEST_ECALL_IVS_PUSH_MSD: return "RIL_REQUEST_ECALL_IVS_PUSH_MSD";
+        case RIL_REQUEST_ECALL_PSAP_PULL_MSD: return "RIL_REQUEST_ECALL_PSAP_PULL_MSD";
+        case RIL_UNSOL_ECALL_MSDHACK : return "ECALL_MSDHACK";
+        case RIL_REQUEST_ECALL_SET_MSD: return "RIL_REQUEST_ECALL_SET_MSD";
+        case RIL_REQUEST_ECALL_CTRL_SEQUENCE: return "ECALL_SET_CTRL_SEQUENCE";
+        case RIL_UNSOL_ECALL_INDICATIONS : return "ECALL_INDICATIONS";
+        case RIL_REQUEST_ECALL_RESET_IVS: return "RIL_REQUEST_ECALL_RESET_IVS";
+        case RIL_REQUEST_ECALL_SET_PRI: return "RIL_REQUEST_ECALL_SET_PRI";
+        case RIL_REQUEST_ECALL_SET_TEST_NUM: return "RIL_REQUEST_ECALL_SET_TEST_NUM";
+        case RIL_REQUEST_ECALL_SET_RECONF_NUM: return "RIL_REQUEST_ECALL_SET_RECONF_NUM";
+        case RIL_REQUEST_SYNC_DATA_SETTINGS_TO_MD: return "RIL_REQUEST_SYNC_DATA_SETTINGS_TO_MD";
+        case RIL_REQUEST_ECALL_SET_NAD_DEREGISTRATION_TIME: return "RIL_REQUEST_ECALL_SET_NAD_DEREGISTRATION_TIME";
+        case RIL_REQUEST_ECALL_SET_REGISTRATION_STATE: return "RIL_REQUEST_ECALL_SET_REGISTRATION_STATE";
+#endif /*ECALL_SUPPORT*/
+#ifdef KEEP_ALIVE
+        case RIL_REQUEST_START_KEEPALIVE_PRO: return "RIL_REQUEST_START_KEEPALIVE_PRO";
+        case RIL_REQUEST_STOP_KEEPALIVE_PRO: return "RIL_REQUEST_STOP_KEEPALIVE_PRO";
+        case RIL_UNSOL_KEEPALIVE_STATUS_PRO: return "RIL_UNSOL_KEEPALIVE_STATUS_PRO";
+#endif /*KEEP_ALIVE*/
+        case RIL_REQUEST_SEND_USSI: return "SEND_USSI";
+        case RIL_REQUEST_CANCEL_USSI: return "CANCEL_USSI";
+        case RIL_REQUEST_GET_SMS_SIM_MEM_STATUS: return "GET_SMS_SIM_MEM_STATUS";
+        case RIL_UNSOL_SIP_CALL_PROGRESS_INDICATOR: return "RIL_UNSOL_SIP_CALL_PROGRESS_INDICATOR";
+        case RIL_REQUEST_REPORT_AIRPLANE_MODE: return "RIL_REQUEST_REPORT_AIRPLANE_MODE";
+        case RIL_REQUEST_SET_ECC_NUM: return "RIL_REQUEST_SET_ECC_NUM";
+        case RIL_REQUEST_GET_ECC_NUM: return "RIL_REQUEST_GET_ECC_NUM";
+        case RIL_UNSOL_ECC_NUM: return "RIL_UNSOL_ECC_NUM";
+        case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS_WITH_ACT: return "RIL_REQUEST_QUERY_AVAILABLE_NETWORKS_WITH_ACT";
+        case RIL_REQUEST_GSM_GET_BROADCAST_LANGUAGE: return "RIL_REQUEST_GSM_GET_BROADCAST_LANGUAGE";
+        case RIL_REQUEST_GSM_SET_BROADCAST_LANGUAGE: return "RIL_REQUEST_GSM_SET_BROADCAST_LANGUAGE";
+        case RIL_UNSOL_CALL_INFO_INDICATION: return "RIL_UNSOL_CALL_INFO_INDICATION";
+#ifdef TARGET_PLATFORM_MT2731
+        case RIL_REQUEST_MODIFY_APN: return "RIL_REQUEST_MODIFY_APN";
+        case RIL_REQUEST_RESET_APN: return "RIL_REQUEST_RESET_APN";
+        case RIL_REQUEST_QUERY_SIM_RETRY_COUNT: return "RIL_REQUEST_QUERY_SIM_RETRY_COUNT";
+#endif
+        case RIL_REQUEST_QUERY_EID: return "RIL_REQUEST_QUERY_EID";
+        default: return "<unknown request>";
+    }
+}
+
+static int sendResponse (Parcel &p, RIL_SOCKET_ID socket_id) {
+    printResponse;
+    int type;
+    if(enable_bt_resp){
+        SendRespToClient(p.data(), p.dataSize());
+    }
+    p.setDataPosition(0);
+    p.readInt32(&type);
+    if(type == RESPONSE_UNSOLICITED){
+        processUnsolicited(p,type);
+    }else if (type == RESPONSE_SOLICITED){
+        processSolicited(p,type);
+    }
+    return 0;
+}
+
+static void speciaRequest_wait()
+{
+    struct timeval now;
+    struct timespec timeout;
+
+    gettimeofday(&now,NULL);
+    timeout.tv_sec = now.tv_sec+1200; //timeout is 2omin. maybe radio on/off need 10s to complete.
+    timeout.tv_nsec = now.tv_usec*1000;
+
+    SPECIA_BLOCK_LOCK();
+    while(!(requestOneByOne == 0)) {
+        int ret = SPECIA_BLOCK_WAIT(&timeout);
+        if(ret == ETIMEDOUT){
+            RLOGD("special request wait timeout");
+            break;
+        }
+    }
+    requestOneByOne = 1;
+    SPECIA_BLOCK_UNLOCK();
+}
+
+static void speciaRequest_wakeup()
+{
+    SPECIA_BLOCK_LOCK();
+    requestOneByOne = 0;
+    SPECIA_BLOCK_WAKEUP();
+    SPECIA_BLOCK_UNLOCK();
+}
+
+static void updateIccCardState(RIL_SOCKET_ID soc_id)
+{
+    ARspRequest(RIL_REQUEST_GET_SIM_STATUS, soc_id);
+}
+
+void sendRequestToMd(int request, int id) {
+    RequestInfo* info = creatRILInfoAndInit(request, INIT, (RIL_SOCKET_ID) ((id)));
+    switch(request){
+        case RIL_REQUEST_DEVICE_IDENTITY:
+        {
+            getDeviceIdentity(1, NULL, (RIL_SOCKET_ID) ((id)), info);
+            break;
+        }
+        case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE:
+        {
+            getPreferredNetworkType(1, NULL, (RIL_SOCKET_ID) ((id)), info);
+            break;
+        }
+        case RIL_REQUEST_GET_SIM_STATUS:
+        {
+            getIccCardStatus(1, NULL, (RIL_SOCKET_ID) (id), info);
+            break;
+        }
+        case RIL_REQUEST_DATA_REGISTRATION_STATE:
+        {
+            getDataRegistrationState(1, NULL, (RIL_SOCKET_ID) (id), info);
+            break;
+        }
+        case RIL_REQUEST_VOICE_REGISTRATION_STATE:
+        {
+            getVoiceRegistrationState(1, NULL, (RIL_SOCKET_ID) (id), info);
+            break;
+        }
+        case RIL_REQUEST_VOICE_RADIO_TECH:
+        {
+            getVoiceRadioTechnology(1, NULL, (RIL_SOCKET_ID) (id), info);
+            break;
+        }
+        case RIL_REQUEST_OEM_HOOK_RAW:
+        {
+            char* tmp[2] = {"RIL_REQUEST_OEM_HOOK_RAW", "AT+ECAL"};
+            sendATCMD(2, tmp, (RIL_SOCKET_ID) (id), info);
+            break;
+        }
+        case RIL_REQUEST_GET_RADIO_CAPABILITY:
+        {
+            getRadioCapability(1, NULL, (RIL_SOCKET_ID) ((id)), info);
+            break;
+        }
+        default:
+            RLOGE("don't support  %d in init", id);
+            if(info) {
+                free(info);
+            }
+    }
+}
+
+static void init(int id) {
+    int waittoken;
+    RIL_RadioState radioState = CALL_ONSTATEREQUEST((RIL_SOCKET_ID )id);
+    while (radioState == RADIO_STATE_UNAVAILABLE) {
+        sleep(1);
+        radioState = CALL_ONSTATEREQUEST((RIL_SOCKET_ID )id);
+        RLOGD("init socket id: %d, %s", id, radioStateToString(radioState));
+    }
+    RLOGD("init socket id: %d, %s", id, radioStateToString(radioState));
+
+    sendRequestToMd(RIL_REQUEST_GET_SIM_STATUS, id);
+
+#if 0
+    if (radioState != RADIO_STATE_ON) {
+        RequestInfo* radio = creatRILInfoAndInit(RIL_REQUEST_RADIO_POWER, INIT, (RIL_SOCKET_ID) (id));
+        waittoken = radio->token;
+        RLOGD("[%s-%d]:token is %x", __FUNCTION__, __LINE__, radio->token);
+        char* tmp[2] = { "RIL_REQUEST_RADIO_POWER", "1" };
+        setRadioPower(2, tmp, (RIL_SOCKET_ID) (id), radio);
+        waitResponse(waittoken);
+        sleep(2);
+        radioState = CALL_ONSTATEREQUEST((RIL_SOCKET_ID )id);
+        RLOGD("NOW radio status %s", radioStateToString(radioState));
+    }
+# endif
+    sendRequestToMd(RIL_REQUEST_DATA_REGISTRATION_STATE, id);
+    sendRequestToMd(RIL_REQUEST_VOICE_REGISTRATION_STATE, id);
+    sendRequestToMd(RIL_REQUEST_VOICE_RADIO_TECH, id);
+    sendRequestToMd(RIL_REQUEST_DEVICE_IDENTITY,id);
+    sendRequestToMd(RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE, id);
+    sendRequestToMd(RIL_REQUEST_OEM_HOOK_RAW, id);
+    sendRequestToMd(RIL_REQUEST_GET_RADIO_CAPABILITY,id);
+}
+
+static void initCoditions()
+{
+    if(utils::is_support_dsds()) {
+        for(int i = 0; i < 2 ; i++) {
+            init(i);
+        }
+    }
+
+    if(utils::is_suppport_dsss()) {
+        int id = Phone_utils::get_enable_sim_for_dsss();
+        init(id);
+    }
+    mixer_init();
+}
+
+
+//For UDP sokcet send response to client
+static int SendRespToClient(const void *data, size_t dataSize)
+{
+    const uint8_t *toWrite;
+    size_t writeOffset = 0;
+
+    toWrite = (const uint8_t *)data;
+
+    if (toWrite == NULL) {
+    //buf is invaild
+        return -1;
+    }
+
+    while (writeOffset < dataSize) {
+        ssize_t written;
+        do {
+            //written = write (fd, toWrite + writeOffset,dataSize - writeOffset);
+            written = sendto(server_socket_fd, toWrite + writeOffset, dataSize - writeOffset,
+                                     0, (struct sockaddr *)&client_addr, sizeof(client_addr));
+        } while (written < 0 && ((errno == EINTR) || (errno == EAGAIN)));
+
+        if (written >= 0) {
+            writeOffset += written;
+        } else {   // written < 0
+            RLOGE ("RIL Response: unexpected error on write errno:%d", errno);
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+static UnsolResponseInfo* find_mtk_unsol_command(int request)
+{
+    int i;
+    for (i = 0; i < (int32_t)NUM_ELEMS(s_mtk_unsolResponses); i++)
+        if (s_mtk_unsolResponses[i].requestNumber == request)
+            return (&s_mtk_unsolResponses[i]);
+    return ((UnsolResponseInfo *)NULL);
+}
+
+static int
+onSupports (int requestCode)
+{
+    switch(requestCode)
+    {
+        case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: return 1;
+        case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: return 1;
+        case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: return 1;
+        case RIL_UNSOL_RESPONSE_NEW_SMS: return 1;
+        case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: return 1;
+        case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: return 1;
+        case RIL_UNSOL_ON_USSD: return 1;
+        case RIL_UNSOL_ON_USSD_REQUEST: return 1;
+        case RIL_UNSOL_NITZ_TIME_RECEIVED: return 1;
+        case RIL_UNSOL_SIGNAL_STRENGTH: return 1;
+        case RIL_UNSOL_DATA_CALL_LIST_CHANGED: return 1;
+        case RIL_UNSOL_SUPP_SVC_NOTIFICATION: return 1;
+        case RIL_UNSOL_STK_SESSION_END: return 1;
+        case RIL_UNSOL_STK_PROACTIVE_COMMAND: return 1;
+        case RIL_UNSOL_STK_EVENT_NOTIFY: return 1;
+        case RIL_UNSOL_STK_CALL_SETUP: return 1;
+        case RIL_UNSOL_SIM_SMS_STORAGE_FULL: return 1;
+        case RIL_UNSOL_SIM_REFRESH: return 1;
+        case RIL_UNSOL_CALL_RING: return 1;
+        case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: return 1;
+        case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: return 1;
+        case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: return 1;
+        case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL: return 0;
+        case RIL_UNSOL_RESTRICTED_STATE_CHANGED: return 1;
+        case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: return 1;
+        case RIL_UNSOL_CDMA_CALL_WAITING: return 1;
+        case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: return 0;
+        case RIL_UNSOL_CDMA_INFO_REC: return 0;
+        case RIL_UNSOL_OEM_HOOK_RAW: return 1;
+        case RIL_UNSOL_RINGBACK_TONE: return 1;
+        case RIL_UNSOL_RESEND_INCALL_MUTE: return 0;
+        case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED: return 0;
+        case RIL_UNSOL_CDMA_PRL_CHANGED: return 0;
+        case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: return 1;
+        case RIL_UNSOL_RIL_CONNECTED: return 1;
+        case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED: return 1;
+        case RIL_UNSOL_CELL_INFO_LIST: return 1;
+        case RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED: return 1;
+        case RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED: return 1;
+        case RIL_UNSOL_SRVCC_STATE_NOTIFY: return 1;
+        case RIL_UNSOL_HARDWARE_CONFIG_CHANGED: return 0;
+        case RIL_UNSOL_DC_RT_INFO_CHANGED: return 0;
+        case RIL_UNSOL_RADIO_CAPABILITY : return 1;
+        case RIL_UNSOL_MAL_RESTART : return 1;
+        case RIL_UNSOL_CALL_INFO_INDICATION : return 1;
+        case RIL_UNSOL_CRSS_NOTIFICATION : return 0;
+        case RIL_UNSOL_ECONF_SRVCC_INDICATION : return 1;
+        case RIL_UNSOL_ECONF_RESULT_INDICATION : return 1;
+        case RIL_UNSOL_STK_BIP_PROACTIVE_COMMAND : return 0;
+        case RIL_UNSOL_MAL_AT_INFO: return 1;
+        case RIL_UNSOL_ECALL_MSDHACK: return 1;
+        case RIL_UNSOL_TX_POWER: return 1;
+        case RIL_UNSOL_NETWORK_INFO: return 1;
+#ifdef ECALL_SUPPORT
+        case RIL_UNSOL_ECALL_INDICATIONS: return 1;
+#endif /*ECALL_SUPPORT*/
+#ifdef KEEP_ALIVE
+        case RIL_UNSOL_KEEPALIVE_STATUS_PRO: return 1;
+#endif /*KEEP_ALIVE*/
+        case RIL_UNSOL_ON_USSI: return 1;
+        case RIL_UNSOL_ECC_NUM: return 1;
+        case RIL_UNSOL_SIP_CALL_PROGRESS_INDICATOR: return 1;
+        default: return 0;
+    }
+}
+
+int parse_param(char *cmd, char *argv[], int max_args)
+{
+    char *pos, *pos2;
+    int argc = 0;
+
+    pos = cmd;
+    while (1) {
+        // Trim the space characters.
+        while (*pos == ' ') {
+            pos++;
+        }
+
+        if (*pos == '\0') {
+            break;
+        }
+
+        // One token may start with '"' or other characters.
+        if (*pos == '"' && (pos2 = strrchr(pos+1, '"'))) {
+            argv[argc++] = pos + 1;
+            *pos2 = '\0';
+            pos = pos2 + 1;
+            if(*pos == '\n'){
+                *pos = '\0';
+                pos = pos + 1;
+            }
+
+        } else {
+            argv[argc++] = pos;
+            while (*pos != '\0' && *pos != ' '&& *pos != '\n') {
+                pos++;
+            }
+            *pos++ = '\0';
+
+            if(argc == 1) {
+              char* at_cmd = strstr(argv[0], "RIL_REQUEST_OEM_HOOK_RAW");
+              if(at_cmd != NULL) {
+                while (*pos == ' ') {
+                    pos++;
+                }
+                argv[argc++] = pos;
+                break;
+              }
+            }
+
+        }
+
+        // Check if the maximum of arguments is reached.
+        if (argc == max_args) {
+            break;
+        }
+    }
+
+    return argc;
+}
+
+/* Look up NAME as the name of a command, and return a pointer to that
+   command.  Return a NULL pointer if NAME isn't a command name. */
+COMMAND* lynq_find_command (int request)
+{
+    int i;
+    for (i = 0; i < (int32_t)NUM_ELEMS(commands); i++)
+        if (commands[i].request == request)
+            return (&commands[i]);
+    return ((COMMAND *)NULL);
+}
+
+COMMAND* find_command (char *name)
+{
+  register int i;
+
+  for (i = 0; commands[i].name; i++)
+    if (strcmp (name, commands[i].name) == 0)
+      return (&commands[i]);
+
+  return ((COMMAND *)NULL);
+}
+
+CommandInfo* find_mtk_command (int request)
+{
+    int i;
+    for (i = 0; i < (int32_t)NUM_ELEMS(mtk_s_command); i++)
+        if (mtk_s_command[i].requestNumber == request)
+            return (&mtk_s_command[i]);
+    return ((CommandInfo *)NULL);
+}
+
+/* The user wishes to quit using this program.  Just set DONE non-zero. */
+static int com_quit (int argc, char *argv[], RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    exit(EXIT_SUCCESS);
+    return (0);
+}
+
+static int enableSyslog(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    if(argc < 2)
+    {
+        RLOGE("[Error] enable syslog paramter is error\n");
+        free(pRI);
+        return -1;
+    }
+    enable_syslog = atoi(argv[1]);
+    RLOGE("%s syslog\n",enable_syslog ? "enable" :"disable");
+    free(pRI);
+    return 0;
+}
+
+static int enableBTResponse(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    if(argc < 2)
+    {
+        RLOGE("[Error] enable BT response paramter is error\n");
+        free(pRI);
+        return -1;
+    }
+    enable_bt_resp = atoi(argv[1]);
+    RLOGE("%s bt response!\n",enable_bt_resp ? "enable" :"disable");
+    free(pRI);
+    return 0;
+
+}
+
+char Time_buf[24];
+void GetTimeString(char * buf)
+{
+    time_t timep;
+    struct tm p;
+
+    if(buf == NULL){
+        RLOGE("[Error] GetTimeString: buf is Null\n");
+        return;
+    }
+    //memset(buf,0,sizeof(buf));
+    time(&timep);
+    localtime_r(&timep,&p);
+    sprintf(buf,"%d_%d_%d %d:%d:%d",(1900+p.tm_year),(1+p.tm_mon),p.tm_mday,
+                                      (p.tm_hour),p.tm_min,p.tm_sec);
+//    printf("data is %s\n",buf);
+
+    return;
+}
+
+void
+RIL_StartRevSocket()
+{
+    RLOGD("RIL_StartRevSocket start\n");
+    char *argv[MAX_ARGS];
+    int  argc = 0;
+
+    prctl(PR_SET_NAME,(unsigned long)"UDP_Thr");
+
+    /*listen UPD SOCKET port */
+    struct sockaddr_in server_addr;
+    bzero(&server_addr, sizeof(server_addr));
+    server_addr.sin_family = AF_INET;
+    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+    server_addr.sin_port = htons(SERVER_PORT);
+    /* create socket */
+    //int server_socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
+    server_socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
+    if(server_socket_fd == -1)
+    {
+     RLOGE("Create Socket Failed:");
+     exit(1);
+    }
+
+    /* bind socket port*/
+    if(-1 == (bind(server_socket_fd,(struct sockaddr*)&server_addr,sizeof(server_addr))))
+    {
+     RLOGE("Server Bind Failed:");
+     exit(1);
+    }
+
+    /* tranlate data */
+    while(true)
+    {
+        if(!s_registerCalled)
+        {
+            sleep(1);
+            continue;
+        }
+         /* define address to catch the client addreess*/
+        //struct sockaddr_in client_addr;
+        socklen_t client_addr_length = sizeof(client_addr);
+
+        /* receive the data */
+        char buffer[BUFFER_SIZE];
+        bzero(buffer, BUFFER_SIZE);
+        if(recvfrom(server_socket_fd, buffer, BUFFER_SIZE,0,(struct sockaddr*)&client_addr, &client_addr_length) == -1)
+        {
+            RLOGE("Receive Data Failed:");
+            continue;
+        }
+        RLOGD("DemoAPP:%s, receve: %s", inet_ntoa(client_addr.sin_addr), buffer);
+        int argc = parse_param(buffer, argv, MAX_ARGS);
+        if(argc < 1)
+        {
+            RLOGE("%s: error input.", buffer);
+            continue;
+        }
+        COMMAND *command = find_command(argv[0]);
+        if(!command)
+        {
+            RLOGE("%s: No such command for DemoApp", argv[0]);
+            continue;
+        }
+
+        int32_t request;
+
+        request = command->request;
+
+        RIL_SOCKET_ID id = RIL_SOCKET_1;
+        if(utils::is_support_dsds()) {
+            id = (RIL_SOCKET_ID)get_default_sim_all_except_data();
+        } else if(utils::is_suppport_dsss()) {
+            id = (RIL_SOCKET_ID)Phone_utils::get_enable_sim_for_dsss();
+        }
+
+        if(request == -1)
+        {
+            (*(command->func)) (argc, argv, id, NULL);
+            continue;
+        }
+
+        if (request < 1 || (request >= (int32_t)NUM_ELEMS(s_commands) && request < RIL_REQUEST_VENDOR_BASE)) {
+            RLOGW("unsupported request code %d token %d", request);
+            // FIXME this should perhaps return a response
+            continue;
+        }
+
+        RLOGD("REQUEST: %s ParamterNum:%d", requestToString(request), argc);
+
+
+        RequestInfo *pRI  = creatRILInfoAndInit(request, UDP, (RIL_SOCKET_ID)(id));
+        //Radio on/off only allow one thread operate.
+        if(request == RIL_REQUEST_RADIO_POWER)
+        {
+            speciaRequest_wait();
+        }
+        memset(Time_buf,0,sizeof(Time_buf));
+        GetTimeString(Time_buf);
+        //FUNCTION_CALLED(Time_buf,requestToString(request));
+        int waittoken = pRI->token;
+        (*(command->func)) (argc, argv, pRI->socket_id, pRI);
+        FUNCTION_CALLED(Time_buf,requestToString(request));
+        waitResponse(waittoken);
+        memset(Time_buf,0,sizeof(Time_buf));
+        GetTimeString(Time_buf);
+        FUNCTION_RETURN(Time_buf,requestToString(request));
+     }
+
+     RLOGD("close socket fd");
+     close(server_socket_fd);
+     return ;
+}
+
+const int waitResponse(int token)
+{
+    int waitToken = token;
+    struct timeval now;
+    struct timespec timeout;
+    if((token&BLOCK_MARK) != BLOCK_MARK){
+        RLOGD("No need wait!,token is %x!",token);
+        return 0;
+    }
+
+    gettimeofday(&now,NULL);
+    timeout.tv_sec = now.tv_sec+60; //timeout is 1min
+    timeout.tv_nsec = now.tv_usec*1000;
+
+    RLOGD("Block Request, wait token is %x,",waitToken);
+    BLOCK_LOCK();
+    if(waitToken == wakeup_token)
+        RLOGD("response early than return, wait token is %x, wakeup token is %x",waitToken, wakeup_token);
+    while(!(waitToken == wakeup_token)) {
+        RLOGD("Wait Response, wait token is %x, wakeup token is %x",waitToken, wakeup_token);
+        int ret = BLOCK_WAIT(&timeout);
+        if(ret == ETIMEDOUT){
+            RLOGD("Wait Response timeout, wait token is %x, wakeup token is %x",waitToken, wakeup_token);
+            goto out;
+        }
+    }
+    RLOGD("Response wakeup,token is %x!",wakeup_token);
+    wakeup_token = -1;
+out:
+    BLOCK_UNLOCK();
+    return 0;
+}
+
+void *
+eventLoop(void *param) {
+    pthread_mutex_lock(&s_startupMutex);
+    s_started = 1;
+    pthread_cond_broadcast(&s_startupCond);
+    pthread_mutex_unlock(&s_startupMutex);
+    #ifdef ECALL_SUPPORT
+    init_ecall_timer_all();
+    #endif /**/ECALL_SUPPORT
+    RIL_StartRevSocket();
+    RLOGD("error in event_loop_base errno:%d", errno);
+    // kill self to restart on error
+    kill(0, SIGKILL);
+
+    return NULL;
+}
+
+const int RspDispFunction(int request,char* arg, RIL_SOCKET_ID socket_id)
+{
+    int waittoken;
+    RequestInfo *pRI = creatRILInfoAndInit(request, RSPD, socket_id);
+    if(pRI == NULL)
+        return 0;
+    waittoken = pRI->token;
+    switch (request) {
+    case RIL_REQUEST_GET_CURRENT_CALLS:
+    {
+        RLOGD("request Current list start!");
+        Parcel p;
+        pRI->pCI->dispatchFunction(p, pRI);
+        waitResponse(waittoken);
+        RLOGD("request Current list end!");
+    }
+        break;
+
+    case RIL_REQUEST_ANSWER:
+    {
+        RLOGD("request Answer a MT call start!");
+        Parcel p;
+        pRI->pCI->dispatchFunction(p, pRI);
+        waitResponse(waittoken);
+        RLOGD("request Answer a MT call end!");
+    }
+        break;
+
+    case RIL_REQUEST_GET_SIM_STATUS:
+    {
+        int ret=getIccCardStatus(1, NULL, socket_id, pRI);
+        if(ret == 0)
+            waitResponse(waittoken);
+    }
+        break;
+
+    case RIL_REQUEST_DATA_REGISTRATION_STATE:
+    {
+        int ret=getDataRegistrationState(1, NULL, socket_id,pRI);
+        if(ret == 0)
+            waitResponse(waittoken);
+    }
+        break;
+
+    case RIL_REQUEST_VOICE_REGISTRATION_STATE:
+    {
+        int ret=getVoiceRegistrationState(1, NULL, socket_id,pRI);
+        if(ret == 0)
+            waitResponse(waittoken);
+    }
+        break;
+    case RIL_REQUEST_SMS_ACKNOWLEDGE:
+    {
+        char* tmp[3] = {"RIL_REQUEST_SMS_ACKNOWLEDGE", "1", "0"};
+        acknowledgeIncomingGsmSmsWithPdu(3,tmp,socket_id,pRI);
+        waitResponse(waittoken);
+        RLOGD("acknowledge last Incoming Gsm Sms : RIL_REQUEST_SMS_ACKNOWLEDGE end!");
+    }
+        break;
+    case RIL_REQUEST_OEM_HOOK_RAW:
+    {
+        if(arg != NULL)
+        {
+            RLOGD("request OEM HOOK RAW start!");
+            pRI->token = pRI->token|BLOCK_MARK;
+            int waittokenOEM = pRI->token;
+            Parcel p;
+
+            size_t pos = p.dataPosition();
+            int len = strlen(arg);
+            p.writeInt32(len);
+            p.write((const void*)arg,len);
+
+            p.setDataPosition(pos);
+            RLOGD("emSendATCommand: %s %d\n",arg,strlen(arg));
+            pRI->pCI->dispatchFunction(p, pRI);
+            waitResponse(waittokenOEM);
+        } else {
+            if(pRI){
+                free(pRI);
+            }
+            RLOGE("at command shouldn't null");
+        }
+    break;
+    }
+    case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM:
+    {
+          char* tmp[2] = {"RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM", "no"};
+          handleCallSetupRequestFromSim(2, tmp, socket_id,pRI);
+          waitResponse(waittoken);
+          RLOGD("timeout 1 minutes, response no by RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM");
+          break;
+    }
+    case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE:
+    {
+        char* tmp[2] ={"RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE", arg};
+        RLOGD("tmp[0]=%s, tmp[1]=%s, arg=%s", tmp[0], tmp[1], arg);
+        sendTerminalResponse(2, tmp, socket_id, pRI);
+        waitResponse(waittoken);
+        break;
+    }
+    case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE:
+    {
+      acknowledgeLastIncomingCdmaSms(1, NULL,socket_id,pRI);
+      waitResponse(waittoken);
+      break;
+    }
+    case RIL_REQUEST_RADIO_POWER:
+    {
+        RLOGD("response loop, RIL_REQUEST_RADIO_POWER: %s", (arg == NULL ? "nul": arg));
+        if(arg != NULL) {
+            char* tmp[2] = {"RIL_REQUEST_RADIO_POWER", arg};
+            setRadioPower(2,tmp,socket_id,pRI);
+            waitResponse(waittoken);
+        } else {
+            if(pRI){
+                free(pRI);
+            }
+            RLOGE("response loop, RIL_REQUEST_RADIO_POWER fail");
+        }
+        break;
+    }
+    case RIL_REQUEST_ALLOW_DATA:
+    {
+        int default_id = get_default_sim_data();
+        RLOGD("RspDispFunction: socket_id=%d switch_id=%d", socket_id, default_id);
+        char* argv[2] = {"RIL_REQUEST_ALLOW_DATA","0"};
+        if(socket_id == default_id) {
+            utils::mtk_property_set(PROP_DEFAULT_DATA_SIM, std::to_string(socket_id + 1).c_str());
+            argv[1] = "1";
+        }
+        while(!isRadioAvailable(socket_id)) {
+            sleep(1);
+            RLOGD("[SIM%d]RspDispFunction(RIL_REQUEST_ALLOW_DATA): wait radio available", socket_id);
+        }
+        setDataAllowed(2, argv, socket_id, pRI);
+        waitResponse(waittoken);
+        break;
+    }
+    case RIL_REQUEST_CDMA_FLASH:
+    {
+        sendCDMAFeatureCode(1, NULL, socket_id, pRI);
+        waitResponse(waittoken);
+        break;
+    }
+    default:
+        break;
+    }
+    return 0;
+}
+
+void * responseLoop(void *param) {
+    pthread_mutex_lock(&s_startupMutex);
+    s_responseDispatch= 1;
+    pthread_cond_broadcast(&s_startupCond);
+    pthread_mutex_unlock(&s_startupMutex);
+    responseDispatch();
+    RLOGD("error in response_loop_base errno:%d", errno);
+    // kill self to restart on error
+    kill(0, SIGKILL);
+
+    return NULL;
+}
+
+void ATCIRequest(int request,char* reqString, void* t,int argc,char**argv)
+{
+    RequestInfo *pRI = (RequestInfo *)t;
+    int waittoken;
+    if (request < RIL_REQUEST_VENDOR_BASE) {
+        pRI->pCI = &(s_commands[request]);
+    } else {
+        pRI->pCI = find_mtk_command(request);
+    }
+    if(pRI->pCI == NULL)
+        RLOGE("pCI command not found!");
+
+    if(utils::is_suppport_dsss()){
+        pRI->socket_id = (RIL_SOCKET_ID)Phone_utils::get_enable_sim_for_dsss();
+    }
+
+    if(utils::is_support_dsds() && (request != RIL_REQUEST_RADIO_POWER)){
+        pRI->socket_id = (RIL_SOCKET_ID)get_atci_sim();
+    }
+
+    pRI->p_next = NULL;
+
+    COMMAND *command = find_command(reqString);
+
+    if(command == NULL) {
+        RLOGE("ATCI request command find error!");
+    } else {
+        RLOGE("ATCI request name is %s!",command->name);
+    }
+
+    pRI->token = GenerateToken(ATCI, request);
+    waittoken = pRI->token;
+    if(request == RIL_REQUEST_RADIO_POWER) {
+        speciaRequest_wait();
+    }
+    (*(command->func)) (argc, argv, pRI->socket_id, pRI);
+    //need wait Ril_onRequestComplete return.
+     waitResponse(waittoken);
+    return;
+}
+void startWakupLoop(void)
+{
+    pthread_t WakeupReasonThread;
+
+    RLOGD("startWakupLoop()");
+    pthread_mutex_lock(&s_startupMutex);
+
+    pthread_attr_t attr;
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+    int result = pthread_create(&WakeupReasonThread, &attr, wakeup_reason_loop, NULL);
+    if (result != 0) {
+        RLOGW("Failed to create wakeup reason thread: %s", strerror(result));
+        goto done;
+    }
+
+done:
+    pthread_mutex_unlock(&s_startupMutex);
+}
+int specialRequestController(char **data, int lenth,int32_t * token)
+{
+    if(data[0]==NULL)
+    {
+        RLOGD("the special request data is NULL");
+        return -1;
+    }
+    COMMAND *command = find_command(data[0]);
+    if(!command)
+    {
+      RLOGE("%s: No such command for DemoApp", data[0]);
+    }
+    int32_t request;
+    request = command->request;
+    RIL_SOCKET_ID id = RIL_SOCKET_1;
+    if(utils::is_support_dsds()) {
+      id = (RIL_SOCKET_ID)get_default_sim_all_except_data();
+    } else if(utils::is_suppport_dsss()) {
+      id = (RIL_SOCKET_ID)Phone_utils::get_enable_sim_for_dsss();
+    }
+    RequestInfo *pRI = creatRILInfoAndInit(request, UDP, (RIL_SOCKET_ID)(id));
+    if(pRI)
+    {
+        *token = pRI->token;
+        free(pRI);
+    }
+    switch(request)
+    {
+        case RIL_REQUEST_SET_MUTE:
+        {
+            if (lenth<2)
+            {
+                RLOGD("set mute parameter is invalid!!!");
+                break;
+            }
+            bool mute = (atoi(data[1]) > 0) ? true: false;
+            RLOGD("set mute %s", ((atoi(data[1]) > 0) ? "on": "off"));
+            return setCallMute(mute);
+        }
+        case RIL_REQUEST_GET_MUTE:
+        {
+            return getCallMute();
+        }
+    }
+    return -1;
+}
+int getRequestData(char **data, int lenth) 
+{
+    int status;
+    int32_t mToken;
+    COMMAND *command = find_command(data[0]);
+    //for(int i = 0;i<10;i++)
+    //{
+    //RLOGD("%s: getRequestData", data[i]);
+    //}
+    if(!command)
+    {
+      RLOGE("%s: No such command for DemoApp", data[0]);
+      return 0;
+    }
+    int32_t request;
+    request = command->request;
+
+    RIL_SOCKET_ID id = RIL_SOCKET_1;
+    if(utils::is_support_dsds()) {
+      id = (RIL_SOCKET_ID)get_default_sim_all_except_data();
+    } else if(utils::is_suppport_dsss()) {
+      id = (RIL_SOCKET_ID)Phone_utils::get_enable_sim_for_dsss();
+    }
+
+    if(request == -1)
+    {
+      (*(command->func)) (lenth, data, id, NULL);
+    }
+    if (request < 1 || (request >= (int32_t)NUM_ELEMS(s_commands) && request < RIL_REQUEST_VENDOR_BASE)) {
+      RLOGW("unsupported request code %d token %d", request);
+            // FIXME this should perhaps return a response
+
+    }
+
+    RLOGD("LYNQ_REQUEST: %s ParamterNum:%d", requestToString(request), lenth);
+
+
+    RequestInfo *pRI  = creatRILInfoAndInit(request, UDP, (RIL_SOCKET_ID)(id));
+    mToken =pRI->token;
+    //printf("pRI->token %x\n",mToken);
+    LYNQ_DispatchRequest(request,mToken);
+    status=(*(command->func)) (lenth, data, pRI->socket_id, pRI);
+    if(status < 0){
+        return status;
+    }
+    return mToken;
+
+}
+
+void startPMLoop(void)
+{
+    pthread_t atciSocketThread;
+
+    RLOGD("startPMLoop()");
+    pthread_mutex_lock(&s_startupMutex);
+
+    pthread_attr_t attr;
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+    int result = pthread_create(&atciSocketThread, &attr, StartPMSocket, NULL);
+    if (result != 0) {
+        RLOGW("Failed to create PM thread: %s", strerror(result));
+        goto done;
+    }
+
+done:
+    pthread_mutex_unlock(&s_startupMutex);
+}
+
+void startGdbusLoop(void)
+{
+    pthread_t atciSocketThread;
+
+    RLOGD("startGdbusLoop()");
+    pthread_mutex_lock(&s_startupMutex);
+
+    pthread_attr_t attr;
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+    int result = pthread_create(&atciSocketThread, &attr, init_data_gdbus_cb, NULL);
+    if (result != 0) {
+        RLOGW("Failed to create gdbus thread: %s", strerror(result));
+        goto done;
+    }
+
+done:
+    pthread_mutex_unlock(&s_startupMutex);
+}
+
+void startATCILoop(void)
+{
+    pthread_t atciSocketThread;
+
+    RLOGD("startATCILoop()");
+    pthread_mutex_lock(&s_startupMutex);
+
+    pthread_attr_t attr;
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+    int result = pthread_create(&atciSocketThread, &attr, StartATCISocket, NULL);
+    if (result != 0) {
+        RLOGW("Failed to create ATCI thread: %s", strerror(result));
+        goto done;
+    }
+
+done:
+    pthread_mutex_unlock(&s_startupMutex);
+}
+
+void RIL_startEventLoop(void)
+{
+    RLOGD("RIL_startEventLoop()");
+    /* spin up eventLoop thread and wait for it to get started */
+    s_started = 0;
+    pthread_mutex_lock(&s_startupMutex);
+
+    pthread_attr_t attr;
+    pthread_attr_init(&attr);
+//    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+//
+//    int result = pthread_create(&s_tid_dispatch, &attr, eventLoop, NULL);
+//    if (result != 0) {
+//        RLOGW("Failed to create dispatch thread: %s", strerror(result));
+//        goto done;
+//    }
+
+//    while (s_started == 0) {
+//        pthread_cond_wait(&s_startupCond, &s_startupMutex);
+//    }
+
+    intRspList();
+    int result = pthread_create(&s_tid_dispatch, &attr, responseLoop, NULL);
+    if (result != 0) {
+        RLOGW("Failed to create response dispatch thread: %s", strerror(result));
+        goto done;
+    }
+
+    while (s_responseDispatch == 0) {
+        pthread_cond_wait(&s_startupCond, &s_startupMutex);
+    }
+done:
+    pthread_mutex_unlock(&s_startupMutex);
+}
+
+void printInputArgs(int argc, char** argv)
+{
+    int i=0;
+
+    for(i=0; i<argc; i++)
+    {
+        RLOGD("%s", argv[i]);
+    }
+}
+
+void initRequestInfo(RequestInfo *pRI, int  request, int mode, RIL_SOCKET_ID soc_id)
+{
+    pRI->token = GenerateToken(mode, request);
+    if (request < RIL_REQUEST_VENDOR_BASE) {
+        pRI->pCI = &(s_commands[request]);
+    } else {
+        pRI->pCI = find_mtk_command(request);
+    }
+    pRI->socket_id = soc_id;
+
+    pRI->p_next = NULL;
+}
+
+void getVoiceAndDataRegistrationState(RIL_SOCKET_ID soc_id)
+{
+    ARspRequest(RIL_REQUEST_DATA_REGISTRATION_STATE,soc_id);
+    ARspRequest(RIL_REQUEST_VOICE_REGISTRATION_STATE,soc_id);
+}
+
+void requestAnswer(RIL_SOCKET_ID soc_id)
+{
+    ARspRequest(RIL_REQUEST_ANSWER,soc_id);
+    return;
+}
+void requestSMSACKNOWLEDGE(RIL_SOCKET_ID soc_id)
+{
+    ARspRequest(RIL_REQUEST_SMS_ACKNOWLEDGE,soc_id);
+    return;
+}
+
+#if EM_MODE_SUPPORT
+void registerForNetworkInfo(netwokInfoNotify cb)
+{
+    networkCb = cb;
+    return ;
+}
+void unregisterNetwork()
+{
+    networkCb = NULL;
+    //AT+EINFO= flag & 0xFFFFFFF7
+}
+void registerForATcmdResponse(atCmdResponse cb)
+{
+    atResponseCb = cb;
+    return ;
+}
+
+void unregisterATcmd()
+{
+    atResponseCb = NULL;
+}
+
+#endif
+void registerForAppResponse(appResponse cb){
+    appResponseCb = cb;
+    return ;
+}
+void unregisterAppResponse(){
+    appResponseCb = NULL;
+}
+
+void registerOnUnsolicitedResponse(user_cb *cb){
+    s_Env = cb;
+    return ;
+}
+void unRegisterOnUnsolicitedResponse(){
+    s_Env = NULL;
+}
+int emResultNotify(const char *str)
+{
+    RLOGD("emResultNotify %s",str);
+    int len_s = sendto(server_socket_fd,str,strlen(str),0,(struct sockaddr *)&client_addr,sizeof(client_addr));
+
+    sendto(server_socket_fd,"stopemdone",strlen("stopemdone"),0,(struct sockaddr *)&client_addr,sizeof(client_addr));
+    return len_s;
+}
+
+void processUnsolicited (Parcel &p, int type)
+{
+    int32_t response;
+    p.readInt32(&response);
+    switch(response){
+        case RIL_UNSOL_MAL_AT_INFO:
+        {
+#if EM_MODE_SUPPORT
+            char *stringresponse = strdupReadString(p);
+            if(strstr(stringresponse,"+ENWINFO") !=  NULL){
+                RLOGD("processUnsolicited ENWINFO \n");
+                char *start = strstr(stringresponse,":");
+                char *end = strstr(stringresponse,",");
+                if(start == NULL ||end == NULL ){
+                    break;
+                }
+                if(networkCb){
+                    //parse type & data, notify to registrants
+                    char ctype[5] = {0};
+                    int type = 0;
+                    memcpy(ctype,start+1, end - start -1);
+                     type = atoi(ctype);
+                    char *data = end+1;
+                    RLOGD("ctype %s type %d data %s\n",ctype,type,data);
+                    //parse response
+                    networkCb(type,data);
+                }
+            }
+            if(stringresponse){
+                free(stringresponse);
+            }
+#endif
+            break;
+        }
+        default:
+            break;
+    }
+}
+void processSolicited(Parcel &p, int type) {
+    int32_t serial, error;
+    p.readInt32(&serial); //telematic it is the same as ril request num
+    p.readInt32(&error);
+    RLOGD("processSolicited serial %d\n", serial);
+    switch (serial) {
+    case RIL_REQUEST_OEM_HOOK_RAW: {
+        if (error != RIL_E_SUCCESS) {
+            RLOGW("RIL_E_fail");
+            if (atResponseCb) {
+               atResponseCb(NULL, 0);
+            }
+            if(m_RfDesense){
+                m_RfDesense->handle_request("", 0, 0, (RIL_Errno)error);
+            }
+            return;
+        }
+        int len;
+        status_t status = 0;
+        status = p.readInt32(&len);
+        if (status != 0) {
+            RLOGW("read int32 fail");
+            return;
+        }
+        char *stringresponse = (char*) calloc(len, sizeof(char));
+        status = p.read((void*) stringresponse, len);
+        if (status != 0) {
+            if (stringresponse) {
+                free(stringresponse);
+            }
+            RLOGW("read int32 fail");
+            return;
+        }
+        parseAtCmd(stringresponse);
+        RLOGD("processSolicited AT string %s %d\n", stringresponse, len);
+#if EM_MODE_SUPPORT
+        if (atResponseCb) {
+            if (stringresponse) {
+
+                atResponseCb(stringresponse, len);
+            } else {
+                atResponseCb(stringresponse, 0);
+            }
+        }
+        if(m_RfDesense){
+            if(stringresponse && (!isFinalResponseErrorEx(stringresponse))) {
+                m_RfDesense->handle_request(stringresponse,len,0, (RIL_Errno)RIL_E_SUCCESS);
+            } else {
+                RLOGD("isFinalResponseErrorEx error or response is null");
+                m_RfDesense->handle_request(stringresponse, 0, 0, (RIL_Errno)RIL_E_GENERIC_FAILURE);
+            }
+        }
+#endif
+        if (stringresponse) {
+            free(stringresponse);
+        }
+        break;
+    }
+    case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: {
+#if EM_MODE_SUPPORT
+        if (atResponseCb) {
+            if (error != RIL_E_SUCCESS) {
+                atResponseCb(NULL, 0);
+            } else {
+                atResponseCb("OK", 2);
+            }
+        }
+#endif
+        break;
+    }
+    case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: {
+#if EM_MODE_SUPPORT
+        int nums = 0;
+        int prefertype = 0;
+        p.readInt32(&nums);
+        if (nums != 1) {
+            RLOGD("getpreferrednetworktype nums > 1");
+        }
+        p.readInt32(&prefertype);
+        char prefertype_str[3] = { 0 };
+        sprintf(prefertype_str, "%d", prefertype);
+        if (atResponseCb) {
+            if (error != RIL_E_SUCCESS) {
+                atResponseCb(NULL, 0);
+            } else {
+                atResponseCb(prefertype_str, strlen(prefertype_str));
+            }
+        }
+#endif
+        break;
+    }
+    case RIL_REQUEST_GET_IMSI: {
+        if (error != RIL_E_SUCCESS) {
+            RLOGD("RIL_REQUEST_GET_IMSI error %d\n", error);
+        }
+        break;
+    }
+    }
+}
+
+#ifdef ECALL_SUPPORT
+static int responseEcallStatus(Parcel &p, void *response, size_t responselen) {
+  if (response == NULL || responselen != sizeof(RIL_Ecall_Unsol_Indications)) {
+    if (response == NULL) {
+      RLOGE("invalid response: NULL");
+    }
+    else {
+      RLOGE("responseEcallStatus: invalid response length %d expecting len: %d",
+            sizeof(RIL_Ecall_Unsol_Indications), responselen);
+    }
+    return RIL_ERRNO_INVALID_RESPONSE;
+  }
+
+  RIL_Ecall_Unsol_Indications *p_cur = (RIL_Ecall_Unsol_Indications *)response;
+  p.writeInt32(p_cur->ind);
+  p.writeInt32(p_cur->call_id);
+
+  startResponse;
+  appendPrintBuf("ECall Status: %d, call_id: %d",
+                 p_cur->ind, p_cur->call_id);
+  closeResponse;
+
+  return 0;
+}
+
+/**
+ * Callee expects const RIL_ECallReqMsg *
+ * Payload is:
+ *   RIL_ECall_Category ecall_cat
+ *   RIL_ECall_Variant ecall_variant
+ *   String address
+ *   String msd_data
+ */
+static void dispatchFastEcall (Parcel &p, RequestInfo *pRI) {
+    RIL_ECallReqMsg eCallReqMsg;
+
+    int32_t t;
+    int size;
+    status_t status;
+    int digitCount;
+    int digitLimit;
+    uint8_t uct;
+
+    memset(&eCallReqMsg, 0, sizeof(eCallReqMsg));
+
+    status = p.readInt32(&t);
+    eCallReqMsg.ecall_cat= (RIL_ECall_Category)t;
+
+    status = p.readInt32(&t);
+    eCallReqMsg.ecall_variant = (RIL_ECall_Variant)t;
+
+    eCallReqMsg.address = strdupReadString(p);
+
+    status = p.readInt32(&t);
+    eCallReqMsg.length = (uint8_t) t;
+
+    digitLimit= MIN((eCallReqMsg.length), MSD_MAX_LENGTH);
+    eCallReqMsg.msd_data = (unsigned char *)alloca(digitLimit);
+
+    for(digitCount = 0 ; digitCount < digitLimit; digitCount ++) {
+        status = p.read(&uct, sizeof(uint8_t));
+        eCallReqMsg.msd_data[digitCount] = (uint8_t) uct;
+    }
+
+    startRequest;
+    appendPrintBuf("%secall_cat=%d,ecall_variant=%d, address=%s", printBuf,
+        eCallReqMsg.ecall_cat, eCallReqMsg.ecall_variant, (char*)eCallReqMsg.address);
+    closeRequest;
+    printRequest(pRI->token, pRI->pCI->requestNumber);
+
+    if (status != NO_ERROR) {
+        goto invalid;
+    }
+
+    size = sizeof(eCallReqMsg);
+    CALL_ONREQUEST(pRI->pCI->requestNumber, &eCallReqMsg, size, pRI, pRI->socket_id);
+
+#ifdef MEMSET_FREED
+    memsetString(eCallReqMsg.address);
+    memset(eCallReqMsg.msd_data, 0, eCallReqMsg.length);
+#endif
+
+    free(eCallReqMsg.address);
+
+#ifdef MEMSET_FREED
+    memset(&eCallReqMsg, 0, sizeof(eCallReqMsg));
+#endif
+
+    return;
+invalid:
+    invalidCommandBlock(pRI);
+    return;
+}
+
+/**
+ * Callee expects const RIL_ECallSetMSD *
+ * Payload is:
+ *   int call_id
+ *   String msd_data
+ */
+static void dispatchSetMsd (Parcel &p, RequestInfo *pRI) {
+    RIL_ECallSetMSD eCallSetMsd;
+
+    int32_t t;
+    int size;
+    status_t status;
+    int digitCount;
+    int digitLimit;
+    uint8_t uct;
+
+    memset(&eCallSetMsd, 0, sizeof(eCallSetMsd));
+
+    status = p.readInt32(&t);
+    eCallSetMsd.call_id = (int)t;
+
+    status = p.readInt32(&t);
+    eCallSetMsd.length = (uint8_t) t;
+
+    digitLimit= MIN((eCallSetMsd.length), MSD_MAX_LENGTH);
+    eCallSetMsd.msd_data = (unsigned char *)alloca(digitLimit);
+
+    for(digitCount = 0 ; digitCount < digitLimit; digitCount ++) {
+        status = p.read(&uct, sizeof(uint8_t));
+        eCallSetMsd.msd_data[digitCount] = (uint8_t) uct;
+    }
+
+    startRequest;
+    appendPrintBuf("%scall_id=%d,msd_data=%s", printBuf, eCallSetMsd.call_id, (char*)eCallSetMsd.msd_data);
+    closeRequest;
+    printRequest(pRI->token, pRI->pCI->requestNumber);
+
+    if (status != NO_ERROR) {
+        goto invalid;
+    }
+
+    size = sizeof(eCallSetMsd);
+    CALL_ONREQUEST(pRI->pCI->requestNumber, &eCallSetMsd, size, pRI, pRI->socket_id);
+
+#ifdef MEMSET_FREED
+    memset(eCallSetMsd.msd_data, 0, eCallSetMsd.length);
+#endif
+
+#ifdef MEMSET_FREED
+    memset(&eCallSetMsd, 0, sizeof(eCallSetMsd));
+#endif
+
+    return;
+invalid:
+    invalidCommandBlock(pRI);
+    return;
+}
+
+/**
+ * Callee expects const RIL_ECallSetNum *
+ * Payload is:
+ *   int arg_num;
+ *   int type
+ *   char* address
+ */
+static void dispatchEcallRecord (Parcel &p, RequestInfo *pRI) {
+    RIL_ECallSetNum args;
+    int32_t t;
+    status_t status;
+
+    RLOGD("dispatchSmsWrite");
+    memset (&args, 0, sizeof(args));
+
+    status = p.readInt32(&t);
+    args.arg_num = (int)t;
+
+    status = p.readInt32(&t);
+    args.type = (int)t;
+
+    args.address = strdupReadString(p);
+
+    if (status != NO_ERROR || args.address == NULL) {
+        goto invalid;
+    }
+
+    startRequest;
+    appendPrintBuf("%s%d,%s,%d", printBuf, args.type, args.address,args.arg_num);
+    closeRequest;
+    printRequest(pRI->token, pRI->pCI->requestNumber);
+
+    CALL_ONREQUEST(pRI->pCI->requestNumber, &args, sizeof(args), pRI, pRI->socket_id);
+
+#ifdef MEMSET_FREED
+    memsetString (args.address);
+#endif
+
+    free (args.address);
+#ifdef MEMSET_FREED
+    memset(&args, 0, sizeof(args));
+#endif
+    return;
+invalid:
+    invalidCommandBlock(pRI);
+    return;
+}
+#endif /*ECALL_SUPPORT*/
+
+#ifdef KEEP_ALIVE
+static void dispatchStartKeepalivePro(Parcel &p, RequestInfo *pRI){
+    RIL_RequestKeepalive_Pro kp;
+    int32_t t;
+    status_t status;
+    std::vector<uint8_t> sadr;
+    std::vector<uint8_t> dadr;
+
+    memset (&kp, 0, sizeof(RIL_RequestKeepalive_Pro));
+
+    status = p.readInt32(&t);
+    kp.type = (RIL_PacketType)t;
+    if (status != NO_ERROR) {
+        goto invalid;
+    }
+
+
+    status = p.readByteVector(&sadr);
+    if (status != NO_ERROR) {
+        goto invalid;
+    } else {
+        for(int i = 0; i < sadr.size(); i++) {
+            kp.sourceAddress[i] = sadr[i];
+        }
+    }
+
+    status = p.readInt32(&t);
+    kp.sourcePort= (int)t;
+    if (status != NO_ERROR) {
+        goto invalid;
+    }
+
+    status = p.readByteVector(&dadr);
+    if (status != NO_ERROR) {
+        goto invalid;
+    } else {
+        for(int i = 0; i < dadr.size(); i++) {
+            kp.destinationAddress[i] = dadr[i];
+        }
+    }
+
+    status = p.readInt32(&t);
+    kp.destinationPort= (int)t;
+    if (status != NO_ERROR) {
+        goto invalid;
+    }
+
+    status = p.readInt32(&t);
+    kp.netif_id = (int)t;
+    if (status != NO_ERROR) {
+        goto invalid;
+    }
+
+    status = p.readInt32(&t);
+    kp.keepIdleTime = (int)t;
+    if (status != NO_ERROR) {
+        goto invalid;
+    }
+
+    status = p.readInt32(&t);
+    kp.keepIntervalTime = (int)t;
+    if (status != NO_ERROR) {
+        goto invalid;
+    }
+
+    status = p.readInt32(&t);
+    kp.retryCount = (int)t;
+    if (status != NO_ERROR) {
+        goto invalid;
+    }
+    startRequest;
+    appendPrintBuf("%s [type:%d, sourceAddress:",printBuf, kp.type);
+
+    for(auto v: sadr) {
+        appendPrintBuf("%s %d",printBuf,v);
+    }
+    appendPrintBuf("%s, sourcePort:%d, destinationAddress:",printBuf, kp.sourcePort);
+
+    for(auto v: dadr) {
+        appendPrintBuf("%s %d",printBuf,v);
+    }
+    appendPrintBuf("%s, destinationPort:%d, netif_id:%d, keepIdleTime:%d,, keepIntervalTime:%d, retryCount:%d",
+            printBuf, kp.destinationPort, kp.netif_id, kp.keepIdleTime, kp.keepIntervalTime, kp.retryCount);
+
+    closeRequest;
+    printRequest(pRI->token, pRI->pCI->requestNumber);
+
+    CALL_ONREQUEST(pRI->pCI->requestNumber,&kp,sizeof(RIL_RequestKeepalive_Pro),pRI, pRI->socket_id);
+    return;
+invalid:
+    invalidCommandBlock(pRI);
+    return;
+}
+#endif /* KEEP_ALIVE*/
+} /* namespace android */
+
+#if 0
+void rilEventAddWakeup_helper(struct ril_event *ev) {
+    android::rilEventAddWakeup(ev);
+}
+
+void listenCallback_helper(int fd, short flags, void *param) {
+    android::listenCallback(fd, flags, param);
+}
+
+int blockingWrite_helper(int fd, void *buffer, size_t len) {
+    return android::blockingWrite(fd, buffer, len);
+}
+#endif
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ril_commands.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ril_commands.h
new file mode 100644
index 0000000..85878ee
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ril_commands.h
@@ -0,0 +1,152 @@
+/*
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+    {0, NULL, NULL},                   //none
+    {RIL_REQUEST_GET_SIM_STATUS, dispatchVoid, responseSimStatus},
+    {RIL_REQUEST_ENTER_SIM_PIN, dispatchStrings, responseInts},
+    {RIL_REQUEST_ENTER_SIM_PUK, dispatchStrings, responseInts},
+    {RIL_REQUEST_ENTER_SIM_PIN2, dispatchStrings, responseInts},
+    {RIL_REQUEST_ENTER_SIM_PUK2, dispatchStrings, responseInts},
+    {RIL_REQUEST_CHANGE_SIM_PIN, dispatchStrings, responseInts},
+    {RIL_REQUEST_CHANGE_SIM_PIN2, dispatchStrings, responseInts},
+    {RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION, dispatchStrings, responseInts},
+    {RIL_REQUEST_GET_CURRENT_CALLS, dispatchVoid, responseCallList},
+    {RIL_REQUEST_DIAL, dispatchDial, responseVoid},
+    {RIL_REQUEST_GET_IMSI, dispatchStrings, responseString},
+    {RIL_REQUEST_HANGUP, dispatchInts, responseVoid},
+    {RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND, dispatchVoid, responseVoid},
+    {RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND, dispatchVoid, responseVoid},
+    {RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE, dispatchVoid, responseVoid},
+    {RIL_REQUEST_CONFERENCE, dispatchVoid, responseVoid},
+    {RIL_REQUEST_UDUB, dispatchVoid, responseVoid},
+    {RIL_REQUEST_LAST_CALL_FAIL_CAUSE, dispatchVoid, responseFailCause},
+    {RIL_REQUEST_SIGNAL_STRENGTH, dispatchVoid, responseRilSignalStrength},
+    {RIL_REQUEST_VOICE_REGISTRATION_STATE, dispatchVoid, responseStrings},
+    {RIL_REQUEST_DATA_REGISTRATION_STATE, dispatchVoid, responseStrings},
+    {RIL_REQUEST_OPERATOR, dispatchVoid, responseStrings},
+    {RIL_REQUEST_RADIO_POWER, dispatchInts, responseVoid},
+    {RIL_REQUEST_DTMF, dispatchString, responseVoid},
+    {RIL_REQUEST_SEND_SMS, dispatchStrings, responseSMS},
+    {RIL_REQUEST_SEND_SMS_EXPECT_MORE, dispatchStrings, responseSMS},
+    {RIL_REQUEST_SETUP_DATA_CALL, dispatchDataCall, responseSetupDataCall},
+    {RIL_REQUEST_SIM_IO, dispatchSIM_IO, responseSIM_IO},
+    {RIL_REQUEST_SEND_USSD, dispatchString, responseVoid},
+    {RIL_REQUEST_CANCEL_USSD, dispatchVoid, responseVoid},
+    {RIL_REQUEST_GET_CLIR, dispatchVoid, responseInts},
+    {RIL_REQUEST_SET_CLIR, dispatchInts, responseVoid},
+    {RIL_REQUEST_QUERY_CALL_FORWARD_STATUS, dispatchCallForward, responseCallForwards},
+    {RIL_REQUEST_SET_CALL_FORWARD, dispatchCallForward, responseVoid},
+    {RIL_REQUEST_QUERY_CALL_WAITING, dispatchInts, responseInts},
+    {RIL_REQUEST_SET_CALL_WAITING, dispatchInts, responseVoid},
+    {RIL_REQUEST_SMS_ACKNOWLEDGE, dispatchInts, responseVoid},
+    {RIL_REQUEST_GET_IMEI, dispatchVoid, responseString},
+    {RIL_REQUEST_GET_IMEISV, dispatchVoid, responseString},
+    {RIL_REQUEST_ANSWER,dispatchVoid, responseVoid},
+    {RIL_REQUEST_DEACTIVATE_DATA_CALL, dispatchStrings, responseVoid},
+    {RIL_REQUEST_QUERY_FACILITY_LOCK, dispatchStrings, responseInts},
+    {RIL_REQUEST_SET_FACILITY_LOCK, dispatchStrings, responseInts},
+    {RIL_REQUEST_CHANGE_BARRING_PASSWORD, dispatchStrings, responseVoid},
+    {RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE, dispatchVoid, responseInts},
+    {RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC, dispatchVoid, responseVoid},
+    {RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL, dispatchString, responseVoid},
+    {RIL_REQUEST_QUERY_AVAILABLE_NETWORKS , dispatchVoid, responseStrings},
+    {RIL_REQUEST_DTMF_START, dispatchString, responseVoid},
+    {RIL_REQUEST_DTMF_STOP, dispatchVoid, responseVoid},
+    {RIL_REQUEST_BASEBAND_VERSION, dispatchVoid, responseString},
+    {RIL_REQUEST_SEPARATE_CONNECTION, dispatchInts, responseVoid},
+    {RIL_REQUEST_SET_MUTE, dispatchInts, responseVoid},
+    {RIL_REQUEST_GET_MUTE, dispatchVoid, responseInts},
+    {RIL_REQUEST_QUERY_CLIP, dispatchVoid, responseInts},
+    {RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE, dispatchVoid, responseInts},
+    {RIL_REQUEST_DATA_CALL_LIST, dispatchVoid, responseDataCallList},
+    {RIL_REQUEST_RESET_RADIO, dispatchVoid, responseVoid},
+    {RIL_REQUEST_OEM_HOOK_RAW, dispatchRaw, responseRaw},
+    {RIL_REQUEST_OEM_HOOK_STRINGS, dispatchStrings, responseStrings},
+    {RIL_REQUEST_SCREEN_STATE, dispatchInts, responseVoid},
+    {RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION, dispatchInts, responseVoid},
+    {RIL_REQUEST_WRITE_SMS_TO_SIM, dispatchSmsWrite, responseInts},
+    {RIL_REQUEST_DELETE_SMS_ON_SIM, dispatchInts, responseVoid},
+    {RIL_REQUEST_SET_BAND_MODE, dispatchInts, responseVoid},
+    {RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE, dispatchVoid, responseInts},
+    {RIL_REQUEST_STK_GET_PROFILE, dispatchVoid, responseString},
+    {RIL_REQUEST_STK_SET_PROFILE, dispatchString, responseVoid},
+    {RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND, dispatchString, responseString},
+    {RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE, dispatchString, responseVoid},
+    {RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM, dispatchInts, responseVoid},
+    {RIL_REQUEST_EXPLICIT_CALL_TRANSFER, dispatchVoid, responseVoid},
+    {RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, dispatchInts, responseVoid},
+    {RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE, dispatchVoid, responseInts},
+    {RIL_REQUEST_GET_NEIGHBORING_CELL_IDS, dispatchVoid, responseCellList},
+    {RIL_REQUEST_SET_LOCATION_UPDATES, dispatchInts, responseVoid},
+    {RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE, dispatchInts, responseVoid},
+    {RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE, dispatchInts, responseVoid},
+    {RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE, dispatchVoid, responseInts},
+    {RIL_REQUEST_SET_TTY_MODE, dispatchInts, responseVoid},
+    {RIL_REQUEST_QUERY_TTY_MODE, dispatchVoid, responseInts},
+    {RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE, dispatchInts, responseVoid},
+    {RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE, dispatchVoid, responseInts},
+    {RIL_REQUEST_CDMA_FLASH, dispatchString, responseVoid},
+    {RIL_REQUEST_CDMA_BURST_DTMF, dispatchStrings, responseVoid},
+    {RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY, dispatchString, responseVoid},
+    {RIL_REQUEST_CDMA_SEND_SMS, dispatchCdmaSms, responseSMS},
+    {RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE, dispatchCdmaSmsAck, responseVoid},
+    {RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG, dispatchVoid, responseGsmBrSmsCnf},
+    {RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG, dispatchGsmBrSmsCnf, responseVoid},
+    {RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION, dispatchInts, responseVoid},
+    {RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG, dispatchVoid, responseCdmaBrSmsCnf},
+    {RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG, dispatchCdmaBrSmsCnf, responseVoid},
+    {RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION, dispatchInts, responseVoid},
+    {RIL_REQUEST_CDMA_SUBSCRIPTION, dispatchVoid, responseStrings},
+    {RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM, dispatchRilCdmaSmsWriteArgs, responseInts},
+    {RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM, dispatchInts, responseVoid},
+    {RIL_REQUEST_DEVICE_IDENTITY, dispatchVoid, responseStrings},
+    {RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE, dispatchVoid, responseVoid},
+    {RIL_REQUEST_GET_SMSC_ADDRESS, dispatchVoid, responseString},
+    {RIL_REQUEST_SET_SMSC_ADDRESS, dispatchString, responseVoid},
+    {RIL_REQUEST_REPORT_SMS_MEMORY_STATUS, dispatchInts, responseVoid},
+    {RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING, dispatchVoid, responseVoid},
+    {RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE, dispatchVoid, responseInts},
+    {RIL_REQUEST_ISIM_AUTHENTICATION, dispatchString, responseString},
+    {RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU, dispatchStrings, responseVoid},
+    {RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS, dispatchString, responseSIM_IO},
+    {RIL_REQUEST_VOICE_RADIO_TECH, dispatchVoid, responseInts},
+    {RIL_REQUEST_GET_CELL_INFO_LIST, dispatchVoid, responseCellInfoList},
+    {RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE, dispatchInts, responseVoid},
+    {RIL_REQUEST_SET_INITIAL_ATTACH_APN, dispatchSetInitialAttachApn, responseVoid},
+    {RIL_REQUEST_IMS_REGISTRATION_STATE, dispatchVoid, responseInts},
+    {RIL_REQUEST_IMS_SEND_SMS, dispatchImsSms, responseSMS},
+    {RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC, dispatchSIM_APDU, responseSIM_IO},
+    {RIL_REQUEST_SIM_OPEN_CHANNEL, dispatchString, responseInts},
+    {RIL_REQUEST_SIM_CLOSE_CHANNEL, dispatchInts, responseVoid},
+    {RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL, dispatchSIM_APDU, responseSIM_IO},
+    {RIL_REQUEST_NV_READ_ITEM, dispatchNVReadItem, responseString},
+    {RIL_REQUEST_NV_WRITE_ITEM, dispatchNVWriteItem, responseVoid},
+    {RIL_REQUEST_NV_WRITE_CDMA_PRL, dispatchRaw, responseVoid},
+    {RIL_REQUEST_NV_RESET_CONFIG, dispatchInts, responseVoid},
+    {RIL_REQUEST_SET_UICC_SUBSCRIPTION, dispatchUiccSubscripton, responseVoid},
+    {RIL_REQUEST_ALLOW_DATA, dispatchInts, responseVoid},
+    {RIL_REQUEST_GET_HARDWARE_CONFIG, dispatchVoid, responseHardwareConfig},
+    {RIL_REQUEST_SIM_AUTHENTICATION, dispatchSimAuthentication, responseSIM_IO},
+    {RIL_REQUEST_GET_DC_RT_INFO, dispatchVoid, responseDcRtInfo},
+    {RIL_REQUEST_SET_DC_RT_INFO_RATE, dispatchInts, responseVoid},
+    {RIL_REQUEST_SET_DATA_PROFILE, dispatchDataProfile, responseVoid},
+    {RIL_REQUEST_SHUTDOWN, dispatchVoid, responseVoid},
+    {RIL_REQUEST_GET_RADIO_CAPABILITY, dispatchVoid, responseRadioCapability},
+    {RIL_REQUEST_SET_RADIO_CAPABILITY, dispatchRadioCapability, responseRadioCapability},
+    {RIL_REQUEST_START_LCE, dispatchInts, responseLceStatus},
+    {RIL_REQUEST_STOP_LCE, dispatchVoid, responseLceStatus},
+    {RIL_REQUEST_PULL_LCEDATA, dispatchVoid, responseLceData},
+    {RIL_REQUEST_GET_ACTIVITY_INFO, dispatchVoid, responseActivityData},
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ril_unsol_commands.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ril_unsol_commands.h
new file mode 100644
index 0000000..debe4a7
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ril_unsol_commands.h
@@ -0,0 +1,62 @@
+/*
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+    {RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, responseVoid, WAKE_PARTIAL},
+    {RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED, responseVoid, WAKE_PARTIAL},
+    {RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED, responseVoid, WAKE_PARTIAL},
+    {RIL_UNSOL_RESPONSE_NEW_SMS, responseString, WAKE_PARTIAL},
+    {RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT, responseString, WAKE_PARTIAL},
+    {RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM, responseInts, WAKE_PARTIAL},
+    {RIL_UNSOL_ON_USSD, responseStrings, WAKE_PARTIAL},
+    {RIL_UNSOL_ON_USSD_REQUEST, responseVoid, DONT_WAKE},
+    {RIL_UNSOL_NITZ_TIME_RECEIVED, responseString, WAKE_PARTIAL},
+    {RIL_UNSOL_SIGNAL_STRENGTH, responseRilSignalStrength, DONT_WAKE},
+    {RIL_UNSOL_DATA_CALL_LIST_CHANGED, responseDataCallList, WAKE_PARTIAL},
+    {RIL_UNSOL_SUPP_SVC_NOTIFICATION, responseSsn, WAKE_PARTIAL},
+    {RIL_UNSOL_STK_SESSION_END, responseVoid, WAKE_PARTIAL},
+    {RIL_UNSOL_STK_PROACTIVE_COMMAND, responseString, WAKE_PARTIAL},
+    {RIL_UNSOL_STK_EVENT_NOTIFY, responseString, WAKE_PARTIAL},
+    {RIL_UNSOL_STK_CALL_SETUP, responseInts, WAKE_PARTIAL},
+    {RIL_UNSOL_SIM_SMS_STORAGE_FULL, responseVoid, WAKE_PARTIAL},
+    {RIL_UNSOL_SIM_REFRESH, responseSimRefresh, WAKE_PARTIAL},
+    {RIL_UNSOL_CALL_RING, responseCallRing, WAKE_PARTIAL},
+    {RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, responseVoid, WAKE_PARTIAL},
+    {RIL_UNSOL_RESPONSE_CDMA_NEW_SMS, responseCdmaSms, WAKE_PARTIAL},
+    {RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS, responseRaw, WAKE_PARTIAL},
+    {RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL, responseVoid, WAKE_PARTIAL},
+    {RIL_UNSOL_RESTRICTED_STATE_CHANGED, responseInts, WAKE_PARTIAL},
+    {RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE, responseVoid, WAKE_PARTIAL},
+    {RIL_UNSOL_CDMA_CALL_WAITING, responseCdmaCallWaiting, WAKE_PARTIAL},
+    {RIL_UNSOL_CDMA_OTA_PROVISION_STATUS, responseInts, WAKE_PARTIAL},
+    {RIL_UNSOL_CDMA_INFO_REC, responseCdmaInformationRecords, WAKE_PARTIAL},
+    {RIL_UNSOL_OEM_HOOK_RAW, responseRaw, WAKE_PARTIAL},
+    {RIL_UNSOL_RINGBACK_TONE, responseInts, WAKE_PARTIAL},
+    {RIL_UNSOL_RESEND_INCALL_MUTE, responseVoid, WAKE_PARTIAL},
+    {RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED, responseInts, WAKE_PARTIAL},
+    {RIL_UNSOL_CDMA_PRL_CHANGED, responseInts, WAKE_PARTIAL},
+    {RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE, responseVoid, WAKE_PARTIAL},
+    {RIL_UNSOL_RIL_CONNECTED, responseInts, WAKE_PARTIAL},
+    {RIL_UNSOL_VOICE_RADIO_TECH_CHANGED, responseInts, WAKE_PARTIAL},
+    {RIL_UNSOL_CELL_INFO_LIST, responseCellInfoList, WAKE_PARTIAL},
+    {RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED, responseVoid, WAKE_PARTIAL},
+    {RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED, responseInts, WAKE_PARTIAL},
+    {RIL_UNSOL_SRVCC_STATE_NOTIFY, responseInts, WAKE_PARTIAL},
+    {RIL_UNSOL_HARDWARE_CONFIG_CHANGED, responseHardwareConfig, WAKE_PARTIAL},
+    {RIL_UNSOL_DC_RT_INFO_CHANGED, responseDcRtInfo, WAKE_PARTIAL},
+    {RIL_UNSOL_RADIO_CAPABILITY, responseRadioCapability, WAKE_PARTIAL},
+    {RIL_UNSOL_ON_SS, responseSSData, WAKE_PARTIAL},
+    {RIL_UNSOL_STK_CC_ALPHA_NOTIFY, responseString, WAKE_PARTIAL},
+    {RIL_UNSOL_LCEDATA_RECV, responseLceData, WAKE_PARTIAL},
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sim.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sim.cpp
new file mode 100644
index 0000000..a6032a2
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sim.cpp
@@ -0,0 +1,477 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include <stdlib.h>
+#include <binder/Parcel.h>
+#include <log/log.h>
+#include <vendor-ril/telephony/ril.h>
+#include <strings.h>
+#include <string>
+
+#include "sim.h"
+#include  "common.h"
+#include "Radio_capability_switch_util.h"
+
+#undef LOG_TAG
+#define LOG_TAG "DEMO_SIM"
+
+static char* checkParameters(char* para){
+    if (strcasecmp(para, "null") == 0) {
+        return "";
+    } else {
+        return para;
+    }
+}
+
+int getIccCardStatus(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if(argc != 1)
+    {
+        free(pRI);
+        RLOGD("the paremeters numbers isn't right , so return");
+        return -1;
+    }
+    RLOGD("getIccCardStatus %d: " , pRI->pCI->requestNumber);
+    android::Parcel p;
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+int supplyIccPinForApp(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if(argc != 2)
+    {
+        free(pRI);
+        RLOGD("the paremeters numbers isn't right , so return");
+        return -1;
+    }
+
+    const char *pin = argv[1];
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+
+    p.writeInt32(2);
+    writeStringToParcel(p, pin);
+    writeStringToParcel(p, getAid(socket_id));
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+
+int changeIccPinForApp(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if(argc != 3)
+    {
+        free(pRI);
+        RLOGD("the paremeters numbers isn't right , so return");
+        return -1;
+    }
+
+    const char *oldPin = argv[1];
+    const char *newPin = argv[2];
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    p.writeInt32(3);
+    writeStringToParcel(p, oldPin);
+    writeStringToParcel(p, newPin);
+    writeStringToParcel(p, getAid(socket_id));
+    p.setDataPosition(pos);
+
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+int supplyIccPukForApp(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if(argc != 3)
+    {
+        free(pRI);
+        RLOGD("the paremeters numbers isn't right , so return");
+        return -1;
+    }
+
+    const char *puk = argv[1];
+    const char *newPin = argv[2];
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    // start customize
+    p.writeInt32(3);
+    //check
+    writeStringToParcel(p, puk);
+    writeStringToParcel(p, newPin);
+    writeStringToParcel(p, getAid(socket_id));
+    p.setDataPosition(pos);
+
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+int getIMSIForApp(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if (argc != 1) {
+        free(pRI);
+        RLOGD("the paremeters numbers isn't right , so return");
+        return -1;
+    }
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    p.writeInt32(1);
+    RLOGD("getIMSIForApp, aid: %s", getAid(socket_id));
+    writeStringToParcel(p, getAid(socket_id));
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+
+int queryIccidForApp(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if(argc != 1)
+    {
+        free(pRI);
+        RLOGD("the paremeters numbers isn't right , so return");
+        return -1;
+    }
+    RLOGD("queryIccidForApp %d: " , pRI->pCI->requestNumber);
+    android::Parcel p;
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+bool is_valid(int id){
+    RLOGD("is_valid id: %d", id);
+    return (id == 0)||(id == 1);
+}
+
+//SET_DEFAULT_SIM_ALL
+int set_default_sim_all(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI){
+    if((argc != 2) || (!is_valid(atoi(argv[1]))))
+    {
+        free(pRI);
+        RLOGD("the paremeters numbers isn't right , so return");
+        android::emResultNotify("Set failed.\n");
+        return -1;
+    }
+
+    if(Radio_capability_switch_util::is_sim_inserted(atoi(argv[1]))) {
+        set_default_sim_all(atoi(argv[1]));
+        android::emResultNotify("Set successful.\n");
+        free(pRI);
+    } else {
+        RLOGD("Set default all fail, SIM card absent");
+        android::emResultNotify("Set default all fail, SIM card absent.\n");
+        free(pRI);
+    }
+
+    return 0;
+}
+
+//GET_DEFAULT_SIM_ALL
+int get_default_sim_all(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI){
+    int slot_id = get_default_sim_all();
+    std::string str("");
+    str = "default SIM(except data): " + std::to_string(get_default_sim_all_except_data()) + "\n";
+    str = str + "default data: " + std::to_string(get_default_sim_data()) + "\n";
+    str = str + "main capability SIM: " + std::to_string(Radio_capability_switch_util::get_main_capability_phone_id()) + "\n";
+    android::emResultNotify(str.c_str());
+    free(pRI);
+    return 0;
+}
+
+//SET_DEFAULT_SIM_VOICE
+int set_default_sim_voice(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI){
+    if((argc != 2) || (!is_valid(atoi(argv[1]))))
+    {
+        free(pRI);
+        RLOGD("the paremeters numbers isn't right , so return");
+        android::emResultNotify("Set failed.\n");
+        return -1;
+    }
+    set_default_sim_voice(atoi(argv[1]));
+    android::emResultNotify("Set successful.\n");
+    free(pRI);
+    return 0;
+}
+
+//GET_DEFAULT_SIM_VOICE
+int get_default_sim_voice(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI){
+    int slot_id = get_default_sim_voice();
+    std::string str("");
+    if(slot_id == UNSET) {
+        str = "SIM NOT insert\n";
+    } else {
+        str = "default SIM for voice: " + std::to_string(slot_id) + "\n";
+    }
+    android::emResultNotify(str.c_str());
+    free(pRI);
+    return 0;
+}
+
+//SET_DEFAULT_SIM_DATA
+int set_default_sim_data(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI){
+    if((argc != 2) || (!is_valid(atoi(argv[1]))))
+    {
+        free(pRI);
+        RLOGD("the paremeters numbers isn't right , so return");
+        android::emResultNotify("Set failed.\n");
+        return -1;
+    }
+    if(Radio_capability_switch_util::is_sim_inserted(atoi(argv[1]))) {
+        set_default_sim_data(atoi(argv[1]));
+        android::emResultNotify("Set successful.\n");
+        free(pRI);
+    } else {
+        RLOGD("Set default data fail, SIM card absent");
+        android::emResultNotify("Set default data fail, SIM card absent.\n");
+        free(pRI);
+    }
+    return 0;
+}
+
+//GET_DEFAULT_SIM_DATA
+int get_default_sim_data(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI){
+    int slot_id = get_default_sim_data();
+    std::string str("");
+    if(slot_id == UNSET) {
+        str = "SIM NOT insert\n";
+    } else {
+        str = "default SIM for data: " + std::to_string(slot_id) + "\n";
+    }
+    android::emResultNotify(str.c_str());
+    free(pRI);
+    return 0;
+}
+
+//GET_MAIN_SIM_CARD
+int get_main_sim_card(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI){
+    int slot_id = Radio_capability_switch_util::get_main_capability_phone_id();
+    std::string str("");
+    str = "main capability SIM: " + std::to_string(slot_id) + "\n";
+    android::emResultNotify(str.c_str());
+    free(pRI);
+    return 0;
+}
+
+//SET_DEFAULT_SIM_SMS
+int set_default_sim_sms(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI){
+    if((argc != 2) || (!is_valid(atoi(argv[1]))))
+    {
+        free(pRI);
+        RLOGD("the paremeters numbers isn't right , so return");
+        android::emResultNotify("Set failed.\n");
+        return -1;
+    }
+    set_default_sim_sms(atoi(argv[1]));
+    android::emResultNotify("Set successful.\n");
+    free(pRI);
+    return 0;
+}
+
+//GET_DEFAULT_SIM_SMS
+int get_default_sim_sms(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI){
+    int slot_id = get_default_sim_sms();
+    std::string str("");
+    if(slot_id == UNSET) {
+        str = "SIM NOT insert\n";
+    } else {
+        str = "default SIM for sms: " + std::to_string(slot_id) + "\n";
+    }
+    android::emResultNotify(str.c_str());
+    free(pRI);
+    return 0;
+}
+
+//SET_DEFAULT_SIM_ALL_EXCEPT_DATA
+int set_default_sim_all_except_data(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI){
+    if((argc != 2) || (!is_valid(atoi(argv[1]))))
+    {
+        free(pRI);
+        RLOGD("the paremeters numbers isn't right , so return");
+        android::emResultNotify("Set failed.\n");
+        return -1;
+    }
+
+    set_default_sim_all_except_data(atoi(argv[1]));
+    android::emResultNotify("Set successful.\n");
+    free(pRI);
+    return 0;
+}
+
+//GET_DEFAULT_SIM_ALL_EXCEPT_DATA
+int get_default_sim_all_except_data(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI){
+    int slot_id = get_default_sim_all_except_data();
+    std::string str("");
+    if(slot_id == UNSET) {
+        str = "SIM NOT insert\n";
+    } else {
+        str = "default SIM(except data): " + std::to_string(slot_id) + "\n";
+    }
+    android::emResultNotify(str.c_str());
+    free(pRI);
+    return 0;
+}
+
+//RIL_REQUEST_SIM_IO
+int iccIOForApp(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if(argc != 10)
+    {
+        free(pRI);
+        RLOGD("the peremeters numbers isn't right , so return");
+        return -1;
+    }
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    p.writeInt32(atoi(argv[1]));
+    p.writeInt32(atoi(argv[2]));
+    writeStringToParcel(p, argv[3]);
+    p.writeInt32(atoi(argv[4]));
+    p.writeInt32(atoi(argv[5]));
+    p.writeInt32(atoi(argv[6]));
+    writeStringToParcel(p, checkParameters(argv[7]));
+    writeStringToParcel(p, checkParameters(argv[8]));
+    writeStringToParcel(p, checkParameters(argv[9]));
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+//RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC
+int iccTransmitApduBasicChannel(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if(argc > 8)
+    {
+        free(pRI);
+        RLOGD("the peremeters numbers isn't right , so return");
+        return -1;
+    }
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    p.writeInt32(atoi(argv[1]));
+    p.writeInt32(atoi(argv[2]));
+    p.writeInt32(atoi(argv[3]));
+    p.writeInt32(atoi(argv[4]));
+    p.writeInt32(atoi(argv[5]));
+    p.writeInt32(atoi(argv[6]));
+    writeStringToParcel(p, ((argc == 7) ? "" : argv[7]));
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+//RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL
+int iccTransmitApduLogicalChannel(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if(argc > 8)
+    {
+        free(pRI);
+        RLOGD("the peremeters numbers isn't right , so return");
+        return -1;
+    }
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    p.writeInt32(atoi(argv[1]));
+    p.writeInt32(atoi(argv[2]));
+    p.writeInt32(atoi(argv[3]));
+    p.writeInt32(atoi(argv[4]));
+    p.writeInt32(atoi(argv[5]));
+    p.writeInt32(atoi(argv[6]));
+    writeStringToParcel(p, ((argc == 7) ? "" : argv[7]));
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+//RIL_REQUEST_SIM_OPEN_CHANNEL
+int iccOpenLogicalChannel(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI){
+    if(argc != 2)
+    {
+        free(pRI);
+        RLOGD("the peremeters numbers isn't right , so return");
+        return -1;
+    }
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    writeStringToParcel(p, (const char *)argv[1]);
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+//RIL_REQUEST_SIM_CLOSE_CHANNEL
+int iccCloseLogicalChannel(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI){
+    if(argc != 2)
+    {
+        free(pRI);
+        RLOGD("the peremeters numbers isn't right , so return");
+        return -1;
+    }
+
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    p.writeInt32(1);
+    p.writeInt32(atoi(argv[1]));
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+//RIL_REQUEST_QUERY_SIM_RETRY_COUNT
+int querySimRetryCount(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if(argc != 1)
+    {
+        free(pRI);
+        RLOGD("the paremeters numbers isn't right , so return");
+        return -1;
+    }
+    RLOGD("getIccCardStatus %d: " , pRI->pCI->requestNumber);
+    android::Parcel p;
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+//RIL_REQUEST_QUERY_EID
+int queryEid(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if(argc != 1)
+    {
+        free(pRI);
+        RLOGD("the paremeters numbers isn't right , so return");
+        return -1;
+    }
+    android::Parcel p;
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sim.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sim.h
new file mode 100644
index 0000000..fe1863c
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sim.h
@@ -0,0 +1,65 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#ifndef YOCTO_SIM_H
+#define YOCTO_SIM_H 1
+
+#include <vendor-ril/telephony/ril.h>
+#include  "common.h"
+
+int getIccCardStatus(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int supplyIccPinForApp(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int changeIccPinForApp(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int supplyIccPukForApp(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int getIMSIForApp(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int queryIccidForApp(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int set_default_sim_all(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int get_default_sim_all(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int set_default_sim_voice(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int get_default_sim_voice(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int set_default_sim_data(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int get_default_sim_data(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int set_default_sim_sms(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int get_default_sim_sms(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int set_default_sim_all_except_data(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int get_default_sim_all_except_data(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int get_main_sim_card(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int iccIOForApp(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int iccTransmitApduBasicChannel(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int iccTransmitApduLogicalChannel(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int iccOpenLogicalChannel(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int iccCloseLogicalChannel(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int querySimRetryCount(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int queryEid(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+#endif
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/BearerData.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/BearerData.cpp
new file mode 100644
index 0000000..fccbfbf
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/BearerData.cpp
@@ -0,0 +1,1624 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <string>
+#include <memory>
+#include <iostream>
+#include <list>
+#include <algorithm>
+using namespace std;
+
+#include "BearerData.h"
+#include "UserData.h"
+#include "SmsConstants.h"
+#include "HexDump.h"
+#include "IccUtils.h"
+#include "BitwiseInputStream.h"
+#include "CdmaSmsCbProgramData.h";
+#include "SmsHeader.h"
+#include "GsmAlphabet.h"
+#include "SmsEnvelope.h"
+
+extern "C" {
+    #include <glib.h>
+}
+
+BearerData::BearerData() {
+  // TODO Auto-generated constructor stub
+
+}
+
+BearerData::~BearerData() {
+  // TODO Auto-generated destructor stub
+}
+
+/**
+ * Decodes a CDMA style BCD byte like {@link #gsmBcdByteToInt}, but
+ * opposite nibble format. The least significant BCD digit
+ * is in the least significant nibble and the most significant
+ * is in the most significant nibble.
+ */
+int BearerData::cdmaBcdByteToInt(uint8_t b) {
+  int ret = 0;
+
+  // treat out-of-range BCD values as 0
+  if ((b & 0xf0) <= 0x90) {
+    ret = ((b >> 4) & 0xf) * 10;
+  }
+
+  if ((b & 0x0f) <= 0x09) {
+    ret += (b & 0xf);
+  }
+
+  return ret;
+}
+
+void BearerData::fromByteArray(std::vector<uint8_t> data, struct tm& ts) {
+  // C.S0015-B v2.0, 4.5.4: range is 1996-2095
+  int year = cdmaBcdByteToInt(data[0]);
+  if (year > 99 || year < 0) {
+    ts = {0};
+    return;
+  }
+  ts.tm_year = year /*>= 96 ? year + 1900 : year + 2000*/; //TBD
+  int month = cdmaBcdByteToInt(data[1]);
+  if (month < 1 || month > 12) {
+    ts = {0};
+    return;
+  }
+  ts.tm_mon = month - 1;
+  int day = cdmaBcdByteToInt(data[2]);
+  if (day < 1 || day > 31) {
+    ts = {0};
+    return;
+  }
+  ts.tm_mday = day;
+  int hour = cdmaBcdByteToInt(data[3]);
+  if (hour < 0 || hour > 23) {
+    ts = {0};
+    return;
+  }
+  ts.tm_hour = hour;
+  int minute = cdmaBcdByteToInt(data[4]);
+  if (minute < 0 || minute > 59) {
+    ts = {0};
+    return;
+  }
+  ts.tm_min = minute;
+  int second = cdmaBcdByteToInt(data[5]);
+  if (second < 0 || second > 59) {
+    ts = {0};
+    return;
+  }
+  ts.tm_sec = second;
+}
+
+void BearerData::encodeMessageId(BearerData* bData,
+    shared_ptr<BitwiseOutputStream> outStream) {
+  outStream->write(8, 3);
+  outStream->write(4, bData->messageType);
+  outStream->write(8, bData->messageId >> 8);
+  outStream->write(8, bData->messageId);
+  outStream->write(1, bData->hasUserDataHeader ? 1 : 0);
+  outStream->skip(3);
+}
+
+uint32_t BearerData::countAsciiSeptets(char* msg, bool force) {
+  string strmsg(msg);
+  int msgLen = strmsg.length();
+  if (force)
+    return msgLen;
+  for (int i = 0; i < msgLen; i++) {
+    if (UserData::charToAscii.find(msg[i]) == UserData::charToAscii.end()) {
+      return -1;
+    }
+  }
+  return msgLen;
+}
+
+std::vector<uint8_t> BearerData::encodeUtf16(std::string msg) {
+    GError *error = NULL;
+    gsize bytes_written = 0;
+    std::vector<uint8_t> data;
+    char *ret = g_convert (msg.c_str(), -1, "UCS-2BE", "UTF-8", NULL, &bytes_written, &error);
+    if (!ret) {
+        if (error) {
+            cout << "failed to convert UTF-8 to UCS-2BE character set: " << (error->code) << error->message << endl;
+            g_error_free (error);
+        }
+        return data;
+    }
+    for (int i = 0; i < bytes_written; i++) {
+        data.push_back(ret[i]);
+    }
+    g_free (ret);
+    return data;
+}
+
+//release byte[]
+std::vector<uint8_t> BearerData::encode7bitAscii(std::string msgs, bool force) {
+  string msg(msgs);
+  shared_ptr<BitwiseOutputStream> outStream = make_shared<BitwiseOutputStream>(
+      msg.length());
+  int msgLen = msg.length();
+  for (int i = 0; i < msgLen; i++) {
+    uint8_t charCode;
+    try {
+      charCode = UserData::charToAscii.at(msg[i]);
+      outStream->write(7, charCode);
+    } catch (const out_of_range &e) {
+      if (force) {
+        outStream->write(7, UserData::UNENCODABLE_7_BIT_CHAR);
+      }
+      //TBD log
+    }
+  }
+  return outStream->toByteVector();
+}
+
+BearerData::Gsm7bitCodingResult BearerData::encode7bitGsm(std::string msg, int septetOffset, bool force) {
+    std::vector<uint8_t> fullData = GsmAlphabet::stringToGsm7BitPacked(msg, septetOffset, !force, 0, 0);
+    Gsm7bitCodingResult result;
+    result.data.insert(result.data.begin(), fullData.begin() + 1, fullData.end());
+    result.septets = fullData[0] & 0x00FF;
+    return result;
+}
+
+void BearerData::encode7bitEms(std::shared_ptr<UserData> uData, std::vector<uint8_t> udhData, bool force) {
+    int udhBytes = udhData.size() + 1;  // Add length octet.
+    int udhSeptets = ((udhBytes * 8) + 6) / 7;
+    BearerData::Gsm7bitCodingResult gcr = encode7bitGsm(uData->payloadStr, udhSeptets, force);
+    uData->msgEncoding = UserData::ENCODING_GSM_7BIT_ALPHABET;
+    uData->msgEncodingSet = true;
+    uData->numFields = gcr.septets;
+    uData->payload = gcr.data;
+    uData->payload.insert(uData->payload.begin()+1, udhData.begin(), udhData.end());
+    uData->payload[0] = (uint8_t)udhData.size();
+}
+
+void BearerData::encode16bitEms(std::shared_ptr<UserData> uData, std::vector<uint8_t> udhData) {
+    std::vector<uint8_t>  payload = encodeUtf16(uData->payloadStr);
+    int udhBytes = udhData.size() + 1;  // Add length octet.
+    int udhCodeUnits = (udhBytes + 1) / 2;
+    int payloadCodeUnits = payload.size() / 2;
+    uData->msgEncoding = UserData::ENCODING_UNICODE_16;
+    uData->msgEncodingSet = true;
+    uData->numFields = udhCodeUnits + payloadCodeUnits;
+    uData->payload.push_back(udhData.size());
+    (uData->payload).insert((uData->payload).begin() + 1, udhData.begin(), udhData.end());
+    (uData->payload).insert((uData->payload).begin() + udhBytes, payload.begin(), payload.end());
+}
+
+void BearerData::encodeOctetEms(std::shared_ptr<UserData> uData, std::vector<uint8_t> udhData) {
+    int udhBytes = udhData.size() + 1;
+    uData->msgEncoding = UserData::ENCODING_OCTET;
+    uData->msgEncodingSet = true;
+    uData->numFields = udhBytes + uData->payload.size();
+    //byte[] payload = new byte[uData.numFields];
+    std::vector<uint8_t> payload;
+    uData->payload.push_back(udhData.size());
+    (uData->payload).insert((uData->payload).begin() + 1, udhData.begin(), udhData.end());
+    (uData->payload).insert((uData->payload).begin() + udhBytes, payload.begin(), payload.end());
+}
+
+void BearerData::encodeEmsUserDataPayload(std::shared_ptr<UserData> uData) {
+    std::vector<uint8_t> headerData = SmsHeader::toByteArray(uData->userDataHeader);
+    if (uData->msgEncodingSet) {
+        if (uData->msgEncoding == UserData::ENCODING_GSM_7BIT_ALPHABET) {
+            encode7bitEms(uData, headerData, true);
+        } else if (uData->msgEncoding == UserData::ENCODING_OCTET) {
+            encodeOctetEms(uData, headerData);
+        } else if (uData->msgEncoding == UserData::ENCODING_UNICODE_16) {
+            encode16bitEms(uData, headerData);
+        } else {
+            cout << "unsupported EMS user data encoding (" << uData->msgEncoding << ")" <<endl;
+        }
+    } else {
+        encode7bitEms(uData, headerData, false);
+    }
+}
+//maybe free memory
+void BearerData::encodeUserDataPayload(std::shared_ptr<UserData> uData) {
+  if ((uData->payloadStr.empty())
+      && (uData->msgEncoding != UserData::ENCODING_OCTET)) {
+    //Rlog.e(LOG_TAG, "user data with null payloadStr");
+    uData->payloadStr = string("");
+  }
+
+   if (uData->userDataHeader != nullptr) {
+      encodeEmsUserDataPayload(uData);
+   return;
+  }
+
+  if (uData->msgEncodingSet) {
+    if (uData->msgEncoding == UserData::ENCODING_OCTET) {
+      if (uData->payload.empty()) {
+        //Rlog.e(LOG_TAG, "user data with octet encoding but null payload");
+        uData->payload.clear();
+        uData->numFields = 0;
+      } else {
+        uData->numFields = uData->payload.size(); //maybe wrong?
+      }
+    } else {
+      if (uData->payloadStr.empty()) {
+        //Rlog.e(LOG_TAG, "non-octet user data with null payloadStr");
+        uData->payloadStr = string("");
+      }
+//                  if (uData.msgEncoding == UserData::ENCODING_GSM_7BIT_ALPHABET) {
+//                      Gsm7bitCodingResult gcr = encode7bitGsm(uData.payloadStr, 0, true);
+//                      uData.payload = gcr.data;
+//                      uData.numFields = gcr.septets;
+//                  } else
+
+      if (uData->msgEncoding == UserData::ENCODING_7BIT_ASCII) {
+        uData->payload = encode7bitAscii(uData->payloadStr, true);
+        uData->numFields = uData->payloadStr.size();
+      } else if (uData->msgEncoding == UserData::ENCODING_UNICODE_16) {
+        uData->payload = encodeUtf16(uData->payloadStr);
+        uData->numFields = string(uData->payloadStr).length();
+//                  } else if (uData->msgEncoding == UserData::ENCODING_SHIFT_JIS) {
+//                      uData->payload = encodeShiftJis(uData->payloadStr);
+//                      uData->numFields = string(uData->payloadStr).length();
+      } else {
+        cout << "unsupported user data encoding (" << uData->msgEncoding << ")"
+            << endl;
+      }
+    }
+  } else {
+    uData->payload = encode7bitAscii(uData->payloadStr, false);
+    string str1 = HexDump::toHexString(uData->payload);
+    //std::cout << "uData->payload: " << str1 << endl;
+    uData->msgEncoding = UserData::ENCODING_7BIT_ASCII;
+//              try {
+//              } catch (CodingException ex) {
+//                  uData.payload = encodeUtf16(uData.payloadStr);
+//                  uData.msgEncoding = UserData.ENCODING_UNICODE_16;
+//              }
+    uData->numFields = uData->payloadStr.size();
+    uData->msgEncodingSet = true;
+  }
+}
+
+void BearerData::encodeUserData(BearerData* bData,
+    shared_ptr<BitwiseOutputStream> outStream) {
+  /*
+   * TODO(cleanup): Do we really need to set userData.payload as
+   * a side effect of encoding?  If not, we could avoid data
+   * copies by passing outStream directly.
+   */
+  encodeUserDataPayload(bData->userData);
+  bData->hasUserDataHeader = false; //bData->userData->userDataHeader != null;
+
+  int length = bData->userData->payload.size();
+  if (length > SmsConstants::MAX_USER_DATA_BYTES) {
+    cout << "encoded user data too large (" << bData->userData->payload.size()
+        << " > " << SmsConstants::MAX_USER_DATA_BYTES << " bytes)" << endl;
+    return;
+  }
+
+  /*
+   * TODO(cleanup): figure out what the right answer is WRT paddingBits field
+   *
+   *   userData->pad->ingBits = (userData->payload.length * 8) - (userData.numFields * 7);
+   *   userData.paddingBits = 0; // XXX this seems better, but why?
+   *
+   */
+  int dataBits = (length * 8) - (bData->userData->paddingBits);
+  int paramBits = dataBits + 13;
+  if (((bData->userData->msgEncoding)
+      == UserData::ENCODING_IS91_EXTENDED_PROTOCOL)
+      || ((bData->userData->msgEncoding) == UserData::ENCODING_GSM_DCS)) {
+    paramBits += 8;
+  }
+  int paramBytes = (paramBits / 8) + ((paramBits % 8) > 0 ? 1 : 0);
+  int paddingBits = (paramBytes * 8) - paramBits;
+  outStream->write(8, paramBytes);
+  outStream->write(5, bData->userData->msgEncoding);
+  if ((bData->userData->msgEncoding == UserData::ENCODING_IS91_EXTENDED_PROTOCOL)
+      || (bData->userData->msgEncoding == UserData::ENCODING_GSM_DCS)) {
+    outStream->write(8, bData->userData->msgType);
+  }
+  outStream->write(8, (bData->userData)->numFields);
+  outStream->writeByteVector(dataBits, (bData->userData)->payload);
+  if (paddingBits > 0)
+    outStream->write(paddingBits, 0);
+}
+
+void BearerData::encodeReplyOption(BearerData* bData,
+    shared_ptr<BitwiseOutputStream> outStream) {
+  outStream->write(8, 1);
+  outStream->write(1, bData->userAckReq ? 1 : 0);
+  outStream->write(1, bData->deliveryAckReq ? 1 : 0);
+  outStream->write(1, bData->readAckReq ? 1 : 0);
+  outStream->write(1, bData->reportReq ? 1 : 0);
+  outStream->write(4, 0);
+}
+
+//free memory
+std::vector<uint8_t> BearerData::encodeDtmfSmsAddress(std::string address) {
+  int digits = address.length();
+  int dataBits = digits * 4;
+  int dataBytes = (dataBits / 8);
+  dataBytes += (dataBits % 8) > 0 ? 1 : 0;
+  //uint8_t* rawData = new uint8_t[dataBytes];
+  std::vector<uint8_t> rawData;
+  for (int i = 0; i < digits; i++) {
+    char c = address[i];
+    int val = 0;
+    if ((c >= '1') && (c <= '9'))
+      val = c - '0';
+    else if (c == '0')
+      val = 10;
+    else if (c == '*')
+      val = 11;
+    else if (c == '#')
+      val = 12;
+    else
+      return rawData;
+    int size = rawData.size();
+    if ((i / 2) < size) {
+      rawData[i / 2] |= val << (4 - ((i % 2) * 4));
+    } else {
+      rawData.push_back(val << (4 - ((i % 2) * 4)));
+    }
+  }
+  return rawData;
+}
+
+void BearerData::encodeCdmaSmsAddress(std::shared_ptr<CdmaSmsAddress> addr) {
+  if (addr->digitMode == CdmaSmsAddress::DIGIT_MODE_8BIT_CHAR) {
+    //TBD
+//              try {
+//                  addr.origBytes = addr.address.getBytes("US-ASCII");
+//              } catch (java.io.UnsupportedEncodingException ex) {
+//                  throw new CodingException("invalid SMS address, cannot convert to ASCII");
+//              }
+  } else {
+    addr->origBytes = encodeDtmfSmsAddress(addr->address);
+  }
+}
+
+void BearerData::encodeCallbackNumber(BearerData* bData,
+    shared_ptr<BitwiseOutputStream> outStream) {
+  auto addr = bData->callbackNumber;
+  encodeCdmaSmsAddress(addr);
+  int paramBits = 9;
+  int dataBits = 0;
+  if (addr->digitMode == CdmaSmsAddress::DIGIT_MODE_8BIT_CHAR) {
+    paramBits += 7;
+    dataBits = addr->numberOfDigits * 8;
+  } else {
+    dataBits = addr->numberOfDigits * 4;
+  }
+  paramBits += dataBits;
+  int paramBytes = (paramBits / 8) + ((paramBits % 8) > 0 ? 1 : 0);
+  int paddingBits = (paramBytes * 8) - paramBits;
+  outStream->write(8, paramBytes);
+  outStream->write(1, addr->digitMode);
+  if (addr->digitMode == CdmaSmsAddress::DIGIT_MODE_8BIT_CHAR) {
+    outStream->write(3, addr->ton);
+    outStream->write(4, addr->numberPlan);
+  }
+  outStream->write(8, addr->numberOfDigits);
+  outStream->writeByteVector(dataBits, addr->origBytes);
+  if (paddingBits > 0)
+    outStream->write(paddingBits, 0);
+}
+
+void BearerData::encodeMsgStatus(BearerData* bData,
+    shared_ptr<BitwiseOutputStream> outStream) {
+  outStream->write(8, 1);
+  outStream->write(2, bData->errorClass);
+  outStream->write(6, bData->messageStatus);
+}
+void BearerData::encodeMsgCount(BearerData* bData,
+    shared_ptr<BitwiseOutputStream> outStream) {
+  outStream->write(8, 1);
+  outStream->write(8, bData->numberOfMessages);
+}
+void BearerData::encodeValidityPeriodRel(BearerData* bData,
+    shared_ptr<BitwiseOutputStream> outStream) {
+  outStream->write(8, 1);
+  outStream->write(8, bData->validityPeriodRelative);
+}
+void BearerData::encodePrivacyIndicator(BearerData* bData,
+    shared_ptr<BitwiseOutputStream> outStream) {
+  outStream->write(8, 1);
+  outStream->write(2, bData->privacy);
+  outStream->skip(6);
+}
+void BearerData::encodeLanguageIndicator(BearerData* bData,
+    shared_ptr<BitwiseOutputStream> outStream) {
+  outStream->write(8, 1);
+  outStream->write(8, bData->language);
+}
+void BearerData::encodeDisplayMode(BearerData* bData,
+    shared_ptr<BitwiseOutputStream> outStream) {
+  outStream->write(8, 1);
+  outStream->write(2, bData->displayMode);
+  outStream->skip(6);
+}
+void BearerData::encodePriorityIndicator(BearerData* bData,
+    shared_ptr<BitwiseOutputStream> outStream) {
+  outStream->write(8, 1);
+  outStream->write(2, bData->priority);
+  outStream->skip(6);
+}
+void BearerData::encodeMsgDeliveryAlert(BearerData* bData,
+    shared_ptr<BitwiseOutputStream> outStream) {
+  outStream->write(8, 1);
+  outStream->write(2, bData->alert);
+  outStream->skip(6);
+}
+std::vector<uint8_t> BearerData::encode(BearerData* bData) {
+  bData->hasUserDataHeader = false; //((bData->userData != nullptr) && (bData->userData->userDataHeader != null));
+  shared_ptr<BitwiseOutputStream> outStream = make_shared<BitwiseOutputStream>(
+      200);
+  outStream->write(8, SUBPARAM_MESSAGE_IDENTIFIER);
+  encodeMessageId(bData, outStream);
+  if (bData->userData != nullptr) {
+    outStream->write(8, SUBPARAM_USER_DATA);
+    encodeUserData(bData, outStream);
+    //cout << "userData" << endl;
+  }
+  if (bData->callbackNumber != nullptr) {
+    //cout << "callbackNumber" << endl;
+    outStream->write(8, SUBPARAM_CALLBACK_NUMBER);
+    encodeCallbackNumber(bData, outStream);
+  }
+  if (bData->userAckReq || bData->deliveryAckReq || bData->readAckReq
+      || bData->reportReq) {
+    //cout << "userAckReq" << endl;
+    outStream->write(8, SUBPARAM_REPLY_OPTION);
+    encodeReplyOption(bData, outStream);
+  }
+  if (bData->numberOfMessages != 0) {
+    //cout << "numberOfMessages" << endl;
+    outStream->write(8, SUBPARAM_NUMBER_OF_MESSAGES);
+    encodeMsgCount(bData, outStream);
+  }
+  if (bData->validityPeriodRelativeSet) {
+    //cout << "validityPeriodRelativeSet" << endl;
+    outStream->write(8, SUBPARAM_VALIDITY_PERIOD_RELATIVE);
+    encodeValidityPeriodRel(bData, outStream);
+  }
+  if (bData->privacyIndicatorSet) {
+    //cout << "privacyIndicatorSet" << endl;
+    outStream->write(8, SUBPARAM_PRIVACY_INDICATOR);
+    encodePrivacyIndicator(bData, outStream);
+  }
+  if (bData->languageIndicatorSet) {
+    //cout << "languageIndicatorSet" << endl;
+    outStream->write(8, SUBPARAM_LANGUAGE_INDICATOR);
+    encodeLanguageIndicator(bData, outStream);
+  }
+  if (bData->displayModeSet) {
+    //cout << "displayModeSet" << endl;
+    outStream->write(8, SUBPARAM_MESSAGE_DISPLAY_MODE);
+    encodeDisplayMode(bData, outStream);
+  }
+  if (bData->priorityIndicatorSet) {
+    //cout << "priorityIndicatorSet" << endl;
+    outStream->write(8, SUBPARAM_PRIORITY_INDICATOR);
+    encodePriorityIndicator(bData, outStream);
+  }
+  if (bData->alertIndicatorSet) {
+    //cout << "alertIndicatorSet" << endl;
+    outStream->write(8, SUBPARAM_ALERT_ON_MESSAGE_DELIVERY);
+    encodeMsgDeliveryAlert(bData, outStream);
+  }
+  if (bData->messageStatusSet) {
+    //cout << "messageStatusSet" << endl;
+    outStream->write(8, SUBPARAM_MESSAGE_STATUS);
+    encodeMsgStatus(bData, outStream);
+  }
+//      if (bData->serviceCategoryProgramResults != null) {
+//          outStream->write(8, SUBPARAM_SERVICE_CATEGORY_PROGRAM_RESULTS);
+//          encodeScpResults(bData, outStream);
+//      }
+  return outStream->toByteVector();
+}
+
+std::shared_ptr<BearerData> BearerData::decode(std::vector<uint8_t> smsData) {
+  return decode(smsData, 0);
+}
+
+bool BearerData::decodeMessageId(std::shared_ptr<BearerData> bData,
+    std::shared_ptr<BitwiseInputStream> inStream) {
+  const int EXPECTED_PARAM_SIZE = 3 * 8;
+  bool decodeSuccess = false;
+  int paramBits = inStream->read(8) * 8;
+  if (paramBits >= EXPECTED_PARAM_SIZE) {
+    paramBits -= EXPECTED_PARAM_SIZE;
+    decodeSuccess = true;
+    bData->messageType = inStream->read(4);
+    bData->messageId = inStream->read(8) << 8;
+    bData->messageId |= inStream->read(8);
+    bData->hasUserDataHeader = (inStream->read(1) == 1);
+    inStream->skip(3);
+  }
+  if ((!decodeSuccess) || (paramBits > 0)) {
+//              Rlog.d(LOG_TAG, "MESSAGE_IDENTIFIER decode " +
+//                        (decodeSuccess ? "succeeded" : "failed") +
+//                        " (extra bits = " + paramBits + ")");
+  }
+  inStream->skip(paramBits);
+  return decodeSuccess;
+}
+
+bool BearerData::decodeUserData(std::shared_ptr<BearerData> bData,
+    std::shared_ptr<BitwiseInputStream> inStream) {
+  uint32_t paramBits = inStream->read((uint32_t) 8) * 8;
+  bData->userData = std::make_shared<UserData>();
+  bData->userData->msgEncoding = inStream->read(5);
+  bData->userData->msgEncodingSet = true;
+  bData->userData->msgType = 0;
+  int consumedBits = 5;
+  if ((bData->userData->msgEncoding == UserData::ENCODING_IS91_EXTENDED_PROTOCOL)
+      || (bData->userData->msgEncoding == UserData::ENCODING_GSM_DCS)) {
+    bData->userData->msgType = inStream->read(8);
+    consumedBits += 8;
+  }
+  bData->userData->numFields = inStream->read(8);
+  consumedBits += 8;
+  int dataBits = paramBits - consumedBits;
+  bData->userData->payload = inStream->readByteVector(dataBits);
+  return true;
+}
+
+bool BearerData::decodeUserResponseCode(std::shared_ptr<BearerData> bData,
+    std::shared_ptr<BitwiseInputStream> inStream) {
+  const uint32_t EXPECTED_PARAM_SIZE = 1 * 8;
+  bool decodeSuccess = false;
+  uint32_t paramBits = inStream->read(8) * 8;
+  if (paramBits >= EXPECTED_PARAM_SIZE) {
+    paramBits -= EXPECTED_PARAM_SIZE;
+    decodeSuccess = true;
+    bData->userResponseCode = inStream->read(8);
+  }
+  if ((!decodeSuccess) || (paramBits > 0)) {
+//      Rlog.d(LOG_TAG, "USER_RESPONSE_CODE decode " +
+//                (decodeSuccess ? "succeeded" : "failed") +
+//                " (extra bits = " + paramBits + ")");
+  }
+  inStream->skip(paramBits);
+  bData->userResponseCodeSet = decodeSuccess;
+  return decodeSuccess;
+}
+
+bool BearerData::decodeReplyOption(std::shared_ptr<BearerData> bData,
+    std::shared_ptr<BitwiseInputStream> inStream) {
+  const int EXPECTED_PARAM_SIZE = 1 * 8;
+  bool decodeSuccess = false;
+  int paramBits = inStream->read(8) * 8;
+  if (paramBits >= EXPECTED_PARAM_SIZE) {
+    paramBits -= EXPECTED_PARAM_SIZE;
+    decodeSuccess = true;
+    bData->userAckReq = (inStream->read(1) == 1);
+    bData->deliveryAckReq = (inStream->read(1) == 1);
+    bData->readAckReq = (inStream->read(1) == 1);
+    bData->reportReq = (inStream->read(1) == 1);
+    inStream->skip(4);
+  }
+  if ((!decodeSuccess) || (paramBits > 0)) {
+//      Rlog->d(LOG_TAG, "REPLY_OPTION decode " +
+//                (decodeSuccess ? "succeeded" : "failed") +
+//                " (extra bits = " + paramBits + ")");
+  }
+  inStream->skip(paramBits);
+  return decodeSuccess;
+}
+
+bool BearerData::decodeMsgCount(std::shared_ptr<BearerData> bData,
+    std::shared_ptr<BitwiseInputStream> inStream) {
+  const int EXPECTED_PARAM_SIZE = 1 * 8;
+  bool decodeSuccess = false;
+  int paramBits = inStream->read(8) * 8;
+  if (paramBits >= EXPECTED_PARAM_SIZE) {
+    paramBits -= EXPECTED_PARAM_SIZE;
+    decodeSuccess = true;
+    bData->numberOfMessages = IccUtils::cdmaBcdByteToInt(
+        (uint8_t) inStream->read(8));
+  }
+  if ((!decodeSuccess) || (paramBits > 0)) {
+//              Rlog.d(LOG_TAG, "NUMBER_OF_MESSAGES decode " +
+//                        (decodeSuccess ? "succeeded" : "failed") +
+//                        " (extra bits = " + paramBits + ")");
+  }
+  inStream->skip(paramBits);
+  return decodeSuccess;
+}
+
+std::string BearerData::decodeDtmfSmsAddress(std::vector<uint8_t> rawData,
+    int numFields) {
+  /* DTMF 4-bit digit encoding, defined in at
+   * 3GPP2 C.S005-D, v2.0, table 2.7.1.3.2.4-4 */
+  string strBuf;
+  for (int i = 0; i < numFields; i++) {
+    int val = 0x0F & (rawData[i / 2] >> (4 - ((i % 2) * 4)));
+    if ((val >= 1) && (val <= 9))
+      strBuf.append(to_string(val));
+    else if (val == 10)
+      strBuf.push_back('0');
+    else if (val == 11)
+      strBuf.push_back('*');
+    else if (val == 12)
+      strBuf.push_back('#');
+    else
+      throw runtime_error(
+          "invalid SMS address DTMF code (" + std::to_string(val) + ")");
+  }
+  return strBuf;
+}
+
+void BearerData::decodeSmsAddress(std::shared_ptr<CdmaSmsAddress> addr) {
+  if (addr->digitMode == CdmaSmsAddress::DIGIT_MODE_8BIT_CHAR) {
+    //android not support
+//              try {
+//                  /* As specified in 3GPP2 C.S0015-B, v2, 4.5.15 -- actually
+//                   * just 7-bit ASCII encoding, with the MSB being zero. */
+//                  addr->address = new string(addr->origBytes, addr->origBytes_length);
+//              } catch (exception& ex) {
+//                  throw runtime_error("invalid SMS address ASCII code");
+//              }
+  } else {
+    addr->address = decodeDtmfSmsAddress(addr->origBytes, addr->numberOfDigits);
+  }
+}
+bool BearerData::decodeCallbackNumber(std::shared_ptr<BearerData> bData,
+    std::shared_ptr<BitwiseInputStream> inStream) {
+  const int EXPECTED_PARAM_SIZE = 1 * 8; //at least
+  int paramBits = inStream->read(8) * 8;
+  if (paramBits < EXPECTED_PARAM_SIZE) {
+    inStream->skip(paramBits);
+    return false;
+  }
+  std::shared_ptr<CdmaSmsAddress> addr = make_shared<CdmaSmsAddress>();
+  addr->digitMode = inStream->read(1);
+  uint8_t fieldBits = 4;
+  uint8_t consumedBits = 1;
+  if (addr->digitMode == CdmaSmsAddress::DIGIT_MODE_8BIT_CHAR) {
+    addr->ton = inStream->read(3);
+    addr->numberPlan = inStream->read(4);
+    fieldBits = 8;
+    consumedBits += 7;
+  }
+  addr->numberOfDigits = inStream->read(8);
+  consumedBits += 8;
+  int remainingBits = paramBits - consumedBits;
+  int dataBits = addr->numberOfDigits * fieldBits;
+  int paddingBits = remainingBits - dataBits;
+  if (remainingBits < dataBits) {
+    throw runtime_error(
+        string("CALLBACK_NUMBER subparam encoding size error (")
+            + string("remainingBits + ") + std::to_string(remainingBits)
+            + string(", dataBits + ") + std::to_string(dataBits)
+            + string(", paddingBits + ") + std::to_string(paddingBits)
+            + string(")"));
+  }
+  addr->origBytes = inStream->readByteVector(dataBits);
+  inStream->skip(paddingBits);
+  decodeSmsAddress(addr);
+  bData->callbackNumber = addr;
+  return true;
+}
+
+bool BearerData::decodeMsgStatus(std::shared_ptr<BearerData> bData,
+    std::shared_ptr<BitwiseInputStream> inStream) {
+  const int EXPECTED_PARAM_SIZE = 1 * 8;
+  bool decodeSuccess = false;
+  int paramBits = inStream->read(8) * 8;
+  if (paramBits >= EXPECTED_PARAM_SIZE) {
+    paramBits -= EXPECTED_PARAM_SIZE;
+    decodeSuccess = true;
+    bData->errorClass = inStream->read(2);
+    bData->messageStatus = inStream->read(6);
+  }
+  if ((!decodeSuccess) || (paramBits > 0)) {
+//      Rlog.d(LOG_TAG, "MESSAGE_STATUS decode " +
+//                (decodeSuccess ? "succeeded" : "failed") +
+//                " (extra bits = " + paramBits + ")");
+  }
+  inStream->skip(paramBits);
+  bData->messageStatusSet = decodeSuccess;
+  return decodeSuccess;
+}
+
+bool BearerData::decodeMsgCenterTimeStamp(std::shared_ptr<BearerData> bData,
+    std::shared_ptr<BitwiseInputStream> inStream) {
+  const int EXPECTED_PARAM_SIZE = 6 * 8;
+  bool decodeSuccess = false;
+  int paramBits = inStream->read(8) * 8;
+  if (paramBits >= EXPECTED_PARAM_SIZE) {
+    paramBits -= EXPECTED_PARAM_SIZE;
+    decodeSuccess = true;
+    fromByteArray(inStream->readByteVector(6 * 8), bData->msgCenterTimeStamp);
+  }
+  if ((!decodeSuccess) || (paramBits > 0)) {
+    /*      Rlog.d(LOG_TAG, "MESSAGE_CENTER_TIME_STAMP decode " +
+     (decodeSuccess ? "succeeded" : "failed") +
+     " (extra bits = " + paramBits + ")");*/
+  }
+  inStream->skip(paramBits);
+  return decodeSuccess;
+}
+
+bool BearerData::decodeValidityAbs(std::shared_ptr<BearerData> bData,
+    std::shared_ptr<BitwiseInputStream> inStream) {
+  const int EXPECTED_PARAM_SIZE = 6 * 8;
+  bool decodeSuccess = false;
+  int paramBits = inStream->read(8) * 8;
+  if (paramBits >= EXPECTED_PARAM_SIZE) {
+    paramBits -= EXPECTED_PARAM_SIZE;
+    decodeSuccess = true;
+    fromByteArray(inStream->readByteVector(6 * 8),
+        bData->validityPeriodAbsolute);
+  }
+  if ((!decodeSuccess) || (paramBits > 0)) {
+//      Rlog.d(LOG_TAG, "VALIDITY_PERIOD_ABSOLUTE decode " +
+//                (decodeSuccess ? "succeeded" : "failed") +
+//                " (extra bits = " + paramBits + ")");
+  }
+  inStream->skip(paramBits);
+  return decodeSuccess;
+}
+
+bool BearerData::decodeValidityRel(std::shared_ptr<BearerData> bData,
+    std::shared_ptr<BitwiseInputStream> inStream) {
+  const int EXPECTED_PARAM_SIZE = 1 * 8;
+  bool decodeSuccess = false;
+  int paramBits = inStream->read(8) * 8;
+  if (paramBits >= EXPECTED_PARAM_SIZE) {
+    paramBits -= EXPECTED_PARAM_SIZE;
+    decodeSuccess = true;
+    //bData->deferredDeliveryTimeRelative = inStream->read(8);
+    bData->validityPeriodRelative = inStream->read(8);
+  }
+  if ((!decodeSuccess) || (paramBits > 0)) {
+    /*      Rlog.d(LOG_TAG, "VALIDITY_PERIOD_RELATIVE decode " +
+     (decodeSuccess ? "succeeded" : "failed") +
+     " (extra bits = " + paramBits + ")");*/
+  }
+  inStream->skip(paramBits);
+  //bData->deferredDeliveryTimeRelativeSet = decodeSuccess;
+  bData->validityPeriodRelativeSet = decodeSuccess;
+  return decodeSuccess;
+}
+
+bool BearerData::decodeDeferredDeliveryAbs(std::shared_ptr<BearerData> bData,
+    std::shared_ptr<BitwiseInputStream> inStream) {
+  const int EXPECTED_PARAM_SIZE = 6 * 8;
+  bool decodeSuccess = false;
+  int paramBits = inStream->read(8) * 8;
+  if (paramBits >= EXPECTED_PARAM_SIZE) {
+    paramBits -= EXPECTED_PARAM_SIZE;
+    decodeSuccess = true;
+    fromByteArray(inStream->readByteVector(6 * 8),
+        bData->deferredDeliveryTimeAbsolute);
+  }
+  if ((!decodeSuccess) || (paramBits > 0)) {
+    /*      Rlog.d(LOG_TAG, "DEFERRED_DELIVERY_TIME_ABSOLUTE decode " +
+     (decodeSuccess ? "succeeded" : "failed") +
+     " (extra bits = " + paramBits + ")");*/
+  }
+  inStream->skip(paramBits);
+  return decodeSuccess;
+}
+
+bool BearerData::decodeDeferredDeliveryRel(std::shared_ptr<BearerData> bData,
+    std::shared_ptr<BitwiseInputStream> inStream) {
+  const int EXPECTED_PARAM_SIZE = 1 * 8;
+  bool decodeSuccess = false;
+  int paramBits = inStream->read(8) * 8;
+  if (paramBits >= EXPECTED_PARAM_SIZE) {
+    paramBits -= EXPECTED_PARAM_SIZE;
+    decodeSuccess = true;
+    //bData->validityPeriodRelative = inStream->read(8);
+    bData->deferredDeliveryTimeRelative = inStream->read(8);
+  }
+  if ((!decodeSuccess) || (paramBits > 0)) {
+    /*      Rlog.d(LOG_TAG, "DEFERRED_DELIVERY_TIME_RELATIVE decode " +
+     (decodeSuccess ? "succeeded" : "failed") +
+     " (extra bits = " + paramBits + ")");*/
+  }
+  inStream->skip(paramBits);
+  //bData->validityPeriodRelativeSet = decodeSuccess;
+  bData->deferredDeliveryTimeRelativeSet = decodeSuccess;
+  return decodeSuccess;
+}
+
+bool BearerData::decodePrivacyIndicator(std::shared_ptr<BearerData> bData,
+    std::shared_ptr<BitwiseInputStream> inStream) {
+  const int EXPECTED_PARAM_SIZE = 1 * 8;
+  bool decodeSuccess = false;
+  int paramBits = inStream->read(8) * 8;
+  if (paramBits >= EXPECTED_PARAM_SIZE) {
+    paramBits -= EXPECTED_PARAM_SIZE;
+    decodeSuccess = true;
+    bData->privacy = inStream->read(2);
+    inStream->skip(6);
+  }
+  if ((!decodeSuccess) || (paramBits > 0)) {
+    /*      Rlog.d(LOG_TAG, "PRIVACY_INDICATOR decode " +
+     (decodeSuccess ? "succeeded" : "failed") +
+     " (extra bits = " + paramBits + ")");*/
+  }
+  inStream->skip(paramBits);
+  bData->privacyIndicatorSet = decodeSuccess;
+  return decodeSuccess;
+}
+bool BearerData::decodeLanguageIndicator(std::shared_ptr<BearerData> bData,
+    std::shared_ptr<BitwiseInputStream> inStream) {
+  const int EXPECTED_PARAM_SIZE = 1 * 8;
+  bool decodeSuccess = false;
+  int paramBits = inStream->read(8) * 8;
+  if (paramBits >= EXPECTED_PARAM_SIZE) {
+    paramBits -= EXPECTED_PARAM_SIZE;
+    decodeSuccess = true;
+    bData->language = inStream->read(8);
+  }
+  if ((!decodeSuccess) || (paramBits > 0)) {
+    /*      Rlog.d(LOG_TAG, "LANGUAGE_INDICATOR decode " +
+     (decodeSuccess ? "succeeded" : "failed") +
+     " (extra bits = " + paramBits + ")");*/
+  }
+  inStream->skip(paramBits);
+  bData->languageIndicatorSet = decodeSuccess;
+  return decodeSuccess;
+}
+
+bool BearerData::decodeDisplayMode(std::shared_ptr<BearerData> bData,
+    std::shared_ptr<BitwiseInputStream> inStream) {
+  const int EXPECTED_PARAM_SIZE = 1 * 8;
+  bool decodeSuccess = false;
+  int paramBits = inStream->read(8) * 8;
+  if (paramBits >= EXPECTED_PARAM_SIZE) {
+    paramBits -= EXPECTED_PARAM_SIZE;
+    decodeSuccess = true;
+    bData->displayMode = inStream->read(2);
+    inStream->skip(6);
+  }
+//  if ((! decodeSuccess) || (paramBits > 0)) {
+//      Rlog.d(LOG_TAG, "DISPLAY_MODE decode " +
+//                (decodeSuccess ? "succeeded" : "failed") +
+//                " (extra bits = " + paramBits + ")");
+//  }
+  inStream->skip(paramBits);
+  bData->displayModeSet = decodeSuccess;
+  return decodeSuccess;
+}
+
+bool BearerData::decodePriorityIndicator(std::shared_ptr<BearerData> bData,
+    std::shared_ptr<BitwiseInputStream> inStream) {
+  const int EXPECTED_PARAM_SIZE = 1 * 8;
+  bool decodeSuccess = false;
+  int paramBits = inStream->read(8) * 8;
+  if (paramBits >= EXPECTED_PARAM_SIZE) {
+    paramBits -= EXPECTED_PARAM_SIZE;
+    decodeSuccess = true;
+    bData->priority = inStream->read(2);
+    inStream->skip(6);
+  }
+//  if ((! decodeSuccess) || (paramBits > 0)) {
+//      Rlog.d(LOG_TAG, "PRIORITY_INDICATOR decode " +
+//                (decodeSuccess ? "succeeded" : "failed") +
+//                " (extra bits = " + paramBits + ")");
+//  }
+  inStream->skip(paramBits);
+  bData->priorityIndicatorSet = decodeSuccess;
+  return decodeSuccess;
+}
+
+bool BearerData::decodeMsgDeliveryAlert(std::shared_ptr<BearerData> bData,
+    std::shared_ptr<BitwiseInputStream> inStream) {
+  const int EXPECTED_PARAM_SIZE = 1 * 8;
+  bool decodeSuccess = false;
+  int paramBits = inStream->read(8) * 8;
+  if (paramBits >= EXPECTED_PARAM_SIZE) {
+    paramBits -= EXPECTED_PARAM_SIZE;
+    decodeSuccess = true;
+    bData->alert = inStream->read(2);
+    inStream->skip(6);
+  }
+  if ((!decodeSuccess) || (paramBits > 0)) {
+//      Rlog.d(LOG_TAG, "ALERT_ON_MESSAGE_DELIVERY decode " +
+//                (decodeSuccess ? "succeeded" : "failed") +
+//                " (extra bits = " + paramBits + ")");
+  }
+  inStream->skip(paramBits);
+  bData->alertIndicatorSet = decodeSuccess;
+  return decodeSuccess;
+}
+
+bool BearerData::decodeDepositIndex(std::shared_ptr<BearerData> bData,
+    std::shared_ptr<BitwiseInputStream> inStream) {
+  const int EXPECTED_PARAM_SIZE = 2 * 8;
+  bool decodeSuccess = false;
+  int paramBits = inStream->read(8) * 8;
+  if (paramBits >= EXPECTED_PARAM_SIZE) {
+    paramBits -= EXPECTED_PARAM_SIZE;
+    decodeSuccess = true;
+    bData->depositIndex = (inStream->read(8) << 8) | inStream->read(8);
+  }
+  /*  if ((! decodeSuccess) || (paramBits > 0)) {
+   Rlog.d(LOG_TAG, "MESSAGE_DEPOSIT_INDEX decode " +
+   (decodeSuccess ? "succeeded" : "failed") +
+   " (extra bits = " + paramBits + ")");
+   }*/
+  inStream->skip(paramBits);
+  return decodeSuccess;
+}
+
+int BearerData::getBitsForNumFields(int msgEncoding, int numFields) {
+  switch (msgEncoding) {
+  case UserData::ENCODING_OCTET:
+  case UserData::ENCODING_SHIFT_JIS:
+  case UserData::ENCODING_KOREAN:
+  case UserData::ENCODING_LATIN:
+  case UserData::ENCODING_LATIN_HEBREW:
+    return numFields * 8;
+
+  case UserData::ENCODING_IA5:
+  case UserData::ENCODING_7BIT_ASCII:
+  case UserData::ENCODING_GSM_7BIT_ALPHABET:
+    return numFields * 7;
+
+  case UserData::ENCODING_UNICODE_16:
+    return numFields * 16;
+
+  default:
+    throw runtime_error("unsupported message encoding (" + msgEncoding + ')');
+  }
+}
+
+std::string BearerData::decodeUtf8(std::vector<uint8_t> data, int offset, int numFields)
+{
+    std::string str;
+    for (int i = offset; i < (offset + numFields); i++)
+    {
+        str.push_back((char)data[i]);
+    }
+    return str;
+}
+
+std::string BearerData::decodeLatin(std::vector<uint8_t> data, int offset, int numFields)
+{
+    std::string str;
+    for (int i = offset; i < (offset + numFields); i++)
+    {
+        str.push_back(data[i]);
+    }
+    char* text = g_convert (str.c_str(), numFields, "UTF-8", "ISO−8859−1", NULL, NULL, NULL);
+    if(!text) {
+        printf("convert (Latin) result is null\n");
+        return std::string("");
+    }
+    std::string ret(text);
+    g_free(text);
+    return ret;
+}
+
+std::string BearerData::decodeUtf16(std::vector<uint8_t> data, int offset, int numFields)
+{
+    std::string str;
+    for (int i = offset; i < (offset + numFields*2); i++)
+    {
+        str.push_back((char)data[i]);
+    }
+    char* text = g_convert (str.c_str(), numFields*2, "UTF-8", "UCS-2BE", NULL, NULL, NULL);
+    if(!text) {
+        printf("convert (Utf16) result is null\n");
+        return std::string("");
+    }
+    std::string ret(text);
+    g_free(text);
+    text = NULL;
+    return ret;
+}
+
+std::string BearerData::decode7bitAscii(std::vector<uint8_t> data, int offset,
+    int numFields) {
+    int headerSeptets = (offset * 8 + 6) / 7;
+    numFields -= headerSeptets;
+    std::string strBuf;
+    auto inStream = std::make_shared<BitwiseInputStream>(data);
+    int wantedBits = (headerSeptets + numFields) * 7;
+    if (inStream->available() < wantedBits) {
+      throw runtime_error(
+          "insufficient data (wanted " + std::to_string(wantedBits)
+              + " bits, but only have " + std::to_string(inStream->available())
+              + ")");
+    }
+    inStream->skip(headerSeptets * 7);
+  for (int i = 0; i < numFields; i++) {
+    int charCode = inStream->read(7);
+    if ((charCode >= UserData::ASCII_MAP_BASE_INDEX)
+        && (charCode <= UserData::ASCII_MAP_MAX_INDEX)) {
+      strBuf.push_back(
+          UserData::ASCII_MAP[charCode - UserData::ASCII_MAP_BASE_INDEX]);
+    } else if (charCode == UserData::ASCII_NL_INDEX) {
+      strBuf.push_back('\n');
+    } else if (charCode == UserData::ASCII_CR_INDEX) {
+      strBuf.push_back('\r');
+    } else {
+      /* For other charCodes, they are unprintable, and so simply use SPACE. */
+      strBuf.push_back(' ');
+    }
+  }
+  return strBuf;
+}
+
+std::string BearerData::decode7bitGsm(std::vector<uint8_t> data, int offset,
+    int numFields) {
+  // Start reading from the next 7-bit aligned boundary after offset.
+  int offsetBits = offset * 8;
+  int offsetSeptets = (offsetBits + 6) / 7;
+  numFields -= offsetSeptets;
+  int paddingBits = (offsetSeptets * 7) - offsetBits;
+  string result = GsmAlphabet::gsm7BitPackedToString(data, offset, numFields,
+      paddingBits, 0, 0);
+  if (result.empty()) {
+    throw runtime_error("7bit GSM decoding failed");
+  }
+  return result;
+}
+
+std::string BearerData::decodeGsmDcs(std::vector<uint8_t> data, int offset,
+    int numFields, int msgType) {
+  if ((msgType & 0xC0) != 0) {
+    throw runtime_error(
+        "unsupported coding group (" + std::to_string(msgType) + ")");
+  }
+
+  switch ((msgType >> 2) & 0x3) {
+  case UserData::ENCODING_GSM_DCS_7BIT:
+    return decode7bitGsm(data, offset, numFields);
+//  case UserData.ENCODING_GSM_DCS_8BIT:
+//      return decodeUtf8(data, offset, numFields);
+//  case UserData.ENCODING_GSM_DCS_16BIT:
+//      return decodeUtf16(data, offset, numFields);
+  default:
+    throw runtime_error(
+        "unsupported user msgType encoding (" + std::to_string(msgType) + ")");
+  }
+}
+
+void BearerData::decodeUserDataPayload(std::shared_ptr<UserData> userData,
+    bool hasUserDataHeader) {
+  int offset = 0;
+  //printf("1st,%s\n",userData->toString().c_str());
+  if (hasUserDataHeader) {
+    int udhLen = userData->payload[0] & 0x00FF;
+    offset += udhLen + 1;
+    /*      byte[] headerData = new byte[udhLen];
+     System.arraycopy(userData.payload, 1, headerData, 0, udhLen)*/;
+    std::vector<uint8_t> v;
+    v.insert(v.end(), userData->payload.begin() + 1,
+        userData->payload.begin() + udhLen);
+    userData->userDataHeader = SmsHeader::fromByteArray(v);
+    //for test cdma long sms, SmsHeader::fromByteArray get the sequence number,but it will always be the last sequence,
+    //maybe overwriten by the last sms part. we print here directly as a temporary solution.
+    if(udhLen == 5 && (userData->payload[1] & 0x00FF)==0x00)//0x00 is the concatenated SMS id
+    {
+        printf("udhLen=%d,refNumber=%d,msgCount=%d, seqNumber=%d\n", udhLen,
+        userData->payload[3] & 0x00FF,userData->payload[4] & 0x00FF,userData->payload[5] & 0x00FF);
+    }
+    else{
+        printf("udhLen=%d, not for test format!\n",udhLen);
+    }
+  }
+  //add for long sms test begin
+  //printf("offset: %d\n",offset);
+  //printf("2nd,%s\n",userData->toString().c_str());
+  //add for long sms test end
+  switch (userData->msgEncoding) {
+  case UserData::ENCODING_OCTET: {
+    /*
+     *  Octet decoding depends on the carrier service.
+     */
+    bool decodingtypeUTF8 = true;
+
+    // Strip off any padding bytes, meaning any differences between the length of the
+    // array and the target length specified by numFields.  This is to avoid any
+    // confusion by code elsewhere that only considers the payload array length.
+    int copyLen = userData->numFields < userData->payload.size() ? userData->numFields : userData->payload.size();
+    std::vector<uint8_t> payload;
+    payload.insert(payload.end(), userData->payload.begin(), userData->payload.begin() + copyLen);
+    userData->payload = payload;
+
+    if (!decodingtypeUTF8) {
+      // There are many devices in the market that send 8bit text sms (latin encoded) as
+      // octet encoded.
+      userData->payloadStr = decodeLatin(userData->payload, offset, userData->numFields);
+    } else {
+      userData->payloadStr = decodeUtf8(userData->payload, offset, userData->numFields);
+    }
+    break;
+  }
+  case UserData::ENCODING_IA5:
+  case UserData::ENCODING_7BIT_ASCII: {
+    userData->payloadStr = decode7bitAscii(userData->payload, offset, userData->numFields);
+    break;
+  case UserData::ENCODING_UNICODE_16:
+      userData->payloadStr = decodeUtf16(userData->payload, offset, userData->numFields);
+      break;
+  }
+  case UserData::ENCODING_GSM_7BIT_ALPHABET: {
+    userData->payloadStr = decode7bitGsm(userData->payload, offset, userData->numFields);
+    break;
+  }
+  case UserData::ENCODING_LATIN:
+      userData->payloadStr = decodeLatin(userData->payload, offset, userData->numFields);
+      break;
+//  case UserData::ENCODING_SHIFT_JIS:
+//     // userData->payloadStr = decodeShiftJis(userData->payload, offset, userData->numFields);
+//    //TBD "unsupported user data encoding"
+//      break;
+  case UserData::ENCODING_GSM_DCS: {
+    userData->payloadStr = decodeGsmDcs(userData->payload, offset,
+        userData->numFields, userData->msgType);
+    break;
+  }
+  default:
+      printf("unsupported user data encoding : %\n" ,std::to_string(userData->msgEncoding));
+//    throw runtime_error(
+//        "unsupported user data encoding ("
+//            + std::to_string(userData->msgEncoding) + ")");
+  }
+}
+bool BearerData::decodeServiceCategoryProgramData(
+    std::shared_ptr<BearerData> bData,
+    std::shared_ptr<BitwiseInputStream> inStream) {
+  if (inStream->available() < 13) {
+    throw runtime_error(
+        string("SERVICE_CATEGORY_PROGRAM_DATA decode failed: only ")
+            + std::to_string(inStream->available())
+            + string(" bits available"));
+  }
+
+  int paramBits = inStream->read(8) * 8;
+  int msgEncoding = inStream->read(5);
+  paramBits -= 5;
+
+  if (inStream->available() < paramBits) {
+    throw runtime_error(
+        string("SERVICE_CATEGORY_PROGRAM_DATA decode failed: only ")
+            + std::to_string(inStream->available())
+            + string(" bits available (") + std::to_string(paramBits)
+            + string(" bits expected)"));
+  }
+
+  auto programDataList = make_shared<list<shared_ptr<CdmaSmsCbProgramData>>>();
+  const int CATEGORY_FIELD_MIN_SIZE = 6 * 8;
+  bool decodeSuccess = false;
+  while (paramBits >= CATEGORY_FIELD_MIN_SIZE) {
+    int operation = inStream->read(4);
+    int category = (inStream->read(8) << 8) | inStream->read(8);
+    int language = inStream->read(8);
+    int maxMessages = inStream->read(8);
+    int alertOption = inStream->read(4);
+    int numFields = inStream->read(8);
+    paramBits -= CATEGORY_FIELD_MIN_SIZE;
+
+    int textBits = getBitsForNumFields(msgEncoding, numFields);
+    if (paramBits < textBits) {
+      throw runtime_error(
+          string("category name is ") + std::to_string(textBits)
+              + string(" bits in length,") + string(" but there are only ")
+              + std::to_string(paramBits) + string(" bits available"));
+    }
+
+    auto userData = make_shared<UserData>();
+    userData->msgEncoding = msgEncoding;
+    userData->msgEncodingSet = true;
+    userData->numFields = numFields;
+    userData->payload = inStream->readByteVector(textBits);
+    paramBits -= textBits;
+
+    decodeUserDataPayload(userData, false);
+    string categoryName = userData->payloadStr;
+    auto programData = std::make_shared<CdmaSmsCbProgramData>(operation,
+        category, language, maxMessages, alertOption, categoryName);
+    programDataList->push_back(programData);
+
+    decodeSuccess = true;
+  }
+
+  if ((!decodeSuccess) || (paramBits > 0)) {
+//      Rlog.d(LOG_TAG, "SERVICE_CATEGORY_PROGRAM_DATA decode " +
+//                (decodeSuccess ? "succeeded" : "failed") +
+//                " (extra bits = " + paramBits + ')');
+  }
+
+  inStream->skip(paramBits);
+  bData->serviceCategoryProgramData = programDataList;
+  return decodeSuccess;
+}
+
+bool BearerData::decodeReserved(std::shared_ptr<BearerData> bData,
+    std::shared_ptr<BitwiseInputStream> inStream, int subparamId) {
+  bool decodeSuccess = false;
+  int subparamLen = inStream->read(8); // SUBPARAM_LEN
+  int paramBits = subparamLen * 8;
+  if (paramBits <= inStream->available()) {
+    decodeSuccess = true;
+    inStream->skip(paramBits);
+  }
+//  Rlog.d(LOG_TAG, "RESERVED bearer data subparameter " + subparamId + " decode "
+//          + (decodeSuccess ? "succeeded" : "failed") + " (param bits = " + paramBits + ")");
+  if (!decodeSuccess) {
+    throw runtime_error(
+        "RESERVED bearer data subparameter " + std::to_string(subparamId)
+            + " had invalid SUBPARAM_LEN " + std::to_string(subparamLen));
+  }
+
+  return decodeSuccess;
+}
+bool BearerData::isCmasAlertCategory(int category) {
+  return category >= SmsEnvelope::SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT
+      && category <= SmsEnvelope::SERVICE_CATEGORY_CMAS_LAST_RESERVED_VALUE;
+}
+
+int BearerData::serviceCategoryToCmasMessageClass(int serviceCategory) {
+  switch (serviceCategory) {
+  case SmsEnvelope::SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT:
+    return SmsCbCmasInfo::CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT;
+
+  case SmsEnvelope::SERVICE_CATEGORY_CMAS_EXTREME_THREAT:
+    return SmsCbCmasInfo::CMAS_CLASS_EXTREME_THREAT;
+
+  case SmsEnvelope::SERVICE_CATEGORY_CMAS_SEVERE_THREAT:
+    return SmsCbCmasInfo::CMAS_CLASS_SEVERE_THREAT;
+
+  case SmsEnvelope::SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY:
+    return SmsCbCmasInfo::CMAS_CLASS_CHILD_ABDUCTION_EMERGENCY;
+
+  case SmsEnvelope::SERVICE_CATEGORY_CMAS_TEST_MESSAGE:
+    return SmsCbCmasInfo::CMAS_CLASS_REQUIRED_MONTHLY_TEST;
+
+  default:
+    return SmsCbCmasInfo::CMAS_CLASS_UNKNOWN;
+  }
+}
+void BearerData::decodeCmasUserData(std::shared_ptr<BearerData> bData,
+    int serviceCategory) {
+  //uint8_t array[bData->userData->payload.size()];
+  //std::copy(bData->userData->payload.begin(), bData->userData->payload.end(), array);
+  auto inStream = make_shared<BitwiseInputStream>(bData->userData->payload);
+
+  if (inStream->available() < 8) {
+    throw runtime_error("emergency CB with no CMAE_protocol_version");
+  }
+  int protocolVersion = inStream->read(8);
+  if (protocolVersion != 0) {
+    throw runtime_error("unsupported CMAE_protocol_version " + protocolVersion);
+  }
+
+  int messageClass = serviceCategoryToCmasMessageClass(serviceCategory);
+  int category = SmsCbCmasInfo::CMAS_CATEGORY_UNKNOWN;
+  int responseType = SmsCbCmasInfo::CMAS_RESPONSE_TYPE_UNKNOWN;
+  int severity = SmsCbCmasInfo::CMAS_SEVERITY_UNKNOWN;
+  int urgency = SmsCbCmasInfo::CMAS_URGENCY_UNKNOWN;
+  int certainty = SmsCbCmasInfo::CMAS_CERTAINTY_UNKNOWN;
+
+  while (inStream->available() >= 16) {
+    int recordType = inStream->read(8);
+    int recordLen = inStream->read(8);
+    switch (recordType) {
+    case 0:     // Type 0 elements (Alert text)
+    {
+      auto alertUserData = make_shared<UserData>();
+      alertUserData->msgEncoding = inStream->read(5);
+      alertUserData->msgEncodingSet = true;
+      alertUserData->msgType = 0;
+
+      int numFields;                          // number of chars to decode
+      switch (alertUserData->msgEncoding) {
+      case UserData::ENCODING_OCTET:
+      case UserData::ENCODING_LATIN:
+        numFields = recordLen - 1;      // subtract 1 byte for encoding
+        break;
+
+      case UserData::ENCODING_IA5:
+      case UserData::ENCODING_7BIT_ASCII:
+      case UserData::ENCODING_GSM_7BIT_ALPHABET:
+        numFields = ((recordLen * 8) - 5) / 7;  // subtract 5 bits for encoding
+        break;
+
+      case UserData::ENCODING_UNICODE_16:
+        numFields = (recordLen - 1) / 2;
+        break;
+
+      default:
+        numFields = 0;      // unsupported encoding
+      }
+
+      alertUserData->numFields = numFields;
+      alertUserData->payload = inStream->readByteVector(recordLen * 8 - 5);
+      decodeUserDataPayload(alertUserData, false);
+      bData->userData = alertUserData;
+      break;
+    }
+    case 1:     // Type 1 elements
+    {
+      category = inStream->read(8);
+      responseType = inStream->read(8);
+      severity = inStream->read(4);
+      urgency = inStream->read(4);
+      certainty = inStream->read(4);
+      inStream->skip(recordLen * 8 - 28);
+      break;
+    }
+    default:
+      //Rlog.w(LOG_TAG, "skipping unsupported CMAS record type " + recordType);
+      inStream->skip(recordLen * 8);
+      break;
+    }
+  }
+
+  bData->cmasWarningInfo = make_shared<SmsCbCmasInfo>(messageClass, category,
+      responseType, severity, urgency, certainty);
+}
+
+void BearerData::decodeIs91VoicemailStatus(std::shared_ptr<BearerData> bData) {
+  //uint8_t array[bData->userData->payload.size()];
+  //std::copy(bData->userData->payload.begin(), bData->userData->payload.end(), array);
+  auto inStream = make_shared<BitwiseInputStream>(bData->userData->payload);
+
+  int dataLen = inStream->available() / 6;  // 6-bit packed character encoding.
+  int numFields = bData->userData->numFields;
+  if ((dataLen > 14) || (dataLen < 3) || (dataLen < numFields)) {
+    throw runtime_error("IS-91 voicemail status decoding failed");
+  }
+  string strbuf;
+  while (inStream->available() >= 6) {
+    strbuf.push_back(UserData::ASCII_MAP[inStream->read(6)]);
+  }
+  string data = strbuf;
+  bData->numberOfMessages = std::stoi(data.substr(0, 2));
+  char prioCode = data.at(2);
+  if (prioCode == ' ') {
+    bData->priority = PRIORITY_NORMAL;
+  } else if (prioCode == '!') {
+    bData->priority = PRIORITY_URGENT;
+  } else {
+    throw runtime_error(
+        string("IS-91 voicemail status decoding failed: ")
+            + string("illegal priority setting (") + std::to_string(prioCode)
+            + string(")"));
+  }
+  bData->priorityIndicatorSet = true;
+  bData->userData->payloadStr = data.substr(3, numFields - 6);
+}
+void BearerData::decodeIs91Cli(std::shared_ptr<BearerData> bData) {
+  //uint8_t array[bData->userData->payload.size()];
+  //std::copy(bData->userData->payload.begin(), bData->userData->payload.end(), array);
+  auto inStream = make_shared<BitwiseInputStream>(bData->userData->payload);
+  int dataLen = inStream->available() / 4;  // 4-bit packed DTMF digit encoding.
+  int numFields = bData->userData->numFields;
+  if ((dataLen > 14) || (dataLen < 3) || (dataLen < numFields)) {
+    throw runtime_error("IS-91 voicemail status decoding failed");
+  }
+  auto addr = make_shared<CdmaSmsAddress>();
+  addr->digitMode = CdmaSmsAddress::DIGIT_MODE_4BIT_DTMF;
+  addr->origBytes = bData->userData->payload;
+  addr->numberOfDigits = (uint8_t) numFields;
+  decodeSmsAddress(addr);
+  bData->callbackNumber = addr;
+}
+
+void BearerData::decodeIs91ShortMessage(std::shared_ptr<BearerData> bData) {
+  //uint8_t array[bData->userData->payload.size()];
+  //std::copy(bData->userData->payload.begin(), bData->userData->payload.end(), array);
+  auto inStream = make_shared<BitwiseInputStream>(bData->userData->payload);
+  int dataLen = inStream->available() / 6;  // 6-bit packed character encoding.
+  int numFields = bData->userData->numFields;
+  // dataLen may be > 14 characters due to octet padding
+  if ((numFields > 14) || (dataLen < numFields)) {
+    throw runtime_error("IS-91 short message decoding failed");
+  }
+  string strbuf;
+  for (int i = 0; i < numFields; i++) {
+    strbuf.push_back(UserData::ASCII_MAP[inStream->read(6)]);
+  }
+  bData->userData->payloadStr = strbuf;
+}
+
+void BearerData::decodeIs91(std::shared_ptr<BearerData> bData) {
+  switch (bData->userData->msgType) {
+  case UserData::IS91_MSG_TYPE_VOICEMAIL_STATUS:
+    decodeIs91VoicemailStatus(bData);
+    break;
+  case UserData::IS91_MSG_TYPE_CLI:
+    decodeIs91Cli(bData);
+    break;
+  case UserData::IS91_MSG_TYPE_SHORT_MESSAGE_FULL:
+  case UserData::IS91_MSG_TYPE_SHORT_MESSAGE:
+    decodeIs91ShortMessage(bData);
+    break;
+  default:
+    throw runtime_error(
+        string("unsupported IS-91 message type (")
+            + std::to_string(bData->userData->msgType) + string(")"));
+  }
+}
+std::shared_ptr<BearerData> BearerData::decode(std::vector<uint8_t> smsData,
+    int serviceCategory) {
+  //uint8_t array[smsData.size()];
+  //std::copy(smsData.begin(), smsData.end(), array);
+  auto inStream = make_shared<BitwiseInputStream>(smsData);
+  shared_ptr<BearerData> bData = make_shared<BearerData>();
+  int foundSubparamMask = 0;
+  while (inStream->available() > 0) {
+    uint32_t subparamId = inStream->read((uint32_t) 8);
+    int subparamIdBit = 1 << subparamId;
+    // int is 4 bytes. This duplicate check has a limit to Id number up to 32 (4*8)
+    // as 32th bit is the max bit in int.
+    // Per 3GPP2 C.S0015-B Table 4.5-1 Bearer Data Subparameter Identifiers:
+    // last defined subparam ID is 23 (00010111 = 0x17 = 23).
+    // Only do duplicate subparam ID check if subparam is within defined value as
+    // reserved subparams are just skipped.
+    if ((foundSubparamMask & subparamIdBit) != 0
+        && (subparamId >= SUBPARAM_MESSAGE_IDENTIFIER
+            && subparamId <= SUBPARAM_ID_LAST_DEFINED)) {
+      throw runtime_error(
+          string("illegal duplicate subparameter (")
+              + std::to_string(subparamId) + string(")"));
+    }
+    bool decodeSuccess;
+    switch (subparamId) {
+    case SUBPARAM_MESSAGE_IDENTIFIER:
+      decodeSuccess = decodeMessageId(bData, inStream);
+      break;
+    case SUBPARAM_USER_DATA:
+      decodeSuccess = decodeUserData(bData, inStream);
+      break;
+    case SUBPARAM_USER_RESPONSE_CODE:
+      decodeSuccess = decodeUserResponseCode(bData, inStream);
+      break;
+    case SUBPARAM_REPLY_OPTION:
+      decodeSuccess = decodeReplyOption(bData, inStream);
+      break;
+    case SUBPARAM_NUMBER_OF_MESSAGES:
+      decodeSuccess = decodeMsgCount(bData, inStream);
+      break;
+    case SUBPARAM_CALLBACK_NUMBER:
+      decodeSuccess = decodeCallbackNumber(bData, inStream);
+      break;
+    case SUBPARAM_MESSAGE_STATUS:
+      decodeSuccess = decodeMsgStatus(bData, inStream);
+      break;
+    case SUBPARAM_MESSAGE_CENTER_TIME_STAMP:
+      decodeSuccess = decodeMsgCenterTimeStamp(bData, inStream);
+      break;
+    case SUBPARAM_VALIDITY_PERIOD_ABSOLUTE:
+      decodeSuccess = decodeValidityAbs(bData, inStream);
+      break;
+    case SUBPARAM_VALIDITY_PERIOD_RELATIVE:
+      decodeSuccess = decodeValidityRel(bData, inStream);
+      break;
+    case SUBPARAM_DEFERRED_DELIVERY_TIME_ABSOLUTE:
+      decodeSuccess = decodeDeferredDeliveryAbs(bData, inStream);
+      break;
+    case SUBPARAM_DEFERRED_DELIVERY_TIME_RELATIVE:
+      decodeSuccess = decodeDeferredDeliveryRel(bData, inStream);
+      break;
+    case SUBPARAM_PRIVACY_INDICATOR:
+      decodeSuccess = decodePrivacyIndicator(bData, inStream);
+      break;
+    case SUBPARAM_LANGUAGE_INDICATOR:
+      decodeSuccess = decodeLanguageIndicator(bData, inStream);
+      break;
+    case SUBPARAM_MESSAGE_DISPLAY_MODE:
+      decodeSuccess = decodeDisplayMode(bData, inStream);
+      break;
+    case SUBPARAM_PRIORITY_INDICATOR:
+      decodeSuccess = decodePriorityIndicator(bData, inStream);
+      break;
+    case SUBPARAM_ALERT_ON_MESSAGE_DELIVERY:
+      decodeSuccess = decodeMsgDeliveryAlert(bData, inStream);
+      break;
+    case SUBPARAM_MESSAGE_DEPOSIT_INDEX:
+      decodeSuccess = decodeDepositIndex(bData, inStream);
+      break;
+    case SUBPARAM_SERVICE_CATEGORY_PROGRAM_DATA:
+      decodeSuccess = decodeServiceCategoryProgramData(bData, inStream);
+      break;
+    default:
+      decodeSuccess = decodeReserved(bData, inStream, subparamId);
+    }
+    if (decodeSuccess
+        && (subparamId >= SUBPARAM_MESSAGE_IDENTIFIER
+            && subparamId <= SUBPARAM_ID_LAST_DEFINED)) {
+      foundSubparamMask |= subparamIdBit;
+    }
+  }
+  if ((foundSubparamMask & (1 << SUBPARAM_MESSAGE_IDENTIFIER)) == 0) {
+    throw runtime_error("missing MESSAGE_IDENTIFIER subparam");
+  }
+  if (bData->userData != nullptr) {
+    if (isCmasAlertCategory(serviceCategory)) {
+      decodeCmasUserData(bData, serviceCategory);
+    } else if (bData->userData->msgEncoding
+        == UserData::ENCODING_IS91_EXTENDED_PROTOCOL) {
+      if ((foundSubparamMask ^ (1 << SUBPARAM_MESSAGE_IDENTIFIER)
+          ^ (1 << SUBPARAM_USER_DATA)) != 0) {
+//                          Rlog.e(LOG_TAG, "IS-91 must occur without extra subparams (" +
+//                                foundSubparamMask + ")");
+      }
+      decodeIs91(bData);
+    } else {
+      decodeUserDataPayload(bData->userData, bData->hasUserDataHeader);
+    }
+  }
+  return bData;
+}
+
+std::string BearerData::toString() {
+  string builder;
+  builder.append("BearerData ");
+  builder.append("{ messageType=" + std::to_string(messageType));
+  builder.append(", messageId=" + std::to_string(messageId));
+  builder.append(
+      string(", priority=")
+          + (priorityIndicatorSet ? std::to_string(priority) : "unset"));
+  builder.append(
+      string(", privacy=")
+          + (privacyIndicatorSet ? std::to_string(privacy) : "unset"));
+  builder.append(
+      string(", alert=")
+          + (alertIndicatorSet ? std::to_string(alert) : "unset"));
+  builder.append(
+      string(", displayMode=")
+          + (displayModeSet ? std::to_string(displayMode) : "unset"));
+  builder.append(
+      string(", language=")
+          + (languageIndicatorSet ? std::to_string(language) : "unset"));
+  builder.append(
+      string(", errorClass=")
+          + (messageStatusSet ? std::to_string(errorClass) : "unset"));
+  builder.append(
+      string(", msgStatus=")
+          + (messageStatusSet ? std::to_string(messageStatus) : "unset"));
+  builder.append(
+      string(
+          ", msgCenterTimeStamp= unset") /*+ string (std::asctime(&msgCenterTimeStamp))*/);
+  builder.append(
+      string(
+          ", validityPeriodAbsolute= unset")/* + string(std::asctime(&validityPeriodAbsolute)))*/);
+  builder.append(
+      string(", validityPeriodRelative= ")
+          + ((validityPeriodRelativeSet) ?
+              std::to_string(validityPeriodRelative) : "unset"));
+  builder.append(
+      string(
+          ", deferredDeliveryTimeAbsolute= ") /*+ string(std::asctime(&deferredDeliveryTimeAbsolute))*/);
+  builder.append(
+      string(", deferredDeliveryTimeRelative=")
+          + ((deferredDeliveryTimeRelativeSet) ?
+              std::to_string(deferredDeliveryTimeRelative) : "unset"));
+  builder.append(", userAckReq=" + std::to_string(userAckReq));
+  builder.append(", deliveryAckReq=" + std::to_string(deliveryAckReq));
+  builder.append(", readAckReq=" + std::to_string(readAckReq));
+  builder.append(", reportReq=" + std::to_string(reportReq));
+  builder.append(", numberOfMessages=" + std::to_string(numberOfMessages));
+  builder.append(string(", callbackNumber=") + string(callbackNumber ?  callbackNumber->toString() : "unset"));
+  builder.append(", depositIndex=" + std::to_string(depositIndex));
+  builder.append(", hasUserDataHeader=" + std::to_string(hasUserDataHeader));
+  builder.append(
+      ", userData=" + string(userData ? userData->toString() : "unset"));
+  builder.append(" }");
+  return builder;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/BearerData.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/BearerData.h
new file mode 100644
index 0000000..23502f3
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/BearerData.h
@@ -0,0 +1,408 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BEARERDATA_H_
+#define BEARERDATA_H_
+#include <cstdint>
+#include <ctime>
+#include <memory>
+#include <string>
+#include <vector>
+#include "UserData.h"
+#include "BitwiseOutputStream.h"
+#include "CdmaSmsAddress.h"
+#include "BitwiseInputStream.h"
+#include "CdmaSmsCbProgramData.h"
+#include "SmsCbCmasInfo.h"
+
+class BearerData {
+public:
+  BearerData();
+  virtual ~BearerData();
+  /**
+   * Supported message types for CDMA SMS messages
+   * (See 3GPP2 C.S0015-B, v2.0, table 4.5.1-1)
+   */
+  static constexpr int MESSAGE_TYPE_DELIVER = 0x01;
+  static constexpr int MESSAGE_TYPE_SUBMIT = 0x02;
+  static constexpr int MESSAGE_TYPE_CANCELLATION = 0x03;
+  static constexpr int MESSAGE_TYPE_DELIVERY_ACK = 0x04;
+  static constexpr int MESSAGE_TYPE_USER_ACK = 0x05;
+  static constexpr int MESSAGE_TYPE_READ_ACK = 0x06;
+  static constexpr int MESSAGE_TYPE_DELIVER_REPORT = 0x07;
+  static constexpr int MESSAGE_TYPE_SUBMIT_REPORT = 0x08;
+  uint32_t messageType = 0;
+  /**
+   * 16-bit value indicating the message ID, which increments modulo 65536.
+   * (Special rules apply for WAP-messages.)
+   * (See 3GPP2 C.S0015-B, v2, 4.5.1)
+   */
+  uint32_t messageId = 0;
+  /**
+   * Supported priority modes for CDMA SMS messages
+   * (See 3GPP2 C.S0015-B, v2.0, table 4.5.9-1)
+   */
+  static constexpr int PRIORITY_NORMAL = 0x0;
+  static constexpr int PRIORITY_INTERACTIVE = 0x1;
+  static constexpr int PRIORITY_URGENT = 0x2;
+  static constexpr int PRIORITY_EMERGENCY = 0x3;
+
+  bool priorityIndicatorSet = false;
+  int priority = PRIORITY_NORMAL;
+
+  /**
+   * Supported privacy modes for CDMA SMS messages
+   * (See 3GPP2 C.S0015-B, v2.0, table 4.5.10-1)
+   */
+  static constexpr int PRIVACY_NOT_RESTRICTED = 0x0;
+  static constexpr int PRIVACY_RESTRICTED = 0x1;
+  static constexpr int PRIVACY_CONFIDENTIAL = 0x2;
+  static constexpr int PRIVACY_SECRET = 0x3;
+
+  bool privacyIndicatorSet = false;
+  int privacy = PRIVACY_NOT_RESTRICTED;
+
+  /**
+   * Supported alert priority modes for CDMA SMS messages
+   * (See 3GPP2 C.S0015-B, v2.0, table 4.5.13-1)
+   */
+  static constexpr int ALERT_DEFAULT = 0x0;
+  static constexpr int ALERT_LOW_PRIO = 0x1;
+  static constexpr int ALERT_MEDIUM_PRIO = 0x2;
+  static constexpr int ALERT_HIGH_PRIO = 0x3;
+
+  bool alertIndicatorSet = false;
+  int alert = ALERT_DEFAULT;
+
+  /**
+   * Supported display modes for CDMA SMS messages.  Display mode is
+   * a 2-bit value used to indicate to the mobile station when to
+   * display the received message.  (See 3GPP2 C.S0015-B, v2,
+   * 4.5.16)
+   */
+  static constexpr int DISPLAY_MODE_IMMEDIATE = 0x0;
+  static constexpr int DISPLAY_MODE_DEFAULT = 0x1;
+  static constexpr int DISPLAY_MODE_USER = 0x2;
+
+  bool displayModeSet = false;
+  int displayMode = DISPLAY_MODE_DEFAULT;
+
+  /**
+   * Language Indicator values.  NOTE: the spec (3GPP2 C.S0015-B,
+   * v2, 4.5.14) is ambiguous as to the meaning of this field, as it
+   * refers to C.R1001-D but that reference has been crossed out.
+   * It would seem reasonable to assume the values from C.R1001-F
+   * (table 9.2-1) are to be used instead.
+   */
+  static constexpr int LANGUAGE_UNKNOWN = 0x00;
+  static constexpr int LANGUAGE_ENGLISH = 0x01;
+  static constexpr int LANGUAGE_FRENCH = 0x02;
+  static constexpr int LANGUAGE_SPANISH = 0x03;
+  static constexpr int LANGUAGE_JAPANESE = 0x04;
+  static constexpr int LANGUAGE_KOREAN = 0x05;
+  static constexpr int LANGUAGE_CHINESE = 0x06;
+  static constexpr int LANGUAGE_HEBREW = 0x07;
+
+  bool languageIndicatorSet = false;
+  int language = LANGUAGE_UNKNOWN;
+
+  /**
+   * SMS Message Status Codes.  The first component of the Message
+   * status indicates if an error has occurred and whether the error
+   * is considered permanent or temporary.  The second component of
+   * the Message status indicates the cause of the error (if any).
+   * (See 3GPP2 C.S0015-B, v2.0, 4.5.21)
+   */
+  /* no-error codes */
+  static constexpr int ERROR_NONE = 0x00;
+  static constexpr int STATUS_ACCEPTED = 0x00;
+  static constexpr int STATUS_DEPOSITED_TO_INTERNET = 0x01;
+  static constexpr int STATUS_DELIVERED = 0x02;
+  static constexpr int STATUS_CANCELLED = 0x03;
+  /* temporary-error and permanent-error codes */
+  static constexpr int ERROR_TEMPORARY = 0x02;
+  static constexpr int STATUS_NETWORK_CONGESTION = 0x04;
+  static constexpr int STATUS_NETWORK_ERROR = 0x05;
+  static constexpr int STATUS_UNKNOWN_ERROR = 0x1F;
+  /* permanent-error codes */
+  static constexpr int ERROR_PERMANENT = 0x03;
+  static constexpr int STATUS_CANCEL_FAILED = 0x06;
+  static constexpr int STATUS_BLOCKED_DESTINATION = 0x07;
+  static constexpr int STATUS_TEXT_TOO_LONG = 0x08;
+  static constexpr int STATUS_DUPLICATE_MESSAGE = 0x09;
+  static constexpr int STATUS_INVALID_DESTINATION = 0x0A;
+  static constexpr int STATUS_MESSAGE_EXPIRED = 0x0D;
+  /* undefined-status codes */
+  static constexpr int ERROR_UNDEFINED = 0xFF;
+  static constexpr int STATUS_UNDEFINED = 0xFF;
+
+  bool messageStatusSet = false;
+  int errorClass = ERROR_UNDEFINED;
+  int messageStatus = STATUS_UNDEFINED;
+
+  /**
+   * 1-bit value that indicates whether a User Data Header (UDH) is present.
+   * (See 3GPP2 C.S0015-B, v2, 4.5.1)
+   *
+   * NOTE: during encoding, this value will be set based on the
+   * presence of a UDH in the structured data, any existing setting
+   * will be overwritten.
+   */
+  bool hasUserDataHeader = false;
+
+  /**
+   * provides the information for the user data
+   * (e.g. padding bits, user data, user data header, etc)
+   * (See 3GPP2 C.S.0015-B, v2, 4.5.2)
+   */
+  std::shared_ptr<UserData> userData = nullptr;
+
+  /**
+   * The User Response Code subparameter is used in the SMS User
+   * Acknowledgment Message to respond to previously received short
+   * messages. This message center-specific element carries the
+   * identifier of a predefined response. (See 3GPP2 C.S.0015-B, v2,
+   * 4.5.3)
+   */
+  bool userResponseCodeSet = false;
+  uint32_t userResponseCode = 0;
+
+  struct tm msgCenterTimeStamp;
+  struct tm validityPeriodAbsolute;
+  struct tm deferredDeliveryTimeAbsolute;
+
+  static int cdmaBcdByteToInt(uint8_t b);
+  static void fromByteArray(std::vector<uint8_t> data, struct tm& ts);
+  /**
+   * Relative time is specified as one byte, the value of which
+   * falls into a series of ranges, as specified below.  The idea is
+   * that shorter time intervals allow greater precision -- the
+   * value means minutes from zero until the MINS_LIMIT (inclusive),
+   * upon which it means hours until the HOURS_LIMIT, and so
+   * forth. (See 3GPP2 C.S0015-B, v2, 4.5.6-1)
+   */
+  static constexpr int RELATIVE_TIME_MINS_LIMIT = 143;
+  static constexpr int RELATIVE_TIME_HOURS_LIMIT = 167;
+  static constexpr int RELATIVE_TIME_DAYS_LIMIT = 196;
+  static constexpr int RELATIVE_TIME_WEEKS_LIMIT = 244;
+  static constexpr int RELATIVE_TIME_INDEFINITE = 245;
+  static constexpr int RELATIVE_TIME_NOW = 246;
+  static constexpr int RELATIVE_TIME_MOBILE_INACTIVE = 247;
+  static constexpr int RELATIVE_TIME_RESERVED = 248;
+
+  bool validityPeriodRelativeSet = false;
+  uint32_t validityPeriodRelative = 0;
+  bool deferredDeliveryTimeRelativeSet = false;
+  uint32_t deferredDeliveryTimeRelative = 0;
+
+  /**
+   * The Reply Option subparameter contains 1-bit values which
+   * indicate whether SMS acknowledgment is requested or not.  (See
+   * 3GPP2 C.S0015-B, v2, 4.5.11)
+   */
+  bool userAckReq = false;
+  bool deliveryAckReq = false;
+  bool readAckReq = false;
+  bool reportReq = false;
+
+  /**
+   * The Number of Messages subparameter (8-bit value) is a decimal
+   * number in the 0 to 99 range representing the number of messages
+   * stored at the Voice Mail System. This element is used by the
+   * Voice Mail Notification service.  (See 3GPP2 C.S0015-B, v2,
+   * 4.5.12)
+   */
+  uint32_t numberOfMessages = 0;
+
+  /**
+   * The Message Deposit Index subparameter is assigned by the
+   * message center as a unique index to the contents of the User
+   * Data subparameter in each message sent to a particular mobile
+   * station. The mobile station, when replying to a previously
+   * received short message which included a Message Deposit Index
+   * subparameter, may include the Message Deposit Index of the
+   * received message to indicate to the message center that the
+   * original contents of the message are to be included in the
+   * reply.  (See 3GPP2 C.S0015-B, v2, 4.5.18)
+   */
+  uint32_t depositIndex = 0;
+  /**
+   * 4-bit or 8-bit value that indicates the number to be dialed in reply to a
+   * received SMS message.
+   * (See 3GPP2 C.S0015-B, v2, 4.5.15)
+   */
+  //CdmaSmsAddress* callbackNumber = nullptr;
+  std::shared_ptr<CdmaSmsAddress> callbackNumber = nullptr;
+  /**
+   * CMAS warning notification information.
+   * @see #decodeCmasUserData(BearerData, int)
+   */
+  std::shared_ptr<SmsCbCmasInfo> cmasWarningInfo = nullptr;
+  std::shared_ptr<std::list<std::shared_ptr<CdmaSmsCbProgramData>>> serviceCategoryProgramData;
+  static void encodeMessageId(BearerData* bData,
+      std::shared_ptr<BitwiseOutputStream> outStream);
+  static uint32_t countAsciiSeptets(char* msg, bool force);
+
+  /**
+   * Create serialized representation for BearerData object.
+   * (See 3GPP2 C.R1001-F, v1.0, section 4.5 for layout details)
+   *
+   * @param bData an instance of BearerData.
+   *
+   * @return uint8_t array of raw encoded SMS bearer data.
+   */
+  static std::vector<uint8_t> encode(BearerData* bData);
+  static std::shared_ptr<BearerData> decode(std::vector<uint8_t> smsData);
+  static std::shared_ptr<BearerData> decode(std::vector<uint8_t> smsData,
+      int serviceCategory);
+  std::string toString();
+private:
+  /**
+   * Bearer Data Subparameter Identifiers
+   * (See 3GPP2 C.S0015-B, v2.0, table 4.5-1)
+   * NOTE: Commented subparameter types are not implemented.
+   */
+  constexpr static uint8_t SUBPARAM_MESSAGE_IDENTIFIER = 0x00;
+  constexpr static uint8_t SUBPARAM_USER_DATA = 0x01;
+  constexpr static uint8_t SUBPARAM_USER_RESPONSE_CODE = 0x02;
+  constexpr static uint8_t SUBPARAM_MESSAGE_CENTER_TIME_STAMP = 0x03;
+  constexpr static uint8_t SUBPARAM_VALIDITY_PERIOD_ABSOLUTE = 0x04;
+  constexpr static uint8_t SUBPARAM_VALIDITY_PERIOD_RELATIVE = 0x05;
+  constexpr static uint8_t SUBPARAM_DEFERRED_DELIVERY_TIME_ABSOLUTE = 0x06;
+  constexpr static uint8_t SUBPARAM_DEFERRED_DELIVERY_TIME_RELATIVE = 0x07;
+  constexpr static uint8_t SUBPARAM_PRIORITY_INDICATOR = 0x08;
+  constexpr static uint8_t SUBPARAM_PRIVACY_INDICATOR = 0x09;
+  constexpr static uint8_t SUBPARAM_REPLY_OPTION = 0x0A;
+  constexpr static uint8_t SUBPARAM_NUMBER_OF_MESSAGES = 0x0B;
+  constexpr static uint8_t SUBPARAM_ALERT_ON_MESSAGE_DELIVERY = 0x0C;
+  constexpr static uint8_t SUBPARAM_LANGUAGE_INDICATOR = 0x0D;
+  constexpr static uint8_t SUBPARAM_CALLBACK_NUMBER = 0x0E;
+  constexpr static uint8_t SUBPARAM_MESSAGE_DISPLAY_MODE = 0x0F;
+  //constexpr static uint8_t SUBPARAM_MULTIPLE_ENCODING_USER_DATA      = 0x10;
+  constexpr static uint8_t SUBPARAM_MESSAGE_DEPOSIT_INDEX = 0x11;
+  constexpr static uint8_t SUBPARAM_SERVICE_CATEGORY_PROGRAM_DATA = 0x12;
+  constexpr static uint8_t SUBPARAM_SERVICE_CATEGORY_PROGRAM_RESULTS = 0x13;
+  constexpr static uint8_t SUBPARAM_MESSAGE_STATUS = 0x14;
+  //constexpr static uint8_t SUBPARAM_TP_FAILURE_CAUSE                 = 0x15;
+  //constexpr static uint8_t SUBPARAM_ENHANCED_VMN                     = 0x16;
+  //constexpr static uint8_t SUBPARAM_ENHANCED_VMN_ACK                 = 0x17;
+
+  // All other values after this are reserved.
+  constexpr static uint8_t SUBPARAM_ID_LAST_DEFINED = 0x17;
+  static void encodeUserData(BearerData* bData,
+      std::shared_ptr<BitwiseOutputStream> outStream);
+  static void encodeUserDataPayload(std::shared_ptr<UserData> uData);
+  static void encodeReplyOption(BearerData* bData,
+      std::shared_ptr<BitwiseOutputStream> outStream);
+  static std::vector<uint8_t> encodeDtmfSmsAddress(std::string address);
+  static void encodeCdmaSmsAddress(std::shared_ptr<CdmaSmsAddress> addr);
+  static void encodeCallbackNumber(BearerData* bData,
+      std::shared_ptr<BitwiseOutputStream> outStream);
+  static void encodeMsgStatus(BearerData* bData,
+      std::shared_ptr<BitwiseOutputStream> outStream);
+  static void encodeMsgCount(BearerData* bData,
+      std::shared_ptr<BitwiseOutputStream> outStream);
+  static void encodeValidityPeriodRel(BearerData* bData,
+      std::shared_ptr<BitwiseOutputStream> outStream);
+  static void encodePrivacyIndicator(BearerData* bData,
+      std::shared_ptr<BitwiseOutputStream> outStream);
+  static void encodeLanguageIndicator(BearerData* bData,
+      std::shared_ptr<BitwiseOutputStream> outStream);
+  static void encodeDisplayMode(BearerData* bData,
+      std::shared_ptr<BitwiseOutputStream> outStream);
+  static void encodePriorityIndicator(BearerData* bData,
+      std::shared_ptr<BitwiseOutputStream> outStream);
+  static void encodeMsgDeliveryAlert(BearerData* bData,
+      std::shared_ptr<BitwiseOutputStream> outStream);
+  static bool decodeMessageId(std::shared_ptr<BearerData> bData,
+      std::shared_ptr<BitwiseInputStream> inStream);
+  static bool decodeUserData(std::shared_ptr<BearerData> bData,
+      std::shared_ptr<BitwiseInputStream> inStream);
+  static bool decodeUserResponseCode(std::shared_ptr<BearerData> bData,
+      std::shared_ptr<BitwiseInputStream> inStream);
+  static bool decodeReplyOption(std::shared_ptr<BearerData> bData,
+      std::shared_ptr<BitwiseInputStream> inStream);
+  static bool decodeMsgCount(std::shared_ptr<BearerData> bData,
+      std::shared_ptr<BitwiseInputStream> inStream);
+  static bool decodeCallbackNumber(std::shared_ptr<BearerData> bData,
+      std::shared_ptr<BitwiseInputStream> inStream);
+  static void decodeSmsAddress(std::shared_ptr<CdmaSmsAddress> addr);
+  static std::string decodeDtmfSmsAddress(std::vector<uint8_t> rawData,
+      int numFields);
+  static bool decodeMsgStatus(std::shared_ptr<BearerData> bData,
+      std::shared_ptr<BitwiseInputStream> inStream);
+  static bool decodeMsgCenterTimeStamp(std::shared_ptr<BearerData> bData,
+      std::shared_ptr<BitwiseInputStream> inStream);
+  static bool decodeValidityAbs(std::shared_ptr<BearerData> bData,
+      std::shared_ptr<BitwiseInputStream> inStream);
+  static bool decodeValidityRel(std::shared_ptr<BearerData> bData,
+      std::shared_ptr<BitwiseInputStream> inStream);
+  static bool decodeDeferredDeliveryAbs(std::shared_ptr<BearerData> bData,
+      std::shared_ptr<BitwiseInputStream> inStream);
+  static bool decodeDeferredDeliveryRel(std::shared_ptr<BearerData> bData,
+      std::shared_ptr<BitwiseInputStream> inStream);
+  static bool decodePrivacyIndicator(std::shared_ptr<BearerData> bData,
+      std::shared_ptr<BitwiseInputStream> inStream);
+  static bool decodeLanguageIndicator(std::shared_ptr<BearerData> bData,
+      std::shared_ptr<BitwiseInputStream> inStream);
+  static bool decodeDisplayMode(std::shared_ptr<BearerData> bData,
+      std::shared_ptr<BitwiseInputStream> inStream);
+  static bool decodePriorityIndicator(std::shared_ptr<BearerData> bData,
+      std::shared_ptr<BitwiseInputStream> inStream);
+  static bool decodeMsgDeliveryAlert(std::shared_ptr<BearerData> bData,
+      std::shared_ptr<BitwiseInputStream> inStream);
+  static bool decodeDepositIndex(std::shared_ptr<BearerData> bData,
+      std::shared_ptr<BitwiseInputStream> inStream);
+  static bool decodeServiceCategoryProgramData(
+      std::shared_ptr<BearerData> bData,
+      std::shared_ptr<BitwiseInputStream> inStream);
+  static void decodeUserDataPayload(std::shared_ptr<UserData> userData,
+      bool hasUserDataHeader);
+  static int getBitsForNumFields(int msgEncoding, int numFields);
+  static std::string decode7bitAscii(std::vector<uint8_t> data, int offset,
+      int numFields);
+  static std::string decode7bitGsm(std::vector<uint8_t> data, int offset,
+      int numFields);
+  static std::string decodeGsmDcs(std::vector<uint8_t> data, int offset,
+      int numFields, int msgType);
+  static bool decodeReserved(std::shared_ptr<BearerData> bData,
+      std::shared_ptr<BitwiseInputStream> inStream, int subparamId);
+  static bool isCmasAlertCategory(int category);
+  static void decodeCmasUserData(std::shared_ptr<BearerData> bData,
+      int serviceCategory);
+  static int serviceCategoryToCmasMessageClass(int serviceCategory);
+  static void decodeIs91(std::shared_ptr<BearerData> bData);
+  static void decodeIs91VoicemailStatus(std::shared_ptr<BearerData> bData);
+  static void decodeIs91Cli(std::shared_ptr<BearerData> bData);
+  static void decodeIs91ShortMessage(std::shared_ptr<BearerData> bData);
+  static std::string decodeLatin(std::vector<uint8_t> data, int offset, int numFields);
+  static std::string decodeUtf16(std::vector<uint8_t> data, int offset, int numFields);
+  static std::string decodeUtf8(std::vector<uint8_t> data, int offset, int numFields);
+  static std::vector<uint8_t> encode7bitAscii(std::string msgs, bool force);
+  static std::vector<uint8_t> encodeUtf16(std::string msg);
+  static void encodeEmsUserDataPayload(std::shared_ptr<UserData> uData);
+  static void encode7bitEms(std::shared_ptr<UserData> uData, std::vector<uint8_t> udhData, bool force);
+  static void encode16bitEms(std::shared_ptr<UserData> uData, std::vector<uint8_t> udhData);
+  static void encodeOctetEms(std::shared_ptr<UserData> uData, std::vector<uint8_t> udhData);
+  class Gsm7bitCodingResult {
+  public:
+     int septets;
+     std::vector<uint8_t> data;
+  };
+  static BearerData::Gsm7bitCodingResult encode7bitGsm(std::string msg, int septetOffset, bool force);
+};
+
+#endif /* BEARERDATA_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/BitwiseInputStream.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/BitwiseInputStream.cpp
new file mode 100644
index 0000000..9e8d626
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/BitwiseInputStream.cpp
@@ -0,0 +1,99 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include "BitwiseInputStream.h"
+#include <algorithm>
+using namespace std;
+
+BitwiseInputStream::BitwiseInputStream(std::vector<uint8_t> buf) {
+  mBuf = buf;
+  mEnd = buf.size() << 3;
+  mPos = 0;
+
+}
+
+BitwiseInputStream::~BitwiseInputStream() {
+  // TODO Auto-generated destructor stub
+}
+
+int BitwiseInputStream::available() {
+  return mEnd - mPos;
+}
+
+uint32_t BitwiseInputStream::read(uint32_t bits) {
+  uint32_t index = mPos >> 3;
+  uint32_t offset = 16 - (mPos & 0x07) - bits;  // &7==%8
+  if ((bits < 0) || (bits > 8) || ((mPos + bits) > mEnd)) {
+    //TDB
+    return -1;
+  }
+  uint32_t data = (mBuf[index] & 0xFF) << 8;
+  if (offset < 8)
+    data |= mBuf[index + 1] & 0xFF;
+  data >>= offset;
+  data &= (0xFFFFFFFF >> (32 - bits));
+  mPos += bits;
+  return data;
+}
+
+//uint8_t* BitwiseInputStream::readByteArray(uint32_t bits, int* length) {
+//  uint32_t bytes = (bits >> 3) + ((bits & 0x07) > 0 ? 1 : 0);  // &7==%8
+//  uint8_t* arr = new uint8_t[bytes];
+//  for (int i = 0; i < bytes; i++) {
+//    int increment = std::min((uint32_t) 8, bits - (i << 3));
+//    arr[i] = (uint8_t) (read(increment) << (8 - increment));
+//  }
+//  return arr;
+//}
+
+std::vector<uint8_t> BitwiseInputStream::readByteVector(uint32_t bits) {
+  uint32_t bytes = (bits >> 3) + ((bits & 0x07) > 0 ? 1 : 0);  // &7==%8
+  std::vector<uint8_t> arr;
+  //uint8_t* arr = new uint8_t[bytes];
+  for (int i = 0; i < bytes; i++) {
+    int increment = std::min((uint32_t) 8, bits - (i << 3));
+    arr.push_back((uint8_t) (read(increment) << (8 - increment)));
+    //arr[i] = (uint8_t) (read(increment) << (8 - increment));
+  }
+  return arr;
+}
+
+void BitwiseInputStream::skip(uint32_t bits) {
+  if ((mPos + bits) > mEnd) {
+    //TBD log
+    return;
+  }
+  mPos += bits;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/BitwiseInputStream.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/BitwiseInputStream.h
new file mode 100644
index 0000000..b436540
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/BitwiseInputStream.h
@@ -0,0 +1,89 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef BITWISEINPUTSTREAM_H_
+#define BITWISEINPUTSTREAM_H_
+#include <cstdint>
+#include <vector>
+
+class BitwiseInputStream {
+public:
+  BitwiseInputStream(std::vector<uint8_t> buf);
+  virtual ~BitwiseInputStream();
+
+  /**
+   * Return the number of bit still available for reading.
+   */
+  int available();
+
+  /**
+   * Read some data and increment the current position.
+   *
+   * The 8-bit limit on access to bitwise streams is intentional to
+   * avoid endianness issues.
+   *
+   * @param bits the amount of data to read (gte 0, lte 8)
+   * @return byte of read data (possibly partially filled, from lsb)
+   */
+  uint32_t read(uint32_t bits);
+
+  /**
+   * Read data in bulk into a byte array and increment the current position.
+   *
+   * @param bits the amount of data to read
+   * @return newly allocated byte array of read data
+   */
+  //uint8_t* readByteArray(uint32_t bits, int* length);
+  std::vector<uint8_t> readByteVector(uint32_t bits);
+  /**
+   * Increment the current position and ignore contained data.
+   *
+   * @param bits the amount by which to increment the position
+   */
+  void skip(uint32_t bits);
+private:
+  // The byte array being read from.
+  //uint8_t* mBuf;
+  std::vector<uint8_t> mBuf;
+
+  // The current position offset, in bits, from the msb in byte 0.
+  uint32_t mPos;
+
+  // The last valid bit offset.
+  uint32_t mEnd;
+
+};
+
+#endif /* BITWISEINPUTSTREAM_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/BitwiseOutputStream.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/BitwiseOutputStream.cpp
new file mode 100644
index 0000000..5d12dee
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/BitwiseOutputStream.cpp
@@ -0,0 +1,118 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include <cstring>
+#include <algorithm>
+#include "BitwiseOutputStream.h"
+using namespace std;
+
+BitwiseOutputStream::BitwiseOutputStream(int startingLength) {
+  mBuf = new uint8_t[startingLength];
+  memset(mBuf, 0, startingLength * sizeof(uint8_t));
+  mEnd = startingLength << 3;
+  mPos = 0;
+}
+
+uint8_t* BitwiseOutputStream::toByteArray(uint32_t* length) {
+  int len = (mPos >> 3) + ((mPos & 0x07) > 0 ? 1 : 0);  // &7==%8
+  uint8_t* newBuf = new uint8_t[len];
+  memset(newBuf, 0, len * sizeof(uint8_t));
+  memcpy(newBuf, mBuf, len * sizeof(uint8_t));
+  (*length) = len;
+  return newBuf;
+}
+
+std::vector<uint8_t> BitwiseOutputStream::toByteVector() {
+  int len = (mPos >> 3) + ((mPos & 0x07) > 0 ? 1 : 0);  // &7==%8
+  std::vector<uint8_t> v(mBuf, mBuf + len);
+  return v;
+}
+
+void BitwiseOutputStream::possExpand(uint32_t bits) {
+  if ((mPos + bits) < mEnd)
+    return;
+  uint8_t* newBuf = new uint8_t[(mPos + bits) >> 2];
+  memset(newBuf, 0, mEnd >> 3);
+  memcpy(newBuf, mBuf, mEnd >> 3);
+  delete[] mBuf;
+  mBuf = nullptr;
+  mBuf = newBuf;
+  mEnd = (mEnd >> 3) << 3;
+}
+
+void BitwiseOutputStream::write(uint32_t bits, uint32_t data) {
+  if ((bits < 0) || (bits > 8)) {
+    //TBD,log
+    return;
+  }
+  possExpand(bits);
+  data &= (0xFFFFFFFF >> (32 - bits));
+  uint32_t index = mPos >> 3;
+  uint32_t offset = 16 - (mPos & 0x07) - bits;  // &7==%8
+  data <<= offset;
+  mPos += bits;
+  mBuf[index] |= data >> 8;
+  if (offset < 8)
+    mBuf[index + 1] |= data & 0xFF;
+}
+
+void BitwiseOutputStream::writeByteArray(uint32_t bits, uint8_t arr[],
+    uint32_t size) {
+  for (uint32_t i = 0; i < size; i++) {
+    uint32_t increment = std::min((uint32_t) 8, bits - (i << 3));
+    if (increment > 0) {
+      write(increment, (uint8_t) (arr[i] >> (8 - increment)));
+    }
+  }
+}
+
+void BitwiseOutputStream::writeByteVector(uint32_t bits,
+    std::vector<uint8_t> v) {
+  for (uint32_t i = 0; i < v.size(); i++) {
+    uint32_t increment = std::min((uint32_t) 8, bits - (i << 3));
+    if (increment > 0) {
+      write(increment, (uint8_t) (v[i] >> (8 - increment)));
+    }
+  }
+}
+
+void BitwiseOutputStream::skip(uint32_t bits) {
+  possExpand(bits);
+  mPos += bits;
+}
+BitwiseOutputStream::~BitwiseOutputStream() {
+  delete[] mBuf;
+  mBuf = nullptr;
+}
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/BitwiseOutputStream.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/BitwiseOutputStream.h
new file mode 100644
index 0000000..b30910a
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/BitwiseOutputStream.h
@@ -0,0 +1,58 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef BITWISEOUTPUTSTREAM_H_
+#define BITWISEOUTPUTSTREAM_H_
+
+#include <cstdint>
+#include <vector>
+class BitwiseOutputStream {
+public:
+  BitwiseOutputStream(int startingLength);
+  virtual ~BitwiseOutputStream();
+  uint8_t* toByteArray(uint32_t* length);
+  void write(uint32_t bits, uint32_t data);
+  std::vector<uint8_t> toByteVector();
+  void writeByteArray(uint32_t bits, uint8_t arr[], uint32_t size);
+  void writeByteVector(uint32_t bits, std::vector<uint8_t> v);
+  void skip(uint32_t bits);
+private:
+  uint8_t* mBuf;
+  uint32_t mPos;
+  uint32_t mEnd;
+  void possExpand(uint32_t bits);
+};
+
+#endif /* BITWISEOUTPUTSTREAM_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/CdmaSmsAddress.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/CdmaSmsAddress.cpp
new file mode 100644
index 0000000..67eeb86
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/CdmaSmsAddress.cpp
@@ -0,0 +1,195 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include <string>
+#include <memory>
+#include <iostream>
+#include <vector>
+using namespace std;
+#include "CdmaSmsAddress.h"
+#include "UserData.h"
+#include "HexDump.h"
+
+const char CdmaSmsAddress::numericCharsDialable[] = { '0', '1', '2', '3', '4',
+    '5', '6', '7', '8', '9', '*', '#' };
+const char CdmaSmsAddress::numericCharsSugar[] = { '(', ')', ' ', '-', '+', '.',
+    '/', '\\' };
+std::map<char, bool> CdmaSmsAddress::numericCharDialableMap(
+    CdmaSmsAddress::init());
+
+CdmaSmsAddress::CdmaSmsAddress() {
+  // TODO Auto-generated constructor stub
+
+}
+
+CdmaSmsAddress::~CdmaSmsAddress() {
+  // TODO Auto-generated destructor stub
+}
+
+//free memory
+std::vector<uint8_t> CdmaSmsAddress::parseToDtmf(string address) {
+  int digits = address.length();
+  std::vector<uint8_t> result;
+  for (int i = 0; i < digits; i++) {
+    char c = address[i];
+    uint8_t val = 0;
+    if ((c >= '1') && (c <= '9'))
+      val = c - '0';
+    else if (c == '0')
+      val = 10;
+    else if (c == '*')
+      val = 11;
+    else if (c == '#')
+      val = 12;
+    else
+      return result;
+
+    result.push_back((uint8_t) val);
+  }
+  return result;
+}
+
+std::map<char, bool> CdmaSmsAddress::init() {
+  std::map<char, bool> tmp;
+  int disable_length = sizeof(numericCharsDialable) / sizeof(char);
+  int suger_length = sizeof(numericCharsSugar) / sizeof(char);
+  for (int i = 0; i < disable_length; i++) {
+    tmp.insert(pair<char, bool>(numericCharsDialable[i], true));
+  }
+  for (int i = 0; i < suger_length; i++) {
+    tmp.insert(pair<char, bool>(numericCharsSugar[i], false));
+  }
+  return tmp;
+}
+
+std::string CdmaSmsAddress::filterNumericSugar(std::string address) {
+  string builder;
+  int len = address.length();
+  for (int i = 0; i < len; i++) {
+    char c = address[i];
+    std::map<char, bool>::iterator it = numericCharDialableMap.find(c);
+    if (it == numericCharDialableMap.end())
+      return nullptr;
+    if (!numericCharDialableMap.at(c))
+      continue;
+    builder.push_back(c);
+  }
+  return builder;
+}
+
+std::string CdmaSmsAddress::filterWhitespace(std::string address) {
+  string builder = nullptr;
+  int len = address.length();
+  for (int i = 0; i < len; i++) {
+    char c = address[i];
+    if ((c == ' ') || (c == '\r') || (c == '\n') || (c == '\t'))
+      continue;
+    builder.push_back(c);
+  }
+  return builder;
+}
+
+std::shared_ptr<CdmaSmsAddress> CdmaSmsAddress::parse(char* adr) {
+  shared_ptr<CdmaSmsAddress> addr = make_shared<CdmaSmsAddress>();
+  string address(adr);
+  addr->address = address;
+  addr->ton = TON_UNKNOWN;
+  addr->digitMode = DIGIT_MODE_4BIT_DTMF;
+  addr->numberPlan = NUMBERING_PLAN_UNKNOWN;
+  addr->numberMode = NUMBER_MODE_NOT_DATA_NETWORK;
+
+  //uint8_t* origBytes = nullptr;
+  //int origBytes_len = 0;
+  std::vector<uint8_t> origBytes;
+  string filteredAddr = filterNumericSugar(address);
+  if ((address.find("+") != string::npos) || filteredAddr.empty()) {
+    // 3GPP2 C.S0015-B section 3.4.3.3 Address Parameters
+    // NUMBER_MODE should set to 1 for network address and email address.
+    addr->digitMode = DIGIT_MODE_8BIT_CHAR;
+    addr->numberMode = NUMBER_MODE_DATA_NETWORK;
+    filteredAddr = filterWhitespace(address);
+
+    if (address.find("@") != string::npos) {
+      // This is an email address
+      addr->ton = TON_NATIONAL_OR_EMAIL;
+    } else if ((address.find("+") != string::npos)
+        && (!(filterNumericSugar(address)).empty())) {
+      // This is an international number
+      // 3GPP2 C.S0015-B section 3.4.3.3 Address Parameters
+      // digit mode is set to 1 and number mode is set to 0, type of number should set
+      // to the value correspond to the value in 3GPP2 C.S005-D, table2.7.1.3.2.4-2
+      addr->ton = TON_INTERNATIONAL_OR_IP;
+      addr->numberPlan = NUMBERING_PLAN_ISDN_TELEPHONY;
+      addr->numberMode = NUMBER_MODE_NOT_DATA_NETWORK;
+      filteredAddr = filterNumericSugar(address);
+    }
+
+    origBytes = UserData::stringToAscii(filteredAddr);
+  } else {
+    // The address is not an international number and it only contains digit and *#
+    origBytes = parseToDtmf(filteredAddr);
+    //std::cout << "sms address: " << origBytes.size() << std::endl;
+    string str1 = HexDump::toHexString(origBytes);
+    //std::cout << "sms address: " << str1 << endl;
+  }
+
+  if (origBytes.empty()) {
+    return nullptr;
+  }
+
+  addr->origBytes = origBytes;
+  addr->numberOfDigits = origBytes.size();
+  return addr;
+}
+
+std::string CdmaSmsAddress::toString() {
+  string builder;
+  builder.append("CdmaSmsAddress ");
+  builder.append("{ digitMode=");
+  builder.append(std::to_string(digitMode));
+  builder.append(", numberMode=");
+  builder.append(std::to_string(numberMode));
+  builder.append(", numberPlan=");
+  builder.append(std::to_string(numberPlan));
+  builder.append(", numberOfDigits=");
+  builder.append(std::to_string(numberOfDigits));
+  builder.append(", ton=");
+  builder.append(std::to_string(ton));
+  builder.append(", address=\"" + address + string("\""));
+  std::cout << "[EVENT][MT_CDMA_SMS]PDU decode: phone number: " << address << " ";
+  builder.append(", origBytes=" + HexDump::toHexString(origBytes));
+  builder.append(" }");
+  return builder;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/CdmaSmsAddress.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/CdmaSmsAddress.h
new file mode 100644
index 0000000..8e1c2c2
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/CdmaSmsAddress.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CDMASMSADDRESS_H_
+#define CDMASMSADDRESS_H_
+#include <map>
+#include <string>
+#include <memory>
+#include "SmsAddress.h"
+
+class CdmaSmsAddress: public SmsAddress {
+public:
+  CdmaSmsAddress();
+  virtual ~CdmaSmsAddress();
+
+  /**
+   * Digit Mode Indicator is a 1-bit value that indicates whether
+   * the address digits are 4-bit DTMF codes or 8-bit codes.  (See
+   * 3GPP2 C.S0015-B, v2, 3.4.3.3)
+   */
+  static constexpr int DIGIT_MODE_4BIT_DTMF = 0x00;
+  static constexpr int DIGIT_MODE_8BIT_CHAR = 0x01;
+
+  int digitMode = -1;
+
+  /**
+   * Number Mode Indicator is 1-bit value that indicates whether the
+   * address type is a data network address or not.  (See 3GPP2
+   * C.S0015-B, v2, 3.4.3.3)
+   */
+  static constexpr int NUMBER_MODE_NOT_DATA_NETWORK = 0x00;
+  static constexpr int NUMBER_MODE_DATA_NETWORK = 0x01;
+
+  int numberMode = -1;
+
+  /**
+   * Number Types for data networks.
+   * (See 3GPP2 C.S005-D, table2.7.1.3.2.4-2 for complete table)
+   * (See 3GPP2 C.S0015-B, v2, 3.4.3.3 for data network subset)
+   * NOTE: value is stored in the parent class ton field.
+   */
+  static constexpr int TON_UNKNOWN = 0x00;
+  static constexpr int TON_INTERNATIONAL_OR_IP = 0x01;
+  static constexpr int TON_NATIONAL_OR_EMAIL = 0x02;
+  static constexpr int TON_NETWORK = 0x03;
+  static constexpr int TON_SUBSCRIBER = 0x04;
+  static constexpr int TON_ALPHANUMERIC = 0x05;
+  static constexpr int TON_ABBREVIATED = 0x06;
+  static constexpr int TON_RESERVED = 0x07;
+
+  /**
+   * Maximum lengths for fields as defined in ril_cdma_sms.h.
+   */
+  static constexpr int SMS_ADDRESS_MAX = 36;
+  static constexpr int SMS_SUBADDRESS_MAX = 36;
+
+  /**
+   * This field shall be set to the number of address digits
+   * (See 3GPP2 C.S0015-B, v2, 3.4.3.3)
+   */
+  int numberOfDigits = -1;
+
+  /**
+   * Numbering Plan identification is a 0 or 4-bit value that
+   * indicates which numbering plan identification is set.  (See
+   * 3GPP2, C.S0015-B, v2, 3.4.3.3 and C.S005-D, table2.7.1.3.2.4-3)
+   */
+  static constexpr int NUMBERING_PLAN_UNKNOWN = 0x0;
+  static constexpr int NUMBERING_PLAN_ISDN_TELEPHONY = 0x1;
+  //static protected final int NUMBERING_PLAN_DATA              = 0x3;
+  //static protected final int NUMBERING_PLAN_TELEX             = 0x4;
+  //static protected final int NUMBERING_PLAN_PRIVATE           = 0x9;
+
+  int numberPlan = -1;
+  static std::vector<uint8_t> parseToDtmf(std::string address);
+  static std::shared_ptr<CdmaSmsAddress> parse(char* adr);
+  std::string toString();
+private:
+  static const char numericCharsDialable[];
+
+  static const char numericCharsSugar[];
+
+  static std::map<char, bool> numericCharDialableMap;
+  static std::map<char, bool> init();
+  static std::string filterNumericSugar(std::string address);
+  static std::string filterWhitespace(std::string address);
+
+};
+#endif /* CDMASMSADDRESS_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/CdmaSmsCbProgramData.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/CdmaSmsCbProgramData.cpp
new file mode 100644
index 0000000..fa1936c
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/CdmaSmsCbProgramData.cpp
@@ -0,0 +1,95 @@
+ /*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "CdmaSmsCbProgramData.h"
+
+CdmaSmsCbProgramData::CdmaSmsCbProgramData(int operation, int category,
+    int language, int maxMessages, int alertOption, std::string categoryName) {
+  mOperation = operation;
+  mCategory = category;
+  mLanguage = language;
+  mMaxMessages = maxMessages;
+  mAlertOption = alertOption;
+  mCategoryName = categoryName;
+}
+
+CdmaSmsCbProgramData::~CdmaSmsCbProgramData() {
+  // TODO Auto-generated destructor stub
+}
+
+/**
+ * Returns the service category operation, e.g. {@link #OPERATION_ADD_CATEGORY}.
+ * @return one of the {@code OPERATION_*} values
+ */
+int CdmaSmsCbProgramData::getOperation() {
+  return mOperation;
+}
+
+/**
+ * Returns the CDMA service category to modify.
+ * @return a 16-bit CDMA service category value
+ */
+int CdmaSmsCbProgramData::getCategory() {
+  return mCategory;
+}
+
+/**
+ * Returns the CDMA language code for this service category.
+ * @return one of the language values defined in BearerData.LANGUAGE_*
+ */
+int CdmaSmsCbProgramData::getLanguage() {
+  return mLanguage;
+}
+
+/**
+ * Returns the maximum number of messages to store for this service category.
+ * @return the maximum number of messages to store for this service category
+ */
+int CdmaSmsCbProgramData::getMaxMessages() {
+  return mMaxMessages;
+}
+
+/**
+ * Returns the service category alert option, e.g. {@link #ALERT_OPTION_DEFAULT_ALERT}.
+ * @return one of the {@code ALERT_OPTION_*} values
+ */
+int CdmaSmsCbProgramData::getAlertOption() {
+  return mAlertOption;
+}
+
+/**
+ * Returns the service category name, in the language specified by {@link #getLanguage()}.
+ * @return an optional service category name
+ */
+std::string CdmaSmsCbProgramData::getCategoryName() {
+  return mCategoryName;
+}
+
+std::string CdmaSmsCbProgramData::toString() {
+  return "CdmaSmsCbProgramData{operation=" + std::to_string(mOperation)
+      + ", category=" + std::to_string(mCategory) + ", language="
+      + std::to_string(mLanguage) + ", max messages="
+      + std::to_string(mMaxMessages) + ", alert option="
+      + std::to_string(mAlertOption) + ", category name=" + mCategoryName + "}";
+}
+
+/**
+ * Describe the kinds of special objects contained in the marshalled representation.
+ * @return a bitmask indicating this Parcelable contains no special objects
+ */
+int CdmaSmsCbProgramData::describeContents() {
+  return 0;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/CdmaSmsCbProgramData.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/CdmaSmsCbProgramData.h
new file mode 100644
index 0000000..22dfb14
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/CdmaSmsCbProgramData.h
@@ -0,0 +1,135 @@
+ /*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CDMASMSCBPROGRAMDATA_H_
+#define CDMASMSCBPROGRAMDATA_H_
+#include <string>
+
+class CdmaSmsCbProgramData {
+public:
+  CdmaSmsCbProgramData(int operation, int category, int language,
+      int maxMessages, int alertOption, std::string categoryName);
+  virtual ~CdmaSmsCbProgramData();
+
+  /** Delete the specified service category from the list of enabled categories. */
+  static constexpr int OPERATION_DELETE_CATEGORY = 0;
+
+  /** Add the specified service category to the list of enabled categories. */
+  static constexpr int OPERATION_ADD_CATEGORY = 1;
+
+  /** Clear all service categories from the list of enabled categories. */
+  static constexpr int OPERATION_CLEAR_CATEGORIES = 2;
+
+  /** Alert option: no alert. */
+  static constexpr int ALERT_OPTION_NO_ALERT = 0;
+
+  /** Alert option: default alert. */
+  static constexpr int ALERT_OPTION_DEFAULT_ALERT = 1;
+
+  /** Alert option: vibrate alert once. */
+  static constexpr int ALERT_OPTION_VIBRATE_ONCE = 2;
+
+  /** Alert option: vibrate alert - repeat. */
+  static constexpr int ALERT_OPTION_VIBRATE_REPEAT = 3;
+
+  /** Alert option: visual alert once. */
+  static constexpr int ALERT_OPTION_VISUAL_ONCE = 4;
+
+  /** Alert option: visual alert - repeat. */
+  static constexpr int ALERT_OPTION_VISUAL_REPEAT = 5;
+
+  /** Alert option: low-priority alert once. */
+  static constexpr int ALERT_OPTION_LOW_PRIORITY_ONCE = 6;
+
+  /** Alert option: low-priority alert - repeat. */
+  static constexpr int ALERT_OPTION_LOW_PRIORITY_REPEAT = 7;
+
+  /** Alert option: medium-priority alert once. */
+  static constexpr int ALERT_OPTION_MED_PRIORITY_ONCE = 8;
+
+  /** Alert option: medium-priority alert - repeat. */
+  static constexpr int ALERT_OPTION_MED_PRIORITY_REPEAT = 9;
+
+  /** Alert option: high-priority alert once. */
+  static constexpr int ALERT_OPTION_HIGH_PRIORITY_ONCE = 10;
+
+  /** Alert option: high-priority alert - repeat. */
+  static constexpr int ALERT_OPTION_HIGH_PRIORITY_REPEAT = 11;
+  /**
+   * Returns the service category operation, e.g. {@link #OPERATION_ADD_CATEGORY}.
+   * @return one of the {@code OPERATION_*} values
+   */
+  int getOperation();
+
+  /**
+   * Returns the CDMA service category to modify.
+   * @return a 16-bit CDMA service category value
+   */
+  int getCategory();
+
+  /**
+   * Returns the CDMA language code for this service category.
+   * @return one of the language values defined in BearerData.LANGUAGE_*
+   */
+  int getLanguage();
+
+  /**
+   * Returns the maximum number of messages to store for this service category.
+   * @return the maximum number of messages to store for this service category
+   */
+  int getMaxMessages();
+
+  /**
+   * Returns the service category alert option, e.g. {@link #ALERT_OPTION_DEFAULT_ALERT}.
+   * @return one of the {@code ALERT_OPTION_*} values
+   */
+  int getAlertOption();
+
+  /**
+   * Returns the service category name, in the language specified by {@link #getLanguage()}.
+   * @return an optional service category name
+   */
+  std::string getCategoryName();
+
+  std::string toString();
+
+  /**
+   * Describe the kinds of special objects contained in the marshalled representation.
+   * @return a bitmask indicating this Parcelable contains no special objects
+   */
+  int describeContents();
+
+private:
+  /** Service category operation (add/delete/clear). */
+  int mOperation;
+
+  /** Service category to modify. */
+  int mCategory;
+
+  /** Language used for service category name (defined in BearerData.LANGUAGE_*). */
+  int mLanguage;
+
+  /** Maximum number of messages to store for this service category. */
+  int mMaxMessages;
+
+  /** Service category alert option. */
+  int mAlertOption;
+
+  /** Name of service category. */
+  std::string mCategoryName;
+};
+
+#endif /* CDMASMSCBPROGRAMDATA_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/CdmaSmsSubaddress.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/CdmaSmsSubaddress.cpp
new file mode 100644
index 0000000..9b4bb94
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/CdmaSmsSubaddress.cpp
@@ -0,0 +1,46 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include "CdmaSmsSubaddress.h"
+
+CdmaSmsSubaddress::CdmaSmsSubaddress() {
+  // TODO Auto-generated constructor stub
+
+}
+
+CdmaSmsSubaddress::~CdmaSmsSubaddress() {
+  // TODO Auto-generated destructor stub
+}
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/CdmaSmsSubaddress.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/CdmaSmsSubaddress.h
new file mode 100644
index 0000000..a21d29c
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/CdmaSmsSubaddress.h
@@ -0,0 +1,53 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef CDMASMSSUBADDRESS_H_
+#define CDMASMSSUBADDRESS_H_
+#include <cstdint>
+#include <vector>
+class CdmaSmsSubaddress {
+public:
+  CdmaSmsSubaddress();
+  virtual ~CdmaSmsSubaddress();
+  int type = -1;
+
+  uint8_t odd = 0;
+
+  //uint8_t* origBytes = nullptr;
+  //uint8_t origBytes_length = 0;
+  std::vector<uint8_t> origBytes;
+};
+
+#endif /* CDMASMSSUBADDRESS_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/GsmAlphabet.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/GsmAlphabet.cpp
new file mode 100644
index 0000000..d2f29b8
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/GsmAlphabet.cpp
@@ -0,0 +1,672 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <memory>
+#include <map>
+#include <string>
+#include <stdexcept>
+#include <iostream>
+using namespace std;
+
+#include "GsmAlphabet.h"
+const std::vector<std::shared_ptr<std::map<char, int>>> GsmAlphabet::sCharsToGsmTables =
+    GsmAlphabet::initCharsToGsmTables();
+const std::vector<std::shared_ptr<std::map<char, int>>> GsmAlphabet::sCharsToShiftTables =
+    GsmAlphabet::initCharsToShiftTables();
+
+std::vector<std::shared_ptr<std::map<char, int>>> GsmAlphabet::initCharsToGsmTables() {
+  std::vector<std::shared_ptr<std::map<char, int>>> temp;
+  int numTables = sLanguageTables.size();
+  int numShiftTables = sLanguageShiftTables.size();
+  if (numTables != numShiftTables) {
+//      Rlog.e(TAG, "Error: language tables array length " + numTables +
+//              " != shift tables array length " + numShiftTables);
+  }
+
+  //sCharsToGsmTables = new SparseIntArray[numTables];
+  for (int i = 0; i < numTables; i++) {
+    std::string table = sLanguageTables[i];
+
+    int tableLen = table.length();
+    if (tableLen != 0 && tableLen != 128) {
+      /*          Rlog.e(TAG, "Error: language tables index " + i +
+       " length " + tableLen + " (expected 128 or 0)");*/
+    }
+
+    auto charToGsmTable = make_shared<std::map<char, int>>();
+    //sCharsToGsmTables[i] = charToGsmTable;
+    for (int j = 0; j < tableLen; j++) {
+      char c = table.at(j);
+      charToGsmTable->insert(std::pair<char, int>(c, j));
+    }
+    temp.push_back(charToGsmTable);
+  }
+  return temp;
+}
+
+std::vector<std::shared_ptr<std::map<char, int>>> GsmAlphabet::initCharsToShiftTables() {
+  std::vector<std::shared_ptr<std::map<char, int>>> temp;
+  int numTables = sLanguageTables.size();
+  int numShiftTables = sLanguageShiftTables.size();
+  if (numTables != numShiftTables) {
+//      Rlog.e(TAG, "Error: language tables array length " + numTables +
+//              " != shift tables array length " + numShiftTables);
+  }
+  for (int i = 0; i < numShiftTables; i++) {
+    string shiftTable = sLanguageShiftTables[i];
+
+    int shiftTableLen = shiftTable.length();
+    if (shiftTableLen != 0 && shiftTableLen != 128) {
+//          Rlog.e(TAG, "Error: language shift tables index " + i +
+//                  " length " + shiftTableLen + " (expected 128 or 0)");
+    }
+
+    auto charToShiftTable = make_shared<std::map<char, int>>();
+    for (int j = 0; j < shiftTableLen; j++) {
+      char c = shiftTable.at(j);
+      if (c != ' ') {
+        charToShiftTable->insert(std::pair<char, int>(c, j));
+      }
+    }
+    temp.push_back(charToShiftTable);
+  }
+  return temp;
+}
+
+std::string GsmAlphabet::gsm7BitPackedToString(std::vector<uint8_t> pdu,
+    int offset, int lengthSeptets, int numPaddingBits, int languageTable,
+    int shiftTable) {
+  string ret;
+
+  if (languageTable < 0 || languageTable > sLanguageTables.size()) {
+    // Rlog.w(TAG, "unknown language table " + languageTable + ", using default");
+    languageTable = 0;
+  }
+  if (shiftTable < 0 || shiftTable > sLanguageShiftTables.size()) {
+    //Rlog.w(TAG, "unknown single shift table " + shiftTable + ", using default");
+    shiftTable = 0;
+  }
+
+  try {
+    bool prevCharWasEscape = false;
+    string languageTableToChar = sLanguageTables[languageTable];
+    string shiftTableToChar = sLanguageShiftTables[shiftTable];
+
+    if (languageTableToChar.empty()) {
+      //Rlog.w(TAG, "no language table for code " + languageTable + ", using default");
+      languageTableToChar = sLanguageTables[0];
+    }
+    if (shiftTableToChar.empty()) {
+      //Rlog.w(TAG, "no single shift table for code " + shiftTable + ", using default");
+      shiftTableToChar = sLanguageShiftTables[0];
+    }
+
+    for (int i = 0; i < lengthSeptets; i++) {
+      int bitOffset = (7 * i) + numPaddingBits;
+
+      int byteOffset = bitOffset / 8;
+      int shift = bitOffset % 8;
+      int gsmVal;
+
+      gsmVal = (0x7f & (pdu[offset + byteOffset] >> shift));
+
+      // if it crosses a byte boundary
+      if (shift > 1) {
+        // set msb bits to 0
+        gsmVal &= 0x7f >> (shift - 1);
+
+        gsmVal |= 0x7f & (pdu[offset + byteOffset + 1] << (8 - shift));
+      }
+
+      if (prevCharWasEscape) {
+        if (gsmVal == GSM_EXTENDED_ESCAPE) {
+          ret.push_back(' '); // display ' ' for reserved double escape sequence
+        } else {
+          char c = shiftTableToChar.at(gsmVal);
+          if (c == ' ') {
+            ret.push_back(languageTableToChar.at(gsmVal));
+          } else {
+            ret.push_back(c);
+          }
+        }
+        prevCharWasEscape = false;
+      } else if (gsmVal == GSM_EXTENDED_ESCAPE) {
+        prevCharWasEscape = true;
+      } else {
+        ret.push_back(languageTableToChar.at(gsmVal));
+      }
+    }
+  } catch (runtime_error& ex) {
+    //Rlog.e(TAG, "Error GSM 7 bit packed: ", ex);
+    return nullptr;
+  }
+
+  return ret;
+}
+
+/** Highest language code to include in array of single shift counters. */
+int GsmAlphabet::sHighestEnabledSingleShiftCode = 0;
+
+/** Flag to bypass check for country-specific overlays (for test cases only). */
+bool GsmAlphabet::sDisableCountryEncodingCheck = false;
+std::vector<std::string> GsmAlphabet::sLanguageShiftTables =
+    {
+        /* 6.2.1.1 GSM 7 bit Default Alphabet Extension Table
+         0123456789A.....BCDEF0123456789ABCDEF0123456789ABCDEF.0123456789ABCDEF0123456789ABCDEF */
+        string(
+            "          \u000c         ^                   {}     \\            [~] |               ")
+        // 0123456789ABCDEF012345.....6789ABCDEF0123456789ABCDEF
+            + string("                     \u20ac                          "),
+
+        /* A.2.1 Turkish National Language Single Shift Table
+         0123456789A.....BCDEF0123456789ABCDEF0123456789ABCDEF.0123456789ABCDEF01234567.....8 */
+        string(
+            "          \u000c         ^                   {}     \\            [~] |      \u011e ")
+        // 9.....ABCDEF0123.....456789ABCDEF0123.....45.....67.....89.....ABCDEF0123.....
+            + string(
+                "\u0130         \u015e               \u00e7 \u20ac \u011f \u0131         \u015f")
+            // 456789ABCDEF
+            + string("            "),
+
+        /* A.2.2 Spanish National Language Single Shift Table
+         0123456789.....A.....BCDEF0123456789ABCDEF0123456789ABCDEF.0123456789ABCDEF01.....23 */
+        string(
+            "         \u00e7\u000c         ^                   {}     \\            [~] |\u00c1  ")
+        // 456789.....ABCDEF.....012345.....6789ABCDEF01.....2345.....6789.....ABCDEF.....012
+            + string(
+                "     \u00cd     \u00d3     \u00da           \u00e1   \u20ac   \u00ed     \u00f3   ")
+            // 345.....6789ABCDEF
+            + string("  \u00fa          "),
+
+        /* A.2.3 Portuguese National Language Single Shift Table
+         012345.....6789.....A.....B.....C.....DE.....F.....012.....3.....45.....6.....7.....8....*/
+        string(
+            "     \u00ea   \u00e7\u000c\u00d4\u00f4 \u00c1\u00e1  \u03a6\u0393^\u03a9\u03a0\u03a8\u03a3")
+        // 9.....ABCDEF.....0123456789ABCDEF.0123456789ABCDEF01.....23456789.....ABCDE
+            + string(
+                "\u0398     \u00ca        {}     \\            [~] |\u00c0       \u00cd     ")
+            // F.....012345.....6789AB.....C.....DEF01.....2345.....6789.....ABCDEF.....01234
+            + string(
+                "\u00d3     \u00da     \u00c3\u00d5    \u00c2   \u20ac   \u00ed     \u00f3     ")
+            // 5.....6789AB.....C.....DEF.....
+            + string("\u00fa     \u00e3\u00f5  \u00e2"),
+
+        /* A.2.4 Bengali National Language Single Shift Table
+         01.....23.....4.....5.6.....789A.....BCDEF0123.....45.....6789.....A.....BC.....D..... */
+        string(
+            "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+ -/<=>\u00a1^\u00a1_#*\u09e6\u09e7 \u09e8\u09e9")
+        // E.....F.....0.....1.....2.....3.....4.....5.....6.....7.....89A.....B.....C.....
+            + string(
+                "\u09ea\u09eb\u09ec\u09ed\u09ee\u09ef\u09df\u09e0\u09e1\u09e2{}\u09e3\u09f2\u09f3")
+            // D.....E.....F.0.....1.....2.....3.....4.....56789ABCDEF0123456789ABCDEF
+            + string(
+                "\u09f4\u09f5\\\u09f6\u09f7\u09f8\u09f9\u09fa       [~] |ABCDEFGHIJKLMNO")
+            // 0123456789ABCDEF012345.....6789ABCDEF0123456789ABCDEF
+            + string("PQRSTUVWXYZ          \u20ac                          "),
+
+        /* A.2.5 Gujarati National Language Single Shift Table
+         01.....23.....4.....5.6.....789A.....BCDEF0123.....45.....6789.....A.....BC.....D..... */
+        string(
+            "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+ -/<=>\u00a1^\u00a1_#*\u0964\u0965 \u0ae6\u0ae7")
+        // E.....F.....0.....1.....2.....3.....4.....5.....6789ABCDEF.0123456789ABCDEF
+            + string(
+                "\u0ae8\u0ae9\u0aea\u0aeb\u0aec\u0aed\u0aee\u0aef  {}     \\            [~] ")
+            // 0123456789ABCDEF0123456789ABCDEF012345.....6789ABCDEF0123456789ABCDEF
+            + string(
+                "|ABCDEFGHIJKLMNOPQRSTUVWXYZ          \u20ac                          "),
+
+        /* A.2.6 Hindi National Language Single Shift Table
+         01.....23.....4.....5.6.....789A.....BCDEF0123.....45.....6789.....A.....BC.....D..... */
+        string(
+            "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+ -/<=>\u00a1^\u00a1_#*\u0964\u0965 \u0966\u0967")
+        // E.....F.....0.....1.....2.....3.....4.....5.....6.....7.....89A.....B.....C.....
+            + string(
+                "\u0968\u0969\u096a\u096b\u096c\u096d\u096e\u096f\u0951\u0952{}\u0953\u0954\u0958")
+            // D.....E.....F.0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.....
+            + string(
+                "\u0959\u095a\\\u095b\u095c\u095d\u095e\u095f\u0960\u0961\u0962\u0963\u0970\u0971")
+            // BCDEF0123456789ABCDEF0123456789ABCDEF012345.....6789ABCDEF0123456789ABCDEF
+            + string(
+                " [~] |ABCDEFGHIJKLMNOPQRSTUVWXYZ          \u20ac                          "),
+
+        /* A.2.7 Kannada National Language Single Shift Table
+         01.....23.....4.....5.6.....789A.....BCDEF0123.....45.....6789.....A.....BC.....D..... */
+        string(
+            "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+ -/<=>\u00a1^\u00a1_#*\u0964\u0965 \u0ce6\u0ce7")
+        // E.....F.....0.....1.....2.....3.....4.....5.....6.....7.....89A.....BCDEF.01234567
+            + string(
+                "\u0ce8\u0ce9\u0cea\u0ceb\u0cec\u0ced\u0cee\u0cef\u0cde\u0cf1{}\u0cf2    \\        ")
+            // 89ABCDEF0123456789ABCDEF0123456789ABCDEF012345.....6789ABCDEF0123456789ABCDEF
+            + string(
+                "    [~] |ABCDEFGHIJKLMNOPQRSTUVWXYZ          \u20ac                          "),
+
+        /* A.2.8 Malayalam National Language Single Shift Table
+         01.....23.....4.....5.6.....789A.....BCDEF0123.....45.....6789.....A.....BC.....D..... */
+        string(
+            "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+ -/<=>\u00a1^\u00a1_#*\u0964\u0965 \u0d66\u0d67")
+        // E.....F.....0.....1.....2.....3.....4.....5.....6.....7.....89A.....B.....C.....
+            + string(
+                "\u0d68\u0d69\u0d6a\u0d6b\u0d6c\u0d6d\u0d6e\u0d6f\u0d70\u0d71{}\u0d72\u0d73\u0d74")
+            // D.....E.....F.0.....1.....2.....3.....4.....56789ABCDEF0123456789ABCDEF0123456789A
+            + string(
+                "\u0d75\u0d7a\\\u0d7b\u0d7c\u0d7d\u0d7e\u0d7f       [~] |ABCDEFGHIJKLMNOPQRSTUVWXYZ")
+            // BCDEF012345.....6789ABCDEF0123456789ABCDEF
+            + string("          \u20ac                          "),
+
+        /* A.2.9 Oriya National Language Single Shift Table
+         01.....23.....4.....5.6.....789A.....BCDEF0123.....45.....6789.....A.....BC.....D..... */
+        string(
+            "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+ -/<=>\u00a1^\u00a1_#*\u0964\u0965 \u0b66\u0b67")
+        // E.....F.....0.....1.....2.....3.....4.....5.....6.....7.....89A.....B.....C.....DE
+            + string(
+                "\u0b68\u0b69\u0b6a\u0b6b\u0b6c\u0b6d\u0b6e\u0b6f\u0b5c\u0b5d{}\u0b5f\u0b70\u0b71  ")
+            // F.0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF012345.....6789ABCDEF0123456789A
+            + string(
+                "\\            [~] |ABCDEFGHIJKLMNOPQRSTUVWXYZ          \u20ac                     ")
+            // BCDEF
+            + string("     "),
+
+        /* A.2.10 Punjabi National Language Single Shift Table
+         01.....23.....4.....5.6.....789A.....BCDEF0123.....45.....6789.....A.....BC.....D..... */
+        string(
+            "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+ -/<=>\u00a1^\u00a1_#*\u0964\u0965 \u0a66\u0a67")
+        // E.....F.....0.....1.....2.....3.....4.....5.....6.....7.....89A.....B.....C.....
+            + string(
+                "\u0a68\u0a69\u0a6a\u0a6b\u0a6c\u0a6d\u0a6e\u0a6f\u0a59\u0a5a{}\u0a5b\u0a5c\u0a5e")
+            // D.....EF.0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF012345.....6789ABCDEF01
+            + string(
+                "\u0a75 \\            [~] |ABCDEFGHIJKLMNOPQRSTUVWXYZ          \u20ac            ")
+            // 23456789ABCDEF
+            + string("              "),
+
+        /* A.2.11 Tamil National Language Single Shift Table
+         NOTE: TS 23.038 V9.1.1 shows code 0x24 as \u0bef, corrected to \u0bee (typo)
+         01.....23.....4.....5.6.....789A.....BCDEF0123.....45.....6789.....A.....BC.....D..... */
+        string(
+            "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+ -/<=>\u00a1^\u00a1_#*\u0964\u0965 \u0be6\u0be7")
+        // E.....F.....0.....1.....2.....3.....4.....5.....6.....7.....89A.....B.....C.....
+            + string(
+                "\u0be8\u0be9\u0bea\u0beb\u0bec\u0bed\u0bee\u0bef\u0bf3\u0bf4{}\u0bf5\u0bf6\u0bf7")
+            // D.....E.....F.0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF012345.....6789ABC
+            + string(
+                "\u0bf8\u0bfa\\            [~] |ABCDEFGHIJKLMNOPQRSTUVWXYZ          \u20ac       ")
+            // DEF0123456789ABCDEF
+            + string("                   "),
+
+        /* A.2.12 Telugu National Language Single Shift Table
+         NOTE: TS 23.038 V9.1.1 shows code 0x22-0x23 as \u06cc\u06cd, corrected to \u0c6c\u0c6d
+         01.....23.....4.....5.6.....789A.....BCDEF0123.....45.....6789ABC.....D.....E.....F..... */
+        string(
+            "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+ -/<=>\u00a1^\u00a1_#*   \u0c66\u0c67\u0c68\u0c69")
+        // 0.....1.....2.....3.....4.....5.....6.....7.....89A.....B.....C.....D.....E.....F.
+            + string(
+                "\u0c6a\u0c6b\u0c6c\u0c6d\u0c6e\u0c6f\u0c58\u0c59{}\u0c78\u0c79\u0c7a\u0c7b\u0c7c\\")
+            // 0.....1.....2.....3456789ABCDEF0123456789ABCDEF0123456789ABCDEF012345.....6789ABCD
+            + string(
+                "\u0c7d\u0c7e\u0c7f         [~] |ABCDEFGHIJKLMNOPQRSTUVWXYZ          \u20ac        ")
+            // EF0123456789ABCDEF
+            + string("                  "),
+
+        /* A.2.13 Urdu National Language Single Shift Table
+         01.....23.....4.....5.6.....789A.....BCDEF0123.....45.....6789.....A.....BC.....D..... */
+        string(
+            "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+ -/<=>\u00a1^\u00a1_#*\u0600\u0601 \u06f0\u06f1")
+        // E.....F.....0.....1.....2.....3.....4.....5.....6.....7.....89A.....B.....C.....
+            + string(
+                "\u06f2\u06f3\u06f4\u06f5\u06f6\u06f7\u06f8\u06f9\u060c\u060d{}\u060e\u060f\u0610")
+            // D.....E.....F.0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.....
+            + string(
+                "\u0611\u0612\\\u0613\u0614\u061b\u061f\u0640\u0652\u0658\u066b\u066c\u0672\u0673")
+            // B.....CDEF.....0123456789ABCDEF0123456789ABCDEF012345.....6789ABCDEF0123456789ABCDEF
+            + string(
+                "\u06cd[~]\u06d4|ABCDEFGHIJKLMNOPQRSTUVWXYZ          \u20ac                          ") };
+
+std::vector<std::string> GsmAlphabet::sLanguageTables =
+    {
+        /* 3GPP TS 23.038 V9.1.1 section 6.2.1 - GSM 7 bit Default Alphabet
+         01.....23.....4.....5.....6.....7.....8.....9.....A.B.....C.....D.E.....F.....0.....1 */
+        string(
+            "@\u00a3$\u00a5\u00e8\u00e9\u00f9\u00ec\u00f2\u00c7\n\u00d8\u00f8\r\u00c5\u00e5\u0394_")
+        // 2.....3.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E.....
+            + string(
+                "\u03a6\u0393\u039b\u03a9\u03a0\u03a8\u03a3\u0398\u039e\uffff\u00c6\u00e6\u00df")
+            // F.....012.34.....56789ABCDEF0123456789ABCDEF0.....123456789ABCDEF0123456789A
+            + string(
+                "\u00c9 !\"#\u00a4%&'()*+,-./0123456789:;<=>?\u00a1ABCDEFGHIJKLMNOPQRSTUVWXYZ")
+            // B.....C.....D.....E.....F.....0.....123456789ABCDEF0123456789AB.....C.....D.....
+            + string(
+                "\u00c4\u00d6\u00d1\u00dc\u00a7\u00bfabcdefghijklmnopqrstuvwxyz\u00e4\u00f6\u00f1")
+            // E.....F.....
+            + string("\u00fc\u00e0"),
+
+        /* A.3.1 Turkish National Language Locking Shift Table
+         01.....23.....4.....5.....6.....7.....8.....9.....A.B.....C.....D.E.....F.....0.....1 */
+        string(""),
+        /*    string("@\u00a3$\u00a5\u20ac\u00e9\u00f9\u0131\u00f2\u00c7\n\u011e\u011f\r\u00c5\u00e5\u0394_")
+         // 2.....3.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E.....
+         + string("\u03a6\u0393\u039b\u03a9\u03a0\u03a8\u03a3\u0398\u039e\uffff\u015e\u015f\u00df")
+         // F.....012.34.....56789ABCDEF0123456789ABCDEF0.....123456789ABCDEF0123456789A
+         + string("\u00c9 !\string("#\u00a4%&'()*+,-./0123456789:;<=>?\u0130ABCDEFGHIJKLMNOPQRSTUVWXYZstring(string(")
+         // B.....C.....D.....E.....F.....0.....123456789ABCDEF0123456789AB.....C.....D.....
+         + string("\u00c4\u00d6\u00d1\u00dc\u00a7\u00e7abcdefghijklmnopqrstuvwxyz\u00e4\u00f6\u00f1")
+         // E.....F.....
+         + string("\u00fc\u00e0"),*/
+
+        /* A.3.2 Void (no locking shift table for Spanish) */
+        string(""),
+
+        /* A.3.3 Portuguese National Language Locking Shift Table
+         01.....23.....4.....5.....6.....7.....8.....9.....A.B.....C.....D.E.....F.....0.....1 */
+        string(
+            "@\u00a3$\u00a5\u00ea\u00e9\u00fa\u00ed\u00f3\u00e7\n\u00d4\u00f4\r\u00c1\u00e1\u0394_")
+        // 2.....3.....4.....5.....67.8.....9.....AB.....C.....D.....E.....F.....012.34.....
+            + string(
+                "\u00aa\u00c7\u00c0\u221e^\\\u20ac\u00d3|\uffff\u00c2\u00e2\u00ca\u00c9 !\"#\u00ba")
+            // 56789ABCDEF0123456789ABCDEF0.....123456789ABCDEF0123456789AB.....C.....D.....E.....
+            + string(
+                "%&'()*+,-./0123456789:;<=>?\u00cdABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c3\u00d5\u00da\u00dc")
+            // F.....0123456789ABCDEF0123456789AB.....C.....DE.....F.....
+            + string(
+                "\u00a7~abcdefghijklmnopqrstuvwxyz\u00e3\u00f5`\u00fc\u00e0"),
+
+        /* A.3.4 Bengali National Language Locking Shift Table
+         0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.B.....CD.EF.....0..... */
+        string(
+            "\u0981\u0982\u0983\u0985\u0986\u0987\u0988\u0989\u098a\u098b\n\u098c \r \u098f\u0990")
+        // 123.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E.....F.....
+            + string(
+                "  \u0993\u0994\u0995\u0996\u0997\u0998\u0999\u099a\uffff\u099b\u099c\u099d\u099e")
+            // 012.....3.....4.....5.....6.....7.....89A.....B.....CD.....EF.....0123456789ABC
+            + string(
+                " !\u099f\u09a0\u09a1\u09a2\u09a3\u09a4)(\u09a5\u09a6,\u09a7.\u09a80123456789:; ")
+            // D.....E.....F0.....1.....2.....3.....4.....56.....789A.....B.....C.....D.....
+            + string(
+                "\u09aa\u09ab?\u09ac\u09ad\u09ae\u09af\u09b0 \u09b2   \u09b6\u09b7\u09b8\u09b9")
+            // E.....F.....0.....1.....2.....3.....4.....5.....6.....789.....A.....BCD.....E.....
+            + string(
+                "\u09bc\u09bd\u09be\u09bf\u09c0\u09c1\u09c2\u09c3\u09c4  \u09c7\u09c8  \u09cb\u09cc")
+            // F.....0.....123456789ABCDEF0123456789AB.....C.....D.....E.....F.....
+            + string(
+                "\u09cd\u09ceabcdefghijklmnopqrstuvwxyz\u09d7\u09dc\u09dd\u09f0\u09f1"),
+
+        /* A.3.5 Gujarati National Language Locking Shift Table
+         0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.B.....C.....D.EF.....0.....*/
+        string(
+            "\u0a81\u0a82\u0a83\u0a85\u0a86\u0a87\u0a88\u0a89\u0a8a\u0a8b\n\u0a8c\u0a8d\r \u0a8f\u0a90")
+        // 1.....23.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E.....
+            + string(
+                "\u0a91 \u0a93\u0a94\u0a95\u0a96\u0a97\u0a98\u0a99\u0a9a\uffff\u0a9b\u0a9c\u0a9d")
+            // F.....012.....3.....4.....5.....6.....7.....89A.....B.....CD.....EF.....0123456789AB
+            + string(
+                "\u0a9e !\u0a9f\u0aa0\u0aa1\u0aa2\u0aa3\u0aa4)(\u0aa5\u0aa6,\u0aa7.\u0aa80123456789:;")
+            // CD.....E.....F0.....1.....2.....3.....4.....56.....7.....89.....A.....B.....C.....
+            + string(
+                " \u0aaa\u0aab?\u0aac\u0aad\u0aae\u0aaf\u0ab0 \u0ab2\u0ab3 \u0ab5\u0ab6\u0ab7\u0ab8")
+            // D.....E.....F.....0.....1.....2.....3.....4.....5.....6.....7.....89.....A.....
+            + string(
+                "\u0ab9\u0abc\u0abd\u0abe\u0abf\u0ac0\u0ac1\u0ac2\u0ac3\u0ac4\u0ac5 \u0ac7\u0ac8")
+            // B.....CD.....E.....F.....0.....123456789ABCDEF0123456789AB.....C.....D.....E.....
+            + string(
+                "\u0ac9 \u0acb\u0acc\u0acd\u0ad0abcdefghijklmnopqrstuvwxyz\u0ae0\u0ae1\u0ae2\u0ae3")
+            // F.....
+            + string("\u0af1"),
+
+        /* A.3.6 Hindi National Language Locking Shift Table
+         0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.B.....C.....D.E.....F.....*/
+        string(
+            "\u0901\u0902\u0903\u0905\u0906\u0907\u0908\u0909\u090a\u090b\n\u090c\u090d\r\u090e\u090f")
+        // 0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....
+            + string(
+                "\u0910\u0911\u0912\u0913\u0914\u0915\u0916\u0917\u0918\u0919\u091a\uffff\u091b\u091c")
+            // E.....F.....012.....3.....4.....5.....6.....7.....89A.....B.....CD.....EF.....012345
+            + string(
+                "\u091d\u091e !\u091f\u0920\u0921\u0922\u0923\u0924)(\u0925\u0926,\u0927.\u0928012345")
+            // 6789ABC.....D.....E.....F0.....1.....2.....3.....4.....5.....6.....7.....8.....
+            + string(
+                "6789:;\u0929\u092a\u092b?\u092c\u092d\u092e\u092f\u0930\u0931\u0932\u0933\u0934")
+            // 9.....A.....B.....C.....D.....E.....F.....0.....1.....2.....3.....4.....5.....6.....
+            + string(
+                "\u0935\u0936\u0937\u0938\u0939\u093c\u093d\u093e\u093f\u0940\u0941\u0942\u0943\u0944")
+            // 7.....8.....9.....A.....B.....C.....D.....E.....F.....0.....123456789ABCDEF012345678
+            + string(
+                "\u0945\u0946\u0947\u0948\u0949\u094a\u094b\u094c\u094d\u0950abcdefghijklmnopqrstuvwx")
+            // 9AB.....C.....D.....E.....F.....
+            + string("yz\u0972\u097b\u097c\u097e\u097f"),
+
+        /* A.3.7 Kannada National Language Locking Shift Table
+         NOTE: TS 23.038 V9.1.1 shows code 0x24 as \u0caa, corrected to \u0ca1 (typo)
+         01.....2.....3.....4.....5.....6.....7.....8.....9.....A.B.....CD.E.....F.....0.....1 */
+        string(
+            " \u0c82\u0c83\u0c85\u0c86\u0c87\u0c88\u0c89\u0c8a\u0c8b\n\u0c8c \r\u0c8e\u0c8f\u0c90 ")
+        // 2.....3.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E.....F.....
+            + string(
+                "\u0c92\u0c93\u0c94\u0c95\u0c96\u0c97\u0c98\u0c99\u0c9a\uffff\u0c9b\u0c9c\u0c9d\u0c9e")
+            // 012.....3.....4.....5.....6.....7.....89A.....B.....CD.....EF.....0123456789ABC
+            + string(
+                " !\u0c9f\u0ca0\u0ca1\u0ca2\u0ca3\u0ca4)(\u0ca5\u0ca6,\u0ca7.\u0ca80123456789:; ")
+            // D.....E.....F0.....1.....2.....3.....4.....5.....6.....7.....89.....A.....B.....
+            + string(
+                "\u0caa\u0cab?\u0cac\u0cad\u0cae\u0caf\u0cb0\u0cb1\u0cb2\u0cb3 \u0cb5\u0cb6\u0cb7")
+            // C.....D.....E.....F.....0.....1.....2.....3.....4.....5.....6.....78.....9.....
+            + string(
+                "\u0cb8\u0cb9\u0cbc\u0cbd\u0cbe\u0cbf\u0cc0\u0cc1\u0cc2\u0cc3\u0cc4 \u0cc6\u0cc7")
+            // A.....BC.....D.....E.....F.....0.....123456789ABCDEF0123456789AB.....C.....D.....
+            + string(
+                "\u0cc8 \u0cca\u0ccb\u0ccc\u0ccd\u0cd5abcdefghijklmnopqrstuvwxyz\u0cd6\u0ce0\u0ce1")
+            // E.....F.....
+            + string("\u0ce2\u0ce3"),
+
+        /* A.3.8 Malayalam National Language Locking Shift Table
+         01.....2.....3.....4.....5.....6.....7.....8.....9.....A.B.....CD.E.....F.....0.....1 */
+        string(""),
+        /*    string(" \u0d02\u0d03\u0d05\u0d06\u0d07\u0d08\u0d09\u0d0a\u0d0b\n\u0d0c \r\u0d0e\u0d0f\u0d10 ")
+         // 2.....3.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E.....F.....
+         + string("\u0d12\u0d13\u0d14\u0d15\u0d16\u0d17\u0d18\u0d19\u0d1a\uffff\u0d1b\u0d1c\u0d1d\u0d1e")
+         // 012.....3.....4.....5.....6.....7.....89A.....B.....CD.....EF.....0123456789ABC
+         + string(" !\u0d1f\u0d20\u0d21\u0d22\u0d23\u0d24)(\u0d25\u0d26,\u0d27.\u0d280123456789:; ")
+         // D.....E.....F0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.....
+         + "\u0d2a\u0d2b?\u0d2c\u0d2d\u0d2e\u0d2f\u0d30\u0d31\u0d32\u0d33\u0d34\u0d35\u0d36")
+         // B.....C.....D.....EF.....0.....1.....2.....3.....4.....5.....6.....78.....9.....
+         + string("\u0d37\u0d38\u0d39 \u0d3d\u0d3e\u0d3f\u0d40\u0d41\u0d42\u0d43\u0d44 \u0d46\u0d47")
+         // A.....BC.....D.....E.....F.....0.....123456789ABCDEF0123456789AB.....C.....D.....
+         + string("\u0d48 \u0d4a\u0d4b\u0d4c\u0d4d\u0d57abcdefghijklmnopqrstuvwxyz\u0d60\u0d61\u0d62")
+         // E.....F.....
+         + string("\u0d63\u0d79"),*/
+
+        /* A.3.9 Oriya National Language Locking Shift Table
+         0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.B.....CD.EF.....0.....12 */
+        string(""),
+        /*    string("\u0b01\u0b02\u0b03\u0b05\u0b06\u0b07\u0b08\u0b09\u0b0a\u0b0b\n\u0b0c \r \u0b0f\u0b10  ")
+         // 3.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E.....F.....01
+         + string("\u0b13\u0b14\u0b15\u0b16\u0b17\u0b18\u0b19\u0b1a\uffff\u0b1b\u0b1c\u0b1d\u0b1e !")
+         // 2.....3.....4.....5.....6.....7.....89A.....B.....CD.....EF.....0123456789ABCD.....
+         + string("\u0b1f\u0b20\u0b21\u0b22\u0b23\u0b24)(\u0b25\u0b26,\u0b27.\u0b280123456789:; \u0b2a")
+         // E.....F0.....1.....2.....3.....4.....56.....7.....89.....A.....B.....C.....D.....
+         + string("\u0b2b?\u0b2c\u0b2d\u0b2e\u0b2f\u0b30 \u0b32\u0b33 \u0b35\u0b36\u0b37\u0b38\u0b39")
+         // E.....F.....0.....1.....2.....3.....4.....5.....6.....789.....A.....BCD.....E.....
+         + string("\u0b3c\u0b3d\u0b3e\u0b3f\u0b40\u0b41\u0b42\u0b43\u0b44  \u0b47\u0b48  \u0b4b\u0b4c")
+         // F.....0.....123456789ABCDEF0123456789AB.....C.....D.....E.....F.....
+         + string("\u0b4d\u0b56abcdefghijklmnopqrstuvwxyz\u0b57\u0b60\u0b61\u0b62\u0b63"),*/
+
+        /* A.3.10 Punjabi National Language Locking Shift Table
+         0.....1.....2.....3.....4.....5.....6.....7.....8.....9A.BCD.EF.....0.....123.....4.....*/
+        string(
+            "\u0a01\u0a02\u0a03\u0a05\u0a06\u0a07\u0a08\u0a09\u0a0a \n  \r \u0a0f\u0a10  \u0a13\u0a14")
+        // 5.....6.....7.....8.....9.....A.....B.....C.....D.....E.....F.....012.....3.....
+            + string(
+                "\u0a15\u0a16\u0a17\u0a18\u0a19\u0a1a\uffff\u0a1b\u0a1c\u0a1d\u0a1e !\u0a1f\u0a20")
+            // 4.....5.....6.....7.....89A.....B.....CD.....EF.....0123456789ABCD.....E.....F0.....
+            + string(
+                "\u0a21\u0a22\u0a23\u0a24)(\u0a25\u0a26,\u0a27.\u0a280123456789:; \u0a2a\u0a2b?\u0a2c")
+            // 1.....2.....3.....4.....56.....7.....89.....A.....BC.....D.....E.....F0.....1.....
+            + string(
+                "\u0a2d\u0a2e\u0a2f\u0a30 \u0a32\u0a33 \u0a35\u0a36 \u0a38\u0a39\u0a3c \u0a3e\u0a3f")
+            // 2.....3.....4.....56789.....A.....BCD.....E.....F.....0.....123456789ABCDEF012345678
+            + string(
+                "\u0a40\u0a41\u0a42    \u0a47\u0a48  \u0a4b\u0a4c\u0a4d\u0a51abcdefghijklmnopqrstuvwx")
+            // 9AB.....C.....D.....E.....F.....
+            + string("yz\u0a70\u0a71\u0a72\u0a73\u0a74"),
+
+        /* A.3.11 Tamil National Language Locking Shift Table
+         01.....2.....3.....4.....5.....6.....7.....8.....9A.BCD.E.....F.....0.....12.....3..... */
+        string(
+            " \u0b82\u0b83\u0b85\u0b86\u0b87\u0b88\u0b89\u0b8a \n  \r\u0b8e\u0b8f\u0b90 \u0b92\u0b93")
+        // 4.....5.....6789.....A.....B.....CD.....EF.....012.....3456.....7.....89ABCDEF.....
+            + string(
+                "\u0b94\u0b95   \u0b99\u0b9a\uffff \u0b9c \u0b9e !\u0b9f   \u0ba3\u0ba4)(  , .\u0ba8")
+            // 0123456789ABC.....D.....EF012.....3.....4.....5.....6.....7.....8.....9.....A.....
+            + string(
+                "0123456789:;\u0ba9\u0baa ?  \u0bae\u0baf\u0bb0\u0bb1\u0bb2\u0bb3\u0bb4\u0bb5\u0bb6")
+            // B.....C.....D.....EF0.....1.....2.....3.....4.....5678.....9.....A.....BC.....D.....
+            + string(
+                "\u0bb7\u0bb8\u0bb9  \u0bbe\u0bbf\u0bc0\u0bc1\u0bc2   \u0bc6\u0bc7\u0bc8 \u0bca\u0bcb")
+            // E.....F.....0.....123456789ABCDEF0123456789AB.....C.....D.....E.....F.....
+            + string(
+                "\u0bcc\u0bcd\u0bd0abcdefghijklmnopqrstuvwxyz\u0bd7\u0bf0\u0bf1\u0bf2\u0bf9"),
+
+        /* A.3.12 Telugu National Language Locking Shift Table
+         0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.B.....CD.E.....F.....0.....*/
+        string(
+            "\u0c01\u0c02\u0c03\u0c05\u0c06\u0c07\u0c08\u0c09\u0c0a\u0c0b\n\u0c0c \r\u0c0e\u0c0f\u0c10")
+        // 12.....3.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E.....
+            + string(
+                " \u0c12\u0c13\u0c14\u0c15\u0c16\u0c17\u0c18\u0c19\u0c1a\uffff\u0c1b\u0c1c\u0c1d")
+            // F.....012.....3.....4.....5.....6.....7.....89A.....B.....CD.....EF.....0123456789AB
+            + string(
+                "\u0c1e !\u0c1f\u0c20\u0c21\u0c22\u0c23\u0c24)(\u0c25\u0c26,\u0c27.\u0c280123456789:;")
+            // CD.....E.....F0.....1.....2.....3.....4.....5.....6.....7.....89.....A.....B.....
+            + string(
+                " \u0c2a\u0c2b?\u0c2c\u0c2d\u0c2e\u0c2f\u0c30\u0c31\u0c32\u0c33 \u0c35\u0c36\u0c37")
+            // C.....D.....EF.....0.....1.....2.....3.....4.....5.....6.....78.....9.....A.....B
+            + string(
+                "\u0c38\u0c39 \u0c3d\u0c3e\u0c3f\u0c40\u0c41\u0c42\u0c43\u0c44 \u0c46\u0c47\u0c48 ")
+            // C.....D.....E.....F.....0.....123456789ABCDEF0123456789AB.....C.....D.....E.....
+            + string(
+                "\u0c4a\u0c4b\u0c4c\u0c4d\u0c55abcdefghijklmnopqrstuvwxyz\u0c56\u0c60\u0c61\u0c62")
+            // F.....
+            + string("\u0c63"),
+
+        /* A.3.13 Urdu National Language Locking Shift Table
+         0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.B.....C.....D.E.....F.....*/
+        string(
+            "\u0627\u0622\u0628\u067b\u0680\u067e\u06a6\u062a\u06c2\u067f\n\u0679\u067d\r\u067a\u067c")
+        // 0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....
+            + string(
+                "\u062b\u062c\u0681\u0684\u0683\u0685\u0686\u0687\u062d\u062e\u062f\uffff\u068c\u0688")
+            // E.....F.....012.....3.....4.....5.....6.....7.....89A.....B.....CD.....EF.....012345
+            + string(
+                "\u0689\u068a !\u068f\u068d\u0630\u0631\u0691\u0693)(\u0699\u0632,\u0696.\u0698012345")
+            // 6789ABC.....D.....E.....F0.....1.....2.....3.....4.....5.....6.....7.....8.....
+            + string(
+                "6789:;\u069a\u0633\u0634?\u0635\u0636\u0637\u0638\u0639\u0641\u0642\u06a9\u06aa")
+            // 9.....A.....B.....C.....D.....E.....F.....0.....1.....2.....3.....4.....5.....6.....
+            + string(
+                "\u06ab\u06af\u06b3\u06b1\u0644\u0645\u0646\u06ba\u06bb\u06bc\u0648\u06c4\u06d5\u06c1")
+            // 7.....8.....9.....A.....B.....C.....D.....E.....F.....0.....123456789ABCDEF012345678
+            + string(
+                "\u06be\u0621\u06cc\u06d0\u06d2\u064d\u0650\u064f\u0657\u0654abcdefghijklmnopqrstuvwx")
+            // 9AB.....C.....D.....E.....F.....
+            + string("yz\u0655\u0651\u0653\u0656\u0670") };
+GsmAlphabet::GsmAlphabet() {
+  // TODO Auto-generated constructor stub
+
+}
+
+GsmAlphabet::~GsmAlphabet() {
+  // TODO Auto-generated destructor stub
+}
+void GsmAlphabet::packSmsChar(std::vector<uint8_t>  packedChars, int bitOffset, int value) {
+    int byteOffset = bitOffset / 8;
+    int shift = bitOffset % 8;
+
+    packedChars[++byteOffset] |= value << shift;
+
+    if (shift > 1) {
+        packedChars[++byteOffset] = (uint8_t)(value >> (8 - shift));
+    }
+}
+
+int GsmAlphabet::countGsmSeptetsUsingTables(std::string s, bool use7bitOnly,int languageTable, int languageShiftTable) {
+    int count = 0;
+    int sz = s.length();
+    std::shared_ptr<std::map<char, int>> charToLanguageTable = sCharsToGsmTables[languageTable];
+    std::shared_ptr<std::map<char, int>> charToShiftTable = sCharsToShiftTables[languageShiftTable];
+    for (int i = 0; i < sz; i++) {
+        char c = s[i];
+        if (c == GSM_EXTENDED_ESCAPE) {
+            std::cout << "countGsmSeptets() string contains Escape character, skipping." << std::endl;
+            continue;
+        }
+        if (charToLanguageTable->find(c) != charToLanguageTable->end()) {
+            count++;
+        } else if (charToShiftTable->find(c) != charToShiftTable->end()) {
+            count += 2; // escape + shift table index
+        } else if (use7bitOnly) {
+            count++;    // encode as space
+        } else {
+            return -1;  // caller must check for this case
+        }
+    }
+    return count;
+}
+std::vector<uint8_t> GsmAlphabet::stringToGsm7BitPacked(std::string data, int startingSeptetOffset,
+          bool throwException, int languageTable, int languageShiftTable) {
+    int dataLen = data.length();
+    int septetCount = countGsmSeptetsUsingTables(data, !throwException,
+            languageTable, languageShiftTable);
+    if (septetCount == -1) {
+        throw runtime_error("countGsmSeptetsUsingTables(): unencodable char");
+    }
+    septetCount += startingSeptetOffset;
+    if (septetCount > 255) {
+        throw runtime_error("Payload cannot exceed 255 septets");
+    }
+    int byteCount = ((septetCount * 7) + 7) / 8;
+    std::vector<uint8_t> ret(byteCount + 1); // Include space for one byte length prefix.
+    std::shared_ptr<std::map<char, int>> charToLanguageTable = sCharsToGsmTables[languageTable];
+    std::shared_ptr<std::map<char, int>> charToShiftTable = sCharsToShiftTables[languageShiftTable];
+    for (int i = 0, septets = startingSeptetOffset, bitOffset = startingSeptetOffset * 7;
+             i < dataLen && septets < septetCount;
+             i++, bitOffset += 7) {
+        char c = data[i];
+        auto v = charToLanguageTable->find(c);
+        int value;
+        if (v == charToLanguageTable->end()) {
+            v = charToShiftTable->find(c);  // Lookup the extended char.
+            if (v == charToShiftTable->end()) {
+                if (throwException) {
+                    throw runtime_error("stringToGsm7BitPacked(): unencodable char");
+                } else {
+                    v = charToLanguageTable->find(' ');   // should return ASCII space
+                    if (v == charToShiftTable->end()) {
+                        value = ' ';
+                    } else {
+                        value = v->second;
+                    }
+                }
+            } else {
+                packSmsChar(ret, bitOffset, GSM_EXTENDED_ESCAPE);
+                bitOffset += 7;
+                septets++;
+            }
+        } else {
+            value = v->second;
+        }
+        packSmsChar(ret, bitOffset, value);
+        septets++;
+    }
+    ret[0] = (uint8_t) (septetCount);  // Validated by check above.
+    return ret;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/GsmAlphabet.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/GsmAlphabet.h
new file mode 100644
index 0000000..bbb9bb8
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/GsmAlphabet.h
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef GSMALPHABET_H_
+#define GSMALPHABET_H_
+#include <cstdint>
+#include <string>
+#include <map>
+#include <memory>
+#include <vector>
+
+class GsmAlphabet {
+public:
+  GsmAlphabet();
+  virtual ~GsmAlphabet();
+  /**
+   * This escapes extended characters, and when present indicates that the
+   * following character should be looked up in the "extended" table.
+   *
+   * gsmToChar(GSM_EXTENDED_ESCAPE) returns 0xffff
+   */
+  static constexpr uint8_t GSM_EXTENDED_ESCAPE = 0x1B;
+
+  /**
+   * User data header requires one octet for length. Count as one septet, because
+   * all combinations of header elements below will have at least one free bit
+   * when padding to the nearest septet boundary.
+   */
+  static constexpr int UDH_SEPTET_COST_LENGTH = 1;
+
+  /**
+   * Using a non-default language locking shift table OR single shift table
+   * requires a user data header of 3 octets, or 4 septets, plus UDH length.
+   */
+  static constexpr int UDH_SEPTET_COST_ONE_SHIFT_TABLE = 4;
+
+  /**
+   * Using a non-default language locking shift table AND single shift table
+   * requires a user data header of 6 octets, or 7 septets, plus UDH length.
+   */
+  static constexpr int UDH_SEPTET_COST_TWO_SHIFT_TABLES = 7;
+
+  /**
+   * Multi-part messages require a user data header of 5 octets, or 6 septets,
+   * plus UDH length.
+   */
+  static constexpr int UDH_SEPTET_COST_CONCATENATED_MESSAGE = 6;
+
+  /**
+   * For a specific text string, this object describes protocol
+   * properties of encoding it for transmission as message user
+   * data.
+   */
+  class TextEncodingDetails {
+  public:
+    /**
+     *The number of SMS's required to encode the text.
+     */
+    int msgCount;
+
+    /**
+     * The number of code units consumed so far, where code units
+     * are basically characters in the encoding -- for example,
+     * septets for the standard ASCII and GSM encodings, and 16
+     * bits for Unicode.
+     */
+    int codeUnitCount;
+
+    /**
+     * How many code units are still available without spilling
+     * into an additional message.
+     */
+    int codeUnitsRemaining;
+
+    /**
+     * The encoding code unit size (specified using
+     * android.telephony.SmsMessage ENCODING_*).
+     */
+    int codeUnitSize;
+
+    /**
+     * The GSM national language table to use, or 0 for the default 7-bit alphabet.
+     */
+    int languageTable;
+
+    /**
+     * The GSM national language shift table to use, or 0 for the default 7-bit extension table.
+     */
+    int languageShiftTable;
+
+    std::string toString() {
+      return "TextEncodingDetails { msgCount=" + std::to_string(msgCount)
+          + ", codeUnitCount=" + std::to_string(codeUnitCount)
+          + ", codeUnitsRemaining=" + std::to_string(codeUnitsRemaining)
+          + ", codeUnitSize=" + std::to_string(codeUnitSize)
+          + ", languageTable=" + std::to_string(languageTable)
+          + ", languageShiftTable=" + std::to_string(languageShiftTable) + " }";
+    }
+  };
+
+  static std::string gsm7BitPackedToString(std::vector<uint8_t> pdu, int offset,
+      int lengthSeptets, int numPaddingBits, int languageTable, int shiftTable);
+  static std::vector<uint8_t> stringToGsm7BitPacked(std::string data, int startingSeptetOffset,
+          bool throwException, int languageTable, int languageShiftTable);
+private:
+  /** Reverse mapping from Unicode characters to indexes into language tables. */
+  static const std::vector<std::shared_ptr<std::map<char, int>>> sCharsToGsmTables;
+  static std::vector<std::shared_ptr<std::map<char, int>>> initCharsToGsmTables();
+  /** Reverse mapping from Unicode characters to indexes into language shift tables. */
+  static const std::vector<std::shared_ptr<std::map<char, int>>> sCharsToShiftTables;
+  static std::vector<std::shared_ptr<std::map<char, int>>> initCharsToShiftTables();
+  /** OEM configured list of enabled national language single shift tables for encoding. */
+  static std::vector<int> sEnabledSingleShiftTables;
+
+  /** OEM configured list of enabled national language locking shift tables for encoding. */
+  static std::vector<int> sEnabledLockingShiftTables;
+
+  /** Highest language code to include in array of single shift counters. */
+  static int sHighestEnabledSingleShiftCode;
+
+  /** Flag to bypass check for country-specific overlays (for test cases only). */
+  static bool sDisableCountryEncodingCheck;
+
+  /**
+   * Septet counter for a specific locking shift table and all of
+   * the single shift tables that it can be paired with.
+   */
+  class LanguagePairCount {
+  public:
+    int languageCode;
+    std::vector<int> septetCounts;
+    std::vector<int> unencodableCounts;
+    LanguagePairCount(int code) {
+      languageCode = code;
+      int maxSingleShiftCode = sHighestEnabledSingleShiftCode;
+      septetCounts.assign((maxSingleShiftCode + 1), 0);
+      unencodableCounts.assign(maxSingleShiftCode + 1, 0);
+      // set counters for disabled single shift tables to -1
+      // (GSM default extension table index 0 is always enabled)
+      for (int i = 1, tableOffset = 0; i <= maxSingleShiftCode; i++) {
+        if (sEnabledSingleShiftTables[tableOffset] == i) {
+          tableOffset++;
+        } else {
+          septetCounts[i] = -1;   // disabled
+        }
+      }
+      // exclude Turkish locking + Turkish single shift table and
+      // Portuguese locking + Spanish single shift table (these
+      // combinations will never be optimal for any input).
+      if (code == 1 && maxSingleShiftCode >= 1) {
+        septetCounts[1] = -1;   // Turkish + Turkish
+      } else if (code == 3 && maxSingleShiftCode >= 2) {
+        septetCounts[2] = -1;   // Portuguese + Spanish
+      }
+    }
+  };
+  static std::vector<std::string> sLanguageTables;
+  static std::vector<std::string> sLanguageShiftTables;
+  static void packSmsChar(std::vector<uint8_t>  packedChars, int bitOffset, int value);
+  static int countGsmSeptetsUsingTables(std::string s, bool use7bitOnly,int languageTable, int languageShiftTable);
+};
+
+#endif /* GSMALPHABET_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/HexDump.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/HexDump.cpp
new file mode 100644
index 0000000..d18c2fa
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/HexDump.cpp
@@ -0,0 +1,218 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include <string>
+#include <algorithm>
+using namespace std;
+
+#include "HexDump.h"
+
+const char HexDump::HEX_DIGITS[] = { '0', '1', '2', '3', '4', '5', '6', '7',
+    '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+const char HexDump::HEX_LOWER_CASE_DIGITS[] = { '0', '1', '2', '3', '4', '5',
+    '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+HexDump::HexDump() {
+  // TODO Auto-generated constructor stub
+
+}
+
+HexDump::~HexDump() {
+  // TODO Auto-generated destructor stub
+}
+
+std::string HexDump::dumpHexString(uint8_t* array, int length) {
+  return dumpHexString(array, 0, length);
+}
+std::string HexDump::dumpHexString(uint8_t* array, uint32_t offset,
+    int length) {
+  string result;
+
+  uint8_t line[16] = { 0 };
+  int lineIndex = 0;
+
+  result.append("\n0x");
+  result.append(toHexString(offset));
+
+  for (uint32_t i = offset; i < offset + length; i++) {
+    if (lineIndex == 16) {
+      result.append(" ");
+
+      for (int j = 0; j < 16; j++) {
+        if (line[j] > ' ' && line[j] < '~') {
+          //(unsigned char)line[j]
+          //result.append(string(line, j, 1));
+          result.push_back(line[j]);
+        } else {
+          result.append(".");
+        }
+      }
+
+      result.append("\n0x");
+      result.append(toHexString(i));
+      lineIndex = 0;
+    }
+
+    uint8_t b = array[i];
+    result.append(" ");
+    result.push_back(HEX_DIGITS[(b >> 4) & 0x0F]);
+    result.push_back(HEX_DIGITS[b & 0x0F]);
+
+    line[lineIndex++] = b;
+  }
+
+  if (lineIndex != 16) {
+    int count = (16 - lineIndex) * 3;
+    count++;
+    for (int i = 0; i < count; i++) {
+      result.append(" ");
+    }
+
+    for (int i = 0; i < lineIndex; i++) {
+      if (line[i] > ' ' && line[i] < '~') {
+        result.push_back(line[i]);
+      } else {
+        result.append(".");
+      }
+    }
+  }
+  return result;
+}
+
+std::string HexDump::toHexString(uint8_t b) {
+  int length = 0;
+  return toHexString(toByteArray(b, &length), length, true);
+}
+
+std::string HexDump::toHexString(uint8_t* array, int length, bool free) {
+  return toHexString(array, 0, length, true, free);
+}
+
+std::string HexDump::toHexString(std::vector<uint8_t> v) {
+  int length = v.size();
+  uint8_t array[length];
+  std::copy(v.begin(), v.end(), array);
+  return toHexString(array, 0, length, true, false);
+}
+
+std::string HexDump::toHexString(uint8_t* array, int length, bool upperCase,
+    bool free) {
+  return toHexString(array, 0, length, upperCase);
+}
+
+std::string HexDump::toHexString(uint8_t* array, int offset, int length,
+    bool free) {
+  return toHexString(array, offset, length, true);
+}
+
+std::string HexDump::toHexString(uint8_t* array, int offset, int length,
+    bool upperCase, bool free) {
+  const char* digits = upperCase ? HEX_DIGITS : HEX_LOWER_CASE_DIGITS;
+  char buf[length * 2];
+
+  int bufIndex = 0;
+  for (int i = offset; i < offset + length; i++) {
+    uint8_t b = array[i];
+    buf[bufIndex++] = digits[(b >> 4) & 0x0F];
+    buf[bufIndex++] = digits[b & 0x0F];
+  }
+  string str(buf, (length * 2));
+  if (free) {
+    delete[] array;
+  }
+  return str;
+}
+
+std::string HexDump::toHexString(uint32_t i) {
+  int length = 0;
+  return toHexString(toByteArray(i, &length), length, true);
+}
+
+/**
+ * @return need free.
+ */
+uint8_t* HexDump::toByteArray(uint8_t b, int* length) {
+  uint8_t* array = new uint8_t[1];
+  (*length) = 1;
+  array[0] = b;
+  return array;
+}
+
+/**
+ * @return need free;
+ */
+uint8_t* HexDump::toByteArray(uint32_t i, int* length) {
+  uint8_t* array = new uint8_t[4];
+  (*length) = 4;
+  array[3] = (uint8_t) (i & 0xFF);
+  array[2] = (uint8_t) ((i >> 8) & 0xFF);
+  array[1] = (uint8_t) ((i >> 16) & 0xFF);
+  array[0] = (uint8_t) ((i >> 24) & 0xFF);
+
+  return array;
+}
+
+uint32_t HexDump::toByte(char c) {
+  if (c >= '0' && c <= '9') {
+    return (c - '0');
+  }
+  if (c >= 'A' && c <= 'F') {
+    return (c - 'A' + 10);
+  }
+  if (c >= 'a' && c <= 'f') {
+    return (c - 'a' + 10);
+  }
+  return 0; //wrong
+}
+
+/**
+ * @return need free
+ */
+uint8_t* HexDump::hexStringToByteArray(std::string hexString, int* length) {
+  int len = hexString.length();
+  uint8_t* buffer = new uint8_t[len / 2];
+
+  for (int i = 0; i < len; i += 2) {
+    buffer[i / 2] = (uint8_t) ((toByte(hexString[i]) << 4)
+        | toByte(hexString[i + 1]));
+  }
+  (*length) = len;
+  return buffer;
+}
+std::string HexDump::appendByteAsHex(std::string& sb, uint8_t b,
+    bool upperCase) {
+  const char* digits = upperCase ? HEX_DIGITS : HEX_LOWER_CASE_DIGITS;
+  sb.push_back(digits[(b >> 4) & 0xf]);
+  sb.push_back(digits[b & 0xf]);
+  return sb;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/HexDump.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/HexDump.h
new file mode 100644
index 0000000..d9676d9
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/HexDump.h
@@ -0,0 +1,70 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef HEXDUMP_H_
+#define HEXDUMP_H_
+#include <string>
+#include <cstdint>
+#include <vector>
+
+class HexDump {
+public:
+  HexDump();
+  virtual ~HexDump();
+  static std::string dumpHexString(uint8_t* array, int length);
+  static std::string dumpHexString(uint8_t* array, uint32_t offset, int length);
+  static std::string toHexString(uint8_t b);
+  static std::string toHexString(uint8_t* array, int length, bool free);
+  static std::string toHexString(uint8_t* array, int length, bool upperCase,
+      bool free);
+  static std::string toHexString(uint8_t* array, int offset, int length,
+      bool free);
+  static std::string toHexString(uint8_t* array, int offset, int length,
+      bool upperCase, bool free);
+
+  static std::string toHexString(uint32_t i);
+  static uint8_t* toByteArray(uint8_t b, int* length);
+  static uint8_t* toByteArray(uint32_t i, int* length);
+  static uint32_t toByte(char c);
+  static uint8_t* hexStringToByteArray(std::string hexString, int* length);
+  static std::string appendByteAsHex(std::string& sb, uint8_t b,
+      bool upperCase);
+  static std::string toHexString(std::vector<uint8_t> v);
+private:
+  static const char HEX_DIGITS[];
+  static const char HEX_LOWER_CASE_DIGITS[];
+};
+
+#endif /* HEXDUMP_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/IccUtils.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/IccUtils.cpp
new file mode 100644
index 0000000..75386ca
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/IccUtils.cpp
@@ -0,0 +1,82 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include "IccUtils.h"
+
+char IccUtils::HEX_CHARS[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
+int IccUtils::cdmaBcdByteToInt(uint8_t b) {
+  int ret = 0;
+
+  // treat out-of-range BCD values as 0
+  if ((b & 0xf0) <= 0x90) {
+    ret = ((b >> 4) & 0xf) * 10;
+  }
+
+  if ((b & 0x0f) <= 0x09) {
+    ret += (b & 0xf);
+  }
+
+  return ret;
+}
+
+std::string IccUtils::bytesToHexString(std::vector<uint8_t> bytes) {
+  if (bytes.empty()) return nullptr;
+
+  std::string ret;
+
+  for (int i = 0 ; i < bytes.size() ; i++) {
+      int b;
+
+      b = 0x0f & (bytes[i] >> 4);
+
+      ret.push_back(HEX_CHARS[b]);
+
+      b = 0x0f & bytes[i];
+
+      ret.push_back(HEX_CHARS[b]);
+  }
+
+  return ret;
+}
+
+IccUtils::IccUtils() {
+  // TODO Auto-generated constructor stub
+
+}
+
+IccUtils::~IccUtils() {
+  // TODO Auto-generated destructor stub
+}
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/IccUtils.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/IccUtils.h
new file mode 100644
index 0000000..b94e12d
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/IccUtils.h
@@ -0,0 +1,60 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef ICCUTILS_H_
+#define ICCUTILS_H_
+#include <cstdint>
+#include <string>
+#include <vector>
+
+class IccUtils {
+public:
+  IccUtils();
+  virtual ~IccUtils();
+  static int cdmaBcdByteToInt(uint8_t b);
+  /**
+   * Converts a byte array into a String of hexadecimal characters.
+   *
+   * @param bytes an array of bytes
+   *
+   * @return hex string representation of bytes array
+   */
+  static std::string bytesToHexString(std::vector<uint8_t> bytes);
+private:
+  // A table mapping from a number to a hex character for fast encoding hex strings.
+      static char HEX_CHARS[];
+};
+
+#endif /* ICCUTILS_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsAddress.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsAddress.cpp
new file mode 100644
index 0000000..a6e690b
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsAddress.cpp
@@ -0,0 +1,46 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include "SmsAddress.h"
+
+SmsAddress::SmsAddress() {
+  // TODO Auto-generated constructor stub
+
+}
+
+SmsAddress::~SmsAddress() {
+  // TODO Auto-generated destructor stub
+}
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsAddress.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsAddress.h
new file mode 100644
index 0000000..6d9cfd9
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsAddress.h
@@ -0,0 +1,94 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef SMSADDRESS_H_
+#define SMSADDRESS_H_
+#include <cstdint>
+#include <string>
+#include <vector>
+
+class SmsAddress {
+public:
+  SmsAddress();
+  virtual ~SmsAddress();
+  // From TS 23.040 9.1.2.5 and TS 24.008 table 10.5.118
+  // and C.S0005-D table 2.7.1.3.2.4-2
+  static constexpr int TON_UNKNOWN = 0;
+  static constexpr int TON_INTERNATIONAL = 1;
+  static constexpr int TON_NATIONAL = 2;
+  static constexpr int TON_NETWORK = 3;
+  static constexpr int TON_SUBSCRIBER = 4;
+  static constexpr int TON_ALPHANUMERIC = 5;
+  static constexpr int TON_ABBREVIATED = 6;
+
+  int ton;
+  std::string address;
+  std::vector<uint8_t> origBytes;
+  //uint8_t* origBytes = nullptr;
+  //int origBytes_length = 0;
+
+  /**
+   * Returns the address of the SMS message in String form or null if unavailable
+   */
+  std::string getAddressString() {
+    return address;
+  }
+
+  /**
+   * Returns true if this is an alphanumeric address
+   */
+  bool isAlphanumeric() {
+    return ton == TON_ALPHANUMERIC;
+  }
+
+  /**
+   * Returns true if this is a network address
+   */
+  bool isNetworkSpecific() {
+    return ton == TON_NETWORK;
+  }
+
+  bool couldBeEmailGateway() {
+    // Some carriers seems to send email gateway messages in this form:
+    // from: an UNKNOWN TON, 3 or 4 digits long, beginning with a 5
+    // PID: 0x00, Data coding scheme 0x03
+    // So we just attempt to treat any message from an address length <= 4
+    // as an email gateway
+
+    return address.length() <= 4;
+  }
+};
+
+#endif /* SMSADDRESS_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsCbCmasInfo.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsCbCmasInfo.cpp
new file mode 100644
index 0000000..834d2d6
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsCbCmasInfo.cpp
@@ -0,0 +1,52 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include "SmsCbCmasInfo.h"
+
+SmsCbCmasInfo::SmsCbCmasInfo(int messageClass, int category, int responseType,
+    int severity, int urgency, int certainty) {
+  mMessageClass = messageClass;
+  mCategory = category;
+  mResponseType = responseType;
+  mSeverity = severity;
+  mUrgency = urgency;
+  mCertainty = certainty;
+
+}
+
+SmsCbCmasInfo::~SmsCbCmasInfo() {
+  // TODO Auto-generated destructor stub
+}
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsCbCmasInfo.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsCbCmasInfo.h
new file mode 100644
index 0000000..9711619
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsCbCmasInfo.h
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SMSCBCMASINFO_H_
+#define SMSCBCMASINFO_H_
+
+#include <string>
+class SmsCbCmasInfo {
+public:
+  SmsCbCmasInfo(int messageClass, int category, int responseType, int severity,
+      int urgency, int certainty);
+  virtual ~SmsCbCmasInfo();
+
+  // CMAS message class (in GSM/UMTS message identifier or CDMA service category).
+
+  /** Presidential-level alert (Korean Public Alert System Class 0 message). */
+  static constexpr int CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT = 0x00;
+
+  /** Extreme threat to life and property (Korean Public Alert System Class 1 message). */
+  static constexpr int CMAS_CLASS_EXTREME_THREAT = 0x01;
+
+  /** Severe threat to life and property (Korean Public Alert System Class 1 message). */
+  static constexpr int CMAS_CLASS_SEVERE_THREAT = 0x02;
+
+  /** Child abduction emergency (AMBER Alert). */
+  static constexpr int CMAS_CLASS_CHILD_ABDUCTION_EMERGENCY = 0x03;
+
+  /** CMAS test message. */
+  static constexpr int CMAS_CLASS_REQUIRED_MONTHLY_TEST = 0x04;
+
+  /** CMAS exercise. */
+  static constexpr int CMAS_CLASS_CMAS_EXERCISE = 0x05;
+
+  /** CMAS category for operator defined use. */
+  static constexpr int CMAS_CLASS_OPERATOR_DEFINED_USE = 0x06;
+
+  /** CMAS category for warning types that are reserved for future extension. */
+  static constexpr int CMAS_CLASS_UNKNOWN = -1;
+
+  // CMAS alert category (in CDMA type 1 elements record).
+
+  /** CMAS alert category: Geophysical including landslide. */
+  static constexpr int CMAS_CATEGORY_GEO = 0x00;
+
+  /** CMAS alert category: Meteorological including flood. */
+  static constexpr int CMAS_CATEGORY_MET = 0x01;
+
+  /** CMAS alert category: General emergency and public safety. */
+  static constexpr int CMAS_CATEGORY_SAFETY = 0x02;
+
+  /** CMAS alert category: Law enforcement, military, homeland/local/private security. */
+  static constexpr int CMAS_CATEGORY_SECURITY = 0x03;
+
+  /** CMAS alert category: Rescue and recovery. */
+  static constexpr int CMAS_CATEGORY_RESCUE = 0x04;
+
+  /** CMAS alert category: Fire suppression and rescue. */
+  static constexpr int CMAS_CATEGORY_FIRE = 0x05;
+
+  /** CMAS alert category: Medical and public health. */
+  static constexpr int CMAS_CATEGORY_HEALTH = 0x06;
+
+  /** CMAS alert category: Pollution and other environmental. */
+  static constexpr int CMAS_CATEGORY_ENV = 0x07;
+
+  /** CMAS alert category: Public and private transportation. */
+  static constexpr int CMAS_CATEGORY_TRANSPORT = 0x08;
+
+  /** CMAS alert category: Utility, telecom, other non-transport infrastructure. */
+  static constexpr int CMAS_CATEGORY_INFRA = 0x09;
+
+  /** CMAS alert category: Chem, bio, radiological, nuclear, high explosive threat or attack. */
+  static constexpr int CMAS_CATEGORY_CBRNE = 0x0a;
+
+  /** CMAS alert category: Other events. */
+  static constexpr int CMAS_CATEGORY_OTHER = 0x0b;
+
+  /**
+   * CMAS alert category is unknown. The category is only available for CDMA broadcasts
+   * containing a type 1 elements record, so GSM and UMTS broadcasts always return unknown.
+   */
+  static constexpr int CMAS_CATEGORY_UNKNOWN = -1;
+
+  // CMAS response type (in CDMA type 1 elements record).
+
+  /** CMAS response type: Take shelter in place. */
+  static constexpr int CMAS_RESPONSE_TYPE_SHELTER = 0x00;
+
+  /** CMAS response type: Evacuate (Relocate). */
+  static constexpr int CMAS_RESPONSE_TYPE_EVACUATE = 0x01;
+
+  /** CMAS response type: Make preparations. */
+  static constexpr int CMAS_RESPONSE_TYPE_PREPARE = 0x02;
+
+  /** CMAS response type: Execute a pre-planned activity. */
+  static constexpr int CMAS_RESPONSE_TYPE_EXECUTE = 0x03;
+
+  /** CMAS response type: Attend to information sources. */
+  static constexpr int CMAS_RESPONSE_TYPE_MONITOR = 0x04;
+
+  /** CMAS response type: Avoid hazard. */
+  static constexpr int CMAS_RESPONSE_TYPE_AVOID = 0x05;
+
+  /** CMAS response type: Evaluate the information in this message (not for public warnings). */
+  static constexpr int CMAS_RESPONSE_TYPE_ASSESS = 0x06;
+
+  /** CMAS response type: No action recommended. */
+  static constexpr int CMAS_RESPONSE_TYPE_NONE = 0x07;
+
+  /**
+   * CMAS response type is unknown. The response type is only available for CDMA broadcasts
+   * containing a type 1 elements record, so GSM and UMTS broadcasts always return unknown.
+   */
+  static constexpr int CMAS_RESPONSE_TYPE_UNKNOWN = -1;
+
+  // 4-bit CMAS severity (in GSM/UMTS message identifier or CDMA type 1 elements record).
+
+  /** CMAS severity type: Extraordinary threat to life or property. */
+  static constexpr int CMAS_SEVERITY_EXTREME = 0x0;
+
+  /** CMAS severity type: Significant threat to life or property. */
+  static constexpr int CMAS_SEVERITY_SEVERE = 0x1;
+
+  /**
+   * CMAS alert severity is unknown. The severity is available for CDMA warning alerts
+   * containing a type 1 elements record and for all GSM and UMTS alerts except for the
+   * Presidential-level alert class (Korean Public Alert System Class 0).
+   */
+  static constexpr int CMAS_SEVERITY_UNKNOWN = -1;
+
+  // CMAS urgency (in GSM/UMTS message identifier or CDMA type 1 elements record).
+
+  /** CMAS urgency type: Responsive action should be taken immediately. */
+  static constexpr int CMAS_URGENCY_IMMEDIATE = 0x0;
+
+  /** CMAS urgency type: Responsive action should be taken within the next hour. */
+  static constexpr int CMAS_URGENCY_EXPECTED = 0x1;
+
+  /**
+   * CMAS alert urgency is unknown. The urgency is available for CDMA warning alerts
+   * containing a type 1 elements record and for all GSM and UMTS alerts except for the
+   * Presidential-level alert class (Korean Public Alert System Class 0).
+   */
+  static constexpr int CMAS_URGENCY_UNKNOWN = -1;
+
+  // CMAS certainty (in GSM/UMTS message identifier or CDMA type 1 elements record).
+
+  /** CMAS certainty type: Determined to have occurred or to be ongoing. */
+  static constexpr int CMAS_CERTAINTY_OBSERVED = 0x0;
+
+  /** CMAS certainty type: Likely (probability > ~50%). */
+  static constexpr int CMAS_CERTAINTY_LIKELY = 0x1;
+
+  /**
+   * CMAS alert certainty is unknown. The certainty is available for CDMA warning alerts
+   * containing a type 1 elements record and for all GSM and UMTS alerts except for the
+   * Presidential-level alert class (Korean Public Alert System Class 0).
+   */
+  static constexpr int CMAS_CERTAINTY_UNKNOWN = -1;
+
+  /**
+   * Returns the CMAS message class, e.g. {@link #CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT}.
+   * @return one of the {@code CMAS_CLASS} values
+   */
+  int getMessageClass() {
+    return mMessageClass;
+  }
+
+  /**
+   * Returns the CMAS category, e.g. {@link #CMAS_CATEGORY_GEO}.
+   * @return one of the {@code CMAS_CATEGORY} values
+   */
+  int getCategory() {
+    return mCategory;
+  }
+
+  /**
+   * Returns the CMAS response type, e.g. {@link #CMAS_RESPONSE_TYPE_SHELTER}.
+   * @return one of the {@code CMAS_RESPONSE_TYPE} values
+   */
+  int getResponseType() {
+    return mResponseType;
+  }
+
+  /**
+   * Returns the CMAS severity, e.g. {@link #CMAS_SEVERITY_EXTREME}.
+   * @return one of the {@code CMAS_SEVERITY} values
+   */
+  int getSeverity() {
+    return mSeverity;
+  }
+
+  /**
+   * Returns the CMAS urgency, e.g. {@link #CMAS_URGENCY_IMMEDIATE}.
+   * @return one of the {@code CMAS_URGENCY} values
+   */
+  int getUrgency() {
+    return mUrgency;
+  }
+
+  /**
+   * Returns the CMAS certainty, e.g. {@link #CMAS_CERTAINTY_OBSERVED}.
+   * @return one of the {@code CMAS_CERTAINTY} values
+   */
+  int getCertainty() {
+    return mCertainty;
+  }
+
+  std::string toString() {
+    return "SmsCbCmasInfo{messageClass=" + std::to_string(mMessageClass)
+        + ", category=" + std::to_string(mCategory) + ", responseType="
+        + std::to_string(mResponseType) + ", severity="
+        + std::to_string(mSeverity) + ", urgency=" + std::to_string(mUrgency)
+        + ", certainty=" + std::to_string(mCertainty) + '}';
+  }
+
+  /**
+   * Describe the kinds of special objects contained in the marshalled representation.
+   * @return a bitmask indicating this Parcelable contains no special objects
+   */
+  int describeContents() {
+    return 0;
+  }
+
+private:
+  /** CMAS message class. */
+  int mMessageClass;
+
+  /** CMAS category. */
+  int mCategory;
+
+  /** CMAS response type. */
+  int mResponseType;
+
+  /** CMAS severity. */
+  int mSeverity;
+
+  /** CMAS urgency. */
+  int mUrgency;
+
+  /** CMAS certainty. */
+  int mCertainty;
+};
+
+#endif /* SMSCBCMASINFO_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsConstants.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsConstants.cpp
new file mode 100644
index 0000000..dcd0d4c
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsConstants.cpp
@@ -0,0 +1,39 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include "SmsConstants.h"
+const std::string SmsConstants::FORMAT_UNKNOWN = "unknown";
+const std::string SmsConstants::FORMAT_3GPP = "3gpp";
+const std::string SmsConstants::FORMAT_3GPP2 = "3gpp2";
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsConstants.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsConstants.h
new file mode 100644
index 0000000..740e33f
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsConstants.h
@@ -0,0 +1,97 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef SMSCONSTANTS_H_
+#define SMSCONSTANTS_H_
+
+#include <string>
+class SmsConstants {
+public:
+  /** User data text encoding code unit size */
+  static constexpr int ENCODING_UNKNOWN = 0;
+  static constexpr int ENCODING_7BIT = 1;
+  static constexpr int ENCODING_8BIT = 2;
+  static constexpr int ENCODING_16BIT = 3;
+
+  /** The maximum number of payload septets per message */
+  static constexpr int MAX_USER_DATA_SEPTETS = 160;
+
+  /**
+   * The maximum number of payload septets per message if a user data header
+   * is present.  This assumes the header only contains the
+   * CONCATENATED_8_BIT_REFERENCE element.
+   */
+  static constexpr int MAX_USER_DATA_SEPTETS_WITH_HEADER = 153;
+
+  /**
+   * This value is not defined in global standard. Only in Korea, this is used.
+   */
+  static constexpr int ENCODING_KSC5601 = 4;
+
+  /** The maximum number of payload bytes per message */
+  static constexpr int MAX_USER_DATA_BYTES = 140;
+
+  /**
+   * The maximum number of payload bytes per message if a user data header
+   * is present.  This assumes the header only contains the
+   * CONCATENATED_8_BIT_REFERENCE element.
+   */
+  static constexpr int MAX_USER_DATA_BYTES_WITH_HEADER = 134;
+  /**
+   * SMS Class enumeration.
+   * See TS 23.038.
+   */
+  enum MessageClass {
+    UNKNOWN, CLASS_0, CLASS_1, CLASS_2, CLASS_3
+  };
+  /**
+   * Indicates unknown format SMS message.
+   * @hide pending API council approval
+   */
+  static const std::string FORMAT_UNKNOWN;
+  /**
+   * Indicates a 3GPP format SMS message.
+   * @hide pending API council approval
+   */
+  static const std::string FORMAT_3GPP;
+
+  /**
+   * Indicates a 3GPP2 format SMS message.
+   * @hide pending API council approval
+   */
+  static const std::string FORMAT_3GPP2;
+};
+
+#endif /* SMSCONSTANTS_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsEnvelope.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsEnvelope.cpp
new file mode 100644
index 0000000..f229b0c
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsEnvelope.cpp
@@ -0,0 +1,45 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include "SmsEnvelope.h"
+SmsEnvelope::SmsEnvelope() {
+  // TODO Auto-generated constructor stub
+
+}
+
+SmsEnvelope::~SmsEnvelope() {
+  // TODO Auto-generated destructor stub
+}
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsEnvelope.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsEnvelope.h
new file mode 100644
index 0000000..e3c0f02
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsEnvelope.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SMSENVELOPE_H_
+#define SMSENVELOPE_H_
+
+#include <cstdint>
+#include <memory>
+#include <vector>
+#include "CdmaSmsAddress.h"
+#include "CdmaSmsSubaddress.h"
+
+class SmsEnvelope {
+public:
+  SmsEnvelope();
+  virtual ~SmsEnvelope();
+  /**
+   * Message Types
+   * (See 3GPP2 C.S0015-B 3.4.1)
+   */
+  static constexpr int MESSAGE_TYPE_POINT_TO_POINT = 0x00;
+  static constexpr int MESSAGE_TYPE_BROADCAST = 0x01;
+  static constexpr int MESSAGE_TYPE_ACKNOWLEDGE = 0x02;
+
+  /**
+   * Supported Teleservices
+   * (See 3GPP2 N.S0005 and TIA-41)
+   */
+  static constexpr int TELESERVICE_NOT_SET = 0x0000;
+  static constexpr int TELESERVICE_WMT = 0x1002;
+  static constexpr int TELESERVICE_VMN = 0x1003;
+  static constexpr int TELESERVICE_WAP = 0x1004;
+  static constexpr int TELESERVICE_WEMT = 0x1005;
+  static constexpr int TELESERVICE_SCPT = 0x1006;
+
+  /**
+   * The following are defined as extensions to the standard teleservices
+   */
+  // Voice mail notification through Message Waiting Indication in CDMA mode or Analog mode.
+  // Defined in 3GPP2 C.S-0005, 3.7.5.6, an Info Record containing an 8-bit number with the
+  // number of messages waiting, it's used by some CDMA carriers for a voice mail count.
+  static constexpr int TELESERVICE_MWI = 0x40000;
+
+  // Service Categories for Cell Broadcast, see 3GPP2 C.R1001 table 9.3.1-1
+  // static final int SERVICE_CATEGORY_EMERGENCY      = 0x0001;
+  //...
+
+  // CMAS alert service category assignments, see 3GPP2 C.R1001 table 9.3.3-1
+  static constexpr int SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT = 0x1000;
+  static constexpr int SERVICE_CATEGORY_CMAS_EXTREME_THREAT = 0x1001;
+  static constexpr int SERVICE_CATEGORY_CMAS_SEVERE_THREAT = 0x1002;
+  static constexpr int SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY = 0x1003;
+  static constexpr int SERVICE_CATEGORY_CMAS_TEST_MESSAGE = 0x1004;
+  static constexpr int SERVICE_CATEGORY_CMAS_LAST_RESERVED_VALUE = 0x10ff;
+
+  /**
+   * Provides the type of a SMS message like point to point, broadcast or acknowledge
+   */
+  int messageType;
+
+  /**
+   * The 16-bit Teleservice parameter identifies which upper layer service access point is sending
+   * or receiving the message.
+   * (See 3GPP2 C.S0015-B, v2, 3.4.3.1)
+   */
+  int teleService = TELESERVICE_NOT_SET;
+
+  /**
+   * The 16-bit service category parameter identifies the type of service provided
+   * by the SMS message.
+   * (See 3GPP2 C.S0015-B, v2, 3.4.3.2)
+   */
+  int serviceCategory;
+
+  /**
+   * The origination address identifies the originator of the SMS message.
+   * (See 3GPP2 C.S0015-B, v2, 3.4.3.3)
+   */
+  std::shared_ptr<CdmaSmsAddress> origAddress = nullptr;
+
+  /**
+   * The destination address identifies the target of the SMS message.
+   * (See 3GPP2 C.S0015-B, v2, 3.4.3.3)
+   */
+  std::shared_ptr<CdmaSmsAddress> destAddress = nullptr;
+
+  /**
+   * The origination subaddress identifies the originator of the SMS message.
+   * (See 3GPP2 C.S0015-B, v2, 3.4.3.4)
+   */
+  std::shared_ptr<CdmaSmsSubaddress> origSubaddress = nullptr;
+
+  /**
+   * The 6-bit bearer reply parameter is used to request the return of a
+   * SMS Acknowledge Message.
+   * (See 3GPP2 C.S0015-B, v2, 3.4.3.5)
+   */
+  int bearerReply;
+
+  /**
+   * Cause Code values:
+   * The cause code parameters are an indication whether an SMS error has occurred and if so,
+   * whether the condition is considered temporary or permanent.
+   * ReplySeqNo 6-bit value,
+   * ErrorClass 2-bit value,
+   * CauseCode 0-bit or 8-bit value
+   * (See 3GPP2 C.S0015-B, v2, 3.4.3.6)
+   */
+  uint8_t replySeqNo;
+  uint8_t errorClass;
+  uint8_t causeCode;
+
+  /**
+   * encoded bearer data
+   * (See 3GPP2 C.S0015-B, v2, 3.4.3.7)
+   */
+  std::vector<uint8_t> bearerData;
+//  uint8_t* bearerData;
+//  uint32_t bearerData_length;
+
+};
+
+#endif /* SMSENVELOPE_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsHeader.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsHeader.cpp
new file mode 100644
index 0000000..4c38581
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsHeader.cpp
@@ -0,0 +1,244 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include <memory>
+#include <vector>
+#include <string>
+using namespace std;
+
+#include "SmsHeader.h"
+#include "HexDump.h"
+
+SmsHeader::SmsHeader() {
+  // TODO Auto-generated constructor stub
+
+}
+
+SmsHeader::~SmsHeader() {
+  // TODO Auto-generated destructor stub
+}
+
+std::shared_ptr<SmsHeader> SmsHeader::fromByteArray(std::vector<uint8_t> v) {
+  //ByteArrayInputStream inStream = new ByteArrayInputStream(data);
+  //uint8_t* temp = data;
+  std::shared_ptr<SmsHeader> smsHeader = std::make_shared<SmsHeader>();
+  auto beg = v.begin();
+  while (beg < v.end() ) {
+    /**
+     * NOTE: as defined in the spec, ConcatRef and PortAddr
+     * fields should not reoccur, but if they do the last
+     * occurrence is to be used.  Also, for ConcatRef
+     * elements, if the count is zero, sequence is zero, or
+     * sequence is larger than count, the entire element is to
+     * be ignored.
+     */
+    int id = (*(beg++));
+    int len = (*(beg++));
+    std::shared_ptr<ConcatRef> concatRef;
+    std::shared_ptr<PortAddrs> portAddrs;
+    switch (id) {
+    case ELT_ID_CONCATENATED_8_BIT_REFERENCE:
+    {
+      concatRef = make_shared<ConcatRef>();
+      concatRef->refNumber = (*(beg++));
+      concatRef->msgCount = (*(beg++));
+      concatRef->seqNumber = (*(beg++));
+      concatRef->isEightBits = true;
+      if (concatRef->msgCount != 0 && concatRef->seqNumber != 0
+          && concatRef->seqNumber <= concatRef->msgCount) {
+        smsHeader->concatRef = concatRef;
+      }
+      break;
+    }
+    case ELT_ID_CONCATENATED_16_BIT_REFERENCE:
+      concatRef = make_shared<ConcatRef>();
+      concatRef->refNumber = ((*(beg++)) << 8) | (*(beg++));
+      concatRef->msgCount = (*(beg++));
+      concatRef->seqNumber = (*(beg++));
+      concatRef->isEightBits = false;
+      if (concatRef->msgCount != 0 && concatRef->seqNumber != 0
+          && concatRef->seqNumber <= concatRef->msgCount) {
+        smsHeader->concatRef = concatRef;
+      }
+      break;
+    case ELT_ID_APPLICATION_PORT_ADDRESSING_8_BIT:
+      portAddrs = make_shared<PortAddrs>();
+      portAddrs->destPort = (*(beg++));
+      portAddrs->origPort = (*(beg++));
+      portAddrs->areEightBits = true;
+      smsHeader->portAddrs = portAddrs;
+      break;
+    case ELT_ID_APPLICATION_PORT_ADDRESSING_16_BIT:
+      portAddrs = make_shared<PortAddrs>();
+      portAddrs->destPort = ((*(beg++)) << 8) | (*(beg++));
+      portAddrs->origPort = ((*(beg++)) << 8) | (*(beg++));
+      portAddrs->areEightBits = false;
+      smsHeader->portAddrs = portAddrs;
+      break;
+    case ELT_ID_NATIONAL_LANGUAGE_SINGLE_SHIFT:
+      smsHeader->languageShiftTable = (*(beg++));
+      break;
+    case ELT_ID_NATIONAL_LANGUAGE_LOCKING_SHIFT:
+      smsHeader->languageTable = (*(beg++));
+      break;
+    case ELT_ID_SPECIAL_SMS_MESSAGE_INDICATION: {
+      auto specialSmsMsg = make_shared<SpecialSmsMsg>();
+      specialSmsMsg->msgIndType = (*(beg++));
+      specialSmsMsg->msgCount = (*(beg++));
+      smsHeader->specialSmsMsgList.push_back(specialSmsMsg);
+      break;
+    }
+    default:
+      auto miscElt = make_shared<MiscElt>();
+      miscElt->id = id;
+      //miscElt->data.insert(miscElt->data.end(), beg, v.end());
+      smsHeader->miscEltList.push_back(miscElt);
+      break;
+    }
+  }
+  return smsHeader;
+}
+
+std::vector<uint8_t> SmsHeader::toByteArray(
+    std::shared_ptr<SmsHeader> smsHeader) {
+  std::vector<uint8_t> temp;
+  temp.clear();
+  if ((smsHeader->portAddrs == nullptr) && (smsHeader->concatRef == nullptr)
+      && (smsHeader->specialSmsMsgList.empty())
+      && (smsHeader->miscEltList.empty())
+      && (smsHeader->languageShiftTable == 0)
+      && (smsHeader->languageTable == 0)) {
+    return temp;
+  }
+
+  auto concatRef = smsHeader->concatRef;
+  if (concatRef != nullptr) {
+    if (concatRef->isEightBits) {
+      temp.push_back(ELT_ID_CONCATENATED_8_BIT_REFERENCE);
+      temp.push_back(3);
+      temp.push_back(concatRef->refNumber);
+    } else {
+      temp.push_back(ELT_ID_CONCATENATED_16_BIT_REFERENCE);
+      temp.push_back(4);
+      temp.push_back(concatRef->refNumber >> 8);
+      temp.push_back(concatRef->refNumber & 0x00FF);
+    }
+    temp.push_back(concatRef->msgCount);
+    temp.push_back(concatRef->seqNumber);
+  }
+  auto portAddrs = smsHeader->portAddrs;
+  if (portAddrs != nullptr) {
+    if (portAddrs->areEightBits) {
+      temp.push_back(ELT_ID_APPLICATION_PORT_ADDRESSING_8_BIT);
+      temp.push_back(2);
+      temp.push_back(portAddrs->destPort);
+      temp.push_back(portAddrs->origPort);
+    } else {
+      temp.push_back(ELT_ID_APPLICATION_PORT_ADDRESSING_16_BIT);
+      temp.push_back(4);
+      temp.push_back(portAddrs->destPort >> 8);
+      temp.push_back(portAddrs->destPort & 0x00FF);
+      temp.push_back(portAddrs->origPort >> 8);
+      temp.push_back(portAddrs->origPort & 0x00FF);
+    }
+  }
+  if (smsHeader->languageShiftTable != 0) {
+    temp.push_back(ELT_ID_NATIONAL_LANGUAGE_SINGLE_SHIFT);
+    temp.push_back(1);
+    temp.push_back(smsHeader->languageShiftTable);
+  }
+  if (smsHeader->languageTable != 0) {
+    temp.push_back(ELT_ID_NATIONAL_LANGUAGE_LOCKING_SHIFT);
+    temp.push_back(1);
+    temp.push_back(smsHeader->languageTable);
+  }
+  for (auto specialSmsMsg : smsHeader->specialSmsMsgList) {
+    temp.push_back(ELT_ID_SPECIAL_SMS_MESSAGE_INDICATION);
+    temp.push_back(2);
+    temp.push_back(specialSmsMsg->msgIndType & 0xFF);
+    temp.push_back(specialSmsMsg->msgCount & 0xFF);
+  }
+  for (auto miscElt : smsHeader->miscEltList) {
+    temp.push_back(miscElt->id);
+    temp.push_back(miscElt->data.size());
+    temp.insert(temp.end(), miscElt->data.begin(), miscElt->data.end());
+  }
+  return temp;
+}
+
+std::string SmsHeader::toString() {
+  string builder;
+  builder.append("UserDataHeader ");
+  builder.append("{ ConcatRef ");
+  if (concatRef == nullptr) {
+    builder.append("unset");
+  } else {
+    builder.append("{ refNumber=" + std::to_string(concatRef->refNumber));
+    builder.append(", msgCount=" + std::to_string(concatRef->msgCount));
+    builder.append(", seqNumber=" + std::to_string(concatRef->seqNumber));
+    builder.append(", isEightBits=" + std::to_string(concatRef->isEightBits));
+    builder.append(" }");
+  }
+  builder.append(", PortAddrs ");
+  if (portAddrs == nullptr) {
+    builder.append("unset");
+  } else {
+    builder.append("{ destPort=" + std::to_string(portAddrs->destPort));
+    builder.append(", origPort=" + std::to_string(portAddrs->origPort));
+    builder.append(", areEightBits=" + std::to_string(portAddrs->areEightBits));
+    builder.append(" }");
+  }
+  if (languageShiftTable != 0) {
+    builder.append(
+        ", languageShiftTable=" + std::to_string(languageShiftTable));
+  }
+  if (languageTable != 0) {
+    builder.append(", languageTable=" + std::to_string(languageTable));
+  }
+  for (auto specialSmsMsg : specialSmsMsgList) {
+    builder.append(", SpecialSmsMsg ");
+    builder.append("{ msgIndType=" + std::to_string(specialSmsMsg->msgIndType));
+    builder.append(", msgCount=" + std::to_string(specialSmsMsg->msgCount));
+    builder.append(" }");
+  }
+  for (auto miscElt : miscEltList) {
+    builder.append(", MiscElt ");
+    builder.append("{ id=" + std::to_string(miscElt->id));
+    builder.append(", length=" + std::to_string((int) miscElt->data.size()));
+    builder.append(", data=" + HexDump::toHexString(miscElt->data));
+    builder.append(" }");
+  }
+  builder.append(" }");
+  return builder;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsHeader.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsHeader.h
new file mode 100644
index 0000000..cd1369c
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsHeader.h
@@ -0,0 +1,140 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef SMSHEADER_H_
+#define SMSHEADER_H_
+#include <cstdint>
+#include <list>
+#include <memory>
+#include <vector>
+#include <string>
+class SmsHeader {
+public:
+  SmsHeader();
+  virtual ~SmsHeader();
+
+  // TODO(cleanup): this data structure is generally referred to as
+  // the 'user data header' or UDH, and so the class name should
+  // change to reflect this...
+
+  /** SMS user data header information element identifiers.
+   * (see TS 23.040 9.2.3.24)
+   */
+  static constexpr int ELT_ID_CONCATENATED_8_BIT_REFERENCE = 0x00;
+  static constexpr int ELT_ID_SPECIAL_SMS_MESSAGE_INDICATION = 0x01;
+  static constexpr int ELT_ID_APPLICATION_PORT_ADDRESSING_8_BIT = 0x04;
+  static constexpr int ELT_ID_APPLICATION_PORT_ADDRESSING_16_BIT = 0x05;
+  static constexpr int ELT_ID_SMSC_CONTROL_PARAMS = 0x06;
+  static constexpr int ELT_ID_UDH_SOURCE_INDICATION = 0x07;
+  static constexpr int ELT_ID_CONCATENATED_16_BIT_REFERENCE = 0x08;
+  static constexpr int ELT_ID_WIRELESS_CTRL_MSG_PROTOCOL = 0x09;
+  static constexpr int ELT_ID_TEXT_FORMATTING = 0x0A;
+  static constexpr int ELT_ID_PREDEFINED_SOUND = 0x0B;
+  static constexpr int ELT_ID_USER_DEFINED_SOUND = 0x0C;
+  static constexpr int ELT_ID_PREDEFINED_ANIMATION = 0x0D;
+  static constexpr int ELT_ID_LARGE_ANIMATION = 0x0E;
+  static constexpr int ELT_ID_SMALL_ANIMATION = 0x0F;
+  static constexpr int ELT_ID_LARGE_PICTURE = 0x10;
+  static constexpr int ELT_ID_SMALL_PICTURE = 0x11;
+  static constexpr int ELT_ID_VARIABLE_PICTURE = 0x12;
+  static constexpr int ELT_ID_USER_PROMPT_INDICATOR = 0x13;
+  static constexpr int ELT_ID_EXTENDED_OBJECT = 0x14;
+  static constexpr int ELT_ID_REUSED_EXTENDED_OBJECT = 0x15;
+  static constexpr int ELT_ID_COMPRESSION_CONTROL = 0x16;
+  static constexpr int ELT_ID_OBJECT_DISTR_INDICATOR = 0x17;
+  static constexpr int ELT_ID_STANDARD_WVG_OBJECT = 0x18;
+  static constexpr int ELT_ID_CHARACTER_SIZE_WVG_OBJECT = 0x19;
+  static constexpr int ELT_ID_EXTENDED_OBJECT_DATA_REQUEST_CMD = 0x1A;
+  static constexpr int ELT_ID_RFC_822_EMAIL_HEADER = 0x20;
+  static constexpr int ELT_ID_HYPERLINK_FORMAT_ELEMENT = 0x21;
+  static constexpr int ELT_ID_REPLY_ADDRESS_ELEMENT = 0x22;
+  static constexpr int ELT_ID_ENHANCED_VOICE_MAIL_INFORMATION = 0x23;
+  static constexpr int ELT_ID_NATIONAL_LANGUAGE_SINGLE_SHIFT = 0x24;
+  static constexpr int ELT_ID_NATIONAL_LANGUAGE_LOCKING_SHIFT = 0x25;
+
+  static constexpr int PORT_WAP_PUSH = 2948;
+  static constexpr int PORT_WAP_WSP = 9200;
+
+  class PortAddrs {
+  public:
+    int destPort;
+    int origPort;
+    bool areEightBits;
+  };
+
+  class ConcatRef {
+  public:
+    int refNumber;
+    int seqNumber;
+    int msgCount;
+    bool isEightBits;
+  };
+
+  class SpecialSmsMsg {
+  public:
+    int msgIndType;
+    int msgCount;
+  };
+
+  /**
+   * A header element that is not explicitly parsed, meaning not
+   * PortAddrs or ConcatRef or SpecialSmsMsg.
+   */
+  class MiscElt {
+  public:
+    int id;
+    std::vector<uint8_t> data;
+    //uint8_t* data; //Remember to free
+    //uint32_t data_length;
+  };
+
+  std::shared_ptr<PortAddrs> portAddrs = nullptr;
+  std::shared_ptr<ConcatRef> concatRef;
+  std::list<std::shared_ptr<SpecialSmsMsg>> specialSmsMsgList;
+  std::list<std::shared_ptr<MiscElt>> miscEltList;
+  //list<SpecialSmsMsg> specialSmsMsgList = new ArrayList<SpecialSmsMsg>();
+  //ArrayList<MiscElt> miscEltList = new ArrayList<MiscElt>();
+
+  /** 7 bit national language locking shift table, or 0 for GSM default 7 bit alphabet. */
+  int languageTable;
+
+  /** 7 bit national language single shift table, or 0 for GSM default 7 bit extension table. */
+  int languageShiftTable;
+  static std::shared_ptr<SmsHeader> fromByteArray(std::vector<uint8_t> v);
+  static std::vector<uint8_t> toByteArray(std::shared_ptr<SmsHeader> smsHeader);
+  std::string toString();
+};
+
+#endif /* SMSHEADER_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsMessage.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsMessage.cpp
new file mode 100644
index 0000000..771e861
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsMessage.cpp
@@ -0,0 +1,416 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <memory>
+#include <iostream>
+#include <numeric>
+using namespace std;
+
+#include <log/log.h>
+
+#include "SmsMessage.h"
+#include "BearerData.h"
+#include "HexDump.h";
+
+#undef LOG_TAG
+#define LOG_TAG "DEMO_CDMA_SMS"
+
+uint32_t SmsMessage::mPos = 0;
+SmsMessage::SmsMessage(std::shared_ptr<SmsAddress> addr,std::shared_ptr<SmsEnvelope> env) {
+  mOriginatingAddress = addr;
+  mEnvelope = env;
+  createPdu();
+}
+
+SmsMessage::SmsMessage() {
+  // TODO Auto-generated constructor stub
+
+}
+
+SmsMessage::~SmsMessage() {
+  // TODO Auto-generated destructor stub
+}
+
+uint8_t SmsMessage::convertDtmfToAscii(uint8_t dtmfDigit) {
+  uint8_t asciiDigit;
+
+  switch (dtmfDigit) {
+  case 0:
+    asciiDigit = 68;
+    break; // 'D'
+  case 1:
+    asciiDigit = 49;
+    break; // '1'
+  case 2:
+    asciiDigit = 50;
+    break; // '2'
+  case 3:
+    asciiDigit = 51;
+    break; // '3'
+  case 4:
+    asciiDigit = 52;
+    break; // '4'
+  case 5:
+    asciiDigit = 53;
+    break; // '5'
+  case 6:
+    asciiDigit = 54;
+    break; // '6'
+  case 7:
+    asciiDigit = 55;
+    break; // '7'
+  case 8:
+    asciiDigit = 56;
+    break; // '8'
+  case 9:
+    asciiDigit = 57;
+    break; // '9'
+  case 10:
+    asciiDigit = 48;
+    break; // '0'
+  case 11:
+    asciiDigit = 42;
+    break; // '*'
+  case 12:
+    asciiDigit = 35;
+    break; // '#'
+  case 13:
+    asciiDigit = 65;
+    break; // 'A'
+  case 14:
+    asciiDigit = 66;
+    break; // 'B'
+  case 15:
+    asciiDigit = 67;
+    break; // 'C'
+  default:
+    asciiDigit = 32; // Invalid DTMF code
+    break;
+  }
+
+  return asciiDigit;
+}
+
+void SmsMessage::writeInt(uint32_t data) {
+  mPdu.push_back((data >> 24) & 0xFF);
+  mPdu.push_back((data >> 16) & 0xFF);
+  mPdu.push_back((data >> 8) & 0xFF);
+  mPdu.push_back((data >> 0) & 0xFF);
+}
+
+uint32_t SmsMessage::readInt(std::vector<uint8_t> pdu) {
+  uint32_t temp = 0;
+  temp = (pdu[mPos++] << 24) & 0xFF000000;
+  temp |= (pdu[mPos++] << 16) & 0xFF0000;
+  temp |= (pdu[mPos++] << 8) & 0xFF00;
+  temp |= (pdu[mPos++] << 0) & 0xFF;
+  return temp;
+}
+
+void SmsMessage::writeVector(std::vector<uint8_t> v) {
+  mPdu.insert(mPdu.end(), v.begin(), v.end());
+}
+
+std::vector<uint8_t> SmsMessage::readVector(std::vector<uint8_t> v,
+    int length) {
+  std::vector<uint8_t> temp;
+  temp.insert(temp.end(), v.begin() + mPos, v.begin() + mPos + length);
+  mPos += length;
+  return temp;
+}
+
+void SmsMessage::writeByte(uint8_t data) {
+  mPdu.push_back(data);
+}
+
+uint8_t SmsMessage::readByte(std::vector<uint8_t> pdu) {
+  return mPdu[mPos++];
+}
+
+void SmsMessage::createPdu() {
+  auto env = mEnvelope;
+  auto addr = env->origAddress;
+  //ByteArrayOutputStream baos = new ByteArrayOutputStream(100);
+  //DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(baos));
+
+  writeInt(env->messageType);
+  writeInt(env->teleService);
+  writeInt(env->serviceCategory);
+
+  writeByte(addr->digitMode);
+  writeByte(addr->numberMode);
+  writeByte(addr->ton);
+  writeByte(addr->numberPlan);
+  writeByte(addr->numberOfDigits);
+  writeVector(addr->origBytes); // digits
+
+  writeInt(env->bearerReply);
+  // CauseCode values:
+  writeByte(env->replySeqNo);
+  writeByte(env->errorClass);
+  writeByte(env->causeCode);
+  //encoded BearerData:
+  writeInt(env->bearerData.size());
+  writeVector(env->bearerData);
+}
+
+void SmsMessage::parsePdu(std::vector<uint8_t> pdu) {
+  int length;
+  int bearerDataLength;
+  auto env = std::make_shared<SmsEnvelope>();
+  auto addr = std::make_shared<CdmaSmsAddress>();
+  // We currently do not parse subaddress in PDU, but it is required when determining
+  // fingerprint (see getIncomingSmsFingerprint()).
+  auto subaddr = std::make_shared<CdmaSmsSubaddress>();
+  mPos = 0;
+  env->messageType = readInt(pdu);
+  env->teleService = readInt(pdu);
+  env->serviceCategory = readInt(pdu);
+
+  addr->digitMode = readByte(pdu);
+  addr->numberMode = readByte(pdu);
+  addr->ton = readByte(pdu);
+  addr->numberPlan = readByte(pdu);
+
+  length = readByte(pdu);
+  addr->numberOfDigits = length;
+
+  // sanity check on the length
+  if (length > pdu.size()) {
+    throw runtime_error(
+        "createFromPdu: Invalid pdu, addr.numberOfDigits "
+            + std::to_string(length) + " > pdu len "
+            + std::to_string(pdu.size()));
+  }
+  addr->origBytes = readVector(pdu, length); // digits
+  env->bearerReply = readInt(pdu);
+  // CauseCode values:
+  env->replySeqNo = readByte(pdu);
+  env->errorClass = readByte(pdu);
+  env->causeCode = readByte(pdu);
+
+  //encoded BearerData:
+  bearerDataLength = readInt(pdu);
+  // sanity check on the length
+  if (bearerDataLength > pdu.size()) {
+    throw runtime_error(
+        "createFromPdu: Invalid pdu, bearerDataLength "
+            + std::to_string(bearerDataLength) + " > pdu len "
+            + std::to_string(pdu.size()));
+  }
+  env->bearerData = readVector(pdu, bearerDataLength);
+  mPos = 0; // reset
+  // link the filled objects to this SMS
+  mOriginatingAddress = addr;
+  env->origAddress = addr;
+  env->origSubaddress = subaddr;
+  mEnvelope = env;
+  mPdu = pdu;
+
+  parseSms();
+}
+std::shared_ptr<SmsMessage> SmsMessage::createFromPdu(
+    std::vector<uint8_t> pdu) {
+  shared_ptr<SmsMessage> msg = make_shared<SmsMessage>();
+
+  msg->parsePdu(pdu);
+  return msg;
+//  try {
+//  } catch (RuntimeException ex) {
+//    Rlog.e(LOG_TAG, "SMS PDU parsing failed: ", ex);
+//    return null;
+//  } catch (OutOfMemoryError e) {
+//    Log.e(LOG_TAG, "SMS PDU parsing failed with out of memory: ", e);
+//    return null;
+//  }
+}
+
+SmsConstants::MessageClass SmsMessage::getMessageClass() {
+  if (BearerData::DISPLAY_MODE_IMMEDIATE == mBearerData->displayMode) {
+    return SmsConstants::MessageClass::CLASS_0;
+  } else {
+    return SmsConstants::MessageClass::UNKNOWN;
+  }
+}
+
+int SmsMessage::getMessageType() {
+  // NOTE: mEnvelope.messageType is not set correctly for cell broadcasts with some RILs.
+  // Use the service category parameter to detect CMAS and other cell broadcast messages.
+  if (mEnvelope->serviceCategory != 0) {
+    return SmsEnvelope::MESSAGE_TYPE_BROADCAST;
+  } else {
+    return SmsEnvelope::MESSAGE_TYPE_POINT_TO_POINT;
+  }
+}
+
+/**
+ * Note: This function is a GSM specific functionality which is not supported in CDMA mode.
+ */
+int SmsMessage::getProtocolIdentifier() {
+  //Rlog.w(LOG_TAG, "getProtocolIdentifier: is not supported in CDMA mode.");
+  // (3GPP TS 23.040): "no interworking, but SME to SME protocol":
+  return 0;
+}
+
+/**
+ * Note: This function is a GSM specific functionality which is not supported in CDMA mode.
+ */
+bool SmsMessage::isReplace() {
+  //Rlog.w(LOG_TAG, "isReplace: is not supported in CDMA mode.");
+  return false;
+}
+
+/**
+ * Note: This function is a GSM specific functionality which is not supported in CDMA mode.
+ */
+bool SmsMessage::isCphsMwiMessage() {
+  //Rlog.w(LOG_TAG, "isCphsMwiMessage: is not supported in CDMA mode.");
+  return false;
+}
+
+bool SmsMessage::isMWIClearMessage() {
+  return ((mBearerData != nullptr) && (mBearerData->numberOfMessages == 0));
+}
+
+bool SmsMessage::isMWISetMessage() {
+  return ((mBearerData != nullptr) && (mBearerData->numberOfMessages > 0));
+}
+
+bool SmsMessage::isMwiDontStore() {
+  return ((mBearerData != nullptr) && (mBearerData->numberOfMessages > 0)
+      && (mBearerData->userData == nullptr));
+}
+
+/**
+ * Returns the status for a previously submitted message.
+ * For not interfering with status codes from GSM, this status code is
+ * shifted to the bits 31-16.
+ */
+int SmsMessage::getStatus() {
+  return (status << 16);
+}
+
+/** Return true iff the bearer data message type is DELIVERY_ACK. */
+bool SmsMessage::isStatusReportMessage() {
+  return (mBearerData->messageType == BearerData::MESSAGE_TYPE_DELIVERY_ACK);
+}
+
+/**
+ * Note: This function is a GSM specific functionality which is not supported in CDMA mode.
+ */
+bool SmsMessage::isReplyPathPresent() {
+  //Rlog.w(LOG_TAG, "isReplyPathPresent: is not supported in CDMA mode.");
+  return false;
+}
+void SmsMessage::parseSms() {
+  // Message Waiting Info Record defined in 3GPP2 C.S-0005, 3.7.5.6
+  // It contains only an 8-bit number with the number of messages waiting
+  if (mEnvelope->teleService == SmsEnvelope::TELESERVICE_MWI) {
+    mBearerData = make_shared<BearerData>();
+    if (mEnvelope->bearerData.empty()) {
+      mBearerData->numberOfMessages = 0x000000FF & mEnvelope->bearerData[0];
+    }
+    std::cout << "parseSms: get MWI " << mBearerData->numberOfMessages << endl;
+    /*              if (VDBG) {
+     Rlog.d(LOG_TAG, "parseSms: get MWI " +
+     Integer.toString(mBearerData.numberOfMessages));
+     }*/
+    return;
+  }
+  mBearerData = BearerData::decode(mEnvelope->bearerData);
+  RLOGD("MT raw BearerData = '%s'", (HexDump::toHexString(mEnvelope->bearerData)).c_str());
+  RLOGD("MT raw BearerData = '%s'",(mBearerData->toString()).c_str());
+  //std::cout << "MT raw BearerData = '"
+  //    << HexDump::toHexString(mEnvelope->bearerData) << "'" << endl;
+  //std::cout << "MT (decoded) BearerData = " << mBearerData->toString() << endl;
+//          if (Rlog.isLoggable(LOGGABLE_TAG, Log.VERBOSE)) {
+//              Rlog.d(LOG_TAG, "MT raw BearerData = '" +
+//                        HexDump.toHexString(mEnvelope.bearerData) + "'");
+//              Rlog.d(LOG_TAG, "MT (decoded) BearerData = " + mBearerData);
+//          }
+  mMessageRef = mBearerData->messageId;
+  if (mBearerData->userData != nullptr) {
+    mUserData = mBearerData->userData->payload;
+    mUserDataHeader = mBearerData->userData->userDataHeader;
+    mMessageBody = mBearerData->userData->payloadStr;
+  }
+
+  if (mOriginatingAddress != nullptr) {
+    for(auto c: mOriginatingAddress->origBytes) {
+      mOriginatingAddress->address.push_back(c);
+    }
+    //std::accumulate(mOriginatingAddress->origBytes.begin(), mOriginatingAddress->origBytes.end(), mOriginatingAddress->address);
+    //mOriginatingAddress->address = HexDump::toHexString(mOriginatingAddress->origBytes);          // modify
+    if (mOriginatingAddress->ton == CdmaSmsAddress::TON_INTERNATIONAL_OR_IP) {
+      if (mOriginatingAddress->address.at(0) != '+') {
+        mOriginatingAddress->address = "+" + mOriginatingAddress->address;
+      }
+    }
+    //std::cout << "SMS originating address: " << mOriginatingAddress->address<< endl;
+//              if (VDBG) Rlog.v(LOG_TAG, "SMS originating address: "
+//                      + mOriginatingAddress.address);
+  }
+
+  //if (mBearerData->msgCenterTimeStamp != nullptr) {
+  //mScTimeMillis = mBearerData->msgCenterTimeStamp.toMillis(true);
+  //}
+
+  //if (VDBG) Rlog.d(LOG_TAG, "SMS SC timestamp: " + mScTimeMillis);
+
+  // Message Type (See 3GPP2 C.S0015-B, v2, 4.5.1)
+  if (mBearerData->messageType == BearerData::MESSAGE_TYPE_DELIVERY_ACK) {
+    // The BearerData MsgStatus subparameter should only be
+    // included for DELIVERY_ACK messages.  If it occurred for
+    // other messages, it would be unclear what the status
+    // being reported refers to.  The MsgStatus subparameter
+    // is primarily useful to indicate error conditions -- a
+    // message without this subparameter is assumed to
+    // indicate successful delivery (status == 0).
+    if (!mBearerData->messageStatusSet) {
+      std::cout << "DELIVERY_ACK message without msgStatus ("
+          << (mUserData.empty() ? "also missing" : "does have") << " userData)."
+          << endl;
+//                  Rlog.d(LOG_TAG, "DELIVERY_ACK message without msgStatus (" +
+//                          (mUserData == null ? "also missing" : "does have") +
+//                          " userData).");
+      status = 0;
+    } else {
+      status = mBearerData->errorClass << 8;
+      status |= mBearerData->messageStatus;
+    }
+  } else if (mBearerData->messageType != BearerData::MESSAGE_TYPE_DELIVER) {
+    throw runtime_error(
+        "Unsupported message type: " + mBearerData->messageType);
+  }
+
+  if (!mMessageBody.empty()) {
+    //std::cout << "SMS message body: '" << mMessageBody << "'" << endl;
+    //if (VDBG) Rlog.v(LOG_TAG, "SMS message body: '" + mMessageBody + "'");
+    parseMessageBody();
+  }
+}
+
+std::vector<std::uint8_t> SmsMessage::getIncomingSmsFingerprint() {
+    RLOGD("getIncomingSmsFingerprint: category=%d, teleservices=%d", mEnvelope->serviceCategory, mEnvelope->teleService);
+    std::vector<uint8_t> output;
+    output.push_back(static_cast<uint8_t> (mEnvelope->serviceCategory));
+    output.push_back(static_cast<uint8_t> (mEnvelope->teleService));
+    output.insert(output.end(), (mEnvelope->origAddress->origBytes).begin(), (mEnvelope->origAddress->origBytes).end());
+    output.insert(output.end(), (mEnvelope->bearerData).begin(), (mEnvelope->bearerData).end());
+    if(mEnvelope->origSubaddress && (!(mEnvelope->origSubaddress->origBytes).empty())) {
+        output.insert(output.end(), (mEnvelope->origSubaddress->origBytes).begin(), (mEnvelope->origSubaddress->origBytes).end());
+    }
+    return output;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsMessage.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsMessage.h
new file mode 100644
index 0000000..f003146
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsMessage.h
@@ -0,0 +1,121 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef SMSMESSAGE_H_
+#define SMSMESSAGE_H_
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "SmsMessageBase.h"
+#include "SmsEnvelope.h"
+#include "BearerData.h"
+
+class SmsMessage: public SmsMessageBase {
+public:
+  SmsMessage();
+  SmsMessage(std::shared_ptr<SmsAddress> addr,
+      std::shared_ptr<SmsEnvelope> env);
+  virtual ~SmsMessage();
+  class SubmitPdu: SubmitPduBase {
+  };
+  static std::shared_ptr<SmsMessage> createFromPdu(std::vector<uint8_t> pdu);
+  virtual SmsConstants::MessageClass getMessageClass() override;
+  virtual int getProtocolIdentifier() override;
+  virtual bool isReplace() override;
+  virtual bool isCphsMwiMessage() override;
+  virtual bool isMWIClearMessage() override;
+  virtual bool isMWISetMessage() override;
+  virtual bool isMwiDontStore() override;
+  virtual int getStatus() override;
+  virtual bool isStatusReportMessage() override;
+  virtual bool isReplyPathPresent() override;
+  //static std::shared_ptr<SmsMessage> createFromEfRecord(int index, uint8_t* data, int length);
+  int getTeleService() {
+    return mEnvelope->teleService;
+  }
+  int getMessageType();
+  void parseSms();
+  void createPdu();
+  std::vector<std::uint8_t> getIncomingSmsFingerprint();
+  static uint8_t convertDtmfToAscii(uint8_t dtmfDigit);
+private:
+
+  //void parsePduFromEfRecord(uint8_t* pdu, int length);
+  constexpr static uint8_t TELESERVICE_IDENTIFIER = 0x00;
+  constexpr static uint8_t SERVICE_CATEGORY = 0x01;
+  constexpr static uint8_t ORIGINATING_ADDRESS = 0x02;
+  constexpr static uint8_t ORIGINATING_SUB_ADDRESS = 0x03;
+  constexpr static uint8_t DESTINATION_ADDRESS = 0x04;
+  constexpr static uint8_t DESTINATION_SUB_ADDRESS = 0x05;
+  constexpr static uint8_t BEARER_REPLY_OPTION = 0x06;
+  constexpr static uint8_t CAUSE_CODES = 0x07;
+  constexpr static uint8_t BEARER_DATA = 0x08;
+
+  /**
+   *  Status of a previously submitted SMS.
+   *  This field applies to SMS Delivery Acknowledge messages. 0 indicates success;
+   *  Here, the error class is defined by the bits from 9-8, the status code by the bits from 7-0.
+   *  See C.S0015-B, v2.0, 4.5.21 for a detailed description of possible values.
+   */
+  int status = 0;
+
+  /** Specifies if a return of an acknowledgment is requested for send SMS */
+  static constexpr int RETURN_NO_ACK = 0;
+  static constexpr int RETURN_ACK = 1;
+
+  /**
+   * Supported priority modes for CDMA SMS messages
+   * (See 3GPP2 C.S0015-B, v2.0, table 4.5.9-1)
+   */
+  static constexpr int PRIORITY_NORMAL = 0x0;
+  static constexpr int PRIORITY_INTERACTIVE = 0x1;
+  static constexpr int PRIORITY_URGENT = 0x2;
+  static constexpr int PRIORITY_EMERGENCY = 0x3;
+
+  std::shared_ptr<SmsEnvelope> mEnvelope = nullptr;
+  std::shared_ptr<BearerData> mBearerData = nullptr;
+  static uint32_t mPos;
+  void writeInt(uint32_t data);
+  uint32_t readInt(std::vector<uint8_t> pdu);
+  void writeVector(std::vector<uint8_t> v);
+  std::vector<uint8_t> readVector(std::vector<uint8_t> v, int length);
+  void writeByte(uint8_t data);
+  uint8_t readByte(std::vector<uint8_t> pdu);
+  void parsePdu(std::vector<uint8_t> pdu);
+};
+
+#endif /* SMSMESSAGE_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsMessageBase.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsMessageBase.cpp
new file mode 100644
index 0000000..14a173a
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsMessageBase.cpp
@@ -0,0 +1,68 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include "SmsMessageBase.h"
+
+SmsMessageBase::SmsMessageBase() {
+  // TODO Auto-generated constructor stub
+
+}
+
+SmsMessageBase::~SmsMessageBase() {
+  // TODO Auto-generated destructor stub
+}
+
+void SmsMessageBase::parseMessageBody() {
+  if (mOriginatingAddress != nullptr
+      && mOriginatingAddress->couldBeEmailGateway()) {
+    extractEmailAddressFromMessageBody();
+  }
+}
+
+void SmsMessageBase::extractEmailAddressFromMessageBody() {
+  //TBD
+  // don't support
+  /* Some carriers may use " /" delimiter as below
+   *
+   * 1. [x@y][ ]/[subject][ ]/[body]
+   * -or-
+   * 2. [x@y][ ]/[body]
+   */
+//   String[] parts = mMessageBody.split("( /)|( )", 2);
+//   if (parts.length < 2) return;
+//   mEmailFrom = parts[0];
+//   mEmailBody = parts[1];
+//   mIsEmail = Telephony.Mms.isEmailAddress(mEmailFrom);
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsMessageBase.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsMessageBase.h
new file mode 100644
index 0000000..445e2f6
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsMessageBase.h
@@ -0,0 +1,320 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SMSMESSAGEBASE_H_
+#define SMSMESSAGEBASE_H_
+
+#include <cstdint>
+#include <string>
+#include <memory>
+#include <vector>
+#include "SmsAddress.h"
+#include "SmsConstants.h"
+#include "SmsHeader.h"
+#include "HexDump.h"
+
+class SmsMessageBase {
+public:
+  SmsMessageBase();
+  virtual ~SmsMessageBase();
+  /** TP-Message-Reference - Message Reference of sent message. @hide */
+  int mMessageRef = 0;
+  class SubmitPduBase {
+  public:
+    uint8_t* encodedScAddress = nullptr; // Null if not applicable.
+    uint32_t encodedScAddress_length = 0;
+    uint8_t* encodedMessage = nullptr;
+    uint32_t encodedMessage_length = 0;
+
+    std::string toString() {
+
+      return "SubmitPdu: encodedScAddress = "
+          + HexDump::dumpHexString(encodedScAddress, encodedScAddress_length)
+          + ", encodedMessage = "
+          + HexDump::dumpHexString(encodedMessage, encodedMessage_length);
+    }
+  };
+  /**
+   * Returns the address of the SMS service center that relayed this message
+   * or null if there is none.
+   */
+  std::string getServiceCenterAddress() {
+    return mScAddress;
+  }
+  std::string getOriginatingAddress() {
+    if (mOriginatingAddress == nullptr) {
+      return nullptr;
+    }
+
+    return mOriginatingAddress->getAddressString();
+  }
+  /**
+   * Returns the originating address, or email from address if this message
+   * was from an email gateway. Returns null if originating address
+   * unavailable.
+   */
+  std::string getDisplayOriginatingAddress() {
+    if (mIsEmail) {
+      return mEmailFrom;
+    } else {
+      return getOriginatingAddress();
+    }
+  }
+  /**
+   * Returns the message body as a String, if it exists and is text based.
+   * @return message body is there is one, otherwise null
+   */
+  std::string getMessageBody() {
+    return mMessageBody;
+  }
+
+  /**
+   * Returns the class of this message.
+   */
+  virtual SmsConstants::MessageClass getMessageClass() = 0;
+
+  /**
+   * Returns the message body, or email message body if this message was from
+   * an email gateway. Returns null if message body unavailable.
+   */
+  std::string getDisplayMessageBody() {
+    if (mIsEmail) {
+      return mEmailBody;
+    } else {
+      return getMessageBody();
+    }
+  }
+
+  /**
+   * Unofficial convention of a subject line enclosed in parens empty string
+   * if not present
+   */
+  std::string getPseudoSubject() {
+    return mPseudoSubject.empty() ? "" : mPseudoSubject;
+  }
+
+  /**
+   * Returns the service centre timestamp in currentTimeMillis() format
+   */
+  long getTimestampMillis() {
+    return mScTimeMillis;
+  }
+
+  /**
+   * Returns true if message is an email.
+   *
+   * @return true if this message came through an email gateway and email
+   *         sender / subject / parsed body are available
+   */
+  bool isEmail() {
+    return mIsEmail;
+  }
+
+  /**
+   * @return if isEmail() is true, body of the email sent through the gateway.
+   *         null otherwise
+   */
+  std::string getEmailBody() {
+    return mEmailBody;
+  }
+
+  /**
+   * @return if isEmail() is true, email from address of email sent through
+   *         the gateway. null otherwise
+   */
+  std::string getEmailFrom() {
+    return mEmailFrom;
+  }
+
+  /**
+   * Get protocol identifier.
+   */
+  virtual int getProtocolIdentifier() = 0;
+
+  /**
+   * See TS 23.040 9.2.3.9 returns true if this is a "replace short message"
+   * SMS
+   */
+  virtual bool isReplace() = 0;
+
+  /**
+   * Returns true for CPHS MWI toggle message.
+   *
+   * @return true if this is a CPHS MWI toggle message See CPHS 4.2 section
+   *         B.4.2
+   */
+  virtual bool isCphsMwiMessage() = 0;
+
+  /**
+   * returns true if this message is a CPHS voicemail / message waiting
+   * indicator (MWI) clear message
+   */
+  virtual bool isMWIClearMessage() = 0;
+
+  /**
+   * returns true if this message is a CPHS voicemail / message waiting
+   * indicator (MWI) set message
+   */
+  virtual bool isMWISetMessage() = 0;
+
+  /**
+   * returns true if this message is a "Message Waiting Indication Group:
+   * Discard Message" notification and should not be stored.
+   */
+  virtual bool isMwiDontStore() = 0;
+
+  /**
+   * returns the user data section minus the user data header if one was
+   * present.
+   */
+  std::vector<uint8_t> getUserData() {
+    return mUserData;
+  }
+
+  /**
+   * Returns an object representing the user data header
+   *
+   * {@hide}
+   */
+  std::shared_ptr<SmsHeader> getUserDataHeader() {
+    return mUserDataHeader;
+  }
+
+  /**
+   * TODO(cleanup): The term PDU is used in a seemingly non-unique
+   * manner -- for example, what is the difference between this byte
+   * array and the contents of SubmitPdu objects.  Maybe a more
+   * illustrative term would be appropriate.
+   */
+
+  /**
+   * Returns the raw PDU for the message.
+   */
+  std::vector<uint8_t> getPdu() {
+    return mPdu;
+  }
+
+  /**
+   * For an SMS-STATUS-REPORT message, this returns the status field from
+   * the status report.  This field indicates the status of a previously
+   * submitted SMS, if requested.  See TS 23.040, 9.2.3.15 TP-Status for a
+   * description of values.
+   *
+   * @return 0 indicates the previously sent message was received.
+   *         See TS 23.040, 9.9.2.3.15 for a description of other possible
+   *         values.
+   */
+  virtual int getStatus() = 0;
+
+  /**
+   * Return true iff the message is a SMS-STATUS-REPORT message.
+   */
+  virtual bool isStatusReportMessage() = 0;
+
+  /**
+   * Returns true iff the <code>TP-Reply-Path</code> bit is set in
+   * this message.
+   */
+  virtual bool isReplyPathPresent() = 0;
+
+  /**
+   * Returns the status of the message on the ICC (read, unread, sent, unsent).
+   *
+   * @return the status of the message on the ICC.  These are:
+   *         SmsManager.STATUS_ON_ICC_FREE
+   *         SmsManager.STATUS_ON_ICC_READ
+   *         SmsManager.STATUS_ON_ICC_UNREAD
+   *         SmsManager.STATUS_ON_ICC_SEND
+   *         SmsManager.STATUS_ON_ICC_UNSENT
+   */
+  int getStatusOnIcc() {
+    return mStatusOnIcc;
+  }
+
+  /**
+   * Returns the record index of the message on the ICC (1-based index).
+   * @return the record index of the message on the ICC, or -1 if this
+   *         SmsMessage was not created from a ICC SMS EF record.
+   */
+  int getIndexOnIcc() {
+    return mIndexOnIcc;
+  }
+protected:
+  void parseMessageBody();
+  void extractEmailAddressFromMessageBody();
+protected:
+  /** {@hide} The address of the SMSC. May be null */
+  std::string mScAddress;
+
+  /** {@hide} The address of the sender */
+  std::shared_ptr<SmsAddress> mOriginatingAddress = nullptr;
+
+  /** {@hide} The message body as a string. May be null if the message isn't text */
+  std::string mMessageBody;
+
+  /** {@hide} */
+  std::string mPseudoSubject;
+
+  /** {@hide} Non-null if this is an email gateway message */
+  std::string mEmailFrom;
+
+  /** {@hide} Non-null if this is an email gateway message */
+  std::string mEmailBody;
+
+  /** {@hide} */
+  bool mIsEmail = false;
+
+  /** {@hide} Time when SC (service centre) received the message */
+  long mScTimeMillis;
+
+  /** {@hide} The raw PDU of the message */
+  //uint8_t* mPdu = nullptr;
+  //uint32_t mPdu_length = 0;
+  std::vector<uint8_t> mPdu;
+
+  /** {@hide} The raw bytes for the user data section of the message */
+  std::vector<uint8_t> mUserData;
+//  uint8_t* mUserData = nullptr;
+//  uint32_t mUserData_length = 0;
+
+  /** {@hide} */
+
+  std::shared_ptr<SmsHeader> mUserDataHeader;
+
+  // "Message Waiting Indication Group"
+  // 23.038 Section 4
+  /** {@hide} */
+  bool mIsMwi = false;
+
+  /** {@hide} */
+  bool mMwiSense = false;
+
+  /** {@hide} */
+  bool mMwiDontStore = false;
+
+  /**
+   * Indicates status for messages stored on the ICC.
+   */
+  int mStatusOnIcc = -1;
+
+  /**
+   * Record index of message in the EF.
+   */
+  int mIndexOnIcc = -1;
+
+};
+
+#endif /* SMSMESSAGEBASE_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsMessageConverter.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsMessageConverter.cpp
new file mode 100644
index 0000000..fdc7b8b
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsMessageConverter.cpp
@@ -0,0 +1,153 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include <cstdint>
+#include <algorithm>
+#include "SmsMessageConverter.h"
+#include "SmsEnvelope.h"
+#include "CdmaSmsAddress.h"
+#include "CdmaSmsSubaddress.h"
+#include "SmsMessage.h"
+#include <log/log.h>
+
+#undef LOG_TAG
+#define LOG_TAG "DEMO_CDMA_SMS"
+SmsMessageConverter::SmsMessageConverter() {
+  // TODO Auto-generated constructor stub
+
+}
+
+SmsMessageConverter::~SmsMessageConverter() {
+  // TODO Auto-generated destructor stub
+}
+
+std::shared_ptr<SmsMessage> SmsMessageConverter::newCdmaSmsMessageFromRil(
+    RIL_CDMA_SMS_Message *p_cur) {
+  // Note: Parcel.readByte actually reads one Int and masks to byte
+  auto env = std::make_shared<SmsEnvelope>();
+  auto addr = std::make_shared<CdmaSmsAddress>();
+  auto subaddr = std::make_shared<CdmaSmsSubaddress>();
+  std::vector<uint8_t> data;
+  uint8_t count;
+  int countInt;
+  int addressDigitMode;
+
+  //currently not supported by the modem-lib: env.mMessageType
+  env->teleService = p_cur->uTeleserviceID;
+
+  if (p_cur->bIsServicePresent) {
+    env->messageType = SmsEnvelope::MESSAGE_TYPE_BROADCAST;
+  } else {
+    if (SmsEnvelope::TELESERVICE_NOT_SET == env->teleService) {
+      // assume type ACK
+      env->messageType = SmsEnvelope::MESSAGE_TYPE_ACKNOWLEDGE;
+    } else {
+      env->messageType = SmsEnvelope::MESSAGE_TYPE_POINT_TO_POINT;
+    }
+  }
+  env->serviceCategory = p_cur->uServicecategory;
+
+  // address
+  addressDigitMode = p_cur->sAddress.digit_mode;
+  addr->digitMode = (uint8_t) (0xFF & addressDigitMode);
+  addr->numberMode = (uint8_t) (0xFF & p_cur->sAddress.number_mode);
+  addr->ton = p_cur->sAddress.number_type;
+  addr->numberPlan = (uint8_t) (0xFF & p_cur->sAddress.number_plan);
+  count = std::min((p_cur->sAddress.number_of_digits), (uint8_t) RIL_CDMA_SMS_ADDRESS_MAX);
+  addr->numberOfDigits = count;
+  //data = new byte[count];
+  std::string str;
+  for (int index = 0; index < count; index++) {
+    data.push_back(p_cur->sAddress.digits[index]);
+    // convert the value if it is 4-bit DTMF to 8 bit
+    if (addressDigitMode == CdmaSmsAddress::DIGIT_MODE_4BIT_DTMF) {
+      data[index] = SmsMessage::convertDtmfToAscii(data[index]);
+      str.push_back((char)(data[index]));
+    }
+  }
+  if (addressDigitMode == CdmaSmsAddress::DIGIT_MODE_4BIT_DTMF) {
+      RLOGD("address: %s", str.empty() ? "": str.c_str());
+      printf("address: %s\n", str.empty() ? "": str.c_str());
+  }
+
+  addr->origBytes = data;
+
+  subaddr->type = p_cur->sSubAddress.subaddressType;
+  subaddr->odd = (uint8_t) (p_cur->sSubAddress.odd ? 1 : 0);
+  count = std::min((p_cur->sSubAddress.number_of_digits),
+      (uint8_t) RIL_CDMA_SMS_SUBADDRESS_MAX);
+
+  if (count < 0) {
+    count = 0;
+  }
+
+  // p_cur->sSubAddress.digits[digitCount] :
+
+  data.clear();
+
+  for (int index = 0; index < count; ++index) {
+    data.push_back(p_cur->sSubAddress.digits[index]);
+  }
+
+  subaddr->origBytes = data;
+
+  /* currently not supported by the modem-lib:
+   env.bearerReply
+   env.replySeqNo
+   env.errorClass
+   env.causeCode
+   */
+
+  // bearer data
+  countInt = std::min((p_cur->uBearerDataLen), RIL_CDMA_SMS_BEARER_DATA_MAX);
+  if (countInt < 0) {
+    countInt = 0;
+  }
+
+  data.clear();
+  for (int index = 0; index < countInt; index++) {
+    data.push_back(p_cur->aBearerData[index]);
+  }
+  // BD gets further decoded when accessed in SMSDispatcher
+  env->bearerData = data;
+
+  // link the the filled objects to the SMS
+  env->origAddress = addr;
+  env->origSubaddress = subaddr;
+
+  auto msg = std::make_shared<SmsMessage>(addr, env);
+
+  return msg;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsMessageConverter.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsMessageConverter.h
new file mode 100644
index 0000000..cf70a9a
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsMessageConverter.h
@@ -0,0 +1,51 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef SMSMESSAGECONVERTER_H_
+#define SMSMESSAGECONVERTER_H_
+
+#include <memory>
+#include "SmsMessage.h"
+#include "ril_cdma_sms.h"
+
+class SmsMessageConverter {
+public:
+  SmsMessageConverter();
+  virtual ~SmsMessageConverter();
+  static std::shared_ptr<SmsMessage> newCdmaSmsMessageFromRil(
+      RIL_CDMA_SMS_Message *p_cur);
+};
+
+#endif /* SMSMESSAGECONVERTER_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/UserData.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/UserData.cpp
new file mode 100644
index 0000000..6bf4ef4
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/UserData.cpp
@@ -0,0 +1,115 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include <string>
+#include <iostream>
+using namespace std;
+
+#include <log/log.h>
+#include "UserData.h"
+#include "HexDump.h"
+
+constexpr int UserData::ASCII_NL_INDEX;
+constexpr int UserData::ASCII_CR_INDEX;
+const char UserData::ASCII_MAP[] = { ' ', '!', '"', '#', '$', '%', '&', '\'',
+    '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6',
+    '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E',
+    'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
+    'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', '`', 'a', 'b', 'c',
+    'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
+    's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~' };
+
+const int UserData::ASCII_MAP_MAX_INDEX = ASCII_MAP_BASE_INDEX
+    + sizeof(ASCII_MAP) / sizeof(char) - 1;
+
+std::map<char, uint8_t> UserData::charToAscii = UserData::init();
+
+std::map<char, uint8_t> UserData::init() {
+  std::map<char, uint8_t> temp;
+  for (uint32_t i = 0; i < sizeof(ASCII_MAP) / sizeof(char); i++) {
+    temp.insert(
+        pair<char, uint8_t>(ASCII_MAP[i], PRINTABLE_ASCII_MIN_INDEX + i));
+  }
+  temp.insert(pair<char, uint8_t>('\n', ASCII_NL_INDEX));
+  temp.insert(pair<char, uint8_t>('\r', ASCII_CR_INDEX));
+  return temp;
+}
+
+//uint8_t* UserData::stringToAscii(string msg, int* length) {
+std::vector<uint8_t> UserData::stringToAscii(std::string msg) {
+  int len = msg.length();
+  //uint8_t* result = new uint8_t[len];
+  std::vector<uint8_t> result;
+  for (int i = 0; i < len; i++) {
+    uint8_t charCode;
+    try {
+      charCode = charToAscii.at(msg[i]);
+    } catch (const out_of_range &e) {
+      //TBD log.
+      return result;
+    }
+    result.push_back(charCode);
+    //result[i] = charCode;
+
+  }
+  return result;
+}
+
+UserData::UserData() {
+
+}
+
+UserData::~UserData() {
+
+}
+
+std::string UserData::toString() {
+  string builder;
+  builder.append("UserData ");
+  builder.append("{ msgEncoding=");
+  builder.append(msgEncodingSet ? std::to_string(msgEncoding) : "unset");
+  builder.append(", msgType=" + std::to_string(msgType));
+  builder.append(", paddingBits=" + std::to_string(paddingBits));
+  builder.append(", numFields=" + std::to_string(numFields));
+  builder.append(
+      ", userDataHeader="
+          + string(userDataHeader ? userDataHeader->toString() : "unset"));
+  builder.append(", payload='" + HexDump::toHexString(payload) + string("'"));
+  builder.append(", payloadStr='" + payloadStr + "'");
+  std::cout << "message content: " << payloadStr << std::endl;
+  RLOGD("[MT_CDMA_SMS]Message conetent: %s", payloadStr.c_str());
+  builder.append(" }");
+  return builder;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/UserData.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/UserData.h
new file mode 100644
index 0000000..0712e55
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/UserData.h
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef USERDATA_H_
+#define USERDATA_H_
+#include <cstdint>
+#include <string>
+#include <map>
+#include <memory>
+#include <vector>
+
+#include "SmsHeader.h"
+
+class UserData {
+public:
+  UserData();
+  virtual ~UserData();
+  std::string toString();
+  /**
+   * User data encoding types.
+   * (See 3GPP2 C.R1001-F, v1.0, table 9.1-1)
+   */
+  static constexpr int ENCODING_OCTET = 0x00;
+  static constexpr int ENCODING_IS91_EXTENDED_PROTOCOL = 0x01;
+  static constexpr int ENCODING_7BIT_ASCII = 0x02;
+  static constexpr int ENCODING_IA5 = 0x03;
+  static constexpr int ENCODING_UNICODE_16 = 0x04;
+  static constexpr int ENCODING_SHIFT_JIS = 0x05;
+  static constexpr int ENCODING_KOREAN = 0x06;
+  static constexpr int ENCODING_LATIN_HEBREW = 0x07;
+  static constexpr int ENCODING_LATIN = 0x08;
+  static constexpr int ENCODING_GSM_7BIT_ALPHABET = 0x09;
+  static constexpr int ENCODING_GSM_DCS = 0x0A;
+
+  /**
+   * User data message type encoding types.
+   * (See 3GPP2 C.S0015-B, 4.5.2 and 3GPP 23.038, Section 4)
+   */
+  static constexpr int ENCODING_GSM_DCS_7BIT = 0x00;
+  static constexpr int ENCODING_GSM_DCS_8BIT = 0x01;
+  static constexpr int ENCODING_GSM_DCS_16BIT = 0x02;
+
+  /**
+   * IS-91 message types.
+   * (See TIA/EIS/IS-91-A-ENGL 1999, table 3.7.1.1-3)
+   */
+  static constexpr int IS91_MSG_TYPE_VOICEMAIL_STATUS = 0x82;
+  static constexpr int IS91_MSG_TYPE_SHORT_MESSAGE_FULL = 0x83;
+  static constexpr int IS91_MSG_TYPE_CLI = 0x84;
+  static constexpr int IS91_MSG_TYPE_SHORT_MESSAGE = 0x85;
+
+  /**
+   * US ASCII character mapping table.
+   *
+   * This table contains only the printable ASCII characters, with a
+   * 0x20 offset, meaning that the ASCII SPACE character is at index
+   * 0, with the resulting code of 0x20.
+   *
+   * Note this mapping is also equivalent to that used by both the
+   * IA5 and the IS-91 encodings.  For the former this is defined
+   * using CCITT Rec. T.50 Tables 1 and 3.  For the latter IS 637 B,
+   * Table 4.3.1.4.1-1 -- and note the encoding uses only 6 bits,
+   * and hence only maps entries up to the '_' character.
+   *
+   */
+  static const char ASCII_MAP[];
+
+  /**
+   * Character to use when forced to encode otherwise unencodable
+   * characters, meaning those not in the respective ASCII or GSM
+   * 7-bit encoding tables.  Current choice is SPACE, which is 0x20
+   * in both the GSM-7bit and ASCII-7bit encodings.
+   */
+  static constexpr uint8_t UNENCODABLE_7_BIT_CHAR = 0x20;
+
+  /**
+   * Only elements between these indices in the ASCII table are printable.
+   */
+  static constexpr int PRINTABLE_ASCII_MIN_INDEX = 0x20;
+  static constexpr int ASCII_NL_INDEX = 0x0A;
+  ;
+  static constexpr int ASCII_CR_INDEX = 0x0D;
+  static std::map<char, uint8_t> charToAscii;
+
+  /*
+   * TODO(cleanup): Move this very generic functionality somewhere
+   * more general.
+   */
+  /**
+   * Given a string generate a corresponding ASCII-encoded byte
+   * array, but limited to printable characters.  If the input
+   * contains unprintable characters, return null.
+   */
+  //static uint8_t* stringToAscii(std::string msg, int* length);
+  static std::vector<uint8_t> stringToAscii(std::string msg);
+  /**
+   * Mapping for ASCII values less than 32 are flow control signals
+   * and not used here.
+   */
+  static constexpr int ASCII_MAP_BASE_INDEX = 0x20;
+  static const int ASCII_MAP_MAX_INDEX;
+
+  /**
+   * Contains the data header of the user data
+   */
+  std::shared_ptr<SmsHeader> userDataHeader = nullptr;
+  /**
+   * Contains the data encoding type for the SMS message
+   */
+  int msgEncoding = -1;
+  bool msgEncodingSet = false;
+
+  int msgType = 0;
+
+  /**
+   * Number of invalid bits in the last byte of data.
+   */
+  int paddingBits = 0;
+
+  int numFields = 0;
+
+  /**
+   * Contains the user data of a SMS message
+   * (See 3GPP2 C.S0015-B, v2, 4.5.2)
+   */
+  //uint8_t* payload = nullptr;
+  //int payload_length = 0;
+  std::vector<uint8_t> payload;
+  std::string payloadStr;
+  //char* payloadStr = nullptr;
+private:
+  static std::map<char, uint8_t> init();
+};
+
+#endif /* USERDATA_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/ril_cdma_sms.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/ril_cdma_sms.h
new file mode 100644
index 0000000..a147d21
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/ril_cdma_sms.h
@@ -0,0 +1,802 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * ISSUES:
+ *
+ */
+
+/**
+ * TODO
+ *
+ *
+ */
+
+#ifndef ANDROID_RIL_CDMA_SMS_H
+#define ANDROID_RIL_CDMA_SMS_H 1
+
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Used by RIL_REQUEST_CDMA_SEND_SMS and RIL_UNSOL_RESPONSE_CDMA_NEW_SMS */
+
+#define RIL_CDMA_SMS_ADDRESS_MAX     36
+#define RIL_CDMA_SMS_SUBADDRESS_MAX  36
+#define RIL_CDMA_SMS_BEARER_DATA_MAX 255
+
+typedef enum {
+  RIL_CDMA_SMS_DIGIT_MODE_4_BIT = 0, /* DTMF digits */
+  RIL_CDMA_SMS_DIGIT_MODE_8_BIT = 1, RIL_CDMA_SMS_DIGIT_MODE_MAX32 = 0x10000000 /* Force constant ENUM size in structures */
+} RIL_CDMA_SMS_DigitMode;
+
+typedef enum {
+  RIL_CDMA_SMS_NUMBER_MODE_NOT_DATA_NETWORK = 0,
+  RIL_CDMA_SMS_NUMBER_MODE_DATA_NETWORK = 1,
+  RIL_CDMA_SMS_NUMBER_MODE_MAX32 = 0x10000000 /* Force constant ENUM size in structures */
+} RIL_CDMA_SMS_NumberMode;
+
+typedef enum {
+  RIL_CDMA_SMS_NUMBER_TYPE_UNKNOWN = 0,
+  RIL_CDMA_SMS_NUMBER_TYPE_INTERNATIONAL_OR_DATA_IP = 1,
+  /* INTERNATIONAL is used when number mode is not data network address.
+   * DATA_IP is used when the number mode is data network address
+   */
+  RIL_CDMA_SMS_NUMBER_TYPE_NATIONAL_OR_INTERNET_MAIL = 2,
+  /* NATIONAL is used when the number mode is not data network address.
+   * INTERNET_MAIL is used when the number mode is data network address.
+   * For INTERNET_MAIL, in the address data "digits", each byte contains
+   * an ASCII character. Examples are "x@y.com,a@b.com - ref TIA/EIA-637A 3.4.3.3
+   */
+  RIL_CDMA_SMS_NUMBER_TYPE_NETWORK = 3,
+  RIL_CDMA_SMS_NUMBER_TYPE_SUBSCRIBER = 4,
+  RIL_CDMA_SMS_NUMBER_TYPE_ALPHANUMERIC = 5,
+  /* GSM SMS: address value is GSM 7-bit chars */
+  RIL_CDMA_SMS_NUMBER_TYPE_ABBREVIATED = 6,
+  RIL_CDMA_SMS_NUMBER_TYPE_RESERVED_7 = 7,
+  RIL_CDMA_SMS_NUMBER_TYPE_MAX32 = 0x10000000 /* Force constant ENUM size in structures */
+} RIL_CDMA_SMS_NumberType;
+
+typedef enum {
+  RIL_CDMA_SMS_NUMBER_PLAN_UNKNOWN = 0,
+  RIL_CDMA_SMS_NUMBER_PLAN_TELEPHONY = 1, /* CCITT E.164 and E.163, including ISDN plan */
+  RIL_CDMA_SMS_NUMBER_PLAN_RESERVED_2 = 2,
+  RIL_CDMA_SMS_NUMBER_PLAN_DATA = 3, /* CCITT X.121 */
+  RIL_CDMA_SMS_NUMBER_PLAN_TELEX = 4, /* CCITT F.69 */
+  RIL_CDMA_SMS_NUMBER_PLAN_RESERVED_5 = 5,
+  RIL_CDMA_SMS_NUMBER_PLAN_RESERVED_6 = 6,
+  RIL_CDMA_SMS_NUMBER_PLAN_RESERVED_7 = 7,
+  RIL_CDMA_SMS_NUMBER_PLAN_RESERVED_8 = 8,
+  RIL_CDMA_SMS_NUMBER_PLAN_PRIVATE = 9,
+  RIL_CDMA_SMS_NUMBER_PLAN_RESERVED_10 = 10,
+  RIL_CDMA_SMS_NUMBER_PLAN_RESERVED_11 = 11,
+  RIL_CDMA_SMS_NUMBER_PLAN_RESERVED_12 = 12,
+  RIL_CDMA_SMS_NUMBER_PLAN_RESERVED_13 = 13,
+  RIL_CDMA_SMS_NUMBER_PLAN_RESERVED_14 = 14,
+  RIL_CDMA_SMS_NUMBER_PLAN_RESERVED_15 = 15,
+  RIL_CDMA_SMS_NUMBER_PLAN_MAX32 = 0x10000000 /* Force constant ENUM size in structures */
+} RIL_CDMA_SMS_NumberPlan;
+
+typedef struct {
+  RIL_CDMA_SMS_DigitMode digit_mode;
+  /* Indicates 4-bit or 8-bit */
+  RIL_CDMA_SMS_NumberMode number_mode;
+  /* Used only when digitMode is 8-bit */
+  RIL_CDMA_SMS_NumberType number_type;
+  /* Used only when digitMode is 8-bit.
+   * To specify an international address, use the following:
+   * digitMode = RIL_CDMA_SMS_DIGIT_MODE_8_BIT
+   * numberMode = RIL_CDMA_SMS_NOT_DATA_NETWORK
+   * numberType = RIL_CDMA_SMS_NUMBER_TYPE_INTERNATIONAL_OR_DATA_IP
+   * numberPlan = RIL_CDMA_SMS_NUMBER_PLAN_TELEPHONY
+   * numberOfDigits = number of digits
+   * digits = ASCII digits, e.g. '1', '2', '3'3, '4', and '5'
+   */
+  RIL_CDMA_SMS_NumberPlan number_plan;
+  /* Used only when digitMode is 8-bit */
+  unsigned char number_of_digits;
+  unsigned char digits[ RIL_CDMA_SMS_ADDRESS_MAX];
+  /* Each byte in this array represnts a 40bit or 8-bit digit of address data */
+} RIL_CDMA_SMS_Address;
+
+typedef enum {
+  RIL_CDMA_SMS_SUBADDRESS_TYPE_NSAP = 0, /* CCITT X.213 or ISO 8348 AD2 */
+  RIL_CDMA_SMS_SUBADDRESS_TYPE_USER_SPECIFIED = 1, /* e.g. X.25 */
+  RIL_CDMA_SMS_SUBADDRESS_TYPE_MAX32 = 0x10000000 /* Force constant ENUM size in structures */
+} RIL_CDMA_SMS_SubaddressType;
+
+typedef struct {
+  RIL_CDMA_SMS_SubaddressType subaddressType;
+  /* 1 means the last byte's lower 4 bits should be ignored */
+  unsigned char odd;
+  unsigned char number_of_digits;
+  /* Each byte respresents a 8-bit digit of subaddress data */
+  unsigned char digits[ RIL_CDMA_SMS_SUBADDRESS_MAX];
+} RIL_CDMA_SMS_Subaddress;
+
+typedef struct {
+  int uTeleserviceID;
+  unsigned char bIsServicePresent;
+  int uServicecategory;
+  RIL_CDMA_SMS_Address sAddress;
+  RIL_CDMA_SMS_Subaddress sSubAddress;
+  int uBearerDataLen;
+  unsigned char aBearerData[ RIL_CDMA_SMS_BEARER_DATA_MAX];
+} RIL_CDMA_SMS_Message;
+
+/* Used by RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE */
+
+typedef enum {
+  RIL_CDMA_SMS_NO_ERROR = 0,
+  RIL_CDMA_SMS_ERROR = 1,
+  RIL_CDMA_SMS_ERROR_MAX32 = 0x10000000 /* Force constant ENUM size in structures */
+} RIL_CDMA_SMS_ErrorClass;
+
+typedef struct {
+  RIL_CDMA_SMS_ErrorClass uErrorClass;
+  int uSMSCauseCode; /* As defined in N.S00005, 6.5.2.125.
+   Currently, only 35 (resource shortage) and
+   39 (other terminal problem) are reported. */
+} RIL_CDMA_SMS_Ack;
+
+/* Used by RIL_REQUEST_CDMA_SMS_GET_BROADCAST_CONFIG and
+ RIL_REQUEST_CDMA_SMS_SET_BROADCAST_CONFIG */
+
+typedef struct {
+  int service_category;
+  int language;
+  unsigned char selected;
+} RIL_CDMA_BroadcastSmsConfigInfo;
+
+/* Used by RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM */
+
+typedef struct {
+  int status; /* Status of message.  See TS 27.005 3.1, "<stat>": */
+  /*      0 = "REC UNREAD"    */
+  /*      1 = "REC READ"      */
+  /*      2 = "STO UNSENT"    */
+  /*      3 = "STO SENT"      */
+
+  RIL_CDMA_SMS_Message message;
+} RIL_CDMA_SMS_WriteArgs;
+
+/* Used by RIL_REQUEST_ENCODE_CDMA_SMS and RIL_REQUEST_DECODE_CDMA_SMS*/
+
+#define RIL_CDMA_SMS_UDH_MAX_SND_SIZE           128
+#define RIL_CDMA_SMS_UDH_EO_DATA_SEGMENT_MAX    131 /* 140 - 3 - 6 */
+#define RIL_CDMA_SMS_MAX_UD_HEADERS         7
+#define RIL_CDMA_SMS_USER_DATA_MAX     229
+#define RIL_CDMA_SMS_ADDRESS_MAX            36
+#define RIL_CDMA_SMS_UDH_LARGE_PIC_SIZE     128
+#define RIL_CDMA_SMS_UDH_SMALL_PIC_SIZE     32
+#define RIL_CDMA_SMS_UDH_VAR_PIC_SIZE       134
+#define RIL_CDMA_SMS_UDH_ANIM_NUM_BITMAPS   4
+#define RIL_CDMA_SMS_UDH_LARGE_BITMAP_SIZE  32
+#define RIL_CDMA_SMS_UDH_SMALL_BITMAP_SIZE  8
+#define RIL_CDMA_SMS_UDH_OTHER_SIZE         226
+#define RIL_CDMA_SMS_IP_ADDRESS_SIZE        4
+
+/* ------------------- */
+/* ---- User Data ---- */
+/* ------------------- */
+typedef enum {
+  RIL_CDMA_SMS_UDH_CONCAT_8 = 0x00,
+  RIL_CDMA_SMS_UDH_SPECIAL_SM,
+  /* 02 - 03    Reserved */
+  RIL_CDMA_SMS_UDH_PORT_8 = 0x04,
+  RIL_CDMA_SMS_UDH_PORT_16,
+  RIL_CDMA_SMS_UDH_SMSC_CONTROL,
+  RIL_CDMA_SMS_UDH_SOURCE,
+  RIL_CDMA_SMS_UDH_CONCAT_16,
+  RIL_CDMA_SMS_UDH_WCMP,
+  RIL_CDMA_SMS_UDH_TEXT_FORMATING,
+  RIL_CDMA_SMS_UDH_PRE_DEF_SOUND,
+  RIL_CDMA_SMS_UDH_USER_DEF_SOUND,
+  RIL_CDMA_SMS_UDH_PRE_DEF_ANIM,
+  RIL_CDMA_SMS_UDH_LARGE_ANIM,
+  RIL_CDMA_SMS_UDH_SMALL_ANIM,
+  RIL_CDMA_SMS_UDH_LARGE_PICTURE,
+  RIL_CDMA_SMS_UDH_SMALL_PICTURE,
+  RIL_CDMA_SMS_UDH_VAR_PICTURE,
+
+  RIL_CDMA_SMS_UDH_USER_PROMPT = 0x13,
+  RIL_CDMA_SMS_UDH_EXTENDED_OBJECT = 0x14,
+
+  /* 15 - 1F    Reserved for future EMS */
+
+  RIL_CDMA_SMS_UDH_RFC822 = 0x20,
+
+  /*  21 - 6F    Reserved for future use */
+  /*  70 - 7f    Reserved for (U)SIM Toolkit Security Headers */
+  /*  80 - 9F    SME to SME specific use */
+  /*  A0 - BF    Reserved for future use */
+  /*  C0 - DF    SC specific use */
+  /*  E0 - FF    Reserved for future use */
+
+  RIL_CDMA_SMS_UDH_OTHER = 0xFFFF, /* For unsupported or proprietary headers */
+  RIL_CDMA_SMS_UDH_ID_MAX32 = 0x10000000 /* Force constant ENUM size in structures */
+
+} RIL_CDMA_SMS_UdhId;
+
+typedef struct {
+  /*indicates the reference number for a particular concatenated short message. */
+  /*it is constant for every short message which makes up a particular concatenated short message*/
+  unsigned char msg_ref;
+
+  /*indicates the total number of short messages within the concatenated short message.
+   The value shall start at 1 and remain constant for every
+   short message which makes up the concatenated short message.
+   if it is 0 then the receiving entity shall ignore the whole Information Element*/
+  unsigned char total_sm;
+
+  /*
+   * it indicates the sequence number of a particular short message within the concatenated short
+   * message. The value shall start at 1 and increment by one for every short message sent
+   * within the concatenated short message. If the value is zero or the value is
+   * greater than the value in octet 2 then the receiving
+   * entity shall ignore the whole Information Element.
+   */
+  unsigned char seq_num;
+} RIL_CDMA_SMS_UdhConcat8;
+
+/* GW message waiting actions
+ */
+typedef enum {
+  RIL_CDMA_SMS_GW_MSG_WAITING_NONE,
+  RIL_CDMA_SMS_GW_MSG_WAITING_DISCARD,
+  RIL_CDMA_SMS_GW_MSG_WAITING_STORE,
+  RIL_CDMA_SMS_GW_MSG_WAITING_NONE_1111,
+  RIL_CDMA_SMS_GW_MSG_WAITING_MAX32 = 0x10000000 /* Force constant ENUM size in structures */
+} RIL_CDMA_SMS_GWMsgWaiting;
+
+/* GW message waiting types
+ */
+typedef enum {
+  RIL_CDMA_SMS_GW_MSG_WAITING_VOICEMAIL,
+  RIL_CDMA_SMS_GW_MSG_WAITING_FAX,
+  RIL_CDMA_SMS_GW_MSG_WAITING_EMAIL,
+  RIL_CDMA_SMS_GW_MSG_WAITING_OTHER,
+  RIL_CDMA_SMS_GW_MSG_WAITING_KIND_MAX32 = 0x10000000 /* Force constant ENUM size in structures */
+} RIL_CDMA_SMS_GWMsgWaitingKind;
+
+typedef struct {
+  RIL_CDMA_SMS_GWMsgWaiting msg_waiting;
+  RIL_CDMA_SMS_GWMsgWaitingKind msg_waiting_kind;
+
+  /*it indicates the number of messages of the type specified in Octet 1 waiting.*/
+  unsigned char message_count;
+} RIL_CDMA_SMS_UdhSpecialSM;
+
+typedef struct {
+  unsigned char dest_port;
+  unsigned char orig_port;
+} RIL_CDMA_SMS_UdhWap8;
+
+typedef struct {
+  unsigned short dest_port;
+  unsigned short orig_port;
+} RIL_CDMA_SMS_UdhWap16;
+
+typedef struct {
+  unsigned short msg_ref;
+  unsigned char total_sm;
+  unsigned char seq_num;
+
+} RIL_CDMA_SMS_UdhConcat16;
+
+typedef enum {
+  RIL_CDMA_SMS_UDH_LEFT_ALIGNMENT = 0,
+  RIL_CDMA_SMS_UDH_CENTER_ALIGNMENT,
+  RIL_CDMA_SMS_UDH_RIGHT_ALIGNMENT,
+  RIL_CDMA_SMS_UDH_DEFAULT_ALIGNMENT,
+  RIL_CDMA_SMS_UDH_MAX_ALIGNMENT,
+  RIL_CDMA_SMS_UDH_ALIGNMENT_MAX32 = 0x10000000 /* Force constant ENUM size in structures */
+} RIL_CDMA_SMS_UdhAlignment;
+
+typedef enum {
+  RIL_CDMA_SMS_UDH_FONT_NORMAL = 0,
+  RIL_CDMA_SMS_UDH_FONT_LARGE,
+  RIL_CDMA_SMS_UDH_FONT_SMALL,
+  RIL_CDMA_SMS_UDH_FONT_RESERVED,
+  RIL_CDMA_SMS_UDH_FONT_MAX,
+  RIL_CDMA_SMS_UDH_FONT_MAX32 = 0x10000000 /* Force constant ENUM size in structures */
+} RIL_CDMA_SMS_UdhFontSize;
+
+typedef enum {
+  RIL_CDMA_SMS_UDH_TEXT_COLOR_BLACK = 0x0,
+  RIL_CDMA_SMS_UDH_TEXT_COLOR_DARK_GREY = 0x1,
+  RIL_CDMA_SMS_UDH_TEXT_COLOR_DARK_RED = 0x2,
+  RIL_CDMA_SMS_UDH_TEXT_COLOR_DARK_YELLOW = 0x3,
+  RIL_CDMA_SMS_UDH_TEXT_COLOR_DARK_GREEN = 0x4,
+  RIL_CDMA_SMS_UDH_TEXT_COLOR_DARK_CYAN = 0x5,
+  RIL_CDMA_SMS_UDH_TEXT_COLOR_DARK_BLUE = 0x6,
+  RIL_CDMA_SMS_UDH_TEXT_COLOR_DARK_MAGENTA = 0x7,
+  RIL_CDMA_SMS_UDH_TEXT_COLOR_GREY = 0x8,
+  RIL_CDMA_SMS_UDH_TEXT_COLOR_WHITE = 0x9,
+  RIL_CDMA_SMS_UDH_TEXT_COLOR_BRIGHT_RED = 0xA,
+  RIL_CDMA_SMS_UDH_TEXT_COLOR_BRIGHT_YELLOW = 0xB,
+  RIL_CDMA_SMS_UDH_TEXT_COLOR_BRIGHT_GREEN = 0xC,
+  RIL_CDMA_SMS_UDH_TEXT_COLOR_BRIGHT_CYAN = 0xD,
+  RIL_CDMA_SMS_UDH_TEXT_COLOR_BRIGHT_BLUE = 0xE,
+  RIL_CDMA_SMS_UDH_TEXT_COLOR_BRIGHT_MAGENTA = 0xF,
+  RIL_CDMA_SMS_UDH_TEXT_COLOR_MAX32 = 0x10000000 /* Force constant ENUM size in structures */
+} RIL_CDMA_SMS_UdhTextColor;
+
+typedef struct {
+  unsigned char start_position;
+  unsigned char text_formatting_length;
+  RIL_CDMA_SMS_UdhAlignment alignment_type; /*bit 0 and  bit 1*/
+  RIL_CDMA_SMS_UdhFontSize font_size; /*bit 3 and  bit 2*/
+  unsigned char style_bold; /*bit 4 */
+  unsigned char style_italic; /*bit 5  */
+  unsigned char style_underlined; /*bit 6 */
+  unsigned char style_strikethrough; /*bit 7 */
+
+  /* if FALSE, ignore the following color information */
+  unsigned char is_color_present;
+  RIL_CDMA_SMS_UdhTextColor text_color_foreground;
+  RIL_CDMA_SMS_UdhTextColor text_color_background;
+
+} RIL_CDMA_SMS_UdhTextFormating;
+
+/* Predefined sound
+ */
+typedef struct {
+  unsigned char position;
+  unsigned char snd_number;
+} RIL_CDMA_SMS_UdhPreDefSound;
+
+/* User Defined sound
+ */
+typedef struct {
+  unsigned char data_length;
+  unsigned char position;
+  unsigned char user_def_sound[RIL_CDMA_SMS_UDH_MAX_SND_SIZE];
+} RIL_CDMA_SMS_UdhUserDefSound;
+
+/* Large picture
+ */
+typedef struct {
+  unsigned char position;
+  unsigned char data[RIL_CDMA_SMS_UDH_LARGE_PIC_SIZE];
+} RIL_CDMA_SMS_UdhLargePictureData;
+
+/* Small picture
+ */
+typedef struct {
+  unsigned char position;
+  unsigned char data[RIL_CDMA_SMS_UDH_SMALL_PIC_SIZE];
+} RIL_CDMA_SMS_UdhSmallPictureData;
+
+/* Variable length picture
+ */
+typedef struct {
+  unsigned char position;
+  unsigned char width; /* Number of pixels - Should be a mutliple of 8 */
+  unsigned char height;
+  unsigned char data[RIL_CDMA_SMS_UDH_VAR_PIC_SIZE];
+} RIL_CDMA_SMS_UdhVarPicture;
+
+/* Predefined animation
+ */
+typedef struct {
+  unsigned char position;
+  unsigned char animation_number;
+} RIL_CDMA_SMS_UdhPreDefAnim;
+
+/* Large animation
+ */
+typedef struct {
+  unsigned char position;
+  unsigned char data[RIL_CDMA_SMS_UDH_ANIM_NUM_BITMAPS][RIL_CDMA_SMS_UDH_LARGE_BITMAP_SIZE];
+} RIL_CDMA_SMS_UdhLargeAnim;
+
+/* Small animation
+ */
+typedef struct {
+  unsigned char position;
+  unsigned char data[RIL_CDMA_SMS_UDH_ANIM_NUM_BITMAPS][RIL_CDMA_SMS_UDH_SMALL_BITMAP_SIZE];
+} RIL_CDMA_SMS_UdhSmallAnim;
+
+/* User Prompt Indicator UDH
+ */
+typedef struct {
+  unsigned char number_of_objects;
+  /* Number of objects of the same kind that follow this header which will
+   ** be stitched together by the applications. For example, 5 small pictures
+   ** are to be stitched together horizontally, or 6 iMelody tones are to be
+   ** connected together with intermediate iMelody header and footer ignored.
+   ** Allowed objects to be stitched:
+   **   - Images (small, large, variable)
+   **   - User defined sounds
+   */
+} RIL_CDMA_SMS_UdhUserPrompt;
+
+typedef struct {
+  unsigned char length;
+
+  unsigned char data[RIL_CDMA_SMS_UDH_EO_DATA_SEGMENT_MAX];
+  /* RIL_CDMA_SMS_UDH_EO_VCARD: See http://www.imc.org/pdi/vcard-21.doc for payload */
+  /* RIL_CDMA_SMS_UDH_EO_VCALENDAR: See http://www.imc.org/pdi/vcal-10.doc */
+  /* Or: Unsupported/proprietary extended objects */
+
+} RIL_CDMA_SMS_UdhEoContent;
+
+/* Extended Object UDH
+ */
+/* Extended Object IDs/types
+ */
+typedef enum {
+  RIL_CDMA_SMS_UDH_EO_VCARD = 0x09,
+  RIL_CDMA_SMS_UDH_EO_VCALENDAR = 0x0A,
+  RIL_CDMA_SMS_UDH_EO_MAX32 = 0x10000000 /* Force constant ENUM size in structures */
+} RIL_CDMA_SMS_UdhEoId;
+
+typedef struct {
+  /* Extended objects are to be used together with 16-bit concatenation
+   ** UDH. The max number of segments supported for E.O. is 8 at least.
+   */
+  RIL_CDMA_SMS_UdhEoContent content;
+
+  unsigned char first_segment;
+  /* The following fields are only present in the first segment of a
+   ** concatenated SMS message.
+   */
+  unsigned char reference;
+  /* Identify those extended object segments which should be linked together
+   */
+  unsigned short length;
+  /* Length of the whole extended object data
+   */
+  unsigned char control;
+  RIL_CDMA_SMS_UdhEoId type;
+  unsigned short position;
+  /* Absolute position of the E.O. in the whole text after concatenation,
+   ** starting from 1.
+   */
+} RIL_CDMA_SMS_UdhEo;
+
+typedef struct {
+  RIL_CDMA_SMS_UdhId header_id;
+  unsigned char header_length;
+  unsigned char data[RIL_CDMA_SMS_UDH_OTHER_SIZE];
+} RIL_CDMA_SMS_UdhOther;
+
+typedef struct {
+  unsigned char header_length;
+} RIL_CDMA_SMS_UdhRfc822;
+
+typedef struct {
+  RIL_CDMA_SMS_UdhId header_id;
+
+  union {
+    RIL_CDMA_SMS_UdhConcat8 concat_8;       // 00
+
+    RIL_CDMA_SMS_UdhSpecialSM special_sm;     // 01
+    RIL_CDMA_SMS_UdhWap8 wap_8;          // 04
+    RIL_CDMA_SMS_UdhWap16 wap_16;         // 05
+    RIL_CDMA_SMS_UdhConcat16 concat_16;      // 08
+    RIL_CDMA_SMS_UdhTextFormating text_formating; // 0a
+    RIL_CDMA_SMS_UdhPreDefSound pre_def_sound;  // 0b
+    RIL_CDMA_SMS_UdhUserDefSound user_def_sound; // 0c
+    RIL_CDMA_SMS_UdhPreDefAnim pre_def_anim;   // 0d
+    RIL_CDMA_SMS_UdhLargeAnim large_anim;     // 0e
+    RIL_CDMA_SMS_UdhSmallAnim small_anim;     // 0f
+    RIL_CDMA_SMS_UdhLargePictureData large_picture;  // 10
+    RIL_CDMA_SMS_UdhSmallPictureData small_picture;  // 11
+    RIL_CDMA_SMS_UdhVarPicture var_picture;    // 12
+
+    RIL_CDMA_SMS_UdhUserPrompt user_prompt;    // 13
+    RIL_CDMA_SMS_UdhEo eo;             // 14
+
+    RIL_CDMA_SMS_UdhRfc822 rfc822;         // 20
+    RIL_CDMA_SMS_UdhOther other;
+
+  } u;
+} RIL_CDMA_SMS_Udh;
+
+/* ----------------------------- */
+/* -- User data encoding type -- */
+/* ----------------------------- */
+typedef enum {
+  RIL_CDMA_SMS_ENCODING_OCTET = 0, /* 8-bit */
+  RIL_CDMA_SMS_ENCODING_IS91EP, /* varies */
+  RIL_CDMA_SMS_ENCODING_ASCII, /* 7-bit */
+  RIL_CDMA_SMS_ENCODING_IA5, /* 7-bit */
+  RIL_CDMA_SMS_ENCODING_UNICODE, /* 16-bit */
+  RIL_CDMA_SMS_ENCODING_SHIFT_JIS, /* 8 or 16-bit */
+  RIL_CDMA_SMS_ENCODING_KOREAN, /* 8 or 16-bit */
+  RIL_CDMA_SMS_ENCODING_LATIN_HEBREW, /* 8-bit */
+  RIL_CDMA_SMS_ENCODING_LATIN, /* 8-bit */
+  RIL_CDMA_SMS_ENCODING_GSM_7_BIT_DEFAULT, /* 7-bit */
+  RIL_CDMA_SMS_ENCODING_MAX32 = 0x10000000
+
+} RIL_CDMA_SMS_UserDataEncoding;
+
+/* ------------------------ */
+/* -- IS-91 EP data type -- */
+/* ------------------------ */
+typedef enum {
+  RIL_CDMA_SMS_IS91EP_VOICE_MAIL = 0x82,
+  RIL_CDMA_SMS_IS91EP_SHORT_MESSAGE_FULL = 0x83,
+  RIL_CDMA_SMS_IS91EP_CLI_ORDER = 0x84,
+  RIL_CDMA_SMS_IS91EP_SHORT_MESSAGE = 0x85,
+  RIL_CDMA_SMS_IS91EP_MAX32 = 0x10000000
+
+} RIL_CDMA_SMS_IS91EPType;
+
+typedef struct {
+  /* NOTE: If message_id.udh_present == TRUE:
+   **       'num_headers' is the number of User Data Headers (UDHs),
+   **       and 'headers' include all those headers.
+   */
+  unsigned char num_headers;
+  RIL_CDMA_SMS_Udh headers[RIL_CDMA_SMS_MAX_UD_HEADERS];
+
+  RIL_CDMA_SMS_UserDataEncoding encoding;
+  RIL_CDMA_SMS_IS91EPType is91ep_type;
+
+  /*----------------------------------------------------------------------
+   'data_len' indicates the valid number of bytes in the 'data' array.
+
+   'padding_bits' (0-7) indicates how many bits in the last byte of 'data'
+   are invalid bits. This parameter is only used for Mobile-Originated
+   messages. There is no way for the API to tell how many padding bits
+   exist in the received message. Instead, the application can find out how
+   many padding bits exist in the user data when decoding the user data.
+
+   'data' has the raw bits of the user data field of the SMS message.
+   The client software should decode the raw user data according to its
+   supported encoding types and languages.
+
+   EXCEPTION 1: CMT-91 user data raw bits are first translated into BD fields
+   (e.g. num_messages, callback, etc.) The translated user data field in
+   VMN and Short Message is in the form of ASCII characters, each occupying
+   a byte in the resulted 'data'.
+
+   EXCEPTION 2: GSM 7-bit Default characters are decoded so that each byte
+   has one 7-bit GSM character.
+
+   'number_of_digits' is the number of digits/characters (7, 8, 16, or
+   whatever bits) in the raw user data, which can be used by the client
+   when decoding the user data according to the encoding type and language.
+   -------------------------------------------------------------------------*/
+  unsigned char data_len;
+  unsigned char padding_bits;
+  unsigned char data[ RIL_CDMA_SMS_USER_DATA_MAX];
+  unsigned char number_of_digits;
+
+} RIL_CDMA_SMS_CdmaUserData;
+
+/* -------------------- */
+/* ---- Message Id ---- */
+/* -------------------- */
+typedef enum {
+  RIL_CDMA_SMS_BD_TYPE_RESERVED_0 = 0, RIL_CDMA_SMS_BD_TYPE_DELIVER, /* MT only */
+  RIL_CDMA_SMS_BD_TYPE_SUBMIT, /* MO only */
+  RIL_CDMA_SMS_BD_TYPE_CANCELLATION, /* MO only */
+  RIL_CDMA_SMS_BD_TYPE_DELIVERY_ACK, /* MT only */
+  RIL_CDMA_SMS_BD_TYPE_USER_ACK, /* MT & MO */
+  RIL_CDMA_SMS_BD_TYPE_READ_ACK, /* MT & MO */
+  RIL_CDMA_SMS_BD_TYPE_MAX32 = 0x10000000
+
+} RIL_CDMA_SMS_BdMessageType;
+
+typedef unsigned int RIL_CDMA_SMS_MessageNumber;
+
+typedef struct {
+  RIL_CDMA_SMS_BdMessageType type;
+  RIL_CDMA_SMS_MessageNumber id_number;
+  unsigned char udh_present;
+  /* NOTE: if FEATURE_SMS_UDH is not defined,
+   ** udh_present should be ignored.
+   */
+} RIL_CDMA_SMS_MessageId;
+
+typedef unsigned char RIL_CDMA_SMS_UserResponse;
+
+/* ------------------- */
+/* ---- Timestamp ---- */
+/* ------------------- */
+typedef struct {
+  /* If 'year' is between 96 and 99, the actual year is 1900 + 'year';
+   if 'year' is between 00 and 95, the actual year is 2000 + 'year'.
+   NOTE: Each field has two BCD digits and byte arrangement is <MSB, ... ,LSB>
+   */
+  unsigned char year; /* 0x00-0x99 */
+  unsigned char month; /* 0x01-0x12 */
+  unsigned char day; /* 0x01-0x31 */
+  unsigned char hour; /* 0x00-0x23 */
+  unsigned char minute; /* 0x00-0x59 */
+  unsigned char second; /* 0x00-0x59 */
+  signed char timezone; /* +/-, [-48,+48] number of 15 minutes - GW only */
+} RIL_CDMA_SMS_Timestamp;
+
+/* ------------------ */
+/* ---- Priority ---- */
+/* ------------------ */
+typedef enum {
+  RIL_CDMA_SMS_PRIORITY_NORMAL = 0,
+  RIL_CDMA_SMS_PRIORITY_INTERACTIVE,
+  RIL_CDMA_SMS_PRIORITY_URGENT,
+  RIL_CDMA_SMS_PRIORITY_EMERGENCY,
+  RIL_CDMA_SMS_PRIORITY_MAX32 = 0x10000000
+
+} RIL_CDMA_SMS_Priority;
+
+/* ----------------- */
+/* ---- Privacy ---- */
+/* ----------------- */
+typedef enum {
+  RIL_CDMA_SMS_PRIVACY_NORMAL = 0,
+  RIL_CDMA_SMS_PRIVACY_RESTRICTED,
+  RIL_CDMA_SMS_PRIVACY_CONFIDENTIAL,
+  RIL_CDMA_SMS_PRIVACY_SECRET,
+  RIL_CDMA_SMS_PRIVACY_MAX32 = 0x10000000
+
+} RIL_CDMA_SMS_Privacy;
+
+/* ---------------------- */
+/* ---- Reply option ---- */
+/* ---------------------- */
+typedef struct {
+  /* whether user ack is requested
+   */
+  unsigned char user_ack_requested;
+
+  /* whether delivery ack is requested.
+   Should be FALSE for incoming messages.
+   */
+  unsigned char delivery_ack_requested;
+
+  /* Message originator requests the receiving phone to send back a READ_ACK
+   ** message automatically when the user reads the received message.
+   */
+  unsigned char read_ack_requested;
+
+} RIL_CDMA_SMS_ReplyOption;
+
+typedef enum {
+  RIL_CDMA_SMS_ALERT_MODE_DEFAULT = 0,
+  RIL_CDMA_SMS_ALERT_MODE_LOW_PRIORITY = 1,
+  RIL_CDMA_SMS_ALERT_MODE_MEDIUM_PRIORITY = 2,
+  RIL_CDMA_SMS_ALERT_MODE_HIGH_PRIORITY = 3,
+
+  /* For pre-IS637A implementations, alert_mode only has values of True/False:
+   */
+  RIL_CDMA_SMS_ALERT_MODE_OFF = 0,
+  RIL_CDMA_SMS_ALERT_MODE_ON = 1
+
+} RIL_CDMA_SMS_AlertMode;
+
+/* ------------------ */
+/* ---- Language ---- */
+/* ------------------ */
+typedef enum {
+  RIL_CDMA_SMS_LANGUAGE_UNSPECIFIED = 0,
+  RIL_CDMA_SMS_LANGUAGE_ENGLISH,
+  RIL_CDMA_SMS_LANGUAGE_FRENCH,
+  RIL_CDMA_SMS_LANGUAGE_SPANISH,
+  RIL_CDMA_SMS_LANGUAGE_JAPANESE,
+  RIL_CDMA_SMS_LANGUAGE_KOREAN,
+  RIL_CDMA_SMS_LANGUAGE_CHINESE,
+  RIL_CDMA_SMS_LANGUAGE_HEBREW,
+  RIL_CDMA_SMS_LANGUAGE_MAX32 = 0x10000000
+
+} RIL_CDMA_SMS_Language;
+
+/* ---------------------------------- */
+/* ---------- Display Mode ---------- */
+/* ---------------------------------- */
+typedef enum {
+  RIL_CDMA_SMS_DISPLAY_MODE_IMMEDIATE = 0,
+  RIL_CDMA_SMS_DISPLAY_MODE_DEFAULT = 1,
+  RIL_CDMA_SMS_DISPLAY_MODE_USER_INVOKE = 2,
+  RIL_CDMA_SMS_DISPLAY_MODE_RESERVED = 3
+} RIL_CDMA_SMS_DisplayMode;
+
+/* IS-637B parameters/fields
+ */
+
+/* ---------------------------------- */
+/* ---------- Delivery Status ------- */
+/* ---------------------------------- */
+typedef enum {
+  RIL_CDMA_SMS_DELIVERY_STATUS_ACCEPTED = 0, /* ERROR_CLASS_NONE */
+  RIL_CDMA_SMS_DELIVERY_STATUS_DEPOSITED_TO_INTERNET = 1, /* ERROR_CLASS_NONE */
+  RIL_CDMA_SMS_DELIVERY_STATUS_DELIVERED = 2, /* ERROR_CLASS_NONE */
+  RIL_CDMA_SMS_DELIVERY_STATUS_CANCELLED = 3, /* ERROR_CLASS_NONE */
+
+  RIL_CDMA_SMS_DELIVERY_STATUS_NETWORK_CONGESTION = 4, /* ERROR_CLASS_TEMP & PERM */
+  RIL_CDMA_SMS_DELIVERY_STATUS_NETWORK_ERROR = 5, /* ERROR_CLASS_TEMP & PERM */
+  RIL_CDMA_SMS_DELIVERY_STATUS_CANCEL_FAILED = 6, /* ERROR_CLASS_PERM */
+  RIL_CDMA_SMS_DELIVERY_STATUS_BLOCKED_DESTINATION = 7, /* ERROR_CLASS_PERM */
+  RIL_CDMA_SMS_DELIVERY_STATUS_TEXT_TOO_LONG = 8, /* ERROR_CLASS_PERM */
+  RIL_CDMA_SMS_DELIVERY_STATUS_DUPLICATE_MESSAGE = 9, /* ERROR_CLASS_PERM */
+  RIL_CDMA_SMS_DELIVERY_STATUS_INVALID_DESTINATION = 10, /* ERROR_CLASS_PERM */
+  RIL_CDMA_SMS_DELIVERY_STATUS_MESSAGE_EXPIRED = 13, /* ERROR_CLASS_PERM */
+
+  RIL_CDMA_SMS_DELIVERY_STATUS_UNKNOWN_ERROR = 0x1F /* ERROR_CLASS_PERM */
+
+/* All the other values are reserved */
+
+} RIL_CDMA_SMS_DeliveryStatusE;
+
+typedef struct {
+  RIL_CDMA_SMS_ErrorClass error_class;
+  RIL_CDMA_SMS_DeliveryStatusE status;
+} RIL_CDMA_SMS_DeliveryStatus;
+
+typedef struct {
+  unsigned char address[RIL_CDMA_SMS_IP_ADDRESS_SIZE];
+  unsigned char is_valid;
+} RIL_CDMA_SMS_IpAddress;
+
+/* This special parameter captures any unrecognized/proprietary parameters
+ */
+typedef struct {
+  unsigned char input_other_len;
+  unsigned char desired_other_len; /* used during decoding */
+  unsigned char * other_data;
+} RIL_CDMA_SMS_OtherParm;
+
+typedef struct {
+  /* the mask indicates which fields are present in this message */
+  unsigned int mask;
+
+  RIL_CDMA_SMS_MessageId message_id;
+  RIL_CDMA_SMS_CdmaUserData user_data;
+  RIL_CDMA_SMS_UserResponse user_response;
+  RIL_CDMA_SMS_Timestamp mc_time;
+  RIL_CDMA_SMS_Timestamp validity_absolute;
+  RIL_CDMA_SMS_Timestamp validity_relative;
+  RIL_CDMA_SMS_Timestamp deferred_absolute;
+  RIL_CDMA_SMS_Timestamp deferred_relative;
+  RIL_CDMA_SMS_Priority priority;
+  RIL_CDMA_SMS_Privacy privacy;
+  RIL_CDMA_SMS_ReplyOption reply_option;
+  unsigned char num_messages; /* the actual value; not BCDs */
+  RIL_CDMA_SMS_AlertMode alert_mode;
+  /* For pre-IS-637A implementations, alert_mode is either Off or On. */
+  RIL_CDMA_SMS_Language language;
+  RIL_CDMA_SMS_Address callback;
+  RIL_CDMA_SMS_DisplayMode display_mode;
+
+  RIL_CDMA_SMS_DeliveryStatus delivery_status;
+  unsigned int deposit_index;
+
+  RIL_CDMA_SMS_IpAddress ip_address;
+  unsigned char rsn_no_notify;
+
+  /* See function comments of wms_ts_decode() and
+   ** wms_ts_decode_cdma_bd_with_other() for details regarding 'other' parameters
+   */
+  RIL_CDMA_SMS_OtherParm other;
+
+} RIL_CDMA_SMS_ClientBd;
+
+typedef struct {
+  unsigned char length; /* length, in bytes, of the encoded SMS message */
+  unsigned char * data; /* the encoded SMS message (max 255 bytes) */
+} RIL_CDMA_Encoded_SMS;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*ANDROID_RIL_CDMA_SMS_H*/
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/sms_pdu_cdma.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/sms_pdu_cdma.cpp
new file mode 100644
index 0000000..5d9325c
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/sms_pdu_cdma.cpp
@@ -0,0 +1,301 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include <cstdint>
+#include <iostream>
+#include <string>
+#include <memory>
+#include <vector>
+#include <algorithm>
+using namespace std;
+#include <vendor-ril/telephony/ril.h>
+#include <binder/Parcel.h>
+#include <log/log.h>
+#include "common.h"
+#include "sms_pdu_cdma.h"
+#include "UserData.h"
+#include "CdmaSmsAddress.h"
+#include "BearerData.h"
+#include "SmsEnvelope.h"
+#include "HexDump.h";
+#include "SmsMessageConverter.h"
+#include "SmsMessage.h"
+
+static uint32_t msgid = 0;
+#undef LOG_TAG
+#define LOG_TAG "DEMO_CDMA_SMS"
+
+std::vector<std::uint8_t> mLastDispatchedSmsFingerprint;
+std::vector<std::uint8_t> mLastAcknowledgedSmsFingerprint;
+
+uint32_t getNextMessageId() {
+  // Testing and dialog with partners has indicated that
+  // msgId==0 is (sometimes?) treated specially by lower levels.
+  // Specifically, the ID is not preserved for delivery ACKs.
+  // Hence, avoid 0 -- constraining the range to 1..65535.
+  uint32_t nextMsgId = (msgid % 0xFFFF) + (uint32_t) 1;
+  msgid++;
+  return nextMsgId;
+}
+
+void resposeCdmaSms(RIL_CDMA_SMS_Message *p_cur) {
+  std::shared_ptr<SmsMessage> smsMessage =
+      SmsMessageConverter::newCdmaSmsMessageFromRil(p_cur);
+  mLastAcknowledgedSmsFingerprint.clear();
+  mLastAcknowledgedSmsFingerprint = smsMessage->getIncomingSmsFingerprint();
+  if ((!mLastAcknowledgedSmsFingerprint.empty()) &&
+          (mLastDispatchedSmsFingerprint == mLastAcknowledgedSmsFingerprint)) {
+      RLOGD("duplicate CDMA MT SMS, just return");
+      std::cout << "duplicate CDMA MT SMS, just return" << std::endl;
+      return;
+  }
+  mLastDispatchedSmsFingerprint.clear();
+  mLastDispatchedSmsFingerprint = mLastAcknowledgedSmsFingerprint;
+  smsMessage->parseSms();
+}
+
+// add for cdma long sms test
+int hexCharToInt(char c)
+{
+    if (c >= '0' && c <= '9')
+        return (c - '0');
+    if (c >= 'A' && c <= 'F')
+        return (c - 'A' + 10);
+    if (c >= 'a' && c <= 'f')
+        return (c - 'a' + 10);
+
+    return 0;
+}
+
+void hexStringToBytes(const char *in, int inLength, char *out, int outLength)
+{
+    int i;
+
+    if (in == NULL || out == NULL)
+    {
+        return;
+    }
+
+    if (inLength != outLength * 2)
+    {
+        return;
+    }
+
+    for (i = 0 ; i < inLength ; i += 2)
+    {
+        out[i/2] = (char)((hexCharToInt(in[i]) << 4)
+                           | hexCharToInt(in[i+1]));
+    }
+}
+
+//
+
+void createCdmaMessage(RequestInfo *pRI, char* dest, char* message, bool isStored, uint8_t retry,int32_t messageRef) {
+  bool statusReportRequested = false;
+  int priority = -1/*PRIORITY_NORMAL*/;
+  std::shared_ptr<UserData> uData = std::make_shared<UserData>();
+  uData->payloadStr = message;
+  uint32_t ascii_unsupported = 0;
+  uint32_t i;
+  uint32_t len;
+
+  len = strlen (message);
+
+  /* Check if we can do ASCII-7 */
+  for (i = 0; i < len; i++) {
+      if (message[i] & 0x80) {
+          ascii_unsupported++;
+          break;
+      }
+  }
+  if (ascii_unsupported) {
+      RLOGD("createCdmaMessage encoding (ENCODING_UNICODE_16)");
+      uData->msgEncodingSet = true;
+      uData->msgEncoding = UserData::ENCODING_UNICODE_16;
+  }
+  //std::cout << "dest: " << dest << std::endl;
+  //std::cout << "uData.payloadStr:" << uData->payloadStr << std::endl;
+  //uData.userDataHeader = smsHeader;
+  std::shared_ptr<CdmaSmsAddress> destAddr = CdmaSmsAddress::parse(dest); //TBD free.
+  //string str1 = HexDump::toHexString(destAddr->origBytes);
+  //std::cout << str1 << std::endl;
+  if (destAddr == nullptr)
+    return;
+  BearerData bearerData;
+  bearerData.messageType = BearerData::MESSAGE_TYPE_SUBMIT;
+
+  bearerData.messageId = getNextMessageId();
+
+  bearerData.deliveryAckReq = statusReportRequested;
+  bearerData.userAckReq = false;
+  bearerData.readAckReq = false;
+  bearerData.reportReq = false;
+  if (priority >= PRIORITY_NORMAL && priority <= PRIORITY_EMERGENCY) {
+    bearerData.priorityIndicatorSet = true;
+    bearerData.priority = priority;
+  }
+  bearerData.userData = uData;
+  std::vector<uint8_t> encodedBearerData = BearerData::encode(&bearerData);
+  RLOGD("MO (encoded) BearerData =  %s", bearerData.toString().c_str());
+  RLOGD("MO raw BearerData = '%s'", HexDump::toHexString(encodedBearerData).c_str());
+  //std::cout << "MO (encoded) BearerData = " << bearerData.toString() << std::endl;
+  //std::cout <<  "MO raw BearerData = '" << HexDump::toHexString(encodedBearerData) << "'" << std::endl;
+  if (encodedBearerData.empty())
+    return;
+
+  int teleservice =
+      bearerData.hasUserDataHeader ?
+          SmsEnvelope::TELESERVICE_WEMT : SmsEnvelope::TELESERVICE_WMT;
+
+  SmsEnvelope envelope;
+  envelope.messageType = SmsEnvelope::MESSAGE_TYPE_POINT_TO_POINT;
+  envelope.teleService = teleservice;
+  envelope.destAddress = destAddr;
+  envelope.bearerReply = RETURN_ACK;
+  envelope.bearerData = encodedBearerData;
+
+  uint32_t uTeleserviceID = envelope.teleService;
+  uint8_t bIsServicePresent = 0; //read?
+  uint32_t uServicecategory = 0;
+  uint32_t sAddress_digit_mode = destAddr->digitMode;
+  uint32_t sAddress_number_mode = destAddr->numberMode;
+  uint32_t sAddress_number_type = destAddr->ton;
+  uint32_t sAddress_number_plan = destAddr->numberPlan;
+  uint8_t sAddress_number_of_digits = destAddr->numberOfDigits;
+  uint8_t sAddress_digits[destAddr->origBytes.size()];
+  std::copy(destAddr->origBytes.begin(), destAddr->origBytes.end(),
+      sAddress_digits);
+  uint32_t sSubAddress_subaddressType = 0;
+  uint8_t sSubAddress_odd = 0;
+  uint8_t sSubAddress_number_of_digits = 0;
+//  uint8_t sSubAddress_digits;
+//  uint8_t sSubAddress.digits[digitCount]
+  int uBearerDataLen = encodedBearerData.size();
+  uint8_t aBearerData[uBearerDataLen];
+  std::copy(encodedBearerData.begin(), encodedBearerData.end(), aBearerData);
+
+  android::Parcel p;
+  size_t pos =  p.dataPosition();
+  if(pRI->pCI->requestNumber == RIL_REQUEST_IMS_SEND_SMS) {
+      p.writeInt32(RADIO_TECH_3GPP2);
+      p.write(&retry,sizeof(retry)); //retry
+      p.write(&messageRef, sizeof(messageRef)); //messageRef
+  }
+
+  if(isStored) {
+    p.writeInt32(2); /*      2 = "STO UNSENT"    */
+  }
+
+  p.writeInt32(uTeleserviceID);
+  p.write(&bIsServicePresent,sizeof(bIsServicePresent));
+  p.writeInt32(uServicecategory);
+  p.writeInt32(sAddress_digit_mode);
+  p.writeInt32(sAddress_number_mode);
+  p.writeInt32(sAddress_number_type);
+  p.writeInt32(sAddress_number_plan);
+  p.write(&sAddress_number_of_digits, sizeof(sAddress_number_of_digits));
+//  for(int i=0; i < sAddress_number_of_digits; i++){
+//    p.write(&(sAddress_digits[i]), sizeof(sAddress_digits[i]));
+//  }
+  for(auto i: destAddr->origBytes) {
+    p.write(&i, sizeof(i));
+  }
+  p.writeInt32(sSubAddress_subaddressType);
+  p.write(&sSubAddress_odd, sizeof(sSubAddress_odd));
+  p.write(&sSubAddress_number_of_digits, sizeof(sSubAddress_number_of_digits));
+  //add for 3gpp2 long sms test
+  size_t posDataLen =  p.dataPosition();
+  int payloadLen = bearerData.userData->payload.size();
+  if (payloadLen > SmsConstants::MAX_USER_DATA_BYTES && !isStored)
+  {
+    RLOGD("MO CDMA SMS, encoded user data too large (%d > %d bytes). Send test encoded string from phone: %s",
+        payloadLen, SmsConstants::MAX_USER_DATA_BYTES,message);
+    int smsCount=0, encodedStrBytes=0;
+    encodedStrBytes = strlen(message);
+    smsCount= encodedStrBytes/336; //the longest part SMS from phone is encoded into a string which has 336 characters in total;
+    if(encodedStrBytes%336)
+    {
+        smsCount += 1;
+    }
+    RLOGD("encodedStrBytes=%d, smsCount=%d",encodedStrBytes, smsCount);
+    int msgSegLen = 168; //336/2, two characters convert to an octet
+    int hasSendBytes = 0;
+    char msgSegByteArray[168]={0};
+    int iBearerDataLenInd=18; // bearer data len field is at 19th octect, index in an array is 18
+    for(int i = 0; i < smsCount; i++){
+      char* messageStart = message+i*336;
+      if(i == smsCount - 1 ){
+        msgSegLen = encodedStrBytes/2 - hasSendBytes;
+      }
+
+      hexStringToBytes(messageStart,msgSegLen*2,msgSegByteArray,msgSegLen);
+
+      int uBearerTestDataLen = msgSegByteArray[iBearerDataLenInd];
+      RLOGD("MO CDMA SMS, uBearerTestDataLen=%d",uBearerTestDataLen);
+      p.writeInt32(uBearerTestDataLen);
+      RLOGD("MO CDMA SMS, send part-%d, msgSegLen=%d, hasSendBytes=%d", i+1, msgSegLen, hasSendBytes);
+      for(int j=iBearerDataLenInd+1; j<msgSegLen; j++){
+        p.writeByte(msgSegByteArray[j]);
+      }
+
+      RequestInfo *pRI_backup = (RequestInfo *)calloc(1, sizeof(RequestInfo));
+      pRI_backup->token = pRI->token;
+      pRI_backup->pCI = pRI->pCI;
+      pRI_backup->socket_id = pRI->socket_id;
+      pRI_backup->p_next = pRI->p_next;
+      p.setDataPosition(pos);
+      pRI->pCI->dispatchFunction(p, pRI_backup);
+      //clean array and update pos
+      memset(msgSegByteArray,0,168);
+      hasSendBytes += msgSegLen;
+      p.setDataPosition(posDataLen);
+    }
+
+    if(pRI != NULL)
+      free(pRI);
+    return;
+  }
+  //end for 3gpp2 long sms test
+
+  p.writeInt32(uBearerDataLen);
+//  for (int i = 0; i < uBearerDataLen; i++) {
+//    p.write(&(aBearerData[i]), sizeof(aBearerData[i]));
+//  }
+  for(auto i: encodedBearerData) {
+    p.write(&i, sizeof(i));
+  }
+  p.setDataPosition(pos);
+  pRI->pCI->dispatchFunction(p, pRI);
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/sms_pdu_cdma.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/sms_pdu_cdma.h
new file mode 100644
index 0000000..d56939e
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/sms_pdu_cdma.h
@@ -0,0 +1,61 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef TEL_DEMO_SRC_SMS_PDU_CDMA_H_
+#define TEL_DEMO_SRC_SMS_PDU_CDMA_H_
+//#ifdef C2K_SUPPORT
+
+#include <cstdint>
+
+#include <vendor-ril/telephony/ril.h>
+#include <binder/Parcel.h>
+#include "common.h"
+
+/** Specifies if a return of an acknowledgment is requested for send SMS */
+static constexpr int RETURN_NO_ACK = 0;
+static constexpr int RETURN_ACK = 1;
+/**
+ * Supported priority modes for CDMA SMS messages
+ * (See 3GPP2 C.S0015-B, v2.0, table 4.5.9-1)
+ */
+static constexpr int PRIORITY_NORMAL = 0x0;
+static constexpr int PRIORITY_INTERACTIVE = 0x1;
+static constexpr int PRIORITY_URGENT = 0x2;
+static constexpr int PRIORITY_EMERGENCY = 0x3;
+
+void createCdmaMessage(RequestInfo *pRI, char* dest, char* message, bool isStored, uint8_t retry,int32_t messageRef);
+void resposeCdmaSms(RIL_CDMA_SMS_Message *p_cur);
+//#endif /*C2K_SUPPORT*/
+#endif /* TEL_DEMO_SRC_SMS_PDU_CDMA_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/gsm/sms_pdu.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/gsm/sms_pdu.cpp
new file mode 100644
index 0000000..a7b682b
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/gsm/sms_pdu.cpp
@@ -0,0 +1,2314 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <regex.h>
+#include <malloc.h>
+#include <time.h>
+#include <sys/timeb.h>
+#include <sys/sysinfo.h>
+#include <ctype.h>
+#include <arpa/inet.h>
+#include <log/log.h>
+
+#include "sms_pdu.h"
+#include "common.h"
+
+#if DEBUG
+#define RLOGE(x...) printf(x);printf("\n")
+#define RLOGD(x...) printf(x);printf("\n")
+#define RLOGW(x...) printf(x);printf("\n")
+#define RLOGE(x...) printf(x);printf("\n")
+#endif
+
+#undef LOG_TAG
+#define LOG_TAG "DEMO_PDU"
+void hexString_To_Bytes(char *in, int inLength, char *out);
+
+/* RFC3629 chapter 4. Syntax of UTF-8 Byte Sequences */
+static kal_int32 is_legal_utf8(const UTF8 *start, kal_int32 len)
+{
+    UTF8 tmp = 0;
+    const UTF8 *ptr = start + len;
+
+    switch (len) {
+        default:
+            return FALSE;
+
+        case 4:
+            tmp = *--ptr;
+            if (tmp < 0x80 || tmp > 0xBF) {
+                return FALSE;
+            }
+
+        case 3:
+            tmp = *--ptr;
+            if (tmp < 0x80 || tmp > 0xBF) {
+                return FALSE;
+            }
+
+        case 2:
+            tmp = *--ptr;
+            if (tmp > 0xBF) {
+                return FALSE;
+            }
+
+            switch (*start) {
+                case 0xE0:
+                    if (tmp < 0xA0) {
+                        return FALSE;
+                    }
+                    break;
+
+                case 0xED:
+                    if (tmp > 0x9F) {
+                        return FALSE;
+                    }
+                    break;
+
+                case 0xF0:
+                    if (tmp < 0x90) {
+                        return FALSE;
+                    }
+                    break;
+
+                case 0xF4:
+                    if (tmp > 0x8F) {
+                        return FALSE;
+                    }
+                    break;
+
+                default:
+                    if (tmp < 0x80) {
+                        return FALSE;
+                    }
+                    break;
+            }
+
+        case 1:
+            if (*start >= 0x80 && *start < 0xC2) {
+                return FALSE;
+            }
+    }
+
+    if (*start > 0xF4) {
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+kal_int32 is_utf8_sequence(const UTF8 *start, const UTF8 *end)
+{
+    kal_int32 len = utf8_tailing_bytes[*start] + 1;
+
+    if (start + len > end) {
+        return FALSE;
+    }
+
+    return is_legal_utf8(start, len);
+}
+
+kal_int32 kal_utf8_to_utf16(UTF16 *dest,
+                            const UTF8 *src,
+                            kal_int32 size)
+{
+    kal_int32 result = STATUS_SUCCESS;
+    const UTF8 *start = src;
+    const UTF8 *end = src;
+    UTF16 *target = dest;
+
+    while(*end) {
+        end++;
+    }
+
+    while (start < end) {
+        unsigned long tmp = 0;
+        unsigned int extra_bytes = utf8_tailing_bytes[*start];
+        //UTF8 *next = start + extra_bytes + 1;
+
+        if (target && target >= dest + size) {
+            result = STATUS_MEM_EXHAUSTED;
+            break;
+        }
+
+        if (start + extra_bytes >= end) {
+            result = STATUS_MEM_EXHAUSTED;
+            break;
+        }
+
+        if (!is_legal_utf8(start, extra_bytes + 1)) {
+            result = STATUS_ILLEGAL_UTF8;
+            break;
+        }
+
+        switch (extra_bytes) {
+            case 5:
+                tmp += *start++;
+                tmp <<= 6; /* illegal UTF8 */
+            case 4:
+                tmp += *start++;
+                tmp <<= 6; /* illegal UTF8 */
+            case 3:
+                tmp += *start++;
+                tmp <<= 6;
+            case 2:
+                tmp += *start++;
+                tmp <<= 6;
+            case 1:
+                tmp += *start++;
+                tmp <<= 6;
+            case 0:
+                tmp += *start++;
+        }
+
+        tmp -= utf8_offsets[extra_bytes];
+
+        if (tmp <= MAX_UNI_BMP) {
+            if (tmp >= SUR_HIGH_START && tmp <= SUR_LOW_END) {
+                result = STATUS_ILLEGAL_UTF8;
+                break;
+            } else {
+                if (target) {
+                    *target++ = (UTF16)tmp;
+                }
+
+                result++;
+            }
+        } else if (tmp > MAX_UTF16) {
+            result = STATUS_ILLEGAL_UTF8;
+            break;
+        } else {
+            if (target && target + 1 >= dest + size) {
+                result = STATUS_MEM_EXHAUSTED;
+                break;
+            }
+
+            tmp -= UTF16_HALF_BASE;
+
+            if (target) {
+                *target++ = (UTF16)((tmp >> UTF16_HALF_SHIFT) + SUR_HIGH_START);
+                *target++ = (UTF16)((tmp & UTF16_HALF_MASK) + SUR_LOW_START);
+            }
+
+            result += 2;
+        }
+    }
+
+    if (target) {
+        *target = 0;
+    }
+
+    return result;
+}
+
+kal_int32 kal_utf8_to_utf32(UTF32 *dest, const UTF8 *src, kal_int32 size)
+{
+    kal_int32 result = STATUS_SUCCESS;
+    const UTF8 *start = src;
+    const UTF8 *end = src;
+    UTF32 *target = dest;
+
+    if (!src) { return STATUS_NULL_POINTER; }
+
+    while(*end) {
+        end++;
+    }
+
+    while (start < end) {
+        unsigned long tmp = 0;
+        unsigned int extra_bytes = utf8_tailing_bytes[*start];
+        //UTF8 *next = start + extra_bytes + 1;
+
+        if (target && target >= dest + size) {
+            result = STATUS_MEM_EXHAUSTED;
+            break;
+        }
+
+        if (start + extra_bytes >= end) {
+            result = STATUS_MEM_EXHAUSTED;
+            break;
+        }
+
+        if (!is_legal_utf8(start, extra_bytes + 1)) {
+            result = STATUS_ILLEGAL_UTF8;
+            break;
+        }
+
+        switch (extra_bytes) {
+            case 5:
+                tmp += *start++;
+                tmp <<= 6; /* illegal UTF8 */
+            case 4:
+                tmp += *start++;
+                tmp <<= 6; /* illegal UTF8 */
+            case 3:
+                tmp += *start++;
+                tmp <<= 6;
+            case 2:
+                tmp += *start++;
+                tmp <<= 6;
+            case 1:
+                tmp += *start++;
+                tmp <<= 6;
+            case 0:
+                tmp += *start++;
+        }
+
+        tmp -= utf8_offsets[extra_bytes];
+
+        if (tmp <= MAX_LEGAL_UTF32) {
+            if (tmp >= SUR_HIGH_START && tmp <= SUR_LOW_END) {
+                result = STATUS_ILLEGAL_UTF8;
+                break;
+            } else {
+                if (target) {
+                    *target++ = tmp;
+                }
+                result++;
+            }
+        } else {
+            result = STATUS_ILLEGAL_UTF8;
+            break;
+        }
+    }
+
+    if (target) {
+        *target = 0;
+    }
+
+    return result;
+}
+
+kal_int32 kal_utf8_to_ucs2(UCS2 *dest, const UTF8 *src, kal_int32 size)
+{
+    kal_int32 result = STATUS_SUCCESS;
+    const UTF8 *start = src;
+    const UTF8 *end = src;
+    UTF16 *target = dest;
+
+    if (!src) { return STATUS_NULL_POINTER; }
+    while(*end) {
+        end++;
+    }
+
+    while (start < end) {
+        unsigned long tmp = 0;
+        unsigned int extra_bytes = utf8_tailing_bytes[*start];
+        //UTF8 *next = start + extra_bytes + 1;
+
+        if (target && target > dest + size) {
+            result = STATUS_MEM_EXHAUSTED;
+            break;
+        }
+
+        if (start + extra_bytes >= end) {
+            result = STATUS_MEM_EXHAUSTED;
+            break;
+        }
+
+        if (!is_legal_utf8(start, extra_bytes + 1)) {
+            result = STATUS_ILLEGAL_UTF8;
+            break;
+        }
+
+        switch (extra_bytes) {
+            case 5:
+                tmp += *start++;
+                tmp <<= 6; /* illegal UTF8 */
+            case 4:
+                tmp += *start++;
+                tmp <<= 6; /* illegal UTF8 */
+            case 3:
+                tmp += *start++;
+                tmp <<= 6;
+            case 2:
+                tmp += *start++;
+                tmp <<= 6;
+            case 1:
+                tmp += *start++;
+                tmp <<= 6;
+            case 0:
+                tmp += *start++;
+        }
+        tmp -= utf8_offsets[extra_bytes];
+
+        if (tmp <= MAX_UNI_BMP) {
+            if (tmp >= SUR_HIGH_START && tmp <= SUR_LOW_END) {
+                result = STATUS_ILLEGAL_UTF8;
+                break;
+            } else {
+                if (target) {
+                    *target++ = (UTF16)tmp;
+                }
+                result++;
+            }
+        } else {
+            result = STATUS_ILLEGAL_UTF8;
+            break;
+        }
+    }
+
+    if (target) {
+        *target = 0;
+    }
+
+    return result;
+}
+
+kal_int32 kal_utf16_to_utf8(UTF8 *dest, const UTF16 *src, kal_int32 size)
+{
+    kal_int32 result = STATUS_SUCCESS;
+    const UTF16 *start = src;
+    const UTF16 *end = src;
+    const UTF32 TAIL_MASK = 0xBF;
+    const UTF32 TAIL_MARK = 0x80;
+
+    UTF8 *target = dest;
+
+    if (!src) { return STATUS_NULL_POINTER; }
+    while (*end) {
+        end++;
+    }
+
+    while (start < end) {
+        UTF32 tmp = 0;
+        unsigned long bytes = 0;
+
+        tmp = *start++;
+        //RLOGD("tmp = [%X]\n", tmp);
+        /* */
+        if (tmp >= SUR_HIGH_START && tmp <= SUR_HIGH_END) {
+            if (start < end) {
+                UTF32 tmp2 = *start;
+                if (tmp2 >= SUR_LOW_START && tmp2 <= SUR_LOW_END) {
+                    tmp = ((tmp - SUR_HIGH_START) << UTF16_HALF_SHIFT)
+                        + (tmp2 - SUR_LOW_START) + UTF16_HALF_BASE;
+                    start++;
+                } else {
+                    result = STATUS_ILLEGAL_UTF16;
+                    break;
+                }
+            } else {
+                result = STATUS_MEM_EXHAUSTED;
+                break;
+            }
+        } else if (tmp >= SUR_LOW_START && tmp <= SUR_LOW_END) {
+            result = STATUS_ILLEGAL_UTF16;
+            break;
+        }
+
+        if (tmp < (UTF32)0x80) {
+            bytes = 1;
+        } else if (tmp < (UTF32)0x800) {
+            bytes = 2;
+        } else if (tmp < (UTF32)0x10000) {
+            bytes = 3;
+        } else if (tmp < (UTF32)0x110000) {
+            bytes = 4;
+        } else {
+            result = STATUS_ILLEGAL_UTF16;
+            break;
+        }
+
+        if (target && size > 0) {
+            size -= bytes;
+            if (0 >= size) {
+                break;
+            }
+
+            switch (bytes) {
+                case 4:
+                    *(target + 3) = (UTF8)((tmp | TAIL_MARK) & TAIL_MASK);
+                    tmp >>= 6;
+                case 3:
+                    *(target + 2) = (UTF8)((tmp | TAIL_MARK) & TAIL_MASK);
+                    tmp >>= 6;
+                case 2:
+                    *(target + 1) = (UTF8)((tmp | TAIL_MARK) & TAIL_MASK);
+                    tmp >>= 6;
+                case 1:
+                    *target = (UTF8)(tmp | first_byte_mark[bytes]);
+            }
+            target += bytes;
+        }
+        result += bytes;
+    }
+
+    if (target)
+        *target = 0;
+
+    return result;
+}
+
+kal_int32 kal_utf32_to_utf8(UTF8 *dest, const UTF32 *src, kal_int32 size)
+{
+    kal_int32 result = STATUS_SUCCESS;
+    const UTF32 *start = src, *end = src;
+    UTF8 *target = dest;
+    const UTF32 TAIL_MASK = 0xBF;
+    const UTF32 TAIL_MARK = 0x80;
+
+    if (!src) { return STATUS_NULL_POINTER; }
+    while (*end) {
+        end++;
+    }
+
+    while (start < end) {
+        UTF32 tmp = 0;
+        unsigned long bytes = 0;
+
+        tmp = *start++;
+        /* UTF16 surrogate values are illegal in UTF32*/
+        if (tmp >= SUR_HIGH_START && tmp <= SUR_LOW_END) {
+            result = STATUS_ILLEGAL_UTF32;
+            break;
+        }
+
+        if (tmp < (UTF32)0x80) {
+            bytes = 1;
+        } else if (tmp < (UTF32)0x800) {
+            bytes = 2;
+        } else if (tmp < (UTF32)0x10000) {
+            bytes = 3;
+        } else if (tmp < (UTF32)0x110000) {
+            bytes = 4;
+        } else {
+            result = STATUS_ILLEGAL_UTF16;
+            break;
+        }
+
+        if (target && size) {
+            size -= bytes;
+            if (size <= 0) {
+                break;
+            }
+
+            switch (bytes) {
+                case 4:
+                    *(target + 3) = (UTF8)((tmp | TAIL_MARK) & TAIL_MASK);
+                    tmp >>= 6;
+                case 3:
+                    *(target + 2) = (UTF8)((tmp | TAIL_MARK) & TAIL_MASK);
+                    tmp >>= 6;
+                case 2:
+                    *(target + 1) = (UTF8)((tmp | TAIL_MARK) & TAIL_MASK);
+                    tmp >>= 6;
+                case 1:
+                    *target = (UTF8)(tmp | first_byte_mark[bytes]);
+            }
+            target += bytes;
+        }
+        result += bytes;
+    }
+
+    if (target) {
+        *target = 0;
+    }
+
+    return result;
+}
+
+kal_int32 kal_ucs2_to_utf8(UTF8 *dest, const UCS2 *src, kal_int32 size)
+{
+    kal_int32 result = STATUS_SUCCESS;
+    const UCS2 *start = src, *end = src;
+    const UTF32 TAIL_MASK = 0xBF;
+    const UTF32 TAIL_MARK = 0x80;
+    UTF8 *target = dest;
+
+    if (!src) { return STATUS_NULL_POINTER; }
+    while (*end) {
+        end++;
+    }
+
+    while (start < end) {
+        UTF32 tmp = 0;
+        unsigned long bytes = 0;
+
+        tmp = *start++;
+        /* */
+        if (tmp >= SUR_HIGH_START && tmp <= SUR_LOW_END) {
+            result = STATUS_ILLEGAL_UCS2;
+            break;
+        }
+
+        if (tmp < (UTF32)0x80) {
+            bytes = 1;
+        } else if (tmp < (UTF32)0x800) {
+            bytes = 2;
+        } else if (tmp < (UTF32)0x10000) {
+            bytes = 3;
+        } else if (tmp < (UTF32)0x110000) {
+            bytes = 4;
+        } else {
+            result = STATUS_ILLEGAL_UCS2;
+            break;
+        }
+
+        if (target && size > 0) {
+            size -= bytes;
+            if (size <= 0) {
+                break;
+            }
+
+            switch (bytes) {
+                case 4:
+                    *(target + 3) = (UTF8)((tmp | TAIL_MARK) & TAIL_MASK);
+                    tmp >>= 6;
+                case 3:
+                    *(target + 2) = (UTF8)((tmp | TAIL_MARK) & TAIL_MASK);
+                    tmp >>= 6;
+                case 2:
+                    *(target + 1) = (UTF8)((tmp | TAIL_MARK) & TAIL_MASK);
+                    tmp >>= 6;
+                case 1:
+                    *target = (UTF8)(tmp | first_byte_mark[bytes]);
+            }
+            target += bytes;
+        }
+        result += bytes;
+    }
+
+    if (target) {
+        *target = 0;
+    }
+
+    return result;
+}
+
+kal_int32 kal_ext_ascii_to_utf8(UTF8 *dest, const kal_uint8 *src, kal_int32 size)
+{
+    kal_int32 result = STATUS_SUCCESS;
+    const kal_uint8 *start = src, *end = src;
+    const UTF32 TAIL_MASK = 0xBF;
+    const UTF32 TAIL_MARK = 0x80;
+    UTF8 *target = dest;
+
+    if (!src) { return STATUS_NULL_POINTER; }
+    while (*end) {
+        end++;
+    }
+
+    while (start < end) {
+        UTF32 tmp = 0;
+        unsigned long bytes = 0;
+
+        tmp = *start++;
+
+        if (tmp < (UTF32)0x80) {
+            bytes = 1;
+        } else {
+            bytes = 2;
+        }
+
+        if (target && size > 0) {
+            size -= bytes;
+            if (size <= 0) {
+                break;
+            }
+
+            switch (bytes) {
+                case 2:
+                    *(target + 1) = (UTF8)((tmp | TAIL_MARK) & TAIL_MASK);
+                    tmp >>= 6;
+                case 1:
+                    *target = (UTF8)(tmp | first_byte_mark[bytes]);
+            }
+            target += bytes;
+        }
+        result += bytes;
+    }
+
+    if (target) {
+        *target = 0;
+    }
+
+    return result;
+}
+
+static kal_int32 _mdapi_sms_set_timestamp(mdapi_sms_record_t *sms)
+{
+    struct timeb tp;
+    struct tm *p;
+    kal_int32 y = 0;
+
+    ftime(&tp);
+    sms->time[6] = tp.timezone;
+
+    p = localtime(&tp.time);
+    y = 1900 + p->tm_year;
+    sms->time[0] = y % 100;
+    sms->time[1] = 1 + p->tm_mon;
+    sms->time[2] = p->tm_mday;
+    sms->time[3] = p->tm_hour;
+    sms->time[4] = p->tm_min;
+    sms->time[5] = p->tm_sec;
+
+    return MDAPI_RET_SUCCESS;
+}
+
+static unsigned char
+internal_mdapi_hex2int(char *s) {
+    int ret = 0;
+    int len = 2, i = 0;
+    while (i < len) {
+        if (s[i] == 0) {
+            return -1;
+        } else if (s[i] >= 'a' && s[i] <= 'f') {
+            ret = (s[i] - 'a' + 10) + (ret << 4);
+        } else if (s[i] >= 'A' && s[i] <= 'F') {
+            ret = (s[i] - 'A' + 10) + (ret << 4);
+        } else if (s[i] >= '0' && s[i] <= '9') {
+            ret = (s[i] - '0') + (ret << 4);
+        } else {
+            return -1;
+        }
+        i++;
+    }
+    return ret;
+}
+
+kal_int32 _mdapi_sms_7bit_encode(kal_int8 *mesg, kal_int32 len, kal_int8 *output, kal_int32 size)
+{
+    kal_int32 i = 0;
+    kal_int8 *ptr = mesg;
+    kal_int32 out_len = 0;
+    kal_uint8 curbyte = 0;
+    kal_uint8 curbit = 0;
+    kal_uint8 c = 0;
+
+    output[0] = '\0';
+    while(*ptr && len) {
+        c = latin1_to_gsm_table[(kal_uint8)*ptr++];
+        len--;
+        for (i = 0; i < 7; i++) {
+            if(((1 << i) & c) != 0) {
+                curbyte |= ((char)1 << curbit);
+            }
+
+            curbit++;
+            if(curbit == 8) {
+                curbit = 0;
+                out_len += snprintf(output + out_len, size - out_len - 1, "%02X", curbyte);
+                curbyte = 0;
+            }
+        }
+    }
+
+    if (curbit > 0) {
+        out_len += snprintf(output + out_len, size - out_len - 1, "%02X", curbyte);
+    }
+
+    return out_len;
+}
+
+int internal_mdapi_sms_7bit_decode(char * message, char * output, int output_size, int padding_bits, int octect)
+{
+    int i = 0, len = 0;
+    char * ptr = message;
+    int output_len = 0;
+    int cur_val = 0;
+    int val = 0;
+    int last_val = 0;//used to save last 1 octet
+    int offset;
+
+    if( padding_bits < 0||padding_bits > 6 )
+    {
+        return 0;
+    }
+    //Calc how many octets are there
+    len = strlen(message) >> 1;
+
+    for(i = 0; i < len - 1; i++){
+        offset = i % 0x7;
+        //Add padding bit, realign to septets.
+        cur_val = ((internal_mdapi_hex2int(ptr)>>padding_bits)&0xFF)+((internal_mdapi_hex2int(ptr+2)<<(8-padding_bits))&0xFF);
+        val = ((cur_val << offset) & 0x7F)+((last_val >> (8 - offset))&0xFF);
+        last_val = cur_val;
+        //printf("val raw = 0x%X, val = 0x%X\n", val, gsm_to_latin1_table[(kal_uint8)(val & 0xFF)]);
+        output[output_len++] = (char)gsm_to_latin1_table[(kal_uint8)(val & 0xFF)];
+        if (output_len == output_size - 1) {
+            output[output_len] = 0;
+            return output_len;
+        }
+
+        if(offset == 6){
+            val = ((cur_val>>1)&0x7F) ;
+            //printf("val raw = 0x%X, val = 0x%X\n", val, gsm_to_latin1_table[(kal_uint8)(val & 0xFF)]);
+            output[output_len++] = (char)gsm_to_latin1_table[(kal_uint8)(val & 0xFF)];
+            if (output_len == output_size - 1) {
+                output[output_len] = 0;
+                return output_len;
+            }
+        }
+        ptr += 2;
+    }
+
+    /* decode the last octet */
+    cur_val = (internal_mdapi_hex2int(ptr) >> padding_bits) & 0xFF;
+    offset = i % 7;
+    val = ((cur_val << offset) & 0x7F)+((last_val >> (8 - offset))&0xFF);
+    //printf("val raw = 0x%X, val = 0x%X\n", val, gsm_to_latin1_table[(kal_uint8)(val & 0xFF)]);
+    output[output_len++] = (char)gsm_to_latin1_table[(kal_uint8)(val & 0xFF)];
+    if (output_len == output_size - 1) {
+        output[output_len] = 0;
+        return output_len;
+    }
+
+    //printf("output = [%s], output_len = [%d]\n", output, output_len);
+    if(offset == 6){
+        val = ((cur_val >> 1) & 0x7F);
+        //printf("val raw = 0x%X, val = 0x%X\n", val, gsm_to_latin1_table[(kal_uint8)(val & 0xFF)]);
+        if (val || octect) {
+            output[output_len++] = (char)gsm_to_latin1_table[(kal_uint8)(val & 0xFF)];
+            if (output_len == output_size - 1) {
+                output[output_len] = 0;
+                return output_len;
+            }
+        }
+    }
+    output[output_len] = 0;
+
+    return output_len;
+}
+
+int internal_mdapi_address_decode(char *number, char *output, int output_size, int type) {
+    // 81 90 21 43 65 87 --> 0912345678
+    RLOGD("%s, %s, %d", __FILE__, __FUNCTION__, __LINE__);
+
+    int len = 0;
+    int output_len = 0;
+    int val = 0;
+    char *ptr = number;
+    int padding_bit = 0;//To identify the number is even or odd
+    //RLOGD("before internal_mdapi_hex2int(ptr), ptr :%s",ptr);
+    // Length
+    len = internal_mdapi_hex2int(ptr);
+    //RLOGD("after internal_mdapi_hex2int(ptr), ptr :%s",ptr);
+    ptr += 2;
+    //RLOGD("after +=2, ptr :%s",ptr);
+
+    if (len == 0) {
+        return 2;
+    } else if (len < 0) {
+        return -1;
+    }
+
+    if (type) {
+        len = (len) << 1;
+    } else {
+        len += 2;
+    }
+
+    RLOGD("Address length = %d ", len);
+
+    // Type-of-address
+    val = internal_mdapi_hex2int(ptr);
+    ptr += 2;
+    len -= 2;
+    if (val == 0x91) {
+        // international number
+        output_len += snprintf(output+output_len, output_size-output_len-1, "+");
+    } else if (val == 0x81) {
+        // national number
+    } else if ((val & 0x50) == 0x50 ){
+        // alphabet number
+    } else {
+        RLOGD("Invalid type-of-address : %02X " , val);
+    }
+
+    // decode alphabet number
+    if (0x50 == (val & 0x50)) {
+        kal_int32 octect = (((len * 4) / 7 ) % 8 == 0) ? 1 : 0;
+        kal_char * tmp = (kal_char * )malloc(len + 1);
+        if (!tmp) {
+            RLOGD("Invalid type-of-address : %02X ", val);
+            return -1;
+        }
+        memcpy(tmp, ptr, len);
+        tmp[len] = 0;
+        output_len += internal_mdapi_sms_7bit_decode(tmp, output, output_size - output_len - 1, 0, octect);
+        free(tmp);
+        tmp = NULL;
+    } else {
+        do {
+            if (len > 1) {
+                if (*ptr == 'F') {
+                    output_len += snprintf(output + output_len, output_size - output_len - 1, "%c", *(ptr + 1));
+                } else {
+                    output_len += snprintf(output + output_len, output_size - output_len - 1, "%c%c", *(ptr + 1), *(ptr));
+                }
+
+                len -= 2;
+                ptr += 2;
+            } else {
+                output_len += snprintf(output + output_len, output_size - output_len - 1, "%c", *(ptr + 1));
+                len -= 1;
+                ptr += 1;
+                padding_bit = 1;
+            }
+        } while (len > 0);
+    }
+
+    return (ptr-number+padding_bit);
+}
+
+void _smsbuf_byte_align(smsbuf_t *buf)
+{
+    if (buf->curbyte > buf->finalbyte) {
+        return;
+    }
+    if (buf->curbit != 0) {
+        buf->curbit = 0;
+        buf->curbyte++;
+    }
+}
+
+void _smsbuf_init(smsbuf_t *buf)
+{
+    buf->curbyte = buf->smsbuf;
+    buf->curbit = 0;
+    memset(buf->smsbuf, 0, sizeof(buf->smsbuf));
+    buf->finalbyte = buf->curbyte + sizeof(buf->smsbuf);
+}
+
+void _smsbuf_set1bit(smsbuf_t *buf, kal_uint8 b)
+{
+    if (buf->curbyte > buf->finalbyte)
+        return;
+
+    if (b != 0)
+        *buf->curbyte |= (1 << buf->curbit);
+
+    buf->curbit++;
+    if (buf->curbit == 8) {
+        buf->curbit = 0;
+        buf->curbyte++;
+    }
+}
+
+void _smsbuf_set_multi_bits(smsbuf_t *buf, kal_uint32 value, kal_uint8 bit_num)
+{
+    kal_int32 i = 0;
+
+    for (i = 0; i < bit_num; i++) {
+        _smsbuf_set1bit(buf, (value & (1 << i)) != 0);
+    }
+}
+
+void _smsbuf_set_octet(smsbuf_t *buf, kal_uint8 c)
+{
+    _smsbuf_byte_align(buf);
+    *(buf->curbyte) = c;
+    buf->curbyte++;
+}
+
+void _smsbuf_septet_align(smsbuf_t *buf)
+{
+    if (buf->curbyte > buf->finalbyte)
+        return;
+    while (((buf->curbyte - buf->septet_start) * 8 + buf->curbit) % 7 != 0)
+        _smsbuf_set1bit(buf, 0);
+}
+
+void _smsbuf_set_septet_start(smsbuf_t *buf)
+{
+    _smsbuf_byte_align(buf);
+    buf->septet_start = buf->curbyte;
+}
+kal_uint8 lookup_latin1_to_gsm_ex_table(kal_int8 character)
+{
+    int i;
+    for( i=0; latin1_to_gsm_tableEx[i].symbol != NULL; i++) {
+        if (character == latin1_to_gsm_tableEx[i].symbol)
+            return latin1_to_gsm_tableEx[i].value;
+    }
+    return NULL;
+}
+void _smsbuf_set_string(smsbuf_t *buf, kal_int8 *str, kal_int32 size)
+{
+    kal_int32 i = 0;
+    _smsbuf_septet_align(buf);
+
+    //RLOGD("%s, %s, %d. string is:[%s],size is:[%d]", __FILE__, __FUNCTION__, __LINE__, (char*)str, size);
+    while (*str && size) {
+        /* change the iso8859latin1 charactor to gsm support charactor */
+        //RLOGD("%s, %s, %d. character is:[%d]-[0x%x]", __FILE__, __FUNCTION__, __LINE__, (int)*str,*str);
+        kal_uint8 c = lookup_latin1_to_gsm_ex_table(*str);
+        if(c != NULL)
+        {
+            //RLOGD("extent table!");
+            for (i = 0; i < 7; i++) {
+                _smsbuf_set1bit(buf, ((1 << i) & 0x1b) != 0);
+            }
+            size--;
+        } else {
+            c = latin1_to_gsm_table[(kal_uint8)*str];
+        }
+        //RLOGD("%s, %s, %d. character is:[%d]-[0x%x]", __FILE__, __FUNCTION__, __LINE__, (int)c,c);
+        str++;
+        size--;
+        for (i = 0; i < 7; i++) {
+            _smsbuf_set1bit(buf, ((1 << i) & c) != 0);
+            //KAL_RLOG(KAL_LOG_INFO, LOG_TAG, "curbit = [%d] curbyte=[%X]", buf->curbit, *buf->curbyte);
+        }
+        //KAL_RLOG(KAL_LOG_INFO, LOG_TAG, "size = [%d] c = [%c]", size, c);
+    }
+}
+
+void _smsbuf_set_addr(smsbuf_t *buf, kal_int8 *str)
+{
+    _smsbuf_byte_align(buf);
+
+    while (*str) {
+        kal_uint8 c = *str;
+
+        if (*str == '*') {
+            c = 0xa;
+        } else if (*str == '#') {
+            c = 0xb;
+        } else if (*str == 'p') {
+            c = 0xc;
+        } else if (*str == 'w') {
+            c = 0xd;
+        } else if (*str == '+') {
+            c = 0xe;
+        } else {
+            c = *str - '0';
+        }
+
+        if (buf->curbit == 0) {
+            *buf->curbyte = c;
+            buf->curbit = 4;
+        } else {
+            *buf->curbyte |= (c << 4);
+            buf->curbyte++;
+            buf->curbit = 0;
+        }
+
+        str++;
+    }
+
+    if (buf->curbit == 4) {
+        *buf->curbyte |= 0xF0;
+        buf->curbyte++;
+        buf->curbit = 0;
+    }
+}
+
+kal_int32 _smsbuf_hex_string(smsbuf_t *buf, kal_int8 *output, kal_int32 size)
+{
+    kal_int32 len = 0;
+    kal_uint8 *str = buf->smsbuf;
+
+    _smsbuf_byte_align(buf);
+    while (str != buf->curbyte && (size - len) > 3) {
+        len += snprintf(output + len, size - len, "%02X", *str);
+        str++;
+    }
+
+    return len;
+}
+
+kal_int32 _mdapi_sms_encode_addr(smsbuf_t *buf, kal_int8 *smsc, kal_int32 type)
+{
+    kal_int32 len = strlen(smsc);
+    kal_int8 *str = smsc;
+
+    kal_uint8 addr_plane = SMS_NP_ISDNTEL;
+    kal_uint8 addr_type = SMS_TON_UNKNOWN;
+
+    if (len <= 0) {
+        /* use default sca for sms message */
+        _smsbuf_set_octet(buf, 0);
+        return 1;;
+    }
+
+    if (len > 255) {
+        RLOGD("input number is too long. len[%d] smsc[%s] ", len, smsc);
+        return 0;
+    }
+
+    /* check the type of address */
+    while (*str) {
+        if (!isdigit(*str) && *str != '+' && *str != '*'
+            && *str != '#' && *str != 'p' && *str != 'w')
+            addr_type = SMS_TON_ALPHANUMERIC;
+        str++;
+    }
+
+    if (smsc[0] == '+' && addr_type != SMS_TON_ALPHANUMERIC) {
+        addr_type = SMS_TON_INTERNATIONAL;
+        /* */
+        str = &smsc[1];
+        len--;
+    } else {
+        str = smsc;
+    }
+
+    /* set len */
+    if (type == SMS_ENCODE_SCA)
+        _smsbuf_set_octet(buf, len / 2 + len % 2 + 1);
+    else {
+        _smsbuf_set_octet(buf, len);
+    }
+
+    RLOGD("%02X, %d ", *(buf->curbyte), buf->curbyte - buf->smsbuf);
+
+    _smsbuf_set_multi_bits(buf, addr_plane, 4);
+    _smsbuf_set_multi_bits(buf, addr_type, 3);
+    _smsbuf_set1bit(buf, 1);
+
+    RLOGD("%02X, %d ", *(buf->curbyte), buf->curbyte - buf->smsbuf);
+
+    if (addr_type == SMS_TON_ALPHANUMERIC) {
+        _smsbuf_set_septet_start(buf);
+        _smsbuf_set_string(buf, str, len);
+    } else {
+        _smsbuf_set_addr(buf, str);
+    }
+
+    _smsbuf_byte_align(buf);
+
+    return buf->curbyte - buf->smsbuf;
+}
+
+kal_int32 _mdapi_sms_encode_pdu(mdapi_sms_record_t *sms,
+                            kal_int8 *smsc,
+                            mdapi_sms_settings_t *settings,
+                            kal_char *start,
+                            kal_int32 send_size,
+                            kal_uint8 *udh,
+                            kal_char *output,
+                            kal_int32 out_len,
+                            kal_int32 *sca_out_len)
+{
+    smsbuf_t smsbuf;
+    kal_int32 udh_len = 0;
+    kal_int32 len = 0;
+    kal_int32 sca_len = 0;
+
+    if (udh) {
+        udh_len = udh[0];
+    } else {
+        udh_len = 0;
+    }
+
+    memset(&smsbuf, 0, sizeof(smsbuf));
+    _smsbuf_init(&smsbuf);
+
+    /* SMSC */
+    sca_len = _mdapi_sms_encode_addr(&smsbuf, smsc, SMS_ENCODE_SCA);
+
+    /* Encode PDU Type */
+    {
+        _smsbuf_byte_align(&smsbuf);
+
+        /* Message Type Indicator */
+        _smsbuf_set_multi_bits(&smsbuf, SMS_SUBMIT, 2);
+        //KAL_RLOG(KAL_LOG_INFO, LOG_TAG, "curbit = [%d] curbyte=[%02X]", smsbuf.curbit, *smsbuf.curbyte);
+        /* Reject Duplicate */
+        _smsbuf_set1bit(&smsbuf, 0);
+        //KAL_RLOG(KAL_LOG_INFO, LOG_TAG, "curbit = [%d] curbyte=[%02X]", smsbuf.curbit, *smsbuf.curbyte);
+        /* Validity Period Format */
+        _smsbuf_set_multi_bits(&smsbuf, settings->vpf, 2);
+        //KAL_RLOG(KAL_LOG_INFO, LOG_TAG, "curbit = [%d] curbyte=[%02X]", smsbuf.curbit, *smsbuf.curbyte);
+
+        /* Status Report Request */
+        if (settings->srr)
+            _smsbuf_set1bit(&smsbuf, 1);
+        else
+            _smsbuf_set1bit(&smsbuf, 0);
+        //KAL_RLOG(KAL_LOG_INFO, LOG_TAG, "curbit = [%d] curbyte=[%02X]", smsbuf.curbit, *smsbuf.curbyte);
+
+        /* User Data Header Indicator */
+        if (udh_len)
+            _smsbuf_set1bit(&smsbuf, 1);
+        else
+            _smsbuf_set1bit(&smsbuf, 0);
+
+        //KAL_RLOG(KAL_LOG_INFO, LOG_TAG, "curbit = [%d] curbyte=[%02X]", smsbuf.curbit, *smsbuf.curbyte);
+
+        /* Replay Path */
+        _smsbuf_set1bit(&smsbuf, settings->rp);
+
+        //KAL_RLOG(KAL_LOG_INFO, LOG_TAG, "curbit = [%d] curbyte=[%02X]", smsbuf.curbit, *smsbuf.curbyte);
+    }
+
+    /* Encode MR */
+    {
+        /* Message Reference Count, Long Message should use this */
+        _smsbuf_set_octet(&smsbuf, 0);
+    }
+
+    /* Encode OA/DA */
+    _mdapi_sms_encode_addr(&smsbuf, sms->phone_number, SMS_ENCODE_OADA);
+
+    /* Encode Protocol Identifier */
+    _smsbuf_set_octet(&smsbuf, 0x00);
+
+    /* Encode DCS */
+    {
+        /* Bit 0,1, Class */
+        _smsbuf_set_multi_bits(&smsbuf, sms->sms_class, 2);
+        /* Bit 2,3, Class */
+        _smsbuf_set_multi_bits(&smsbuf, sms->charset, 2);
+        /* Bit 4 */
+        _smsbuf_set1bit(&smsbuf, 0);
+        /* Bit 5 */
+        /* No text compressed */
+        _smsbuf_set1bit(&smsbuf, 0);
+        /* Bit 6, 7 */
+        _smsbuf_set_multi_bits(&smsbuf, 0, 0);
+    }
+    //_smsbuf_byte_align(&smsbuf);
+
+    /* Validity Period */
+    {
+        if (settings->vpf == SMS_VPF_ABSOLUTE) {
+            // TODO: add absolute validity period
+
+        } else if (settings->vpf == SMS_VPF_RELATIVE) {
+            // TODO: add validity period support
+            kal_uint8 validity_period = 0xAA;
+            _smsbuf_set_octet(&smsbuf, validity_period);
+        }
+    }
+
+    /* User Data Header */
+    {
+        if (udh_len) {
+            kal_int32 i = 0;
+            if (sms->charset == MDAPI_SMS_CHARSET_UCS2) {
+                _smsbuf_set_octet(&smsbuf, 1 + udh_len + send_size);
+            } else if (sms->charset == MDAPI_SMS_CHARSET_GSM_7BIT) {
+                _smsbuf_set_octet(&smsbuf, (((1 + udh_len) * 8 + 6) / 7) + send_size);
+            } else if (sms->charset == MDAPI_SMS_CHARSET_GSM_8BIT) {
+                _smsbuf_set_octet(&smsbuf, 1 + udh_len + send_size/2);
+            }
+
+            /* set the start byte of septet(7bits) align */
+            _smsbuf_set_septet_start(&smsbuf);
+            for (i = 0; i < udh_len + 1; i++) {
+                _smsbuf_set_octet(&smsbuf, udh[i]);
+            }
+        } else {
+            if(sms->charset == MDAPI_SMS_CHARSET_GSM_8BIT)
+            {
+                _smsbuf_set_octet(&smsbuf, send_size/2);
+            }
+            else
+            {
+                _smsbuf_set_octet(&smsbuf, send_size);
+            }
+
+            /* set the start byte of septet(7bits) align */
+            _smsbuf_set_septet_start(&smsbuf);
+        }
+    }
+
+    /* Get the Hex String */
+    len = _smsbuf_hex_string(&smsbuf, output, out_len);
+    RLOGD("encoded pdu = (%s), len = (%d) ", output, len);
+
+    /* Set User Data */
+    if (sms->charset == MDAPI_SMS_CHARSET_GSM_7BIT) {
+        //_sms_iso8859latin1_to_gsm(start, gsm, *size + 1);
+        _smsbuf_set_string(&smsbuf, start, send_size);
+    } else if(sms->charset == MDAPI_SMS_CHARSET_GSM_8BIT) {
+        kal_int32 i = 0;
+        char outhex[MAX_PDU_SIZE] = {0};
+        hexString_To_Bytes(start, send_size, outhex);
+        for (i = 0; i < send_size/2; i++) {
+            _smsbuf_set_octet(&smsbuf, outhex[i]);
+        }
+    } else {
+        kal_int32 i = 0;
+        for (i = 0; i < send_size; i += 2) {
+            kal_uint16 tmp = 0;
+            kal_uint8 *ptr = (kal_uint8 *)&tmp;
+
+            *ptr = *(start + i);
+            *(ptr + 1) = *(start + i + 1);
+            tmp = htons(tmp);
+            _smsbuf_set_octet(&smsbuf, *(ptr));
+            _smsbuf_set_octet(&smsbuf, *(ptr + 1));
+        }
+    }
+
+    /* Get the Hex String */
+    len = _smsbuf_hex_string(&smsbuf, output, out_len);
+    *sca_out_len = sca_len * 2;
+    RLOGD("start = [%p] size = [%d] encoded pdu = (%s), len = (%d)", start, send_size, output, len);
+
+    return len;
+}
+
+static kal_int32 _mdapi_sms_decode_pdu(mdapi_sms_record_t *sms,
+                            kal_int8 *smsc,
+                            kal_int8 *content,
+                            kal_int32 content_size,
+                            kal_int32 *record_size)
+{
+
+
+    kal_int32 ret = 0;
+
+    kal_int8 *ptr = content;
+    kal_int32 udh = 0;
+
+    /*
+    * Service Centre address informaction element
+    */
+     RLOGD("%s, %s, %d, ptr_len: %d, ptr: %s", __FILE__,__FUNCTION__, __LINE__, content_size, ptr);
+    ret = internal_mdapi_address_decode(ptr, smsc, 512, 1);
+    if (ret <= 0) {
+        RLOGW("can't get SMSC address");
+        return MDAPI_RET_ERROR;
+    }
+    ptr += ret;
+    RLOGD("SMSC = [%s]", smsc);
+
+    /* Protocol Data Unit Type(PDU Type) */
+    {
+        kal_int32 pdu_type = internal_mdapi_hex2int(ptr);
+        if ((pdu_type & 0x03) == SMS_DELIVER) {
+            sms->msg_type = MDAPI_SMS_NORMAL_MSG;
+        } else if ((pdu_type & 0x03) == SMS_STATUS_REPORT){
+            sms->msg_type = MDAPI_SMS_MSG_REPORT;
+        } else {
+            RLOGD("unkown PDU type = %02X(%02X), content = %s", pdu_type, pdu_type & 0x03, content);
+            return MDAPI_RET_ERROR;
+        }
+
+        if ((pdu_type & 0x40) == 0x40) {
+            udh = 1; /* find UDH header */
+        }
+
+        RLOGD("PDU Type = [%d]", pdu_type);
+    }
+    ptr += 2;
+
+    /* decode originator address(OA) destination address(DA)*/
+    ret =  internal_mdapi_address_decode(ptr, sms->phone_number, sizeof(sms->phone_number), 0);
+    if (ret <= 0) {
+        RLOGD("can't get sender address");
+        return MDAPI_RET_ERROR;
+    }
+    ptr += ret;
+    RLOGD("sender = [%s]", sms->phone_number);
+
+    /* protocol identifiler(PID) */
+    ptr += 2;
+
+    /* Data Coding Scheme (DCS) */
+    {
+        //kal_int32 text_compressed = 0;
+        kal_int32 dcs = 0;
+
+        dcs = internal_mdapi_hex2int(ptr);
+        if (dcs < 0) {
+            RLOGW("can't get the DCS");
+            return MDAPI_RET_ERROR;
+        }
+
+        if ( (dcs & 0xC0) == 0x00) {
+            /* General Data Coding indication */
+            if (dcs & 0x20) {
+                //text_compressed = 1;
+            }
+
+            if (dcs & 0x10) {
+                sms->sms_class = dcs & 0xF;
+            }
+
+            if (dcs & 0x04) {
+                sms->charset = MDAPI_SMS_CHARSET_GSM_8BIT;
+
+            } else if (dcs & 0x08) {
+                sms->charset = MDAPI_SMS_CHARSET_UCS2;
+            } else {
+                sms->charset = MDAPI_SMS_CHARSET_GSM_7BIT;
+            }
+        } else {
+            RLOGD("un-supported dcs type ");
+            return MDAPI_RET_ERROR;
+        }
+        ptr += 2;
+    }
+
+    /* Time */
+    {
+        kal_int32 i = 0;
+        kal_int8 tmp[4] = {0};
+        kal_uint8 time[7] = {0};
+
+        for (i = 0; i < 7; i++) {
+            tmp[0] = *(ptr + 1);
+            tmp[1] = *ptr;
+            tmp[2] = 0;
+            time[i] = strtoul(tmp, 0, 10);
+            ptr += 2;
+        }
+
+        if (time[0] < 80) {
+            time[0] += 100;
+        }
+
+        snprintf(sms->time, sizeof(sms->time), "%04u-%02u-%02u %02u:%02u:%02u",
+            time[0] + 1900, time[1], time[2], time[3], time[4], time[5]);
+
+        RLOGD("sms time = [%s]", sms->time);
+    }
+      {
+       kal_int32 i = 0;
+        kal_int32 udh_len = 0;
+        kal_int32 data_len = 0;
+        kal_int32 buf_len = 0;
+        kal_int32 octect = 0;
+
+        data_len = internal_mdapi_hex2int(ptr);
+        ptr += 2;
+
+        /* parse UDH header, to parse log SMS header */
+        if (udh) {
+            kal_int8 *ptr_udh = NULL;
+            udh_len = internal_mdapi_hex2int(ptr);
+            ptr += 2;
+            ptr_udh = ptr;
+            while (i < udh_len) {
+                kal_int32 iei = 0;
+                kal_int32 iei_len = 0;
+
+                iei = internal_mdapi_hex2int(ptr);
+                ptr += 2;
+                iei_len = internal_mdapi_hex2int(ptr);
+                ptr += 2;
+
+                if (iei != 0x00 && iei != 0x08) {
+                    ptr += (iei_len) * 2;
+                    i += 2 + iei_len;
+                    continue;
+                }
+
+                if (iei == 0x00) {
+                    sms->ref_num = internal_mdapi_hex2int(ptr);
+                    ptr += 2;
+                } else {
+                    sms->ref_num = ((internal_mdapi_hex2int(ptr) & 0xFF) << 8)
+                                | (internal_mdapi_hex2int(ptr + 2) & 0xFF);
+                    ptr += 4;
+                }
+
+                sms->total_pack = internal_mdapi_hex2int(ptr);
+                sms->curr_pack  = internal_mdapi_hex2int(ptr+2);
+                break;
+            }
+
+            ptr = ptr_udh + (udh_len) * 2;
+        }
+
+        RLOGD("sms->charset = [%d] \n", sms->charset);
+        switch (sms->charset) {
+            case MDAPI_SMS_CHARSET_GSM_7BIT:
+                octect = (data_len % 8 == 0) ? 1 : 0;
+                // decode 7bit
+                if (1 == udh) {
+                    kal_int32 padding_bits = ((udh_len + 1) * 8) % 7;
+                    if (padding_bits) {
+                        padding_bits = 7 - padding_bits;
+                    }
+                    data_len = internal_mdapi_sms_7bit_decode(ptr, sms->msg_content, content_size, padding_bits, octect);
+                } else {
+                    data_len = internal_mdapi_sms_7bit_decode(ptr, sms->msg_content, content_size, 0, octect);
+                }
+
+                *(sms->msg_content + data_len++) = '\0';
+                *(sms->msg_content + data_len++) = '\0';
+
+                *record_size = data_len;
+                break;
+
+            case MDAPI_SMS_CHARSET_GSM_8BIT:
+                sms->msg_content = ptr;
+                content_size = strlen(sms->msg_content);
+                #if 0
+                if( 1 == udh ) {
+                    data_len -= (udh_len + 1);
+                }
+                if (data_len >= *record_size - 2) {
+                    data_len = *record_size - 2;
+                }
+
+                sms->msg_content[0] = '\0';
+                for (i = 0 ; i < data_len ; i++) {
+                    kal_uint8 tmp[2] = {0, 0};
+
+                    tmp[0] = internal_mdapi_hex2int(ptr);
+                    ptr += 2;
+
+                    buf_len += kal_ext_ascii_to_utf8((UTF8 *)(sms->msg_content + buf_len), tmp, *record_size - buf_len);
+                    if (*record_size - buf_len < 0) {
+                        return MDAPI_RET_ERROR;
+                    }
+                }
+
+                *(sms->msg_content + buf_len++) = '\0';
+                *(sms->msg_content + buf_len++) = '\0';
+
+                *record_size = buf_len;
+
+                //KAL_RLOG(KAL_LOG_INFO, LOG_TAG, "is utf8 = [%d]", is_utf8_sequence((UTF8 *)sms->msg_content, (UTF8 *)sms->msg_content + data_len - 2));
+                #endif
+                break;
+
+            case MDAPI_SMS_CHARSET_UCS2:
+                buf_len = 0;
+
+                if( 1 == udh ) {
+                    data_len -= (udh_len + 1);
+                }
+
+                sms->msg_content[0] = '\0';
+
+                for (i=0 ; i < data_len ; i = i + 2) {
+                    UTF16 tmp[2] = {0, 0};
+                    kal_uint8 *tmp_ptr = (kal_uint8 *)tmp;
+
+                    tmp_ptr[0] = internal_mdapi_hex2int(ptr);
+                    ptr += 2;
+                    tmp_ptr[1] = internal_mdapi_hex2int(ptr);
+                    ptr += 2;
+                    tmp[0] = ntohs(tmp[0]);
+                    //KAL_RLOG(KAL_LOG_INFO, LOG_TAG, "tmp = [%04X]", tmp);
+
+                    buf_len += kal_utf16_to_utf8((UTF8 *)(sms->msg_content + buf_len), tmp, *record_size - buf_len);
+                    if (*record_size - buf_len < 0) {
+                        return MDAPI_RET_ERROR;
+                    }
+                }
+
+                *(sms->msg_content + buf_len++) = '\0';
+                *(sms->msg_content + buf_len++) = '\0';
+
+                *record_size = buf_len;
+
+
+                break;
+
+            default:
+                return MDAPI_RET_ERROR;
+        }
+    }
+
+    sms->position = MDAPI_SMS_POS_INBOX;
+    return MDAPI_RET_SUCCESS;
+}
+
+kal_int32 _mdapi_sms_get_msg_num(const char *msg, int charset, kal_int32 *msg_num, kal_int32 *msg_len)
+{
+    RLOGD("%s, %s, %d, send sms content = [%s]",__FILE__, __FUNCTION__, __LINE__, msg);
+    *msg_num = 0;
+    *msg_len = 0;
+    kal_int32 max_len = 0;
+
+    if (charset == MDAPI_SMS_CHARSET_GSM_7BIT) {
+        *msg_len = strlen(msg);
+
+        //special char
+        kal_int32 extenSize =0;
+        kal_char* point = (kal_char*)msg;
+        kal_int32 size = *msg_len;
+        while (*point && size) {
+            kal_uint8 c = lookup_latin1_to_gsm_ex_table((kal_int8)*point);
+            if(c != NULL)
+                extenSize++;
+            point++;
+            size--;
+        }
+        //special char
+        if (*msg_len + extenSize > 160) {
+            *msg_num = (*msg_len + extenSize + MAX_7BIT_MSG_LEN - 1) / MAX_7BIT_MSG_LEN;
+            max_len = MAX_7BIT_MSG_LEN;
+        } else {
+            *msg_num = 1;
+        }
+
+        if (*msg_num > MAX_CONCATENATED_MSG) {
+            RLOGW("message is too long. msg_len[%d], msg_num[%d]", *msg_len, *msg_num);
+            return MDAPI_RET_ERROR;
+        }
+    RLOGD("%s, %s, %d, 7bit msg_len = [%d] ,msg_num=[%d]", __FILE__, __FUNCTION__, __LINE__, *msg_len, *msg_num);
+    } else if (charset == MDAPI_SMS_CHARSET_UCS2) {
+        UTF16 *dest = NULL;
+        *msg_len = kal_utf8_to_utf16(NULL, (const UTF8 *)msg, 0);
+        if (*msg_len > 70) {
+            *msg_num = (*msg_len + MAX_UCS2_MSG_LEN - 1) / MAX_UCS2_MSG_LEN;
+            max_len = MAX_UCS2_MSG_LEN * 2;
+        } else {
+            *msg_num = 1;
+        }
+
+        if (*msg_num > MAX_CONCATENATED_MSG) {
+            RLOGW("message is too long. msg_len[%d], msg_num[%d]", msg_len, msg_num);
+            return MDAPI_RET_ERROR;
+        }
+    } else if (charset == MDAPI_SMS_CHARSET_GSM_8BIT) {
+        *msg_len = strlen(msg);
+        if(*msg_len > (140 * 2))
+        {
+            *msg_num = (*msg_len + MAX_8BIT_MSG_LEN - 1) / MAX_8BIT_MSG_LEN;
+            max_len = MAX_8BIT_MSG_LEN;
+
+            if (*msg_num > MAX_CONCATENATED_MSG) {
+                RLOGW("message is too long. msg_len[%d], msg_num[%d]", *msg_len, *msg_num);
+                return MDAPI_RET_ERROR;
+            }
+        }
+        else {
+            *msg_num = 1;
+        }
+    } else{
+        RLOGW("Not support charset");
+        return MDAPI_RET_ERROR;
+    }
+
+    return MDAPI_RET_SUCCESS;
+}
+
+int smsPduEncode(const char *smsc, const char *da_num, const char *msg, int charset,
+                        char *smsc_pdu, char **pdu)
+{
+    mdapi_sms_record_t record;
+    mdapi_sms_settings_t sms_settings;
+    kal_int32 status = MDAPI_RET_ERROR;
+    kal_int32 msg_num = 0;
+    kal_int32 msg_len = 0;
+    kal_int32 max_len = 0;
+    kal_char *msg_content = NULL;
+    kal_int32 out_len = 0;
+    kal_int8 output[MAX_PDU_SIZE] = {0};
+    kal_int32 sca_out_len;
+    mdapi_sms_record_t *sms = &record;
+
+    memset(sms, 0, sizeof(mdapi_sms_record_t));
+
+    snprintf(sms->phone_number, sizeof(sms->phone_number), "%s", da_num);
+    sms->msg_content = (kal_char *)msg;
+    sms->charset = charset;
+
+    sms_settings.rd  = 1;
+    sms_settings.vpf = SMS_VPF_RELATIVE;
+    sms_settings.srr = 1;
+    sms_settings.rp  = 0;
+    sms_settings.validity_period = 0;
+
+   // status = _mdapi_sms_get_msg_num(msg, charset, &msg_num, &msg_len);
+
+    /*if (sms->charset == MDAPI_SMS_CHARSET_GSM_7BIT) {
+        msg_content = sms->msg_content;
+    } else if (sms->charset == MDAPI_SMS_CHARSET_UCS2) {
+        UTF16 *dest = NULL;
+        msg_content = (kal_char *)malloc((msg_len + 1) * sizeof(UTF16));
+        dest = (UTF16 *)msg_content;
+        msg_len = kal_utf8_to_utf16(dest, (const UTF8 *)sms->msg_content, (msg_len + 1) * sizeof(UTF16));
+        if (msg_len <= 0) {
+            free(msg_content);
+            msg_content = NULL;
+            return MDAPI_RET_ERROR;
+        }
+        msg_len *= 2;
+        RLOGD("ucs2 msg_len = [%d] ,msg_num=[%d] ", msg_len,msg_num);
+    }else {
+        RLOGW("Not support charset");
+        return MDAPI_RET_ERROR;
+    }*/
+       if (sms->charset == MDAPI_SMS_CHARSET_GSM_7BIT) {
+            msg_len = strlen(sms->msg_content);
+
+            //for special char
+            kal_int32 extenTotalSize =0;
+            kal_int32 i = 0;
+            kal_char* point = sms->msg_content;
+        RLOGD("XXX msg len %d \n",msg_len);
+            kal_int32 size = msg_len;
+            while (*point && size) {
+                kal_uint8 c = lookup_latin1_to_gsm_ex_table((kal_int8)*point);
+                if(c != NULL){
+                    extenTotalSize++;
+                }
+                point++;
+                size--;
+            }
+            //for specail char
+        msg_len += extenTotalSize;
+        RLOGD("XXX msg_len %d extenTotalSize %d \n",msg_len,extenTotalSize);
+        if (msg_len > 160) {
+            msg_num = (msg_len + MAX_7BIT_MSG_LEN - 1) / MAX_7BIT_MSG_LEN;
+                max_len = MAX_7BIT_MSG_LEN;
+            } else {
+                msg_num = 1;
+            }
+
+            if (msg_num > MAX_CONCATENATED_MSG) {
+                RLOGW("message is too long. msg_len[%d], msg_num[%d]", msg_len, msg_num);
+                return MDAPI_RET_ERROR;
+            }
+        RLOGD("7bit msg_len = [%d] ,msg_num=[%d]", msg_len,msg_num);
+            msg_content = sms->msg_content;
+        } else if (sms->charset == MDAPI_SMS_CHARSET_UCS2) {
+            UTF16 *dest = NULL;
+            msg_len = kal_utf8_to_utf16(NULL, (const UTF8 *)sms->msg_content, 0);
+            if (msg_len > 70) {
+                msg_num = (msg_len + MAX_UCS2_MSG_LEN - 1) / MAX_UCS2_MSG_LEN;
+                max_len = MAX_UCS2_MSG_LEN * 2;
+            } else {
+                msg_num = 1;
+            }
+
+            if (msg_num > MAX_CONCATENATED_MSG) {
+                RLOGW("message is too long. msg_len[%d], msg_num[%d]", msg_len, msg_num);
+                return MDAPI_RET_ERROR;
+            }
+
+            msg_content = (kal_char *)malloc((msg_len + 1) * sizeof(UTF16));
+            dest = (UTF16 *)msg_content;
+            msg_len = kal_utf8_to_utf16(dest, (const UTF8 *)sms->msg_content, (msg_len + 1) * sizeof(UTF16));
+            if (msg_len <= 0) {
+                free(msg_content);
+                msg_content = NULL;
+                return MDAPI_RET_ERROR;
+            }
+            msg_len *= 2;
+                RLOGD("ucs2 msg_len = [%d] ,msg_num=[%d] ", msg_len,msg_num);
+            } else if (sms->charset == MDAPI_SMS_CHARSET_GSM_8BIT) {
+                msg_len = strlen(sms->msg_content);
+                msg_content = sms->msg_content;
+                if (msg_len > (140 * 2)) {
+                        msg_num = (msg_len + MAX_8BIT_MSG_LEN - 1) / MAX_8BIT_MSG_LEN;
+                        max_len = MAX_8BIT_MSG_LEN;
+                    } else {
+                        msg_num = 1;
+                    }
+
+                    if (msg_num > MAX_CONCATENATED_MSG) {
+                        RLOGW("message is too long. msg_len[%d], msg_num[%d]", msg_len, msg_num);
+                        return MDAPI_RET_ERROR;
+                    }
+                RLOGD("8bit msg_len = [%d] ,msg_num=[%d] ", msg_len,msg_num);
+            }else {
+                RLOGW("Not support charset");
+                return MDAPI_RET_ERROR;
+            }
+
+    // set sms record
+    _mdapi_sms_set_timestamp(sms);
+    if (msg_num == 1) {
+        out_len = _mdapi_sms_encode_pdu(sms, (kal_int8 *)smsc, &sms_settings, msg_content, msg_len, NULL, output, sizeof(output), &sca_out_len);
+        memcpy(smsc_pdu, output, sca_out_len);
+        //RLOGD("%s, %s, %d, returned encoded smsc_pdu:%s", __FILE__, __FUNCTION__, __LINE__, smsc_pdu);
+        //RLOGD("%s, %s, %d, output + sca_out_len:%s, out_len - sca_out_len: %d", __FILE__, __FUNCTION__, __LINE__, output + sca_out_len, out_len - sca_out_len);
+
+        //RLOGD("%s, %s, %d, pdu:%s sizeof(pdu[0])=%d", __FILE__, __FUNCTION__, __LINE__, pdu[0], sizeof(pdu[0]));
+
+        memset(pdu[0], 0, MAX_PDU_SIZE);
+        RLOGD("%s, %s, %d, pdu:%s", __FILE__, __FUNCTION__, __LINE__, pdu[0]);
+        strncpy(pdu[0], output + sca_out_len, out_len - sca_out_len);
+        RLOGD("%s, %s, %d, returned encoded pdu:%s\n, len=%d", __FILE__, __FUNCTION__, __LINE__, pdu[0], strlen(pdu[0]));
+    } else {
+         // send long sms
+        kal_int32 index = 0;
+        kal_int32 offset = 0;
+        static kal_uint8 concat_msgid;
+        concat_msgid += (rand() + 1) % 256;
+        RLOGD("start send one long msg, total has %d part msg", msg_num);
+        for (index = 0; index < msg_num; index++) {
+            kal_uint8 udh[] = {5, 0, 3, concat_msgid, msg_num, index + 1};
+            kal_uint32 size = 0;
+            kal_int8 *start = NULL;
+            size = msg_len > max_len ? max_len : msg_len;
+            msg_len -= size;
+            start  = msg_content + offset;
+            int exterSize = 0;
+            if (sms->charset == MDAPI_SMS_CHARSET_GSM_7BIT){
+                char* point = start;
+                int calsize = size;
+                while (*point && calsize) {
+                    kal_uint8 c = lookup_latin1_to_gsm_ex_table((kal_int8)*point);
+                    if(c != NULL){
+                        exterSize++;
+                        calsize--;
+                    }
+                    point++;
+                    calsize--;
+                }
+            }
+            offset = offset + size - exterSize;
+            //calculate offset
+            RLOGD(" msg_len %d size %d offset %d exterSize %d", msg_len,size ,offset,exterSize);
+            out_len = _mdapi_sms_encode_pdu(sms, (kal_int8 *)smsc, &sms_settings, start, size, udh, output, sizeof(output), &sca_out_len);
+            memcpy(smsc_pdu, output, sca_out_len);
+            memset(pdu[index], 0, MAX_PDU_SIZE);
+            memcpy(pdu[index], output + sca_out_len, out_len - sca_out_len);
+         }
+    }
+    if (sms->charset == MDAPI_SMS_CHARSET_UCS2) {
+        if(msg_content != NULL)
+            free(msg_content);
+    }
+    return MDAPI_RET_SUCCESS;
+}
+
+int smsPduDecode(const char *pdu_str, int pdu_len,
+                        char *da_num, char *smsc, char *msg, int *charset)
+{
+    kal_char msg_tmp[MAX_PDU_SIZE] = {0};
+    mdapi_sms_record_t record;
+    kal_int32 status = MDAPI_RET_ERROR;
+    kal_int32 out_len = 210;
+    RLOGD("%s, %s, %d, pdu_len: %d, pdu_str: %s", __FILE__,__FUNCTION__, __LINE__, pdu_len, pdu_str);
+
+    record.msg_content = msg_tmp;
+
+    status = _mdapi_sms_decode_pdu(&record, smsc, (kal_int8 *)pdu_str,
+                            pdu_len, &out_len);
+    if(status == MDAPI_RET_SUCCESS) {
+        memcpy(da_num, record.phone_number, strlen(record.phone_number));
+        memcpy(msg, record.msg_content, strlen(record.msg_content));
+        *charset = record.charset;
+    } else {
+        RLOGW("PDU decode error");
+    }
+
+    return status;
+}
+
+#define SMSCPDU_PREFIX_LEN 2
+int getNewSmsPduAndSmsc(const kal_int8 *pdu_str, int pdu_len, char *smsc_pdu, char *pdu)
+{
+    kal_int32 status = MDAPI_RET_ERROR;
+    kal_int32 smscpdulen;
+    const kal_int8 *ptr = pdu_str;
+    kal_int8 smslenstr[SMSCPDU_PREFIX_LEN];
+
+    memcpy(smslenstr, ptr, SMSCPDU_PREFIX_LEN);
+    smscpdulen = (atoi(smslenstr) * 2) + SMSCPDU_PREFIX_LEN;
+
+    memcpy(smsc_pdu, ptr, smscpdulen);
+    ptr += smscpdulen;
+    if(strlen(ptr) > MAX_PDU_SIZE)
+    {
+        RLOGD("%s, pdusize > 512 pdu_len:%d", __FUNCTION__, pdu_len);
+        return -1;
+    }
+    strcpy(pdu, ptr);
+
+    RLOGD("%s, %s, %d, pdu_len: %d, pdu_str: %s, smscpdulen = %d", __FILE__,__FUNCTION__, __LINE__,
+        pdu_len, pdu_str,smscpdulen);
+
+    return 0;
+}
+
+const unsigned short Crc16Table[256] = {
+    0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
+    0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
+    0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
+    0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
+    0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
+    0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
+    0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
+    0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
+    0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
+    0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
+    0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
+    0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
+    0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
+    0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
+    0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
+    0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
+    0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
+    0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
+    0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
+    0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
+    0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
+    0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
+    0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
+    0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
+    0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
+    0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
+    0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
+    0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
+    0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
+    0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
+    0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
+    0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
+};
+
+unsigned short CRC16(unsigned char * pcBlock, int len)
+{
+    unsigned short crc = 0xFFFF;
+    while(len--)
+    {
+        crc = (crc << 8) ^ Crc16Table[(crc >> 8) ^ *pcBlock++];
+    }
+    return crc;
+}
+
+const unsigned char CRC8Table[256] = {
+    0x00, 0x31, 0x62, 0x53, 0xC4, 0xF5, 0xA6, 0x97,
+    0xB9, 0x88, 0xDB, 0XEA, 0x7D, 0x4C, 0x1F, 0x2E,
+    0x43, 0x72, 0x21, 0x10, 0x87, 0xB6, 0xE5, 0xD4,
+    0XFA, 0xCB, 0x98, 0xA9, 0x3E, 0x0F, 0x5C, 0x6D,
+    0x86, 0xB7, 0xE4, 0xD5, 0x42, 0x73, 0x20, 0x11,
+    0x3F, 0x0E, 0x5D, 0x6C, 0xFB, 0xCA, 0x99, 0xA8,
+    0xC5, 0xF4, 0xA7, 0x96, 0x01, 0x30, 0x63, 0x52,
+    0x7C, 0x4D, 0x1E, 0x2F, 0xB8, 0x89, 0xDA, 0xEB,
+    0x3D, 0x0C, 0x5F, 0x6E, 0xF9, 0xC8, 0x9B, 0xAA,
+    0x84, 0xB5, 0xE6, 0xD7, 0x40, 0x71, 0x22, 0x13,
+    0x7E, 0x4F, 0x1C, 0x2D, 0xBA, 0x8B, 0xD8, 0xE9,
+    0xC7, 0xF6, 0xA5, 0x94, 0x03, 0x32, 0x61, 0x50,
+    0xBB, 0x8A, 0xD9, 0xE8, 0x7F, 0x4E, 0x1D, 0x2C,
+    0x02, 0x33, 0x60, 0x51, 0xC6, 0xF7, 0xA4, 0x95,
+    0xF8, 0xC9, 0x9A, 0xAB, 0x3C, 0x0D, 0x5E, 0x6F,
+    0x41, 0x70, 0x23, 0x12, 0x85, 0xB4, 0xE7, 0xD6,
+    0x7A, 0x4B, 0x18, 0x29, 0xBE, 0x8F, 0xDC, 0xED,
+    0xC3, 0xF2, 0xA1, 0x90, 0x07, 0x36, 0x65, 0x54,
+    0x39, 0x08, 0x5B, 0x6A, 0xFD, 0xCC, 0x9F, 0XAE,
+    0x80, 0xB1, 0xE2, 0xD3, 0x44, 0x75, 0x26, 0x17,
+    0xFC, 0xCD, 0x9E, 0xAF, 0x38, 0x09, 0x5A, 0x6B,
+    0x45, 0x74, 0x27, 0x16, 0x81, 0xB0, 0xE3, 0xD2,
+    0xBF, 0x8E, 0xDD, 0xEC, 0x7B, 0x4A, 0x19, 0x28,
+    0x06, 0x37, 0x64, 0x55, 0xC2, 0xF3, 0xA0, 0x91,
+    0x47, 0x76, 0x25, 0x14, 0x83, 0xB2, 0xE1, 0xD0,
+    0xFE, 0xCF, 0x9C, 0xAD, 0x3A, 0x0B, 0x58, 0x69,
+    0x04, 0x35, 0x66, 0x57, 0xC0, 0xF1, 0xA2, 0x93,
+    0xBD, 0x8C, 0xDF, 0xEE, 0x79, 0x48, 0x1B, 0x2A,
+    0xC1, 0xF0, 0xA3, 0x92, 0x05, 0x34, 0x67, 0x56,
+    0x78, 0x49, 0x1A, 0x2B, 0xBC, 0x8D, 0xDE, 0xEF,
+    0x82, 0xB3, 0xE0, 0xD1, 0x46, 0x77, 0x24, 0x15,
+    0x3B, 0x0A, 0x59, 0x68, 0xFF, 0xCE, 0x9D, 0xAC
+};
+
+unsigned char CRC8(unsigned char * lpBlock, int len)
+{
+    unsigned char crc = 0xFF;
+    while(len--)
+    {
+        crc = CRC8Table[crc ^ *lpBlock++];
+    }
+    return crc;
+}
+
+int showtransferHeadInfo(gost_transfer_head_t record)
+{
+    RLOGD("record.prv:0x%x", record.prv);
+    RLOGD("record.skid:0x%x", record.skid);
+    RLOGD("record.seting:0x%x", record.seting);
+    RLOGD("record.hl:0x%x", record.hl);
+    RLOGD("record.he:0x%x", record.he);
+    RLOGD("record.fdl:0x%x", record.fdl);
+    RLOGD("record.pid:0x%x", record.pid);
+    RLOGD("record.pt:0x%x", record.pt);
+    RLOGD("record.hcs:0x%x", record.hcs);
+    RLOGD("record.sfrcs:0x%x", record.sfrcs);
+
+    RLOGD("record.pra:%s", record.pra);
+    RLOGD("record.rca:%s", record.rca);
+    RLOGD("record.ttl:0x%x", record.ttl);
+
+    return 0;
+}
+
+int hexChar_To_Int(char c)
+{
+    if (c >= '0' && c <= '9')
+        return (c - '0');
+    if (c >= 'A' && c <= 'F')
+        return (c - 'A' + 10);
+    if (c >= 'a' && c <= 'f')
+        return (c - 'a' + 10);
+
+    return 0;
+}
+
+void hexString_To_Bytes(char *in, int inLength, char *out)
+{
+    int i;
+
+    if (in == NULL || out == NULL)
+    {
+        return;
+    }
+
+    for (i = 0 ; i < inLength ; i += 2)
+    {
+        out[i/2] = (char)((hexChar_To_Int(in[i]) << 4)
+                           | hexChar_To_Int(in[i+1]));
+    }
+}
+
+/*
+1byte: 0xxxxxxx
+2byte: 110xxxxx 10xxxxxx
+3byte: 1110xxxx 10xxxxxx 10xxxxxx
+4byte: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+5byte: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
+6byte: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
+*/
+int ascii_to_utf8_encode(char *asciiBuf, char *utf8Buf, int len)
+{
+    int transbeforlen = 1;
+    int translastlen = 1;
+    char *pcurrBuf = asciiBuf;
+    char utf8len[6] = {0x00, 0xB0, 0xE0, 0xF0, 0xF8, 0xFB};
+    int i;
+    char currEncBuf[6] = {0};
+    int movebit = 0;
+    char output[12];
+    int j = 0;
+
+    while(*pcurrBuf != '\0')
+    {
+        i = 5;
+        if(*pcurrBuf < 0x80)
+        {
+            transbeforlen = 1;
+            sprintf(output, "%02X", *pcurrBuf);
+            strcat(utf8Buf, output);
+            pcurrBuf++;
+            continue;
+        }
+
+        while(i--)
+        {
+            if(*pcurrBuf > utf8len[i])
+            {
+                //printf("i:%d\n", i);
+                transbeforlen = i + 1;
+                break;
+            }
+        }
+        printf("transbeforlen======%d\n", transbeforlen);
+
+        for(i = 0; i < transbeforlen; i++)
+        {
+            currEncBuf[i] = *pcurrBuf;
+            pcurrBuf++;
+        }
+
+        for(i = transbeforlen -1; i > 1; i--)
+        {
+            movebit = 2*(transbeforlen-1-i);
+            if(movebit == 6)
+            {
+                movebit = 2*(transbeforlen-1-i-3);
+                continue;
+            }
+            currEncBuf[i] = (currEncBuf[i] & (0x3F >> movebit)) | (currEncBuf[i - 1] << (6 - movebit));
+            currEncBuf[i-1] = (currEncBuf[i-1] & 0x3F) >> (2 + movebit);
+        }
+
+        currEncBuf[1] = currEncBuf[1] & (0x3F >> (transbeforlen - 2)) | currEncBuf[0] << (8 - (0x1 << (transbeforlen -1)%4));
+        currEncBuf[0] = (currEncBuf[0] & (0xFF >> (transbeforlen + 1))) >> (0x1 << (transbeforlen -1)%4);
+
+        translastlen = transbeforlen - transbeforlen / 3;
+        //printf("translastlen=====%d\n", translastlen);
+
+        if(translastlen > 2)
+        {
+            i = 1;
+        }
+        j = 0;
+        memset(&output, 0, sizeof(output));
+        for(i = translastlen/3; i <= translastlen; i++)
+        {
+            //printf("0x%x\n", currEncBuf[i]);
+            sprintf(output+(j*2), "%02X", currEncBuf[i]);
+            j++;
+        }
+        strcat(utf8Buf, output);
+        //printf("======%s\n", output);
+    }
+    //printf("\nutf8Buf:%s\n", utf8Buf);
+}
+
+#define GOST_EGTS_PC_OK 0
+#define GOST_EGTS_PC_TEST_FAILED 164
+int gostResponseTypeSfrdEncode(char *sdata, gost_transfer_head_t stransferHead, int parseStatus)
+{
+    kal_int8 rpid[2];
+    kal_int8 pr;
+    char outData[512] = {0};
+    int sdatalen = strlen(sdata);
+
+    rpid[0] = (stransferHead.pid >> 8) & 0x00ff;
+    rpid[1] = (stransferHead.pid) & 0x00ff;
+    if(parseStatus == 0)
+    {
+        pr = GOST_EGTS_PC_OK;
+    }
+    else
+    {
+        pr = GOST_EGTS_PC_TEST_FAILED;
+    }
+    sprintf(outData, "%02x%02x%02x", rpid[1], rpid[0], pr);
+    strncat(outData, sdata, sdatalen);
+    memset(sdata, 0, sizeof(sdata));
+    memcpy(sdata, outData, sizeof(outData));
+    RLOGD("%s:%s\n", __FUNCTION__, sdata);
+    return 0;
+}
+
+int gostTransferLayerEncode(kal_int8 *output, kal_int32 rte, char *sdata, kal_int32 pt, kal_int32 out_len)
+{
+    smsbuf_t smsbuf;
+    gost_transfer_head_t record;
+    gost_transfer_setting_t settype;
+    int len = 0;
+
+    memset(&settype, 0, sizeof(settype));
+    memset(&smsbuf, 0, sizeof(smsbuf));
+    _smsbuf_init(&smsbuf);
+
+    record.prv = 0x01;
+    record.skid = 0x00;
+    settype.pr = 0;
+    settype.cmp = 0;
+    settype.ena = 0;
+    settype.rte = rte;
+    settype.prf = 0;
+    record.seting = settype.prf << 6 | settype.rte << 5 |
+                       settype.ena << 3 | settype.cmp << 2 | settype.pr;
+    record.hl = 0x0B;
+    record.he = 0;
+    record.fdl = strlen(sdata) / 2;
+    record.pid = 0;
+    record.pt = pt;
+    if(settype.rte != 0)
+    {
+        record.hl = 0x0B + 0x05;
+        record.pra[0] = 0x11;
+        record.pra[1] = 0xe5;
+        record.rca[0] = 0x11;
+        record.rca[1] = 0xe5;
+        record.ttl = 54;
+    }
+    record.hcs = 0;
+
+    char crcout[512] = {0};
+    int crcoutlen = record.fdl;
+    hexString_To_Bytes(sdata, record.fdl * 2, crcout);
+    record.sfrcs = CRC16((unsigned char*)crcout, crcoutlen);
+
+    _smsbuf_set_octet(&smsbuf, record.prv);
+    _smsbuf_set_octet(&smsbuf, record.skid);
+    _smsbuf_set_octet(&smsbuf, record.seting);
+    _smsbuf_set_octet(&smsbuf, record.hl);
+    _smsbuf_set_octet(&smsbuf, record.he);
+
+    int fdlh = (record.fdl >> 8)& 0x00ff;
+    int fdll = record.fdl & 0x00ff;
+    int pidh = (record.pid >> 8)& 0x00ff;
+    int pidl = record.pid & 0x00ff;
+    _smsbuf_set_octet(&smsbuf, fdll);
+    _smsbuf_set_octet(&smsbuf, fdlh);
+    _smsbuf_set_octet(&smsbuf, pidl);
+    _smsbuf_set_octet(&smsbuf, pidh);
+    _smsbuf_set_octet(&smsbuf, record.pt);
+    if(settype.rte != 0)
+    {
+        _smsbuf_set_octet(&smsbuf, record.pra[1]);
+        _smsbuf_set_octet(&smsbuf, record.pra[0]);
+        _smsbuf_set_octet(&smsbuf, record.rca[1]);
+        _smsbuf_set_octet(&smsbuf, record.rca[0]);
+        _smsbuf_set_octet(&smsbuf, record.ttl);
+    }
+    //no contain hcs
+    len = _smsbuf_hex_string(&smsbuf, output, out_len);
+
+    memset(crcout, 0, sizeof(crcout));
+    crcoutlen = len / 2;
+    hexString_To_Bytes(output, len, crcout);
+    record.hcs = CRC8((unsigned char*)crcout, crcoutlen);
+
+    _smsbuf_set_octet(&smsbuf, record.hcs);
+
+    len = _smsbuf_hex_string(&smsbuf, output, out_len);
+    //printf("1----%s,len:%d,%d\n", output, len, record.fdl * 2);
+    strncat(output, sdata, record.fdl * 2);
+    kal_int8 sfrcs[2];
+    sfrcs[0] = record.sfrcs >> 8 & 0x00ff;  //high bit
+    sfrcs[1] = record.sfrcs & 0x00ff;   //low bit
+    sprintf(sfrcs,"%02x%02x", sfrcs[1], sfrcs[0]);
+    strncat(output, sfrcs, 4);
+    RLOGD("%s:%s\n", __FUNCTION__, output);
+
+    return 0;
+}
+
+int gostTransferLayerDecode(kal_int8 *tmsg, kal_char *servData, kal_int32 *server_len, gost_transfer_head_t *transHead)
+{
+    RLOGD("%s, %s, %d, tmsg: %s", __FILE__,__FUNCTION__, __LINE__, tmsg);
+    gost_transfer_head_t record;
+    gost_transfer_setting_t settype;
+    kal_int32 ret = 0;
+    kal_char *ptr = tmsg;
+    int servBuffLen;
+
+    if(tmsg == NULL)
+    {
+        RLOGD("%s, tmsg is null", __FUNCTION__);
+        return -1;
+    }
+
+    memset(&record, 0, sizeof(record));
+    record.prv = internal_mdapi_hex2int(ptr);
+    ptr += 2;
+    record.skid = internal_mdapi_hex2int(ptr);
+    ptr += 2;
+    record.seting = internal_mdapi_hex2int(ptr);
+    ptr += 2;
+
+    settype.pr = record.seting & 0x03;
+    settype.cmp = (record.seting >> 2) & 0x01;
+    settype.ena = (record.seting >> 3) & 0x03;
+    settype.rte = (record.seting >> 5) & 0x01;
+    settype.prf = (record.seting >> 6) & 0x03;
+    if (settype.ena != 0)
+    {
+        RLOGD("error:this data is encryption, not support");
+    }
+
+    if (settype.cmp != 0)
+    {
+        RLOGD("error:this data is compression, not support");
+    }
+
+    record.hl = internal_mdapi_hex2int(ptr);
+    ptr += 2;
+    record.he = internal_mdapi_hex2int(ptr);
+    ptr += 2;
+
+    int fdlh, fdll;
+    int pidh, pidl;
+
+    fdll = internal_mdapi_hex2int(ptr);
+    ptr += 2;
+    fdlh = internal_mdapi_hex2int(ptr);
+    ptr += 2;
+    record.fdl = (fdlh << 8) | fdll;
+    servBuffLen = record.fdl * 2;
+
+    pidl = internal_mdapi_hex2int(ptr);
+    ptr += 2;
+    pidh = internal_mdapi_hex2int(ptr);
+    ptr += 2;
+    record.pid = (pidh << 8) | pidl;
+
+    record.pt = internal_mdapi_hex2int(ptr);
+    ptr += 2;
+
+    if(record.pt == EGTS_PT_RESPONSE)
+    {
+        RLOGD("record.pt:0x%x", record.pt);
+    }
+    else if (record.pt == EGTS_PT_APPDATA)
+    {
+        RLOGD("record.pt:0x%x", record.pt);
+    }
+    else
+    {
+
+    }
+
+    if(settype.rte != 0)
+    {
+        record.pra[1] = internal_mdapi_hex2int(ptr);
+        ptr += 2;
+        record.pra[0] = internal_mdapi_hex2int(ptr);
+        ptr += 2;
+        record.rca[1] = internal_mdapi_hex2int(ptr);
+        ptr += 2;
+        record.rca[0] = internal_mdapi_hex2int(ptr);
+        ptr += 2;
+
+        record.ttl = internal_mdapi_hex2int(ptr);
+        ptr += 2;
+    }
+
+    record.hcs = internal_mdapi_hex2int(ptr);
+
+    char crcout[512] = {0};
+    int incrclen = (record.hl - 1) * 2;
+    int crcoutlen = incrclen / 2;
+    hexString_To_Bytes(tmsg, incrclen, crcout);
+    int crc8hcs = CRC8((unsigned char*)crcout, crcoutlen);
+    if(crc8hcs != record.hcs)
+    {
+        RLOGD("ERR, hcs err,hcs(0x%x),crc8hcs(0x%x)", record.hcs, crc8hcs);
+        ret = -1;
+    }
+    ptr += 2;
+
+    *server_len = record.fdl;
+    memcpy(transHead, &record, sizeof(record));
+    memcpy(servData, ptr, servBuffLen);
+    ptr += servBuffLen;
+
+    int sfrcsh, sfrcsl;
+    sfrcsh = internal_mdapi_hex2int(ptr);
+    ptr += 2;
+    sfrcsl = internal_mdapi_hex2int(ptr);
+    ptr += 2;
+    record.sfrcs = (sfrcsl << 8) | sfrcsh;
+
+    memset(crcout, 0, sizeof(crcout));
+    crcoutlen = servBuffLen / 2;
+    hexString_To_Bytes(servData, servBuffLen, crcout);
+    int crc16sfrcs = CRC16((unsigned char*)crcout, crcoutlen);
+    if(crc16sfrcs != record.sfrcs)
+    {
+        RLOGD("ERR, sfrcs err,sfrcs(0x%x),crc16sfrcs(0x%x)", record.sfrcs, crc16sfrcs);
+        ret = -1;
+    }
+
+    RLOGD("servData:%s,len=%d,ret=%d\n", servData, *server_len, ret);
+    showtransferHeadInfo(record);
+    return ret;
+}
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/gsm/sms_pdu.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/gsm/sms_pdu.h
new file mode 100644
index 0000000..bf69736
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/gsm/sms_pdu.h
@@ -0,0 +1,470 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#ifndef YOCTO_SMS_PDU_H
+#define YOCTO_SMS_PDU_H
+
+/*
+ * Unix/Linux
+ */
+typedef char kal_int8;
+
+typedef unsigned char kal_uint8;
+
+typedef short kal_int16;
+
+typedef unsigned short kal_uint16;
+
+typedef int kal_int32;
+
+typedef unsigned int kal_uint32;
+
+/**/
+typedef long long kal_int64;
+
+/**/
+typedef unsigned long long kal_uint64;
+
+typedef char kal_char;
+
+/* portable wide character for unicode character set */
+typedef unsigned short          kal_wchar;
+
+typedef kal_uint32 kal_time_t;
+
+
+typedef unsigned long   UTF32;
+
+typedef unsigned short  UTF16;
+
+typedef unsigned short  UCS2;
+
+typedef unsigned char   UTF8;
+
+#define REPLACEMENT_CHAR    (UTF32)0x0000FFFD
+#define MAX_UNI_BMP         (UTF32)0x0000FFFF
+#define MAX_UNI_UCS2        MAX_UNI_BMP
+#define MAX_UTF16           (UTF32)0x0010FFFF
+#define MAX_UTF32           (UTF32)0x7FFFFFFF
+#define MAX_LEGAL_UTF32     (UTF32)0x0010FFFF
+
+#define STATUS_SUCCESS          0
+#define STATUS_MEM_EXHAUSTED    (-0xC0000)
+#define STATUS_ILLEGAL_UTF8     (-0xC0001)
+#define STATUS_ILLEGAL_UTF16    (-0xC0002)
+#define STATUS_ILLEGAL_UTF32    (-0xC0003)
+#define STATUS_ILLEGAL_UCS2     (-0xC0004)
+#define STATUS_NULL_POINTER     (-0x00001)
+
+#define MDAPI_TIME_STR_SIZE         22
+#define MDAPI_PHONE_NUMBER_SIZE     32
+#define MDAPI_MAX_PDU_SIZE          512
+#define MAX_CONCATENATED_MSG 32
+
+#define MAX_OUT_SIZE 512
+#define MAX_PDU_SIZE 512
+
+// TODO: why ??
+#define MAX_7BIT_MSG_LEN    153
+#define MAX_UCS2_MSG_LEN    67
+#define MAX_8BIT_MSG_LEN    268 //134*2
+
+#define SMS_DELIVER         0x00
+#define SMS_DELIVER_REPORT  0x00
+#define SMS_SUBMIT          0x01
+#define SMS_SUBMIT_REPORT   0x01
+#define SMS_STATUS_REPORT   0x02
+#define SMS_STATUS_COMMAND  0x02
+
+#define TRUE    1
+#define FALSE   0
+
+#define SUR_HIGH_START  (UTF32)0xD800
+#define SUR_HIGH_END    (UTF32)0xDBFF
+#define SUR_LOW_START   (UTF32)0xDC00
+#define SUR_LOW_END     (UTF32)0xDFFF
+
+enum SMS_VPF_E
+{
+    SMS_VPF_NO_PRESENT  = 0x00,
+    SMS_VPF_RESORVED    = 0x01,
+    SMS_VPF_RELATIVE    = 0x02,
+    SMS_VPF_ABSOLUTE    = 0x03,
+    SMS_VPF_INVALID     = 0xFF,
+};
+
+
+enum SMS_ADDR_NUM_PLAN
+{
+    SMS_NP_UNKOWN       = 0x00,
+    SMS_NP_ISDNTEL      = 0x01,
+    SMS_NP_DATA         = 0x03,
+    SMS_NP_TELIX        = 0x04,
+    SMS_NP_NATIONAL     = 0x08,
+    SMS_NP_PRIVATE      = 0x09,
+    SMS_NP_RESERVED     = 0xFF,
+};
+
+enum SMS_ADDR_TYPE
+{
+    SMS_TON_UNKNOWN         = 0,
+    SMS_TON_INTERNATIONAL   = 1,
+    SMS_TON_NATIONAL        = 2,
+    SMS_TON_NETWORKSPECIFIC = 3,
+    SMS_TON_SUBSCRIBER      = 4,
+    SMS_TON_ALPHANUMERIC    = 5,
+    SMS_TON_ABBREVIATED     = 6,
+    SMS_TON_RESERVED        = 7
+};
+
+enum SMS_ADDR_ENCODE_TYPE
+{
+    SMS_ENCODE_SCA      = 0,
+    SMS_ENCODE_OADA     = 1,
+    SMS_ENCODE_INVALID  = 0xFF,
+};
+
+enum MDAPI_RET_e {
+    MDAPI_RET_SUCCESS       = 0,
+    MDAPI_RET_ERROR         = 1,
+    MDAPI_RET_TIMEOUT       = 2,
+    MDAPI_RET_NOT_SUPPORT   = 3,
+};
+
+enum MDAPI_SMS_CHARSET_E
+{
+    MDAPI_SMS_CHARSET_GSM_7BIT  = 0x00000000,
+    MDAPI_SMS_CHARSET_GSM_8BIT  = 0x00000001,
+    MDAPI_SMS_CHARSET_UCS2      = 0x00000002,
+    MDAPI_SMS_CHARSET_INVALID,
+};
+
+enum MDAPI_SMS_POSITION_E
+{
+    MDAPI_SMS_POS_INBOX     = 0x00000001,
+    MDAPI_SMS_POS_SENTBOX   = 0x00000002,
+    MDAPI_SMS_POS_DRAFBOX   = 0x00000003,
+    MDAPI_SMS_POS_OUTBOX    = 0x00000004,
+    MDAPI_SMS_POS_INVALID,
+};
+
+/* */
+enum  MDAPI_SMS_MSGTYPE_E
+{
+    MDAPI_SMS_NORMAL_MSG    = 0x00000000,
+    MDAPI_SMS_MSG_REPORT    = 0x00000001,
+    MDAPI_SMS_MMS_ALERT     = 0x00000002,
+    MDAPI_SMS_VOICE_MAIL    = 0x00000003,
+    MDAPI_SMS_MSGTYPE_INVALID,
+};
+
+typedef struct _mdapi_sms_setting {
+    kal_int8 rd;    /* reject duplicate */
+    kal_int8 vpf;   /* validity peroid format */
+    kal_int8 srr;   /* status report request */
+    kal_int8 rp;    /* replay path */
+    kal_int32 validity_period;   /* validity peroid */
+} mdapi_sms_settings_t;
+
+typedef struct _mdapi_sms_record {
+    kal_int32 msg_id;
+    kal_int32 is_read;
+    kal_int32 position;
+    kal_int32 result;
+    kal_int32 msg_type;
+    kal_int32 sms_class;
+    kal_int32 total_pack;
+    kal_int32 curr_pack;
+    kal_int32 ref_num;
+    kal_int32 msg_location;
+    kal_int16 charset;
+    kal_char  time[MDAPI_TIME_STR_SIZE];            /*YYYY-MM-DD HH:MM:SS*/
+    kal_char  phone_number[MDAPI_PHONE_NUMBER_SIZE];
+    kal_char  *msg_content;
+} mdapi_sms_record_t;
+
+typedef struct _smsbuf {
+    kal_uint8 *curbyte;
+    kal_uint8 *finalbyte;
+    kal_uint8 *septet_start;
+    kal_uint8 curbit;
+    kal_uint8 smsbuf[512];
+} smsbuf_t;
+
+typedef struct _gost_transfer_head {
+    kal_int32 prv;				/*protocol version*/
+    kal_int32 skid;				/*security key id*/
+    kal_int32 seting;			/*type set*/
+    kal_int32 hl;				/*header length*/
+    kal_int32 he;				/*header encoding*/
+    kal_int32 fdl;				/*frame data length*/
+    kal_int32 pid;				/*packet identifier*/
+    kal_int32 pt;				/*packet type*/
+    kal_int32 pra[2];				/*peer address*/
+    kal_int32 rca[2];				/*recipient address*/
+    kal_int32 ttl;				/*time to live*/
+    kal_int32 hcs;				/*header check sum*/
+    kal_int32  sfrcs;			/*services frame data check sum*/
+} gost_transfer_head_t;
+
+typedef struct {
+    gost_transfer_head_t transHead;
+    char *servData;
+} gost_msd_save_t;
+
+typedef struct _gost_transfer_setting {
+    kal_int8 pr;    /* reject duplicate, 0-top,1-high,2-medium,3-low*/
+    kal_int8 cmp;   /* validity peroid format, must be 0*/
+    kal_int8 ena;   /* status report request, must be 0*/
+    kal_int8 rte;   /* replay path, if set 1 PRA,RCA,TTL exsit*/
+    kal_int8 prf;   /* validity peroid, must be 0*/
+} gost_transfer_setting_t;
+
+enum GOST_TRANSFER_PACKET_TYPE{
+	EGTS_PT_RESPONSE = 0,
+	EGTS_PT_APPDATA,
+	EGTS_PT_SIGNED_APPDATA
+};
+
+static const kal_int32 UTF16_HALF_SHIFT  = 10; /* used for shifting by 10 bits */
+
+static const UTF32 UTF16_HALF_BASE = 0x0010000UL;
+static const UTF32 UTF16_HALF_MASK = 0x3FFUL;
+
+static const unsigned char utf8_tailing_bytes[256] = {
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+    3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
+};
+
+static const UTF32 utf8_offsets[6] = {
+    0x00000000UL,
+    0x00003080UL,
+    0x000E2080UL,
+    0x03C82080UL,
+    0xFA082080UL,
+    0x80282080UL
+};
+
+static const UTF8 first_byte_mark[7] = {
+    0x00,
+    0x00,
+    0xC0,
+    0xE0,
+    0xF0,
+    0xF8,
+    0xFC
+};
+
+//ISO 8859 Latin-1 / GSM 7 bit undefined char
+#define NOP  ('_')
+
+static kal_uint8 gsm_to_latin1_table[] =
+{
+  //0x00 '@',  -,  '$',  -,   -,   -,   -,   -,
+    '@', 163, '$', 165, 232, 233, 249, 236,
+  //0x08  -,   -,  LF,   -,   -,   CR,  -,   -,
+    242, 199,  10, 216, 248,  13, 197, 229,
+  //0x10  -,  '_',  -,   -,   -,   -,   -,   -,
+    NOP, '_', NOP, NOP, NOP, NOP, NOP, NOP,
+  //0x18  -,   -,   -,   -,   -,   -,   -,   -,
+    NOP, NOP, NOP, NOP, 198, 230, 223, 201,
+  //0x20 ' ', '!', '"', '#', '?,  '%', '&', ''',
+    ' ', '!', '"', '#', 164, '%', '&', '\'',
+  //0x28 '(', ')', '*', '+', ',', '-', '.', '/',
+    '(', ')', '*', '+', ',', '-', '.', '/',
+  //0x30 '0', '1', '2', '3', '4', '5', '6', '7',
+    '0', '1', '2', '3', '4', '5', '6', '7',
+  //0x38 '8', '9', ':', ';', '<', '=', '>', '?',
+    '8', '9', ':', ';', '<', '=', '>', '?',
+  //0x40  -,  'A', 'B', 'C', 'D', 'E', 'F', 'G',
+    161, 'A', 'B', 'C', 'D', 'E', 'F', 'G',
+  //0x48 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
+    'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
+  //0x50 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
+    'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
+  //0x58 'X', 'Y', 'Z',  -,   -,   -,   -,   -,
+    'X', 'Y', 'Z', 196, 214, 209, 220, 167,
+  //0x60  -,  'a', 'b', 'c', 'd', 'e', 'f', 'g',
+    191, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
+  //0x68 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+    'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+  //0x70 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
+    'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
+  //0x78 'x', 'y', 'z',  -,   -,   -,   -,   -,
+    'x', 'y', 'z', 228, 246, 241, 252, 224
+};
+
+static kal_uint8 latin1_to_gsm_table[] =
+{
+  //0x00  -,   -,   -,  -,   -,   -,   -,   -,
+    NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP,
+  //0x08  -,   -,   LF,  -,   -,   CR,  -,   -,
+    NOP, NOP,  10, NOP, NOP,  13, NOP, NOP,
+  //0x10  -,   -,   -,   -,   -,   -,   -,   -,
+    NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP,
+  //0x18  -,   -,   -,   -,   -,   -,   -,   -,
+    NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP,
+  //0x20 ' ', '!', '"', '#',  -,  '%', '&', ''',
+    ' ', '!', '"', '#', 0x2, '%', '&', '\'',
+  //0x28 '(', ')', '*', '+', ',', '-', '.', '/',
+    '(', ')', '*', '+', ',', '-', '.', '/',
+  //0x30 '0', '1', '2', '3', '4', '5', '6', '7',
+    '0', '1', '2', '3', '4', '5', '6', '7',
+  //0x38 '8', '9', ':', ';', '<', '=', '>', '?',
+    '8', '9', ':', ';', '<', '=', '>', '?',
+  //0x40  -,  'A', 'B', 'C', 'D', 'E', 'F', 'G',
+    0x0, 'A', 'B', 'C', 'D', 'E', 'F', 'G',
+  //0x48 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
+    'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
+  //0x50 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
+    'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
+  //0x58 'X', 'Y', 'Z',  -,   -,   -,   -,   -,
+    'X', 'Y', 'Z', NOP, NOP, NOP, NOP,0x11,
+  //0x60  -,  'a', 'b', 'c', 'd', 'e', 'f', 'g',
+    NOP, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
+  //0x68 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+    'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+  //0x70 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
+    'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
+  //0x78 'x', 'y', 'z',  -,   -,   -,   -,   -,
+    'x', 'y', 'z', NOP, NOP, NOP, NOP, NOP,
+  //0x80  -,   -,   -,   -,   -,   -,   -,   -,
+    NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP,
+  //0x88  -,   -,   -,   -,   -,   -,   -,   -,
+    NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP,
+  //0x90  -,   -,   -,   -,   -,   -,   -,   -,
+    NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP,
+  //0x98  -,   -,   -,   -,   -,   -,   -,   -,
+    NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP,
+  //0xA0  -,   -,   -,   -,   -,   -,   -,   -,
+    NOP, 0x40,NOP, 0x1, 0x24,0x3, NOP,0x5F,
+  //0xA8  -,   -,   -,   -,   -,   -,   -,   -,
+    NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP,
+  //0xB0  -,   -,   -,   -,   -,   -,   -,   -,
+    NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP,
+  //0xB8  -,   -,   -,   -,   -,   -,   -,   -,
+    NOP, NOP, NOP, NOP, NOP, NOP, NOP,0x60,
+  //0xC0 'A', 'A', 'A', 'A',  -,   -,   -,   -,
+    'A', 'A', 'A', 'A', 0x5B,0xE, 0x1C,0x9,
+  //0xC8 'E',  -,  'E', 'E', 'I', 'I', 'I', 'I',
+    'E',0x1F, 'E', 'E', 'I', 'I', 'I', 'I',
+  //0xD0  -,  -,   'O', 'O', 'O', 'O',  -,   -,
+    NOP,0x5D, 'O', 'O', 'O', 'O',0x5C, NOP,
+  //0xD8  -,  'U', 'U', 'U',  -,   -,  'Y',  -,
+    0x0B,'U', 'U', 'U',0x5E, 'Y', NOP,0x1E,
+  //0xE0  -,  'a', 'a', 'a',  -,   -,   -,   -,
+    0x7F,'a', 'a', 'a',0x7B, 0xF,0x1D, 0x9,
+  //0xE8  -,   -,  'e', 'e',  -,  'i', 'i', 'i',
+    0x4, 0x5, 'e', 'e', 0x7, 'i', 'i', 'i',
+  //0xF0  -,   -,   -,  'o', 'o', 'o',  -,   -,
+    NOP,0x7D, 0x8, 'o', 'o', 'o',0x7C, NOP,
+  //0xF8  -,   -,  'u', 'u',  -,  'y',  -,  'y',
+    0xC, 0x6, 'u', 'u',0x7E, 'y', NOP, 'y'
+};
+typedef struct latin1_to_gsm_extable {
+    kal_int8 symbol;
+    kal_uint8 value;
+} Latin1_to_Gsm_ExTable;
+static Latin1_to_Gsm_ExTable latin1_to_gsm_tableEx[]=
+{
+    {'^', 0x14,},
+    {'{', 0x28,},
+    {'}', 0x29,},
+    {'\\',0x2f,},
+    {'[', 0x3C,},
+    {'~', 0x3d,},
+    {']', 0x3e,},
+    {'|', 0x40,},
+    {NULL,NULL,},
+};
+
+/* boolean representation */
+typedef enum
+{
+    /* FALSE value */
+    KAL_FALSE,
+    /* TRUE value */
+    KAL_TRUE
+} kal_bool;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+kal_int32 kal_utf8_to_utf16(UTF16 *dest, const UTF8 *src, kal_int32 size);
+
+kal_int32 kal_utf8_to_utf32(UTF32 *dest, const UTF8 *src, kal_int32 size);
+
+kal_int32 kal_utf8_to_ucs2(UCS2 *dest, const UTF8 *src, kal_int32 size);
+
+kal_int32 kal_utf16_to_utf8(UTF8 *dest, const UTF16 *src, kal_int32 size);
+
+kal_int32 kal_utf32_to_utf8(UTF8 *dest, const UTF32 *src, kal_int32 size);
+
+kal_int32 kal_ucs2_to_utf8(UTF8 *dest, const UCS2 *src, kal_int32 size);
+
+kal_int32 kal_ext_ascii_to_utf8(UTF8 *dest, const kal_uint8 *src, kal_int32 size);
+
+kal_int32 is_utf8_sequence(const UTF8 *start, const UTF8 *end);
+
+int smsPduEncode(const char *smsc, const char *da_num, const char *msg, int charset,
+                        char *smsc_pdu, char **pdu);
+
+int smsPduDecode(const char *pdu_str, kal_int32 pdu_len,
+                        char *da_num, char *smsc, char *msg, int *charset);
+kal_int32 _mdapi_sms_get_msg_num(const char *msg, int charset, kal_int32 *msg_num, kal_int32 *msg_len);
+int getNewSmsPduAndSmsc(const kal_int8 *pdu_str, int pdu_len, char *smsc, char *msg);
+int gostTransferLayerDecode(kal_int8 *tmsg, kal_char *servData, kal_int32 *server_len, gost_transfer_head_t *transHead);
+int gostResponseTypeSfrdEncode(char *sdata, gost_transfer_head_t stransferHead, int parseStatus);
+int gostTransferLayerEncode(kal_int8 *output, kal_int32 rte, char *sdata, kal_int32 pt, kal_int32 out_len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/lynq_sms.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/lynq_sms.cpp
new file mode 100644
index 0000000..5ff7de4
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/lynq_sms.cpp
@@ -0,0 +1,849 @@
+/*============================================================================= 
+#     FileName: lynq_sms.cpp
+#         Desc: about sms api
+#         Author: MoblieTek 
+#         Version:
+#   LastChange: 2021-01-06  
+#      History: 
+ 
+=============================================================================*/
+#include <dlfcn.h>
+#include <string.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <cutils/jstring.h>
+#include <cutils/properties.h>
+#include "lynq_sms.h"
+#include "lynq_common.h"
+#include <liblog/lynq_deflog.h>
+#define KERNAL 19
+#define SMS_INDEX_VALUE "persist.sms.memory.index"
+#define SMS_INDEX_FLAG_VALUE "persist.sms.memory.flag"
+#undef LOG_TAG
+#define LOG_TAG "LYNQ_SMS"
+
+int lynq_send_sms(const char *telephonyNumber, const int charset,const char *msg, const char *smsc,smsResponse* smsResp)
+{
+    int lenth = MIN_MSM_PARAM_NUM;
+    char *argv[MAX_LEN];
+    int32_t token=0;
+    RIL_Errno err=-1;
+    lynqQueue *node =NULL;
+    int num = 0;
+    int res = 0;
+    char requestStr[MAX_QUEST_LEN] = {0};
+    sprintf(requestStr, "%d", charset);
+    argv[0] = "RIL_REQUEST_SEND_SMS";
+    argv[1] = telephonyNumber;
+    argv[2] = requestStr;
+    argv[3] = msg;
+    argv[4] = smsc;
+    if(smsc ==NULL)
+    {
+        token = android::getRequestData(argv,4);
+        //RLOGD("token is %d",token);
+        LYDBGLOG("[%s][%d][%s]token:%d\n",__FUNCTION__, __LINE__,__FILE__,token);
+    }
+    else
+    {
+        token = android::getRequestData(argv,5);
+        //RLOGD("token is %d",token);
+        LYDBGLOG("[%s][%d][%s]token:%d\n",__FUNCTION__, __LINE__,__FILE__,token);
+    }
+    smsResp->base.request = RIL_REQUEST_SEND_SMS;
+    smsResp->base.token=token;
+    smsResp->smsResp.messageRef = 0;
+    smsResp->smsResp.errorCode = 0;
+    if(token<0)
+    {
+        smsResp->base.e=err;
+        return -1;
+    }
+    node = commonFindParcelmsg(token, 500, err);
+    smsResp->base.e=err;
+    if (node !=NULL)
+    {
+        node->parcel.readInt32(&num);
+        if(num ==0)
+        {
+            LYDBGLOG("[%s][%d][%s]the call back message is null!\n",__FUNCTION__, __LINE__,__FILE__);
+            if(err==RIL_E_SUCCESS)
+            {
+                smsResp->base.e=-1;
+            }
+            lynqDeQueue(token);
+            return token;
+        }
+        node->parcel.readInt32(&smsResp->smsResp.messageRef);
+        smsResp->smsResp.ackPDU= lynqStrdupReadString(node->parcel);
+        node->parcel.readInt32(&smsResp->smsResp.errorCode);
+    }
+    lynqDeQueue(token);
+    return token;
+}
+int lynq_Ims_send_sms(const char *telephonyNumber, const int charset,const char *msg, const char* retryNum,const char *messageRef, const char *smsc,smsResponse *smsResp)
+{
+    int lenth = MIN_IMS_MSM_PARAM_NUM;
+    char *argv[MAX_LEN];
+    char requestStr[MAX_QUEST_LEN] = {0};
+    int32_t token=0 ;
+    RIL_Errno err=-1;
+    lynqQueue *node =NULL;
+    int num = 0;
+    int res = 0;
+    sprintf(requestStr, "%d", charset);
+    argv[0] = "RIL_REQUEST_IMS_SEND_SMS";
+    argv[1] = telephonyNumber;
+    argv[2] = requestStr;
+    argv[3] = msg;
+    argv[4] = retryNum;
+    argv[5] = messageRef;
+    argv[6] = smsc;
+    if(smsc==NULL)
+    {
+        token = android::getRequestData(argv, 5);
+        //RLOGD("token is %d",token);
+        LYDBGLOG("%s,%d,%s,token:%d\n",__FUNCTION__, __LINE__,__FILE__,token);
+    }
+    else
+    {
+        token = android::getRequestData(argv, 6);
+        //RLOGD("token is %d",token);
+        LYDBGLOG("%s,%d,%s,token:%d\n",__FUNCTION__, __LINE__,__FILE__,token);
+    }
+    smsResp->base.request = RIL_REQUEST_SEND_SMS;
+    smsResp->base.token=token;
+    smsResp->smsResp.messageRef = 0;
+    smsResp->smsResp.errorCode = 0;
+    if(token<0)
+    {
+        smsResp->base.e=err;
+        return -1;
+    }
+    node = commonFindParcelmsg(token, 500, err);
+    smsResp->base.e=err;
+    if (node !=NULL)
+    {
+        node->parcel.readInt32(&num);
+        if(num ==0)
+        {
+            //RLOGD("[%s]the call back message is null!",__FUNCTION__);
+            LYDBGLOG("[%s][%d][%s]the call back message is null!\n",__FUNCTION__, __LINE__,__FILE__);
+            if(err==RIL_E_SUCCESS)
+            {
+                smsResp->base.e=-1;
+            }
+            lynqDeQueue(token);
+            return token;
+        }
+        node->parcel.readInt32(&smsResp->smsResp.messageRef);
+        smsResp->smsResp.ackPDU= lynqStrdupReadString(node->parcel);
+        node->parcel.readInt32(&smsResp->smsResp.errorCode);
+    }
+    lynqDeQueue(token);
+    return token;
+}
+int lynq_write_sms_to_sim(const int smsStatus,const char *recPhonNum,const int charset,const char *msg,const char *smsc,messageStoreInfo *msgstroeInfo)
+{
+    char *argv[MAX_LEN];
+    char smsStatusStr[MAX_QUEST_LEN] = {0};
+    char charsetStr[MAX_QUEST_LEN] = {0};
+    int32_t token=0 ;
+    RIL_Errno err=-1;
+    lynqQueue *node =NULL;
+    int num = 0;
+    int res = 0;
+    sprintf(smsStatusStr, "%d", smsStatus);
+    sprintf(charsetStr, "%d", charset);
+    argv[0] = "RIL_REQUEST_WRITE_SMS_TO_SIM";
+    argv[1] = smsStatusStr;
+    argv[2] = recPhonNum;
+    argv[3] = charsetStr;
+    argv[4] = msg;
+    argv[5] = smsc;
+    if(smsc==NULL)
+    {
+        token = android::getRequestData(argv, 5);
+        //RLOGD("token is %d",token);
+        LYDBGLOG("%s,%d,%s,token:%d\n",__FUNCTION__, __LINE__,__FILE__,token);
+    }
+    else
+    {
+        token = android::getRequestData(argv, 6);
+        //RLOGD("token is %d",token);
+        LYDBGLOG("%s,%d,%s,token:%d\n",__FUNCTION__, __LINE__,__FILE__,token);
+    }
+    msgstroeInfo->base.request = RIL_REQUEST_WRITE_SMS_TO_SIM;
+    msgstroeInfo->base.token=token;
+    msgstroeInfo->msgStoreIndex = 0;
+    if(token<0)
+    {
+        msgstroeInfo->base.e=err;
+        return -1;
+    }
+    node = commonFindParcelmsg(token, 500, err);
+    printf("function = %s, err = %d\n", __FUNCTION__, (int)err);
+    msgstroeInfo->base.e=err;
+    if(node == NULL){
+        printf("node == NULL\n");
+    }
+    if (node !=NULL)
+    {
+        node->parcel.readInt32(&num);
+        if(num ==0)
+        {
+            //RLOGD("[%s]the call back message is null!",__FUNCTION__);
+            LYDBGLOG("[%s][%d][%s]the call back message is null!\n",__FUNCTION__, __LINE__,__FILE__);
+            if(err==RIL_E_SUCCESS)
+            {
+                msgstroeInfo->base.e=-1;
+            }
+            lynqDeQueue(token);
+            return token;
+        }
+        node->parcel.readInt32(&msgstroeInfo->msgStoreIndex);
+    }
+    lynqDeQueue(token);
+    return token;
+}
+
+/**
+RIL_REQUEST_REPORT_SMS_MEMORY_STATUS
+index is Unavailable or Available
+*/
+int lynq_report_sms_memory_status(const int status,lynqBase *base)
+{   
+    int32_t token=0 ;
+    RIL_Errno err=-1;
+    lynqQueue *node =NULL;
+    int state = 0;
+    int res = 0;
+    if(status == 0 || status == 1){
+        
+        const char requestStr[MAX_LEN] = {"RIL_REQUEST_REPORT_SMS_MEMORY_STATUS"};
+        token = lynqIntParame(requestStr,status);
+        base->request = RIL_REQUEST_REPORT_SMS_MEMORY_STATUS;
+        base->token=token;
+        if(token<0)
+        {
+            base->e=err;
+            return -1;
+        }
+        node = commonFindParcelmsg(token, 500, err);
+        base->e=err;
+        if (node !=NULL)
+        {
+            node->parcel.readInt32(&state);
+            if(state ==0)
+            {
+                //RLOGD("[%s]the call back message is null!",__FUNCTION__);
+                LYDBGLOG("[%s][%d][%s]the call back message is null!\n",__FUNCTION__, __LINE__,__FILE__);
+                if(err==RIL_E_SUCCESS)
+                {
+                    base->e=-1;
+                }
+                lynqDeQueue(token);
+                return token;
+            }
+        }
+        lynqDeQueue(token);
+        return token;
+    }
+    else{
+        LYDBGLOG("input status value error");
+        base->e = err;
+        return -1;
+    }
+    
+}
+
+/**
+RIL_REQUEST_REPORT_SMS_MEMORY_STATUS
+index is lynqWriteSMSToSim get index
+*/
+int lynq_delet_sms_on_sim(const int index,lynqBase *base)
+{
+    int32_t token=0 ;
+    RIL_Errno err=-1;
+    lynqQueue *node =NULL;
+    int status = 0;
+    int res = 0;
+    const char requestStr[MAX_LEN] = {"RIL_REQUEST_DELETE_SMS_ON_SIM"};
+    token = lynqIntParame(requestStr,index);
+    base->request = RIL_REQUEST_DELETE_SMS_ON_SIM;
+    base->token=token;
+    if(token<0)
+    {
+        base->e=err;
+        return -1;
+    }
+    node = commonFindParcelmsg(token, 500, err);
+    base->e=err;
+    if (node !=NULL)
+    {
+        node->parcel.readInt32(&status);
+        if(status ==0)
+        {
+            //RLOGD("[%s]the call back message is null!",__FUNCTION__);
+            LYDBGLOG("[%s][%d][%s]the call back message is null!\n",__FUNCTION__, __LINE__,__FILE__);
+            if(err==RIL_E_SUCCESS)
+            {
+                base->e=-1;
+            }
+            lynqDeQueue(token);
+            return token;
+        }
+    }
+    lynqDeQueue(token);
+    return token;
+}
+
+int lynq_get_smsc_address(smscCbInfo *smscInfo)
+{
+    int32_t token=0 ;
+    RIL_Errno err=-1;
+    lynqQueue *node =NULL;
+    int num = 0;
+    int res = 0;
+    const char requestStr[MAX_LEN] = {"RIL_REQUEST_GET_SMSC_ADDRESS"};
+    token = lynqNoneParame(requestStr);
+    smscInfo->base.request = RIL_REQUEST_GET_SMSC_ADDRESS;
+    smscInfo->base.token = token;
+    smscInfo->smsc = NULL;
+    if(token<0)
+    {
+        smscInfo->base.e=err;
+        return -1;
+    }
+    node = commonFindParcelmsg(token, 500, err);
+    smscInfo->base.e=err;
+    if (node !=NULL)
+    {
+        node->parcel.readInt32(&num);
+        if(num ==0)
+        {
+            //RLOGD("[%s]the call back message is null!",__FUNCTION__);
+            LYDBGLOG("[%s][%d][%s]the call back message is null!\n",__FUNCTION__, __LINE__,__FILE__);
+            if(err==RIL_E_SUCCESS)
+            {
+                smscInfo->base.e=-1;
+            }
+            lynqDeQueue(token);
+            return token;
+        }
+        smscInfo->smsc =lynqStrdupReadString(node->parcel);
+    }
+    lynqDeQueue(token);
+    return token;
+}
+
+int lynq_set_smsc_address(const char* serviceNumber,lynqBase *base)
+{
+    int32_t token=0 ;
+    RIL_Errno err=-1;
+    lynqQueue *node =NULL;
+    int status = 0;
+    int res = 0;
+    const char requestStr[MAX_LEN] = {"RIL_REQUEST_SET_SMSC_ADDRESS"};
+    token = lynqStringParame(requestStr,serviceNumber);
+    base->request = RIL_REQUEST_SET_SMSC_ADDRESS;
+    base->token=token;
+    if(token<0)
+    {
+        base->e=err;
+        return -1;
+    }
+    node = commonFindParcelmsg(token, 500, err);
+    base->e=err;
+    if (node !=NULL)
+    {
+        node->parcel.readInt32(&status);
+        if(status ==0)
+        {
+            //RLOGD("[%s]the call back message is null!",__FUNCTION__);
+            LYDBGLOG("[%s][%d][%s]the call back message is null!\n",__FUNCTION__, __LINE__,__FILE__);
+            if(err==RIL_E_SUCCESS)
+            {
+                base->e=-1;
+            }
+            lynqDeQueue(token);
+            return token;
+        }
+    }
+    lynqDeQueue(token);
+    return token;
+}
+/*
+void lynq_recive_new_sms_cb(RIL_SOCKET_ID soc_id,char * num, char * smsc, char * msg, int charset)
+{
+    printf("[SIM%d]num is %s,smsc is %s,msg is %s,charset is %d\n",soc_id,num,smsc,msg,charset);
+}*/
+/*Convert the decimal number into hexadecimal and write it into the buffer
+int decToHex(int aa,char *buffer)
+{
+    itoa(aa, buffer, 16);
+    return 0;
+
+}
+*/
+/*Convert the index into string and write it into the buf*/
+int hexToDec(char* s)
+{
+    int t = 0;         //t记录临时加的数 
+    int sum = 0;
+    for (int i = 0;s[i];i++)
+    {
+        if (s[i] >= '0' && s[i] <= '9')
+            t = s[i] - '0';       //当字符是0~9时保持原数不变
+        if (s[i] >= 'a' && s[i] <= 'z')
+            t = s[i] - 'a' + 10;
+        if (s[i] >= 'A' && s[i] <= 'Z')
+            t = s[i] - 'A' + 10;
+        sum = sum * 16 + t;
+    }
+    //printf("SUM:%d\n", sum);
+    return sum;
+}
+
+int indexToString(int index,char buf[])
+{
+    int smslen = 0;
+    if (index > 0 && index < 10)
+    {
+        snprintf(buf, sizeof(buf), "00%d", index);
+    }
+    else if (index >= 10 && index < 100)
+    {
+        snprintf(buf, sizeof(buf), "0%d", index);
+    }
+    else if (index == 100)
+    {
+        snprintf(buf, sizeof(buf), "%d", index);
+    }
+    else if (index <= 0 ||index > 100)
+    {
+        snprintf(buf, sizeof(buf), "%d", 110);
+    }
+    buf[3] = '\0';
+    return 0;
+}
+/*组装短消息头,并且和短消息实体拼接。
+**储存短消息的头信息格式如下
+**头部的格式:index|status|soc_id|teleNumLen|smslen|
+**index 表示存储索引,占3位
+**status 表示短消息的阅读状态,占1位
+**smslen 表示短消息实体长度,是16进制数0x0000,占6位
+**soc_id 表示卡槽编号,占1位
+**teleNumLen 表示电话号码的长度,占2位。
+**
+*/
+int assembleMsgInfo(FILE* fp,int property,int status,int smslen,RIL_SOCKET_ID soc_id,char * num,char element[],char *sms)
+{
+    char indexString[10] = { 0 };
+    char numBuf[50]={0};
+    char smsBuffer[MSG_MAX_LEN] = { 0 };
+    indexToString(property,indexString);
+    snprintf(element, KERNAL+1, "|%s|%d|0x%04x|%d|%02d|", indexString, status, smslen,soc_id,strlen(num));
+    element[KERNAL] = '\0';//必须加结束符‘\0’.
+    snprintf(numBuf, strlen(num)+1, "%s", num);//加1是因为需要把结束符‘\0’也保存进来。
+    snprintf(smsBuffer, strlen(sms)+1, "%s", sms);
+    strncat(element, numBuf, strlen(num));
+    strncat(element, smsBuffer, smslen);
+    //printf("head %s\n", element);
+    LYDBGLOG("[%s][%d][%s]element sms%s!\n",__FUNCTION__, __LINE__,__FILE__,element);
+    return 0;
+}
+
+int parseHeader(const char *message,int number,storeMessageInfo *SMI[])
+{
+    const char* temp = message;
+    const char* nextP = NULL;
+    char docker[100] = { 0 };
+    char smsbuffer[MSG_MAX_LEN] = {0};
+    char indexbuf[10] = { 0 };
+    char smslenbuf[10] = { 0 };
+    char socIdBuf[10] ={0};
+    char numLenBuf[10] = {0};
+    char numBuf[50] = {0};
+    int count = 0;
+    if (temp == NULL)
+    {
+        LYERRLOG("[%s][%d][%s]input message is null !!\n",__FUNCTION__, __LINE__,__FILE__);
+        return LYNQ_E_NULL_ANONALY;
+    }
+    while (1)
+    {
+        if (*temp == '\0')
+        {
+            break;
+        }
+        nextP = temp + 1;
+        for (int i = 0;i < KERNAL; i++)
+        {
+            docker[i] = *temp;
+            temp++;
+        }
+        if (docker[0] == '|' && docker[4] == '|' && docker[6] == '|' && docker[13] == '|')
+        {
+            for (int i = 0;i < 3;i++)
+            {
+                strncat(indexbuf, &docker[i+1], 1);
+            }
+            indexbuf[3] = '\0';
+            for (int i = 0; i < 4; i++)
+            {
+                strncat(smslenbuf, &docker[i + 9], 1);
+            }
+            smslenbuf[4] = '\0';
+            for(int i=0;i<2;i++)
+            {
+                strncat(numLenBuf,&docker[i+16],1);
+            }
+            SMI[count]->index = atoi(indexbuf);
+            SMI[count]->status = atoi(&docker[5]);
+            SMI[count]->soc_id=atoi(&docker[14]);
+            SMI[count]->numLen = atoi(numLenBuf);
+            SMI[count]->smslen = hexToDec(smslenbuf);
+            int i=0;
+            for(i=0;i<SMI[count]->numLen;i++)
+            {
+                numBuf[i]=*temp;
+                temp++;
+            }
+            numBuf[i + 1]='\0';
+            for (i = 0;i < SMI[count]->smslen;i++)
+            {
+                smsbuffer[i] = *temp;
+                temp++;
+            }
+            smsbuffer[i + 1] = '\0';
+            memcpy(SMI[count]->message, smsbuffer, SMI[count]->smslen + 1);
+            memcpy(SMI[count]->teleNum, numBuf, SMI[count]->numLen + 1);
+            LYDBGLOG("[%s][%d][%s]index:%d,status:%d,smslen:%d,message:%s,soc_id:%d,numberlen:%d,number:%s!!\n",__FUNCTION__,
+            __LINE__,__FILE__,SMI[count]->index,SMI[count]->status,SMI[count]->smslen,SMI[count]->message,
+            SMI[count]->soc_id,SMI[count]->numLen,SMI[count]->numLen);
+            memset(smslenbuf, 0, strlen(smslenbuf));
+            memset(indexbuf, 0, strlen(indexbuf));
+            memset(docker, 0, strlen(docker));
+            memset(smsbuffer, 0, strlen(smsbuffer));
+            memset(socIdBuf,0,strlen(socIdBuf));
+            memset(numLenBuf,0,strlen(numLenBuf));
+            memset(numBuf,0,strlen(numBuf));
+            count += 1;
+        }
+        else
+        {
+            temp = nextP;
+        }
+    }
+    if (count != number||count ==0)
+    {
+        return -1;
+    }
+    return 0;
+}
+storeMessageInfo **getAllMessage(int &smsNum,int index)
+{
+    int result = 0;
+    int property = 0;
+    int flag =0;
+    int len = 0;
+    char indexBuf[10]={ 0 };
+    char flagBuf[10]={0};
+    char buff[MSG_MAX_LEN*100] = { 0 };
+    char element[MSG_MAX_LEN] = { 0 };
+    storeMessageInfo** SMI = NULL;
+    property_get(SMS_INDEX_VALUE,indexBuf,NULL);
+    property_get(SMS_INDEX_FLAG_VALUE,flagBuf,NULL);
+    property = atoi(indexBuf);
+    //printf("property:%d\n",property);
+    flag = atoi(flagBuf);
+    //printf("flag:%d\n",flag);
+    if((property==0)&&(flag==1))
+    {
+        property =100;
+    }
+    if((property==0)&&(flag==0))
+    {
+        LYERRLOG("[%s][%d][%s]not have SMS was store in memory!!\n",__FUNCTION__, __LINE__,__FILE__);
+        return NULL;
+    }
+    if(property<index)
+    {
+        LYERRLOG("[%s][%d][%s]Out of bounds!!\n",__FUNCTION__, __LINE__,__FILE__);
+        return NULL;
+    }
+    FILE* fp = NULL;
+    fp = fopen("/usr/bin/demoscript/SMS_API/custerm_message.txt", "r");
+    if (fp == 0)
+    {
+        LYERRLOG("[%s][%d][%s]Can't open log file!!\n",__FUNCTION__, __LINE__,__FILE__);
+        return NULL;
+    }
+    fseek(fp, 0, SEEK_END);    //将文件指针指向文件的结尾;
+    len = ftell(fp);           //获取当前文件指针在文件内的位置,单位为byte       ,len为文件的长度。
+    fseek(fp, 0, SEEK_SET);
+    fread(buff, len + 1, 1, fp);
+    if ((SMI = (storeMessageInfo**)malloc(sizeof(storeMessageInfo*) * property)) == NULL)
+    {
+        LYERRLOG("[%s][%d][%s]Core dump,malloc fail!!\n",__FUNCTION__, __LINE__,__FILE__);
+        return NULL;
+    }
+    for (int i = 0;i < property;i++)
+    {
+        if (!(SMI[i] = (storeMessageInfo*)malloc(sizeof(storeMessageInfo))))
+        {
+            LYERRLOG("[%s][%d][%s]Core dump,malloc fail!!\n",__FUNCTION__, __LINE__,__FILE__);
+            for (int n = 0;n < i;n++)
+            {
+                free(SMI[n]);
+            }
+            free(SMI);
+            return NULL;
+        }
+        memset(SMI[i], 0, sizeof(storeMessageInfo));
+    }
+    result = parseHeader(buff, property, SMI);
+    fclose(fp);
+    smsNum=property;
+    return SMI;
+}
+int lynq_store_sms_to_memory(RIL_SOCKET_ID soc_id,const int status,char * num,const char* sms,lynqBase *base)
+{
+    int index = 0;
+    int indexflag = 0;
+    int indexlen =0;
+    int headlen = 0;
+    int smslen = 0;
+    int smsNum = 0;
+    FILE* fp = NULL;
+    char smsBuffer[MSG_MAX_LEN] = {0};
+    char enCode[MSG_MAX_LEN] = {0};
+    char buffer[MSG_MAX_LEN*100]={0};
+    char indexBuf[50] = { 0 };
+    char indexflagBuf[50]={0};
+    char teleNumBuf[70]={0};
+    storeMessageInfo ** SMI =NULL;
+    if (sms == NULL)
+    {
+        LYERRLOG("[%s][%d][%s] Message is null!!\n",__FUNCTION__, __LINE__,__FILE__);
+        base->e = LYNQ_E_NULL_ANONALY;
+        return -1;
+    }
+    fp=fopen("/usr/bin/demoscript/SMS_API/custerm_message.txt", "a+");
+    if (fp == 0)
+    {
+        LYERRLOG("[%s][%d][%s] Can't open log file!!\n",__FUNCTION__, __LINE__,__FILE__);
+        return 0;
+    }
+    indexlen = property_get(SMS_INDEX_VALUE,indexBuf,"0");
+    index = atoi(indexBuf);
+    indexlen = property_get(SMS_INDEX_FLAG_VALUE,indexflagBuf,"0");
+    indexflag = atoi(indexflagBuf);
+    smslen = strlen(sms);
+    if(indexflag==1)
+    {
+        SMI = getAllMessage(smsNum, -1);
+        if(SMI==NULL)
+        {
+            base->e= LYNQ_E_NULL_ANONALY;
+            return -1;
+        }
+        for (int i = 0;i < smsNum;i++)
+        {
+            if(index ==0)
+            {
+                index = 1;
+            }
+            if (SMI[i]->index == index)
+            {
+                 memset(indexBuf,0,strlen(indexBuf));
+                 indexToString(index+1, indexBuf);
+                 property_set(SMS_INDEX_VALUE,indexBuf);
+                 assembleMsgInfo(fp,index,status,smslen,soc_id,num,enCode,sms);
+                 strncat(buffer, enCode, strlen(enCode));
+                 memset(enCode,0, strlen(enCode));
+            }
+            else
+            {
+                assembleMsgInfo(fp,SMI[i]->index, SMI[i]->status, SMI[i]->smslen,SMI[i]->soc_id,SMI[i]->teleNum, enCode, SMI[i]->message);
+                strncat(buffer, enCode, strlen(enCode));
+                memset(enCode,0, strlen(enCode));
+            }
+        }
+        fwrite(buffer, strlen(buffer), 1, fp);//将msg对应的字符串append到文件末尾
+        fclose(fp);
+        for(int i=0;i<smsNum;i++)
+        {
+            free(SMI[i]);
+        }
+        free(SMI);
+        base->e= RIL_E_SUCCESS;
+        return 0;
+    }
+    else
+    {
+        index = index+1;
+        if(index==100)
+        {
+            property_set(SMS_INDEX_VALUE,"0");
+            property_set(SMS_INDEX_FLAG_VALUE,"1");
+            assembleMsgInfo(fp,index,status,smslen,soc_id,num,enCode,sms);
+        }
+        else
+        {
+            memset(indexBuf,0,strlen(indexBuf));
+            indexToString(index, indexBuf);
+            property_set(SMS_INDEX_VALUE,indexBuf);
+            assembleMsgInfo(fp,index,status,smslen,soc_id,num,enCode,sms);
+        }
+        fseek(fp, 0, SEEK_END);//定位到文件末尾
+        fwrite(enCode, strlen(enCode), 1, fp);//将msg对应的字符串append到文件末尾
+        fclose(fp);
+        base->e= RIL_E_SUCCESS;
+        return 0;
+    }
+    return -1;
+}
+int lynq_get_sms_from_memory(const int index, storeMessageInfo* sms,lynqBase *base)
+{
+    int smsNum = 0;
+    storeMessageInfo **SMI=NULL;
+    SMI = getAllMessage(smsNum,index);
+    if(SMI==NULL)
+    {
+        base->e= LYNQ_E_NULL_ANONALY;
+        return -1;
+    }
+    /*
+    printf("test sms--001\n");
+    printf("smsNUM%d, index %d\n",smsNum,index-1);
+    sms->index= SMI[index-1]->index;
+    printf("test sms--002\n");
+    sms->numLen= SMI[index-1]->numLen;
+    printf("test sms--003\n");
+    sms->smslen = SMI[index-1]->smslen;
+    printf("test sms--004\n");
+    sms->soc_id= (RIL_SOCKET_ID)SMI[index-1]->soc_id;
+    printf("test sms--005\n");
+    sms->status=SMI[index-1]->status;
+    printf("test sms--006\n");
+    memcpy(sms->message,SMI[index-1]->message,strlen(SMI[index-1]->message)+1);
+    printf("test sms--007\n");
+    memcpy(sms->teleNum,SMI[index-1]->teleNum,strlen(SMI[index-1]->teleNum)+1);
+    printf("test sms--008\n");
+    */
+    for(int i=0;i<smsNum;i++)
+    {
+        if(SMI[i]->index==index)
+        {
+            sms->index= SMI[i]->index;
+            sms->numLen= SMI[i]->numLen;
+            sms->smslen = SMI[i]->smslen;
+            sms->soc_id= SMI[i]->soc_id;
+            sms->status=SMI[i]->status;
+            memcpy(sms->message,SMI[i]->message,strlen(SMI[i]->message)+1);
+            memcpy(sms->teleNum,SMI[i]->teleNum,strlen(SMI[i]->teleNum)+1);
+            for(int i=0;i<smsNum;i++)
+            {
+                free(SMI[i]);
+            }
+            free(SMI);
+            base->e= RIL_E_SUCCESS;
+            return 0;
+        }
+    }
+    for(int i=0;i<smsNum;i++)
+    {
+        free(SMI[i]);
+    }
+    free(SMI);
+    base->e= RIL_E_SUCCESS;
+    return 0;
+}
+// The value range of index is -1, 1-100.
+//-1 means to delete all.
+int lynq_delete_message_from_memory(const int index,lynqBase *base)
+{
+    char buff[MSG_MAX_LEN*100] = { 0 };
+    char element[MSG_MAX_LEN] = {0};
+    char indexBuf[10]={ 0 };
+    char flagBuf[10]={0};
+    int smsNum = 0;
+    int property_Count =0;
+    int property_Flag = 0;
+    int removeflag = 0;
+    FILE *fpW=NULL;
+    storeMessageInfo **SMI=NULL;
+    if(index==(-1))
+    {
+        fpW = fopen("/usr/bin/demoscript/SMS_API/custerm_message.txt", "w+");
+        if (fpW == 0)
+        {
+            LYERRLOG("[%s][%d][%s] Can't open log file!!\n",__FUNCTION__, __LINE__,__FILE__);
+            return -1;
+        }
+        fwrite(buff, strlen(buff), 1, fpW);
+        fclose(fpW);
+        property_set(SMS_INDEX_VALUE,"0");
+        property_set(SMS_INDEX_FLAG_VALUE,"0");
+        base->e= RIL_E_SUCCESS;
+        return 0;
+    }
+    property_get(SMS_INDEX_VALUE,indexBuf,NULL);
+    property_get(SMS_INDEX_FLAG_VALUE,flagBuf,NULL);
+    property_Count = atoi(indexBuf);
+    memset(indexBuf,0,strlen(indexBuf));
+    property_Flag = atoi(flagBuf);
+    SMI = getAllMessage(smsNum,index);
+    if(SMI==NULL)
+    {
+        base->e= LYNQ_E_NULL_ANONALY;
+        return -1;
+    }
+    fpW = fopen("/usr/bin/demoscript/SMS_API/custerm_message.txt", "w+");
+    if (fpW == 0)
+    {
+        LYERRLOG("[%s][%d][%s] Can't open log file!!\n",__FUNCTION__, __LINE__,__FILE__);
+        return -1;
+    }
+    for (int i = 0;i < smsNum;i++)
+    {
+        if (SMI[i]->index == index)
+        {
+            removeflag =1;
+            continue;
+        }
+        assembleMsgInfo(fpW,SMI[i]->index, SMI[i]->status, SMI[i]->smslen,SMI[i]->soc_id,SMI[i]->teleNum, element, SMI[i]->message);
+        strncat(buff, element, SMI[i]->smslen + KERNAL+SMI[i]->numLen);
+            //strncat(buff, SMI[i]->message,SMI[i]->smslen);
+    }
+    if(removeflag==1)
+    {
+        if(property_Flag==1)
+        {
+            snprintf(indexBuf,4, "%03d",99);
+            property_set(SMS_INDEX_VALUE,indexBuf);
+            property_set(SMS_INDEX_FLAG_VALUE,"0");
+
+        }
+        else
+        {
+            snprintf(indexBuf,4, "%03d", property_Count-1);
+            property_set(SMS_INDEX_VALUE,indexBuf);
+            property_set(SMS_INDEX_FLAG_VALUE,"0");
+        }
+    }
+    //printf("%s\n",buff);
+    fwrite(buff, strlen(buff), 1, fpW);//将msg对应的字符串append到文件末尾
+    fclose(fpW);
+    for(int i=0;i<smsNum;i++)
+    {
+        free(SMI[i]);
+    }
+    free(SMI);
+    base->e= RIL_E_SUCCESS;
+    return 0;
+}
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/sms.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/sms.cpp
new file mode 100644
index 0000000..c18e656
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/sms.cpp
@@ -0,0 +1,893 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include "sms/sms.h"
+
+#include <stdlib.h>
+#include <binder/Parcel.h>
+
+#include "sms/gsm/sms_pdu.h"
+#include "sms/cdma/sms_pdu_cdma.h"
+#include "common.h"
+#include "ecall/eCall.h"
+#include "util/utils.h"
+
+#define GSM_PHONE 1
+
+#undef LOG_TAG
+#define LOG_TAG "DEMO_SMS"
+
+#define PROP_ECALL_NUM "vendor.gost.ecall.ecall_sms_fallback_number"
+
+static void constructGsmSendSmsRilRequest (android::Parcel &p, char *smscPDU, char *pdu) {
+    p.writeInt32(2);
+    writeStringToParcel(p, (const char *)smscPDU);
+    writeStringToParcel(p, (const char *)pdu);
+}
+
+//RIL_REQUEST_SEND_SMS
+int sendSMS(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI){
+    char smscPDU[30]= {0};
+    char **pdu;
+    char smsc[4] = {0};
+    kal_int32 msg_num = 0;
+    kal_int32 msg_len = 0;
+    kal_int32 status = MDAPI_RET_ERROR;
+    kal_int32 index = 0;
+
+    status = _mdapi_sms_get_msg_num(argv[3], atoi(argv[2]), &msg_num, &msg_len);
+    RLOGD("%s, %s, %d, msg_len = [%d] ,msg_num=[%d]", __FILE__, __FUNCTION__, __LINE__, msg_len, msg_num);
+    if(status == MDAPI_RET_ERROR){
+        RLOGD("get message number failed");
+    }else {
+        //allocate memory for **pdu
+        pdu = (char **)malloc(sizeof(char *) * msg_num);
+        if(pdu == NULL){
+            RLOGD("%s, %s, %d, allocate memory for pdu failed", __FILE__, __FUNCTION__, __LINE__);
+        } else {
+            for(index = 0; index < msg_num; index++){
+                pdu[index] = (char *)malloc(sizeof(char)*MAX_PDU_SIZE);
+                if(pdu[index] == NULL){
+                    for(int i = 0; i < index; i++){
+                        free(pdu[i]);
+                    }
+                    free(pdu);
+                    pdu = NULL;
+                    if(pRI != NULL)
+                    {
+                        free(pRI);
+                    }
+                    RLOGD("%s, %s, %d, allocate memory for pdu[%d] failed", __FILE__, __FUNCTION__, __LINE__,index);
+                    return 0;
+                }else {
+                    memset(pdu[index], 0, MAX_PDU_SIZE);
+                    RLOGD("%s, %s, %d, pdu[%d} init value is: %s ", __FILE__, __FUNCTION__, __LINE__, index, pdu[index]);
+                }
+            }
+        }
+        //allocate memory for **pdu success
+        if(index == msg_num){
+            if(argc < 5){
+                smsPduEncode(smsc, argv[1], argv[3], atoi(argv[2]), smscPDU, pdu);
+            } else {
+                smsPduEncode(argv[4], argv[1], argv[3], atoi(argv[2]), smscPDU, pdu);
+            }
+            for (index = 0; index < msg_num; index++) {
+                RLOGD("%s, %s, %d, smscPDU: %s, pdu: %s",__FILE__, __FUNCTION__, __LINE__, smscPDU, pdu[index]);
+                android::Parcel p;
+                size_t pos = p.dataPosition();
+                RequestInfo *pRI_backup = (RequestInfo *)calloc(1, sizeof(RequestInfo));
+                pRI_backup->token = pRI->token;
+                pRI_backup->pCI = pRI->pCI;
+                pRI_backup->socket_id = pRI->socket_id;
+                pRI_backup->p_next = pRI->p_next;
+                constructGsmSendSmsRilRequest(p, smscPDU, pdu[index]);
+                p.setDataPosition(pos);
+                pRI->pCI->dispatchFunction(p, pRI_backup);
+            }
+            for(index = 0; index < msg_num; index++){
+                free(pdu[index]);
+            }
+
+            free(pdu);
+        }
+    }
+
+    //for auto save sms to sim    
+    if(argc < 5){
+        saveSendedSmsInfo(atoi(argv[2]), argv[1], argv[3], smsc);
+    } else {
+        saveSendedSmsInfo(atoi(argv[2]), argv[1], argv[3], argv[4]);
+    }
+
+    if(pRI != NULL)
+    {
+        free(pRI);
+    }
+
+    return 0;
+}
+
+
+//RIL_REQUEST_SEND_SMS_EXPECT_MORE
+int sendSMSExpectMore(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI){
+    char smscPDU[512]= {0};
+    char **pdu;
+    char smsc[4] = {0};
+    smsc[0] = '\0';
+    kal_int32 msg_num = 0;
+    kal_int32 msg_len = 0;
+    kal_int32 status = MDAPI_RET_ERROR;
+    kal_int32 index = 0;
+
+    status = _mdapi_sms_get_msg_num(argv[3], atoi(argv[2]), &msg_num, &msg_len);
+    RLOGD("%s, %s, %d, msg_len = [%d] ,msg_num=[%d]", __FILE__, __FUNCTION__, __LINE__, msg_len, msg_num);
+    if(status == MDAPI_RET_ERROR){
+        RLOGD("get message number failed");
+    } else {
+        //allocate memory for **pdu
+        pdu = (char **)malloc(sizeof(char *) * msg_num);
+        if(pdu == NULL){
+            RLOGD("%s, %s, %d, allocate memory for pdu failed", __FILE__, __FUNCTION__, __LINE__);
+        } else {
+            for(index = 0; index < msg_num; index++){
+                pdu[index] = (char *)malloc(sizeof(char)*MAX_PDU_SIZE);
+                if(pdu[index] == NULL){
+                    for(int i = 0; i < index; i++){
+                        free(pdu[i]);
+                    }
+                    free(pdu);
+                    pdu = NULL;
+                    if(pRI != NULL)
+                    {
+                        free(pRI);
+                    }
+                    RLOGD("%s, %s, %d, allocate memory for pdu[%d] failed", __FILE__, __FUNCTION__, __LINE__,index);
+                    return 0;
+                } else {
+                    memset(pdu[index], 0, MAX_PDU_SIZE);
+                    RLOGD("%s, %s, %d, pdu[%d} init value is: %s ", __FILE__, __FUNCTION__, __LINE__, index, pdu[index]);
+                }
+            }
+        }
+
+        //allocate memory for **pdu success
+        if(index == msg_num){
+            if(argc < 5){
+                smsPduEncode(smsc, argv[1], argv[3], atoi(argv[2]), smscPDU, pdu);
+            } else {
+                smsPduEncode(argv[4], argv[1], argv[3], atoi(argv[2]), smscPDU, pdu);
+            }
+            for (index = 0; index < msg_num; index++) {
+                RLOGD("%s, %s, %d, smscPDU: %s, pdu: %s",__FILE__, __FUNCTION__, __LINE__, smscPDU, pdu[index]);
+                android::Parcel p;
+                size_t pos = p.dataPosition();
+                RequestInfo *pRI_backup = (RequestInfo *)calloc(1, sizeof(RequestInfo));
+                pRI_backup->token = pRI->token;
+                pRI_backup->pCI = pRI->pCI;
+                pRI_backup->socket_id = pRI->socket_id;
+                pRI_backup->p_next = pRI->p_next;
+                constructGsmSendSmsRilRequest(p, smscPDU, pdu[index]);
+                p.setDataPosition(pos);
+                pRI->pCI->dispatchFunction(p, pRI_backup);
+            }
+
+            for(index = 0; index < msg_num; index++){
+                free(pdu[index]);
+            }
+
+            free(pdu);
+            pdu = NULL;
+        }
+    }
+
+    if(pRI != NULL)
+    {
+        free(pRI);
+    }
+
+    //for auto save sms to sim    
+    if(argc < 5){
+        saveSendedSmsInfo(atoi(argv[2]), argv[1], argv[3], smsc);
+    } else {
+        saveSendedSmsInfo(atoi(argv[2]), argv[1], argv[3], argv[4]);
+    }
+
+    return 0;
+}
+
+//RIL_REQUEST_IMS_SEND_SMS
+int sendImsGsmSms(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI){
+    char smscPDU[30]= {0};
+    char **pdu;
+    char smsc[4] = {0};
+    kal_int32 msg_num = 0;
+    kal_int32 msg_len = 0;
+    kal_int32 status = MDAPI_RET_ERROR;
+    kal_int32 index = 0;
+    uint8_t retry = atoi(argv[4]);
+    int32_t messageRef = atoi(argv[5]);
+
+    status = _mdapi_sms_get_msg_num(argv[3], atoi(argv[2]), &msg_num, &msg_len);
+    RLOGD("%s, %s, %d, msg_len = [%d] ,msg_num=[%d]", __FILE__, __FUNCTION__, __LINE__, msg_len, msg_num);
+    if(status == MDAPI_RET_ERROR){
+        RLOGD("get message number failed");
+    } else {
+        //allocate memory for **pdu
+        pdu = (char **)malloc(sizeof(char *) * msg_num);
+        if(pdu == NULL){
+            RLOGD("%s, %s, %d, allocate memory for pdu failed", __FILE__, __FUNCTION__, __LINE__);
+        } else {
+            for(index = 0; index < msg_num; index++){
+                pdu[index] = (char *)malloc(sizeof(char)*MAX_PDU_SIZE);
+                if(pdu[index] == NULL){
+                    for(int i = 0; i < index; i++){
+                        free(pdu[i]);
+                    }
+                    free(pdu);
+                    pdu = NULL;
+                    if(pRI != NULL)
+                    {
+                        free(pRI);
+                    }
+                    RLOGD("%s, %s, %d, allocate memory for pdu[%d] failed", __FILE__, __FUNCTION__, __LINE__,index);
+                    return 0;
+                } else {
+                    memset(pdu[index], 0, MAX_PDU_SIZE);
+                    RLOGD("%s, %s, %d, pdu[%d} init value is: %s ", __FILE__, __FUNCTION__, __LINE__, index, pdu[index]);
+                }
+            }
+        }
+
+        //allocate memory for **pdu success
+        if(index == msg_num){
+            if(argc < 7){
+                smsPduEncode(smsc, argv[1], argv[3], atoi(argv[2]), smscPDU, pdu);
+            } else {
+                smsPduEncode(argv[6], argv[1], argv[3], atoi(argv[2]), smscPDU, pdu);
+            }
+            for (index = 0; index < msg_num; index++) {
+                RLOGD("%s, %s, %d, smscPDU: %s, pdu: %s",__FILE__, __FUNCTION__, __LINE__, smscPDU, pdu[index]);
+                android::Parcel p;
+                size_t pos = p.dataPosition();
+                RequestInfo *pRI_backup = (RequestInfo *)calloc(1, sizeof(RequestInfo));
+                pRI_backup->token = pRI->token;
+                pRI_backup->pCI = pRI->pCI;
+                pRI_backup->socket_id = pRI->socket_id;
+                pRI_backup->p_next = pRI->p_next;
+                p.writeInt32(RADIO_TECH_3GPP);
+                p.write(&retry, sizeof(retry));
+                p.write(&messageRef, sizeof(messageRef));
+                constructGsmSendSmsRilRequest(p, smscPDU, pdu[index]);
+                p.setDataPosition(pos);
+                pRI->pCI->dispatchFunction(p, pRI_backup);
+            }
+
+            for(index = 0; index < msg_num; index++){
+                free(pdu[index]);
+            }
+
+            free(pdu);
+            pdu = NULL;
+        }
+    }
+
+    if(pRI != NULL)
+    {
+        free(pRI);
+        pRI = NULL;
+    }
+
+    //for auto save sms to sim    
+    if(argc < 7){
+        saveSendedSmsInfo(atoi(argv[2]), argv[1], argv[3], smsc);
+    } else {
+        saveSendedSmsInfo(atoi(argv[2]), argv[1], argv[3], argv[6]);
+    }
+
+    return 0;
+}
+
+int sendImsCdmaSms(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    uint8_t retry = atoi(argv[1]);
+    int32_t messageRef = atoi(argv[2]);
+    char* destAddr = argv[3];
+    char* message = argv[4];
+    createCdmaMessage(pRI,destAddr,message, false, retry, messageRef);
+    return 0;
+}
+
+//RIL_REQUEST_WRITE_SMS_TO_SIM
+int writeSmsToSim(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI){
+    char smscPDU[30]= {0};
+    char **pdu;
+    char smsc[4] = {0};
+    kal_int32 msg_num = 0;
+    kal_int32 msg_len = 0;
+    kal_int32 status = MDAPI_RET_ERROR;
+    kal_int32 index = 0;
+
+    status = _mdapi_sms_get_msg_num(argv[4], atoi(argv[3]), &msg_num, &msg_len);
+    RLOGD("%s, %s, %d, msg_len = [%d] ,msg_num=[%d]", __FILE__, __FUNCTION__, __LINE__, msg_len, msg_num);
+    if(status == MDAPI_RET_ERROR){
+        RLOGD("get message number failed");
+    } else {
+        //allocate memory for **pdu
+        pdu = (char **)malloc(sizeof(char *) * msg_num);
+        if(pdu == NULL){
+            RLOGD("%s, %s, %d, allocate memory for pdu failed", __FILE__, __FUNCTION__, __LINE__);
+        } else {
+            for(index = 0; index < msg_num; index++){
+                pdu[index] = (char *)malloc(sizeof(char)*MAX_PDU_SIZE);
+                if(pdu[index] == NULL){
+                    for(int i = 0; i < index; i++){
+                        free(pdu[i]);
+                    }
+                    free(pdu);
+                    pdu = NULL;
+                    if(pRI != NULL)
+                    {
+                        free(pRI);
+                    }
+                    RLOGD("%s, %s, %d, allocate memory for pdu[%d] failed", __FILE__, __FUNCTION__, __LINE__,index);
+                    return 0;
+                } else {
+                    memset(pdu[index], 0, MAX_PDU_SIZE);
+                    RLOGD("%s, %s, %d, pdu[%d} init value is: %s ", __FILE__, __FUNCTION__, __LINE__, index, pdu[index]);
+                }
+            }
+        }
+        //allocate memory for **pdu success
+        if(index == msg_num){
+            if(argc < 6){
+                smsPduEncode(smsc, argv[2], argv[4], atoi(argv[3]), smscPDU, pdu);
+            } else {
+                smsPduEncode(argv[5], argv[2], argv[4], atoi(argv[3]), smscPDU, pdu);
+            }
+            for (index = 0; index < msg_num; index++) {
+                RLOGD("%s, %s, %d, smscPDU: %s, pdu: %s",__FILE__, __FUNCTION__, __LINE__, smscPDU, pdu[index]);
+                android::Parcel p;
+                size_t pos = p.dataPosition();
+                RequestInfo *pRI_backup = (RequestInfo *)calloc(1, sizeof(RequestInfo));
+                pRI_backup->token = pRI->token;
+                pRI_backup->pCI = pRI->pCI;
+                pRI_backup->socket_id = pRI->socket_id;
+                pRI_backup->p_next = pRI->p_next;
+                p.writeInt32(atoi(argv[1]));
+                writeStringToParcel(p, (const char *)pdu[index]);
+                writeStringToParcel(p, (const char *)smscPDU);
+                p.setDataPosition(pos);
+                pRI->pCI->dispatchFunction(p, pRI_backup);
+            }
+
+            for(index = 0; index < msg_num; index++){
+                free(pdu[index]);
+            }
+
+            free(pdu);
+            pdu = NULL;
+        }
+    }
+    if(pRI != NULL)
+    {
+        free(pRI);
+    }
+
+    return 0;
+}
+
+//RIL_REQUEST_DELETE_SMS_ON_SIM
+int deleteSmsOnSim(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI){
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+
+    p.writeInt32(1);
+    p.writeInt32(atoi(argv[1]));
+
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+//RIL_REQUEST_SMS_ACKNOWLEDGE
+int acknowledgeLastIncomingGsmSms(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI){
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+
+    p.writeInt32(2);
+    p.writeInt32(atoi(argv[1]) ? 1 : 0);
+    p.writeInt32(atoi(argv[2]));
+
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+//RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU
+int acknowledgeIncomingGsmSmsWithPdu(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI){
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+
+    p.writeInt32(2);
+    p.writeInt32(atoi(argv[1]));
+    p.writeInt32(atoi(argv[2]));
+
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+//RIL_REQUEST_REPORT_SMS_MEMORY_STATUS
+int reportSmsMemoryStatus(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI){
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+
+    p.writeInt32(1);
+    p.writeInt32(atoi(argv[1]) ? 1 : 0);
+
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+//RIL_REQUEST_SET_SMSC_ADDRESS
+int setSmscAddress(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI){
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+
+    writeStringToParcel(p, (const char *)argv[1]);
+
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+//RIL_REQUEST_GET_SMSC_ADDRESS
+int getSmscAddress(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI){
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+void sendSMSACK(RIL_SOCKET_ID soc_id)
+{
+    sendSmsMsg(soc_id); //for power manager test.
+    android::requestSMSACKNOWLEDGE(soc_id);
+    return;
+}
+
+int responseNewSMS(const char *data, size_t datalen, int soc_id,int32_t unsol){
+    char smsc[512] = {0};
+    char msg[512] = {0};
+    char num[512] = {0};
+    int charset = 0;
+    RLOGD("slot: %d, len: %d, sms: %s",soc_id, datalen, data);
+    smsPduDecode(data, datalen, num, smsc, msg, &charset);
+    if(s_Env)
+    {
+        s_Env->recive_new_sms_cb(soc_id,num,smsc,msg,charset);
+    }
+    printf("[EVENT][MT_SMS][SIM%d]PDU decode:smsc: %s, phone number: %s , charset: %d, msg_len: %d, message content: %s\n", soc_id, smsc, num, charset, strlen(msg), msg);
+	RLOGD("[EVENT][MT_SMS][SIM%d]PDU decode:smsc: %s, phone number: %s , charset: %d, msg_len: %d, message content: %s", soc_id, smsc, num, charset, strlen(msg), msg);
+    if(isGostEcall() && (MDAPI_SMS_CHARSET_GSM_8BIT == charset))
+    {
+        gostParseSmsHandle(soc_id, num, msg);
+    }
+
+    return 0;
+}
+
+#ifdef C2K_SUPPORT
+//RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG
+int getCdmaBroadcastConfig(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI){
+  printf("test function is %s\n", __func__);
+  android::Parcel p;
+  pRI->pCI->dispatchFunction(p, pRI);
+  return 0;
+}
+
+//RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM
+int deleteSmsOnRUIM(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+  if(argc < 2) {
+      RLOGE("%s parameter error!",__func__);
+      free(pRI);
+      return -1;
+  }
+  printf("test function is %s\n", __func__);
+  android::Parcel p;
+  size_t pos = p.dataPosition();
+
+  p.writeInt32(1);
+  p.writeInt32(atoi(argv[1]));
+
+  p.setDataPosition(pos);
+  pRI->pCI->dispatchFunction(p, pRI);
+
+  return 0;
+}
+
+//RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG
+int setCdmaBroadcastConfig(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI){
+  if(argc < 5) {
+      RLOGE("%s parameter error!",__func__);
+      free(pRI);
+      return -1;
+  }
+  int from = atoi(argv[1]);
+  int to = atoi(argv[2]);
+  if (from < 0 || to < 0 || from > to) {
+    RLOGE("%s parameter error: from > to !",__func__);
+    free(pRI);
+    return -1;
+  }
+  int num = (to - from) + 1;
+  int language = atoi(argv[3]);
+  int selected = atoi(argv[4]);
+  if (selected > 0) {
+    selected = 1;
+  } else {
+    selected = 0;
+  }
+  android::Parcel p;
+  size_t pos = p.dataPosition();
+  p.writeInt32(num);
+  for(int index = from; index <= to ; index++){
+    p.writeInt32(index);
+    p.writeInt32(language);
+    p.writeInt32(selected);
+  }
+  p.setDataPosition(pos);
+  pRI->pCI->dispatchFunction(p, pRI);
+  return 0;
+}
+
+//RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION
+int setCdmaBroadcastActivation(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI){
+  //printf("test function is %s\n", __func__);
+  if(argc < 2) {
+      RLOGE("%s parameter error!",__func__);
+      free(pRI);
+      return -1;
+  }
+  android::Parcel p;
+  size_t pos =  p.dataPosition();
+  p.writeInt32(1);
+  p.writeInt32(atoi(argv[1])? 1 : 0);
+  p.setDataPosition(pos);
+  pRI->pCI->dispatchFunction(p, pRI);
+
+  return 0;
+}
+
+//RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM
+int writeSmsToRuim(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI){
+  printf("test function is %s\n", __func__);
+  char* destAddr = argv[1];
+  char* message = argv[2];
+  if(argc < 3 || destAddr == NULL || message == NULL ) {
+      RLOGE("%s parameter error!",__func__);
+      free(pRI);
+      return -1;
+  }
+  createCdmaMessage(pRI,destAddr,message, true, 0 ,0);
+  return 0;
+}
+
+//RIL_REQUEST_CDMA_SEND_SMS
+int sendCdmaSms(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI){
+  if(argc != 3) {
+      RLOGE("%s parameter num error!",__func__);
+      free(pRI);
+      return -1;
+  }
+  char* destAddr = argv[1];
+  char* message = argv[2];
+  if(destAddr == NULL || message == NULL ) {
+      RLOGE("%s parameter error!",__func__);
+      free(pRI);
+      return -1;
+  }
+  createCdmaMessage(pRI,destAddr,message, false, 0 ,0);
+  return 0;
+}
+
+//RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE
+int acknowledgeLastIncomingCdmaSms(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI){
+  //printf("test function is %s\n", __func__);
+  android::Parcel p;
+  size_t pos =  p.dataPosition();
+  p.writeInt32(0);
+  p.writeInt32(1);
+  p.setDataPosition(pos);
+  pRI->pCI->dispatchFunction(p, pRI);
+  return 0;
+}
+#endif /*C2K_SUPPORT*/
+
+//RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG
+int getGsmBroadcastConfig(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI){
+    android::Parcel p;
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+//RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG
+int setGsmBroadcastConfig(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if(argc != 6) {
+        RLOGE("%s parameter error!",__func__);
+        free(pRI);
+        return -1;
+    }
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    p.writeInt32(1);
+    p.writeInt32(atoi(argv[1]));
+    p.writeInt32(atoi(argv[2]));
+    p.writeInt32(atoi(argv[3]));
+    p.writeInt32(atoi(argv[4]));
+    p.writeInt32(atoi(argv[5]));
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+//RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION
+int setGsmBroadcastActivation(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if(argc != 2) {
+        RLOGE("%s parameter error!",__func__);
+        free(pRI);
+        return -1;
+    }
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    p.writeInt32(1);
+    p.writeInt32(atoi(argv[1]));
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+int getSmsSimMemStatus(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI){
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+static bool auto_save_sms_to_sim = false;
+static bool Sim_sms_storage_full = false;
+static smsSaveInfo* psmsSaveInfo = NULL;
+
+int setAutoSaveSmsToSimFlag(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI){
+    if(argc != 2) {
+        RLOGE("%s parameter error!",__func__);
+        free(pRI);
+        return -1;
+    }
+
+    int enable = atoi(argv[1]);
+    if(enable)
+    {
+        auto_save_sms_to_sim = true;
+    }
+    else
+    {
+        auto_save_sms_to_sim = false;
+    }
+    RLOGE("%s:%d", __FUNCTION__, auto_save_sms_to_sim);
+    return 0;
+}
+
+int setSimSmsStorageFullFlag(bool enable)
+{
+    Sim_sms_storage_full = enable;
+    RLOGE("%s:%d", __FUNCTION__, Sim_sms_storage_full);
+    return 0;
+}
+
+//sent status save
+int saveSendedSmsInfo(int charset, char* num, char* msg, char* smsc)
+{
+    if(psmsSaveInfo == NULL)
+    {
+        psmsSaveInfo = (smsSaveInfo*)malloc(sizeof(smsSaveInfo));
+    }
+    memset(psmsSaveInfo, 0, sizeof(psmsSaveInfo));
+
+    psmsSaveInfo->charset = charset;
+    psmsSaveInfo->sendStatus = 3; //UnRead|Read|UnSent|Sent
+    strcpy(psmsSaveInfo->num, num);
+    strcpy(psmsSaveInfo->sms, msg);
+    strcpy(psmsSaveInfo->smsc, smsc);
+    RLOGE("%s:send sms saved", __FUNCTION__);
+
+    return 0;
+}
+
+int sendStatusWriteSmsToSim(int socket_id)
+{
+    if(psmsSaveInfo == NULL)
+    {
+        RLOGE("%s error psmsSaveInfo is null",__func__);
+        return 0;
+    }
+    autoWriteSmsToSim(psmsSaveInfo, socket_id);
+    free(psmsSaveInfo);
+    psmsSaveInfo = NULL;
+    return 0;
+}
+
+int autoWriteSmsToSim(smsSaveInfo *smsInfo, int id)
+{
+    int argc = 6;
+    char *argv[6];
+    RIL_SOCKET_ID socket_id;
+    char charset[4] = {0};
+    char status[4] = {0};
+
+    if((true == auto_save_sms_to_sim)&&(false == Sim_sms_storage_full))
+    {
+        RequestInfo *pRI = creatRILInfoAndInit(RIL_REQUEST_WRITE_SMS_TO_SIM, UDP, (RIL_SOCKET_ID)(id));
+        if(pRI == NULL)
+        {
+            RLOGE("error PRI is NULL");
+            return 0;
+        }
+        sprintf(charset, "%d", smsInfo->charset);
+        argv[3] = charset;
+
+        argv[0] = "RIL_REQUEST_WRITE_SMS_TO_SIM";
+        sprintf(status, "%d", smsInfo->sendStatus);
+        argv[1] = status;
+        argv[2] = smsInfo->num;
+        argv[4] = smsInfo->sms;
+        argv[5] = smsInfo->smsc;
+
+        RLOGE("%s status:%s, num:%s, sms:%s, charset:%s, sms:%s",__func__,
+                                                argv[1],argv[2],argv[3],argv[5],argv[4]);
+        
+        writeSmsToSim(argc, argv, pRI->socket_id, pRI);
+    }
+    return 0;
+}
+
+int unreadStatusWriteSMSToSim(const char *data, size_t datalen, int soc_id)
+{
+    char smscPDU[30]= {0};
+    char pdu[MAX_PDU_SIZE] = {0};
+    int32_t status = 0;
+    RLOGD("%s:slot: %d, len: %d, sms: %s",__FUNCTION__, soc_id, datalen, data);
+
+    if((true == auto_save_sms_to_sim)&&(false == Sim_sms_storage_full))
+    {
+        RequestInfo *pRI = creatRILInfoAndInit(RIL_REQUEST_WRITE_SMS_TO_SIM, UDP, (RIL_SOCKET_ID)(soc_id));
+        if(pRI == NULL)
+        {
+            RLOGE("error PRI is NULL");
+            return 0;
+        }
+        if(getNewSmsPduAndSmsc(data, datalen, smscPDU, pdu) < 0)
+        {
+            if(pRI != NULL)
+            {
+                free(pRI);
+                pRI = NULL;
+            }
+            RLOGD("%s, %s, %d, smsc: ERR",__FILE__, __FUNCTION__, __LINE__);
+            return 0;
+        }
+        RLOGD("%s, %s, %d, smsc: %s, msg: %s",__FILE__, __FUNCTION__, __LINE__, smscPDU, pdu);
+
+        android::Parcel p;
+        size_t pos = p.dataPosition();
+        RequestInfo *pRI_backup = (RequestInfo *)calloc(1, sizeof(RequestInfo));
+        pRI_backup->token = pRI->token;
+        pRI_backup->pCI = pRI->pCI;
+        pRI_backup->socket_id = pRI->socket_id;
+        pRI_backup->p_next = pRI->p_next;
+        p.writeInt32(status);
+        writeStringToParcel(p, (const char *)pdu);
+        writeStringToParcel(p, (const char *)smscPDU);
+        p.setDataPosition(pos);
+        pRI->pCI->dispatchFunction(p, pRI_backup);
+
+        if(pRI != NULL)
+        {
+            free(pRI);
+            pRI = NULL;
+        }
+    }
+    return 0;
+}
+
+int gostSendSmsForMsd(int id, char *num, char *msd)
+{
+    int argc = 4;
+    char *argv[5];
+    char charset[4] = {0};
+
+    RequestInfo *pRI = creatRILInfoAndInit(RIL_REQUEST_SEND_SMS, UDP, (RIL_SOCKET_ID)(id));
+    if(pRI == NULL)
+    {
+        RLOGE("error PRI is NULL");
+        return 0;
+    }
+    char configNum[140]= {0};
+    utils::mtk_property_get(PROP_ECALL_NUM, configNum, "112");
+
+    sprintf(charset, "%d", MDAPI_SMS_CHARSET_GSM_8BIT);
+    argv[2] = charset;
+
+    argv[0] = "RIL_REQUEST_SEND_SMS";
+    argv[1] = configNum;
+    argv[3] = msd;
+    gostSaveSmsData(argc, argv, (RIL_SOCKET_ID)(id));
+    sendSMS(argc, argv, pRI->socket_id, pRI);
+
+    return 0;
+}
+
+int getGsmBroadcastLanguage(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI){
+    android::Parcel p;
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+int setGsmBroadcastLanguage(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if(argc != 2) {
+        RLOGE("%s parameter error!",__func__);
+        free(pRI);
+        return -1;
+    }
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+
+    writeStringToParcel(p, (const char *)argv[1]);
+
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/sms.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/sms.h
new file mode 100644
index 0000000..55697a6
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/sms.h
@@ -0,0 +1,97 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#ifndef YOCTO_SMS_H
+#define YOCTO_SMS_H 1
+
+#include <vendor-ril/telephony/ril.h>
+#include  "common.h"
+
+//for auto save sms to sim    
+typedef struct {
+    int charset;
+    int sendStatus;
+    char num[16];
+    char sms[512];
+    char smsc[16];
+}smsSaveInfo;
+
+//RIL_REQUEST_SEND_SMS
+int sendSMS(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+//RIL_REQUEST_SEND_SMS_EXPECT_MORE
+int sendSMSExpectMore(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+//RIL_REQUEST_IMS_SEND_SMS
+int sendImsGsmSms(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int sendImsCdmaSms(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+/*int sendImsCdmaSms(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);*/
+//RIL_REQUEST_WRITE_SMS_TO_SIM
+int writeSmsToSim(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+//RIL_REQUEST_DELETE_SMS_ON_SIM
+int deleteSmsOnSim(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+//RIL_REQUEST_SMS_ACKNOWLEDGE
+int acknowledgeLastIncomingGsmSms(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+//RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU
+int acknowledgeIncomingGsmSmsWithPdu(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+//RIL_REQUEST_REPORT_SMS_MEMORY_STATUS
+int reportSmsMemoryStatus(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+//RIL_REQUEST_SET_SMSC_ADDRESS
+int setSmscAddress(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+//RIL_REQUEST_GET_SMSC_ADDRESS
+int getSmscAddress(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+void sendSMSACK(RIL_SOCKET_ID soc_id);
+int responseNewSMS(const char *data, size_t datalen, int soc_id,int32_t unsol);
+
+#ifdef C2K_SUPPORT
+int getCdmaBroadcastConfig(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int deleteSmsOnRUIM(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setCdmaBroadcastConfig(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setCdmaBroadcastActivation(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int writeSmsToRuim(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int sendCdmaSms(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int acknowledgeLastIncomingCdmaSms(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+#endif /*C2K_SUPPORT*/
+int getGsmBroadcastConfig(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setGsmBroadcastConfig(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setGsmBroadcastActivation(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int getSmsSimMemStatus(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setAutoSaveSmsToSimFlag(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setSimSmsStorageFullFlag(bool enable);
+int autoWriteSmsToSim(smsSaveInfo *smsInfo, int id);
+int saveSendedSmsInfo(int charset, char* num, char* msg, char* smsc);
+int sendStatusWriteSmsToSim(int socket_id);
+int unreadStatusWriteSMSToSim(const char *data, size_t datalen, int soc_id);
+int gostSendSmsForMsd(int id, char *num, char *msd);
+int getGsmBroadcastLanguage(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setGsmBroadcastLanguage(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+#endif
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ss.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ss.cpp
new file mode 100644
index 0000000..78f0113
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ss.cpp
@@ -0,0 +1,716 @@
+ /*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <alloca.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <cutils/jstring.h>
+#include <stdlib.h>
+#include <binder/Parcel.h>
+#include <string.h>
+#include <strings.h>
+#include <log/log.h>
+#include<iconv.h>
+
+#include "common.h"
+#include "ss.h"
+
+#undef LOG_TAG
+#define LOG_TAG "DEMO_SS"
+
+static int TOA_International = 0x91;
+static int TOA_Unknown = 0x81;
+
+static const int SERVICE_CLASS_NONE     = 0; // no user input
+static const int SERVICE_CLASS_VOICE    = (1 << 0);
+static const int SERVICE_CLASS_DATA     = (1 << 1); //synonym for 16+32+64+128
+static const int SERVICE_CLASS_FAX      = (1 << 2);
+static const int SERVICE_CLASS_SMS      = (1 << 3);
+static const int SERVICE_CLASS_DATA_SYNC = (1 << 4);
+static const int SERVICE_CLASS_DATA_ASYNC = (1 << 5);
+static const int SERVICE_CLASS_PACKET   = (1 << 6);
+static const int SERVICE_CLASS_PAD      = (1 << 7);
+static const int SERVICE_CLASS_MAX      = (1 << 9); // Max SERVICE_CLASS value
+
+// Used for call barring methods below
+static char* CB_FACILITY_BAOC         = "AO";
+static char* CB_FACILITY_BAOIC        = "OI";
+static char* CB_FACILITY_BAOICxH      = "OX";
+static char* CB_FACILITY_BAIC         = "AI";
+static char* CB_FACILITY_BAICr        = "IR";
+static char* CB_FACILITY_BA_ALL       = "AB";
+static char* CB_FACILITY_BA_MO        = "AG";
+static char* CB_FACILITY_BA_MT        = "AC";
+static char* CB_FACILITY_BA_SIM       = "SC";
+static char* CB_FACILITY_BA_FD        = "FD";
+
+
+// Used as parameters for call forward methods below
+static const int CF_ACTION_DISABLE          = 0;
+static const int CF_ACTION_ENABLE           = 1;
+static const int CF_ACTION_INTERROGATE      = 2;
+static const int CF_ACTION_REGISTRATION     = 3;
+static const int CF_ACTION_ERASURE          = 4;
+
+static const int CF_REASON_UNCONDITIONAL    = 0;
+static const int CF_REASON_BUSY             = 1;
+static const int CF_REASON_NO_REPLY         = 2;
+static const int CF_REASON_NOT_REACHABLE    = 3;
+static const int CF_REASON_ALL              = 4;
+static const int CF_REASON_ALL_CONDITIONAL  = 5;
+static const int CF_REASON_NOT_REGISTERED   = 6;
+
+//Called line presentation
+static const char* SC_CLIP   = "30";
+static const char* SC_CLIR   = "31";
+
+// Call Forwarding
+static const char* SC_CFU    = "21";
+static const char* SC_CFB    = "67";
+static const char* SC_CFNRy   = "61";
+static const char* SC_CFNR   = "62";
+
+static const char* SC_CF_All = "002";
+static const char* SC_CF_All_Conditional = "004";
+
+// Call Waiting
+static const char* SC_WAIT    = "43";
+
+// Call Barring
+static const char* SC_BAOC        = "33";
+static const char* SC_BAOIC       = "331";
+static const char* SC_BAOICxH     = "332";
+static const char* SC_BAIC        = "35";
+static const char* SC_BAICr       = "351";
+
+static const char* SC_BA_ALL      = "330";
+static const char* SC_BA_MO       = "333";
+static const char* SC_BA_MT       = "353";
+
+// Supp Service Password registration
+static const char* SC_PWD         = "03";
+
+// PIN/PIN2/PUK/PUK2
+static const char* SC_PIN         = "04";
+static const char* SC_PIN2        = "042";
+static const char* SC_PUK         = "05";
+static const char* SC_PUK2        = "052";
+
+///M:For query CNAP
+static const char* SC_CNAP        = "300";
+
+int toaFromString(char* s) {
+    if (s != NULL && strlen(s) > 0 && *s == '+') {
+        return TOA_International;
+    }
+
+    return TOA_Unknown;
+}
+
+char* scToBarringFacility(char* sc) {
+    if (sc == NULL) {
+        RLOGE("invalid call barring sc");
+        return NULL;
+    }
+
+    if (strcmp(sc, SC_BAOC) == 0) {
+        return CB_FACILITY_BAOC;
+    } else if (strcmp(sc, SC_BAOIC) == 0) {
+        return CB_FACILITY_BAOIC;
+    } else if (strcmp(sc, SC_BAOICxH) == 0) {
+        return CB_FACILITY_BAOICxH;
+    } else if (strcmp(sc, SC_BAIC) == 0) {
+        return CB_FACILITY_BAIC;
+    } else if (strcmp(sc, SC_BAICr) == 0) {
+        return CB_FACILITY_BAICr;
+    } else if (strcmp(sc, SC_BA_ALL) == 0) {
+        return CB_FACILITY_BA_ALL;
+    } else if (strcmp(sc, SC_BA_MO) == 0) {
+        return CB_FACILITY_BA_MO;
+    } else if (strcmp(sc, SC_BA_MT) == 0) {
+        return CB_FACILITY_BA_MT;
+    } else if (strcasecmp(sc, CB_FACILITY_BA_FD) == 0 ) {
+        return CB_FACILITY_BA_FD;
+    } else if (strcasecmp(sc, CB_FACILITY_BA_SIM) == 0 ) {
+        return CB_FACILITY_BA_SIM;
+    } else {
+        RLOGE("invalid call barring sc");
+        return NULL;
+    }
+}
+
+
+int scToCallForwardReason(char* sc) {
+    if (sc == NULL) {
+        RLOGE("invalid call forward sc");
+        return -1;
+    }
+
+    if (strcmp(sc, SC_CF_All) == 0) {
+       return CF_REASON_ALL;
+    } else if (strcmp(sc, SC_CFU) == 0) {
+        return CF_REASON_UNCONDITIONAL;
+    } else if (strcmp(sc, SC_CFB) == 0) {
+        return CF_REASON_BUSY;
+    } else if (strcmp(sc, SC_CFNR) == 0) {
+        return CF_REASON_NOT_REACHABLE;
+    } else if (strcmp(sc, SC_CFNRy) == 0) {
+        return CF_REASON_NO_REPLY;
+    } else if (strcmp(sc, SC_CF_All_Conditional) == 0) {
+       return CF_REASON_ALL_CONDITIONAL;
+    } else {
+        RLOGE("invalid call forward sc");
+        return -1;
+    }
+}
+
+int siToServiceClass(char* si)
+{
+    if (si == NULL || strcmp(si, "null") == 0)
+    {
+        return  SERVICE_CLASS_NONE;
+    } else {
+            // NumberFormatException should cause MMI fail
+        int serviceCode = atoi(si);
+
+        switch (serviceCode) {
+                case 10: return SERVICE_CLASS_SMS + SERVICE_CLASS_FAX  + SERVICE_CLASS_VOICE;
+                case 11: return SERVICE_CLASS_VOICE;
+                case 12: return SERVICE_CLASS_SMS + SERVICE_CLASS_FAX;
+                case 13: return SERVICE_CLASS_FAX;
+
+                case 16: return SERVICE_CLASS_SMS;
+
+                case 19: return SERVICE_CLASS_FAX + SERVICE_CLASS_VOICE;
+/*
+    Note for code 20:
+     From TS 22.030 Annex C:
+                "All GPRS bearer services" are not included in "All tele and bearer services"
+                    and "All bearer services"."
+....so SERVICE_CLASS_DATA, which (according to 27.007) includes GPRS
+*/
+                case 20: return SERVICE_CLASS_DATA_ASYNC + SERVICE_CLASS_DATA_SYNC;
+
+                case 21: return SERVICE_CLASS_PAD + SERVICE_CLASS_DATA_ASYNC;
+                case 22: return SERVICE_CLASS_PACKET + SERVICE_CLASS_DATA_SYNC;
+                case 24: return SERVICE_CLASS_DATA_SYNC;
+                //don't support video
+                //case 24: return SERVICE_CLASS_DATA_SYNC + SERVICE_CLASS_VIDEO;
+                case 25: return SERVICE_CLASS_DATA_ASYNC;
+                case 26: return SERVICE_CLASS_DATA_SYNC + SERVICE_CLASS_VOICE;
+                case 99: return SERVICE_CLASS_PACKET;
+
+                default:
+                    RLOGW("unsupported MMI service code:%s ", si);
+                    return SERVICE_CLASS_NONE;
+         }
+    }
+}
+
+int siToTime (char* si) {
+    if (si == NULL || strcmp(si, "null") == 0) {
+        return 0;
+    } else {
+        // NumberFormatException should cause MMI fail
+        return atoi(si);
+    }
+}
+
+bool isGBK(unsigned char* data, int len)
+{
+    return false;
+    int i = 0;
+    while(i < len)
+    {
+        if(data[i] <= 0x7f)
+        {
+            //one byte encode
+            i++;
+            continue;
+        }
+        else
+        {
+            //two byte encode
+            if(data[i] >= 0x81 && data[i] <= 0xfe && data[i + 1] >= 0x40
+                &&data[i + 1] <= 0xfe && data[i + 1] != 0xf7)
+            {
+                i += 2;
+                continue;
+            }
+            else
+            {
+                return false;
+            }
+        }
+    }
+
+    return true;
+}
+int gbkToUtf8(char* src_str, size_t src_len, char* dst_str, size_t dst_len)
+{
+    iconv_t cd;
+    char **pin = &src_str;
+    char **pout = &dst_str;
+    cd = iconv_open("UTF-8", "GBK");
+    if(cd == (iconv_t) - 1)
+    {
+        printf("iconv_open error\n");
+        RLOGE("iconv_open error");
+        return -1;
+    }
+    memset(dst_str, 0, dst_len);
+    if(iconv(cd, pin, &src_len, pout, &dst_len) == -1){
+        printf("format error or nosupport\n");
+        RLOGE("format error or nosupport");
+        return -1;
+    }
+
+    iconv_close(cd);
+//    **pout = '\0';
+    
+    return 0;
+}
+//xxx ussiString
+int sendUSSI(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if(argc != 3)
+    {
+        RLOGD("the peremeters numbers isn't right , so return");
+        return -1;
+    }
+    char* srcstr = argv[2];
+    char utf8str[64];
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    p.writeInt32(2);
+    writeStringToParcel(p, (const char *)argv[1]);//ussdaction
+
+    printf("srcstr:%s\n", srcstr);
+    printf("srcstr:%s\n", argv[2]);
+    if(isGBK((unsigned char *)srcstr, strlen(srcstr)))
+    {
+        if(gbkToUtf8(srcstr, strlen(srcstr), utf8str, sizeof(utf8str)) < 0)
+        {
+            RLOGE("format change error");
+        }
+        printf("gbk to utf8:%s\n", utf8str);
+        writeStringToParcel(p, (const char *)utf8str);//ussdString
+    }
+    else
+    {
+        printf("--------utf8:%s\n", srcstr);
+        writeStringToParcel(p, (const char *)srcstr);//ussdString
+    }
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+int cancelPendingUssi(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if(argc != 1)
+    {
+        RLOGD("the peremeters numbers isn't right , so return");
+        return -1;
+    }
+
+    android::Parcel p;
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+//xxx ussdString
+int sendUSSD(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if(argc != 2)
+    {
+        RLOGD("the peremeters numbers isn't right , so return");
+        return -1;
+    }
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    writeStringToParcel(p, (const char *)argv[1]);//ussdString
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+int cancelPendingUssd(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if(argc != 1)
+    {
+        RLOGD("the peremeters numbers isn't right , so return");
+        return -1;
+    }
+
+    android::Parcel p;
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+int getCLIR(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if(argc != 1)
+    {
+        RLOGD("the peremeters numbers isn't right , so return");
+        return -1;
+    }
+
+    android::Parcel p;
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+//xxx clirMode
+int setCLIR(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if(argc != 2)
+    {
+        RLOGD("the peremeters numbers isn't right , so return");
+        return -1;
+    }
+
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    p.writeInt32(1);
+    //0: "user subscription default value;  1:restrict CLI presentation; 2: allow CLI presentation
+    p.writeInt32(atoi(argv[1]));//clirMode
+    p.setDataPosition(pos);
+
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+int queryCLIP(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if(argc != 1)
+    {
+        RLOGD("the peremeters numbers isn't right , so return");
+        return -1;
+    }
+    android::Parcel p;
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+//xxx cfReason serviceClass number
+// mCi.queryCallForwardStatus(commandInterfaceCFReason,0,null,resp);
+int queryCallForwardStatus(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if(argc != 4)
+    {
+        RLOGD("the peremeters numbers isn't right , so return");
+        return -1;
+    }
+
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+
+    int cfReason = scToCallForwardReason(argv[1]);
+    RLOGD("queryCallForwardStatus() cfReason: %d", cfReason);
+    if(cfReason == -1) return -1;
+    p.writeInt32(2);
+    p.writeInt32(cfReason); //cfReason
+    p.writeInt32(siToServiceClass(argv[2])); //serviceClass
+    p.writeInt32(toaFromString(argv[3])); //number
+    writeStringToParcel(p, argv[3]);//number
+    p.writeInt32(0);
+
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+//xxx action cfReason serviceClass number timeSeconds
+int setCallForward(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if(argc != 6 )
+    {
+        RLOGD("the paremeters isn't enough!");
+        return -1;
+    }
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    int action = atoi(argv[1]); //status
+    int reason = scToCallForwardReason(argv[2]);
+    if(reason == -1) return -1;
+    char* number = argv[3];
+    int time = siToTime(argv[4]);
+    int serviceClass = siToServiceClass(argv[5]);
+    p.writeInt32(action); //action
+    p.writeInt32(reason); //cfReason
+    p.writeInt32(serviceClass); //serviceClass
+    p.writeInt32(toaFromString(number)); //number
+    writeStringToParcel(p, number);
+    p.writeInt32(time); //timeSeconds
+
+    p.setDataPosition(pos);
+    
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+
+
+//xxx serviceClass
+int queryCallWaiting(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if(argc != 2)
+    {
+        RLOGD("the peremeters numbers isn't right , so return");
+        return -1;
+    }
+
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    p.writeInt32(1);
+    p.writeInt32(siToServiceClass(argv[1]));//serviceClass
+
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+
+//xxx enable serviceClass
+int setCallWaiting(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if(argc != 3)
+    {
+        RLOGD("the peremeters numbers isn't right , so return");
+        return -1;
+    }
+
+
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    p.writeInt32(2);
+    p.writeInt32(atoi(argv[1])? 1 : 0);//enable
+    p.writeInt32(siToServiceClass(argv[2])); //serviceClass
+
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+//xxx facility oldPwd newPwd
+int changeBarringPassword(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if(argc != 4)
+    {
+        RLOGD("the peremeters numbers isn't right , so return");
+        return -1;
+    }
+
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    p.writeInt32(3);
+    char* facility = scToBarringFacility(argv[1]);
+    if(facility == NULL) return -1;
+    writeStringToParcel(p, facility); //facility
+    writeStringToParcel(p, (const char *)argv[2]); //oldPwd
+    writeStringToParcel(p, (const char *)argv[3]); //newPwd
+
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+//xxx enable
+int setSuppServiceNotifications(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if(argc != 2)
+    {
+        RLOGD("the peremeters numbers isn't right , so return");
+        return -1;
+    }
+
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    p.writeInt32(1);
+    p.writeInt32(atoi(argv[1])? 1 : 0);//enable
+
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+int setCLIP(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if(argc != 2)
+    {
+        RLOGD("the peremeters numbers isn't right , so return");
+        return -1;
+    }
+
+
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    p.writeInt32(1);
+    p.writeInt32(atoi(argv[1])? 1 : 0);//enable
+
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+
+}
+
+int getCOLP(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if(argc != 1)
+    {
+        RLOGD("the peremeters numbers isn't right , so return");
+        return -1;
+    }
+
+    android::Parcel p;
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+
+}
+
+int setCOLP(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if(argc != 2)
+    {
+        RLOGD("the peremeters numbers isn't right , so return");
+        return -1;
+    }
+
+
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    p.writeInt32(1);
+    p.writeInt32(atoi(argv[1])? 1 : 0);//enable
+
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+
+}
+
+int getCOLR(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if(argc != 1)
+    {
+        RLOGD("the peremeters numbers isn't right , so return");
+        return -1;
+    }
+
+    android::Parcel p;
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+
+}
+
+int queryFacilityLockForApp(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if(argc != 4)
+    {
+        RLOGD("the peremeters numbers isn't right , so return");
+        return -1;
+    }
+
+    char* facility = scToBarringFacility(argv[1]);
+    if(facility == NULL) return -1;
+
+    char *password = argv[2];
+    if(strcmp(password, "null") == 0){
+        password = "";
+    }
+
+    int serviceClassX = SERVICE_CLASS_NONE;
+    if (strcmp(facility, CB_FACILITY_BA_FD) == 0) {
+        serviceClassX = SERVICE_CLASS_VOICE + SERVICE_CLASS_DATA + SERVICE_CLASS_FAX;
+    } else if(strcmp(facility, CB_FACILITY_BA_SIM) == 0) {
+        serviceClassX = SERVICE_CLASS_VOICE + SERVICE_CLASS_DATA + SERVICE_CLASS_FAX;
+    } else {
+        serviceClassX = siToServiceClass(argv[3]);
+    }
+    char serviceclass[16] = {0};
+    sprintf(serviceclass, "%d", serviceClassX);
+
+    char* appId = "";
+    if (strcmp(facility, CB_FACILITY_BA_FD) == 0) {
+        appId = getAid(socket_id);
+    } else if(strcmp(facility, CB_FACILITY_BA_SIM) == 0) {
+        appId = getAid(socket_id);
+    }
+
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    p.writeInt32(4);
+    writeStringToParcel(p, facility);
+    writeStringToParcel(p, password);
+    writeStringToParcel(p, serviceclass);
+    writeStringToParcel(p, appId);
+
+    p.setDataPosition(pos);
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+
+int setFacilityLockForApp(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    RLOGD("setFacilityLockForApp %d: " , pRI->pCI->requestNumber);
+    if(argc != 5)
+    {
+        RLOGD("the peremeters numbers isn't right , so return");
+        return -1;
+    }
+
+
+    char* facility = scToBarringFacility(argv[1]);
+    if(facility == NULL) return -1;
+
+    char *password = argv[2];
+    if(strcmp(password, "null") == 0){
+        password = "";
+    }
+
+    int serviceClassX = SERVICE_CLASS_NONE;
+    if (strcmp(facility, CB_FACILITY_BA_FD) == 0) {
+        serviceClassX = SERVICE_CLASS_VOICE + SERVICE_CLASS_DATA + SERVICE_CLASS_FAX;
+    } else if(strcmp(facility, CB_FACILITY_BA_SIM) == 0) {
+        serviceClassX = SERVICE_CLASS_VOICE + SERVICE_CLASS_DATA + SERVICE_CLASS_FAX;
+    } else {
+        serviceClassX = siToServiceClass(argv[3]);
+    }
+    char serviceclass[16] = {0};
+    sprintf(serviceclass, "%d", serviceClassX);
+
+    char* appId = "";
+    if (strcmp(facility, CB_FACILITY_BA_FD) == 0) {
+        appId = getAid(socket_id);
+    } else if(strcmp(facility, CB_FACILITY_BA_SIM) == 0) {
+        appId = getAid(socket_id);
+    }
+
+
+    const char *lockStrings = argv[4];
+
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    p.writeInt32(5);
+    writeStringToParcel(p, facility);
+    writeStringToParcel(p, lockStrings);
+    writeStringToParcel(p, password);
+    writeStringToParcel(p, serviceclass);
+    writeStringToParcel(p, appId);
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ss.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ss.h
new file mode 100644
index 0000000..b21966e
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ss.h
@@ -0,0 +1,60 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#ifndef RIL_SS_H
+#define RIL_SS_H
+
+#include  <vendor-ril/telephony/ril.h>
+#include  "common.h"
+
+int sendUSSI(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int cancelPendingUssi(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int sendUSSD(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int cancelPendingUssd(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int getCLIR(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setCLIR(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int queryCLIP(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int queryCallForwardStatus(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setCallForward(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int queryCallWaiting(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setCallWaiting(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int changeBarringPassword(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setSuppServiceNotifications(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setCLIP(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int getCOLP(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setCOLP(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int getCOLR(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int queryFacilityLockForApp(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setFacilityLockForApp(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+#endif
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/stateManager/stateManager.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/stateManager/stateManager.cpp
new file mode 100644
index 0000000..02eb018
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/stateManager/stateManager.cpp
@@ -0,0 +1,1754 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include "stateManager/stateManager.h"
+
+#include <string>
+#include <string.h>
+#include <alloca.h>
+#include <stdlib.h>
+#include <vector>
+#include <arpa/inet.h>
+#include <string.h>
+
+#include "../util/AtLine.h"
+#include "powerManager.h"
+#include "util/utils.h"
+#include <cutils/jstring.h>
+#include <liblog/lynq_deflog.h>
+#undef LOG_TAG
+#define LOG_TAG "DEMO_MANAGER"
+
+lynqCallStatus s_callStatus = LYNQ_CALL_OFF;
+
+//static pthread_mutex_t s_startupMutex = PTHREAD_MUTEX_INITIALIZER;
+//RIL_REQUEST_DEVICE_IDENTITY
+int getDeviceIdentity(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+//  RIL_REQUEST_GET_IMEI
+int getIMEI(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+//RIL_REQUEST_GET_IMEISV
+int getIMEISV(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+//RIL_REQUEST_BASEBAND_VERSION
+int getBasebandVersion(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+//RIL_REQUEST_RESET_RADIO
+int resetRadio(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+//RIL_REQUEST_SCREEN_STATE
+int getScreenState(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+
+    p.writeInt32(1);
+    p.writeInt32(atoi(argv[1]));
+
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+//RIL_REQUEST_SET_TRM
+int setTRM(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+//  android::Parcel p;
+
+//  pRI->pCI->dispatchFunction(p, pRI);
+    free(pRI);
+    return 0;
+}
+//RIL_REQUEST_SET_IMS_ENABLE
+int setIMSEnable(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+
+    p.writeInt32(1);
+    p.writeInt32(atoi(argv[1]));
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+//RIL_REQUEST_OEM_HOOK_RAW
+int sendATCMD(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    char *cmd = (char *)argv[1];
+    size_t pos = p.dataPosition();
+    if (cmd == NULL){
+        RLOGD("sendATCMD:cmd is null\n");
+        free(pRI);
+        return -1;
+    }
+    int len = strlen(cmd);
+    p.writeInt32(len);
+    p.write((const void*)cmd,len);
+    RLOGD("sendATCMD: %s %d",cmd,strlen(cmd));
+
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+#ifdef KEEP_ALIVE
+//RIL_REQUEST_START_KEEPALIVE_PRO
+void tranferToNetByteOrder(int type, char* addr, std::vector<uint8_t> & dest) {
+    RLOGD("type is %d, addr: %s", type ,addr);
+    int ret;
+    int len = 0;
+    int domain;
+    if(type == static_cast<int>(RIL_PacketType::IPV4_TCP) || type == static_cast<int>(RIL_PacketType::IPV4_UDP)) {
+        len = sizeof(struct in_addr);
+        domain = AF_INET;
+    } else if(type == static_cast<int>(RIL_PacketType::IPV6_TCP) || type == static_cast<int>(RIL_PacketType::IPV6_UDP)) {
+        int len = sizeof(struct in6_addr);
+        domain = AF_INET6;
+    }
+    if (len > 0) {
+        unsigned char buf[len];
+        ret = inet_pton(domain, addr, &buf);
+        if (ret <= 0) {
+            if (ret == 0)
+                RLOGE("Not in presentation format");
+            else
+                RLOGE("inet_pton");
+            return;
+        }
+        for (int i = 0 ; i < len; i++ ) {
+            dest.push_back(buf[i]);
+            RLOGD("tranferToNetByteOrder[%d]: %d", i,buf[i]);
+        }
+    }
+
+}
+
+int startKeepAlivePro(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if (argc != 10){
+        RLOGD("startKeepAlivePro parameters  number isn't enough");
+        free(pRI);
+        return -1;
+    }
+    RLOGD("startKeepAlivePro");
+    std::vector<uint8_t> sourceAddress;
+    std::vector<uint8_t> destinationAddress;
+    int type = atoi(argv[1]);
+    tranferToNetByteOrder(type, argv[2], sourceAddress);
+    int sourcePort = atoi(argv[3]);
+    tranferToNetByteOrder(type, argv[4], destinationAddress);
+    int destinationPort = atoi(argv[5]);
+    int netif_id = atoi(argv[6]);
+    int keepIdleTime = atoi(argv[7]);
+    int keepIntervalTime = atoi(argv[8]);
+    int retryCount = atoi(argv[9]);
+
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+
+    p.writeInt32(type);
+    p.writeByteVector(sourceAddress);
+    p.writeInt32(sourcePort);
+    p.writeByteVector(destinationAddress);
+    p.writeInt32(destinationPort);
+    p.writeInt32(netif_id);
+    p.writeInt32(keepIdleTime);
+    p.writeInt32(keepIntervalTime);
+    p.writeInt32(retryCount);
+
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+//RIL_REQUEST_STOP_KEEPALIVE_PRO
+int stopKeepAlivePro(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if (argc != 2){
+        RLOGD("stopKeepAlivePro parameters  number isn't enough");
+        free(pRI);
+        return -1;
+    }
+    RLOGD("stopKeepAlivePro");
+    android::Parcel p;
+    uint32_t id = atoi(argv[1]);
+    RLOGD("stopKeepAlivePro sesssion id:%d", id);
+    size_t pos = p.dataPosition();
+    p.writeInt32(1);
+    p.writeInt32(id);
+
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+void composeMsg(int request,const void* data, size_t datalen) {
+    int* p_int = (int*) (data);
+    int numInts = datalen / sizeof(int);
+    if (numInts < 2) {
+        RLOGD("%s error.", android::requestToString(request));
+        std::string fail(android::requestToString(request));
+        fail.append(",fail");
+        sendKeepAlive(fail.c_str());
+        return;
+    }
+    std::string msg(android::requestToString(request));
+    if(request == RIL_REQUEST_START_KEEPALIVE_PRO) {
+        msg.append(",ok");
+    }
+    int sessionHandle = p_int[0];
+    int code = p_int[1];
+    msg.append(",");
+    msg.append(std::to_string(sessionHandle));
+    msg.append(",");
+    msg.append(std::to_string(code));
+    RLOGD("%s response(%s)", android::requestToString(request),msg.c_str());
+    sendKeepAlive(msg.c_str());
+}
+
+void handleKeepAliveResponse(int request, const void* data, size_t datalen, RIL_SOCKET_ID soc_id, bool is_error) {
+    RLOGD("handleKeepAliveResponse(%s) is_error: %d", android::requestToString(request),is_error);
+    if(is_error) {
+        if(request == RIL_REQUEST_START_KEEPALIVE_PRO) {
+            sendKeepAlive("RIL_REQUEST_START_KEEPALIVE_PRO,fail");
+        } else if(request == RIL_REQUEST_STOP_KEEPALIVE_PRO) {
+            sendKeepAlive("RIL_REQUEST_STOP_KEEPALIVE_PRO,fail");
+        }
+    } else {
+        if(request == RIL_REQUEST_START_KEEPALIVE_PRO) {
+            composeMsg(request, data, datalen);
+        } else if(request == RIL_REQUEST_STOP_KEEPALIVE_PRO) {
+            sendKeepAlive("RIL_REQUEST_STOP_KEEPALIVE_PRO,ok");
+        } else if (request == RIL_UNSOL_KEEPALIVE_STATUS_PRO) {
+            composeMsg(request, data, datalen);
+        }
+    }
+}
+#endif /*KEEP_ALIVE*/
+
+void parseAtCmd(const char* line) {
+    if (strstr(line, "+ETHERMAL") != NULL) {
+        RLOGD("parse at command: ETHERMAL");
+        AtLine* atLine = new AtLine(line, NULL);
+        int err;
+        atLine->atTokStart(&err);
+        if (err < 0) {
+            delete atLine;
+            RLOGW("this is not a valid response string");
+            return;
+        }
+        int rat = atLine->atTokNextint(&err);
+        if (err < 0) {
+            delete atLine;
+            RLOGW("parse rat fail");
+            return;
+        }
+        int temperature = atLine->atTokNextint(&err);
+        if (err < 0) {
+            delete atLine;
+            RLOGW("parse temperature fail");
+            return;
+        }
+        int tx_power = atLine->atTokNextint(&err);
+        if (err < 0) {
+            delete atLine;
+            RLOGW("parse tx_power fail");
+            return;
+        }
+        RLOGD("[tx_power]rat: %d, temperature: %d, tx_power: %d", rat, temperature, tx_power);
+        printf("[tx_power]rat: %d, temperature: %d, tx_power: %d\n", rat, temperature, tx_power);
+        delete atLine;
+    } else if (strstr(line, "+ECAL") != NULL) {
+        RLOGD("parse at command: ECAL");
+        AtLine* atLine = new AtLine(line, NULL);
+        int err;
+        atLine->atTokStart(&err);
+        if (err < 0) {
+            delete atLine;
+            RLOGW("this is not a valid response string");
+            return;
+        }
+        int cal = atLine->atTokNextint(&err);
+        if (err < 0) {
+            delete atLine;
+            RLOGW("parse rat fail");
+            return;
+        }
+        RLOGD("calibration data is %s", cal == 1 ? "download" : "not download");
+        if (cal == 0) {
+            printf(
+                    "************************************************\n*** NOTICE: calibration data is not download ***\n************************************************\n");
+        }
+        delete atLine;
+    }
+}
+//RIL_REQUEST_SET_IMSCFG
+int setIMSCfg(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+
+    p.writeInt32(6);
+    p.writeInt32(atoi(argv[1]));
+    p.writeInt32(atoi(argv[2]));
+    p.writeInt32(atoi(argv[3]));
+    p.writeInt32(atoi(argv[4]));
+    p.writeInt32(atoi(argv[5]));
+    p.writeInt32(atoi(argv[6]));
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+/*****mobiletek-add****/
+lynq_call_list **pCallList=NULL;
+//lynq_call_list *CallList=NULL;
+//callInfoLink * callInfoLinkhead = (callInfoLink *)malloc(sizeof(callInfoLink));
+//memset(callInfoLinkhead,0,sizeof(callInfoLink));
+int calllistNum=0;
+int flag=0;
+callInfoLink * create_callInfoLink()
+{
+    callInfoLink * head = (callInfoLink *)malloc(sizeof(callInfoLink));
+    if(head==NULL)
+    {
+         return NULL;
+    }
+    memset(head,0,sizeof(callInfoLink));
+    head->next=NULL;
+    head->calllist_tok=NULL;
+    //head->parcel=NULL;
+    return head;
+}
+lynqQueue * createLynqQueue()
+{
+    lynqQueue *head = (lynqQueue *)malloc(sizeof(lynqQueue));
+    if(head==NULL)
+    {
+         return NULL;
+    }
+    memset(head,0,sizeof(lynqQueue));
+    head->next=NULL;
+    return head;
+}
+lynqQueue * searchRequestinQueue(int32_t request,lynqQueue *head)
+{
+    lynqQueue *p;
+    p=head;
+    if(p!=NULL)
+    {
+       do
+       {
+           if(p->request == request)
+           {
+              return p;
+           }
+            
+           p = p->next;
+       } while (p != NULL);
+    }
+    RLOGD("search  request %d failure from lynq queue",request);
+    return NULL;
+}
+lynqQueue * searchTokeninQueue(int32_t token,lynqQueue *head)
+{
+    lynqQueue *p;
+    p=head;
+    if(p!=NULL)
+    {
+       do
+       {
+           if(p->token == token)
+           {
+              return p;
+           }
+           p = p->next;
+       } while (p != NULL);
+    }
+    LYDBGLOG("[%s] search token %x failure from lynq queue\n",__FUNCTION__,token);
+    return NULL;
+}
+int lynqApiInit()
+{
+    LynqQueueHead=createLynqQueue();
+    LYDBGLOG("[%s] init head is %p\n",__FUNCTION__,LynqQueueHead);
+    if(LynqQueueHead==NULL)
+    {
+        LYERRLOG("[%s] init call  lynq queue head fail,maybe malloc fail!",__FUNCTION__);
+        return -1;
+    }
+    return 0;
+}
+int getCallStatus(void)
+{
+    return s_callStatus;
+}
+int setCallStatus(lynqCallStatus callStatus)
+{
+    s_callStatus = callStatus;
+    return 0;
+}
+
+simInfoLink *createSimInfoLink()
+{
+    simInfoLink * head = (simInfoLink *)malloc(sizeof(simInfoLink));
+    if(head==NULL)
+    {
+         RLOGD("create sim info queue fail");
+         return NULL;
+    }
+    memset(head,0,sizeof(simInfoLink));
+    head->next=NULL;
+    return head;
+}
+int callListToParcel(void *response,size_t responselen,Parcel &p);
+static int updateCallStatus(void *response,size_t responselen);
+int imsiToParcel(int32_t request,int32_t token,void *response,size_t responselen,RIL_Errno e);
+int simInfoToParcel(int32_t request,int32_t token,void *response,size_t responselen,RIL_Errno e);
+int lastCallFailCauseToParce(int32_t request,int32_t token,void *response,size_t responselen,RIL_Errno e);
+int dataCalllistToParcel(int32_t request,int32_t token,void *response,size_t responselen,RIL_Errno e);
+int currentOperatorInfoToParcel(int32_t request,int32_t token,void *response,size_t responselen,RIL_Errno e);
+int queryNetSelectModeToParcel(int32_t request,int32_t token,void *response,size_t responselen,RIL_Errno e);
+static int stringsToParecl(int32_t request,int32_t token,void *response,size_t responselen,RIL_Errno e);
+static int stringToParecl(int32_t request,int32_t token,void *response,size_t responselen,RIL_Errno e);
+static int intToParcel(int32_t request,int32_t token,void *response,size_t responselen,RIL_Errno e);
+static int updateErrnoToQueue(int32_t request,int32_t token,void *response,size_t responselen,RIL_Errno e);
+int cellinfoToParcel(int32_t request,int32_t token,void *response,size_t responselen,RIL_Errno e);
+int neighboringCellToParcel(int32_t request,int32_t token,void *response,size_t responselen,RIL_Errno e);
+int solicitedSignalStrengthToParcel(int32_t request,int32_t token,void *response,size_t responselen,RIL_Errno e);
+int smsResponseToParcel(int32_t request,int32_t token,void *response,size_t responselen,RIL_Errno e);
+ int updateE_status(int32_t token,RIL_Errno respe)
+{
+    lynqQueue *node =NULL;
+    node = searchTokeninQueue(token,LynqQueueHead);
+    if(node)
+    {
+        node->t_Errno = respe;
+        node->E_status = 1;
+    }
+    return 0;
+}
+void LYNQ_DispatchResponse(int request,int32_t token,RIL_Errno respe,lynq_call_list**nodeCallList,void *response,size_t respLen)
+{
+
+    switch (request) {
+        case RIL_REQUEST_DIAL:
+        case RIL_REQUEST_ANSWER:
+        case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND:
+        case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND:
+        case RIL_REQUEST_SEPARATE_CONNECTION:
+        case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE:
+        case RIL_REQUEST_CONFERENCE:
+        case RIL_REQUEST_HANGUP:
+        case RIL_REQUEST_UDUB:
+        case RIL_REQUEST_DTMF:
+        {
+            /*
+            lynqQueue *node =NULL;
+            node = searchTokeninQueue(token,LynqQueueHead);
+            if(node)
+            {
+                node->t_Errno = respe;
+                node->E_status = 1;
+            }
+            */
+            updateE_status(token,respe);
+            break;
+        }
+        case RIL_REQUEST_GET_IMSI:
+        {
+            updateE_status(token,respe);
+            imsiToParcel(request,token,response,respLen,respe);
+            //addImsiInfo(request,respe,token,simInfoLinkHead,response,respLen);
+            break;
+        }
+        case RIL_REQUEST_GET_SIM_STATUS:
+        {
+            updateE_status(token,respe);
+            simInfoToParcel(request,token,response,respLen,respe);
+            break;
+        }
+        case RIL_REQUEST_LAST_CALL_FAIL_CAUSE:
+        {
+            /*
+            lynqQueue *node =NULL;
+            node = searchTokeninQueue(token,LynqQueueHead);
+            if(node)
+            {
+                node->t_Errno = respe;
+                node->E_status = 1;
+            }
+            */
+            updateE_status(token,respe);
+            lastCallFailCauseToParce(request,token,response,respLen,respe);
+            break;
+        }
+        case RIL_REQUEST_DATA_CALL_LIST:
+        {
+            dataCalllistToParcel(request,token,response,respLen,respe);
+            break;
+        }
+        case RIL_REQUEST_OPERATOR:
+        case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS:
+        case RIL_REQUEST_DATA_REGISTRATION_STATE:
+        case RIL_REQUEST_VOICE_REGISTRATION_STATE:
+        {
+            //currentOperatorInfoToParcel(request,token,response,respLen,respe);
+            updateE_status(token,respe);
+            stringsToParecl(request,token,response,respLen,respe);
+            break;
+        }
+        case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE:
+        case RIL_REQUEST_IMS_REGISTRATION_STATE:
+        case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE:
+        case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE:
+        case RIL_REQUEST_VOICE_RADIO_TECH:
+        case RIL_REQUEST_WRITE_SMS_TO_SIM:
+        {
+            intToParcel(request,token,response,respLen,respe);
+            break;
+        }
+        case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC:
+        case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL:
+        case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE:
+        case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE:
+        case RIL_REQUEST_SET_BAND_MODE:
+        case RIL_REQUEST_RADIO_POWER:
+        case RIL_REQUEST_MODEM_POWERON:
+        case RIL_REQUEST_MODEM_POWEROFF:
+        case RIL_REQUEST_DELETE_SMS_ON_SIM:
+        case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS:
+        case RIL_REQUEST_SET_SMSC_ADDRESS:
+        {
+            updateErrnoToQueue(request,token,response,respLen,respe);
+            break;
+        }
+        case RIL_REQUEST_GET_CELL_INFO_LIST:
+        {
+            cellinfoToParcel(request,token,response,respLen,respe);
+            break;
+        }
+        case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS:
+        {
+            neighboringCellToParcel(request,token,response,respLen,respe);
+            break;
+        }
+        case RIL_REQUEST_SIGNAL_STRENGTH:
+        {
+            solicitedSignalStrengthToParcel(request,token,response,respLen,respe);
+            break;
+        }
+        case RIL_REQUEST_SEND_SMS:
+        case RIL_REQUEST_IMS_SEND_SMS:
+        {
+            smsResponseToParcel(request,token,response,respLen,respe);
+            break;
+        }
+        case RIL_REQUEST_GET_SMSC_ADDRESS:
+        {
+            stringToParecl(request,token,response,respLen,respe);
+            break;
+        }
+        default:
+            break;
+        }
+}
+callInfoLink* addCallInfo(int32_t tok,int request,RIL_Errno respe,callInfoLink* head,lynq_call_list**nodeCallList)
+{
+    if (head == NULL)
+    {
+         flag= 0;
+         RLOGD("callInfoLink is null,set flag to 0!");
+        return NULL;
+    }
+    if (flag == 0) 
+    {
+        head->token = tok;
+        head->Error_tok = respe;
+        head->request=request;
+        if(nodeCallList!=NULL)
+        {
+            head->calllist_tok=nodeCallList;
+        }
+        head->next = NULL;
+        flag=1;
+    }
+    else
+    {
+        if (head->token != tok)
+        {
+            callInfoLink* Node = (callInfoLink*)malloc(sizeof(callInfoLink));
+            memset(Node,0,sizeof(callInfoLink));
+            if (Node)
+            {
+                printf("new node p is %p\n", Node);
+                Node->token = tok;
+                Node->Error_tok = respe;
+                Node->request=request;
+                if(nodeCallList!=NULL)
+                {
+                    Node->calllist_tok=nodeCallList;
+                }
+                Node->next = head;
+                head = Node;
+            }
+            else 
+            {
+                RLOGD("malloc Node failed!\n");
+                flag = 0;
+                return NULL;
+            }
+        }
+        else
+        {
+            //head->token = tok;
+            //head->Error_tok = respe;
+            head->calllist_tok=nodeCallList;
+        }
+
+    }
+    return head;
+}
+void updateLinkCallInfo(callInfoLink * callInfoLinkhead,lynq_call_list**nodeCallList)
+{
+    callInfoLink *p;
+    p=callInfoLinkhead;
+    if(p!=NULL)
+    {
+       do
+       {
+           p->calllist_tok=nodeCallList;
+           p = p->next;
+       } while (p != NULL);
+    }
+}
+static int dispatchEvent(lynqQueue *node,void * response, size_t responselen, Parcel & p)
+{
+    //printf("request is %d\n",node->request);
+    switch(node->request)
+    {
+        case RIL_REQUEST_DIAL:
+        case RIL_REQUEST_ANSWER:
+        //case RIL_REQUEST_HANGUP:
+        //case RIL_REQUEST_UDUB:
+        case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND:
+        case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND:
+        case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE:
+        case RIL_REQUEST_CONFERENCE:
+        //case RIL_REQUEST_SEPARATE_CONNECTION:
+        //case RIL_REQUEST_DTMF:
+        {
+            //printf("request is %d\n",node->request);
+            callListToParcel(response, responselen, p);
+            break;
+        }
+        /*
+        case RIL_REQUEST_HANGUP:
+        {
+            break;
+        }
+        */
+        default:
+            //printf("other test\n");
+            //updateCallStatus(response,responselen);
+            break;
+    }
+     return 0;
+}
+void updateAsyncData(RIL_Token t, RIL_Errno e,void * response, size_t responselen,lynqQueue* head)
+{
+    lynqQueue *p;
+    p=head;
+    if(p!=NULL)
+    {
+       do
+       {
+           dispatchEvent(p, response,responselen, p->parcel);
+           p = p->next;
+       } while (p != NULL);
+    }
+    updateCallStatus(response,responselen);
+    return;
+}
+void printlist(callInfoLink * callInfoLinkhead)
+{
+    callInfoLink* p;
+    p = callInfoLinkhead;
+    if (p != NULL)
+    {
+        do
+        {
+            LYDBGLOG("[%s] token=%x Error_tok=%d,request =%d",__FUNCTION__,p->token, p->Error_tok,p->request);
+            p = p->next;
+        } while (p != NULL);
+    }
+    return ;
+}
+void setCallList_old(int token,RIL_Call **pCallLists,size_t respLen,RIL_Errno error)
+{
+    /*
+    if(pCallLists!=NULL)
+    {
+        printf("DEMO_MANAGER:resplen is %d\n",respLen);
+        for(int i=0;i<respLen;i++)
+        {
+            RIL_Call* p_cur = pCallLists[i];
+            printf("state is %d\n",p_cur->state);
+            RLOGD("state is %d\n",p_cur->state);
+            printf("callid is %d\n",p_cur->index);
+            RLOGD("callid is %d\n",p_cur->index);
+            printf("toa is %d\n",p_cur->toa);
+            RLOGD("toa is %d\n",p_cur->toa);
+            printf("addr is %s\n",p_cur->number);
+            RLOGD("addr is %s\n",p_cur->number);
+        }
+    }
+    */
+    if(calllistNum!=0)
+    {
+        printf("calllistNum!=0\n");
+        RLOGD("calllistNum!=0\n");
+        if(calllistNum!=respLen)
+        {
+            if (pCallList != NULL)
+            {
+                for (int index = 0; index < calllistNum; index++ ) 
+                {
+                    if (pCallList[index] != NULL) 
+                    {
+                        free(pCallList[index]->addr);
+                        pCallList[index]->addr=NULL;
+                        free(pCallList[index]);
+                    }
+                }
+            free(pCallList);
+            pCallList=NULL;
+            RLOGD("free pCalllist\n");
+          }
+        if(respLen==0)
+        {
+           RLOGD("the call list is NULL,the pCalllist is NULL");
+           return;
+        }
+        if(!(pCallList=(lynq_call_list **)malloc(sizeof(lynq_call_list *)*respLen)))
+        {
+            RLOGD("malloc pCallList failed");
+            printf("malloc pCallList failed");
+            return;
+        }
+        
+        for(int index=0;index<respLen;index++)
+        {
+            if((pCallList[index]=(lynq_call_list *)malloc(sizeof(lynq_call_list)))==NULL)
+            {    
+                RLOGD("malloc CallList failed");
+                printf("malloc CallList failed");
+                for(int i=0;i<index;i++)
+                {
+                    free(pCallList[i]->addr);
+                    pCallList[i]->addr=NULL;
+                    free(pCallList[i]);
+                }
+                free(pCallList);
+                pCallList=NULL;
+                return;
+            }
+            pCallList[index]->addr=(char *)malloc(sizeof(char)*(sizeof(pCallLists[index]->number)+1));
+            memcpy(pCallList[index]->addr, pCallLists[index]->number, strlen(pCallLists[index]->number)+1);
+            pCallList[index]->token=token;
+            //pCallList[index]->addr=pCallLists[index]->number;
+            pCallList[index]->callid=pCallLists[index]->index;
+            pCallList[index]->callState=pCallLists[index]->state;
+            pCallList[index]->toa= pCallLists[index]->toa;
+            pCallList[index]->lynq_error=error;
+            pCallList[index]->selflen=respLen;
+            
+        }
+        calllistNum=respLen;
+      }
+      else
+      {
+        for(int index=0;index<respLen;index++)
+        {
+            pCallList[index]->addr=(char *)malloc(sizeof(char)*(sizeof(pCallLists[index]->number)+1));
+            memcpy(pCallList[index]->addr, pCallLists[index]->number, strlen(pCallLists[index]->number)+1);
+            pCallList[index]->token=token;
+            //pCallList[index]->addr=pCallLists[index]->number;
+            pCallList[index]->callid=pCallLists[index]->index;
+            pCallList[index]->callState=pCallLists[index]->state;
+            pCallList[index]->toa= pCallLists[index]->toa;
+            pCallList[index]->lynq_error=error;
+            pCallList[index]->selflen=respLen;
+        }
+      }
+      printf("retrun more than once\n");
+      ///pthread_mutex_unlock(&s_startupMutex);
+    }
+    else
+    {
+        RLOGD("calllistNum==0\n");
+        if((pCallList=(lynq_call_list **)malloc(sizeof(lynq_call_list *)*respLen))==NULL)
+        {
+            RLOGD("malloc pCallList failed");
+            printf("malloc pCallList failed");
+            return;
+        }
+        printf("pCalllist %p\n",pCallList);
+        for(int index=0;index<respLen;index++)
+        {
+            if((pCallList[index]=(lynq_call_list *)malloc(sizeof(lynq_call_list)))==NULL)
+            {    
+                RLOGD("malloc CallList failed");
+                printf("malloc CallList failed");
+                for(int i=0;i<index;i++)
+                {
+                    free(pCallList[i]->addr);
+                    pCallList[i]->addr=NULL;
+                    free(pCallList[i]);
+                }
+                free(pCallList);
+                pCallList=NULL;
+                return;
+            }
+            pCallList[index]->addr=(char *)malloc(sizeof(char)*(sizeof(pCallLists[index]->number)+1));
+            memcpy(pCallList[index]->addr, pCallLists[index]->number, strlen(pCallLists[index]->number)+1);
+            pCallList[index]->token=token;
+            //pCallList[index]->addr=pCallLists[index]->number;
+            pCallList[index]->callid=pCallLists[index]->index;
+            pCallList[index]->callState=pCallLists[index]->state;
+            pCallList[index]->toa= pCallLists[index]->toa;
+            pCallList[index]->lynq_error=error;
+            pCallList[index]->selflen=respLen;
+            
+        }
+        calllistNum=respLen;
+        printf("retrun first\n");
+        //pthread_mutex_unlock(&s_startupMutex);
+    }
+}
+static void StringWriteToParcel(Parcel &p, const char *s) {
+    char16_t *s16;
+    size_t s16_len;
+    s16 = strdup8to16(s, &s16_len);
+    p.writeString16(s16, s16_len);
+    free(s16);
+}
+char * lynqStrdupReadString(Parcel &p) {
+    size_t stringlen;
+    const char16_t *s16;
+
+    s16 = p.readString16Inplace(&stringlen);
+    return strndup16to8(s16, stringlen);
+}
+void setCallList(int token,RIL_Call **pCallLists,size_t respLen,RIL_Errno error)
+{
+    if(respLen==0)
+    {
+          LYDBGLOG("[%s] the call list is NULL",__FUNCTION__);
+          return;
+     }
+    if((pCallList=(lynq_call_list **)malloc(sizeof(lynq_call_list *)*respLen))==NULL)
+    {
+        LYDBGLOG("[%s] malloc pCallList failed",__FUNCTION__);
+        return;
+    }
+    //printf("pCalllist %p\n",pCallList);
+    for(int index=0;index<respLen;index++)
+    {
+        if((pCallList[index]=(lynq_call_list *)malloc(sizeof(lynq_call_list)))==NULL)
+        {    
+            LYDBGLOG("[%s]malloc CallList failed",__FUNCTION__);
+            for(int i=0;i<index;i++)
+            {
+                free(pCallList[i]->addr);
+                pCallList[i]->addr=NULL;
+                free(pCallList[i]);
+            }
+            free(pCallList);
+            pCallList=NULL;
+            return;
+        }
+        pCallList[index]->addr=(char *)malloc(sizeof(char)*(sizeof(pCallLists[index]->number)+1));
+        memcpy(pCallList[index]->addr, pCallLists[index]->number, strlen(pCallLists[index]->number)+1);
+        pCallList[index]->token=token;
+        pCallList[index]->callid=pCallLists[index]->index;
+        pCallList[index]->callState=pCallLists[index]->state;
+        pCallList[index]->toa= pCallLists[index]->toa;
+        pCallList[index]->lynq_error=error;
+        pCallList[index]->isMT = pCallLists[index]->isMT;
+        pCallList[index]->selflen=respLen;
+   }
+}
+void freeCallList(int respLen)
+{
+    if(respLen!=0)
+    {    
+        LYDBGLOG("call on going");
+        return;
+    }
+    if (pCallList != NULL)
+    {
+       if (pCallList[0]==NULL)
+       {
+           LYDBGLOG("pCalllist pCallList[0]");
+           return;
+       }
+        int length=pCallList[0]->selflen;
+        for (int index = 0; index < length; index++ ) 
+        {
+            if (pCallList[index] != NULL) 
+            {
+                free(pCallList[index]->addr);
+                pCallList[index]->addr=NULL;
+                free(pCallList[index]);
+            }
+        }
+    free(pCallList);
+    pCallList=NULL;
+    LYDBGLOG("free pCalllist");
+    }
+    return ;
+    
+}
+void updateSimStatus(void *response,size_t respLen,simInfoLink *msg)
+{
+    if(response!=NULL)
+    {
+        //printf("RIL_CardStatus_v6 length is %d\n",sizeof (RIL_CardStatus_v6));
+        if (respLen == sizeof (RIL_CardStatus_v6)) 
+        {
+            RIL_CardStatus_v6 *p_cur = ((RIL_CardStatus_v6 *) response);
+            msg->card_status=p_cur->card_state;
+            for(int i=0;i<p_cur->num_applications;i++)
+            {
+                msg->card_type=p_cur->applications[i].app_type;
+                msg->pin_state=p_cur->applications[i].pin1;
+            }
+        }
+    }
+return;
+}
+void addSimInfo(int request,RIL_Errno respe,int32_t token,simInfoLink *head,void *response,size_t respLen)
+{
+    if(head==NULL)
+    {
+        LYDBGLOG("[%s] the head is NULL!\n",__FUNCTION__);
+        return;
+    }
+    LYDBGLOG("addSimInfo respLen is %d\n",respLen);
+    if(response==NULL)
+    {
+        LYDBGLOG("the get sim status response is NULL!\n");
+        return;
+    }
+    simInfoLink * temp=head;
+    do
+    {
+        if(temp->token==token)
+        {
+            temp->Error_tok=respe;
+            updateSimStatus(response,respLen,temp);
+            temp->simInfoLen=respLen/sizeof(RIL_CardStatus_v6);
+            break;
+        }
+        temp=temp->next;
+    }while(temp!=NULL);
+    return;
+}
+simInfoLink * inSimQueue(int request,int32_t token,simInfoLink *head)
+{
+    simInfoLink* Node = (simInfoLink*)malloc(sizeof(simInfoLink));
+    memset(Node,0,sizeof(simInfoLink));
+    if (Node)
+    {
+        Node->token = token;
+        Node->request=request;
+        Node->next = head;
+        head = Node;
+    }
+    else 
+    {
+        LYDBGLOG("[%s] malloc Node failed!\n",__FUNCTION__);
+        return NULL;
+    }
+    return head;
+
+}
+static lynqQueue * lynqInQueue(int request,int32_t token,lynqQueue *head)
+{
+    lynqQueue* Node = (lynqQueue*)malloc(sizeof(lynqQueue));
+    memset(Node,0,sizeof(lynqQueue));
+    if (Node)
+    {
+        Node->token = token;
+        Node->request=request;
+        Node->next = head;
+        head = Node;
+        LYDBGLOG("[%s] node->token is %x,request is %d\n",__FUNCTION__,Node->token,Node->request);
+    }
+    else 
+    {
+        LYDBGLOG("[%s] malloc Node failed!\n",__FUNCTION__);
+        return head;
+    }
+    return head;
+
+}
+simInfoLink * deSimQueue(simInfoLink *head,int32_t token)
+{
+    simInfoLink *p,*temp;
+    p = head;
+    if((head ==NULL)||(head->next==NULL))
+    {
+        LYDBGLOG("deSimQueue head is NULL\n");
+        return head;
+    }
+    //delete head note
+    if(p->token == token)
+    {
+        temp=head->next;
+        free(head);
+        head =NULL;
+        head = temp;
+        return head;
+    }
+    //delete intermediate node
+    do
+    {
+        temp = p;
+        p=p->next;
+        if(p->token==token)
+        {
+            temp->next=p->next;
+            free(p);
+            p=NULL;
+            return head;
+        }
+    }while(p->next->next!=NULL);
+    return head;
+}
+void lynqDeQueue(int32_t token)
+{
+    lynqQueue *p,*temp;
+    p = LynqQueueHead;
+    if((p ==NULL)||(p->next==NULL))
+    {
+        LYDBGLOG("[%s] lynqDeQueue head is NULL\n",__FUNCTION__);
+        return 0;
+        //return head;
+    }
+    //delete head note
+    if(p->token == token)
+    {
+        temp=p->next;
+        free(p);
+        p =NULL;
+        LynqQueueHead = temp;
+        LYDBGLOG("[%s] delete head note!!\n",__FUNCTION__);
+        return 0;
+        //return head;
+    }
+    //delete intermediate node
+    do
+    {
+        temp = p;
+        p=p->next;
+        if(p->token==token)
+        {
+            temp->next=p->next;
+            free(p);
+            p=NULL;
+            LYDBGLOG("[%s] delete intermediate node!!\n",__FUNCTION__);
+            //return head;
+            return 0;
+        }
+    }while(p->next->next!=NULL);
+    LYDBGLOG("[%s] Not find this token,token is %d!!\n",__FUNCTION__,token);
+    return 0;
+}
+void LYNQ_DispatchRequest(int32_t request,int32_t token)
+{
+    switch(request)
+    {
+    //SIM CONTROLLER
+        case RIL_REQUEST_GET_SIM_STATUS:
+        case RIL_REQUEST_GET_IMSI:
+    //CC CONTROLLER
+        case RIL_REQUEST_DIAL:
+        case RIL_REQUEST_ANSWER:
+        case RIL_REQUEST_LAST_CALL_FAIL_CAUSE:
+        case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND:
+        case RIL_REQUEST_HANGUP:
+        case RIL_REQUEST_UDUB:
+        case RIL_REQUEST_DTMF:
+        case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND:
+        case RIL_REQUEST_SEPARATE_CONNECTION:
+        case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE:
+        case RIL_REQUEST_CONFERENCE:
+    //DATA CONTROLLER
+        //case RIL_REQUEST_SETUP_DATA_CALL:
+        case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE:
+        case RIL_REQUEST_DATA_CALL_LIST:
+    //NETWORK CONTROLLER
+        case RIL_REQUEST_OPERATOR:
+        case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE:
+        case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC:
+        case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL:
+        case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS:
+        case RIL_REQUEST_DATA_REGISTRATION_STATE:
+        case RIL_REQUEST_VOICE_REGISTRATION_STATE:
+        case RIL_REQUEST_IMS_REGISTRATION_STATE:
+        case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE:
+        case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE:
+        case RIL_REQUEST_GET_CELL_INFO_LIST:
+        case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE:
+        case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS:
+        case RIL_REQUEST_SET_BAND_MODE:
+        case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE:
+        case RIL_REQUEST_RADIO_POWER:
+        case RIL_REQUEST_VOICE_RADIO_TECH:
+        case RIL_REQUEST_SIGNAL_STRENGTH:
+        case RIL_REQUEST_MODEM_POWEROFF:
+        case RIL_REQUEST_MODEM_POWERON:
+    //SMS CONTROLLER
+        case RIL_REQUEST_SEND_SMS:
+        case RIL_REQUEST_IMS_SEND_SMS:
+        case RIL_REQUEST_WRITE_SMS_TO_SIM:
+        case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS:
+        case RIL_REQUEST_DELETE_SMS_ON_SIM:
+        case RIL_REQUEST_GET_SMSC_ADDRESS:
+        case RIL_REQUEST_SET_SMSC_ADDRESS:
+        {
+            //simInfoLinkHead=inSimQueue(request, token, simInfoLinkHead);
+            LynqQueueHead = lynqInQueue(request,token,LynqQueueHead);
+            break;
+        }
+        default:
+            break;
+    }
+    return;
+}
+void addImsiInfo(int request,RIL_Errno respe,int32_t token,simInfoLink *head,void *response,size_t respLen)
+{
+    if(head==NULL)
+    {
+        LYDBGLOG("[addImsiInfo] the head is NULL!\n");
+        return;
+    }
+    LYDBGLOG("addImsiInfo respLen is %d\n",respLen);
+    if(response==NULL)
+    {
+        LYDBGLOG("the get IMSI response is NULL!\n");
+        return;
+    }
+    simInfoLink * temp=head;
+    do
+    {
+        if(temp->token==token)
+        {
+            temp->Error_tok=respe;
+            memcpy(temp->imsi,((char *)response),respLen+1);
+            //temp->imsi = (char *)response;
+            temp->simInfoLen=respLen/strlen((char*)response);
+            break;
+        }
+        temp=temp->next;
+    }while(temp!=NULL);
+    return;
+}
+static int updateCallStatus(void *response,size_t responselen)
+{
+    if(response ==NULL||responselen==0)
+    {
+        s_callStatus=LYNQ_CALL_OFF;
+        LYDBGLOG("[%s] update call status to call off\n",__FUNCTION__);
+    }
+    return 0;
+}
+int callListToParcel(void *response,size_t responselen,Parcel &p)
+{
+    int num;
+    if (response == NULL && responselen != 0) {
+        LYDBGLOG("[%s] invalid response: NULL\n",__FUNCTION__);
+        s_callStatus=LYNQ_CALL_OFF;
+        return -1;
+    }
+    if(response ==NULL)
+    {
+        s_callStatus=LYNQ_CALL_OFF;
+        LYDBGLOG("[%s] update call state to CALL_OFF!\n",__FUNCTION__);
+    }
+    if (responselen % sizeof (RIL_Call *) != 0) {
+        LYDBGLOG("responseCallList: invalid response length %d expected multiple of %d\n",
+            (int)responselen, (int)sizeof (RIL_Call *));
+        s_callStatus=LYNQ_CALL_OFF;
+        return -1;
+    }
+    /* number of call info's */
+    num = responselen / sizeof(RIL_Call *);
+    p.setDataPosition(0);
+    p.writeInt32(num);
+    for (int i = 0 ; i < num ; i++) 
+    {
+        RIL_Call *p_cur = ((RIL_Call **) response)[i];
+        /* each call info */
+        p.writeInt32(p_cur->state);
+        //printf("callListToParcel state is %d\n",p_cur->state);
+        p.writeInt32(p_cur->index);
+        p.writeInt32(p_cur->toa);
+        p.writeInt32(p_cur->isMpty);
+        p.writeInt32(p_cur->isMT);
+        StringWriteToParcel(p, p_cur->number);
+        s_callStatus=LYNQ_CALL_ON;
+        //printf("----parcel write success----\n");
+    }
+    return 0;
+}
+int imsiToParcel(int32_t request,int32_t token,void *response,size_t responselen,RIL_Errno e)
+{
+    int num;
+    lynqQueue * node;
+    if (response == NULL && responselen != 0) {
+        LYDBGLOG("[%s] invalid response: NULL\n",__FUNCTION__);
+        return -1;
+    }
+    if(responselen ==0)
+    {
+        LYDBGLOG("[%s] get imsi fail\n");
+        return -1;
+    }
+    /* number of imsi info's */
+    node = searchTokeninQueue(token,LynqQueueHead);
+    if(node==NULL)
+    {
+        LYDBGLOG("[%s] search token %x failure from lynq queue\n",__FUNCTION__,token);
+        return -1;
+    }
+    node->t_Errno = e;
+    num=responselen/strlen((char*)response);
+    node->parcel.writeInt32(num);
+    for (int i = 0 ; i < num ; i++) 
+    {
+        StringWriteToParcel(node->parcel, response);
+        LYDBGLOG("[%s] parcel write success\n",__FUNCTION__);
+    }
+    return 0;
+}
+int simInfoToParcel(int32_t request,int32_t token,void *response,size_t responselen,RIL_Errno e)
+{
+    int num;
+    lynqQueue * node;
+    if (response == NULL && responselen != 0) {
+        LYDBGLOG("[%s] invalid response: NULL\n",__FUNCTION__);
+        return -1;
+    }
+    if(responselen ==0)
+    {
+        LYDBGLOG("[%s] get sim fail\n",__FUNCTION__);
+        return -1;
+    }
+    /* number of imsi info's */
+    node = searchTokeninQueue(token,LynqQueueHead);
+    if(node==NULL)
+    {
+        LYDBGLOG("[%s] simInfoToParcel search token %d failure from lynq queue\n",__FUNCTION__,token);
+        return -1;
+    }
+    node->t_Errno = e;
+    if (responselen == sizeof (RIL_CardStatus_v6)) 
+    {
+        RIL_CardStatus_v6 *p_cur = ((RIL_CardStatus_v6 *) response);
+        node->parcel.writeInt32(p_cur->card_state);
+        node->parcel.writeInt32(p_cur->num_applications);
+        for(int i=0;i<p_cur->num_applications;i++)
+        {
+            node->parcel.writeInt32(p_cur->applications[i].app_type);
+            node->parcel.writeInt32(p_cur->applications[i].pin1);
+            LYDBGLOG("[%s] parcel write success\n",__FUNCTION__);
+        }
+    }
+    return 0;
+}
+int lastCallFailCauseToParce(int32_t request,int32_t token,void *response,size_t responselen,RIL_Errno e)
+{
+    int num;
+    lynqQueue * node;
+    if (response == NULL && responselen != 0) {
+        LYDBGLOG("[%s] invalid response: NULL\n",__FUNCTION__);
+        return -1;
+    }
+    if(responselen ==0)
+    {
+        LYDBGLOG("get last call fail cause fail\n");
+        return -1;
+    }
+    /* number of imsi info's */
+    node = searchTokeninQueue(token,LynqQueueHead);
+    if(node==NULL)
+    {
+        LYDBGLOG("[%s] search token %x failure from lynq queue\n",__FUNCTION__,token);
+        return -1;
+    }
+    node->t_Errno = e;
+    node->parcel.writeInt32(responselen);
+    RIL_LastCallFailCauseInfo *p_cur = (RIL_LastCallFailCauseInfo *)response;
+    //num=responselen/strlen((char*)response);
+    node->parcel.writeInt32(p_cur->cause_code);
+    StringWriteToParcel(node->parcel, p_cur->vendor_cause);
+    LYDBGLOG("[%s] parcel write success\n",__FUNCTION__);
+    return 0;
+
+}
+int dataCalllistToParcel(int32_t request,int32_t token,void *response,size_t responselen,RIL_Errno e)
+{
+    int num;
+    lynqQueue * node;
+    if (response == NULL && responselen != 0) {
+        LYDBGLOG("[%s] invalid response: NULL\n",__FUNCTION__);
+        return -1;
+    }
+    if(responselen ==0)
+    {
+        RLOGD("get data call list fail\n");
+        return -1;
+    }
+    /* number of data call list info's */
+    node = searchTokeninQueue(token,LynqQueueHead);
+    if(node==NULL)
+    {
+        LYDBGLOG("[%s] search token %x failure from lynq queue\n",__FUNCTION__,token);
+        return -1;
+    }
+    node->t_Errno = e;
+    num = responselen/sizeof(RIL_Data_Call_Response_v11);
+    node->parcel.writeInt32(num);
+    RIL_Data_Call_Response_v11 *p_cur = (RIL_Data_Call_Response_v11 *)response;
+    for(int i=0;i<num;i++)
+    {
+        //RIL_Data_Call_Response_v11 *p_cur = (RIL_Data_Call_Response_v11 *)response;
+        node->parcel.writeInt32(p_cur[i].status);
+        node->parcel.writeInt32(p_cur[i].suggestedRetryTime);
+        node->parcel.writeInt32(p_cur[i].cid);
+        node->parcel.writeInt32(p_cur[i].active);
+        StringWriteToParcel(node->parcel, p_cur[i].type);
+        StringWriteToParcel(node->parcel, p_cur[i].ifname);
+        StringWriteToParcel(node->parcel, p_cur[i].addresses);
+        StringWriteToParcel(node->parcel, p_cur[i].dnses);
+        StringWriteToParcel(node->parcel, p_cur[i].gateways);
+        StringWriteToParcel(node->parcel, p_cur[i].pcscf);
+        node->parcel.writeInt32(p_cur[i].mtu);
+    }
+    LYDBGLOG("[%s] parcel write success\n",__FUNCTION__);
+    return 0;
+
+}
+int currentOperatorInfoToParcel(int32_t request,int32_t token,void *response,size_t responselen,RIL_Errno e)
+{
+    int num;
+    lynqQueue * node;
+    char **pString=NULL;
+    char * subString=NULL;
+    if (response == NULL && responselen != 0) {
+        LYDBGLOG("[%s] invalid response: NULL\n",__FUNCTION__);
+        return -1;
+    }
+    if(responselen ==0)
+    {
+        RLOGD("response is null\n");
+        return -1;
+    }
+    node = searchTokeninQueue(token,LynqQueueHead);
+    if(node==NULL)
+    {
+        LYDBGLOG("[%s] search token %x failure from lynq queue\n",__FUNCTION__,token);
+        return -1;
+    }
+    num = responselen/(sizeof(char*));
+    LYDBGLOG("currentOperatorInfoToParcel is %d\n",num);
+    node->t_Errno = e;
+    pString=(char **)response;
+    node->parcel.writeInt32(num);
+    for (int i=0;i<num;i++)
+    {
+        subString = pString[i];
+        LYDBGLOG("[%s] subString is %s\n",__FUNCTION__,subString);
+        StringWriteToParcel(node->parcel,subString);
+    }
+    LYDBGLOG("[%s] parcel write success\n",__FUNCTION__);
+    return 0;
+
+}
+//int queryNetSelectModeToParcel(int32_t request,int32_t token,void *response,size_t responselen,RIL_Errno e);
+static int stringsToParecl(int32_t request,int32_t token,void *response,size_t responselen,RIL_Errno e)
+{
+    int num;
+    lynqQueue * node;
+    char **pString=NULL;
+    char * subString=NULL;
+    if (response == NULL && responselen != 0){
+        LYDBGLOG("[%s] invalid response: NULL\n",__FUNCTION__);
+        return -1;
+    }
+    if(responselen ==0)
+    {
+        LYDBGLOG("response is null\n");
+        node = searchTokeninQueue(token,LynqQueueHead);
+        if(node==NULL)
+        {
+            LYDBGLOG("[%s] search token %x failure from lynq queue\n",__FUNCTION__,token);
+            return -1;
+        }
+        node->parcel.writeInt32(0);
+        node->t_Errno = e;
+        return -1;
+    }
+    node = searchTokeninQueue(token,LynqQueueHead);
+    if(node==NULL)
+    {
+        LYDBGLOG("[%s][%d] search token %x failure from lynq queue\n",__FUNCTION__,__LINE__,token);
+        return -1;
+    }
+    num = responselen/(sizeof(char*));
+    node->t_Errno = e;
+    pString=(char **)response;
+    node->parcel.writeInt32(num);
+    for (int i=0;i<num;i++)
+    {
+        subString = pString[i];
+        LYDBGLOG("[%s] subString is %s\n",__FUNCTION__,subString);
+        StringWriteToParcel(node->parcel,subString);
+    }
+    LYDBGLOG("[%s] parcel write success\n",__FUNCTION__);
+    return 0;
+}
+static int stringToParecl(int32_t request,int32_t token,void *response,size_t responselen,RIL_Errno e)
+{
+    int num;
+    lynqQueue * node;
+    char *pString=NULL;
+    node = searchTokeninQueue(token,LynqQueueHead);
+    if(node==NULL)
+    {
+        LYDBGLOG("[%s] search token %x failure from lynq queue\n",__FUNCTION__,token);
+        return -1;
+    }
+    node->t_Errno = e;
+    if (response == NULL && responselen != 0){
+        LYDBGLOG("[%s] invalid response: NULL\n",__FUNCTION__);
+        return -1;
+    }
+    if(responselen ==0)
+    {
+        LYDBGLOG("[%s] response is null\n",__FUNCTION__);
+        node->parcel.writeInt32(0);
+        return -1;
+    }
+    pString=(char *)response;
+    node->parcel.writeInt32(1);
+    StringWriteToParcel(node->parcel,pString);
+    LYDBGLOG("[%s] parcel write success\n",__FUNCTION__);
+    return 0;
+}
+
+static int intToParcel(int32_t request, int32_t token, void * response, size_t responselen, RIL_Errno e)
+{
+    int num;
+    lynqQueue * node;
+    int *pInts=NULL;
+    node = searchTokeninQueue(token,LynqQueueHead);
+    if(node==NULL)
+    {
+        LYDBGLOG("[%s] search token %x failure from lynq queue\n",__FUNCTION__,token);
+        return -1;
+    }
+    node->t_Errno = e;
+    if (response == NULL && responselen != 0){
+        LYDBGLOG("[%s] invalid response: NULL\n",__FUNCTION__);
+        return -1;
+    }
+    if(responselen ==0)
+    {
+        LYDBGLOG("[%s] response is null\n",__FUNCTION__);
+        node->parcel.writeInt32(0);
+        return -1;
+    }
+    num = responselen/(sizeof(int));
+    //printf("intToParcel is %d\n",num);
+    pInts=(int*)response;
+    node->parcel.writeInt32(num);
+    for (int i=0;i<num;i++)
+    {
+        //printf("subints is %d\n",pInts[i]);
+        node->parcel.writeInt32(pInts[i]);
+    }
+    LYDBGLOG("[%s] parcel write success\n",__FUNCTION__);
+    return 0;
+}
+static int updateErrnoToQueue(int32_t request,int32_t token,void *response,size_t responselen,RIL_Errno e)
+{
+    int status=0;//something change
+    lynqQueue * node;
+    node = searchTokeninQueue(token,LynqQueueHead);
+    if(node==NULL)
+    {
+        LYDBGLOG("[%s] search token %x failure from lynq queue\n",__FUNCTION__,token);
+        return -1;
+    }
+    status =1;
+    node->t_Errno=e;
+    node->parcel.writeInt32(status);
+    LYDBGLOG("[%s,%d] end!!! \n",__FUNCTION__,__LINE__);
+    return 0;
+}
+int cellinfoToParcel(int32_t request,int32_t token,void *response,size_t responselen,RIL_Errno e)
+{
+    int num = 0;
+    lynqQueue * node;
+    node = searchTokeninQueue(token,LynqQueueHead);
+    if(node==NULL)
+    {
+        LYDBGLOG("[%s] search token %x failure from lynq queue\n",__FUNCTION__,token);
+        return -1;
+    }
+    node->t_Errno = e;
+    if (response == NULL && responselen != 0) {
+        LYDBGLOG("[%s] invalid response: NULL\n",__FUNCTION__);
+        return -1;
+    }
+    if(responselen ==0)
+    {
+        LYDBGLOG("[%s] response is null\n",__FUNCTION__);
+        node->parcel.writeInt32(0);
+        return -1;
+    }
+    num = responselen/sizeof(RIL_CellInfo);
+    node->parcel.writeInt32(num);
+    RIL_CellInfo *p_cur = (RIL_CellInfo *)response;
+    for (int i = 0; i< num; i++) {
+    node->parcel.writeInt32(p_cur[i].cellInfoType);
+    node->parcel.writeInt32(p_cur[i].registered);
+    node->parcel.writeInt32(p_cur[i].timeStampType);
+    node->parcel.writeInt64(p_cur[i].timeStamp);
+    switch(p_cur[i].cellInfoType) {
+        case RIL_CELL_INFO_TYPE_GSM: {
+            node->parcel.writeInt32(p_cur[i].CellInfo.gsm.cellIdentityGsm.mcc);
+            node->parcel.writeInt32(p_cur[i].CellInfo.gsm.cellIdentityGsm.mnc);
+            node->parcel.writeInt32(p_cur[i].CellInfo.gsm.cellIdentityGsm.lac);
+            node->parcel.writeInt32(p_cur[i].CellInfo.gsm.cellIdentityGsm.cid);
+            node->parcel.writeInt32(p_cur[i].CellInfo.gsm.signalStrengthGsm.signalStrength);
+            node->parcel.writeInt32(p_cur[i].CellInfo.gsm.signalStrengthGsm.bitErrorRate);
+            node->parcel.writeInt32(p_cur[i].CellInfo.gsm.signalStrengthGsm.timingAdvance);
+            break;
+        }
+        case RIL_CELL_INFO_TYPE_WCDMA: {
+            node->parcel.writeInt32(p_cur[i].CellInfo.wcdma.cellIdentityWcdma.mcc);
+            node->parcel.writeInt32(p_cur[i].CellInfo.wcdma.cellIdentityWcdma.mnc);
+            node->parcel.writeInt32(p_cur[i].CellInfo.wcdma.cellIdentityWcdma.lac);
+            node->parcel.writeInt32(p_cur[i].CellInfo.wcdma.cellIdentityWcdma.cid);
+            node->parcel.writeInt32(p_cur[i].CellInfo.wcdma.cellIdentityWcdma.psc);
+            node->parcel.writeInt32(p_cur[i].CellInfo.wcdma.signalStrengthWcdma.signalStrength);
+            node->parcel.writeInt32(p_cur[i].CellInfo.wcdma.signalStrengthWcdma.bitErrorRate);
+            break;
+        }
+        case RIL_CELL_INFO_TYPE_CDMA: {
+            node->parcel.writeInt32(p_cur[i].CellInfo.cdma.cellIdentityCdma.networkId);
+            node->parcel.writeInt32(p_cur[i].CellInfo.cdma.cellIdentityCdma.systemId);
+            node->parcel.writeInt32(p_cur[i].CellInfo.cdma.cellIdentityCdma.basestationId);
+            node->parcel.writeInt32(p_cur[i].CellInfo.cdma.cellIdentityCdma.longitude);
+            node->parcel.writeInt32(p_cur[i].CellInfo.cdma.cellIdentityCdma.latitude);
+            node->parcel.writeInt32(p_cur[i].CellInfo.cdma.signalStrengthCdma.dbm);
+            node->parcel.writeInt32(p_cur[i].CellInfo.cdma.signalStrengthCdma.ecio);
+            node->parcel.writeInt32(p_cur[i].CellInfo.cdma.signalStrengthEvdo.dbm);
+            node->parcel.writeInt32(p_cur[i].CellInfo.cdma.signalStrengthEvdo.ecio);
+            node->parcel.writeInt32(p_cur[i].CellInfo.cdma.signalStrengthEvdo.signalNoiseRatio);
+            break;
+        }
+        case RIL_CELL_INFO_TYPE_LTE: {
+            node->parcel.writeInt32(p_cur[i].CellInfo.lte.cellIdentityLte.mcc);
+            node->parcel.writeInt32(p_cur[i].CellInfo.lte.cellIdentityLte.mnc);
+            node->parcel.writeInt32(p_cur[i].CellInfo.lte.cellIdentityLte.ci);
+            node->parcel.writeInt32(p_cur[i].CellInfo.lte.cellIdentityLte.pci);
+            node->parcel.writeInt32(p_cur[i].CellInfo.lte.cellIdentityLte.tac);
+            node->parcel.writeInt32(p_cur[i].CellInfo.lte.signalStrengthLte.signalStrength);
+            node->parcel.writeInt32(p_cur[i].CellInfo.lte.signalStrengthLte.rsrp);
+            node->parcel.writeInt32(p_cur[i].CellInfo.lte.signalStrengthLte.rsrq);
+            node->parcel.writeInt32(p_cur[i].CellInfo.lte.signalStrengthLte.rssnr);
+            node->parcel.writeInt32(p_cur[i].CellInfo.lte.signalStrengthLte.cqi);
+            node->parcel.writeInt32(p_cur[i].CellInfo.lte.signalStrengthLte.timingAdvance);
+            break;
+        }
+        case RIL_CELL_INFO_TYPE_TD_SCDMA: {
+            node->parcel.writeInt32(p_cur[i].CellInfo.tdscdma.cellIdentityTdscdma.mcc);
+            node->parcel.writeInt32(p_cur[i].CellInfo.tdscdma.cellIdentityTdscdma.mnc);
+            node->parcel.writeInt32(p_cur[i].CellInfo.tdscdma.cellIdentityTdscdma.lac);
+            node->parcel.writeInt32(p_cur[i].CellInfo.tdscdma.cellIdentityTdscdma.cid);
+            node->parcel.writeInt32(p_cur[i].CellInfo.tdscdma.cellIdentityTdscdma.cpid);
+            node->parcel.writeInt32(p_cur[i].CellInfo.tdscdma.signalStrengthTdscdma.rscp);
+            break;
+        }
+    }
+    }
+    LYDBGLOG("[%s] parcel write success\n",__FUNCTION__);
+    return 0;
+}
+int neighboringCellToParcel(int32_t request,int32_t token,void *response,size_t responselen,RIL_Errno e)
+{
+    int num = 0;
+    lynqQueue * node;
+    node = searchTokeninQueue(token,LynqQueueHead);
+    if(node==NULL)
+    {
+        LYDBGLOG("[%s] search token %x failure from lynq queue\n",__FUNCTION__,token);
+        return -1;
+    }
+    node->t_Errno = e;
+    if (response == NULL && responselen != 0) {
+        LYDBGLOG("[%s] invalid response: NULL\n",__FUNCTION__);
+        return -1;
+    }
+    if(responselen ==0)
+    {
+        LYDBGLOG("[%s]  get cell list fail\n",__FUNCTION__);
+        node->parcel.writeInt32(0);
+        return -1;
+    }
+    num = responselen/sizeof(RIL_NeighboringCell*);
+    node->parcel.writeInt32(num);
+    RIL_NeighboringCell **p_cur = (RIL_NeighboringCell **)response;
+    for (int i = 0; i< num; i++) {
+        StringWriteToParcel(node->parcel,p_cur[i]->cid);
+        node->parcel.writeInt32(p_cur[i]->rssi);
+    }
+    return 0;
+}
+int solicitedSignalStrengthToParcel(int32_t request,int32_t token,void *response,size_t responselen,RIL_Errno e)
+{
+    int num = 0;
+    lynqQueue * node;
+    node = searchTokeninQueue(token,LynqQueueHead);
+    if(node==NULL)
+    {
+        LYDBGLOG("[%s] search token %x failure from lynq queue\n",__FUNCTION__,token);
+        return -1;
+    }
+    node->t_Errno = e;
+    if (response == NULL && responselen != 0) {
+        LYDBGLOG("[%s] invalid response: NULL\n",__FUNCTION__);
+        return -1;
+    }
+    if(responselen ==0)
+    {
+        LYDBGLOG("[%s]  get signal strength fail\n",__FUNCTION__);
+        node->parcel.writeInt32(0);
+        return -1;
+    }
+    num = responselen/sizeof(RIL_SignalStrength_v10);
+    node->parcel.writeInt32(num);
+    RIL_SignalStrength_v10 *p_cur = (RIL_SignalStrength_v10 *)response;
+    node->parcel.writeInt32(p_cur->GW_SignalStrength.signalStrength);
+    node->parcel.writeInt32(p_cur->GW_SignalStrength.bitErrorRate);
+    node->parcel.writeInt32(p_cur->GW_SignalStrength.timingAdvance);
+    node->parcel.writeInt32(p_cur->CDMA_SignalStrength.dbm);
+    node->parcel.writeInt32(p_cur->CDMA_SignalStrength.ecio);
+    node->parcel.writeInt32(p_cur->EVDO_SignalStrength.dbm);
+    node->parcel.writeInt32(p_cur->EVDO_SignalStrength.ecio);
+    node->parcel.writeInt32(p_cur->EVDO_SignalStrength.signalNoiseRatio);
+    node->parcel.writeInt32(p_cur->LTE_SignalStrength.signalStrength);
+    node->parcel.writeInt32(p_cur->LTE_SignalStrength.rsrp);
+    node->parcel.writeInt32(p_cur->LTE_SignalStrength.rsrq);
+    node->parcel.writeInt32(p_cur->LTE_SignalStrength.rssnr);
+    node->parcel.writeInt32(p_cur->LTE_SignalStrength.cqi);
+    node->parcel.writeInt32(p_cur->LTE_SignalStrength.timingAdvance);
+    node->parcel.writeInt32(p_cur->TD_SCDMA_SignalStrength.signalStrength);
+    node->parcel.writeInt32(p_cur->TD_SCDMA_SignalStrength.bitErrorRate);
+    node->parcel.writeInt32(p_cur->TD_SCDMA_SignalStrength.rscp);
+    node->parcel.writeInt32(p_cur->WCDMA_SignalStrength.signalStrength);
+    node->parcel.writeInt32(p_cur->WCDMA_SignalStrength.bitErrorRate);
+    node->parcel.writeInt32(p_cur->WCDMA_SignalStrength.rscp);
+    node->parcel.writeInt32(p_cur->WCDMA_SignalStrength.ecno);
+    return 0;
+}
+int smsResponseToParcel(int32_t request,int32_t token,void *response,size_t responselen,RIL_Errno e)
+{
+    int num = 0;
+    lynqQueue * node;
+    node = searchTokeninQueue(token,LynqQueueHead);
+    if(node==NULL)
+    {
+        LYDBGLOG("[%s] search token %x failure from lynq queue\n",__FUNCTION__,token);
+        return -1;
+    }
+    node->t_Errno = e;
+    if (response == NULL && responselen != 0) {
+        LYDBGLOG("[%s] invalid response: NULL\n",__FUNCTION__);
+        return -1;
+    }
+    if(responselen ==0)
+    {
+        LYDBGLOG("[%s] sms response\n",__FUNCTION__);
+        node->parcel.writeInt32(0);
+        return -1;
+    }
+    num = responselen/sizeof(RIL_SMS_Response);
+    node->parcel.writeInt32(num);
+    RIL_SMS_Response *p_cur = (RIL_SMS_Response *)response;
+    node->parcel.writeInt32(p_cur->messageRef);
+    StringWriteToParcel(node->parcel,p_cur->ackPDU);
+    node->parcel.writeInt32(p_cur->errorCode);
+    return 0;
+}
+
+/*****mobiletek-end****/
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/stateManager/stateManager.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/stateManager/stateManager.h
new file mode 100644
index 0000000..63e0578
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/stateManager/stateManager.h
@@ -0,0 +1,152 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#ifndef __RIL_STAM__
+#define __RIL_STAM__
+#include  <vendor-ril/telephony/ril.h>
+#include  "common.h"
+
+//#include <vendor-ril/telephony/mtk_ril_sp.h>
+//#include "Parcel.h"
+
+using::android::Parcel;
+
+#define MAX_IMSI  20
+int getDeviceIdentity(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int getIMEI(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int getIMEISV(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int getBasebandVersion(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int resetRadio(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int getScreenState(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setTRM(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int setIMSEnable(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int sendATCMD(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+void parseAtCmd(const char* line);
+int setIMSCfg(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+#ifdef KEEP_ALIVE
+int startKeepAlivePro(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int stopKeepAlivePro(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+void handleKeepAliveResponse(int request, const void* data, size_t datalen, RIL_SOCKET_ID soc_id, bool is_error);
+
+
+/*****mobiletek-add****/
+typedef enum{
+    LYNQ_CALL_ON=0,
+    LYNQ_CALL_OFF,
+}lynqCallStatus;
+typedef struct {
+int32_t token;
+int callid;
+int toa;
+char * addr;
+int isMpty;
+int isMT;
+int selflen;
+RIL_CallState callState;
+RIL_Errno lynq_error;
+} lynq_call_list;
+typedef struct callInfo
+{
+    int32_t token;
+    int request;
+    RIL_Errno Error_tok;
+    Parcel parcel;
+    lynq_call_list **calllist_tok;
+    struct callInfo * next;
+}callInfoLink;
+
+extern lynq_call_list **pCallList;
+extern callInfoLink * callInfoLinkhead;
+
+extern lynqCallStatus s_callStatus;
+
+callInfoLink * create_callInfoLink();
+
+typedef struct LQueue
+{
+    int32_t token;
+    int request;
+    RIL_Errno t_Errno; //token error number.
+    int E_status;
+    Parcel parcel;
+    struct LQueue * next;
+}lynqQueue;
+extern lynqQueue * LynqQueueHead;
+
+lynqQueue * createLynqQueue();
+int lynqApiInit();
+lynqQueue * searchRequestinQueue(int32_t request,lynqQueue *head);
+lynqQueue * searchTokeninQueue(int32_t token,lynqQueue *head);
+void lynqDeQueue(int32_t token);
+int getCallStatus(void);
+int setCallStatus(lynqCallStatus callStatus);
+
+typedef struct simInfo{
+    int32_t token;
+    int request;
+    int simInfoLen;
+    RIL_CardState card_status;
+    RIL_AppType    card_type;
+    RIL_PinState pin_state;
+    RIL_Errno Error_tok;
+    char imsi[MAX_IMSI];  
+    //char *imsi;
+    struct simInfo* next;
+}simInfoLink;
+extern simInfoLink *simInfoLinkHead;
+char * lynqStrdupReadString(Parcel &p);
+simInfoLink *createSimInfoLink();
+void LYNQ_DispatchResponse(int request,int32_t token,RIL_Errno respe,lynq_call_list**nodeCallList,void *response,size_t respLen);
+void updateLinkCallInfo(callInfoLink * callInfoLinkhead,lynq_call_list** nodeCallList);
+callInfoLink* addCallInfo(int tok,int request,RIL_Errno respe,callInfoLink* head,lynq_call_list** nodeCallList);
+void printlist(callInfoLink * callInfoLinkhead);
+
+void setCallList(int token,RIL_Call **pCallLists,size_t respLen,RIL_Errno error);
+int callListToParcel(void *response,size_t responselen,Parcel &p);
+
+void updateAsyncData(RIL_Token t, RIL_Errno e,void * response, size_t responselen,lynqQueue* head);
+
+
+
+void freeCallList(int respLen);
+
+void addSimInfo(int request,RIL_Errno respe,int32_t token,simInfoLink *NodeSimInfoLink,void *response,size_t respLen);
+simInfoLink * inSimQueue(int request,int32_t token,simInfoLink *head);
+simInfoLink * deSimQueue(simInfoLink *head,int32_t token);
+void LYNQ_DispatchRequest(int32_t request,int32_t token);
+void addImsiInfo(int request,RIL_Errno respe,int32_t token,simInfoLink *head,void *response,size_t respLen);
+
+/*****moblietek-end****/
+#endif /*KEEP_ALIVE*/
+#endif
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/stk.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/stk.cpp
new file mode 100644
index 0000000..29643db
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/stk.cpp
@@ -0,0 +1,300 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include "stk.h"
+#include <vendor-ril/telephony/ril.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <cutils/jstring.h>
+#include <string.h>
+#include <time.h>
+
+#include "resp_timeout.h"
+
+#undef LOG_TAG
+#define LOG_TAG "DEMO_STK"
+#define INVALID -1;
+#define ACCEPT 1;
+#define REJECT 0;
+
+extern void ARspRequestWithArg(int request, const char* arg,RIL_SOCKET_ID socket_id);
+
+//RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND
+int sendEnvelope(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+
+    //p.writeString(contents);
+    writeStringToParcel(p, (const char *)argv[1]);
+    p.setDataPosition(pos);
+
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+//RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE
+int sendTerminalResponse(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+
+    //p.writeString(contents);
+    writeStringToParcel(p, (const char *)argv[1]);
+    p.setDataPosition(pos);
+
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+//RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS
+int sendEnvelopeWithStatus(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+
+    //p.writeString(contents);
+    writeStringToParcel(p, (const char *)argv[1]);
+    p.setDataPosition(pos);
+
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+//RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM
+int handleCallSetupRequestFromSim(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    if(argc != 2) {
+      free(pRI);
+      RLOGD("handleCallSetupRequestFromSim parameter lost");
+      return 0;
+    }
+    int reject = INVALID;
+    if(strcasecmp("yes", argv[1])){
+      reject = ACCEPT;
+    } else if (strcasecmp("no", argv[1])){
+      reject = REJECT;
+    } else {
+      free(pRI);
+      RLOGD("input: %s, parameter is wrong, please input again!", argv[1]);
+      return 0;
+    }
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    p.writeInt32(1);
+    p.writeInt32(reject);
+    p.setDataPosition(pos);
+
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    clear_timeout(socket_id);
+    return 0;
+}
+
+//RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING
+int reportStkServiceIsRunning(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+
+    pRI->pCI->dispatchFunction(p, pRI);
+
+    return 0;
+}
+
+static int getStkCommandType(char *cmd) {
+    char temp[3] = {0};
+    int cmdType = 0;
+
+    strncpy(temp, cmd, 2);
+    cmdType = strtoul(temp, NULL, 16);
+    cmdType = 0xFF & cmdType;
+
+    return cmdType;
+}
+
+static void parseStkCmdType(char* cmd, int* cmdType) {
+    int cmd_len = strlen(cmd);
+    int typePos = 0;
+
+    if (cmd_len < 14) {
+        RLOGD("parseStkCmdType exception!");
+        return;
+    }
+
+    if(cmd[2] <= '7' ) {
+        typePos = 10;
+    } else {
+        typePos = 12;
+    }
+
+    // get command type
+    *cmdType = getStkCommandType(&cmd[typePos]);
+}
+
+static void parseStkCmdQualifier(char* cmd, int* cmdQual) {
+    int cmd_len = strlen(cmd);
+    int typePos = 0;
+
+    if (cmd_len < 14) {
+        RLOGD("parseStkCmdQualifier exception!");
+        return;
+    }
+
+    if(cmd[2] <= '7' ) {
+        typePos = 12;
+    } else {
+        typePos = 14;
+    }
+
+    // get command qualifier
+    *cmdQual = getStkCommandType(&cmd[typePos]);
+}
+
+static int getStkCommandNumber(char *cmd) {
+    char temp[3] = {0};
+    int cmdNum = 0;
+
+    strncpy(temp, cmd, 2);
+    cmdNum = strtoul(temp, NULL, 16);
+    cmdNum = 0xFF & cmdNum;
+
+    return cmdNum;
+}
+
+static void parseStkCmdNum(char* cmd, int* cmdNum) {
+    int cmd_len = strlen(cmd);
+    int typePos = 0;
+
+    if (cmd_len < 12) {
+        RLOGD("parseStkCmdNum exception!");
+        return;
+    }
+
+    if (cmd[2] <= '7') {
+        typePos = 8;
+    } else {
+        typePos = 10;
+    }
+
+    // check command num
+    *cmdNum = getStkCommandNumber(&cmd[typePos]);
+    RLOGD("parseStkCmdNum cmdNum:%d", *cmdNum);
+}
+
+static int numToBCD(int data) {
+    char string[20] = {0};
+    int low = 0;
+    int high = 0;
+    int result = -1;
+    char num_table[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
+
+    snprintf(string, 20, "%2d", data);
+    if(strlen(string)>2) {
+        RLOGD("[numToBCD]Out of range, data = %d, string = %s", data, string);
+        return -1;
+    }
+    for(int i=0; i<10; i++) {
+        if(num_table[i] == string[0])
+            low = i ;
+        if(num_table[i] == string[1])
+            high = i;
+    }
+    result = ((high<<4)&0xF0)+(low&0x0F);
+    RLOGD("[numToBCD]data=%d, result=%#x, string=%s, low=%d, high=%d", data, result, string, low, high);
+    return result;
+}
+
+static void handleProvideLocalInfo(char *cmd, int slot_id){
+    int cmdNum = -1;
+    time_t now_tmp;
+    struct tm *now;
+    int year = -1, year_bcd = -1;
+    int month = -1, month_bcd = -1;
+    int day = -1, day_bcd = -1;
+    int hour = -1, hour_bcd = -1;
+    int min = -1, min_bcd = -1;
+    int sec = -1, sec_bcd = -1;
+    char response[200]="";
+    
+    parseStkCmdNum(cmd, &cmdNum);
+    time(&now_tmp);
+    now = localtime(&now_tmp);
+    year = now->tm_year + 1900-2000;
+    month = now->tm_mon+1;
+    day = now->tm_mday;
+    hour = now->tm_hour;
+    min = now->tm_min;
+    sec = now->tm_sec;
+    RLOGD("[handleProvideLocalInfo]Get time from system: %d/%d/%d, %d:%d:%d", year, month, day, hour, min, sec);
+    year_bcd = numToBCD(year);
+    month_bcd = numToBCD(month);
+    day_bcd = numToBCD(day);
+    hour_bcd = numToBCD(hour);
+    min_bcd = numToBCD(min);
+    sec_bcd = numToBCD(sec);
+    snprintf(response, 200, "8103%02X260382028281830100A607%02X%02X%02X%02X%02X%02XFF", cmdNum&0XFF, year_bcd&0XFF, month_bcd&0XFF, 
+                    day_bcd&0XFF, hour_bcd&0XFF, min_bcd&0XFF, sec_bcd&0XFF);
+    RLOGD("[handleProvideLocalInfo]Send RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE, data=%s", response);
+    ARspRequestWithArg(RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE, response, (RIL_SOCKET_ID)slot_id);
+}
+
+void handleStkCommand(char* response, int responselen, int slot_id) {
+    int cmdType = -1;
+    int cmdQual = -1;
+    int cmdNum = -1;
+
+    parseStkCmdType(response, &cmdType);
+    parseStkCmdQualifier(response, &cmdQual);
+    parseStkCmdNum(response, &cmdNum);
+    RLOGD("[handleStkCommand][slot%d]cmdType=%d, cmdQual=%d, cmdNum=%d", slot_id, cmdType, cmdQual, cmdNum);
+    
+    switch (cmdType)
+    {
+    case CMD_OPEN_CHAN:
+      RLOGD("[URC][CAT][BIP][SIM%d]: the proactive command include open channel TLV, please choose yes or no", slot_id);
+      printf("[URC][CAT][BIP][SIM%d]: the proactive command include open channel TLV, please choose yes or no\n", slot_id+1);
+      setup_timeout(slot_id); //set up timeout one minutes
+      break;
+    case CMD_PROVIDE_LOCAL_INFO:
+      if (0x03 != cmdQual){
+        RLOGD("not request for data/time, qualifier = %#x", cmdQual);
+        return;
+      }
+      handleProvideLocalInfo(response, slot_id);
+      break;
+    default:
+      break;
+  }
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/stk.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/stk.h
new file mode 100644
index 0000000..122f459
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/stk.h
@@ -0,0 +1,91 @@
+ /*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2005
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+#ifndef __RIL_STK__
+#define __RIL_STK__
+
+#include  <vendor-ril/telephony/ril.h>
+#include  "common.h"
+/*****************************************************************************
+ * Enum
+ *****************************************************************************/
+// Proactive Command Type
+typedef enum {
+    CMD_REFRESH = 0x01,
+    CMD_MORE_TIME = 0x02,
+    CMD_POLL_INTERVAL = 0x03,
+    CMD_POLLING_OFF = 0x04,
+    CMD_SETUP_EVENT_LIST = 0x05,
+    CMD_SETUP_CALL = 0x10,
+    CMD_SEND_SS = 0x11,
+    CMD_SEND_USSD = 0x12,
+    CMD_SEND_SMS = 0x13,
+    CMD_DTMF = 0x14,
+    CMD_LAUNCH_BROWSER = 0x15,
+    CMD_PLAY_TONE = 0x20,
+    CMD_DSPL_TXT = 0x21,
+    CMD_GET_INKEY = 0x22,
+    CMD_GET_INPUT = 0x23,
+    CMD_SELECT_ITEM = 0x24,
+    CMD_SETUP_MENU = 0x25,
+    CMD_PROVIDE_LOCAL_INFO = 0x26,
+    CMD_TIMER_MANAGER = 0x27,
+    CMD_IDLE_MODEL_TXT = 0x28,
+    CMD_PERFORM_CARD_APDU = 0x30,
+    CMD_POWER_ON_CARD = 0x31,
+    CMD_POWER_OFF_CARD = 0x32,
+    CMD_GET_READER_STATUS = 0x33,
+    CMD_RUN_AT = 0x34,
+    CMD_LANGUAGE_NOTIFY = 0x35,
+    CMD_OPEN_CHAN = 0x40,
+    CMD_CLOSE_CHAN = 0x41,
+    CMD_RECEIVE_DATA = 0x42,
+    CMD_SEND_DATA = 0x43,
+    CMD_GET_CHAN_STATUS = 0x44,
+    CMD_RFU = 0x60,
+    CMD_END_PROACTIVE_SESSION = 0x81,
+    CMD_DETAIL = 0xFF
+} CatProactiveCmdEnum;
+typedef enum {
+    CMD_TYPE_PROACTIVE = 0x00,
+    CMD_TYPE_NOTIFY = 0x01,
+    CMD_YPE_SESSIONEND = 0x02
+} sat_cmd_type_num;
+int sendEnvelope(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int sendTerminalResponse(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int sendEnvelopeWithStatus(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int handleCallSetupRequestFromSim(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int reportStkServiceIsRunning(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+void handleStkCommand(char* response, int responselen, int slot_id);
+#endif
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/storeFile/customer_message.txt b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/storeFile/customer_message.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/storeFile/customer_message.txt
@@ -0,0 +1 @@
+
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/AtLine.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/AtLine.cpp
new file mode 100644
index 0000000..7abba8a
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/AtLine.cpp
@@ -0,0 +1,441 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include "../util/AtLine.h"
+
+#include <assert.h>
+
+#include "../util/Misc.h"
+
+#define RFX_LOG_TAG "RfxAtLine"
+
+static const char *s_finalResponsesSuccess[] = { "OK", "CONNECT" /* some stacks start up data on another channel */
+};
+
+/**
+ * returns 1 if line is a final response indicating error
+ * See 27.007 annex B
+ * WARNING: NO CARRIER and others are sometimes unsolicited
+ */
+static const char *s_finalResponsesError[] = { "ERROR", "+CMS ERROR:",
+        "+CME ERROR:", "NO CARRIER", /* sometimes! */
+        "NO ANSWER", "NO DIALTONE", "+C2K ERROR:", "+EC2KCME ERROR", /* for distinguish CME error between MD1 and MD3 */
+};
+
+/**
+ * returns 1 if line is a intermediate response
+ * Such as
+ * AT+CMGW <CR>
+ * >XXXXXX  <CTRL+Z> or <ESC>
+ * OK
+ * WARNING: NO CARRIER and others are sometimes unsolicited
+ */
+static const char *s_IntermediatePattern[] = { "> ", };
+
+static const char *s_finalResponsesSuccessInNumeric[] = { "0", "1", };
+
+static const char *s_finalResponsesErrorInNumeric[] = { "2", "3", "4", "6", "7",
+        "8", "+CMS ERROR:", "+CME ERROR:", "+C2K ERROR:", };
+
+static const char *s_ackResponse[] = { "ACK" };
+
+AtLine::AtLine(const AtLine &other) {
+    // Only copy THIS node
+    assert(other.m_pNext == NULL);
+
+    m_line = (char *) calloc(strlen(other.m_line) + 1, sizeof(char));
+    if (m_line == NULL) {
+        //RFX_LOG_E(RFX_LOG_TAG, "OOM");
+        m_pNext = NULL;
+        m_pCur = NULL;
+        return;
+    }
+    memcpy(m_line, other.m_line, strlen(other.m_line));
+    m_line[strlen(other.m_line)] = '\0';
+    m_pNext = NULL;
+
+    // initialize p_cur
+    m_pCur = m_line;
+}
+
+AtLine::AtLine(const char* line, AtLine* next) {
+    m_line = (char *) calloc(strlen(line) + 1, sizeof(char));
+    if (m_line == NULL) {
+        //RFX_LOG_E(RFX_LOG_TAG, "OOM");
+        m_pNext = NULL;
+        m_pCur = NULL;
+        return;
+    }
+    memcpy(m_line, line, strlen(line));
+    m_line[strlen(line)] = '\0';
+    m_pNext = next;
+
+    // initialize p_cur
+    m_pCur = m_line;
+}
+
+AtLine::~AtLine() {
+    if (m_pNext) {
+        delete (m_pNext);
+    }
+
+    m_pCur = NULL;
+    if (m_line) {
+        free(m_line);
+    }
+}
+
+/**
+ * Starts tokenizing an AT response string
+ * Set err to -1 if this is not a valid response string, 0 on success.
+ * updates m_pCur with current position
+ */
+void AtLine::atTokStart(int *err) {
+    *err = 0;
+    m_pCur = m_line;
+    if (m_pCur == NULL) {
+        *err = -1;
+        return;
+    }
+
+    // skip prefix
+    // consume "^[^:]:"
+
+    m_pCur = strchr(m_pCur, ':');
+
+    if (m_pCur == NULL) {
+        *err = -1;
+        return;
+    }
+
+    m_pCur++;
+}
+
+char* AtLine::atTokChar(int *err) {
+    *err = 0;
+    if (m_pCur == NULL) {
+        *err = -1;
+        return NULL;
+    }
+    m_pCur = strchr(m_pCur, '(');
+
+    if (m_pCur == NULL) {
+        *err = -1;
+        return NULL;
+    }
+
+    return (m_pCur++);
+}
+
+void AtLine::skipWhiteSpace() {
+    if (m_pCur == NULL)
+        return;
+
+    while (*m_pCur != '\0' && isspace(*m_pCur)) {
+        m_pCur++;
+    }
+}
+
+void AtLine::skipNextComma() {
+    if (m_pCur == NULL)
+        return;
+
+    while (*m_pCur != '\0' && *m_pCur != ',') {
+        m_pCur++;
+    }
+
+    if (*m_pCur == ',') {
+        m_pCur++;
+    }
+}
+
+char* AtLine::nextTok() {
+    char *ret;
+
+    skipWhiteSpace();
+
+    if (m_pCur == NULL) {
+        ret = NULL;
+    } else if (*m_pCur == '"') {
+        m_pCur++;
+        ret = strsep(&m_pCur, "\"");
+        skipNextComma();
+    } else if (*m_pCur == '(' && *(m_pCur + 1) == '"') {
+        m_pCur = m_pCur + 2;
+        ret = strsep(&m_pCur, "\"");
+        skipNextComma();
+    } else {
+        ret = strsep(&m_pCur, ",");
+    }
+
+    return ret;
+}
+
+/**
+ * Parses the next integer in the AT response line and places it in *p_out
+ * Set err to 0 on success and -1 on fail
+ * updates m_pCur
+ * "base" is the same as the base param in strtol
+ */
+
+int AtLine::atTokNextintBase(int base, int uns, int *err) {
+    int out;
+    char *ret;
+    *err = 0;
+
+    if (m_pCur == NULL) {
+        *err = -1;
+        return 0;
+    }
+
+    ret = nextTok();
+
+    if (ret == NULL) {
+        *err = -1;
+        return 0;
+    } else {
+        long l;
+        char *end;
+
+        if (uns)
+            l = strtoul(ret, &end, base);
+        else
+            l = strtol(ret, &end, base);
+
+        out = (int) l;
+
+        if (end == ret) {
+            *err = -1;
+            return 0;
+        }
+        return out;
+    }
+}
+
+/**
+ * Parses the next base 10 integer in the AT response line
+ * and places it in *p_out
+ * Set err to 0 on success and -1 on fail
+ * updates m_pCur
+ */
+int AtLine::atTokNextint(int *err) {
+    return atTokNextintBase(10, 0, err);
+}
+
+/**
+ * Parses the next base 16 integer in the AT response line
+ * and places it in *p_out
+ * Set err to 0 on success and -1 on fail
+ * updates m_pCur
+ */
+int AtLine::atTokNexthexint(int *err) {
+    return atTokNextintBase(16, 1, err);
+}
+
+bool AtLine::atTokNextbool(int *err) {
+    int result;
+
+    result = atTokNextint(err);
+
+    if (*err < 0) {
+        *err = -1;
+        return false;
+    }
+
+    // booleans should be 0 or 1
+    if (!(result == 0 || result == 1)) {
+        *err = -1;
+        return false;
+    }
+
+    return result ? true : false;
+}
+
+char* AtLine::atTokNextstr(int *err) {
+    *err = 0;
+    if (m_pCur == NULL) {
+        *err = -1;
+        return NULL;
+    }
+
+    return nextTok();
+}
+
+/** returns 1 on "has more tokens" and 0 if no */
+int AtLine::atTokHasmore() {
+    return !(m_pCur == NULL || *m_pCur == '\0');
+}
+
+/// M: eMBMS feature
+void AtLine::atTokEqual(int *err) {
+    *err = 0;
+    m_pCur = m_line;
+    if (m_pCur == NULL) {
+        *err = -1;
+        return;
+    }
+
+    // skip prefix
+    // consume "^[^=]:"
+
+    m_pCur = strchr(m_pCur, '=');
+
+    if (m_pCur == NULL) {
+        *err = -1;
+        return;
+    }
+
+    m_pCur++;
+}
+
+/**
+ * Parses the next long long in the AT response line and places it in *p_out
+ * Set err to 0 on success and -1 on fail
+ * updates m_pCur
+ * "base" is the same as the base param in strtoll
+ */
+
+long long AtLine::atTokNextlonglongBase(int base, int uns, int *err) {
+    char *ret;
+    long long out;
+    *err = 0;
+
+    if (m_pCur == NULL) {
+        *err = -1;
+        return 0;
+    }
+
+    ret = nextTok();
+
+    if (ret == NULL) {
+        *err = -1;
+        return 0;
+    } else {
+        long long ll;
+        char *end;
+
+        if (uns)
+            ll = strtoull(ret, &end, base);
+        else
+            ll = strtoll(ret, &end, base);
+
+        out = ll;
+
+        if (end == ret) {
+            *err = -1;
+            return 0;
+        }
+    }
+
+    return out;
+}
+
+/**
+ * Parse the next base 10 long long in the AT response line
+ * and places it in *p_out
+ * Set err to 0 on success and -1 on fail
+ * updates m_pCur
+ */
+long long AtLine::atTokNextlonglong(int *err) {
+    return atTokNextlonglongBase(10, 0, err);
+}
+
+int AtLine::isFinalResponseSuccess() {
+    for (size_t i = 0; i < NUM_ELEMS(s_finalResponsesSuccess); i++) {
+        if (Misc::strStartsWith(m_line, s_finalResponsesSuccess[i])) {
+            return 1;
+        }
+    }
+
+    return 0;
+}
+
+int AtLine::isFinalResponseErrorEx(int channel_id) {
+    size_t i;
+
+//    int j=0;
+//    for(j=0; j<RfxRilUtils::getSimCount(); j++){
+//        if( (channel_id == (int)(RIL_URC+j*RIL_CHANNEL_OFFSET)) &&
+//                (RfxMisc::strStartsWith(m_line, "NO CARRIER")) ){
+//            // [ALPS01225455]NO CARRIER in URC channel is URC, not final response for mediatek modem
+//            return 0;
+//        }
+//    }
+
+    for (i = 0; i < NUM_ELEMS(s_finalResponsesError); i++) {
+        if (Misc::strStartsWith(m_line, s_finalResponsesError[i])) {
+            return 1;
+        }
+    }
+    return 0;
+}
+
+int AtLine::isIntermediatePattern() {
+    size_t i;
+    for (i = 0; i < NUM_ELEMS(s_IntermediatePattern); i++) {
+        if (!strcmp(m_line, s_IntermediatePattern[i])) {
+            return 1;
+        }
+    }
+    return 0;
+}
+
+bool AtLine::isFinalResponseSuccessInNumeric() {
+    for (size_t i = 0; i < NUM_ELEMS(s_finalResponsesSuccessInNumeric); i++) {
+        if (!strcmp(m_line, s_finalResponsesSuccessInNumeric[i])) {
+            return 1;
+        }
+    }
+    return 0;
+}
+
+bool AtLine::isFinalResponseErrorInNumeric() {
+    for (size_t i = 0; i < NUM_ELEMS(s_finalResponsesErrorInNumeric); i++) {
+        if (!strncmp(m_line, s_finalResponsesErrorInNumeric[i],
+                strlen(s_finalResponsesErrorInNumeric[i]))) {
+            return 1;
+        }
+    }
+    return 0;
+}
+
+bool AtLine::isAckResponse() {
+    for (size_t i = 0; i < NUM_ELEMS(s_ackResponse); i++) {
+        if (!strncmp(m_line, s_ackResponse[i], strlen(s_ackResponse[i]))) {
+            return true;
+        }
+    }
+    return false;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/AtLine.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/AtLine.h
new file mode 100644
index 0000000..8768ac6
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/AtLine.h
@@ -0,0 +1,103 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef __RFX_AT_LINE_H__
+#define __RFX_AT_LINE_H__
+
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+#define NUM_ELEMS(x) (sizeof(x)/sizeof(x[0]))
+
+class AtLine {
+public:
+    AtLine() :
+            m_line(NULL), m_pNext(NULL) {
+    }
+
+    AtLine(const char* line, AtLine* next);
+
+    // copy constructor
+    AtLine(const AtLine &other);
+
+    ~AtLine();
+
+    AtLine &operator=(const AtLine &other);
+public:
+    AtLine* getNext() const {
+        return m_pNext;
+    }
+    void setNext(AtLine* next) {
+        m_pNext = next;
+    }
+    char *getLine() const {
+        return m_line;
+    }
+    void setLine(char* line) {
+        m_line = line;
+    }
+    char *getCurrentLine() {
+        return m_pCur;
+    }
+    void atTokStart(int *err);
+    int atTokNextint(int *err);
+    int atTokNexthexint(int *err);
+    bool atTokNextbool(int *err);
+    char* atTokNextstr(int *err);
+    int atTokHasmore();
+    char* atTokChar(int *err);
+    void atTokEqual(int *err);
+    long long atTokNextlonglong(int *err);
+    int isFinalResponseSuccess();
+    int isFinalResponseErrorEx(int channel_id);
+    int isIntermediatePattern();
+    bool isFinalResponseSuccessInNumeric();
+    bool isFinalResponseErrorInNumeric();
+    bool isAckResponse();
+
+private:
+    void skipWhiteSpace();
+    void skipNextComma();
+    int atTokNextintBase(int base, int uns, int *err);
+    long long atTokNextlonglongBase(int base, int uns, int *err);
+    char* nextTok();
+
+private:
+    char *m_line; // should dynamic allocate memory?
+    AtLine *m_pNext;
+    char *m_pCur; // current position, initialize at atTokStart
+};
+#endif
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Misc.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Misc.cpp
new file mode 100644
index 0000000..0536a68
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Misc.cpp
@@ -0,0 +1,29 @@
+/* //device/system/reference-ril/misc.c
+ **
+ ** Copyright 2006, The Android Open Source Project
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ **     http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+#include "../util/Misc.h"
+
+/** returns 1 if line starts with prefix, 0 if it does not */
+int Misc::strStartsWith(const char *line, const char *prefix) {
+    for (; *line != '\0' && *prefix != '\0'; line++, prefix++) {
+        if (*line != *prefix) {
+            return 0;
+        }
+    }
+
+    return *prefix == '\0';
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Misc.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Misc.h
new file mode 100644
index 0000000..06ce1b3
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Misc.h
@@ -0,0 +1,36 @@
+/* //device/system/reference-ril/misc.h
+ **
+ ** Copyright 2006, The Android Open Source Project
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ **     http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+#ifndef __RFX_MISC_H__
+#define __RFX_MISC_H__
+
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+class Misc {
+private:
+    Misc() {
+    }
+    ~Misc() {
+    }
+public:
+    /** returns 1 if line starts with prefix, 0 if it does not */
+    static int strStartsWith(const char *line, const char *prefix);
+};
+
+#endif
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/ModemCategory.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/ModemCategory.cpp
new file mode 100644
index 0000000..b9a79ec
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/ModemCategory.cpp
@@ -0,0 +1,123 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include <log/log.h>
+#include "ModemCategory.h"
+#include "WorldPhoneUtil.h"
+#include "RatConfiguration.h"
+#include "Radio_capability_switch_util.h"
+#include "common.h"
+#undef LOG_TAG
+#define LOG_TAG "EM_ModemCategory"
+
+const int ModemCategory::MODEM_FDD = 1;
+const int ModemCategory::MODEM_TD = 2;
+const int ModemCategory::MODEM_NO3G = 3;
+const std::string ModemCategory::FK_SIM_SWITCH = "persist.vendor.radio.simswitch";
+const std::string ModemCategory::FK_CDMA_SLOT = "persist.vendor.radio.cdma_slot";
+
+/**
+ * The property is used to check if the card is cdma 3G dual mode card in the slot.
+ */
+std::vector<std::string> ModemCategory::PROPERTY_RIL_CT3G {
+    "vendor.gsm.ril.ct3g",
+    "vendor.gsm.ril.ct3g.2",
+    "vendor.gsm.ril.ct3g.3",
+    "vendor.gsm.ril.ct3g.4",
+};
+
+/**
+ * The property is used to get supported card type of each SIM card in the slot.
+ */
+std::vector<std::string> ModemCategory::PROPERTY_RIL_FULL_UICC_TYPE {
+    "vendor.gsm.ril.fulluicctype",
+    "vendor.gsm.ril.fulluicctype.2",
+    "vendor.gsm.ril.fulluicctype.3",
+    "vendor.gsm.ril.fulluicctype.4"};
+
+ModemCategory::ModemCategory() {
+    // TODO Auto-generated constructor stub
+
+}
+
+ModemCategory::~ModemCategory() {
+    // TODO Auto-generated destructor stub
+}
+
+int ModemCategory::getModemType() {
+    int mode = MODEM_NO3G;
+    int mask = WorldPhoneUtil::get3GDivisionDuplexMode();
+    if ((1 == mask) || (2 == mask)) {
+        mode = mask;
+    }
+    RLOGD("mode = %d", mode);
+    return mode;
+}
+
+bool ModemCategory::isCdma() {
+    return RatConfiguration::isC2kSupported();
+}
+
+bool ModemCategory::isLteSupport() {
+    return (RatConfiguration::isLteFddSupported() || RatConfiguration::isLteTddSupported());
+}
+
+bool ModemCategory::isGsmSupport() {
+    return (RatConfiguration::isGsmSupported());
+}
+
+bool ModemCategory::isWcdmaSupport() {
+    return (RatConfiguration::isWcdmaSupported());
+}
+
+bool ModemCategory::isTdscdmaSupport() {
+    return (RatConfiguration::isTdscdmaSupported());
+}
+
+bool ModemCategory::isCapabilitySim(int type) {
+    int mainCard = Radio_capability_switch_util::get_main_capability_phone_id();
+    bool isCapability = (type == mainCard) ? true : false;
+    RLOGD("The card(%d) is main card = %d", type, isCapability);
+    return isCapability;
+}
+
+bool ModemCategory::checkViceSimCapability(int simType, int capability) {
+    int rat  = get_radio_capa(simType).rat;
+    if ((rat & capability) > 0) {
+        RLOGD("SIM has checked capability. rat: %d, cap: %d", rat , capability);
+        return true;
+    }
+    return false;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/ModemCategory.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/ModemCategory.h
new file mode 100644
index 0000000..847a9d8
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/ModemCategory.h
@@ -0,0 +1,65 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef SRC_UTIL_MODEMCATEGORY_H_
+#define SRC_UTIL_MODEMCATEGORY_H_
+
+#include <string>
+#include <vector>
+class ModemCategory {
+public:
+    static const int MODEM_FDD;
+    static const int MODEM_TD;
+    static const int MODEM_NO3G;
+    static const std::string FK_SIM_SWITCH;
+    static const std::string FK_CDMA_SLOT;
+
+private:
+    static std::vector<std::string> PROPERTY_RIL_CT3G;
+    static std::vector<std::string> PROPERTY_RIL_FULL_UICC_TYPE;
+public:
+    ModemCategory();
+    virtual ~ModemCategory();
+    static int getModemType();
+    static bool isCdma();
+    static bool isLteSupport();
+    static bool isGsmSupport();
+    static bool isWcdmaSupport();
+    static bool isTdscdmaSupport();
+    static bool isCapabilitySim(int type);
+    static bool checkViceSimCapability(int simType, int capability);
+};
+
+#endif /* SRC_UTIL_MODEMCATEGORY_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/MtkRadioAccessFamily.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/MtkRadioAccessFamily.cpp
new file mode 100644
index 0000000..6fa8dc0
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/MtkRadioAccessFamily.cpp
@@ -0,0 +1,267 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include "MtkRadioAccessFamily.h"
+#include "Phone_utils.h"
+// Radio Access Family
+// 2G
+const int MtkRadioAccessFamily::RAF_UNKNOWN = RIL_RadioAccessFamily::RAF_UNKNOWN;
+const int MtkRadioAccessFamily::RAF_GSM = RIL_RadioAccessFamily::RAF_GSM;
+const int MtkRadioAccessFamily::RAF_GPRS = RIL_RadioAccessFamily::RAF_GPRS;
+const int MtkRadioAccessFamily::RAF_EDGE = RIL_RadioAccessFamily::RAF_EDGE;
+const int MtkRadioAccessFamily::RAF_IS95A = RIL_RadioAccessFamily::RAF_IS95A;
+const int MtkRadioAccessFamily::RAF_IS95B = RIL_RadioAccessFamily::RAF_IS95B;
+const int MtkRadioAccessFamily::RAF_1xRTT = RIL_RadioAccessFamily::RAF_1xRTT;
+// 3G
+const int MtkRadioAccessFamily::RAF_EVDO_0 = RIL_RadioAccessFamily::RAF_EVDO_0;
+const int MtkRadioAccessFamily::RAF_EVDO_A = RIL_RadioAccessFamily::RAF_EVDO_A;
+const int MtkRadioAccessFamily::RAF_EVDO_B = RIL_RadioAccessFamily::RAF_EVDO_B;
+const int MtkRadioAccessFamily::RAF_EHRPD = RIL_RadioAccessFamily::RAF_EHRPD;
+const int MtkRadioAccessFamily::RAF_HSUPA = RIL_RadioAccessFamily::RAF_HSUPA;
+const int MtkRadioAccessFamily::RAF_HSDPA = RIL_RadioAccessFamily::RAF_HSDPA;
+const int MtkRadioAccessFamily::RAF_HSPA = RIL_RadioAccessFamily::RAF_HSPA;
+const int MtkRadioAccessFamily::RAF_HSPAP = RIL_RadioAccessFamily::RAF_HSPAP;
+const int MtkRadioAccessFamily::RAF_UMTS = RIL_RadioAccessFamily::RAF_UMTS;
+const int MtkRadioAccessFamily::RAF_TD_SCDMA =
+        RIL_RadioAccessFamily::RAF_TD_SCDMA;
+// 4G
+const int MtkRadioAccessFamily::RAF_LTE = RIL_RadioAccessFamily::RAF_LTE;
+const int MtkRadioAccessFamily::RAF_LTE_CA = 19; //RIL_RadioAccessFamily::RAF_LTE_CA;
+
+// Grouping of RAFs
+// 2G
+const int MtkRadioAccessFamily::GSM = RAF_GSM | RAF_GPRS | RAF_EDGE;
+const int MtkRadioAccessFamily::CDMA = RAF_IS95A | RAF_IS95B | RAF_1xRTT;
+// 3G
+const int MtkRadioAccessFamily::EVDO = RAF_EVDO_0 | RAF_EVDO_A | RAF_EVDO_B
+        | RAF_EHRPD;
+const int MtkRadioAccessFamily::HS = RAF_HSUPA | RAF_HSDPA | RAF_HSPA
+        | RAF_HSPAP;
+const int MtkRadioAccessFamily::WCDMA = HS | RAF_UMTS | RAF_TD_SCDMA;
+// 4G
+const int MtkRadioAccessFamily::LTE = RAF_LTE | RAF_LTE_CA;
+
+MtkRadioAccessFamily::MtkRadioAccessFamily() {
+    // TODO Auto-generated constructor stub
+
+}
+
+MtkRadioAccessFamily::~MtkRadioAccessFamily() {
+    // TODO Auto-generated destructor stub
+}
+
+int MtkRadioAccessFamily::getRafFromNetworkType(int type) {
+    int raf;
+
+    switch (type) {
+    case Phone_utils::NETWORK_MODE_WCDMA_PREF:
+        raf = GSM | WCDMA;
+        break;
+    case Phone_utils::NETWORK_MODE_GSM_ONLY:
+        raf = GSM;
+        break;
+    case Phone_utils::NETWORK_MODE_WCDMA_ONLY:
+        raf = WCDMA;
+        break;
+    case Phone_utils::NETWORK_MODE_GSM_UMTS:
+        raf = GSM | WCDMA;
+        break;
+    case Phone_utils::NETWORK_MODE_CDMA:
+        raf = CDMA | EVDO;
+        break;
+    case Phone_utils::NETWORK_MODE_LTE_CDMA_EVDO:
+        raf = LTE | CDMA | EVDO;
+        break;
+    case Phone_utils::NETWORK_MODE_LTE_GSM_WCDMA:
+        raf = LTE | GSM | WCDMA;
+        break;
+    case Phone_utils::NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
+        raf = LTE | CDMA | EVDO | GSM | WCDMA;
+        break;
+    case Phone_utils::NETWORK_MODE_LTE_ONLY:
+        raf = LTE;
+        break;
+    case Phone_utils::NETWORK_MODE_LTE_WCDMA:
+        raf = LTE | WCDMA;
+        break;
+    case Phone_utils::NETWORK_MODE_CDMA_NO_EVDO:
+        raf = CDMA;
+        break;
+    case Phone_utils::NETWORK_MODE_EVDO_NO_CDMA:
+        raf = EVDO;
+        break;
+    case Phone_utils::NETWORK_MODE_GLOBAL:
+        raf = GSM | WCDMA | CDMA | EVDO;
+        break;
+    case Phone_utils::NETWORK_MODE_TDSCDMA_ONLY:
+        raf = RAF_TD_SCDMA;
+        break;
+    case Phone_utils::NETWORK_MODE_TDSCDMA_WCDMA:
+        raf = RAF_TD_SCDMA | WCDMA;
+        break;
+    case Phone_utils::NETWORK_MODE_LTE_TDSCDMA:
+        raf = LTE | RAF_TD_SCDMA;
+        break;
+    case Phone_utils::NETWORK_MODE_TDSCDMA_GSM:
+        raf = RAF_TD_SCDMA | GSM;
+        break;
+    case Phone_utils::NETWORK_MODE_LTE_TDSCDMA_GSM:
+        raf = LTE | RAF_TD_SCDMA | GSM;
+        break;
+    case Phone_utils::NETWORK_MODE_TDSCDMA_GSM_WCDMA:
+        raf = RAF_TD_SCDMA | GSM | WCDMA;
+        break;
+    case Phone_utils::NETWORK_MODE_LTE_TDSCDMA_WCDMA:
+        raf = LTE | RAF_TD_SCDMA | WCDMA;
+        break;
+    case Phone_utils::NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA:
+        raf = LTE | RAF_TD_SCDMA | GSM | WCDMA;
+        break;
+    case Phone_utils::NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
+        raf = RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA;
+        break;
+    case Phone_utils::NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
+        raf = LTE | RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA;
+        break;
+    case Phone_utils::NETWORK_MODE_LTE_GSM:
+        raf = LTE | GSM;
+        break;
+    case Phone_utils::NETWORK_MODE_LTE_TDD_ONLY:
+        raf = LTE;
+        break;
+    case Phone_utils::NETWORK_MODE_CDMA_GSM:
+        raf = CDMA | GSM;
+        break;
+    case Phone_utils::NETWORK_MODE_CDMA_EVDO_GSM:
+        raf = CDMA | EVDO | GSM;
+        break;
+    case Phone_utils::NETWORK_MODE_LTE_CDMA_EVDO_GSM:
+        raf = LTE | CDMA | EVDO | GSM;
+        break;
+    default:
+        raf = RAF_UNKNOWN;
+        break;
+    }
+
+    return raf;
+}
+
+/**
+ * if the raf includes ANY bit set for a group
+ * adjust it to contain ALL the bits for that group
+ */
+int MtkRadioAccessFamily::getAdjustedRaf(int raf) {
+    raf = ((GSM & raf) > 0) ? (GSM | raf) : raf;
+    raf = ((WCDMA & raf) > 0) ? (WCDMA | raf) : raf;
+    raf = ((CDMA & raf) > 0) ? (CDMA | raf) : raf;
+    raf = ((EVDO & raf) > 0) ? (EVDO | raf) : raf;
+    raf = ((LTE & raf) > 0) ? (LTE | raf) : raf;
+
+    return raf;
+}
+
+int MtkRadioAccessFamily::getNetworkTypeFromRaf(int raf) {
+    int type;
+
+    raf = getAdjustedRaf(raf);
+
+    switch (raf) {
+    case (GSM | WCDMA):
+        type = Phone_utils::NETWORK_MODE_WCDMA_PREF;
+        break;
+    case GSM:
+        type = Phone_utils::NETWORK_MODE_GSM_ONLY;
+        break;
+    case WCDMA:
+        type = Phone_utils::NETWORK_MODE_WCDMA_ONLY;
+        break;
+    case (CDMA | EVDO):
+        type = Phone_utils::NETWORK_MODE_CDMA;
+        break;
+    case (LTE | CDMA | EVDO):
+        type = Phone_utils::NETWORK_MODE_LTE_CDMA_EVDO;
+        break;
+    case (LTE | GSM | WCDMA):
+        type = Phone_utils::NETWORK_MODE_LTE_GSM_WCDMA;
+        break;
+    case (LTE | CDMA | EVDO | GSM | WCDMA):
+        type = Phone_utils::NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA;
+        break;
+    case LTE:
+        type = Phone_utils::NETWORK_MODE_LTE_ONLY;
+        break;
+    case (LTE | WCDMA):
+        type = Phone_utils::NETWORK_MODE_LTE_WCDMA;
+        break;
+    case CDMA:
+        type = Phone_utils::NETWORK_MODE_CDMA_NO_EVDO;
+        break;
+    case EVDO:
+        type = Phone_utils::NETWORK_MODE_EVDO_NO_CDMA;
+        break;
+    case (GSM | WCDMA | CDMA | EVDO):
+        type = Phone_utils::NETWORK_MODE_GLOBAL;
+        break;
+    case RAF_TD_SCDMA:
+        type = Phone_utils::NETWORK_MODE_TDSCDMA_ONLY;
+        break;
+    case (LTE | RAF_TD_SCDMA):
+        type = Phone_utils::NETWORK_MODE_LTE_TDSCDMA;
+        break;
+    case (RAF_TD_SCDMA | GSM):
+        type = Phone_utils::NETWORK_MODE_TDSCDMA_GSM;
+        break;
+    case (LTE | RAF_TD_SCDMA | GSM):
+        type = Phone_utils::NETWORK_MODE_LTE_TDSCDMA_GSM;
+        break;
+    case (LTE | GSM):
+        type = Phone_utils::NETWORK_MODE_LTE_GSM;
+        break;
+    case (CDMA | GSM):
+        type = Phone_utils::NETWORK_MODE_CDMA_GSM;
+        break;
+    case (CDMA | EVDO | GSM):
+        type = Phone_utils::NETWORK_MODE_CDMA_EVDO_GSM;
+        break;
+    case (LTE | CDMA | EVDO | GSM):
+        type = Phone_utils::NETWORK_MODE_LTE_CDMA_EVDO_GSM;
+        break;
+    default:
+        type = Phone_utils::PREFERRED_NETWORK_MODE;
+        break;
+    }
+
+    return type;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/MtkRadioAccessFamily.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/MtkRadioAccessFamily.h
new file mode 100644
index 0000000..537f622
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/MtkRadioAccessFamily.h
@@ -0,0 +1,85 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef SRC_UTIL_MTKRADIOACCESSFAMILY_H_
+#define SRC_UTIL_MTKRADIOACCESSFAMILY_H_
+
+#include <vendor-ril/telephony/ril.h>
+
+class MtkRadioAccessFamily {
+public:
+    MtkRadioAccessFamily();
+    virtual ~MtkRadioAccessFamily();
+    static int getRafFromNetworkType(int type);
+    static int getAdjustedRaf(int raf);
+    static int getNetworkTypeFromRaf(int raf);
+public:
+    // Radio Access Family
+    // 2G
+    static const int RAF_UNKNOWN;
+    static const int RAF_GSM;
+    static const int RAF_GPRS;
+    static const int RAF_EDGE;
+    static const int RAF_IS95A;
+    static const int RAF_IS95B;
+    static const int RAF_1xRTT;
+    // 3G
+    static const int RAF_EVDO_0;
+    static const int RAF_EVDO_A;
+    static const int RAF_EVDO_B;
+    static const int RAF_EHRPD;
+    static const int RAF_HSUPA;
+    static const int RAF_HSDPA;
+    static const int RAF_HSPA;
+    static const int RAF_HSPAP;
+    static const int RAF_UMTS;
+    static const int RAF_TD_SCDMA;
+    // 4G
+    static const int RAF_LTE;
+    static const int RAF_LTE_CA;
+private:
+    // Grouping of RAFs
+    // 2G
+    static const int GSM;
+    static const int CDMA;
+    // 3G
+    static const int EVDO;
+    static const int HS;
+    static const int WCDMA;
+    // 4G
+    static const int LTE;
+};
+
+#endif /* SRC_UTIL_MTKRADIOACCESSFAMILY_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Phone_utils.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Phone_utils.cpp
new file mode 100644
index 0000000..06b4917
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Phone_utils.cpp
@@ -0,0 +1,203 @@
+ /*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <cutils/properties.h>
+#include <string>
+
+#include "log_extra.h"
+#include "Phone_utils.h"
+#include "utils.h"
+#include "common.h"
+
+#define LOG_TAG "DEMO_PHONE_UTILS"
+
+/* NETWORK_MODE_* See ril.h RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE */
+constexpr int Phone_utils::NETWORK_MODE_WCDMA_PREF; /* GSM/WCDMA (WCDMA preferred) */
+constexpr int Phone_utils::NETWORK_MODE_GSM_ONLY; /* GSM only */
+constexpr int Phone_utils::NETWORK_MODE_WCDMA_ONLY ; /* WCDMA only */
+constexpr int Phone_utils::NETWORK_MODE_GSM_UMTS; /* GSM/WCDMA (auto mode, according to PRL)
+                                        AVAILABLE Application Settings menu*/
+constexpr int Phone_utils::NETWORK_MODE_CDMA; /* CDMA and EvDo (auto mode, according to PRL)
+                                        AVAILABLE Application Settings menu*/
+constexpr int Phone_utils::NETWORK_MODE_CDMA_NO_EVDO; /* CDMA only */
+constexpr int Phone_utils::NETWORK_MODE_EVDO_NO_CDMA; /* EvDo only */
+constexpr int Phone_utils::NETWORK_MODE_GLOBAL; /* GSM/WCDMA, CDMA, and EvDo (auto mode, according to PRL)
+                                        AVAILABLE Application Settings menu*/
+constexpr int Phone_utils::NETWORK_MODE_LTE_CDMA_EVDO; /* LTE, CDMA and EvDo */
+constexpr int Phone_utils::NETWORK_MODE_LTE_GSM_WCDMA; /* LTE, GSM/WCDMA */
+constexpr int Phone_utils::NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA; /* LTE, CDMA, EvDo, GSM/WCDMA */
+constexpr int Phone_utils::NETWORK_MODE_LTE_ONLY; /* LTE Only mode. */
+constexpr int Phone_utils::NETWORK_MODE_LTE_WCDMA; /* LTE/WCDMA */
+constexpr int Phone_utils::NETWORK_MODE_TDSCDMA_ONLY; /* TD-SCDMA only */
+constexpr int Phone_utils::NETWORK_MODE_TDSCDMA_WCDMA; /* TD-SCDMA and WCDMA */
+constexpr int Phone_utils::NETWORK_MODE_LTE_TDSCDMA; /* TD-SCDMA and LTE */
+constexpr int Phone_utils::NETWORK_MODE_TDSCDMA_GSM; /* TD-SCDMA and GSM */
+constexpr int Phone_utils::NETWORK_MODE_LTE_TDSCDMA_GSM; /* TD-SCDMA,GSM and LTE */
+constexpr int Phone_utils::NETWORK_MODE_TDSCDMA_GSM_WCDMA; /* TD-SCDMA, GSM/WCDMA */
+constexpr int Phone_utils::NETWORK_MODE_LTE_TDSCDMA_WCDMA; /* TD-SCDMA, WCDMA and LTE */
+constexpr int Phone_utils::NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA; /* TD-SCDMA, GSM/WCDMA and LTE */
+constexpr int Phone_utils::NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA; /*TD-SCDMA,EvDo,CDMA,GSM/WCDMA*/
+constexpr int Phone_utils::NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA; /* TD-SCDMA/LTE/GSM/WCDMA, CDMA, and EvDo */
+/// M: [Network][C2K]Add the MTK new network type. @{
+constexpr int Phone_utils::NETWORK_MODE_LTE_GSM; /*LTE/GSM */
+constexpr int Phone_utils::NETWORK_MODE_LTE_TDD_ONLY; /* LTE TDD Only mode. */
+constexpr int Phone_utils::NETWORK_MODE_CDMA_GSM; /* CDMA,GSM(2G Global) */
+constexpr int Phone_utils::NETWORK_MODE_CDMA_EVDO_GSM; /* CDMA,EVDO,GSM */
+constexpr int Phone_utils::NETWORK_MODE_LTE_CDMA_EVDO_GSM; /* LTE,CDMA,EVDO,GSM(4G Global, 4M) */
+
+const int Phone_utils::PHONE_TYPE_NONE = 0;
+const int Phone_utils::PHONE_TYPE_GSM = 1;
+const int Phone_utils::PHONE_TYPE_CDMA = 2;
+const int Phone_utils::PHONE_TYPE_SIP = 3;
+const int Phone_utils::PHONE_TYPE_THIRD_PARTY = 4;
+const int Phone_utils::PHONE_TYPE_IMS = 5;
+
+/// @}
+
+/**
+ * Available radio technologies for GSM, UMTS and CDMA.
+ * Duplicates the constants from hardware/radio/include/ril.h
+ * This should only be used by agents working with the ril.  Others
+ * should use the equivalent TelephonyManager.NETWORK_TYPE_*
+ */
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_UNKNOWN;
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_GPRS;
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_EDGE;
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_UMTS;
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_IS95A;
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_IS95B;
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_1xRTT;
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_EVDO_0;
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_EVDO_A;
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_HSDPA;
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_HSUPA;
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_HSPA;
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_EVDO_B;
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_EHRPD;
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_LTE;
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_HSPAP;
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_GSM;
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_TD_SCDMA;
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_IWLAN;
+constexpr int Phone_utils::RIL_RADIO_TECHNOLOGY_LTE_CA;
+
+int Phone_utils::PREFERRED_NETWORK_MODE = init();
+
+const int Phone_utils::APP_FAM_3GPP =  1;
+const int Phone_utils::APP_FAM_3GPP2 = 2;
+const int Phone_utils::APP_FAM_IMS   = 3;
+
+const std::string Phone_utils::RADIO_DSSS_SIM_DISABLE = "persist.radio.dsss.sim.disable";
+int32_t Phone_utils::disable_sim = -1;
+
+int Phone_utils::init() {
+    char mtk_protocol1_rat_config[PROPERTY_VALUE_MAX] = { 0 };
+    char opt_ps1_rat[PROPERTY_VALUE_MAX] = { 0 };
+    char default_network[PROPERTY_VALUE_MAX] = { 0 };
+    utils::mtk_property_get("ro.mtk_protocol1_rat_config",mtk_protocol1_rat_config, "");
+    utils::mtk_property_get("ro.boot.opt_ps1_rat",opt_ps1_rat, "");
+    utils::mtk_property_get("ro.telephony.default_network",default_network, "");
+    std::string mtk_rat(mtk_protocol1_rat_config);
+    std::string rat(opt_ps1_rat);
+    std::string default_rat(default_network);
+    if("C/Lf" == mtk_rat ) {
+        return NETWORK_MODE_LTE_CDMA_EVDO;
+    } else {
+        if(rat.find("C") != std::string::npos) {
+            if(rat.find("L") != std::string::npos) {
+                return NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA;
+            } else {
+                return NETWORK_MODE_GLOBAL;
+            }
+        } else  {
+            if(rat.find("L") != std::string::npos) {
+                return NETWORK_MODE_LTE_GSM_WCDMA;
+            } else {
+                return NETWORK_MODE_WCDMA_PREF;
+            }
+        }
+    }
+}
+
+int Phone_utils::get_enable_sim_for_dsss() {
+    if(disable_sim == -1) {
+        disable_sim = utils::mtk_property_get_int32(RADIO_DSSS_SIM_DISABLE.c_str(), -1);
+        LOG_D(LOG_TAG,"get_enable_sim_for_dsss: %d", disable_sim);
+    }
+
+    if(disable_sim == 2) {
+        return 0; //slot 0 enable, slot 1 disable
+    }else if(disable_sim == 1) {
+        return 1; //slot 1 enable, slot 0 disable
+    }
+    return 0;
+}
+
+Phone_utils::Phone_utils() {
+    // TODO Auto-generated constructor stub
+
+}
+
+Phone_utils::~Phone_utils() {
+    // TODO Auto-generated destructor stub
+}
+
+int Phone_utils::get_phone_count() {
+    int phoneCount = 1;
+    if(utils::is_support_dsds()) {
+        phoneCount = 2;
+    }
+    return phoneCount;
+}
+
+int Phone_utils::get_phone_type(int slot) {
+    int tech = get_voice_radio_tech(slot);
+    LOG_D(LOG_TAG,"get_phone_type: %d", tech);
+    if(isCdma(tech)){
+        return PHONE_TYPE_CDMA;
+    } else {
+        return PHONE_TYPE_GSM;
+    }
+}
+
+bool Phone_utils::isGsm(int radioTechnology){
+    return radioTechnology == RIL_RADIO_TECHNOLOGY_GPRS
+            || radioTechnology == RIL_RADIO_TECHNOLOGY_EDGE
+            || radioTechnology == RIL_RADIO_TECHNOLOGY_UMTS
+            || radioTechnology == RIL_RADIO_TECHNOLOGY_HSDPA
+            || radioTechnology == RIL_RADIO_TECHNOLOGY_HSUPA
+            || radioTechnology == RIL_RADIO_TECHNOLOGY_HSPA
+            || radioTechnology == RIL_RADIO_TECHNOLOGY_LTE
+            || radioTechnology == RIL_RADIO_TECHNOLOGY_HSPAP
+            || radioTechnology == RIL_RADIO_TECHNOLOGY_GSM
+            || radioTechnology == RIL_RADIO_TECHNOLOGY_TD_SCDMA
+            || radioTechnology == RIL_RADIO_TECHNOLOGY_IWLAN
+            || radioTechnology == RIL_RADIO_TECHNOLOGY_LTE_CA;
+}
+
+bool Phone_utils::isCdma(int radioTechnology){
+    return radioTechnology == RIL_RADIO_TECHNOLOGY_IS95A
+            || radioTechnology == RIL_RADIO_TECHNOLOGY_IS95B
+            || radioTechnology == RIL_RADIO_TECHNOLOGY_1xRTT
+            || radioTechnology == RIL_RADIO_TECHNOLOGY_EVDO_0
+            || radioTechnology == RIL_RADIO_TECHNOLOGY_EVDO_A
+            || radioTechnology == RIL_RADIO_TECHNOLOGY_EVDO_B
+            || radioTechnology == RIL_RADIO_TECHNOLOGY_EHRPD;
+}
+
+bool Phone_utils::isLte(int radioTechnology){
+    return radioTechnology == RIL_RADIO_TECHNOLOGY_LTE ||
+            radioTechnology == RIL_RADIO_TECHNOLOGY_LTE_CA;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Phone_utils.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Phone_utils.h
new file mode 100644
index 0000000..b05e5a0
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Phone_utils.h
@@ -0,0 +1,130 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef SRC_UTIL_PHONE_UTILS_H_
+#define SRC_UTIL_PHONE_UTILS_H_
+
+#include <string>
+#include <vendor-ril/telephony/ril.h>
+
+class Phone_utils {
+public:
+    Phone_utils();
+    virtual ~Phone_utils();
+    static int get_phone_count();
+    static bool isGsm(int radioTechnology);
+    static bool isCdma(int radioTechnology);
+    static bool isLte(int radioTechnology);
+    static int get_enable_sim_for_dsss();
+    static int get_phone_type(int slot);
+public:
+    static const int APP_FAM_3GPP;
+    static const int APP_FAM_3GPP2;
+    static const int APP_FAM_IMS;
+    /* NETWORK_MODE_* See ril.h RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE */
+    static constexpr int NETWORK_MODE_WCDMA_PREF     = RIL_PreferredNetworkType::PREF_NET_TYPE_GSM_WCDMA; /* GSM/WCDMA (WCDMA preferred) */
+    static constexpr int NETWORK_MODE_GSM_ONLY       = RIL_PreferredNetworkType::PREF_NET_TYPE_GSM_ONLY; /* GSM only */
+    static constexpr int NETWORK_MODE_WCDMA_ONLY     = RIL_PreferredNetworkType::PREF_NET_TYPE_WCDMA; /* WCDMA only */
+    static constexpr int NETWORK_MODE_GSM_UMTS       = RIL_PreferredNetworkType::PREF_NET_TYPE_GSM_WCDMA_AUTO; /* GSM/WCDMA (auto mode, according to PRL)
+                                            AVAILABLE Application Settings menu*/
+    static constexpr int NETWORK_MODE_CDMA           = RIL_PreferredNetworkType::PREF_NET_TYPE_CDMA_EVDO_AUTO; /* CDMA and EvDo (auto mode, according to PRL)
+                                            AVAILABLE Application Settings menu*/
+    static constexpr int NETWORK_MODE_CDMA_NO_EVDO   = RIL_PreferredNetworkType::PREF_NET_TYPE_CDMA_ONLY; /* CDMA only */
+    static constexpr int NETWORK_MODE_EVDO_NO_CDMA   = RIL_PreferredNetworkType::PREF_NET_TYPE_EVDO_ONLY; /* EvDo only */
+    static constexpr int NETWORK_MODE_GLOBAL         = RIL_PreferredNetworkType::PREF_NET_TYPE_GSM_WCDMA_CDMA_EVDO_AUTO; /* GSM/WCDMA, CDMA, and EvDo (auto mode, according to PRL)
+                                            AVAILABLE Application Settings menu*/
+    static constexpr int NETWORK_MODE_LTE_CDMA_EVDO  = RIL_PreferredNetworkType::PREF_NET_TYPE_LTE_CDMA_EVDO; /* LTE, CDMA and EvDo */
+    static constexpr int NETWORK_MODE_LTE_GSM_WCDMA  = RIL_PreferredNetworkType::PREF_NET_TYPE_LTE_GSM_WCDMA; /* LTE, GSM/WCDMA */
+    static constexpr int NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA = RIL_PreferredNetworkType::PREF_NET_TYPE_LTE_CMDA_EVDO_GSM_WCDMA; /* LTE, CDMA, EvDo, GSM/WCDMA */
+    static constexpr int NETWORK_MODE_LTE_ONLY       = RIL_PreferredNetworkType::PREF_NET_TYPE_LTE_ONLY; /* LTE Only mode. */
+    static constexpr int NETWORK_MODE_LTE_WCDMA      = RIL_PreferredNetworkType::PREF_NET_TYPE_LTE_WCDMA; /* LTE/WCDMA */
+    static constexpr int NETWORK_MODE_TDSCDMA_ONLY            = 13; /*RIL_PreferredNetworkType::PREF_NET_TYPE_TD_SCDMA_ONLY;  TD-SCDMA only */
+    static constexpr int NETWORK_MODE_TDSCDMA_WCDMA           = 14; /*RIL_PreferredNetworkType::PREF_NET_TYPE_TD_SCDMA_WCDMA;  TD-SCDMA and WCDMA */
+    static constexpr int NETWORK_MODE_LTE_TDSCDMA             = 15; /*RIL_PreferredNetworkType::PREF_NET_TYPE_TD_SCDMA_LTE; TD-SCDMA and LTE */
+    static constexpr int NETWORK_MODE_TDSCDMA_GSM             = 16; /*RIL_PreferredNetworkType::PREF_NET_TYPE_TD_SCDMA_GSM;  TD-SCDMA and GSM */
+    static constexpr int NETWORK_MODE_LTE_TDSCDMA_GSM         = 17; /*RIL_PreferredNetworkType::PREF_NET_TYPE_TD_SCDMA_GSM_LTE;  TD-SCDMA,GSM and LTE */
+    static constexpr int NETWORK_MODE_TDSCDMA_GSM_WCDMA       = 18; /*RIL_PreferredNetworkType::PREF_NET_TYPE_TD_SCDMA_GSM_WCDMA;  TD-SCDMA, GSM/WCDMA */
+    static constexpr int NETWORK_MODE_LTE_TDSCDMA_WCDMA       = 19; /*RIL_PreferredNetworkType::PREF_NET_TYPE_TD_SCDMA_WCDMA_LTE;  TD-SCDMA, WCDMA and LTE */
+    static constexpr int NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA   =  20; /*RIL_PreferredNetworkType::PREF_NET_TYPE_TD_SCDMA_GSM_WCDMA_LTE;  TD-SCDMA, GSM/WCDMA and LTE */
+    static constexpr int NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA  = 21; /*RIL_PreferredNetworkType::PREF_NET_TYPE_TD_SCDMA_GSM_WCDMA_CDMA_EVDO_AUTO; TD-SCDMA,EvDo,CDMA,GSM/WCDMA*/
+    static constexpr int NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = 22; /*RIL_PreferredNetworkType::PREF_NET_TYPE_TD_SCDMA_LTE_CDMA_EVDO_GSM_WCDMA;  TD-SCDMA/LTE/GSM/WCDMA, CDMA, and EvDo */
+    /// M: [Network][C2K]Add the MTK new network type. @{
+    static constexpr int NETWORK_MODE_LTE_GSM        = 30; /*LTE/GSM */
+    static constexpr int NETWORK_MODE_LTE_TDD_ONLY   = 31; /* LTE TDD Only mode. */
+    static constexpr int NETWORK_MODE_CDMA_GSM                         = 32; /* CDMA,GSM(2G Global) */
+    static constexpr int NETWORK_MODE_CDMA_EVDO_GSM                    = 33; /* CDMA,EVDO,GSM */
+    static constexpr int NETWORK_MODE_LTE_CDMA_EVDO_GSM                = 34; /* LTE,CDMA,EVDO,GSM(4G Global, 4M) */
+    static const int PHONE_TYPE_NONE;
+    static const int PHONE_TYPE_GSM;
+    static const int PHONE_TYPE_CDMA;
+    static const int PHONE_TYPE_SIP;
+    static const int PHONE_TYPE_THIRD_PARTY;
+    static const int PHONE_TYPE_IMS;
+    /**
+     * Available radio technologies for GSM, UMTS and CDMA.
+     * Duplicates the constants from hardware/radio/include/ril.h
+     * This should only be used by agents working with the ril.  Others
+     * should use the equivalent TelephonyManager.NETWORK_TYPE_*
+     */
+    static constexpr int RIL_RADIO_TECHNOLOGY_UNKNOWN = RIL_RadioTechnology::RADIO_TECH_UNKNOWN;
+    static constexpr int RIL_RADIO_TECHNOLOGY_GPRS = RIL_RadioTechnology::RADIO_TECH_GPRS;
+    static constexpr int RIL_RADIO_TECHNOLOGY_EDGE = RIL_RadioTechnology::RADIO_TECH_EDGE;
+    static constexpr int RIL_RADIO_TECHNOLOGY_UMTS = RIL_RadioTechnology::RADIO_TECH_UMTS;
+    static constexpr int RIL_RADIO_TECHNOLOGY_IS95A = RIL_RadioTechnology::RADIO_TECH_IS95A;
+    static constexpr int RIL_RADIO_TECHNOLOGY_IS95B = RIL_RadioTechnology::RADIO_TECH_IS95B;
+    static constexpr int RIL_RADIO_TECHNOLOGY_1xRTT = RIL_RadioTechnology::RADIO_TECH_1xRTT;
+    static constexpr int RIL_RADIO_TECHNOLOGY_EVDO_0 = RIL_RadioTechnology::RADIO_TECH_EVDO_0;
+    static constexpr int RIL_RADIO_TECHNOLOGY_EVDO_A = RIL_RadioTechnology::RADIO_TECH_EVDO_A;
+    static constexpr int RIL_RADIO_TECHNOLOGY_HSDPA = RIL_RadioTechnology::RADIO_TECH_HSDPA;
+    static constexpr int RIL_RADIO_TECHNOLOGY_HSUPA = RIL_RadioTechnology::RADIO_TECH_HSUPA;
+    static constexpr int RIL_RADIO_TECHNOLOGY_HSPA = RIL_RadioTechnology::RADIO_TECH_HSPA;
+    static constexpr int RIL_RADIO_TECHNOLOGY_EVDO_B = RIL_RadioTechnology::RADIO_TECH_EVDO_B;
+    static constexpr int RIL_RADIO_TECHNOLOGY_EHRPD = RIL_RadioTechnology::RADIO_TECH_EHRPD;
+    static constexpr int RIL_RADIO_TECHNOLOGY_LTE = RIL_RadioTechnology::RADIO_TECH_LTE;
+    static constexpr int RIL_RADIO_TECHNOLOGY_HSPAP = RIL_RadioTechnology::RADIO_TECH_HSPAP;
+    static constexpr int RIL_RADIO_TECHNOLOGY_GSM = RIL_RadioTechnology::RADIO_TECH_GSM;
+    static constexpr int RIL_RADIO_TECHNOLOGY_TD_SCDMA = RIL_RadioTechnology::RADIO_TECH_TD_SCDMA;
+    static constexpr int RIL_RADIO_TECHNOLOGY_IWLAN = RIL_RadioTechnology::RADIO_TECH_IWLAN;
+    static constexpr int RIL_RADIO_TECHNOLOGY_LTE_CA = 19;//RIL_RadioTechnology::RADIO_TECH_LTE_CA;
+
+    static int PREFERRED_NETWORK_MODE;
+private:
+    static const std::string RADIO_DSSS_SIM_DISABLE;
+    static int32_t disable_sim;
+private:
+    static int init();
+};
+
+#endif /* SRC_UTIL_PHONE_UTILS_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Proxycontroller.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Proxycontroller.cpp
new file mode 100644
index 0000000..d173c71
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Proxycontroller.cpp
@@ -0,0 +1,772 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <log/log.h>
+#include <set>
+#include <stdexcept>
+
+#include "Proxycontroller.h"
+#include "common.h"
+#include "network.h"
+#include "data.h"
+#include "bitset"
+#include "utils.h"
+#include "WorldPhoneUtil.h"
+
+#define LOG_TAG "DEMO_Proxy_controller"
+
+constexpr int Proxy_controller::EVENT_NOTIFICATION_RC_CHANGED;
+constexpr int Proxy_controller::EVENT_START_RC_RESPONSE;
+constexpr int Proxy_controller::EVENT_APPLY_RC_RESPONSE;
+constexpr int Proxy_controller::EVENT_FINISH_RC_RESPONSE;
+constexpr int Proxy_controller::EVENT_TIMEOUT;
+
+const int Proxy_controller::SET_RC_STATUS_IDLE             = 0;
+const int Proxy_controller::SET_RC_STATUS_STARTING         = 1;
+const int Proxy_controller::SET_RC_STATUS_STARTED          = 2;
+const int Proxy_controller::SET_RC_STATUS_APPLYING         = 3;
+const int Proxy_controller::SET_RC_STATUS_SUCCESS          = 4;
+const int Proxy_controller::SET_RC_STATUS_FAIL             = 5;
+
+const std::string Proxy_controller::PROPERTY_CAPABILITY_SWITCH = "persist.vendor.radio.simswitch";
+const std::string Proxy_controller::PROPERTY_CAPABILITY_SWITCH_STATE = "persist.vendor.radio.simswitchstate";
+
+// event 1-5 is defined in ProxyController
+const int Proxy_controller::EVENT_RADIO_AVAILABLE = 6;
+const int Proxy_controller::EVENT_RIL_CONNECTED = 7;
+
+// marker for retry cause
+const int Proxy_controller::RC_RETRY_CAUSE_NONE                  = 0;
+const int Proxy_controller::RC_RETRY_CAUSE_WORLD_MODE_SWITCHING  = 1;
+const int Proxy_controller::RC_RETRY_CAUSE_CAPABILITY_SWITCHING  = 2;
+const int Proxy_controller::RC_RETRY_CAUSE_IN_CALL               = 3;
+const int Proxy_controller::RC_RETRY_CAUSE_RADIO_UNAVAILABLE     = 4;
+const int Proxy_controller::RC_RETRY_CAUSE_AIRPLANE_MODE         = 5;
+const int Proxy_controller::RC_RETRY_CAUSE_RESULT_ERROR          = 6;
+
+    // marker for switch conditions pre-checking
+const int Proxy_controller::RC_DO_SWITCH       = 0;
+const int Proxy_controller::RC_NO_NEED_SWITCH  = 1;
+const int Proxy_controller::RC_CANNOT_SWITCH   = 2;
+
+Proxy_controller* Proxy_controller::sInstance = nullptr;
+    // The entire transaction must complete within this amount of time
+    // or a FINISH will be issued to each Logical Modem with the old
+    // Radio Access Family.
+const int Proxy_controller::SET_RC_TIMEOUT_WAITING_MSEC    = (45 * 1000);
+
+Proxy_controller::Proxy_controller() :mRadioCapabilitySessionId(0), mTransactionFailed(false){
+    //***** Class Variables
+    mIsCapSwitching = false;
+    mHasRegisterWorldModeReceiver = false;
+    mHasRegisterPhoneStateReceiver = false;
+    mHasRegisterEccStateReceiver = false;
+    mIsRildReconnected = false;
+    mSetRafRetryCause = RC_RETRY_CAUSE_NONE;
+    // Exception counter
+    onExceptionCount = 0;
+    clearTransaction();
+}
+
+Proxy_controller::~Proxy_controller() {
+    // TODO Auto-generated destructor stub
+}
+
+Proxy_controller::Handle_thread::Handle_thread(): m_looper(NULL){
+    RLOGD("RequestHandleThread created");
+}
+
+Proxy_controller::Handle_thread::~Handle_thread() {
+    RLOGD("RequestHandleThread destroyed");
+}
+
+sp<Looper> Proxy_controller::Handle_thread::getLooper() {
+    return m_looper;
+}
+
+bool Proxy_controller::Handle_thread::threadLoop() {
+    RLOGD("Handler threadLoop");
+    m_looper = Looper::prepare(0);
+    int result;
+    do {
+        result = m_looper->pollAll(-1);
+        RLOGD("Handler threadLoop, pull message result = %d", result);
+    } while (result == Looper::POLL_WAKE || result == Looper::POLL_CALLBACK);
+    return true;
+}
+
+Proxy_controller::Request_message::Request_message(): what(0), slot(-1),e(RIL_E_SUCCESS), is_rc_set(true),id(-1){
+
+}
+
+void Proxy_controller::init() {
+    handle_thread = new Handle_thread();
+    handle_thread->run();
+}
+
+Proxy_controller *Proxy_controller::getInstance() {
+    if (sInstance == NULL) {
+        sInstance = new Proxy_controller();
+        sInstance->init();
+    }
+    return sInstance;
+}
+
+sp<Proxy_controller::Request_handler> Proxy_controller::sendMessage(sp<Request_message> msg, int delayms) {
+    RLOGD("sendMessage msg what=%d delayms=%d", msg->what, delayms);
+    // Create a handler to handle this message
+    sp<Request_handler> handler = new Request_handler(this);
+    handler->msg = msg;
+    // Sand message to looper
+    if(handle_thread.get()) {
+        sp<Looper> looper = handle_thread->getLooper();
+        if(looper.get()) {
+            if (delayms > 0) {
+                looper->sendMessageDelayed(ms2ns(delayms),handler, handler->m_dummyMsg);
+            } else {
+                looper->sendMessage(handler, handler->m_dummyMsg);
+            }
+        } else {
+            RLOGD("looper");
+        }
+    } else {
+        RLOGD("handle_thread");
+    }
+
+    return handler;
+}
+
+void Proxy_controller::handle_request_resp(RIL_RadioCapability* cap, RIL_Errno e, int slot) {
+    if(m_eventId[slot] < 0) {
+        RLOGD("handle_request_resp cap is null.m_eventId[%d]=%d", slot, m_eventId[slot]);
+        return;
+    }
+    RLOGD("handle_request_resp what[%d]: %d , phase: %d", slot,m_eventId[slot], cap->phase);
+    // Create a request message
+    sp<Request_message> msg = new Request_message();
+    msg->what = m_eventId[slot];
+    if(cap != NULL) {
+        msg->cap = (*cap);
+    } else {
+        msg->is_rc_set = false;
+        RLOGD("handle_request_resp[slot%d]: cap is null", slot);
+    }
+    msg->e = e;
+    msg->slot = slot;
+    RLOGD("handle_request_resp logicalModemUuid: %s , phase: %d, rat: %d, session: %d, status: %d, version: %d",
+            msg->cap.logicalModemUuid, msg->cap.phase, msg->cap.rat, msg->cap.session, msg->cap.status, msg->cap.version);
+    sendMessage(msg, 0);
+}
+
+void Proxy_controller::issueFinish(int sessionId) {
+    m_mutex.lock();
+    for (int i = 0; i < SIM_COUNT; i++) {
+        RLOGD("issueFinish: phoneId=%d sessionId= %d  mTransactionFailed=%d", i, sessionId, mTransactionFailed);
+        mRadioAccessFamilyStatusCounter++;
+        sendRadioCapabilityRequest(
+                i,
+                sessionId,
+                RadioCapabilityPhase(RC_PHASE_FINISH),
+                (mTransactionFailed ? mOldRadioAccessFamily[i] :
+                mNewRadioAccessFamily[i]),
+                (mTransactionFailed ? mCurrentLogicalModemIds[i] :
+                mNewLogicalModemIds[i]),
+                (mTransactionFailed ? RadioCapabilityStatus(RC_STATUS_FAIL) :
+                        RadioCapabilityStatus(RC_STATUS_SUCCESS)),
+                EVENT_FINISH_RC_RESPONSE);
+        if (mTransactionFailed) {
+            RLOGD("issueFinish: phoneId: %d status: FAIL", i);
+            // At least one failed, mark them all failed.
+            mSetRadioAccessFamilyStatus[i] = SET_RC_STATUS_FAIL;
+        }
+    }
+    m_mutex.unlock();
+}
+
+void Proxy_controller::onStartRadioCapabilityResponse(sp<Request_message> msg) {
+    m_mutex.lock();
+
+    RIL_RadioCapability rc = msg->cap;
+    if ((rc.session != mRadioCapabilitySessionId.load())) {
+        RLOGD("onStartRadioCapabilityResponse: Ignore session=%d,rc.logicalModemUuid = %d, rc.phase = %d, rc.rat = %d, rc.session = %d, rc.status = %d, rc.version = %d",
+                mRadioCapabilitySessionId.load(), rc.logicalModemUuid,rc.phase,rc.rat,rc.session,rc.status,rc.version);
+        return;
+    }
+    mRadioAccessFamilyStatusCounter--;
+    int id = msg->slot;
+    if (msg->e != RIL_E_SUCCESS) {
+        RLOGD("onStartRadioCapabilityResponse: Error response session=%d", rc.session);
+        RLOGD("onStartRadioCapabilityResponse: phoneId=%d status=FAIL", id);
+        mSetRadioAccessFamilyStatus[id] = SET_RC_STATUS_FAIL;
+        mTransactionFailed = true;
+    } else {
+        RLOGD("onStartRadioCapabilityResponse: phoneId=%d status=STARTED", id);
+        mSetRadioAccessFamilyStatus[id] = SET_RC_STATUS_STARTED;
+    }
+
+    if (mRadioAccessFamilyStatusCounter == 0) {
+        /**
+        std::set<std::string> modemsInUse;
+        for (auto modemId : mNewLogicalModemIds) {
+            if (!(modemsInUse.insert(modemId).second)) {
+                mTransactionFailed = true;
+                RLOGD("ERROR: sending down the same id for different phones");
+            }
+        }
+        **/
+        RLOGD("onStartRadioCapabilityResponse: success=%d", !mTransactionFailed);
+        if (mTransactionFailed) {
+            // Sends a variable number of requests, so don't resetRadioAccessFamilyCounter
+            // here.
+            m_mutex.unlock();
+            issueFinish(mRadioCapabilitySessionId.load());
+            return;
+        } else {
+            // All logical modem accepted the new radio access family, issue the APPLY
+            resetRadioAccessFamilyStatusCounter();
+            for (int i = 0; i < SIM_COUNT; i++) {
+                sendRadioCapabilityRequest(
+                    i,
+                    mRadioCapabilitySessionId.load(),
+                    RadioCapabilityPhase(RC_PHASE_APPLY),
+                    mNewRadioAccessFamily[i],
+                    mNewLogicalModemIds[i],
+                    RadioCapabilityStatus(RC_STATUS_NONE),
+                    EVENT_APPLY_RC_RESPONSE);
+
+               RLOGD("onStartRadioCapabilityResponse: phoneId=%d status=APPLYING", i);
+                mSetRadioAccessFamilyStatus[i] = SET_RC_STATUS_APPLYING;
+            }
+        }
+    }
+    m_mutex.unlock();
+}
+
+void Proxy_controller::onApplyRadioCapabilityErrorHandler(sp<Request_message> msg){
+
+}
+void Proxy_controller::onApplyExceptionHandler(sp<Request_message> msg){
+
+}
+
+void Proxy_controller::onApplyRadioCapabilityResponse(sp<Request_message> msg) {
+    RIL_RadioCapability rc = msg->cap;
+    if ((rc.session != mRadioCapabilitySessionId.load())) {
+        RLOGD("onApplyRadioCapabilityResponse: Ignore session=%d,rc.logicalModemUuid = %d, rc.phase = %d, rc.rat = %d, rc.session = %d, rc.status = %d, rc.version = %d",
+                mRadioCapabilitySessionId.load(), rc.logicalModemUuid,rc.phase,rc.rat,rc.session,rc.status,rc.version);
+        /// M: handle rc error, retry sim switch if possible. @{
+        onApplyRadioCapabilityErrorHandler(msg);
+        /// @}
+        return;
+    }
+    RLOGD("onApplyRadioCapabilityResponse: rc.logicalModemUuid = %d, rc.phase = %d, rc.rat = %d, rc.session = %d, rc.status = %d, rc.version = %d",
+                mRadioCapabilitySessionId.load(), rc.logicalModemUuid,rc.phase,rc.rat,rc.session,rc.status,rc.version);
+    if (msg->e != RIL_E_SUCCESS) {
+        m_mutex.lock();
+        RLOGD("onApplyRadioCapabilityResponse: Error response session=%d",rc.session);
+        int id = msg->slot;
+        /// M: handle exception, retry sim switch if possible. @{
+        onApplyExceptionHandler(msg);
+        /// @}
+        RLOGD("onApplyRadioCapabilityResponse: phoneId=%d status=FAIL", id);
+        mSetRadioAccessFamilyStatus[id] = SET_RC_STATUS_FAIL;
+        mTransactionFailed = true;
+        m_mutex.unlock();
+    } else {
+        RLOGD("onApplyRadioCapabilityResponse: Valid start expecting notification rc.logicalModemUuid = %d, rc.phase = %d, rc.rat = %d, rc.session = %d, rc.status = %d, rc.version = %d",
+                mRadioCapabilitySessionId.load(), rc.logicalModemUuid,rc.phase,rc.rat,rc.session,rc.status,rc.version);
+    }
+}
+
+void Proxy_controller::handle_message_notify(RIL_RadioCapability* cap,int slot) {
+    sp<Request_message> msg = new Request_message();
+    msg->what = EVENT_NOTIFICATION_RC_CHANGED;
+    if(cap != NULL) {
+        msg->cap = (*cap);
+    } else {
+        msg->is_rc_set = false;
+        RLOGD("handle_request_resp[slot%d]: cap is null", slot);
+    }
+    msg->slot = slot;
+    RLOGD("handle_request_resp logicalModemUuid: %s , phase: %d, rat: %d, session: %d, status: %d, version: %d",
+            msg->cap.logicalModemUuid, msg->cap.phase, msg->cap.rat, msg->cap.session, msg->cap.status, msg->cap.version);
+    sendMessage(msg, 0);
+}
+
+void Proxy_controller::onNotificationRadioCapabilityChanged(sp<Request_message> msg) {
+    RIL_RadioCapability rc = msg->cap;
+    if (msg->is_rc_set == false || (rc.session != mRadioCapabilitySessionId.load())) {
+        RLOGD("onNotificationRadioCapabilityChanged: Ignore session=%d,rc.logicalModemUuid = %d, rc.phase = %d, rc.rat = %d, rc.session = %d, rc.status = %d, rc.version = %d",
+                mRadioCapabilitySessionId.load(), rc.logicalModemUuid,rc.phase,rc.rat,rc.session,rc.status,rc.version);
+        return;
+    }
+    m_mutex.lock();
+    RLOGD("onNotificationRadioCapabilityChanged: rc.logicalModemUuid = %d, rc.phase = %d, rc.rat = %d, rc.session = %d, rc.status = %d, rc.version = %d",
+            rc.logicalModemUuid,rc.phase,rc.rat,rc.session,rc.status,rc.version);
+
+    int id = msg->slot;
+    if (msg-> e != RIL_E_SUCCESS ||
+            (rc.status == RadioCapabilityStatus(RC_STATUS_FAIL))) {
+        RLOGD("onNotificationRadioCapabilityChanged: phoneId=%d status=FAIL", id);
+        mSetRadioAccessFamilyStatus[id] = SET_RC_STATUS_FAIL;
+        mTransactionFailed = true;
+    } else {
+        RLOGD("onNotificationRadioCapabilityChanged: phoneId=%d status=SUCCESS(%d)", id, !mTransactionFailed);
+        mSetRadioAccessFamilyStatus[id] = SET_RC_STATUS_SUCCESS;
+        // The modems may have been restarted and forgotten this
+
+        RequestInfo *info = creatRILInfoAndInit(RIL_REQUEST_ALLOW_DATA, OTHER, (RIL_SOCKET_ID)id);
+
+        int switch_id = get_default_sim_data_for_switch();
+        RLOGD("onNotificationRadioCapabilityChanged: phoneId=%d switch_id=%d", id, switch_id);
+        char* argv[2] = {"RIL_REQUEST_ALLOW_DATA","0"};
+        if(id == switch_id) {
+            argv[1] = "1";
+        }
+        setDataAllowed(2, argv, RIL_SOCKET_ID(id), info);
+    }
+
+    mRadioAccessFamilyStatusCounter--;
+    if (mRadioAccessFamilyStatusCounter == 0) {
+        RLOGD("onNotificationRadioCapabilityChanged: APPLY URC success=%d",!mTransactionFailed);
+        m_mutex.unlock();
+        issueFinish(mRadioCapabilitySessionId.load());
+        return;
+    }
+    m_mutex.unlock();
+}
+
+void Proxy_controller::completeRadioCapabilityTransaction() {
+    RLOGD("completeRadioCapabilityTransaction: success=%d" , !mTransactionFailed);
+    if (!mTransactionFailed) {
+
+
+        // make messages about the old transaction obsolete (specifically the timeout)
+        //mRadioCapabilitySessionId++;
+
+        // Reinitialize
+        clearTransaction();
+        android::emResultNotify("default data slot switch success\n");
+    } else {
+        android::emResultNotify("default data slot switch fail, now retry\n");
+        // now revert.
+        mTransactionFailed = false;
+        std::vector<RIL_RadioAccessFamily> rafs = {RAF_UNKNOWN, RAF_UNKNOWN};
+        for (int phoneId = 0; phoneId < SIM_COUNT; phoneId++) {
+            rafs[phoneId] = (RIL_RadioAccessFamily)mOldRadioAccessFamily[phoneId];
+        }
+        doSetRadioCapabilities(rafs);
+    }
+
+}
+
+void Proxy_controller::onFinishRadioCapabilityResponse(sp<Request_message> msg){
+    RIL_RadioCapability rc = msg->cap;;
+    if (msg->is_rc_set == false || (rc.session != mRadioCapabilitySessionId.load())) {
+        RLOGD("onFinishRadioCapabilityResponse: Ignore session=%d,rc.logicalModemUuid = %d, rc.phase = %d, rc.rat = %d, rc.session = %d, rc.status = %d, rc.version = %d",
+                mRadioCapabilitySessionId.load(), rc.logicalModemUuid,rc.phase,rc.rat,rc.session,rc.status,rc.version);
+        return;
+    }
+    m_mutex.lock();
+    RLOGD("onFinishRadioCapabilityResponse mRadioAccessFamilyStatusCounter=%d",mRadioAccessFamilyStatusCounter);
+    mRadioAccessFamilyStatusCounter--;
+    if (mRadioAccessFamilyStatusCounter == 0) {
+        m_mutex.unlock();
+        completeRadioCapabilityTransaction();
+        return;
+    }
+    m_mutex.unlock();
+}
+
+void Proxy_controller::onTimeoutRadioCapability(sp<Request_message> msg){
+    if (msg->id != mRadioCapabilitySessionId.load()) {
+       RLOGD("RadioCapability timeout: Ignore msg->id=%d != mRadioCapabilitySessionId.load()=%d", msg->id,mRadioCapabilitySessionId.load());
+        return;
+    }
+
+    m_mutex.lock();
+    // timed-out.  Clean up as best we can
+    for (int i = 0; i < SIM_COUNT; i++) {
+        RLOGD("RadioCapability timeout: mSetRadioAccessFamilyStatus[%d]=%d",i,mSetRadioAccessFamilyStatus[i]);
+    }
+
+    // Increment the sessionId as we are completing the transaction below
+    // so we don't want it completed when the FINISH phase is done.
+    mRadioCapabilitySessionId++;
+
+    // Reset the status counter as existing session failed
+    mRadioAccessFamilyStatusCounter = 0;
+
+    // send FINISH request with fail status and then uniqueDifferentId
+    mTransactionFailed = true;
+    m_mutex.unlock();
+    issueFinish(mRadioCapabilitySessionId.load());
+}
+
+void Proxy_controller::Request_handler::sendMessage(sp<Request_message> msg, int delayms) {
+    RLOGD("Proxy_controller::Request_handler, sendMessage msg what=%d delayms=%d", msg->what, delayms);
+    // Sand message to looper
+    this->msg = msg;
+    if (delayms > 0) {
+        proxy_controller->handle_thread->getLooper()->sendMessageDelayed(ms2ns(delayms),
+                this, this->m_dummyMsg);
+    } else {
+        proxy_controller->handle_thread->getLooper()->sendMessage(this, this->m_dummyMsg);
+    }
+    return ;
+}
+
+void Proxy_controller::Request_handler::handleMessage(const Message& message) {
+
+    RLOGD("handleMessage msg->what: %d", msg->what);
+    switch( msg->what){
+    case EVENT_START_RC_RESPONSE:
+    {
+        proxy_controller->onStartRadioCapabilityResponse(msg);
+        break;
+    }
+    case EVENT_APPLY_RC_RESPONSE:
+    {
+        proxy_controller->onApplyRadioCapabilityResponse(msg);
+        break;
+    }
+    case EVENT_NOTIFICATION_RC_CHANGED:
+    {
+        proxy_controller->onNotificationRadioCapabilityChanged(msg);
+        break;
+    }
+    case EVENT_FINISH_RC_RESPONSE:
+    {
+        proxy_controller->onFinishRadioCapabilityResponse(msg);
+        break;
+    }
+    case EVENT_TIMEOUT:
+    {
+        proxy_controller->onTimeoutRadioCapability(msg);
+        break;
+    }
+    default:
+        break;
+    }
+}
+
+void Proxy_controller::clearTransaction() {
+    RLOGD("clearTransaction");
+    m_mutex.lock();
+    mSetRadioAccessFamilyStatus.clear();
+    mOldRadioAccessFamily.clear();
+    mNewRadioAccessFamily.clear();
+    m_eventId.clear();
+    mCurrentLogicalModemIds.clear();
+    mNewLogicalModemIds.clear();
+    for (int i = 0; i < 2; i++) {
+        RLOGD("clearTransaction: phoneId=%d status=IDLE",i);
+        mSetRadioAccessFamilyStatus.push_back(SET_RC_STATUS_IDLE);
+        mOldRadioAccessFamily.push_back(0);
+        mNewRadioAccessFamily.push_back(0);
+        mCurrentLogicalModemIds.push_back("");
+        mNewLogicalModemIds.push_back("");
+        mTransactionFailed = false;
+        m_eventId.push_back(-1);
+    }
+    if(handle_thread.get()) {
+        sp<Looper> looper = handle_thread->getLooper();
+        if(looper.get()) {
+            if(timeout_handle.get()) {
+                looper->removeMessages(timeout_handle);
+            } else {
+                RLOGD("clearTransaction,timeout_handle");
+            }
+        } else {
+            RLOGD("clearTransaction,looper");
+        }
+    } else {
+        RLOGD("clearTransaction,handle_thread");
+    }
+    m_mutex.unlock();
+}
+
+int Proxy_controller::checkRadioCapabilitySwitchConditions(std::vector<RIL_RadioAccessFamily> rafs) {
+    m_mutex.lock();
+    mNextRafs = rafs;
+
+    // check if still switching
+    if (mIsCapSwitching == true) {
+        //throw new RuntimeException("is still switching");
+        RLOGD("keep it and return,because capability swithing");
+        mSetRafRetryCause = RC_RETRY_CAUSE_CAPABILITY_SWITCHING;
+        return RC_NO_NEED_SWITCH;
+    } else if (mSetRafRetryCause == RC_RETRY_CAUSE_CAPABILITY_SWITCHING) {
+        RLOGD("setCapability, mIsCapSwitching is not switching, can switch");
+        mSetRafRetryCause = RC_RETRY_CAUSE_NONE;
+    }
+    mIsCapSwitching = true;
+    m_mutex.lock();
+
+    // check if capability switch disabled
+    if (utils::mtk_property_get_bool("ro.vendor.mtk_disable_cap_switch", false) == true) {
+        mNextRafs.clear();
+        completeRadioCapabilityTransaction();
+        RLOGD("skip switching because mtk_disable_cap_switch is true");
+        return RC_NO_NEED_SWITCH;
+    }
+    // check FTA mode
+    if (utils::mtk_property_get_int32("vendor.gsm.gcf.testmode", 0) == 2) {
+        mNextRafs.clear();
+        completeRadioCapabilityTransaction();
+        RLOGD("skip switching because FTA mode");
+        return RC_NO_NEED_SWITCH;
+    }
+    // check EM disable mode
+    if (utils::mtk_property_get_int32("persist.vendor.radio.simswitch.emmode", 1) == 0) {
+        mNextRafs.clear();
+        completeRadioCapabilityTransaction();
+        RLOGD("skip switching because EM disable mode");
+        return RC_NO_NEED_SWITCH;
+    }
+
+    // check world mode switching
+    if (WorldPhoneUtil::isWorldPhoneSupport()) {
+        if (!WorldPhoneUtil::isWorldModeSupport()) {
+            if (/*ModemSwitchHandler.isModemTypeSwitching()*/!isRadioAvailable((RIL_SOCKET_ID)Radio_capability_switch_util::get_main_capability_phone_id())) {
+                RLOGD("world mode switching.");
+                if (!mHasRegisterWorldModeReceiver) {
+                    mHasRegisterWorldModeReceiver = true;
+                }
+                mSetRafRetryCause = RC_RETRY_CAUSE_WORLD_MODE_SWITCHING;
+                m_mutex.lock();
+                mIsCapSwitching = false;
+                m_mutex.unlock();
+                return RC_CANNOT_SWITCH;
+            }
+        } else if (mSetRafRetryCause == RC_RETRY_CAUSE_WORLD_MODE_SWITCHING) {
+            if (mHasRegisterWorldModeReceiver) {
+                mHasRegisterWorldModeReceiver = false;
+                mSetRafRetryCause = RC_RETRY_CAUSE_NONE;
+            }
+        }
+    }
+
+    // check call state
+    if (!(is_call_state_idle(0) || is_call_state_idle(1))) {
+        //throw new RuntimeException("in call, fail to set RAT for phones");
+        RLOGD("setCapability in calling, fail to set RAT for phones");
+        if (!mHasRegisterPhoneStateReceiver) {
+            mHasRegisterPhoneStateReceiver = true;
+        }
+        mSetRafRetryCause = RC_RETRY_CAUSE_IN_CALL;
+        m_mutex.lock();
+        mIsCapSwitching = false;
+        m_mutex.unlock();
+        return RC_CANNOT_SWITCH;
+    } else if (isEccInProgress()) {
+        RLOGD("setCapability in ECC, fail to set RAT for phones");
+        if (!mHasRegisterEccStateReceiver) {
+            mHasRegisterEccStateReceiver = true;
+        }
+        mSetRafRetryCause = RC_RETRY_CAUSE_IN_CALL;
+        m_mutex.lock();
+        mIsCapSwitching = false;
+        m_mutex.unlock();
+        return RC_CANNOT_SWITCH;
+    } else if (mSetRafRetryCause == RC_RETRY_CAUSE_IN_CALL) {
+        if (mHasRegisterPhoneStateReceiver) {
+            mHasRegisterPhoneStateReceiver = false;
+            mSetRafRetryCause = RC_RETRY_CAUSE_NONE;
+        }
+        if (mHasRegisterEccStateReceiver) {
+            mHasRegisterEccStateReceiver = false;
+            mSetRafRetryCause = RC_RETRY_CAUSE_NONE;
+        }
+    }
+
+    // check radio available
+    for (int i = 0; i < SIM_COUNT; i++) {
+        if (!isRadioAvailable((RIL_SOCKET_ID)i)) {
+            //throw new RuntimeException("Phone" + i + " is not available");
+            mSetRafRetryCause = RC_RETRY_CAUSE_RADIO_UNAVAILABLE;
+            //mCi[i].registerForAvailable(mMtkHandler, EVENT_RADIO_AVAILABLE, null);
+            RLOGD("setCapability fail,Phone%d is not available", i);
+            m_mutex.lock();
+            mIsCapSwitching = false;
+            m_mutex.unlock();
+            return RC_CANNOT_SWITCH;
+        } else if (mSetRafRetryCause == RC_RETRY_CAUSE_RADIO_UNAVAILABLE) {
+            //mCi[i].unregisterForAvailable(mMtkHandler);
+            if (i == SIM_COUNT - 1) {
+                mSetRafRetryCause = RC_RETRY_CAUSE_NONE;
+            }
+        }
+    }
+
+    int switchStatus = utils::mtk_property_get_int32(PROPERTY_CAPABILITY_SWITCH.c_str(), 1);
+    // check parameter
+    bool bIsboth3G = false;
+    bool bIsMajorPhone = false;
+    int newMajorPhoneId = 0;
+    for (int i = 0; i < rafs.size(); i++) {
+        bIsMajorPhone = false;
+        if ((rafs[i] & RIL_RadioAccessFamily::RAF_GPRS) > 0) {
+            bIsMajorPhone = true;
+        }
+
+        if (bIsMajorPhone) {
+            newMajorPhoneId = i;
+            if (newMajorPhoneId == (switchStatus - 1)) {
+                RLOGD("no change, skip setRadioCapability");
+                mSetRafRetryCause = RC_RETRY_CAUSE_NONE;
+                mNextRafs.clear();
+                completeRadioCapabilityTransaction();
+                return RC_NO_NEED_SWITCH;
+            }
+            if (bIsboth3G) {
+                RLOGD("set more than one 3G phone, fail");
+                m_mutex.lock();
+                mIsCapSwitching = false;
+                m_mutex.unlock();
+                throw std::runtime_error("input parameter is incorrect");
+            } else {
+                bIsboth3G = true;
+            }
+        }
+    }
+    if (bIsboth3G == false) {
+        m_mutex.lock();
+        mIsCapSwitching = false;
+        m_mutex.unlock();
+        throw std::runtime_error("input parameter is incorrect - no 3g phone");
+    }
+
+    // check operator spec
+    if (!isNeedSimSwitch(newMajorPhoneId, SIM_COUNT)) {
+        RLOGD("check sim card type and skip setRadioCapability");
+        mSetRafRetryCause = RC_RETRY_CAUSE_NONE;
+        mNextRafs.clear();
+        completeRadioCapabilityTransaction();
+        return RC_NO_NEED_SWITCH;
+    }
+
+//    if (!WorldPhoneUtil::isWorldModeSupport() && WorldPhoneUtil::isWorldPhoneSupport()) {
+//        WorldPhoneUtil.getWorldPhone().notifyRadioCapabilityChange(newMajorPhoneId);
+//    }
+    RLOGD("checkRadioCapabilitySwitchConditions, do switch");
+    return RC_DO_SWITCH;
+}
+
+bool Proxy_controller::isEccInProgress() {
+    bool inEcm = utils::mtk_property_get_bool("ril.cdma.inecmmode", false);
+    return inEcm;
+}
+
+bool Proxy_controller::isNeedSimSwitch(int majorPhoneId, int phoneNum) {
+    RLOGD("OMisNeedSimSwitch, majorPhoneId = %d ", majorPhoneId);
+    return !Radio_capability_switch_util::isSkipCapabilitySwitch(majorPhoneId, phoneNum);
+}
+
+bool Proxy_controller::set_Radio_Capability(std::vector<RIL_RadioAccessFamily> rafs) {
+    if (rafs.size() != SIM_COUNT) {
+        RLOGD("Length of input rafs must equal to total phone count");
+    }
+    // Check if there is any ongoing transaction and throw an exception if there
+    // is one as this is a programming error.
+    m_mutex.lock();
+    for (int i = 0; i < rafs.size(); i++) {
+        if (mSetRadioAccessFamilyStatus[i] != SET_RC_STATUS_IDLE) {
+            // TODO: The right behaviour is to cancel previous request and send this.
+            RLOGE("setRadioCapability: Phone[%d] is not idle. Rejecting request.", i);
+            return false;
+        }
+    }
+    m_mutex.unlock();
+
+    // Clear to be sure we're in the initial state
+    clearTransaction();
+
+    return doSetRadioCapabilities(rafs);
+}
+
+void Proxy_controller::resetRadioAccessFamilyStatusCounter() {
+    mRadioAccessFamilyStatusCounter = SIM_COUNT;
+}
+
+std::string Proxy_controller::getLogicalModemIdFromRaf(int raf) {
+    std::string modemUui;
+
+    for (int phoneId = 0; phoneId < SIM_COUNT; phoneId++) {
+        if (get_radio_capa(phoneId).rat == raf) {
+            modemUui = get_radio_capa(phoneId).logicalModemUuid;
+            break;
+        }
+    }
+    return modemUui;
+}
+
+void Proxy_controller::sendRadioCapabilityRequest(int phoneId, int sessionId, int rcPhase,
+            int radioFamily, std::string logicalModemId, int status, int eventId){
+    RequestInfo *info = creatRILInfoAndInit(RIL_REQUEST_SET_RADIO_CAPABILITY, OTHER, (RIL_SOCKET_ID)phoneId);
+
+    char* argv[7] = {"RIL_REQUEST_SET_RADIO_CAPABILITY",
+            const_cast<char*>(std::to_string(RIL_RADIO_CAPABILITY_VERSION).c_str()),
+            const_cast<char*>(std::to_string(sessionId).c_str()),
+            const_cast<char*>(std::to_string(rcPhase).c_str()),
+            const_cast<char*>(std::to_string(radioFamily).c_str()),
+            const_cast<char*>(logicalModemId.c_str()),
+            const_cast<char*>(std::to_string(status).c_str())
+    };
+    setRadioCapability(7, argv,(RIL_SOCKET_ID)phoneId, info);
+    m_eventId[phoneId] = eventId;
+}
+
+bool Proxy_controller::doSetRadioCapabilities(std::vector<RIL_RadioAccessFamily> rafs) {
+    // A new sessionId for this transaction
+    mRadioCapabilitySessionId++;
+    // Start timer to make sure all phones respond within a specific time interval.
+    // Will send FINISH if a timeout occurs.
+    sp<Request_message> msg = new Request_message();
+    msg->what = EVENT_TIMEOUT;
+    msg->id = mRadioCapabilitySessionId.load();
+    timeout_handle = sendMessage(msg, SET_RC_TIMEOUT_WAITING_MSEC);
+
+    m_mutex.lock();
+    RLOGD("setRadioCapability: new request session id=%d", mRadioCapabilitySessionId.load());
+    resetRadioAccessFamilyStatusCounter();
+    for (int i = 0; i < rafs.size(); i++) {
+        RLOGD("setRadioCapability: phoneId=%d status=STARTING", i);
+        mSetRadioAccessFamilyStatus[i] = SET_RC_STATUS_STARTING;
+        mOldRadioAccessFamily[i] = get_radio_capa(i).rat;
+        int requestedRaf = rafs[i];
+        // TODO Set the new radio access family to the maximum of the requested & supported
+        // int supportedRaf = mPhones[i].getRadioAccessFamily();
+        // mNewRadioAccessFamily[i] = requestedRaf & supportedRaf;
+        mNewRadioAccessFamily[i] = requestedRaf;
+
+        mCurrentLogicalModemIds[i] = get_radio_capa(i).logicalModemUuid;
+        // get the logical mode corresponds to new raf requested and pass the
+        // same as part of SET_RADIO_CAP APPLY phase
+        mNewLogicalModemIds[i] = getLogicalModemIdFromRaf(requestedRaf);
+        RLOGD("setRadioCapability: mOldRadioAccessFamily[%d]=%d", i,mOldRadioAccessFamily[i]);
+        RLOGD("setRadioCapability: mNewRadioAccessFamily[%d]=%d", i,mNewRadioAccessFamily[i]);
+        sendRadioCapabilityRequest(
+                i,
+                mRadioCapabilitySessionId.load(),
+                RadioCapabilityPhase(RC_PHASE_START),
+                mOldRadioAccessFamily[i],
+                mCurrentLogicalModemIds[i],
+                RadioCapabilityStatus(RC_STATUS_NONE),
+                EVENT_START_RC_RESPONSE);
+    }
+    m_mutex.unlock();
+    return true;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Proxycontroller.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Proxycontroller.h
new file mode 100644
index 0000000..da3ce2f
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Proxycontroller.h
@@ -0,0 +1,200 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef SRC_UTIL_PROXYCONTROLLER_H_
+#define SRC_UTIL_PROXYCONTROLLER_H_
+
+#include <vector>
+#include <atomic>
+#include <mutex>
+#include <string>
+
+#include <utils/Looper.h>
+#include <utils/Thread.h>
+#include <utils/RefBase.h>
+#include <vendor-ril/telephony/ril.h>
+
+using ::android::Looper;
+using ::android::Thread;
+using ::android::MessageHandler;
+using ::android::Message;
+using ::android::sp;
+using ::android::RefBase;
+
+class Proxy_controller: public RefBase {
+public:
+    static constexpr int EVENT_NOTIFICATION_RC_CHANGED = 1;
+    static constexpr int EVENT_START_RC_RESPONSE = 2;
+    static constexpr int EVENT_APPLY_RC_RESPONSE = 3;
+    static constexpr int EVENT_FINISH_RC_RESPONSE = 4;
+    static constexpr int EVENT_TIMEOUT = 5;
+
+    static const int SET_RC_STATUS_IDLE;
+    static const int SET_RC_STATUS_STARTING;
+    static const int SET_RC_STATUS_STARTED;
+    static const int SET_RC_STATUS_APPLYING;
+    static const int SET_RC_STATUS_SUCCESS;
+    static const int SET_RC_STATUS_FAIL;
+
+    // The entire transaction must complete within this amount of time
+    // or a FINISH will be issued to each Logical Modem with the old
+    // Radio Access Family.
+    static const int SET_RC_TIMEOUT_WAITING_MSEC;
+    static const std::string PROPERTY_CAPABILITY_SWITCH;
+    static const std::string PROPERTY_CAPABILITY_SWITCH_STATE;
+
+// event 1-5 is defined in ProxyController
+    static const int EVENT_RADIO_AVAILABLE;
+    static const int EVENT_RIL_CONNECTED;
+
+// marker for retry cause
+    static const int RC_RETRY_CAUSE_NONE;
+    static const int RC_RETRY_CAUSE_WORLD_MODE_SWITCHING;
+    static const int RC_RETRY_CAUSE_CAPABILITY_SWITCHING;
+    static const int RC_RETRY_CAUSE_IN_CALL;
+    static const int RC_RETRY_CAUSE_RADIO_UNAVAILABLE;
+    static const int RC_RETRY_CAUSE_AIRPLANE_MODE;
+    static const int RC_RETRY_CAUSE_RESULT_ERROR;
+
+// marker for switch conditions pre-checking
+    static const int RC_DO_SWITCH;
+    static const int RC_NO_NEED_SWITCH;
+    static const int RC_CANNOT_SWITCH;
+//***** Class Variables
+private:
+    bool mIsCapSwitching;
+    bool mHasRegisterWorldModeReceiver;
+    bool mHasRegisterPhoneStateReceiver;
+    bool mHasRegisterEccStateReceiver;
+    bool mIsRildReconnected;
+    std::vector<RIL_RadioAccessFamily> mNextRafs;
+    int mSetRafRetryCause;
+// Exception counter
+    int onExceptionCount;
+public:
+    static Proxy_controller* sInstance;
+    static Proxy_controller *getInstance();
+
+    Proxy_controller();
+    virtual ~Proxy_controller();
+    int checkRadioCapabilitySwitchConditions(std::vector<RIL_RadioAccessFamily> rafs);
+    bool isNeedSimSwitch(int majorPhoneId, int phoneNum);
+    bool isEccInProgress();
+    class Handle_thread: public Thread {
+    public:
+        Handle_thread();
+        virtual ~Handle_thread();
+        sp<Looper> getLooper();
+
+    protected:
+        virtual bool threadLoop();
+    private:
+        sp<Looper> m_looper;
+    };
+
+    class Request_message: public RefBase {
+    public:
+        Request_message();
+        virtual ~Request_message() {};
+
+    public:
+        int what;
+        int slot;
+        int id;
+        RIL_Errno e;
+        RIL_RadioCapability cap;
+        bool is_rc_set;
+    };
+
+    class Request_handler: public MessageHandler {
+    public:
+        Request_handler(Proxy_controller* proxy): proxy_controller(proxy){}
+        virtual ~Request_handler() {}
+
+    public:
+        void sendMessage(sp<Request_message> msg, int delayms);
+        void handleMessage(const Message& message);
+        sp<Request_message> msg;
+        // dummy message that makes handler happy
+        Message m_dummyMsg;
+    private:
+        Proxy_controller* proxy_controller;
+    };
+public:
+    // send message to request handler
+    sp<Request_handler> sendMessage(sp<Request_message> msg, int delayms);
+    void handle_request_resp(RIL_RadioCapability* cap, RIL_Errno e, int slot);
+    void handle_message_notify(RIL_RadioCapability* cap,int slot);
+    bool doSetRadioCapabilities(std::vector<RIL_RadioAccessFamily> rafs);
+    bool set_Radio_Capability(std::vector<RIL_RadioAccessFamily> rafs);
+private:
+    sp<Request_handler> timeout_handle;
+    sp<Handle_thread> handle_thread;
+    void init();
+    void clearTransaction();
+    void resetRadioAccessFamilyStatusCounter();
+    std::string getLogicalModemIdFromRaf(int raf);
+    void sendRadioCapabilityRequest(int phoneId, int sessionId, int rcPhase,
+                int radioFamily, std::string logicalModemId, int status, int eventId);
+    void onStartRadioCapabilityResponse(sp<Request_message> msg);
+    void onApplyRadioCapabilityResponse(sp<Request_message> msg);
+    void onApplyRadioCapabilityErrorHandler(sp<Request_message> msg);
+    void onFinishRadioCapabilityResponse(sp<Request_message> msg);
+    void onTimeoutRadioCapability(sp<Request_message> msg);
+    void onApplyExceptionHandler(sp<Request_message> msg);
+    void onNotificationRadioCapabilityChanged(sp<Request_message> msg);
+    void completeRadioCapabilityTransaction();
+    void issueFinish(int sessionId);
+private:
+    std::atomic_int mRadioCapabilitySessionId;
+    std::mutex m_mutex;
+    // record each phone's set radio capability status
+    std::vector<int> mSetRadioAccessFamilyStatus;
+    int mRadioAccessFamilyStatusCounter;
+    bool mTransactionFailed;
+
+    std::vector<std::string> mCurrentLogicalModemIds;
+    std::vector<std::string> mNewLogicalModemIds;
+
+     // Record new and old Radio Access Family (raf) configuration.
+     // The old raf configuration is used to restore each logical modem raf when FINISH is
+     // issued if any requests fail.
+    std::vector<int> mNewRadioAccessFamily;
+    std::vector<int> mOldRadioAccessFamily;
+    std::vector<int> m_eventId;
+};
+
+
+#endif /* SRC_UTIL_PROXYCONTROLLER_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Radio_capability_switch_util.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Radio_capability_switch_util.cpp
new file mode 100644
index 0000000..0147650
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Radio_capability_switch_util.cpp
@@ -0,0 +1,642 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include <utils/String8.h>
+#include <cutils/properties.h>
+#include <vendor-ril/telephony/ril.h>
+#include <bitset>
+#include <vector>
+
+#include "Radio_capability_switch_util.h"
+#include "utils.h"
+#include "log_extra.h"
+#include "Phone_utils.h"
+#include "common.h"
+#include "Proxycontroller.h"
+#include "RatConfiguration.h"
+#include "MtkRadioAccessFamily.h"
+#include "network.h"
+
+const int Radio_capability_switch_util::SIM_OP_INFO_UNKNOWN = 0;
+const int Radio_capability_switch_util::SIM_OP_INFO_OVERSEA = 1;
+const int Radio_capability_switch_util::SIM_OP_INFO_OP01 = 2;
+const int Radio_capability_switch_util::SIM_OP_INFO_OP02 = 3;
+const int Radio_capability_switch_util::SIM_OP_INFO_OP09 = 4;
+const int Radio_capability_switch_util::SIM_OP_INFO_OP18 = 4;
+
+const int Radio_capability_switch_util::SIM_TYPE_SIM = 0;
+const int Radio_capability_switch_util::SIM_TYPE_USIM = 1;
+const int Radio_capability_switch_util::SIM_TYPE_OTHER = 2;
+
+const int Radio_capability_switch_util::OP01_6M_PRIORITY_OP01_USIM = 0;
+const int Radio_capability_switch_util::OP01_6M_PRIORITY_OP01_SIM = 1;
+const int Radio_capability_switch_util::OP01_6M_PRIORITY_OTHER = 2;
+
+// sync to ril_oem.h for dsda
+const int Radio_capability_switch_util::SIM_SWITCH_MODE_SINGLE_TALK_MDSYS       = 1;
+const int Radio_capability_switch_util::SIM_SWITCH_MODE_SINGLE_TALK_MDSYS_LITE  = 2;
+const int Radio_capability_switch_util::SIM_SWITCH_MODE_DUAL_TALK               = 3;
+const int Radio_capability_switch_util::SIM_SWITCH_MODE_DUAL_TALK_SWAP          = 4;
+const int Radio_capability_switch_util::ENHANCEMENT_T_PLUS_T = 0;
+const int Radio_capability_switch_util::ENHANCEMENT_T_PLUS_W = 1;
+const int Radio_capability_switch_util::ENHANCEMENT_T_PLUS_C = 2;
+const int Radio_capability_switch_util::ENHANCEMENT_W_PLUS_C = 3;
+const int Radio_capability_switch_util::ENHANCEMENT_W_PLUS_W = 4;
+const int Radio_capability_switch_util::ENHANCEMENT_W_PLUS_NA = 5;
+
+#define LOG_TAG "DEMO_RADIO_CAPABILITY_SWITCH_UTIL"
+
+const std::string Radio_capability_switch_util::PROPERTY_ICCID = "vendor.ril.iccid.sim";
+const std::string Radio_capability_switch_util::PROPERTY_CAPABILITY_SWITCH = "persist.vendor.radio.simswitch";
+// OP01 SIMs
+const std::string Radio_capability_switch_util::PLMN_TABLE_OP01[] = {
+    "46000", "46002", "46007", "46008", "45412", "45413",
+    // Lab test IMSI
+    "00101", "00211", "00321", "00431", "00541", "00651",
+    "00761", "00871", "00902", "01012", "01122", "01232",
+    "46004", "46602", "50270"
+};
+
+// OP02 SIMs
+const std::string Radio_capability_switch_util::PLMN_TABLE_OP02[]= {
+    "46001", "46006", "46009", "45407"
+};
+
+// OP09 SIMs
+const std::string Radio_capability_switch_util::PLMN_TABLE_OP09[]= {
+    "46005", "45502", "46003", "46011"
+};
+
+// OP18 SIMs
+const std::string Radio_capability_switch_util::PLMN_TABLE_OP18[] = {
+    "405840", "405854", "405855", "405856",
+    "405857", "405858", "405855", "405856",
+    "405857", "405858", "405859", "405860",
+    "405861", "405862", "405863", "405864",
+    "405865", "405866", "405867", "405868",
+    "405869", "405870", "405871", "405872",
+    "405873", "405874"
+};
+
+// OP02 case
+const std::string Radio_capability_switch_util::NO_SIM_VALUE = "N/A";
+const std::string Radio_capability_switch_util::CN_MCC = "460";
+const std::string Radio_capability_switch_util::PROPERTY_SIM_ICCID[] = {
+    "vendor.ril.iccid.sim1",
+    "vendor.ril.iccid.sim2",
+    "vendor.ril.iccid.sim3",
+    "vendor.ril.iccid.sim4"
+};
+
+const int Radio_capability_switch_util::IMSI_NOT_READY_OR_SIM_LOCKED = 2;
+const int Radio_capability_switch_util::ICCID_ERROR = 3;
+
+// sim icc status
+// 0: imsi not ready
+// 1: imsi ready
+const std::string Radio_capability_switch_util::IMSI_NOT_READY = "0";
+const std::string Radio_capability_switch_util::IMSI_READY = "1";
+const std::string Radio_capability_switch_util::PROPERTY_SIM_IMSI_STATUS[] = {
+    "vendor.ril.imsi.status.sim1",
+    "vendor.ril.imsi.status.sim2",
+    "vendor.ril.imsi.status.sim3",
+    "vendor.ril.imsi.status.sim4"
+};
+
+const std::string Radio_capability_switch_util::PROPERTY_RIL_FULL_UICC_TYPE[] = {
+    "vendor.gsm.ril.fulluicctype",
+    "vendor.gsm.ril.fulluicctype.2",
+    "vendor.gsm.ril.fulluicctype.3",
+    "vendor.gsm.ril.fulluicctype.4",
+};
+
+const std::string Radio_capability_switch_util::PROPERTY_RIL_CT3G[] = {
+    "vendor.gsm.ril.ct3g",
+    "vendor.gsm.ril.ct3g.2",
+    "vendor.gsm.ril.ct3g.3",
+    "vendor.gsm.ril.ct3g.4",
+};
+
+#define PROPERTY_ICCID_PREIFX "vendor.ril.iccid.sim"
+
+std::string Radio_capability_switch_util::get_sim_app_type(int slot) {
+    char buf[PROPERTY_VALUE_MAX] = {0};
+    utils::mtk_property_get(PROPERTY_RIL_FULL_UICC_TYPE[slot].c_str(), buf, "");
+    std::string str(buf);
+    logd(android::String8::format("get slot(%d) type %s", slot, str.c_str()));
+    return str;
+}
+
+Radio_capability_switch_util::Radio_capability_switch_util() {
+    // TODO Auto-generated constructor stub
+}
+
+Radio_capability_switch_util::~Radio_capability_switch_util() {
+    // TODO Auto-generated destructor stub
+}
+
+int Radio_capability_switch_util::get_main_capability_phone_id() {
+    int phoneId = 0;
+    phoneId = utils::mtk_property_get_int32(PROPERTY_CAPABILITY_SWITCH.c_str(), 1) - 1;
+    logd(android::String8::format("getMainCapabilityPhoneId %d",phoneId));
+    return phoneId;
+}
+
+bool Radio_capability_switch_util::is_sim_inserted(int slot) {
+    char iccid[PROPERTY_VALUE_MAX] = {0};
+    android::String8 prop(PROPERTY_ICCID_PREIFX);
+
+    prop.append(android::String8::format("%d", (slot + 1)));
+    utils::mtk_property_get(prop.string(), iccid, "");
+
+    LOG_D(LOG_TAG, "(slot%d)iccid: %s", slot, iccid);
+    if ((strlen(iccid) > 0) && (strcmp(iccid, "N/A") != 0)){
+        return true;
+    }
+    return false;
+}
+
+int Radio_capability_switch_util::get_max_raf_supported(){
+    int maxRaf = RAF_UNKNOWN;
+
+    // RAF_GPRS is a marker of main capability
+    for (int i = 0; i < SIM_COUNT; i++) {
+        int rat = get_radio_capa(i).rat;
+        LOG_D(LOG_TAG, "(slot%d)rat: %d", i, rat);
+        if ((rat & RAF_GPRS) == RAF_GPRS) {
+            maxRaf = rat;
+        }
+    }
+    RLOGD("get_max_raf_supported:  maxRaf= %d" , maxRaf);
+
+    // If the phone capability cannot be updated promptly, the max capability should mark with
+    // GPRS, to avoid using an unknown RAF to trigger sim switch
+    if (maxRaf == RAF_UNKNOWN) {
+        maxRaf |= RAF_GPRS;
+    }
+
+    return maxRaf;
+}
+
+//RIL_RadioAccessFamily
+int Radio_capability_switch_util::get_min_rat_supported(){
+    int minRaf = RAF_UNKNOWN;
+
+    // RAF_GPRS is a marker of main capability
+    for (int i = 0; i < SIM_COUNT; i++) {
+        int rat = get_radio_capa(i).rat;
+        LOG_D(LOG_TAG, "(slot%d)rat: %d", i, rat);
+        if ((rat & RAF_GPRS) == 0) {
+            minRaf = rat;
+        }
+    }
+    RLOGD("get_max_raf_supported:  minRaf= %d" , minRaf);
+    return minRaf;
+}
+
+void Radio_capability_switch_util::sendRadioCapabilityRequest(int slotid) {
+    RequestInfo *info = creatRILInfoAndInit(RIL_REQUEST_SET_RADIO_CAPABILITY, OTHER, (RIL_SOCKET_ID)slotid);
+    char* version  = strdup((std::to_string(RIL_RADIO_CAPABILITY_VERSION)).c_str());
+    char* argv[7] = {"RIL_REQUEST_SET_RADIO_CAPABILITY", "0", "1", "2", "0","modem_sys1_ps0","0"};
+    argv[1] = version;
+    setRadioCapability(7, argv,(RIL_SOCKET_ID)slotid, info);
+    free(version);
+}
+
+void Radio_capability_switch_util::set_default_data_slot(int slot) {
+    int id = get_main_capability_phone_id();
+    if(id == slot) {
+        android::emResultNotify("default data slot is right, no need switch\n");
+        LOG_D(LOG_TAG, "the default data slot capability is right, don't need to set");
+        return;
+    }
+
+    int len = Phone_utils::get_phone_count();
+    std::vector<RIL_RadioAccessFamily> rafs = {RAF_UNKNOWN, RAF_UNKNOWN};
+    if(slot == 0 ){
+        rafs[1] = (RIL_RadioAccessFamily)get_min_rat_supported();
+    } else if(slot == 1) {
+        rafs[0] = (RIL_RadioAccessFamily)get_min_rat_supported();
+    } else {
+        LOG_D(LOG_TAG, "slot is %d, range 0 or 1", slot);
+        return ;
+    }
+    rafs[slot] = (RIL_RadioAccessFamily)get_max_raf_supported();
+    Proxy_controller::getInstance()->set_Radio_Capability(rafs);
+}
+
+/**
+ * Check if need to skip switch capability.
+ *
+ * @param majorPhoneId new major phone ID
+ * @return true : don't switch and stay current capability setting
+ * @       false  :  keep do setCapability
+ */
+bool Radio_capability_switch_util::isSkipCapabilitySwitch(int majorPhoneId, int phoneNum) {
+    std::vector<int> simOpInfo(phoneNum);
+    std::vector<int> simType(phoneNum);
+    int insertedState = 0;
+    int insertedSimCount = 0;
+    int tSimCount = 0;
+    int wSimCount = 0;
+    int cSimCount = 0;
+    std::vector<std::string> currIccId(phoneNum, "");
+    char optr[PROPERTY_VALUE_MAX] = {0};
+    utils::mtk_property_get("persist.vendor.operator.optr", optr, "OM");
+    std::string opSpec(optr);
+    std::string opOM("OM");
+
+    if (isPS2SupportLTE()) {
+        if (phoneNum > 2) {
+            if (majorPhoneId < 2 && get_main_capability_phone_id() < 2
+                    && !RatConfiguration::isC2kSupported()
+                    && !RatConfiguration::isTdscdmaSupported()) {
+                return true;
+            }
+            return false;
+        }
+        // check sim cards number
+        for (int i = 0; i < phoneNum; i++) {
+            char iccid[PROPERTY_VALUE_MAX] = {0};
+            utils::mtk_property_get(std::string(PROPERTY_ICCID).append(std::to_string(i+1)).c_str(), iccid, "");
+            currIccId[i] = iccid;
+            if (currIccId[i].empty()) {
+                LOG_D(LOG_TAG, "iccid not found, do capability switch");
+                return false;
+            }
+            if (!(NO_SIM_VALUE == currIccId[i])) {
+                ++insertedSimCount;
+                insertedState = insertedState | (1 << i);
+            }
+        }
+
+        // no sim card
+        if (insertedSimCount == 0) {
+            LOG_D(LOG_TAG, "no sim card, skip capability switch");
+            return true;
+        }
+
+        // check sim info
+        if (getSimInfo(simOpInfo, simType, insertedState) == false) {
+            LOG_D(LOG_TAG, "cannot get sim operator info, do capability switch");
+            return false;
+        }
+
+        for (int i = 0; i < phoneNum; i++) {
+            if (SIM_OP_INFO_OP01 == simOpInfo[i]) {
+                tSimCount++;
+            } else if (isCdmaCard(i, simOpInfo[i])) {
+                cSimCount++;
+            } else if (SIM_OP_INFO_UNKNOWN!= simOpInfo[i]){
+                wSimCount++;
+            }
+        }
+
+        LOG_D(LOG_TAG, "isSkipCapabilitySwitch : Inserted SIM count: %d, insertedStatus: %d, tSimCount: %d, wSimCount: %d, cSimCount: %d",
+                insertedSimCount, insertedState, tSimCount, wSimCount ,cSimCount );
+
+        if (opOM == opSpec ) {
+            // t + t --> don't need to capability switch
+            if (isSupportSimSwitchEnhancement(ENHANCEMENT_T_PLUS_T)
+                    && (insertedSimCount == 2) && (tSimCount == 2)) {
+                return true;
+            }
+
+            // t + w --> if support real T+W, always on t card
+            if (isSupportSimSwitchEnhancement(ENHANCEMENT_T_PLUS_W)
+                    && (insertedSimCount == 2) && (tSimCount == 1) && (wSimCount == 1)) {
+                if (isTPlusWSupport() && (simOpInfo[majorPhoneId] != SIM_OP_INFO_OP01)) {
+                    return true;
+                }
+            }
+
+            // t + c --> always on c card
+            if (isSupportSimSwitchEnhancement(ENHANCEMENT_T_PLUS_C)
+                    && (insertedSimCount == 2) && (tSimCount == 1) && (cSimCount == 1)) {
+                if (!isCdmaCard(majorPhoneId, simOpInfo[majorPhoneId])) {
+                    return true;
+                }
+            }
+
+            // w + c--> always on c card
+            if (isSupportSimSwitchEnhancement(ENHANCEMENT_W_PLUS_C)
+                    && (insertedSimCount == 2) && (wSimCount == 1) && (cSimCount == 1)) {
+                if (!isCdmaCard(majorPhoneId, simOpInfo[majorPhoneId])) {
+                    return true;
+                }
+            }
+
+        }
+
+        // w + w --> don't need to capability switch
+        if (isSupportSimSwitchEnhancement(ENHANCEMENT_W_PLUS_W)
+                && (insertedSimCount == 2) && (wSimCount == 2)) {
+            return true;
+        }
+
+        // w + empty --> don't need to capability switch
+        if (isSupportSimSwitchEnhancement(ENHANCEMENT_W_PLUS_NA)
+                && (insertedSimCount == 1) && (wSimCount == 1)) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+bool Radio_capability_switch_util::getSimInfo(std::vector<int> simOpInfo, std::vector<int>  simType, int insertedStatus) {
+    std::vector<std::string> strMnc(simOpInfo.size(), "");
+    std::vector<std::string> strSimType(simOpInfo.size(),"");
+    std::string propStr;
+
+    for (int i = 0; i < simOpInfo.size(); i++) {
+        if (i == 0) {
+            propStr = "vendor.gsm.ril.uicctype";
+        } else {
+            propStr = std::string("vendor.gsm.ril.uicctype.").append(std::to_string(i + 1));
+        }
+        char uicctype[PROPERTY_VALUE_MAX] = { 0 };
+        utils::mtk_property_get(propStr.c_str(),uicctype, "");
+        strSimType[i] = uicctype;
+        if (strSimType[i] == "SIM") {
+            simType[i] = Radio_capability_switch_util::SIM_TYPE_SIM;
+        } else if (strSimType[i] == "USIM") {
+            simType[i] = Radio_capability_switch_util::SIM_TYPE_USIM;
+        } else {
+            simType[i] = Radio_capability_switch_util::SIM_TYPE_OTHER;
+        }
+        LOG_D(LOG_TAG, "SimType[%d]= %s, simType[%d]= %d",i, strSimType[i].c_str(), i, simType[i]);
+
+        if (strMnc[i].empty()) {
+            LOG_D(LOG_TAG, "strMnc[%d] is null, get mnc by ril.uim.subscriberid",i);
+            propStr = std::string("vendor.ril.uim.subscriberid.").append(std::to_string(i+1));
+            char uim[PROPERTY_VALUE_MAX] = { 0 };
+            utils::mtk_property_get(propStr.c_str(), uim, "");
+            strMnc[i] = uim;
+        }
+        if (strMnc[i].empty()) {
+            LOG_D(LOG_TAG, "strMnc[%d] is null, get mnc by vendor.gsm.ril.uicc.mccmnc", i);
+            if (i == 0) {
+                propStr = "vendor.gsm.ril.uicc.mccmnc";
+            } else {
+                propStr = std::string("vendor.gsm.ril.uicc.mccmnc.").append(std::to_string(i));
+            }
+            char mccmnc[PROPERTY_VALUE_MAX] = { 0 };
+            utils::mtk_property_get(propStr.c_str(), mccmnc, "");
+            strMnc[i] = mccmnc;
+        }
+
+        if (strMnc[i].empty()) {
+            LOG_D(LOG_TAG, "strMnc[%d] is null", i);
+            strMnc[i] = "";
+        }
+
+        if (strMnc[i].length() >= 6) {
+            strMnc[i] = strMnc[i].substr(0, 6);
+        } else if (strMnc[i].length() >= 5) {
+            strMnc[i] = strMnc[i].substr(0, 5);
+        }
+        LOG_D(LOG_TAG, "insertedStatus: %d, imsi status:", insertedStatus, getSimImsiStatus(i));
+        if ((insertedStatus >= 0) && (((1 << i) & insertedStatus) > 0)) {
+            if (strMnc[i].empty() || strMnc[i] == "error") {
+                LOG_D(LOG_TAG, "SIM is inserted but no imsi");
+                return false;
+            }
+            if (strMnc[i] == "sim_lock") {
+                LOG_D(LOG_TAG, "SIM is lock, wait pin unlock");
+                return false;
+            }
+            if (strMnc[i] == "N/A" || strMnc[i] == "sim_absent") {
+                LOG_D(LOG_TAG, "strMnc have invalid value, return false");
+                return false;
+            }
+        }
+        for (std::string mccmnc : PLMN_TABLE_OP01) {
+            if (strMnc[i].find(mccmnc) == 0) {
+                simOpInfo[i] = SIM_OP_INFO_OP01;
+                break;
+            }
+        }
+        if (simOpInfo[i] == SIM_OP_INFO_UNKNOWN) {
+            for (std::string mccmnc : PLMN_TABLE_OP02) {
+                if (strMnc[i].find(mccmnc) == 0) {
+                    simOpInfo[i] = SIM_OP_INFO_OP02;
+                    break;
+                }
+            }
+        }
+        if (simOpInfo[i] == SIM_OP_INFO_UNKNOWN) {
+            for (std::string mccmnc : PLMN_TABLE_OP09) {
+                if (strMnc[i].find(mccmnc) == 0) {
+                    simOpInfo[i] = SIM_OP_INFO_OP09;
+                    break;
+                }
+            }
+        }
+        char optr[PROPERTY_VALUE_MAX] = { 0 };
+        utils::mtk_property_get("persist.vendor.operator.optr", optr,"");
+        if ("OP18" == std::string(optr)) {
+            if (simOpInfo[i] == SIM_OP_INFO_UNKNOWN) {
+                for (std::string mccmnc : PLMN_TABLE_OP18) {
+                    if (strMnc[i].find(mccmnc) == 0) {
+                        simOpInfo[i] = SIM_OP_INFO_OP18;
+                        break;
+                    }
+                }
+            }
+        }
+        if (simOpInfo[i] == SIM_OP_INFO_UNKNOWN) {
+            if (!(strMnc[i].empty()) && !(strMnc[i] == "N/A")) {
+                simOpInfo[i] = SIM_OP_INFO_OVERSEA;
+            }
+        }
+        LOG_D(LOG_TAG, "strMnc[%d]= %s, simOpInfo[%d]=%d", i, strMnc[i].c_str(), i,simOpInfo[i]);
+    }
+    for(auto info : simOpInfo) {
+        LOG_D(LOG_TAG, "getSimInfo(simOpInfo): %d", info);
+    }
+    for(auto type: simType) {
+        LOG_D(LOG_TAG, "getSimInfo(simType): %d", type);
+    }
+    return true;
+}
+
+std::string Radio_capability_switch_util::getSimImsiStatus(int slot) {
+    char sim_status[PROPERTY_VALUE_MAX] = { 0 };
+    utils::mtk_property_get(PROPERTY_SIM_IMSI_STATUS[slot].c_str(), sim_status,
+            IMSI_NOT_READY.c_str());
+    return std::string(sim_status);
+}
+
+bool Radio_capability_switch_util::isPS2SupportLTE() {
+    char ps2_rat[PROPERTY_VALUE_MAX] = { 0 };
+    utils::mtk_property_get("persist.vendor.radio.mtk_ps2_rat", ps2_rat, "");
+    std::string rat(ps2_rat);
+    if (rat.find('L') != std::string::npos) {
+        LOG_D(LOG_TAG, "isPS2SupportLTE = true");
+        return true;
+    }
+    LOG_D(LOG_TAG, "isPS2SupportLTE = false");
+    return false;
+}
+
+bool Radio_capability_switch_util::isTPlusWSupport() {
+    char tpluswsupport[PROPERTY_VALUE_MAX] = { 0 };
+    utils::mtk_property_get("vendor.ril.simswitch.tpluswsupport", tpluswsupport,
+            "");
+    if ("1" == std::string(tpluswsupport)) {
+        LOG_D(LOG_TAG, "return true for T+W support");
+        return true;
+    }
+    return false;
+}
+
+bool Radio_capability_switch_util::isVolteEnabled(int phoneId) {
+    bool imsUseEnabled = utils::mtk_property_get_bool("persist.mtk.volte.enable", false);
+    if (imsUseEnabled == true) {
+        // check 4G is enabled or not
+        if (is_sim_inserted(phoneId)) {
+            int nwMode = get_preferred_network_type(phoneId);
+            int rafFromNwMode = MtkRadioAccessFamily::getRafFromNetworkType(
+                    nwMode);
+            int rafLteGroup = MtkRadioAccessFamily::RAF_LTE
+                    | MtkRadioAccessFamily::RAF_LTE_CA;
+            if ((rafFromNwMode & rafLteGroup) == 0) {
+                imsUseEnabled = false;
+            }
+            LOG_D(LOG_TAG, "isVolteEnabled, imsUseEnabled = %d, nwMode = %d, rafFromNwMode = %d, rafLteGroup = %d",
+                    imsUseEnabled,nwMode, rafFromNwMode, rafLteGroup);
+        } else {
+            LOG_D(LOG_TAG,"isVolteEnabled, subId[] is null");
+        }
+    }
+    LOG_D(LOG_TAG,"isVolteEnabled = %d", imsUseEnabled);
+    return imsUseEnabled;
+}
+
+bool Radio_capability_switch_util::isHVolteEnabled() {
+    char mtk_ct_volte[PROPERTY_VALUE_MAX] = {0};
+    utils::mtk_property_get("persist.vendor.mtk_ct_volte_support", mtk_ct_volte, "");
+    if ( "2" == std::string(mtk_ct_volte) || "3" == std::string(mtk_ct_volte)) {
+        return true;
+    }
+    return false;
+}
+
+bool Radio_capability_switch_util::isCdmaCard(int phoneId, int opInfo) {
+    bool isCdmaSim = false;
+    if (phoneId < 0
+            || phoneId >= SIM_COUNT) {
+        LOG_D(LOG_TAG, "isCdmaCard invalid phoneId: %d", phoneId);
+        return isCdmaSim;
+    }
+
+    char uicc_type[PROPERTY_VALUE_MAX] = {0};
+    utils::mtk_property_get(PROPERTY_RIL_FULL_UICC_TYPE[phoneId].c_str(), uicc_type, "");
+    std::string cardType(uicc_type);
+    isCdmaSim =
+            (cardType.find("CSIM") != std::string::npos || cardType.find("RUIM") != std::string::npos);
+
+    if (!isCdmaSim && ("SIM" == cardType)) {
+        char ct3g[PROPERTY_VALUE_MAX] = {0};
+        utils::mtk_property_get(PROPERTY_RIL_CT3G[phoneId].c_str(), ct3g, "");
+        std::string uimDualMode(ct3g);
+        if ("1" == uimDualMode) {
+            isCdmaSim = true;
+        }
+    }
+
+    if (opInfo == SIM_OP_INFO_OP09) {
+        isCdmaSim = true;
+    }
+
+    if (isCdmaSim == true && isVolteEnabled(phoneId) == true
+            && isHVolteEnabled() == false) {
+        // if volte is enabled and h-volte is disbale, SRLTE is unused for CT card, treat as CU sim
+        isCdmaSim = false;
+        LOG_D(LOG_TAG,"isCdmaCard, volte is enabled, SRLTE is unused for CT card");
+    }
+
+    return isCdmaSim;
+}
+
+/**
+ * Check if support SIM switch enhancement
+ *
+ * @return true : support SIM switch enhancement.
+ * @       false  :  don't support SIM switch enhancement
+ */
+bool Radio_capability_switch_util::isSupportSimSwitchEnhancement(int simType) {
+    bool ret = false;
+    switch (simType) {
+    // CMCC + CMCC
+    case ENHANCEMENT_T_PLUS_T:
+        ret = true;
+        break;
+
+        // CMCC + CU
+    case ENHANCEMENT_T_PLUS_W:
+        ret = true;
+        break;
+
+        // CMCC + CT
+    case ENHANCEMENT_T_PLUS_C:
+        ret = false;
+        break;
+
+        // CT + CU
+    case ENHANCEMENT_W_PLUS_C:
+        ret = false;
+        break;
+
+        // CU + CU
+    case ENHANCEMENT_W_PLUS_W:
+        ret = true;
+        break;
+
+        // CU + Empty
+    case ENHANCEMENT_W_PLUS_NA:
+        ret = true;
+        break;
+
+    default:
+        break;
+    }
+    return ret;
+}
+
+void Radio_capability_switch_util::logd(android::String8 s) {
+    LOG_D(LOG_TAG, "%s", s.string());
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Radio_capability_switch_util.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Radio_capability_switch_util.h
new file mode 100644
index 0000000..c16ee4d
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/Radio_capability_switch_util.h
@@ -0,0 +1,127 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef SRC_UTIL_RADIO_CAPABILITY_SWITCH_UTIL_H_
+#define SRC_UTIL_RADIO_CAPABILITY_SWITCH_UTIL_H_
+
+#include <string>
+#include <utils/String8.h>
+
+class Radio_capability_switch_util {
+public:
+    static const int SIM_OP_INFO_UNKNOWN;
+    static const int SIM_OP_INFO_OVERSEA;
+    static const int SIM_OP_INFO_OP01;
+    static const int SIM_OP_INFO_OP02;
+    static const int SIM_OP_INFO_OP09;
+    static const int SIM_OP_INFO_OP18;
+
+    static const int SIM_TYPE_SIM;
+    static const int SIM_TYPE_USIM;
+    static const int SIM_TYPE_OTHER;
+
+    static const int OP01_6M_PRIORITY_OP01_USIM;
+    static const int OP01_6M_PRIORITY_OP01_SIM;
+    static const int OP01_6M_PRIORITY_OTHER;
+
+    // sync to ril_oem.h for dsda
+    static const int SIM_SWITCH_MODE_SINGLE_TALK_MDSYS;
+    static const int SIM_SWITCH_MODE_SINGLE_TALK_MDSYS_LITE;
+    static const int SIM_SWITCH_MODE_DUAL_TALK;
+    static const int SIM_SWITCH_MODE_DUAL_TALK_SWAP;
+    static const int ENHANCEMENT_T_PLUS_T;
+    static const int ENHANCEMENT_T_PLUS_W;
+    static const int ENHANCEMENT_T_PLUS_C;
+    static const int ENHANCEMENT_W_PLUS_C;
+    static const int ENHANCEMENT_W_PLUS_W;
+    static const int ENHANCEMENT_W_PLUS_NA;
+
+public:
+    Radio_capability_switch_util();
+    virtual ~Radio_capability_switch_util();
+    std::string get_sim_app_type(int slot);
+    static int get_main_capability_phone_id();
+    static bool is_sim_inserted(int slot);
+    static int get_max_raf_supported();
+    static int get_min_rat_supported();
+    static void set_default_data_slot(int slot);
+    static bool isSkipCapabilitySwitch(int majorPhoneId, int phoneNum);
+    static bool isSupportSimSwitchEnhancement(int simType);
+    static bool isVolteEnabled(int phoneId);
+    static bool isHVolteEnabled();
+    static bool isCdmaCard(int phoneId, int opInfo);
+    static bool isTPlusWSupport();
+    static bool isPS2SupportLTE();
+    static bool getSimInfo(std::vector<int> simOpInfo, std::vector<int>  simType, int insertedStatus);
+    static void sendRadioCapabilityRequest(int slotid);
+    static std::string getSimImsiStatus(int slot);
+private:
+    static void logd(android::String8 s);
+private:
+    static const std::string PROPERTY_ICCID;
+    static const std::string PROPERTY_CAPABILITY_SWITCH;
+    // OP01 SIMs
+    static const std::string PLMN_TABLE_OP01[];
+
+    // OP02 SIMs
+    static const std::string PLMN_TABLE_OP02[];
+
+    // OP09 SIMs
+    static const std::string PLMN_TABLE_OP09[];
+
+    // OP18 SIMs
+    static const std::string PLMN_TABLE_OP18[];
+
+    // OP02 case
+    static const std::string NO_SIM_VALUE;
+    static const std::string CN_MCC;
+    static const std::string PROPERTY_SIM_ICCID[];
+
+    static const int IMSI_NOT_READY_OR_SIM_LOCKED;
+    static const int ICCID_ERROR;
+
+    // sim icc status
+    // 0: imsi not ready
+    // 1: imsi ready
+    static const std::string IMSI_NOT_READY;
+    static const std::string IMSI_READY;
+    static const std::string PROPERTY_SIM_IMSI_STATUS[];
+
+    static const std::string PROPERTY_RIL_FULL_UICC_TYPE[];
+
+    static const std::string PROPERTY_RIL_CT3G[];
+};
+
+#endif /* SRC_UTIL_RADIO_CAPABILITY_SWITCH_UTIL_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/RatConfiguration.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/RatConfiguration.cpp
new file mode 100644
index 0000000..60fb5af
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/RatConfiguration.cpp
@@ -0,0 +1,293 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include <log/log.h>
+#include <cutils/properties.h>
+
+#include "RatConfiguration.h"
+#include "utils.h"
+
+#define LOG_TAG "DEMO_RatConfig"
+
+const std::string RatConfiguration::PROPERTY_BUILD_RAT_CONFIG =
+        "ro.vendor.mtk_protocol1_rat_config";
+/* the system property of active rat */
+const std::string RatConfiguration::PROPERTY_RAT_CONFIG = "ro.boot.opt_ps1_rat";
+const std::string RatConfiguration::PROPERTY_IS_USING_DEFAULT_CONFIG =
+        "ro.boot.opt_using_default";
+/* the valid characters of the human-readable rat config */
+/* the defination must be sync with ratconfig.c */
+const std::string RatConfiguration::CDMA = "C";
+const std::string RatConfiguration::LteFdd = "Lf";
+const std::string RatConfiguration::LteTdd = "Lt";
+const std::string RatConfiguration::WCDMA = "W";
+const std::string RatConfiguration::TDSCDMA = "T";
+const std::string RatConfiguration::GSM = "G";
+const std::string RatConfiguration::DELIMITER = "/";
+
+/* bitmask */
+/* the defination must be sync with ratconfig.c */
+const int RatConfiguration::MASK_CDMA = (1 << 5);
+const int RatConfiguration::MASK_LteFdd = (1 << 4);
+const int RatConfiguration::MASK_LteTdd = (1 << 3);
+const int RatConfiguration::MASK_WCDMA = (1 << 2);
+const int RatConfiguration::MASK_TDSCDMA = (1 << 1);
+const int RatConfiguration::MASK_GSM = (1);
+
+const int RatConfiguration::MD_MODE_UNKNOWN = 0;
+const int RatConfiguration::MD_MODE_LTG = 8;   //uLTG
+const int RatConfiguration::MD_MODE_LWG = 9;   //uLWG
+const int RatConfiguration::MD_MODE_LWTG = 10;  //uLWTG
+const int RatConfiguration::MD_MODE_LWCG = 11;  //uLWCG
+const int RatConfiguration::MD_MODE_LWCTG = 12;  //uLWTCG(Auto mode)
+const int RatConfiguration::MD_MODE_LTTG = 13;  //LtTG
+const int RatConfiguration::MD_MODE_LFWG = 14;  //LfWG
+const int RatConfiguration::MD_MODE_LFWCG = 15;  //uLfWCG
+const int RatConfiguration::MD_MODE_LCTG = 16;  //uLCTG
+const int RatConfiguration::MD_MODE_LTCTG = 17;  //uLtCTG
+
+int RatConfiguration::max_rat = 0;
+bool RatConfiguration::max_rat_initialized = false;
+int RatConfiguration::actived_rat = 0;
+bool RatConfiguration::is_default_config = true;
+
+RatConfiguration::RatConfiguration() {
+    // TODO Auto-generated constructor stub
+
+}
+
+RatConfiguration::~RatConfiguration() {
+    // TODO Auto-generated destructor stub
+}
+
+/*
+ * transfer rat format from "L/T/G" to bitmask
+ * @params String rat, the rat in format like "L/T/G"
+ * @return int, the rat in bitmask.
+ */
+int RatConfiguration::ratToBitmask(std::string rat) {
+    int iRat = 0;
+    if (rat.find(CDMA) != std::string::npos) {
+        iRat = iRat | MASK_CDMA;
+    }
+    if (rat.find(LteFdd) != std::string::npos) {
+        iRat = iRat | MASK_LteFdd;
+    }
+    if (rat.find(LteTdd) != std::string::npos) {
+        iRat = iRat | MASK_LteTdd;
+    }
+    if (rat.find(WCDMA) != std::string::npos) {
+        iRat = iRat | MASK_WCDMA;
+    }
+    if (rat.find(TDSCDMA) != std::string::npos) {
+        iRat = iRat | MASK_TDSCDMA;
+    }
+    if (rat.find(GSM) != std::string::npos) {
+        iRat = iRat | MASK_GSM;
+    }
+    return iRat;
+}
+
+/*
+ * get the rat of project config
+ * @return int, the rat in bitmask.
+ */
+int RatConfiguration::getMaxRat() {
+    if (!max_rat_initialized) {
+        char rat[PROPERTY_VALUE_MAX] = {0};
+        utils::mtk_property_get(PROPERTY_BUILD_RAT_CONFIG.c_str(), rat, "");
+        std::string sMaxRat(rat);
+        max_rat = ratToBitmask(sMaxRat);
+        char def_rat[PROPERTY_VALUE_MAX] = {0};
+        is_default_config = (utils::mtk_property_get_int32(PROPERTY_IS_USING_DEFAULT_CONFIG.c_str(), 1) != 0) ? true : false;
+        max_rat_initialized = true;
+        RLOGD("getMaxRat: initial %s %d ", sMaxRat.c_str(), max_rat);
+    }
+    return max_rat;
+}
+
+/*
+ * check rat config is supported by project config
+ * @params int iRat, the rat to be checked.
+ * @return boolean,
+ *              true, the rat is supported.
+ *              false, the rat is not supported.
+ */
+bool RatConfiguration::checkRatConfig(int iRat) {
+    int maxrat = getMaxRat();
+    if ((iRat | maxrat) == maxrat) {
+        return true;
+    } else {
+        RLOGD("checkRatConfig: FAIL with %d", iRat);
+        return false;
+    }
+}
+
+/*
+ * get the active rat in bitmask.
+ * @return int, the rat in bitmask.
+ */
+int RatConfiguration::getRatConfig() {
+    int default_rat_config = getMaxRat();
+    if (default_rat_config == 0) {
+        actived_rat = 0;
+        return actived_rat;
+    }
+    if (is_default_config) {
+        actived_rat = default_rat_config;
+        return default_rat_config;
+    }
+    char rat_config[PROPERTY_VALUE_MAX] = {0};
+    utils::mtk_property_get(PROPERTY_RAT_CONFIG.c_str(), rat_config, "");
+    std::string rat(rat_config);
+    if (rat.length() > 0) {
+        actived_rat = ratToBitmask(rat);
+        if (checkRatConfig(actived_rat) == false) {
+            RLOGD("getRatConfig: invalid PROPERTY_RAT_CONFIG, set to max_rat");
+            actived_rat = getMaxRat();
+        }
+    } else {
+        RLOGD("getRatConfig: ger property PROPERTY_RAT_CONFIG fail, initialize");
+        actived_rat = getMaxRat();
+    }
+    return actived_rat;
+}
+
+/*
+ * transfer the format from bitmask to "L/T/G".
+ * @params int iRat, rat in bitmask
+ * @return String, rat in format like "L/T/G".
+ */
+std::string RatConfiguration::ratToString(int iRat) {
+    std::string rat = "";
+    if ((iRat & MASK_CDMA) == MASK_CDMA) {
+        rat += (DELIMITER + CDMA);
+    }
+    if ((iRat & MASK_LteFdd) == MASK_LteFdd) {
+        rat += (DELIMITER + LteFdd);
+    }
+    if ((iRat & MASK_LteTdd) == MASK_LteTdd) {
+        rat += (DELIMITER + LteTdd);
+    }
+    if ((iRat & MASK_WCDMA) == MASK_WCDMA) {
+        rat += (DELIMITER + WCDMA);
+    }
+    if ((iRat & MASK_TDSCDMA) == MASK_TDSCDMA) {
+        rat += (DELIMITER + TDSCDMA);
+    }
+    if ((iRat & MASK_GSM) == MASK_GSM) {
+        rat += (DELIMITER + GSM);
+    }
+    if (rat.length() > 0) {
+        // for remove the delimiter at rat[0]
+        rat = rat.substr(1);
+    }
+    return rat;
+}
+
+/*
+ * check C2k suppport
+ * @return boolean, cases as following
+ *       true, rat is active and project config supports it.
+ *       false, rat is inactive no matter project config supports.
+ */
+bool RatConfiguration::isC2kSupported() {
+    return (getMaxRat() & getRatConfig() & MASK_CDMA) == MASK_CDMA ?
+            true : false;
+}
+
+/*
+ * check LteFdd suppport
+ * @return boolean, cases as following
+ *       true, rat is active and project config supports it.
+ *       false, rat is inactive no matter project config supports.
+ */
+bool RatConfiguration::isLteFddSupported() {
+    return (getMaxRat() & getRatConfig() & MASK_LteFdd) == MASK_LteFdd ?
+            true : false;
+}
+
+/*
+ * check LteTdd suppport
+ * @return boolean, cases as following
+ *       true, rat is active and project config supports it.
+ *       false, rat is inactive no matter project config supports.
+ */
+bool RatConfiguration::isLteTddSupported() {
+    return (getMaxRat() & getRatConfig() & MASK_LteTdd) == MASK_LteTdd ?
+            true : false;
+}
+
+/*
+ * check Wcdma suppport
+ * @return boolean, cases as following
+ *       true, rat is active and project config supports it.
+ *       false, rat is inactive no matter project config supports.
+ */
+bool RatConfiguration::isWcdmaSupported() {
+    return (getMaxRat() & getRatConfig() & MASK_WCDMA) == MASK_WCDMA ?
+            true : false;
+}
+
+/*
+ * check Tdscdma suppport
+ * @return boolean, cases as following
+ *       true, rat is active and project config supports it.
+ *       false, rat is inactive no matter project config supports.
+ */
+bool RatConfiguration::isTdscdmaSupported() {
+    return (getMaxRat() & getRatConfig() & MASK_TDSCDMA) == MASK_TDSCDMA ?
+            true : false;
+}
+
+/*
+ * check GSM suppport
+ * @return boolean, cases as following
+ *       true, rat is active and project config supports it.
+ *       false, rat is inactive no matter project config supports.
+ */
+bool RatConfiguration::isGsmSupported() {
+    return (getMaxRat() & getRatConfig() & MASK_GSM) == MASK_GSM ? true : false;
+}
+
+/*
+ * get the active rat
+ * @return String, the rat in format like C/Lf/Lt/T/W/G
+ */
+std::string RatConfiguration::getActiveRatConfig() {
+    std::string rat = ratToString(getRatConfig());
+    RLOGD("getActiveRatConfig: %s", rat.c_str());
+    return rat;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/RatConfiguration.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/RatConfiguration.h
new file mode 100644
index 0000000..1a941fe
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/RatConfiguration.h
@@ -0,0 +1,99 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef SRC_UTIL_RATCONFIGURATION_H_
+#define SRC_UTIL_RATCONFIGURATION_H_
+
+#include <string>
+class RatConfiguration {
+public:
+    RatConfiguration();
+    virtual ~RatConfiguration();
+    static const std::string PROPERTY_BUILD_RAT_CONFIG;
+    /* the system property of active rat */
+    static const std::string PROPERTY_RAT_CONFIG;
+    static const std::string PROPERTY_IS_USING_DEFAULT_CONFIG;
+    /* the valid characters of the human-readable rat config */
+    /* the defination must be sync with ratconfig.c */
+    static const std::string CDMA;
+    static const std::string LteFdd;
+    static const std::string LteTdd;
+    static const std::string WCDMA;
+    static const std::string TDSCDMA;
+    static const std::string GSM;
+    static const std::string DELIMITER;
+
+    /* bitmask */
+    /* the defination must be sync with ratconfig.c */
+    static const int MASK_CDMA;
+    static const int MASK_LteFdd;
+    static const int MASK_LteTdd;
+    static const int MASK_WCDMA;
+    static const int MASK_TDSCDMA;
+    static const int MASK_GSM;
+
+    static const int MD_MODE_UNKNOWN;
+    static const int MD_MODE_LTG;   //uLTG
+    static const int MD_MODE_LWG;   //uLWG
+    static const int MD_MODE_LWTG;  //uLWTG
+    static const int MD_MODE_LWCG;  //uLWCG
+    static const int MD_MODE_LWCTG;  //uLWTCG(Auto mode)
+    static const int MD_MODE_LTTG;  //LtTG
+    static const int MD_MODE_LFWG;  //LfWG
+    static const int MD_MODE_LFWCG;  //uLfWCG
+    static const int MD_MODE_LCTG;  //uLCTG
+    static const int MD_MODE_LTCTG;  //uLtCTG
+
+    static int max_rat;
+    static bool max_rat_initialized;
+    static int actived_rat;
+    static bool is_default_config;
+public:
+    static int ratToBitmask(std::string rat);
+    static int getMaxRat();
+    static bool checkRatConfig(int iRat);
+    static int getRatConfig();
+    static std::string ratToString(int iRat);
+    static bool isC2kSupported();
+    static bool isLteFddSupported();
+    static bool isLteTddSupported();
+    static bool isWcdmaSupported();
+    static bool isTdscdmaSupported();
+    static bool isGsmSupported();
+    static std::string getActiveRatConfig();
+
+};
+
+#endif /* SRC_UTIL_RATCONFIGURATION_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/WorldPhoneUtil.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/WorldPhoneUtil.cpp
new file mode 100644
index 0000000..0b7f05e
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/WorldPhoneUtil.cpp
@@ -0,0 +1,239 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include <string>
+#include "WorldPhoneUtil.h"
+#include "RatConfiguration.h"
+#include "utils.h"
+#include "log_extra.h"
+
+#undef LOG_TAG
+#define LOG_TAG "DEMO_WorldPhoneUtil"
+const int WorldPhoneUtil::ACTIVE_MD_TYPE_UNKNOWN = 0;
+const int WorldPhoneUtil::ACTIVE_MD_TYPE_WG   = 1;//3G(WCDMA)+2G(GSM)
+const int WorldPhoneUtil::ACTIVE_MD_TYPE_TG   = 2;//3G(TDS-CDMA)+2G(GSM)
+const int WorldPhoneUtil::ACTIVE_MD_TYPE_LWG  = 3;//4G(TDD-LTE+FDD-LTE)+3G(WCDMA)+2G(GSM)
+const int WorldPhoneUtil::ACTIVE_MD_TYPE_LTG  = 4;//4G(TDD-LTE+FDD-LTE)+3G(TDS-CDMA)+2G(GSM)
+    //4G(TDD-LTE+FDD-LTE)+3G(WCDMA+EVDO)+2G(GSM+CDMA2000)
+const int WorldPhoneUtil::ACTIVE_MD_TYPE_LWCG = 5;
+const int WorldPhoneUtil::ACTIVE_MD_TYPE_LtTG = 6;//4G(TDD-LTE)+3G(TDS-CDMA)+2G(GSM)
+const int WorldPhoneUtil::ACTIVE_MD_TYPE_LfWG = 7;//4G(FDD-LTE)+3G(WCDMA)+2G(GSM)
+
+
+const int WorldPhoneUtil::MD_TYPE_UNKNOWN = 0;
+const int WorldPhoneUtil::MD_TYPE_WG      = 3;
+const int WorldPhoneUtil::MD_TYPE_TG      = 4;
+const int WorldPhoneUtil::MD_TYPE_LWG     = 5;
+const int WorldPhoneUtil::MD_TYPE_LTG     = 6;
+const int WorldPhoneUtil::MD_TYPE_FDD     = 100;
+const int WorldPhoneUtil::MD_TYPE_TDD     = 101;
+
+const int WorldPhoneUtil::MD_WORLD_MODE_UNKNOWN = 0;
+const int WorldPhoneUtil::MD_WORLD_MODE_LTG     = 8;   //uLTG
+const int WorldPhoneUtil::MD_WORLD_MODE_LWG     = 9;   //uLWG
+const int WorldPhoneUtil::MD_WORLD_MODE_LWTG    = 10;  //uLWTG
+const int WorldPhoneUtil::MD_WORLD_MODE_LWCG    = 11;  //uLWCG
+const int WorldPhoneUtil::MD_WORLD_MODE_LWCTG   = 12;  //uLWTCG(Auto mode)
+const int WorldPhoneUtil::MD_WORLD_MODE_LTTG    = 13;  //LtTG
+const int WorldPhoneUtil::MD_WORLD_MODE_LFWG    = 14;  //LfWG
+const int WorldPhoneUtil::MD_WORLD_MODE_LFWCG   = 15;  //uLfWCG
+const int WorldPhoneUtil::MD_WORLD_MODE_LCTG    = 16;  //uLCTG
+const int WorldPhoneUtil::MD_WORLD_MODE_LTCTG   = 17;  //uLtCTG
+const int WorldPhoneUtil::MD_WORLD_MODE_LTWG    = 18;  //uLtWG
+const int WorldPhoneUtil::MD_WORLD_MODE_LTWCG   = 19;  //uLTWCG
+const int WorldPhoneUtil::MD_WORLD_MODE_LFTG    = 20;  //uLfTG
+const int WorldPhoneUtil::MD_WORLD_MODE_LFCTG   = 21;  //uLfCTG
+
+std::string WorldPhoneUtil::PROPERTY_RAT_CONFIG = "ro.boot.opt_ps1_rat";
+std::string WorldPhoneUtil::PROPERTY_ACTIVE_MD = "vendor.ril.active.md";
+std::string WorldPhoneUtil::WCDMA = "W";
+std::string WorldPhoneUtil::TDSCDMA = "T";
+std::string WorldPhoneUtil::CDMA = "C";
+const int WorldPhoneUtil::UTRAN_DIVISION_DUPLEX_MODE_UNKNOWN = 0;
+const int WorldPhoneUtil::UTRAN_DIVISION_DUPLEX_MODE_FDD = 1;
+const int WorldPhoneUtil::UTRAN_DIVISION_DUPLEX_MODE_TDD = 2;
+
+    // World mode result cause for EN.
+const int WorldPhoneUtil::WORLD_MODE_RESULT_SUCCESS            = 100;
+const int WorldPhoneUtil::WORLD_MODE_RESULT_ERROR              = 101;
+const int WorldPhoneUtil::WORLD_MODE_RESULT_WM_ID_NOT_SUPPORT  = 102;
+
+    /* bitmask */
+    /* the defination must be sync with ratconfig.c */
+const int WorldPhoneUtil::MASK_CDMA    = (1 << 5);
+const int WorldPhoneUtil::MASK_LTEFDD  = (1 << 4);
+const int WorldPhoneUtil::MASK_LTETDD  = (1 << 3);
+const int WorldPhoneUtil::MASK_WCDMA   = (1 << 2);
+const int WorldPhoneUtil::MASK_TDSCDMA = (1 << 1);
+const int WorldPhoneUtil::MASK_GSM     = (1);
+
+const int WorldPhoneUtil::MODEM_FDD = 1;
+const int WorldPhoneUtil::MODEM_TD = 2;
+const int WorldPhoneUtil::MODEM_NO3G = 3;
+
+WorldPhoneUtil::WorldPhoneUtil() {
+    // TODO Auto-generated constructor stub
+
+}
+
+WorldPhoneUtil::~WorldPhoneUtil() {
+    // TODO Auto-generated destructor stub
+}
+
+bool WorldPhoneUtil::isWorldPhoneSupport() {
+    return (RatConfiguration::isWcdmaSupported()
+            && RatConfiguration::isTdscdmaSupported());
+}
+
+bool WorldPhoneUtil::isLteSupport() {
+    return (RatConfiguration::isLteFddSupported()
+            || RatConfiguration::isLteTddSupported());
+}
+
+bool WorldPhoneUtil::isWorldModeSupport() {
+    //bool is_support = (utils::mtk_property_get_int32("ro.vendor.mtk_md_world_mode_support", 0) == 1);
+    //return is_support;
+    return true;
+}
+
+int WorldPhoneUtil::get3GDivisionDuplexMode() {
+    int duplexMode = UTRAN_DIVISION_DUPLEX_MODE_UNKNOWN;
+    int activeMdType = getActiveModemType();
+
+    switch (activeMdType) {
+        case ACTIVE_MD_TYPE_WG:
+        case ACTIVE_MD_TYPE_LWG:
+        case ACTIVE_MD_TYPE_LWCG:
+        case ACTIVE_MD_TYPE_LfWG:
+            duplexMode = UTRAN_DIVISION_DUPLEX_MODE_FDD;
+            break;
+        case ACTIVE_MD_TYPE_TG:
+        case ACTIVE_MD_TYPE_LTG:
+        case ACTIVE_MD_TYPE_LtTG:
+            duplexMode = UTRAN_DIVISION_DUPLEX_MODE_TDD;
+            break;
+        default:
+            duplexMode = UTRAN_DIVISION_DUPLEX_MODE_UNKNOWN;
+        break;
+    }
+    LOG_D(LOG_TAG, "get3GDivisionDuplexMode= %d", duplexMode);
+    return duplexMode;
+}
+
+int WorldPhoneUtil::getActiveModemType() {
+    int modemType = 0;
+    int activeMdType = ACTIVE_MD_TYPE_UNKNOWN;
+    int activeMode = -1;
+    if (!isWorldModeSupport()) {
+        modemType = getWorldModeId();
+        switch (modemType) {
+            case MD_TYPE_WG:
+                activeMdType = ACTIVE_MD_TYPE_WG;
+                break;
+            case MD_TYPE_TG:
+                activeMdType = ACTIVE_MD_TYPE_TG;
+                break;
+            case MD_TYPE_LWG:
+                activeMdType = ACTIVE_MD_TYPE_LWG;
+                break;
+            case MD_TYPE_LTG:
+                activeMdType = ACTIVE_MD_TYPE_LTG;
+                break;
+            default:
+                activeMdType = ACTIVE_MD_TYPE_UNKNOWN;
+            break;
+        }
+    } else {
+        modemType = getWorldModeId();
+        activeMode = utils::mtk_property_get_int32("vendor.ril.nw.worldmode.activemode",ACTIVE_MD_TYPE_UNKNOWN);
+        switch (modemType) {
+            case MD_WORLD_MODE_LTG:
+            case MD_WORLD_MODE_LCTG:
+            case MD_WORLD_MODE_LFTG:
+            case MD_WORLD_MODE_LFCTG:
+                activeMdType = ACTIVE_MD_TYPE_LTG;
+                break;
+            case MD_WORLD_MODE_LWG:
+            case MD_WORLD_MODE_LTWG:
+                activeMdType = ACTIVE_MD_TYPE_LWG;
+                break;
+            case MD_WORLD_MODE_LWTG:
+            case MD_WORLD_MODE_LWCTG:
+                if (activeMode > 0){
+                    if (activeMode == 1){
+                        //FDD mode
+                        activeMdType = ACTIVE_MD_TYPE_LWG;
+                    } else if (activeMode == 2){
+                        //TDD mode
+                        activeMdType = ACTIVE_MD_TYPE_LTG;
+                    }
+                }
+                break;
+            case MD_WORLD_MODE_LWCG:
+            case MD_WORLD_MODE_LFWCG:
+            case MD_WORLD_MODE_LTWCG:
+                activeMdType = ACTIVE_MD_TYPE_LWCG;
+                break;
+            case MD_WORLD_MODE_LTTG:
+            case MD_WORLD_MODE_LTCTG:
+                activeMdType = ACTIVE_MD_TYPE_LtTG;
+                break;
+            case MD_WORLD_MODE_LFWG:
+                activeMdType = ACTIVE_MD_TYPE_LfWG;
+                break;
+            default:
+                activeMdType = ACTIVE_MD_TYPE_UNKNOWN;
+            break;
+        }
+    }
+    LOG_D(LOG_TAG, "getActiveModemType=%d activeMode=%d",activeMdType , activeMode);
+    return activeMdType;
+}
+
+int WorldPhoneUtil::getWorldModeId() {
+    int modemType = 0;
+    modemType = utils::mtk_property_get_int32(PROPERTY_ACTIVE_MD.c_str(),MD_TYPE_UNKNOWN);
+    return modemType;
+}
+
+int WorldPhoneUtil::getModemType() {
+    int mode = MODEM_NO3G;
+    int mask = get3GDivisionDuplexMode();
+    if ((1 == mask) || (2 == mask)) {
+        mode = mask;
+    }
+    LOG_D(LOG_TAG, "mode = %d", mode);
+    return mode;
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/WorldPhoneUtil.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/WorldPhoneUtil.h
new file mode 100644
index 0000000..2b215cd
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/WorldPhoneUtil.h
@@ -0,0 +1,119 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef SRC_UTIL_WORLDPHONEUTIL_H_
+#define SRC_UTIL_WORLDPHONEUTIL_H_
+
+#include <string>
+
+class WorldPhoneUtil {
+private:
+    static const int ACTIVE_MD_TYPE_UNKNOWN;
+    static const int ACTIVE_MD_TYPE_WG;//3G(WCDMA)+2G(GSM)
+    static const int ACTIVE_MD_TYPE_TG;//3G(TDS-CDMA)+2G(GSM)
+    static const int ACTIVE_MD_TYPE_LWG;//4G(TDD-LTE+FDD-LTE)+3G(WCDMA)+2G(GSM)
+    static const int ACTIVE_MD_TYPE_LTG;//4G(TDD-LTE+FDD-LTE)+3G(TDS-CDMA)+2G(GSM)
+    //4G(TDD-LTE+FDD-LTE)+3G(WCDMA+EVDO)+2G(GSM+CDMA2000)
+    static const int ACTIVE_MD_TYPE_LWCG;
+    static const int ACTIVE_MD_TYPE_LtTG;//4G(TDD-LTE)+3G(TDS-CDMA)+2G(GSM)
+    static const int ACTIVE_MD_TYPE_LfWG;//4G(FDD-LTE)+3G(WCDMA)+2G(GSM)
+
+
+    static const int MD_TYPE_UNKNOWN;
+    static const int MD_TYPE_WG;
+    static const int MD_TYPE_TG;
+    static const int MD_TYPE_LWG;
+    static const int MD_TYPE_LTG;
+    static const int MD_TYPE_FDD;
+    static const int MD_TYPE_TDD;
+
+    static const int MD_WORLD_MODE_UNKNOWN;
+    static const int MD_WORLD_MODE_LTG;   //uLTG
+    static const int MD_WORLD_MODE_LWG;   //uLWG
+    static const int MD_WORLD_MODE_LWTG;  //uLWTG
+    static const int MD_WORLD_MODE_LWCG;  //uLWCG
+    static const int MD_WORLD_MODE_LWCTG;  //uLWTCG(Auto mode)
+    static const int MD_WORLD_MODE_LTTG;  //LtTG
+    static const int MD_WORLD_MODE_LFWG;  //LfWG
+    static const int MD_WORLD_MODE_LFWCG;  //uLfWCG
+    static const int MD_WORLD_MODE_LCTG;  //uLCTG
+    static const int MD_WORLD_MODE_LTCTG;  //uLtCTG
+    static const int MD_WORLD_MODE_LTWG;  //uLtWG
+    static const int MD_WORLD_MODE_LTWCG;  //uLTWCG
+    static const int MD_WORLD_MODE_LFTG;  //uLfTG
+    static const int MD_WORLD_MODE_LFCTG;  //uLfCTG
+
+    static std::string PROPERTY_RAT_CONFIG;
+    static std::string PROPERTY_ACTIVE_MD;
+    static std::string WCDMA;
+    static std::string TDSCDMA;
+    static std::string CDMA;
+    static const int UTRAN_DIVISION_DUPLEX_MODE_UNKNOWN;
+    static const int UTRAN_DIVISION_DUPLEX_MODE_FDD;
+    static const int UTRAN_DIVISION_DUPLEX_MODE_TDD;
+
+    // World mode result cause for EN.
+    static const int WORLD_MODE_RESULT_SUCCESS;
+    static const int WORLD_MODE_RESULT_ERROR;
+    static const int WORLD_MODE_RESULT_WM_ID_NOT_SUPPORT;
+
+    /* bitmask */
+    /* the defination must be sync with ratconfig.c */
+    static const int MASK_CDMA;
+    static const int MASK_LTEFDD;
+    static const int MASK_LTETDD;
+    static const int MASK_WCDMA;
+    static const int MASK_TDSCDMA;
+    static const int MASK_GSM;
+
+private:
+    static int getActiveModemType();
+public:
+    static const int MODEM_FDD;
+    static const int MODEM_TD;
+    static const int MODEM_NO3G;
+public:
+    WorldPhoneUtil();
+    virtual ~WorldPhoneUtil();
+    static bool isWorldPhoneSupport();
+    static bool isLteSupport();
+    static bool isWorldModeSupport();
+    static int get3GDivisionDuplexMode();
+    static int getWorldModeId();
+    static int getModemType();
+
+};
+
+#endif /* SRC_UTIL_WORLDPHONEUTIL_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/log_extra.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/log_extra.h
new file mode 100644
index 0000000..ead0d50
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/log_extra.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef TEL_DEMO_SRC_UTIL_LOG_EXTRA_H_
+#define TEL_DEMO_SRC_UTIL_LOG_EXTRA_H_
+
+/*****************************************************************************
+ * Include
+ *****************************************************************************/
+
+#include <log/log.h>
+
+/*****************************************************************************
+ * Example
+ *****************************************************************************/
+/* Add a debug log with your tag, write it like:
+ * LOG_D(tag, "this is a sample");
+ *
+ * Print a variable, write it like:
+ * LOG_D(tag, "this is a sample %d", variable);
+ *
+ * Print multi-variable, write it like:
+ * LOG_D(tag, "this is a sample %d,%d", variable1, variable2);
+ *
+ * Staple output format
+ * %c  char
+ * %s  char* string
+ * %d  sign decimal
+ * %p  pointer
+ * %x  hex
+ *
+ * Add a debug log with your condition and tag, write it like:
+ * LOG_D_IF(condition, tag, "this is a sample");
+ * When condition is not 0 (this is true), the log will be printed, otherwise, no log printed.
+ *
+ */
+
+/*****************************************************************************
+ * Define
+ *****************************************************************************/
+
+/*
+ * Simplified macro to send a verbose radio log message using the user given tag - _tag.
+ */
+#ifndef LOG_V
+#define __LOG_V(_tag, ...) \
+    ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_VERBOSE, _tag, __VA_ARGS__))
+#if LOG_NDEBUG
+#define LOG_V(_tag, ...) do { if (0) { __LOG_V(_tag, __VA_ARGS__); } } while (0)
+#else
+#define LOG_V(_tag, ...) __LOG_V(_tag, __VA_ARGS__)
+#endif
+#endif
+
+#define CONDITION(cond)     (__builtin_expect((cond) != 0, 0))
+
+#ifndef LOG_V_IF
+#if LOG_NDEBUG
+#define LOG_V_IF(cond, _tag, ...)   ((void)0)
+#else
+#define LOG_V_IF(cond, _tag, ...) \
+    ( (CONDITION(cond)) \
+    ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_VERBOSE, _tag, __VA_ARGS__)) \
+    : (void)0 )
+#endif
+#endif
+
+/*
+ * Simplified macro to send a debug radio log message using the user given tag - _tag.
+ */
+#ifndef LOG_D
+#define LOG_D(_tag, ...) \
+    ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_DEBUG, _tag, __VA_ARGS__))
+#endif
+
+#ifndef LOG_D_IF
+#define LOG_D_IF(cond, _tag, ...) \
+    ( (CONDITION(cond)) \
+    ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_DEBUG, _tag, __VA_ARGS__)) \
+    : (void)0 )
+#endif
+
+/*
+ * Simplified macro to send an info radio log message using the user given tag - _tag.
+ */
+#ifndef LOG_I
+#define LOG_I(_tag, ...) \
+    ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO, _tag, __VA_ARGS__))
+#endif
+
+#ifndef LOG_I_IF
+#define LOG_I_IF(cond, _tag, ...) \
+    ( (CONDITION(cond)) \
+    ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO, _tag, __VA_ARGS__)) \
+    : (void)0 )
+#endif
+
+/*
+ * Simplified macro to send a warning radio log message using the user given tag - _tag.
+ */
+#ifndef LOG_W
+#define LOG_W(_tag, ...) \
+    ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_WARN, _tag, __VA_ARGS__))
+#endif
+
+#ifndef LOG_W_IF
+#define LOG_W_IF(cond, _tag, ...) \
+    ( (CONDITION(cond)) \
+    ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_WARN, _tag, __VA_ARGS__)) \
+    : (void)0 )
+#endif
+
+/*
+ * Simplified macro to send an error radio log message using the user given tag - _tag.
+ */
+#ifndef LOG_E
+#define LOG_E(_tag, ...) \
+    ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_ERROR, _tag, __VA_ARGS__))
+#endif
+
+#ifndef LOG_E_IF
+#define LOG_E_IF(cond, _tag, ...) \
+    ( (CONDITION(cond)) \
+    ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_ERROR, _tag, __VA_ARGS__)) \
+    : (void)0 )
+#endif
+
+#ifndef ASSERT_EX
+#define ASSERT_EX(_expr)                                                         \
+    do {                                                                          \
+        if (!(_expr)) {                                                           \
+            LOG_E("ASSERT_EX", "ASSERT_EX:%s, %d", __FILE__, __LINE__);     \
+            LOG_ALWAYS_FATAL();                                        \
+        }                                                                         \
+    } while(0)
+#endif
+
+
+
+#endif /* TEL_DEMO_SRC_UTIL_LOG_EXTRA_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/utils.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/utils.cpp
new file mode 100644
index 0000000..a430d10
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/utils.cpp
@@ -0,0 +1,316 @@
+ /*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cstdarg>
+#include <cstdio>
+#include <string>
+#include <algorithm>
+#include <cutils/properties.h>
+#include <errno.h>
+#include <inttypes.h>
+
+#include "utils.h"
+#include "log_extra.h"
+
+#undef LOG_TAG
+#define LOG_TAG "DEMO_UTILS"
+
+constexpr int utils::MODEM_UNKNOWN;
+constexpr int utils::MODEM_GSM;
+constexpr int utils::MODEM_TDSCDMA;
+constexpr int utils::MODEM_WCDMA;
+constexpr int utils::MODEM_LTE_TDD;
+constexpr int utils::MODEM_LTE_FDD;
+constexpr int utils::MODEM_CDMA_EVDO;
+constexpr int utils::MODEM_CDMA_1X;
+
+utils::utils() {
+    // TODO Auto-generated constructor stub
+
+}
+
+utils::~utils() {
+    // TODO Auto-generated destructor stub
+}
+
+bool utils::is93Modem() {
+#ifdef MD_93_SUPPORT
+    return true;
+#else
+    return false;
+#endif
+}
+
+bool utils::is90Modem() {
+#ifdef MD_90_SUPPORT
+    return true;
+#else
+    return false;
+#endif
+}
+
+bool utils::isC2KSupport() {
+#ifdef C2K_SUPPORT
+    return true;
+#else
+    return false;
+#endif
+}
+
+
+bool utils::isMt2635() {
+#ifdef TARGET_PLATFORM_MT2635
+    return true;
+#else
+    return false;
+#endif
+}
+
+bool utils::isMt2731(){
+#ifdef TARGET_PLATFORM_MT2731
+    return true;
+#else
+    return false;
+#endif
+}
+
+bool utils::is_support_dsds(){
+#ifdef MODE_DSDS
+    return true;
+#else
+    return false;
+#endif
+}
+
+bool utils::is_suppport_dsss(){
+#ifdef MODE_DSSS
+    return true;
+#else
+    return false;
+#endif
+}
+
+/*
+ * Get property
+ */
+int utils::mtk_property_get(const char *key, char *value, const char *default_value)
+{
+    int ali_pro_res = property_get(key, value, default_value);
+    LOG_D(LOG_TAG, "get key is %s, value is %s, result: %d", key, value, ali_pro_res);
+    return ali_pro_res;
+}
+
+/*
+ * Set property
+ */
+int utils::mtk_property_set(const char *key, const char *value)
+{
+    int ret_val = property_set(key, value);
+    LOG_D(LOG_TAG, "set key is %s, value is %s,result: %d", key, value, ret_val);
+    return ret_val;
+}
+
+bool utils::mtk_property_get_bool(const char *key, bool default_value) {
+    if (!key) {
+        return default_value;
+    }
+
+    bool result = default_value;
+    char buf[PROPERTY_VALUE_MAX] = {'\0',};
+
+    int len = property_get(key, buf, "");
+    if (len == 1) {
+        char ch = buf[0];
+        if (ch == '0' || ch == 'n') {
+            result = false;
+        } else if (ch == '1' || ch == 'y') {
+            result = true;
+        }
+    } else if (len > 1) {
+         if (!strcmp(buf, "no") || !strcmp(buf, "false") || !strcmp(buf, "off")) {
+            result = false;
+        } else if (!strcmp(buf, "yes") || !strcmp(buf, "true") || !strcmp(buf, "on")) {
+            result = true;
+        }
+    }
+
+    return result;
+}
+
+intmax_t utils::property_get_imax(const char *key, intmax_t lower_bound, intmax_t upper_bound,
+        intmax_t default_value) {
+    if (!key) {
+        return default_value;
+    }
+
+    intmax_t result = default_value;
+    char buf[PROPERTY_VALUE_MAX] = {'\0',};
+    char *end = NULL;
+
+    int len = property_get(key, buf, "");
+    if (len > 0) {
+        int tmp = errno;
+        errno = 0;
+
+        // Infer base automatically
+        result = strtoimax(buf, &end, /*base*/0);
+        if ((result == INTMAX_MIN || result == INTMAX_MAX) && errno == ERANGE) {
+            // Over or underflow
+            result = default_value;
+            ALOGV("%s(%s,%" PRIdMAX ") - overflow", __FUNCTION__, key, default_value);
+        } else if (result < lower_bound || result > upper_bound) {
+            // Out of range of requested bounds
+            result = default_value;
+            ALOGV("%s(%s,%" PRIdMAX ") - out of range", __FUNCTION__, key, default_value);
+        } else if (end == buf) {
+            // Numeric conversion failed
+            result = default_value;
+            ALOGV("%s(%s,%" PRIdMAX ") - numeric conversion failed",
+                    __FUNCTION__, key, default_value);
+        }
+
+        errno = tmp;
+    }
+
+    return result;
+}
+
+int64_t utils::mtk_property_get_int64(const char *key, int64_t default_value){
+    return (int64_t)property_get_imax(key, INT64_MIN, INT64_MAX, default_value);
+}
+
+int32_t utils::mtk_property_get_int32(const char *key, int32_t default_value) {
+    return (int32_t)property_get_imax(key, INT32_MIN, INT32_MAX, default_value);
+}
+
+int utils::find_index(std::vector<std::string> v, std::string &str) {
+    auto is_find = std::find(v.begin(), v.end(), str);
+    int index = -1;
+    if(is_find != v.end()) {
+        index = std::distance(v.begin(), is_find);
+        LOG_D(LOG_TAG,"find_index: %d, band: %s", index, str.c_str());
+    }
+    return index;
+}
+
+std::string utils::format(const std::string& format, ...) {
+    va_list args;
+    va_start (args, format);
+    size_t len = std::vsnprintf(NULL, 0, format.c_str(), args);
+    va_end(args);
+    std::vector<char> vec(len + 1);
+    va_start(args, format);
+    std::vsnprintf(&vec[0], len + 1, format.c_str(), args);
+    va_end(args);
+    return &vec[0];
+}
+
+void utils::tokenize(std::string const &str, const char delim, std::vector<std::string> &out){
+    std::stringstream ss(str);
+    std::string s;
+    while(std::getline(ss, s ,delim)) {
+        out.push_back(s);
+    }
+}
+
+void utils::tokenize(std::string const &str, const char* delim, std::vector<std::string> &out){
+    char* token = strtok(const_cast<char*>(str.c_str()), delim);
+    while (token != nullptr) {
+        out.push_back(std::string(token));
+        token = strtok(nullptr, delim);
+    }
+}
+
+void utils::setMSimProperty(int phoneId, char *pPropertyName, char *pUpdateValue) {
+    #define MAX_PHONE_NUM 10
+    #define MIN(a,b) ((a)<(b) ? (a) : (b))
+
+    char oldItemValue[PROPERTY_VALUE_MAX] = {0};
+    char newPropertyValue[PROPERTY_VALUE_MAX] = {0};
+    int i = 0;
+    int strLen = 0;
+
+    for (i = 0; i < MAX_PHONE_NUM; i++) {
+        if (i == phoneId) {
+            // use new value
+            strncat(newPropertyValue, pUpdateValue, PROPERTY_VALUE_MAX - strlen(newPropertyValue));
+        } else {
+            getMSimProperty(i, pPropertyName, oldItemValue);
+            strncat(newPropertyValue, oldItemValue, PROPERTY_VALUE_MAX - strlen(newPropertyValue));
+        }
+        if (i != MAX_PHONE_NUM-1) {
+            strncat(newPropertyValue, ",", 1);
+        }
+        memset(oldItemValue, 0, PROPERTY_VALUE_MAX);
+    }
+    LOG_D(LOG_TAG,"setMSimProperty phoneId=%d, newPropertyValue=%s", phoneId, newPropertyValue);
+    // remove no use ','
+    strLen = strlen(newPropertyValue);
+    for (i = (strLen-1); i >= 0; i--) {
+        if (newPropertyValue[i] == ',') {
+            // remove
+            newPropertyValue[i] = '\0';
+        } else {
+            break;
+        }
+    }
+    LOG_D(LOG_TAG,"newPropertyValue %s\n", newPropertyValue);
+    mtk_property_set(pPropertyName, newPropertyValue);
+}
+
+void utils::getMSimProperty(int phoneId, char *pPropertyName,char *pPropertyValue) {
+    char prop[PROPERTY_VALUE_MAX] = {0};
+    char value[PROPERTY_VALUE_MAX] = {0};
+    int count= 0;
+    int propLen = 0;
+    int i = 0;
+    int j = 0;
+
+    mtk_property_get(pPropertyName, prop, "");
+    LOG_D(LOG_TAG,"getMSimProperty pPropertyName=%s, prop=%s", pPropertyName, prop);
+    propLen = strlen(prop);
+    for (i = 0; i < propLen; i++) {
+        if(prop[i] == ',') {
+            count++;
+            if((count-1) == phoneId) {
+                // return current buffer
+                LOG_D(LOG_TAG,"getMSimProperty found! phoneId=%d, value =%s", phoneId, value);
+                strncpy(pPropertyValue, value, strlen(value));
+                return;
+            } else {
+                // clear current buffer
+                j = 0;
+                memset(value, 0, sizeof(char) * PROPERTY_VALUE_MAX);
+            }
+        } else {
+            value[j] = prop[i];
+            j++;
+        }
+    }
+    if (count == phoneId) {
+        strncpy(pPropertyValue, value, strlen(value));
+        LOG_D(LOG_TAG,"getMSimProperty found at end! phoneId=%d, value =%s", phoneId, value);
+    }
+}
+
+bool utils::is_number(const std::string& s) {
+    std::string::const_iterator it = s.begin();
+    while(it != s.end() && std::isdigit(*it))
+    {
+        ++it;
+    }
+    return !s.empty() && it == s.end();
+}
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/utils.h b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/utils.h
new file mode 100644
index 0000000..83a46a1
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/util/utils.h
@@ -0,0 +1,80 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef MODEMCATEGORY_H_
+#define MODEMCATEGORY_H_
+
+#include <string>
+#include <vector>
+#include <sstream>
+#include <cstring>
+
+class utils {
+public:
+    utils();
+    virtual ~utils();
+    static bool is93Modem();
+    static bool is90Modem();
+    static bool isC2KSupport();
+    static bool isMt2635();
+    static bool isMt2731();
+    static bool is_support_dsds();
+    static bool is_suppport_dsss();
+    static int find_index(std::vector<std::string> v, std::string& str);
+    static std::string format(const std::string& format, ...);
+    static void tokenize(std::string const &str, const char delim, std::vector<std::string> &out);
+    static void tokenize(std::string const &str, const char* delim, std::vector<std::string> &out);
+    static int mtk_property_set(const char *key, const char *value);
+    static int mtk_property_get(const char *key, char *value, const char *default_value);
+    static bool mtk_property_get_bool(const char *key, bool default_value);
+    static int64_t mtk_property_get_int64(const char *key, int64_t default_value);
+    static int32_t mtk_property_get_int32(const char *key, int32_t default_value);
+    static void setMSimProperty(int phoneId, char *pPropertyName, char *pUpdateValue);
+    static void getMSimProperty(int phoneId, char *pPropertyName,char *pPropertyValue);
+    static bool is_number(const std::string& s);
+public:
+    static intmax_t property_get_imax(const char *key, intmax_t lower_bound, intmax_t upper_bound,
+            intmax_t default_value);
+    static constexpr int MODEM_UNKNOWN = 0;
+    static constexpr int MODEM_GSM = 1;
+    static constexpr int MODEM_TDSCDMA = 2;
+    static constexpr int MODEM_WCDMA = 3;
+    static constexpr int MODEM_LTE_TDD = 4;
+    static constexpr int MODEM_LTE_FDD = 5;
+    static constexpr int MODEM_CDMA_EVDO = 6;
+    static constexpr int MODEM_CDMA_1X = 7;
+};
+
+#endif /* MODEMCATEGORY_H_ */
diff --git a/src/lynq/lib/liblynq-tele-ril/ringtone/ring.wav b/src/lynq/lib/liblynq-tele-ril/ringtone/ring.wav
new file mode 100644
index 0000000..64dd030
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/ringtone/ring.wav
Binary files differ