[T106][ZXW-27]create lynq DEV environment in zxw yocto system

Change-Id: I5cd94f103ddf630475190ed5cdcac6553611b56d
diff --git a/cap/zx297520v3/sources/meta-zxic-custom/classes/workonsrc.bbclass b/cap/zx297520v3/sources/meta-zxic-custom/classes/workonsrc.bbclass
new file mode 100755
index 0000000..1137e98
--- /dev/null
+++ b/cap/zx297520v3/sources/meta-zxic-custom/classes/workonsrc.bbclass
@@ -0,0 +1,301 @@
+# Copyright (C) 2017 Mediatek
+# Author: Richard Sun
+# Some code and influence taken from externalsrc.bbclass:
+# Copyright (C) 2012 Linux Foundation
+# Author: Richard Purdie
+# Some code and influence taken from srctree.bbclass:
+# Copyright (C) 2009 Chris Larson <clarson@kergoth.com>
+# Released under the MIT license (see COPYING.MIT for the terms)
+#
+# workonsrc.bbclass enables use of an existing source tree, usually workon to 
+# the build system to build a piece of software rather than the usual fetch/unpack/patch
+# process.
+#
+# To use, add workonsrc to the global inherit and set WORKONSRC to point at the
+# directory you want to use containing the sources e.g. from local.conf for a recipe
+# called "myrecipe" you would do:
+#
+# INHERIT += "workonsrc"
+# WORKONSRC_pn-myrecipe = "/path/to/my/source/tree"
+#
+# In order to make this class work for both target and native versions (or with
+# multilibs/cross or other BBCLASSEXTEND variants), B is set to point to a separate
+# directory under the work directory (split source and build directories). This is
+# the default, but the build directory can be set to the source directory if
+# circumstances dictate by setting WORKONSRC_BUILD to the same value, e.g.:
+#
+# WORKONSRC_BUILD_pn-myrecipe = "/path/to/my/source/tree"
+#
+
+SRCTREECOVEREDTASKS ?= "do_patch do_unpack do_fetch"
+EXTERNALSRC_SYMLINKS ?= "oe-workdir:${WORKDIR} oe-logs:${T}"
+
+python () {
+    import subprocess, os.path
+
+    depends = d.getVar("DEPENDS")
+    depends = "%s rsync-native" % depends
+    d.setVar("DEPENDS", depends)
+
+    pn = d.getVar('PN')
+    d.appendVarFlag('do_populate_lic', 'depends', ' %s:do_configure' % pn)
+    workonsrc = d.getVar('WORKONSRC')
+    workonsrcbuild = d.getVar('WORKONSRC_BUILD')
+    if workonsrc and not workonsrc.startswith("/"):
+        bb.error("WORKONSRC must be an absolute path")
+    if workonsrcbuild and not workonsrcbuild.startswith("/"):
+        bb.error("WORKONSRC_BUILD must be an absolute path")
+
+    workonprebuilt = workonsrc.replace("build/../src/", "build/../prebuilt/")
+    if not os.path.exists(workonsrc):
+        if os.path.exists(workonprebuilt):
+            workonsrc = workonprebuilt
+        else:
+            bb.warn("Both %s and %s aren't existed" % (workonsrc, workonprebuilt) )
+
+    # If this is the base recipe and WORKONSRC is set for it or any of its
+    # derivatives, then enable BB_DONT_CACHE to force the recipe to always be
+    # re-parsed so that the file-checksums function for do_compile is run every
+    # time.
+    bpn = d.getVar('BPN')
+    classextend = (d.getVar('BBCLASSEXTEND') or '').split()
+    if bpn == d.getVar('PN') or not classextend:
+        if (workonsrc or
+                ('native' in classextend and
+                 d.getVar('WORKONSRC_pn-%s-native' % bpn)) or
+                ('nativesdk' in classextend and
+                 d.getVar('WORKONSRC_pn-nativesdk-%s' % bpn)) or
+                ('cross' in classextend and
+                 d.getVar('WORKONSRC_pn-%s-cross' % bpn))):
+            d.setVar('BB_DONT_CACHE', '1')
+
+    if workonsrc:
+        import oe.recipeutils
+        import oe.path
+
+        d.setVar('S', workonsrc)
+        if workonsrcbuild:
+            d.setVar('B', workonsrcbuild)
+        else:
+            d.setVar('B', '${WORKDIR}/${BPN}-${PV}/')
+            workonsrcbuild = d.getVar('B')
+
+        if workonsrc != workonsrcbuild:
+            d.setVar('S', workonsrcbuild)
+
+        local_srcuri = []
+        fetch = bb.fetch2.Fetch((d.getVar('SRC_URI') or '').split(), d)
+        for url in fetch.urls:
+            url_data = fetch.ud[url]
+            parm = url_data.parm
+            if (url_data.type == 'file' or
+                    'type' in parm and parm['type'] == 'kmeta'):
+                local_srcuri.append(url)
+
+        d.setVar('SRC_URI', ' '.join(local_srcuri))
+
+        if '{SRCPV}' in d.getVar('PV', False):
+            # Dummy value because the default function can't be called with blank SRC_URI
+            d.setVar('SRCPV', '999')
+
+        if d.getVar('CONFIGUREOPT_DEPTRACK') == '--disable-dependency-tracking':
+            d.setVar('CONFIGUREOPT_DEPTRACK', '')
+
+        tasks = filter(lambda k: d.getVarFlag(k, "task"), d.keys())
+
+        for task in tasks:
+            if task.endswith("_setscene"):
+                # sstate is never going to work for workon source trees, disable it
+                bb.build.deltask(task, d)
+            else:
+                # Since configure will likely touch ${S}, ensure only we lock so one task has access at a time
+                d.appendVarFlag(task, "lockfiles", " ${S}/singletask.lock")
+
+            # We do not want our source to be wiped out, ever (kernel.bbclass does this for do_clean)
+            cleandirs = oe.recipeutils.split_var_value(d.getVarFlag(task, 'cleandirs', False) or '')
+            setvalue = False
+            for cleandir in cleandirs[:]:
+                if oe.path.is_path_parent(workonsrc, d.expand(cleandir)):
+                    cleandirs.remove(cleandir)
+                    setvalue = True
+            if setvalue:
+                d.setVarFlag(task, 'cleandirs', ' '.join(cleandirs))
+
+        fetch_tasks = ['do_fetch', 'do_unpack']
+        # If we deltask do_patch, there's no dependency to ensure do_unpack gets run, so add one
+        # Note that we cannot use d.appendVarFlag() here because deps is expected to be a list object, not a string
+        d.setVarFlag('do_configure', 'deps', (d.getVarFlag('do_configure', 'deps', False) or []) + ['do_unpack'])
+
+        for task in d.getVar("SRCTREECOVEREDTASKS").split():
+            if local_srcuri and task in fetch_tasks:
+                continue
+            bb.build.deltask(task, d)
+
+        d.prependVarFlag('do_compile', 'prefuncs', "workonsrc_compile_prefunc ")
+        d.prependVarFlag('do_configure', 'prefuncs', "workonsrc_configure_prefunc ")
+
+        d.setVarFlag('do_compile', 'file-checksums', '${@srctree_hash_files(d)}')
+        d.setVarFlag('do_configure', 'file-checksums', '${@srctree_configure_hash_files(d)}')
+
+        # We don't want the workdir to go away
+        d.appendVar('RM_WORK_EXCLUDE', ' ' + d.getVar('PN'))
+
+        bb.build.addtask('do_buildclean',
+                         'do_clean' if d.getVar('S') == d.getVar('B') else None,
+                         None, d)
+
+
+        # If B=S the same builddir is used even for different architectures.
+        # Thus, use a shared CONFIGURESTAMPFILE and STAMP directory so that
+        # change of do_configure task hash is correctly detected and stamps are
+        # invalidated if e.g. MACHINE changes.
+        if d.getVar('S') == d.getVar('B'):
+            configstamp = '${TMPDIR}/work-shared/${PN}/${EXTENDPE}${PV}-${PR}/configure.sstate'
+            d.setVar('CONFIGURESTAMPFILE', configstamp)
+            d.setVar('STAMP', '${STAMPS_DIR}/work-shared/${PN}/${EXTENDPE}${PV}-${PR}')
+            d.setVar('STAMPCLEAN', '${STAMPS_DIR}/work-shared/${PN}/*-*')
+}
+
+python workonsrc_configure_prefunc() {
+    srctree_rsync_files(d)
+    s_dir = d.getVar('S')
+    # Create desired symlinks
+    symlinks = (d.getVar('EXTERNALSRC_SYMLINKS') or '').split()
+    newlinks = []
+    for symlink in symlinks:
+        symsplit = symlink.split(':', 1)
+        lnkfile = os.path.join(s_dir, symsplit[0])
+        target = d.expand(symsplit[1])
+        if len(symsplit) > 1:
+            if os.path.islink(lnkfile):
+                # Link already exists, leave it if it points to the right location already
+                if os.readlink(lnkfile) == target:
+                    continue
+                os.unlink(lnkfile)
+            elif os.path.exists(lnkfile):
+                # File/dir exists with same name as link, just leave it alone
+                continue
+            os.symlink(target, lnkfile)
+            newlinks.append(symsplit[0])
+    # Hide the symlinks from git
+    try:
+        git_exclude_file = os.path.join(s_dir, '.git/info/exclude')
+        if os.path.exists(git_exclude_file):
+            with open(git_exclude_file, 'r+') as efile:
+                elines = efile.readlines()
+                for link in newlinks:
+                    if link in elines or '/'+link in elines:
+                        continue
+                    efile.write('/' + link + '\n')
+    except IOError as ioe:
+        bb.note('Failed to hide EXTERNALSRC_SYMLINKS from git')
+}
+
+python workonsrc_compile_prefunc() {
+    srctree_rsync_files(d)
+    # Make it obvious that this is happening, since forgetting about it could lead to much confusion
+    bb.plain('NOTE: %s: compiling from workon source tree %s' % (d.getVar('PN'), d.getVar('WORKONSRC')))
+}
+
+do_buildclean[dirs] = "${S} ${B}"
+do_buildclean[nostamp] = "1"
+do_buildclean[doc] = "Call 'make clean' or equivalent in ${B}"
+workonsrc_do_buildclean() {
+	if [ -e Makefile -o -e makefile -o -e GNUmakefile ]; then
+		rm -f ${@' '.join([x.split(':')[0] for x in (d.getVar('EXTERNALSRC_SYMLINKS') or '').split()])}
+		if [ "${CLEANBROKEN}" != "1" ]; then
+			oe_runmake clean || die "make failed"
+		fi
+	else
+		bbnote "nothing to do - no makefile found"
+	fi
+}
+
+def srctree_rsync_files(d):
+    import subprocess, os.path
+
+    workonsrc = d.getVar('WORKONSRC')
+    workonprebuilt = workonsrc.replace("build/../src/", "build/../prebuilt/")
+    if not os.path.exists(workonsrc):
+        if os.path.exists(workonprebuilt):
+            workonsrc = workonprebuilt
+        else:
+            bb.warn("Both %s and %s aren't existed" % (workonsrc, workonprebuilt) )
+
+    if workonsrc:
+        d.setVar('S', workonsrc)
+        workonsrcbuild = d.getVar('WORKONSRC_BUILD')
+        if workonsrcbuild:
+            d.setVar('B', workonsrcbuild)
+        else:
+            d.setVar('B', '${WORKDIR}/${BPN}-${PV}/')
+            workonsrcbuild = d.getVar('B')
+
+        if workonsrc != workonsrcbuild:
+            cmd = "mkdir -p %s" % (workonsrcbuild)
+            subprocess.call(cmd, shell=True)
+
+            if os.path.exists(workonsrc):
+                workonsrc_rsync_appended_flag = d.getVar('WORKONSRC_RSYNC_APPENDED_FLAG')
+                if workonsrc_rsync_appended_flag is None:
+                    workonsrc_rsync_appended_flag=""
+                cmd = "rsync -aL %s %s/* %s" % (workonsrc_rsync_appended_flag, workonsrc, workonsrcbuild)
+                ret = subprocess.call(cmd, shell=True)
+                if ret != 0:
+                    bb.fatal("rsync -aL %s %s/* %s failed." % (workonsrc_rsync_appended_flag, workonsrc, workonsrcbuild))
+            d.setVar('S', workonsrcbuild)
+
+def srctree_hash_files(d, srcdir=None):
+    import shutil
+    import subprocess
+    import tempfile
+
+    s_dir = srcdir or d.getVar('WORKONSRC')
+    git_dir = None
+
+    try:
+        git_dir = os.path.join(s_dir,
+            subprocess.check_output(['git', '-C', s_dir, 'rev-parse', '--git-dir'], stderr=subprocess.DEVNULL).decode("utf-8").rstrip())
+    except subprocess.CalledProcessError:
+        pass
+
+    ret = " "
+    if git_dir is not None:
+        oe_hash_file = os.path.join(git_dir, 'oe-devtool-tree-sha1')
+        with tempfile.NamedTemporaryFile(prefix='oe-devtool-index') as tmp_index:
+            # Clone index
+            shutil.copyfile(os.path.join(git_dir, 'index'), tmp_index.name)
+            # Update our custom index
+            env = os.environ.copy()
+            env['GIT_INDEX_FILE'] = tmp_index.name
+            subprocess.check_output(['git', 'add', '-A', '.'], cwd=s_dir, env=env)
+            sha1 = subprocess.check_output(['git', 'write-tree'], cwd=s_dir, env=env).decode("utf-8")
+        with open(oe_hash_file, 'w') as fobj:
+            fobj.write(sha1)
+        ret = oe_hash_file + ':True'
+    else:
+        ret = s_dir + '/*:True'
+    return ret
+
+def srctree_configure_hash_files(d):
+    """
+    Get the list of files that should trigger do_configure to re-execute,
+    based on the value of CONFIGURE_FILES
+    """
+    in_files = (d.getVar('CONFIGURE_FILES') or '').split()
+    out_items = []
+    search_files = []
+    for entry in in_files:
+        if entry.startswith('/'):
+            out_items.append('%s:%s' % (entry, os.path.exists(entry)))
+        else:
+            search_files.append(entry)
+    if search_files:
+        s_dir = d.getVar('WORKONSRC')
+        for root, _, files in os.walk(s_dir):
+            for f in files:
+                if f in search_files:
+                    out_items.append('%s:True' % os.path.join(root, f))
+    return ' '.join(out_items)
+
+EXPORT_FUNCTIONS do_buildclean
diff --git a/cap/zx297520v3/sources/meta-zxic-custom/conf/lynq_base.conf b/cap/zx297520v3/sources/meta-zxic-custom/conf/lynq_base.conf
new file mode 100755
index 0000000..bcfe0af
--- /dev/null
+++ b/cap/zx297520v3/sources/meta-zxic-custom/conf/lynq_base.conf
@@ -0,0 +1,68 @@
+#DISTRO   = "lynq_vehicle_dc"
+#DISTRO_NAME   = "lynq distro vehicle_dc"
+RAT_CONFIG_C2K_SUPPORT = "no"
+MTK_MULTI_SIM_SUPPORT = "dsds" 
+TARGET_PLATFORM = "T106"
+MTK_LED_SUPPORT = "no"
+#support lynq_atsvc [hong.liu add for lynq atsvc on 2022.12.1]
+LYNQ_ATSVC_SUPPORT = "yes"
+
+#GPIO_CFG value:"PLATFORM" , "GENVICT" ,"GSW"
+MOBILETEK_GPIO_CFG = "PLATFORM"
+
+#PLL_CFG value:"PLATFORM","GSW"
+MOBILETEK_PLL_CFG = "PLATFORM"
+
+#RTP_CFG value:"PLATFORM","GSW"
+MOBILETEK_RTP_CFG = "PLATFORM"
+
+#MEDIA_CFG value:"PLATFORM","GSW"
+MOBILETEK_MEDIA_CFG = "PLATFORM"
+
+#LOG_CFG value:"PLATFORM","GSW"
+MOBILETEK_LOG_CFG = "PLATFORM"
+
+#FOTA_CFG value:"PLATFORM","GSW"
+MOBILETEK_FOTA_CFG = "PLATFORM"
+
+#RIL_CFG value:"PLATFORM","GSW"
+MOBILETEK_RIL_CFG = "PLATFORM"
+
+#UART_CFG value:"PLATFORM","GSW"
+MOBILETEK_UART_CFG = "PLATFORM"
+
+#USB_CFG value:"PLATFORM","GSW"
+MOBILETEK_USB_CFG = "PLATFORM"
+
+#ndis_CFG value:"PLATFORM","GSW"
+MOBILETEK_NDIS_CFG = "PLATFORM"
+
+#SUSPEND_CFG value:"PLATFORM","GSW"
+MOBILETEK_SUSPEND_CFG = "PLATFORM"
+
+#MNLDLOG_CFG value:"PLATFORM","GSW"
+MOBILETEK_MNLDLOG_CFG = "PLATFORM"
+
+#OPTEE_CFG value:"PLATFORM","GSW"
+MOBILETEK_OPTEE_CFG = "PLATFORM"
+
+#EMMC_CFG value:"PLATFORM","GSW"
+MOBILETEK_EMMC_CFG = "PLATFORM"
+
+#WIFIKERNELCODE_CFG value:"PLATFORM","GSW"
+MOBILETEK_WIFIKERNELCODE_CFG = "PLATFORM"
+
+#SYSTEMD_CFG value:"PLATFORM","GSW"
+MOBILETEK_SYSTEMD_CFG = "PLATFORM"
+
+#GSTREAMER_CFG value:"PLATFORM","GSW"
+MOBILETEK_GSTREAMER_CFG = "PLATFORM"
+
+#BUSYBOX_CFG value:"PLATFORM","GSW"
+MOBILETEK_BUSYBOX_CFG = "PLATFORM"
+
+#OPENSSH_CFG value:"PLATFORM","GSW"
+MOBILETEK_OPENSSH_CFG = "PLATFORM"
+
+#OEMAPP_CFG value:"PLATFORM","GSW"
+MOBILETEK_OEMAPP_CFG = "PLATFORM"
diff --git a/cap/zx297520v3/sources/meta-zxic-custom/recipes-core/images/lynq_base.conf b/cap/zx297520v3/sources/meta-zxic-custom/recipes-core/images/lynq_base.conf
new file mode 100755
index 0000000..ce7ed5a
--- /dev/null
+++ b/cap/zx297520v3/sources/meta-zxic-custom/recipes-core/images/lynq_base.conf
@@ -0,0 +1,5 @@
+#DISTRO   = "lynq_vehicle_dc"
+#DISTRO_NAME   = "lynq distro vehicle_dc"
+RAT_CONFIG_C2K_SUPPORT = "no"
+MTK_MULTI_SIM_SUPPORT = "dsds" 
+TARGET_PLATFORM = "T106"
diff --git a/cap/zx297520v3/sources/meta-zxic-custom/recipes-core/images/zxic-image.bb b/cap/zx297520v3/sources/meta-zxic-custom/recipes-core/images/zxic-image.bb
index edf84c9..2921727 100755
--- a/cap/zx297520v3/sources/meta-zxic-custom/recipes-core/images/zxic-image.bb
+++ b/cap/zx297520v3/sources/meta-zxic-custom/recipes-core/images/zxic-image.bb
@@ -36,6 +36,7 @@
 CORE_IMAGE_BASE_INSTALL = '\
     ${@bb.utils.contains("DISTRO_FEATURES", "OPENWRT", "${OPENWRT_PACKAGE}", "", d)} \ 
     packagegroup-core-boot-zxic \
+    packagegroup-lynq-t106 \
     ${@bb.utils.contains("DISTRO_FEATURES", "selinux", "packagegroup-selinux-minimal", "", d)} \ 
     ${MACHINE_EXTRA_RDEPENDS}   \
     ${CORE_IMAGE_EXTRA_INSTALL} \
diff --git a/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/liblynq-log/liblynq-log.bb b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/liblynq-log/liblynq-log.bb
new file mode 100755
index 0000000..c6ee2f1
--- /dev/null
+++ b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/liblynq-log/liblynq-log.bb
@@ -0,0 +1,67 @@
+inherit externalsrc package

+

+DESCRIPTION = "lynq-log.so demo"

+SECTION = "base"

+#LICENSE = "MediaTekProprietary"

+LICENSE = "CLOSED"

+LIC_FILES_CHKSUM = "file://LICENSE;md5=e1696b147d49d491bcb4da1a57173fff"

+#DEPENDS += "platform-libs libpal nandapi liblynq-uci"

+DEPENDS += "liblynq-uci"

+inherit workonsrc

+WORKONSRC = "${TOPDIR}/../src/lynq/lib/liblynq-log"

+

+TARGET_CC_ARCH += "${LDFLAGS}"

+BB_INCLUDE_ADD = "--sysroot=${STAGING_DIR_HOST}"

+BB_LDFLAGS_ADD = "--sysroot=${STAGING_DIR_HOST} -Wl,--hash-style=gnu"

+#Parameters passed to do_compile()

+EXTRA_OEMAKE = "'RAT_CONFIG_C2K_SUPPORT = ${RAT_CONFIG_C2K_SUPPORT}'\

+                'MTK_MULTI_SIM_SUPPORT = ${MTK_MULTI_SIM_SUPPORT}'\

+                'TARGET_PLATFORM = ${TARGET_PLATFORM}'"

+

+

+FILES_${PN} = "${base_libdir}/*.so \

+               ${base_bindir}\

+               ${base_sbindir}"

+

+

+FILES_${PN}-dev = "/test \

+                   ${includedir}"

+

+FILES_${PN}-doc = "/doc"

+

+FILES_${PN}-dbg ="${base_bindir}/.debug \

+                  ${base_libdir}/.debug \

+                  ${base_sbindir}/.debug"

+

+INSANE_SKIP_${PN} += "already-stripped"

+INSANE_SKIP_${PN} += "installed-vs-shipped"

+

+

+#INHIBIT_PACKAGE_STRIP = "1"

+do_compile () {

+	if [ "${PACKAGE_ARCH}" = "cortexa7hf-vfp-vfpv4-neon" ]; then

+		oe_runmake all ROOT=${STAGING_DIR_HOST} OFLAGS="--sysroot=${STAGING_DIR_HOST} -Os -mhard-float -Wl,--hash-style=gnu -DTELEPHONYWARE"

+	elif [ "${PACKAGE_ARCH}" = "cortexa7hf-neon-vfpv4" ]; then

+		oe_runmake all ROOT=${STAGING_DIR_HOST} OFLAGS="--sysroot=${STAGING_DIR_HOST} -Os -mhard-float -Wl,--hash-style=gnu -DTELEPHONYWARE"

+	elif [ "${PACKAGE_ARCH}" = "cortexa53hf-neon-fp-armv8" ]; then

+		oe_runmake all ROOT=${STAGING_DIR_HOST} OFLAGS="--sysroot=${STAGING_DIR_HOST} -Os -mhard-float -Wl,--hash-style=gnu -DTELEPHONYWARE -mhard-float -mfpu=neon-fp-armv8 -mfloat-abi=hard -mcpu=cortex-a53 -mtune=cortex-a53"

+	else

+		oe_runmake all ROOT=${STAGING_DIR_HOST} OFLAGS="--sysroot=${STAGING_DIR_HOST} -Os -Wl,--hash-style=gnu -DTELEPHONYWARE"

+	fi

+}

+

+do_install () {

+    oe_runmake install ROOT=${D}

+    echo "warren-D:${D}"

+    echo "warren-S:${S}"

+    if [ -d "${WORKONSRC}" ] ; then

+        install -d ${D}${includedir}/liblog

+        cp -af ${S}/include/liblog ${D}${includedir}/liblog

+      fi

+}

+

+addtask bachclean

+do_bachclean () {

+    oe_runmake clean

+}

+

diff --git a/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/liblynq-shm/liblynq-shm.bb b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/liblynq-shm/liblynq-shm.bb
new file mode 100755
index 0000000..57f2be5
--- /dev/null
+++ b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/liblynq-shm/liblynq-shm.bb
@@ -0,0 +1,55 @@
+inherit externalsrc package

+

+DESCRIPTION = "liblynq-shm.so"

+LICENSE = "MobileTekProprietary"

+LIC_FILES_CHKSUM = "file://LICENSE;md5=b1e07e8d88e26263e71d3a9e2aa9a2ff"

+DEPENDS += "liblynq-log"

+inherit workonsrc

+WORKONSRC = "${TOPDIR}/../src/lynq/lib/liblynq-shm/"

+

+TARGET_CC_ARCH += "${LDFLAGS}"

+BB_INCLUDE_ADD = "--sysroot=${STAGING_DIR_HOST}"

+BB_LDFLAGS_ADD = "--sysroot=${STAGING_DIR_HOST} -Wl,--hash-style=gnu"

+

+

+FILES_${PN} = "${base_libdir}/*.so "

+

+FILES_${PN}-dev = "/test \

+                   ${includedir}"

+

+FILES_${PN}-doc = "/doc"

+

+FILES_${PN}-dbg ="${base_bindir}/.debug \

+                  ${base_libdir}/.debug \

+                  ${base_sbindir}/.debug"

+

+INSANE_SKIP_${PN} += "already-stripped"

+INSANE_SKIP_${PN} += "installed-vs-shipped"

+

+

+#INHIBIT_PACKAGE_STRIP = "1"

+do_compile () {

+	if [ "${PACKAGE_ARCH}" = "cortexa7hf-vfp-vfpv4-neon" ]; then

+		oe_runmake all ROOT=${STAGING_DIR_HOST} OFLAGS="--sysroot=${STAGING_DIR_HOST} -Os -mhard-float -Wl,--hash-style=gnu -DTELEPHONYWARE"

+	elif [ "${PACKAGE_ARCH}" = "cortexa7hf-neon-vfpv4" ]; then

+		oe_runmake all ROOT=${STAGING_DIR_HOST} OFLAGS="--sysroot=${STAGING_DIR_HOST} -Os -mhard-float -Wl,--hash-style=gnu -DTELEPHONYWARE"

+	elif [ "${PACKAGE_ARCH}" = "cortexa53hf-neon-fp-armv8" ]; then

+		oe_runmake all ROOT=${STAGING_DIR_HOST} OFLAGS="--sysroot=${STAGING_DIR_HOST} -Os -mhard-float -Wl,--hash-style=gnu -DTELEPHONYWARE -mhard-float -mfpu=neon-fp-armv8 -mfloat-abi=hard -mcpu=cortex-a53 -mtune=cortex-a53"

+	else

+		oe_runmake all ROOT=${STAGING_DIR_HOST} OFLAGS="--sysroot=${STAGING_DIR_HOST} -Os -Wl,--hash-style=gnu -DTELEPHONYWARE"

+	fi

+}

+

+do_install () {

+    oe_runmake install ROOT=${D}

+	

+    if [ -d "${WORKONSRC}" ] ; then

+        install -d ${D}${includedir}/lynq_shm

+        cp -arf ${S}/include/* ${D}${includedir}/lynq_shm/	    	

+    fi 

+}

+

+addtask bachclean

+do_bachclean () {

+    oe_runmake clean

+}

diff --git a/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/liblynq-uci/liblynq-uci.bb b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/liblynq-uci/liblynq-uci.bb
new file mode 100755
index 0000000..b68663b
--- /dev/null
+++ b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/liblynq-uci/liblynq-uci.bb
@@ -0,0 +1,67 @@
+inherit externalsrc package
+
+DESCRIPTION = "liblynq-uci.so demo"
+LICENSE = "CLOSED"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=e1696b147d49d491bcb4da1a57173fff"
+#DEPENDS += "platform-libs-common uci"
+DEPENDS += "uci"
+inherit workonsrc
+WORKONSRC = "${TOPDIR}/../src/lynq/lib/liblynq-uci/"
+
+TARGET_CC_ARCH += "${LDFLAGS}"
+BB_INCLUDE_ADD = "--sysroot=${STAGING_DIR_HOST}"
+BB_LDFLAGS_ADD = "--sysroot=${STAGING_DIR_HOST} -Wl,--hash-style=gnu"
+#Parameters passed to do_compile()
+EXTRA_OEMAKE = "'RAT_CONFIG_C2K_SUPPORT = ${RAT_CONFIG_C2K_SUPPORT}'\
+                'MTK_MULTI_SIM_SUPPORT = ${MTK_MULTI_SIM_SUPPORT}'\
+                'TARGET_PLATFORM = ${TARGET_PLATFORM}'"
+
+FILES_${PN} = "${base_libdir}/*.so \
+               ${base_bindir}\
+               ${base_sbindir} \
+               /etc/config \
+               /etc/dbus-1/system.d/"
+
+FILES_${PN}-dev = "/test \
+                   ${includedir}"
+
+FILES_${PN}-doc = "/doc"
+
+FILES_${PN}-dbg ="${base_bindir}/.debug \
+                  ${base_libdir}/.debug \
+                  ${base_sbindir}/.debug"
+
+INSANE_SKIP_${PN} += "already-stripped"
+INSANE_SKIP_${PN} += "installed-vs-shipped"
+
+
+#INHIBIT_PACKAGE_STRIP = "1"
+do_compile () {
+	echo "TOPDIR:${TOPDIR}" 
+	if [ "${PACKAGE_ARCH}" = "cortexa7hf-vfp-vfpv4-neon" ]; then
+		oe_runmake all ROOT=${STAGING_DIR_HOST} OFLAGS="--sysroot=${STAGING_DIR_HOST} -Os -mhard-float -Wl,--hash-style=gnu -DTELEPHONYWARE"
+	elif [ "${PACKAGE_ARCH}" = "cortexa7hf-neon-vfpv4" ]; then
+		oe_runmake all ROOT=${STAGING_DIR_HOST} OFLAGS="--sysroot=${STAGING_DIR_HOST} -Os -mhard-float -Wl,--hash-style=gnu -DTELEPHONYWARE"
+	elif [ "${PACKAGE_ARCH}" = "cortexa53hf-neon-fp-armv8" ]; then
+		oe_runmake all ROOT=${STAGING_DIR_HOST} OFLAGS="--sysroot=${STAGING_DIR_HOST} -Os -mhard-float -Wl,--hash-style=gnu -DTELEPHONYWARE -mhard-float -mfpu=neon-fp-armv8 -mfloat-abi=hard -mcpu=cortex-a53 -mtune=cortex-a53"
+	else
+		oe_runmake all ROOT=${STAGING_DIR_HOST} OFLAGS="--sysroot=${STAGING_DIR_HOST} -Os -Wl,--hash-style=gnu -DTELEPHONYWARE"
+	fi
+}
+
+do_install () {
+    oe_runmake install ROOT=${D}
+	
+    if [ -d "${WORKONSRC}" ] ; then
+        install -d ${D}${includedir}/
+        cp -af ${S}/include/ ${D}${includedir}/
+        install -d ${D}/etc/config
+        install -m 0644 ${S}/lynq_uci.config ${D}/etc/config/lynq_uci
+        install -m 0644 ${S}/lynq_uci_ro.config ${D}/etc/config/lynq_uci_ro
+    fi 
+}
+
+addtask bachclean
+do_bachclean () {
+    oe_runmake clean
+}
diff --git a/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/libvendor-ril/LICENSE b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/libvendor-ril/LICENSE
new file mode 100755
index 0000000..77f59ed
--- /dev/null
+++ b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/libvendor-ril/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/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/libvendor-ril/libvendor-ril.bb b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/libvendor-ril/libvendor-ril.bb
new file mode 100644
index 0000000..e53e26b
--- /dev/null
+++ b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/libvendor-ril/libvendor-ril.bb
@@ -0,0 +1,35 @@
+#Basic Configuration
+DESCRIPTION = "Library for RILD"
+SECTION = "base"
+#LICENSE = "MobileTekProprietary"
+LICENSE = "CLOSED"
+#LIC_FILES_CHKSUM = "file://LICENSE;md5=e1696b147d49d491bcb4da1a57173fff"
+DEPENDS = "libreference-ril"
+
+do_install () {
+    echo "warren-D:${D}"
+    echo "warren-S:${S}"
+    echo "warren-test:${PKG_CONFIG_SYSROOT_DIR}"
+    install -d ${D}${includedir}/vendor-ril
+    cp -af ${PKG_CONFIG_SYSROOT_DIR}/${includedir}/telephony/ril.h ${D}${includedir}/vendor-ril
+    cp -af ${PKG_CONFIG_SYSROOT_DIR}/${includedir}/telephony ${D}${includedir}/vendor-ril
+    #install -d ${D}/lib64
+    install -d ${D}/${base_libdir}
+    ln -sf -r ${PKG_CONFIG_SYSROOT_DIR}${libdir}/libreference-ril.so ${D}/${base_libdir}/libvendor-ril.so
+    #ln -s ${S}/../recipe-sysroot/usr/lib/libreference-ril.so ${D}${bindir}/libvendor-ril.so
+    #cp ${PKG_CONFIG_SYSROOT_DIR}${libdir}/libreference-ril.so ${D}/lib64/
+    #mv ${D}/lib64/libreference-ril.so ${D}/lib64/libvendor-ril.so
+    #if [ -d "${WORKONSRC}" ] ; then
+    #    install -d ${D}${includedir}/vendor-ril
+    #    cp -af ${S}/include/telephony/ril.h ${D}${includedir}/vendor-ril
+    #    cp -af ${S}/include/telephony ${D}${includedir}/vendor-ril
+    #    install -d ${D}/etc/dbus-1/system.d
+    #    install -m 0644 ${S}/mtk-rilproxy/telephony/sdk/data_sdk.conf ${D}/etc/dbus-1/system.d
+    #fi
+}
+
+addtask bachclean
+do_bachclean () {
+    oe_runmake clean
+}
+
diff --git a/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/lynq-ril-service/lynq-ril-service.bb b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/lynq-ril-service/lynq-ril-service.bb
new file mode 100755
index 0000000..f77e994
--- /dev/null
+++ b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/lynq-ril-service/lynq-ril-service.bb
@@ -0,0 +1,53 @@
+#inherit externalsrc package
+inherit externalsrc package systemd
+DESCRIPTION = "lynq ril service"
+LICENSE = "MobileTekProprietary"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=b1e07e8d88e26263e71d3a9e2aa9a2ff"
+DEPENDS += "${@bb.utils.contains('TARGET_PLATFORM', 'mt2735', 'platform-libs audio-mixer-ctrl libpal streamer1.0', '', d)} libvendor-ril libbinder glib-2.0 dbus liblynq-log liblynq-uci liblynq-shm"
+inherit workonsrc
+WORKONSRC = "${TOPDIR}/../src/lynq/framework/lynq-ril-service/src"
+
+TARGET_CC_ARCH += "${LDFLAGS}"
+SYSTEMD_PACKAGES = "${PN}"
+SYSTEMD_SERVICE_${PN} = "lynq_ril_service.service"
+FILES_${PN} += "${systemd_unitdir}/system/lynq_ril_service.service"
+FILES_${PN} += "/system/etc/tele/ring ${bindir}"
+#Parameters passed to do_compile()
+EXTRA_OEMAKE = "'RAT_CONFIG_C2K_SUPPORT = ${RAT_CONFIG_C2K_SUPPORT}'\
+                'MTK_MULTI_SIM_SUPPORT = ${MTK_MULTI_SIM_SUPPORT}'\
+                'TARGET_PLATFORM = ${TARGET_PLATFORM}'\
+                'MTK_LED_SUPPORT = ${MTK_LED_SUPPORT}'"
+EXTRA_OEMAKE += "'MOBILETEK_RIL_CFG = ${MOBILETEK_RIL_CFG}'"
+
+EXTRA_OEMAKE += "'MOBILETEK_FOTA_CFG = ${MOBILETEK_FOTA_CFG}'"
+
+#INHIBIT_PACKAGE_STRIP = "1"
+do_compile () {
+	if test "${PACKAGE_ARCH}" = "cortexa7hf-vfp-vfpv4-neon" || test "${PACKAGE_ARCH}" = "cortexa7hf-neon-vfpv4"; then
+		oe_runmake all ROOT=${STAGING_DIR_HOST} OFLAGS="--sysroot=${STAGING_DIR_HOST} -mhard-float"
+	else
+		oe_runmake all ROOT=${STAGING_DIR_HOST} OFLAGS="--sysroot=${STAGING_DIR_HOST}"
+	fi
+}
+
+do_install() {
+	echo "lynq-ril-service PN ${PN}"
+	echo "lynq-ril-service FILES_${PN} ${FILES_${PN}}"
+	echo "lynq-ril-service D ${D}"
+	echo "lynq-ril-service bindir ${bindir}"
+	echo "lynq-ril-service ${D}${bindir}"
+	echo "lynq-ril-service ${S}/lynq-ril-service"
+	install -d ${D}${bindir}/
+	install -m 0755 ${S}lynq-ril-service ${D}${bindir}/
+	if ${@bb.utils.contains('DISTRO_FEATURES','systemd','true','false',d)}; then
+		install -d ${D}${systemd_unitdir}/system/
+		install -m 0644 ${B}/lynq_ril_service.service ${D}${systemd_unitdir}/system
+	fi
+#	install -d ${D}${includedir}
+#	install ${S}/atci/ATCI.h ${D}${includedir}
+#	cp -R ${S}/demoscript ${D}${bindir}/
+	if test "${TARGET_PLATFORM}" = "mt2731"; then
+		install -d ${D}/system/etc/tele/ring
+		cp -R ${TOPDIR}/../src/lynq/framework/lynq-ril-service/ringtone/*.wav ${D}/system/etc/tele/ring
+	fi
+}
diff --git a/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/packagegroups/packagegroup-lynq-t106.bb b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/packagegroups/packagegroup-lynq-t106.bb
new file mode 100755
index 0000000..916dab9
--- /dev/null
+++ b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/packagegroups/packagegroup-lynq-t106.bb
@@ -0,0 +1,12 @@
+SUMMARY = "Lynq Package Group - t106"
+LICENSE = "MediaTekProprietary"
+
+inherit packagegroup
+
+RDEPENDS_packagegroup-lynq-t106 = "\
+    uci \
+    liblynq-log \
+    liblynq-uci \
+    liblynq-shm \
+    "
+
diff --git a/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/uci/uci_git.bb b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/uci/uci_git.bb
new file mode 100755
index 0000000..a3abe4c
--- /dev/null
+++ b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/uci/uci_git.bb
@@ -0,0 +1,36 @@
+DESCRIPTION = "Unified Configuration Interface (UCI)"
+SECTION = "libs"
+LICENSE = "LGPL-2.1"
+LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/LGPL-2.1;md5=1a6d268fd218675ffea8be556788b780"
+
+SRC_URI = " \
+    git://git.openwrt.org/project/uci.git \
+"
+
+SRCREV = "415f9e48436d29f612348f58f546b3ad8d74ac38"
+PV = "1.0.0+git${SRCPV}"
+
+S = "${WORKDIR}/git"
+
+#SRC_URI += "file://uci.sh"
+
+DEPENDS += "libubox"
+
+INSANE_SKIP_${PN} += "dev-deps"
+FILES_SOLIBSDEV = ""
+
+FILES_${PN}-dev = "${includedir}/*"
+FILES_${PN} = "${bindir}/uci ${libdir}/libuci.so"
+
+inherit cmake
+
+EXTRA_OECMAKE = " -DBUILD_LUA=OFF -DCMAKE_SKIP_RPATH=TRUE"
+
+do_install() {
+    install -d ${D}${libdir}
+    install -d ${D}${bindir}
+    install -d ${D}${includedir}
+    install -m 0755 ${B}/uci ${D}${bindir}
+    install -m 0755 ${B}/libuci.so ${D}${libdir}/
+    install -m 0644 ${S}/uci*.h ${D}${includedir}
+}
diff --git a/cap/zx297520v3/sources/poky/meta-poky/conf/local.conf.sample b/cap/zx297520v3/sources/poky/meta-poky/conf/local.conf.sample
index b555f1d..2ad664c 100644
--- a/cap/zx297520v3/sources/poky/meta-poky/conf/local.conf.sample
+++ b/cap/zx297520v3/sources/poky/meta-poky/conf/local.conf.sample
@@ -265,3 +265,5 @@
 # track the version of this file when it was generated. This can safely be ignored if
 # this doesn't mean anything to you.
 CONF_VERSION = "1"
+#add lynq require
+require ${BSPDIR}/sources/meta-zxic-custom/conf/lynq_base.conf
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service.rar.gz b/cap/zx297520v3/src/lynq/framework/lynq-ril-service.rar.gz
new file mode 100644
index 0000000..ae394da
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service.rar.gz
Binary files differ
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/LICENSE b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/LICENSE
new file mode 100755
index 0000000..605b7ea
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/LICENSE
@@ -0,0 +1,31 @@
+Copyright Statement:
+
+This software/firmware and related documentation ("MobileTek Software") are
+protected under relevant copyright laws. The information contained herein is
+confidential and proprietary to MobileTek Inc. and/or its licensors. Without
+the prior written permission of MobileTek inc. and/or its licensors, any
+reproduction, modification, use or disclosure of MobileTek Software, and
+information contained herein, in whole or in part, shall be strictly
+prohibited.
+
+MobileTek Inc. (C) 2015. All rights reserved.
+
+BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MobileTek SOFTWARE")
+RECEIVED FROM MobileTek AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ON AN "AS-IS" BASIS ONLY. MobileTek 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 MobileTek PROVIDE ANY WARRANTY WHATSOEVER WITH
+RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+INCORPORATED IN, OR SUPPLIED WITH THE MobileTek 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 MobileTek
+SOFTWARE. MobileTek SHALL ALSO NOT BE RESPONSIBLE FOR ANY MobileTek SOFTWARE
+RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MobileTek'S
+ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MobileTek SOFTWARE
+RELEASED HEREUNDER WILL BE, AT MobileTek'S OPTION, TO REVISE OR REPLACE THE
+MobileTek SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+CHARGE PAID BY RECEIVER TO MobileTek FOR SUCH MobileTek SOFTWARE AT ISSUE.
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/Makefile b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/Makefile
new file mode 100755
index 0000000..2ff74f9
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/NOTICE b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/NOTICE
new file mode 100755
index 0000000..c5b1efa
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/README b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/README
new file mode 100755
index 0000000..9a7e82f
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/lynq-riltel.tar.gz b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/lynq-riltel.tar.gz
new file mode 100755
index 0000000..d3f120e
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/lynq-riltel.tar.gz
Binary files differ
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/ringtone/ring.wav b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/ringtone/ring.wav
new file mode 100755
index 0000000..64dd030
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/ringtone/ring.wav
Binary files differ
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/LICENSE b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/LICENSE
new file mode 100755
index 0000000..605b7ea
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/LICENSE
@@ -0,0 +1,31 @@
+Copyright Statement:
+
+This software/firmware and related documentation ("MobileTek Software") are
+protected under relevant copyright laws. The information contained herein is
+confidential and proprietary to MobileTek Inc. and/or its licensors. Without
+the prior written permission of MobileTek inc. and/or its licensors, any
+reproduction, modification, use or disclosure of MobileTek Software, and
+information contained herein, in whole or in part, shall be strictly
+prohibited.
+
+MobileTek Inc. (C) 2015. All rights reserved.
+
+BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MobileTek SOFTWARE")
+RECEIVED FROM MobileTek AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ON AN "AS-IS" BASIS ONLY. MobileTek 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 MobileTek PROVIDE ANY WARRANTY WHATSOEVER WITH
+RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+INCORPORATED IN, OR SUPPLIED WITH THE MobileTek 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 MobileTek
+SOFTWARE. MobileTek SHALL ALSO NOT BE RESPONSIBLE FOR ANY MobileTek SOFTWARE
+RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MobileTek'S
+ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MobileTek SOFTWARE
+RELEASED HEREUNDER WILL BE, AT MobileTek'S OPTION, TO REVISE OR REPLACE THE
+MobileTek SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+CHARGE PAID BY RECEIVER TO MobileTek FOR SUCH MobileTek SOFTWARE AT ISSUE.
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/Ril_responsedispatch.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/Ril_responsedispatch.cpp
new file mode 100755
index 0000000..ad253c9
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/Ril_responsedispatch.cpp
@@ -0,0 +1,204 @@
+//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 <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;
+static bool list_init_done = false;
+//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);
+
+//function define
+void initList(struct RspDisp_Event* list)
+{
+    memset(list, 0 ,sizeof(struct RspDisp_Event));
+    list->next = list;
+    list->prev = list;
+    list_init_done = true;
+    WAKEUPLIST();
+    RLOGD("Demo Ril_event init list!");
+}
+
+void addToList(struct RspDisp_Event* ev, struct RspDisp_Event* list)
+{ //add to list tail
+    if(!list_init_done) {
+        RLOGD("Demo Ril_event add an event , wait list init done!");
+        WAITLIST();
+        RLOGD("Demo Ril_event add an event , list init done,continue...");
+    }
+    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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/ATCI.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/ATCI.cpp
new file mode 100755
index 0000000..236a3d7
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/ATCI.cpp
@@ -0,0 +1,897 @@
+//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 <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"
+#include "atci_lynq_data_cmd.h" //warren add for lynq atsvc on 20221207
+#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 = -1;
+int atci_client_connect = -1;
+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);
+}
+
+/*warren add for lynq atsvc on 20221208 start*/
+int atci_send_result(int error_code)
+{
+    char buf[32];
+    memset(buf, 0, sizeof(buf));
+    if(error_code != 0)
+    {
+        sprintf(buf,"%s%d\r\n","\r\n+CME ERROR: ",error_code);
+    }
+    else
+    {
+        sprintf(buf,"%s","\r\nOK\r\n");
+    }
+    int len_s = send(atci_client_connect, buf, strlen(buf), 0);
+    if(len_s != strlen(buf))
+    {
+        RLOGD("send buf fail Response Buf is %s, send length is %d",buf,len_s);
+        return -1;
+    }
+    RLOGD("Response Buf is %s, send length is %d",buf,len_s);
+    return 0;
+}
+int atci_send_data(char *data)
+{
+    char buf[256];
+    int data_len = 0;
+    memset(buf, 0, sizeof(buf));
+    if(NULL == data)
+    {
+        RLOGD("data is null");
+        return -1;
+    }
+    else
+    {
+        data_len = strlen(data);
+        if(data_len > 252)// \r\n + \r\n\0
+        {
+            RLOGD("data too long");
+            snprintf(buf,252,"\r\n%s\r\n",data);
+        }
+        else
+        {
+            snprintf(buf,data_len+5,"\r\n%s\r\n",data);// \r\n + \r\n\0
+        }
+        int len_s = send(atci_client_connect, buf, strlen(buf), 0);
+        if(len_s != strlen(buf))
+        {
+            RLOGD("send buf fail Response Buf is %s, send length is %d",buf,len_s);
+            return -1;
+        }
+        RLOGD("Response Buf is %s, send length is %d",buf,len_s);
+    }
+    return 0;
+}
+void ATCIResponseNoToken(int error, char* data, int reqNum)
+{
+    char buf[64];
+    if(NULL == data && reqNum == 0)
+    {
+          RLOGD("[%d][%s] input error",__LINE__,__FUNCTION__);
+          return;
+    }
+    RLOGD("request is %d,%s",reqNum,android::requestToString(reqNum));
+    if(NULL == data)
+    {
+        if(atci_send_result(error)!=0)
+        {
+            RLOGD("send result fail");
+        }
+    }
+    else
+    {
+        if(atci_send_data(data)!=0)
+        {
+            RLOGD("send data fail");
+            return;
+        }
+        if(atci_send_result(error)!=0)
+        {
+            RLOGD("send result fail");
+        }
+    }
+}
+/*warren add for lynq atsvc on 20221208 end*/
+#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)||atci_lynq_data_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);
+  if(atci_client_connect >= 0) {
+      RLOGE("atci_client_connect need close!");
+      close(atci_client_connect);
+      atci_client_connect = -1;
+  }
+  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,cmd_mode:%d",cmd_mode);
+    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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/ATCI.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/ATCI.h
new file mode 100755
index 0000000..6d52dbf
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/ATCI.h
@@ -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.
+ */
+#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 ATCIResponseNoToken(int error, char* data, int reqNum); /*warren add for lynq atsvc on 20221208*/
+int atci_send_data(char *data);
+int atci_send_result(int error_code);
+void * StartATCISocket(void *param);
+#endif
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/atci_at_util.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/atci_at_util.cpp
new file mode 100755
index 0000000..027d924
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/atci_at_util.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/atci_at_util.h
new file mode 100755
index 0000000..dfcc324
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/atci_cc_cmd.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/atci_cc_cmd.cpp
new file mode 100755
index 0000000..8a41e90
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/atci_cc_cmd.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/atci_cc_cmd.h
new file mode 100755
index 0000000..a532180
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/atci_common.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/atci_common.h
new file mode 100755
index 0000000..01e738a
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/atci_lynq_data_cmd.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/atci_lynq_data_cmd.cpp
new file mode 100755
index 0000000..2994ca3
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/atci_lynq_data_cmd.cpp
@@ -0,0 +1,769 @@
+/**********************************************************************************************
+* @file atci_lynq_data_cmd.cpp
+* @brief.Implementation of lynq data AT commands function 
+* @details None
+* @author   Hong Liu。
+* @date     2022-12-07
+* @version  V1.0
+* @copyright   Copyright (c) MobileTek 
+***********************************************************************************************/
+#include <vendor-ril/telephony/ril.h>
+#include <string.h>
+#include <log/log.h>
+#include <vector>
+#include "Radio_capability_switch_util.h"
+#include "ATCI.h"
+#include "atci_util.h"
+#include "atci_at_util.h"
+#include "atci_lynq_data_cmd.h"
+#include "atci_common.h"
+#include "lynq_common.h"
+#include "common.h"
+#include "sim.h"
+
+
+#undef LOG_TAG
+#define LOG_TAG "DEMO_ATCI_DATA"
+#define LINE __LINE__
+#define FUNC __FUNCTION__
+#define SET_DEFAULT_SIM_ALL -1
+
+int g_flag_apn = 0;
+
+atci_cmd_type_t atci_data_cmd_table[] = {
+//cmd_name      target_type        handler
+    { "AT+LAPNACT", TARGET_TELEPHONY, atci_data_enable_pdp_hdlr },            //AT command to enable defult PDP
+    { "AT+ELAPNACT", TARGET_TELEPHONY, atci_data_enable_pdp_with_apn_hdlr },  //AT command to enable PDP with APN
+    { "AT+LEAPNMOD", TARGET_TELEPHONY, atci_data_modify_apn_hdlr },           //AT command to modify APN
+    { "AT+LCSUS", TARGET_TELEPHONY, atci_switch_card_halr },
+    { NULL, TARGET_UNKNOWN, NULL }
+};
+int atci_lynq_data_init(void *arg) {
+    int ret;
+    ret = atci_cmd_register(atci_data_cmd_table);
+    return ret;
+}
+
+int atci_switch_card_halr(char *cmd, int op_mode, int target, char *response)
+{
+    char buf[16];
+    switch (op_mode)
+    {
+        case AT_SET_MODE:
+        {
+            //paser parameter
+            //send to target handle
+            //ex: at+lapnact=int
+            RLOGD("input cmd[%s]", cmd);
+            if (SYS_FAIL == atci_at_to_equal(&cmd))
+            {
+                //input error
+                ATCIResponseNoToken(100,NULL,SET_DEFAULT_SIM_ALL);
+                return SYS_FAIL;
+            }
+            RLOGD("[%d][%s] data is[%s]",LINE,FUNC,cmd);
+            int state;
+            if (SYS_FAIL == atci_at_get_nexthexint(&cmd, &state))
+            {
+                ATCIResponseNoToken(100,NULL,SET_DEFAULT_SIM_ALL);
+                return SYS_FAIL;
+            }
+            RLOGD("state value is %d", state);
+            if(state==1)
+            {
+                char* argv[2] = { 0 };
+                argv[0] = "SET_DEFAULT_SIM_ALL";
+                //sprintf(argv[1], "%d", state);
+                argv[1] = "1";
+                
+                int argc = 2;
+                android::lynqSendToRil(2,argv,1024);
+                RLOGD("%s g_switch_card_error %d %d", __FUNCTION__, g_switch_card_error, __LINE__);
+                if(!g_switch_card_error)
+                {
+                    ATCIResponseNoToken(0,NULL,-1);
+                }
+                else
+                {
+                    ATCIResponseNoToken(g_switch_card_error,NULL,-1);
+                }
+                
+            }
+            else if(state == 0)
+            {
+                char* argv[2] = { 0 };
+                argv[0] = "SET_DEFAULT_SIM_ALL";
+                //sprintf(argv[1], "%d", state);
+                argv[1] = "0";
+                
+                int argc = 2;
+                android::lynqSendToRil(2,argv,1024);
+                RLOGD("%s g_switch_card_error %d %d", __FUNCTION__, g_switch_card_error, __LINE__);
+                if(!g_switch_card_error)
+                {
+                    ATCIResponseNoToken(0,NULL,-1);
+                }
+                else
+                {
+                    ATCIResponseNoToken(g_switch_card_error,NULL,-1);
+                }
+            }
+            else
+            {
+                
+                ATCIResponseNoToken(100,NULL,SET_DEFAULT_SIM_ALL);
+                return SYS_FAIL;
+            }
+            break;
+        }
+        case AT_TEST_MODE:
+        {
+            memset(buf,0,sizeof(buf));
+            sprintf(buf,"%s","+LCSUS: (0,1)");
+            ATCIResponseNoToken(0,buf,SET_DEFAULT_SIM_ALL);
+            break;
+        }
+        case AT_READ_MODE:
+        {
+            
+            int id = get_default_sim_all();
+            memset(buf,0,sizeof(buf));
+            sprintf(buf,"+LCSUS: %d", id);
+            ATCIResponseNoToken(0,buf,SET_DEFAULT_SIM_ALL);
+            break;
+        }
+        default:
+        {
+            RLOGD("set mute error");
+            break;
+        }
+    }
+    return SYS_SUCC;
+}
+
+int check_sim_state(void)
+{
+    char buf[16];
+    //send request
+    char* argv[1] = { 0 };
+    argv[0] = "RIL_REQUEST_GET_SIM_STATUS";
+    android::lynqSendToRil(1,argv,1024);
+    //wait response from callback
+    if(lynq_wait_result_comeback(2000))
+    {
+        sprintf(buf,"%s","+CME ERROR: 14");//sim busy
+        if(atci_send_data(buf)!=0)
+        {
+            RLOGD("send data fail");
+            return SYS_FAIL;
+        }
+        RLOGD("[%d][%s] wait sim state timeout",LINE,FUNC);
+        return SYS_FAIL;
+    }
+    //judge result
+    if(g_lynq_sim_state != 1)
+    {
+        RLOGD("SIM card absent");
+        sprintf(buf,"%s","+CME ERROR: 10");
+        if(atci_send_data(buf)!=0)
+        {
+            RLOGD("send data fail");
+            return SYS_FAIL;
+        }
+        return SYS_FAIL;
+    }
+    if(checkDataRegistration(1024))
+    {
+        RLOGD("[%d][%s] data registion fail",LINE,FUNC);
+        sprintf(buf,"%s","+CME ERROR: 1");
+        if(atci_send_data(buf)!=0)
+        {
+            RLOGD("send data fail");
+            return SYS_FAIL;
+        }
+        return SYS_FAIL;
+    }
+    return SYS_SUCC;
+}
+
+int atci_data_enable_pdp_hdlr(char *cmd, int op_mode, int target, char *response)
+{
+    int ret;
+    char buf[16];
+    switch (op_mode)
+    {
+        case AT_SET_MODE:
+        {
+            //paser parameter
+            //send to target handle
+            //ex: at+lapnact=int
+            RLOGD("input cmd[%s]", cmd);
+            if (SYS_FAIL == atci_at_to_equal(&cmd))
+            {
+                //input error
+                ATCIResponseNoToken(100,NULL,RIL_REQUEST_SETUP_DATA_CALL);
+                return SYS_FAIL;
+            }
+            RLOGD("[%d][%s] data is[%s]",LINE,FUNC,cmd);
+            int state;
+
+            if (SYS_FAIL == atci_at_get_nexthexint(&cmd, &state))
+            {
+                ATCIResponseNoToken(100,NULL,RIL_REQUEST_SETUP_DATA_CALL);
+                return SYS_FAIL;
+            }
+
+            RLOGD("state value is %d", state);
+
+            //wrire data to target
+            atci_data_req_t req;
+            if(state==1)
+            {
+                if(check_sim_state())
+                {
+                    return SYS_FAIL;
+                }
+                req.request_id = RIL_REQUEST_SETUP_DATA_CALL;
+            }
+            else if(state == 0)
+            {
+                req.request_id = RIL_REQUEST_DEACTIVATE_DATA_CALL;
+            }
+            else
+            {
+                ATCIResponseNoToken(100,NULL,RIL_REQUEST_SETUP_DATA_CALL);
+                return SYS_FAIL;
+            }
+            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;
+            int argc = 1;
+            sendAtciRequest(req.request_id, reqStr, argc, argv);
+            ATCIResponseNoToken(0,NULL,req.request_id);
+            break;
+        }
+        case AT_TEST_MODE:
+        {
+            memset(buf,0,sizeof(buf));
+            sprintf(buf,"%s","+LAPNACT: (0,1)");
+            ATCIResponseNoToken(0,buf,RIL_REQUEST_SETUP_DATA_CALL);
+            break;
+        }
+        case AT_READ_MODE:
+        {
+            for(int i = 0;i < LYNQ_APN_CHANNEL_MAX; i ++)
+            {
+                if(!apn_table[i].used)
+                {
+                    continue;
+                }
+                memset(buf,0,sizeof(buf));
+                sprintf(buf,"+LAPNACT: %s,%s,%d,%s,%s\n", apn_table[i].apn, apn_table[i].apntype ,apn_table[i].pdpstate, apn_table[i].ifaceName, apn_table[i].address);
+                if(atci_send_data(buf)!=0)
+                {
+                    RLOGD("send data fail");
+                    return SYS_FAIL;
+                }
+            }
+            if(apn_count == 0)
+            {
+                memset(buf,0,sizeof(buf));
+                ATCIResponseNoToken(0,buf,RIL_REQUEST_SETUP_DATA_CALL);
+                return SYS_SUCC;
+            }
+            atci_send_result(0);
+            break;
+        }
+        default:
+        {
+            RLOGD("set mute error");
+            break;
+        }
+    }
+    return SYS_SUCC;
+}
+
+int atci_data_enable_pdp_with_apn_hdlr(char *cmd, int op_mode, int target,char *response)
+{
+    int ret;
+    int argc = 0;
+    char* argv[8] = { 0 };
+    char buf[512];
+    char authTypebuf[16] = {0};
+    int state = 0;
+    int authType = 0;
+    char *apn = NULL;
+    char *apnTpye = NULL;
+    char *user = NULL;
+    char *password =NULL;
+    char *apnprotocol = NULL;
+    char *apnRoamProtocol = NULL;
+    switch (op_mode)
+    {
+        case AT_SET_MODE:
+        {
+            //paser parameter
+            //send to target handle
+            //ex: at+lapnact=int
+            RLOGD("input cmd[%s]", cmd);
+            if (SYS_FAIL == atci_at_to_equal(&cmd))
+            {
+              //input error
+                ATCIResponseNoToken(100,NULL,RIL_REQUEST_SETUP_DATA_CALL);
+                return SYS_FAIL;
+            }
+            RLOGD("[%d][%s] data is[%s]",LINE,FUNC,cmd);
+
+            if (SYS_FAIL == atci_at_get_nexthexint(&cmd, &state))
+            {
+                ATCIResponseNoToken(100,NULL,RIL_REQUEST_SETUP_DATA_CALL);
+                return SYS_FAIL;
+            }
+            RLOGD("state value is %d", state);
+            if(state == 1)
+            {
+                if (SYS_FAIL == atci_at_get_next_key(&cmd, &apn))
+                {
+                    ATCIResponseNoToken(100,NULL,RIL_REQUEST_SETUP_DATA_CALL);
+                    return SYS_FAIL;
+                }
+                RLOGD("apn value is %s", apn);
+                if (SYS_FAIL == atci_at_get_next_key(&cmd, &apnTpye))
+                {
+                    ATCIResponseNoToken(100,NULL,RIL_REQUEST_SETUP_DATA_CALL);
+                    return SYS_FAIL;
+                }
+                RLOGD("apnTpye value is %s", apnTpye);
+                if (SYS_FAIL == atci_at_get_next_key(&cmd, &user))
+                {
+                    ATCIResponseNoToken(100,NULL,RIL_REQUEST_SETUP_DATA_CALL);
+                    return SYS_FAIL;
+                }
+                RLOGD("user value is %s", user);
+                if (SYS_FAIL == atci_at_get_next_key(&cmd, &password))
+                {
+                    ATCIResponseNoToken(100,NULL,RIL_REQUEST_SETUP_DATA_CALL);
+                    return SYS_FAIL;
+                }
+                RLOGD("pwd value is %s", password);
+                if (SYS_FAIL == atci_at_get_nexthexint(&cmd, &authType))
+                {
+                    ATCIResponseNoToken(100,NULL,RIL_REQUEST_SETUP_DATA_CALL);
+                    return SYS_FAIL;
+                }
+                RLOGD("authType value is %d", authType);
+                if (SYS_FAIL == atci_at_get_next_key(&cmd, &apnprotocol))
+                {
+                    ATCIResponseNoToken(100,NULL,RIL_REQUEST_SETUP_DATA_CALL);
+                    return SYS_FAIL;
+                }
+                RLOGD("apnprotocol value is %s", apnprotocol);
+                if (SYS_FAIL == atci_at_get_next_key(&cmd, &apnRoamProtocol))
+                {
+                    ATCIResponseNoToken(100,NULL,RIL_REQUEST_SETUP_DATA_CALL);
+                    return SYS_FAIL;
+                }
+                RLOGD("apnRoamProtocol value is %s", apnRoamProtocol);
+                argv[1] = apn;
+                argv[2] = apnTpye;
+                argv[3] = user;
+                argv[4] = password;
+                sprintf(authTypebuf,"%d",authType);
+                argv[5] = authTypebuf;
+                argv[6] = apnprotocol;
+                argv[7] = apnRoamProtocol;
+                argc = 8;
+            }
+            else if(state == 0)
+            {
+                if (SYS_FAIL == atci_at_get_next_key(&cmd, &apnTpye))
+                {
+                    ATCIResponseNoToken(100,NULL,RIL_REQUEST_SETUP_DATA_CALL);
+                    return SYS_FAIL;
+                }
+                RLOGD("apnTpye value is %s", apnTpye);
+                argv[1] = apnTpye;
+                argc = 2;
+            }
+            //wrire data to target
+            atci_data_req_t req;
+            if(state==1)
+            {
+                if(check_sim_state())
+                {
+                    return SYS_FAIL;
+                }
+                req.request_id = RIL_REQUEST_SETUP_DATA_CALL;
+            }
+            else if(state == 0)
+            {
+                req.request_id = RIL_REQUEST_DEACTIVATE_DATA_CALL;
+            }
+            else
+            {
+                ATCIResponseNoToken(100,NULL,RIL_REQUEST_SETUP_DATA_CALL);
+                return SYS_FAIL;
+            }
+            
+
+            char reqStr[RIL_REQUEST_STRING_LENGTH] = {0};
+            memcpy(reqStr, request2RILStr(req.request_id),strlen(request2RILStr(req.request_id)) + 1);
+            RLOGD("request is %s", reqStr);
+            argv[0] = reqStr;
+            sendAtciRequest(req.request_id, reqStr, argc, argv);
+            ATCIResponseNoToken(0,NULL,req.request_id);
+            break;
+        }
+        case AT_TEST_MODE:
+        {
+            memset(buf,0,sizeof(buf));
+            sprintf(buf,"%s","+ELAPNACT: (0,1),"","","","",(0-3),(\"null\",\"IPV4\",\"IPV6\",\"IPV4V6\"),(\"null\",\"IPV4\",\"IPV6\",\"IPV4V6\")");
+            ATCIResponseNoToken(0,buf,RIL_REQUEST_SETUP_DATA_CALL);
+            break;
+        }
+        case AT_READ_MODE:
+        {
+            for(int i = 0;i < LYNQ_APN_CHANNEL_MAX; i ++)
+            {
+                if(!apn_table[i].used)
+                {
+                    continue;
+                }
+                memset(buf,0,sizeof(buf));
+                sprintf(buf,"+ELAPNACT: %s,%s,%d,%s,%s\n", apn_table[i].apn, apn_table[i].apntype ,apn_table[i].pdpstate, apn_table[i].ifaceName, apn_table[i].address);
+                if(atci_send_data(buf)!=0)
+                {
+                    RLOGD("send data fail");
+                    return SYS_FAIL;
+                }
+            }
+            if(apn_count == 0)
+            {
+                memset(buf,0,sizeof(buf));
+                ATCIResponseNoToken(0,buf,RIL_REQUEST_SETUP_DATA_CALL);
+                return SYS_SUCC;
+            }
+            atci_send_result(0);
+            break;
+        }
+        default:
+        {
+            RLOGD("set mute error");
+            break;
+        }
+    }
+    return SYS_SUCC;
+}
+
+static int insert_apn_char(char *agc, char *id,char *mcc, char *mnc, char *apn, char *apntype, char *user, char *password, char *normalprotocol, char *roamingprotocol, char *carrier)
+{
+    char strtmp[10][64];
+    if (!strcmp(id,"null"))
+    {
+        sprintf(strtmp[0], "id=;");
+    }
+    else
+    {
+        sprintf(strtmp[0], "id=%s;", id);
+    }
+    if (!strcmp(mcc,"null"))
+    {
+        char mcc[8] = {0};
+        if(strlen(mccmnc))
+        {
+            strncpy(mcc, mccmnc, 3);
+            sprintf(strtmp[1], "mcc=%s;", mcc);
+        }
+        else
+        {
+            sprintf(strtmp[2], "mcc=;");
+        }
+    }
+    else
+    {
+        sprintf(strtmp[1], "mcc=%s;", mcc);
+    }
+    if (!strcmp(mnc,"null"))
+    {
+        if(strlen(mccmnc))
+        {
+            sprintf(strtmp[2], "mnc=%s;", mccmnc+3);
+        }
+        else
+        {
+            sprintf(strtmp[2], "mnc=;");
+        }
+    }
+    else
+    {
+        sprintf(strtmp[2], "mnc=%s;", mnc);
+    }
+    if (!strcmp(apn,"null"))
+    {
+        sprintf(strtmp[3], "apn=;");
+    }
+    else
+    {
+        sprintf(strtmp[3], "apn=%s;", apn);
+    }
+    if (!strcmp(apntype,"null"))
+    {
+        sprintf(strtmp[4], "apntype=;");
+    }
+    else
+    {
+        sprintf(strtmp[4], "type=%s;", apntype);
+    }
+    if (!strcmp(user,"null"))
+    {
+        sprintf(strtmp[5], "user=;");
+    }
+    else
+    {
+        sprintf(strtmp[5], "user=%s;", user);
+    }
+    if (!strcmp(password,"null"))
+    {
+        sprintf(strtmp[6], "password=;");
+    }
+    else
+    {
+        sprintf(strtmp[6], "password=%s;", password);
+    }
+    if (!strcmp(normalprotocol,"null"))
+    {
+        sprintf(strtmp[7], "protocol=;");
+    }
+    else
+    {
+        sprintf(strtmp[7], "normalprotocol=%s;", normalprotocol);
+    }
+    if (!strcmp(roamingprotocol,"null"))
+    {
+        sprintf(strtmp[8], "roamingprotocol=;");
+    }
+    else
+    {
+        sprintf(strtmp[8], "roamingprotocol=%s;", roamingprotocol);
+    }
+    if (!strcmp(carrier,"null"))
+    {
+        sprintf(strtmp[9], "carrier=;");
+    }
+    else
+    {
+        sprintf(strtmp[9], "carrier=%s;", carrier);
+    }
+    sprintf(agc, "%s%s%s%s%s%s%s%s%s%s",strtmp[0], strtmp[1], strtmp[2], strtmp[3], strtmp[4], strtmp[5], strtmp[6], strtmp[7], strtmp[8], strtmp[9]);
+    return 0;
+}
+
+int atci_data_modify_apn_hdlr(char *cmd, int op_mode, int target, char *response)
+{
+    char *id  = NULL;
+    char *mcc = NULL;
+    char *mnc = NULL;
+    char *apn = NULL;
+    char *apntype = NULL;
+    char *user = NULL;
+    char *password = NULL;
+    char *normalprotocol = NULL;
+    char *roamingprotocol = NULL;
+    char *carrier = NULL;
+    int state = -1;
+    char apn_info[512];
+    char* argv[3] = { 0 };
+    int argc = 0;
+    g_flag_apn = 1;
+    switch (op_mode)
+    {
+        case AT_SET_MODE:
+        {
+            RLOGD("input cmd[%s]", cmd);
+            if (SYS_FAIL == atci_at_to_equal(&cmd))
+            {
+                //input error
+                ATCIResponseNoToken(100,NULL,RIL_REQUEST_MODIFY_APN);
+                return SYS_FAIL;
+            }
+            RLOGD("[%d][%s] data is[%s]",LINE,FUNC,cmd);
+            if (SYS_FAIL == atci_at_get_nexthexint(&cmd, &state))
+            {
+                ATCIResponseNoToken(100,NULL,RIL_REQUEST_MODIFY_APN);
+                return SYS_FAIL;
+            }
+            RLOGD("state value is %d", state);
+            if (SYS_FAIL == atci_at_get_next_key(&cmd, &id))
+            {
+                ATCIResponseNoToken(100,NULL,RIL_REQUEST_MODIFY_APN);
+                return SYS_FAIL;
+            }
+            if(state == 0)
+            {
+                if (SYS_FAIL == atci_at_get_next_key(&cmd, &mcc))
+                {
+                    ATCIResponseNoToken(100,NULL,RIL_REQUEST_MODIFY_APN);
+                    return SYS_FAIL;
+                }
+                if (SYS_FAIL == atci_at_get_next_key(&cmd, &mnc))
+                {
+                    ATCIResponseNoToken(100,NULL,RIL_REQUEST_MODIFY_APN);
+                    return SYS_FAIL;
+                }
+                if (SYS_FAIL == atci_at_get_next_key(&cmd, &apn))
+                {
+                    ATCIResponseNoToken(100,NULL,RIL_REQUEST_MODIFY_APN);
+                    return SYS_FAIL;
+                }
+                if (SYS_FAIL == atci_at_get_next_key(&cmd, &apntype))
+                {
+                    ATCIResponseNoToken(100,NULL,RIL_REQUEST_MODIFY_APN);
+                    return SYS_FAIL;
+                }
+                if (SYS_FAIL == atci_at_get_next_key(&cmd, &user))
+                {
+                    ATCIResponseNoToken(100,NULL,RIL_REQUEST_MODIFY_APN);
+                    return SYS_FAIL;
+                }
+                if (SYS_FAIL == atci_at_get_next_key(&cmd, &password))
+                {
+                    ATCIResponseNoToken(100,NULL,RIL_REQUEST_MODIFY_APN);
+                    return SYS_FAIL;
+                }
+                if (SYS_FAIL == atci_at_get_next_key(&cmd, &normalprotocol))
+                {
+                    ATCIResponseNoToken(100,NULL,RIL_REQUEST_MODIFY_APN);
+                    return SYS_FAIL;
+                }
+                if (SYS_FAIL == atci_at_get_next_key(&cmd, &roamingprotocol))
+                {
+                    ATCIResponseNoToken(100,NULL,RIL_REQUEST_MODIFY_APN);
+                    return SYS_FAIL;
+                }
+                if (SYS_FAIL == atci_at_get_next_key(&cmd, &carrier))
+                {
+                    ATCIResponseNoToken(100,NULL,RIL_REQUEST_MODIFY_APN);
+                    return SYS_FAIL;
+                }
+                /*get mccmnc*/
+                lynq_req_mccmnc(666);
+                lynq_wait_result_comeback(100);//wait 100ms
+                /*get mccmnc*/
+                insert_apn_char(apn_info, id, mcc, mnc, apn, apntype, user, password, normalprotocol, roamingprotocol, carrier);
+                argv[1] = "0";
+                argv[2] = apn_info;
+                RLOGD("apn_info %s\n", apn_info);
+                atci_data_req_t req;
+                req.request_id = RIL_REQUEST_MODIFY_APN;
+                char reqStr[RIL_REQUEST_STRING_LENGTH] = {0};
+                memcpy(reqStr, request2RILStr(req.request_id),strlen(request2RILStr(req.request_id)) + 1);
+                RLOGD("request is %s", reqStr);
+                argv[0] = reqStr;
+                argc = 3;
+                sendAtciRequest(req.request_id, reqStr, argc, argv);
+            }
+            else if (state == 1)
+            {
+                sprintf(apn_info, "id=%s", id);
+                argv[1] = "1";
+                argv[2] = apn_info;
+                atci_data_req_t req;
+                req.request_id = RIL_REQUEST_MODIFY_APN;
+                char reqStr[RIL_REQUEST_STRING_LENGTH] = {0};
+                memcpy(reqStr, request2RILStr(req.request_id),strlen(request2RILStr(req.request_id)) + 1);
+                RLOGD("request is %s", reqStr);
+                argv[0] = reqStr;
+                argc = 3;
+                sendAtciRequest(req.request_id, reqStr, argc, argv);
+            }
+            else if (state == 2)
+            {
+                sprintf(apn_info, "id=%s", id);
+                argv[1] = "2";
+                argv[2] = apn_info;
+                atci_data_req_t req;
+                req.request_id = RIL_REQUEST_MODIFY_APN;
+                char reqStr[RIL_REQUEST_STRING_LENGTH] = {0};
+                memcpy(reqStr, request2RILStr(req.request_id),strlen(request2RILStr(req.request_id)) + 1);
+                RLOGD("request is %s", reqStr);
+                argv[0] = reqStr;
+                argc = 3;
+                sendAtciRequest(req.request_id, reqStr, argc, argv);
+            }
+            else if (state == 3)
+            {
+                if (SYS_FAIL == atci_at_get_next_key(&cmd, &mcc))
+                {
+                    ATCIResponseNoToken(100,NULL,RIL_REQUEST_MODIFY_APN);
+                    return SYS_FAIL;
+                }
+                if (SYS_FAIL == atci_at_get_next_key(&cmd, &mnc))
+                {
+                    ATCIResponseNoToken(100,NULL,RIL_REQUEST_MODIFY_APN);
+                    return SYS_FAIL;
+                }
+                if (SYS_FAIL == atci_at_get_next_key(&cmd, &apn))
+                {
+                    ATCIResponseNoToken(100,NULL,RIL_REQUEST_MODIFY_APN);
+                    return SYS_FAIL;
+                }
+                if (SYS_FAIL == atci_at_get_next_key(&cmd, &apntype))
+                {
+                    ATCIResponseNoToken(100,NULL,RIL_REQUEST_MODIFY_APN);
+                    return SYS_FAIL;
+                }
+                if (SYS_FAIL == atci_at_get_next_key(&cmd, &user))
+                {
+                    ATCIResponseNoToken(100,NULL,RIL_REQUEST_MODIFY_APN);
+                    return SYS_FAIL;
+                }
+                if (SYS_FAIL == atci_at_get_next_key(&cmd, &password))
+                {
+                    ATCIResponseNoToken(100,NULL,RIL_REQUEST_MODIFY_APN);
+                    return SYS_FAIL;
+                }
+                if (SYS_FAIL == atci_at_get_next_key(&cmd, &normalprotocol))
+                {
+                    ATCIResponseNoToken(100,NULL,RIL_REQUEST_MODIFY_APN);
+                    return SYS_FAIL;
+                }
+                if (SYS_FAIL == atci_at_get_next_key(&cmd, &roamingprotocol))
+                {
+                    ATCIResponseNoToken(100,NULL,RIL_REQUEST_MODIFY_APN);
+                    return SYS_FAIL;
+                }
+                if (SYS_FAIL == atci_at_get_next_key(&cmd, &carrier))
+                {
+                    ATCIResponseNoToken(100,NULL,RIL_REQUEST_MODIFY_APN);
+                    return SYS_FAIL;
+                }
+                insert_apn_char(apn_info, id, mcc, mnc, apn, apntype, user, password, normalprotocol, roamingprotocol, carrier);
+                argv[1] = "3";
+                argv[2] = apn_info;
+                atci_data_req_t req;
+                req.request_id = RIL_REQUEST_MODIFY_APN;
+                char reqStr[RIL_REQUEST_STRING_LENGTH] = {0};
+                memcpy(reqStr, request2RILStr(req.request_id),strlen(request2RILStr(req.request_id)) + 1);
+                RLOGD("request is %s", reqStr);
+                argv[0] = reqStr;
+                argc = 3;
+                sendAtciRequest(req.request_id, reqStr, argc, argv);
+            }
+            else
+            {
+                RLOGD("function %s line %d unknow command", __FUNCTION__, __LINE__);
+            }
+            break;
+        }
+        default:
+        {
+            break;
+        }
+       
+    }
+    return SYS_SUCC;
+}
+
+
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/atci_lynq_data_cmd.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/atci_lynq_data_cmd.h
new file mode 100755
index 0000000..09a030f
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/atci_lynq_data_cmd.h
@@ -0,0 +1,22 @@
+/**********************************************************************************************
+* @file atci_lynq_data_cmd.h
+* @brief.define lynq data at commands function
+* @details None
+* @author   Hong Liu。
+* @date     2022-12-07
+* @version  V1.0
+* @copyright   Copyright (c) MobileTek 
+***********************************************************************************************/
+
+#ifndef __ATCI_LYNQ_DATA_CMD_H__
+#define __ATCI_LYNQ_DATA__CMD_H__
+
+extern int g_flag_apn;
+
+int atci_lynq_data_init(void *arg);
+int atci_data_enable_pdp_hdlr(char *cmd, int op_type, int target, char *response);
+int atci_data_enable_pdp_with_apn_hdlr(char *cmd, int op_mode, int target, char *response);
+int atci_data_modify_apn_hdlr(char *cmd, int op_mode, int target, char *response);
+int atci_switch_card_halr(char *cmd, int op_mode, int target, char *response);
+#endif
+
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/atci_lynq_generic_cmd.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/atci_lynq_generic_cmd.cpp
new file mode 100755
index 0000000..f94947c
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/atci_lynq_generic_cmd.cpp
@@ -0,0 +1,26 @@
+#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_lynq_generic_cmd.h"
+#include "atci_common.h"
+
+#undef LOG_TAG
+#define LOG_TAG "DEMO_ATCI_GENERIC"
+/*
+atci_cmd_type_t atci_generic_cmd_table[] = {
+//cmd_name      target_type        handler
+    { "AT+LCSUS", TARGET_TELEPHONY, atci_data_enable_pdp_hdlr },              //AT command to dsds
+    { "AT+SCREEN", TARGET_TELEPHONY, atci_data_enable_pdp_with_apn_hdlr },    //AT command to off/on modem screen
+    { "ATD", TARGET_TELEPHONY, atci_data_modify_apn_hdlr },
+    { NULL, TARGET_UNKNOWN, NULL }
+};
+int atci_lynq_generic_init(void *arg) {
+  int ret;
+  ret = atci_cmd_register(atci_generic_cmd_table);
+  return ret;
+}
+*/
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/atci_lynq_generic_cmd.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/atci_lynq_generic_cmd.h
new file mode 100755
index 0000000..33882cd
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/atci_lynq_generic_cmd.h
@@ -0,0 +1 @@
+int atci_lynq_generic_init(void *arg);
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/atci_ss_cmd.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/atci_ss_cmd.cpp
new file mode 100755
index 0000000..ffcafea
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/atci_ss_cmd.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/atci_ss_cmd.h
new file mode 100755
index 0000000..a59c92d
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/atci_sys_cmd.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/atci_sys_cmd.cpp
new file mode 100755
index 0000000..ce58981
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/atci_sys_cmd.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/atci_sys_cmd.h
new file mode 100755
index 0000000..3c33095
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/atci_util.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/atci_util.cpp
new file mode 100755
index 0000000..0cc6d9a
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/atci_util.cpp
@@ -0,0 +1,90 @@
+#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";
+  case RIL_REQUEST_DEACTIVATE_DATA_CALL:
+    return "RIL_REQUEST_DEACTIVATE_DATA_CALL";
+  case RIL_REQUEST_SETUP_DATA_CALL:
+    return "RIL_REQUEST_SETUP_DATA_CALL";
+  case RIL_REQUEST_MODIFY_APN:
+    return "RIL_REQUEST_MODIFY_APN";
+  case RIL_REQUEST_OPERATOR:
+    return "RIL_REQUEST_OPERATOR";
+  default:
+    return "unknown define";
+  }
+}
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/atci_util.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/atci/atci_util.h
new file mode 100755
index 0000000..991ab8d
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/cc.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/cc.cpp
new file mode 100755
index 0000000..8afb2d3
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/cc.cpp
@@ -0,0 +1,1648 @@
+//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 "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"
+/*Warren add for t800 ril servie 2021/12/23 start*/
+#include "lynq_interface.h"
+#include <binder/Parcel.h>
+#ifdef LED_SUPPORT
+#include "led.h"
+#endif
+using android::Parcel;
+/*Warren add for t800 ril servie 2021/12/23 end*/
+
+static int dtmf_volume = 0;
+void *dtmf_handle = NULL;
+
+extern "C" {
+    #include <dtmf.h>
+    #include "mixer_ctrl.h"
+}
+#undef LOG_TAG
+#define LOG_TAG "LYNQ_RIL_CC"
+
+static speech_status speechStatus = SPEECH_OFF;
+static 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 (7)
+#define MIN_VOLUME (1)
+#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()
+{
+    RLOGD("set_card_name: %s", g_card_name);
+    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);
+        ret = -1;
+    }
+    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 %ld", 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)
+{
+     android::Parcel p;
+    int recordEnable = 0;
+    char* filepath = NULL;
+    if(inCallstatus == CALL_OFF || speechStatus == SPEECH_OFF) {
+        RLOGW("[warning],not in calling status. Can't do record!");
+        goto FAIL_RETURN;
+    }
+
+    if(argc < 3) {   
+        RLOGW("[error],inCallRecord parameter error!");
+        goto FAIL_RETURN;
+    }
+
+    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!");
+            goto FAIL_RETURN;
+      }
+    } else { //disable record
+        if (inCallRecordMode == 1) {
+            inCallRecordMode = 0;
+            if(!(-1 != GSM_Stop() && -1 != GSM_Close()))
+            {
+                RLOGW("[error],inCallRecord fail!");
+                goto FAIL_RETURN;
+            }            
+        }
+    }
+    if(pRI != NULL) {
+       android::lynqAssemblyParcelheader(p,socket_id,pRI->uToken,LYNQ_REQUEST_RECORD,0,0);  
+       android::LYNQ_RIL_respSocket_sp(p,pRI);
+       free(pRI);
+    }
+    return 0;
+FAIL_RETURN:
+    if(pRI != NULL) {    
+        android::lynqAssemblyParcelheader(p,socket_id,pRI->uToken,LYNQ_REQUEST_RECORD,0,2);
+        android::LYNQ_RIL_respSocket_sp(p,pRI);
+        free(pRI);
+    }
+    return -1;       
+}
+
+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)
+{
+    android::Parcel p;
+    int setValue = 0;
+    RLOGD("setSpeechVolume start!");
+
+    if(argc < 2) {
+        android::lynqAssemblyParcelheader(p,socket_id,pRI->uToken,LYNQ_REQUEST_SET_SPEECH_VOLUME,0,2);
+        android::LYNQ_RIL_respSocket_sp(p,pRI);
+        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!");
+            android::lynqAssemblyParcelheader(p,socket_id,pRI->uToken,LYNQ_REQUEST_SET_SPEECH_VOLUME,0,2);
+            android::LYNQ_RIL_respSocket_sp(p,pRI);
+            free(pRI);
+            return -1;
+        }
+    } else {
+        if(setValue < BT_MIN_VOLUME || setValue > BT_MAX_VOLUME) {
+            RLOGW("Warning: set bt volume value is over-range!");
+            android::lynqAssemblyParcelheader(p,socket_id,pRI->uToken,LYNQ_REQUEST_SET_SPEECH_VOLUME,0,2);
+            android::LYNQ_RIL_respSocket_sp(p,pRI);
+            free(pRI);
+            return -1;
+        }
+    }
+    //paramter is from 1 to 7
+    mixer_set_volume(setValue);
+    android::lynqAssemblyParcelheader(p,socket_id,pRI->uToken,LYNQ_REQUEST_SET_SPEECH_VOLUME,0,0);
+    printf(">>>>set speech Volume<<<< success value is %d!\n",setValue);
+    /*Warren add for t800 ril service 2021/12/23 end*/
+    android::LYNQ_RIL_respSocket_sp(p,pRI);
+    free(pRI);
+    return 0;
+}
+int getSpeechVolume(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    printf("WARREN TEST001!!!\n");
+    int volumn = mixer_get_volume();
+    //TBC -200 fail status
+    if(volumn <0) {
+        printf("get speech volumn fail, please check whether does call exsit.\n");
+        /*Warren add for t800 ril service 2021/12/23 start*/
+        android::lynqAssemblyParcelheader(p,socket_id,pRI->uToken,LYNQ_REQUEST_GET_SPEECH_VOLUME,0,2);
+        /*Warren add for t800 ril service 2021/12/23 end*/
+    } else {
+        /*Warren add for t800 ril service 2021/12/23 start*/
+        android::lynqAssemblyParcelheader(p,socket_id,pRI->uToken,LYNQ_REQUEST_GET_SPEECH_VOLUME,0,0);
+        /*Warren add for t800 ril service 2021/12/23 end*/
+    }
+    printf("current Speech Volume is%d",volumn);
+    p.writeInt32(volumn);
+    android::LYNQ_RIL_respSocket(p,(void *)pRI);
+    if(pRI) {
+        free(pRI);
+    }
+    return 0;
+}
+int setDtmfVolume(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    int setValue = 0;
+    RLOGD("setDtmfVolume start!");
+    printf("setDtmfVolume start!\n");
+    if(argc < 2) {
+        RLOGW("Warning: no set volume value!");
+        printf("Warning: no set volume value!\n");
+        android::lynqAssemblyParcelheader(p,socket_id,pRI->uToken,LYNQ_REQUEST_SET_DTMF_VOLUME,0,2);
+        android::LYNQ_RIL_respSocket_sp(p,pRI);
+        free(pRI);
+        return -1;
+    }
+
+    setValue = atoi(argv[1]);
+    RLOGD("set dtmf Volume value is %d!",setValue);
+    printf("set dtmf Volume value is %d!\n",setValue);
+    if(setValue < DTMF_MIN_VOLUME || setValue > DTMF_MAX_VOLUME) {
+        RLOGW("Warning: set volume value is over-range!");
+        printf("set dtmf Volume value is %d!\n",setValue);
+        /*Warren add for t800 ril service 2021/12/23 start*/
+        android::lynqAssemblyParcelheader(p,socket_id,pRI->uToken,LYNQ_REQUEST_SET_DTMF_VOLUME,0,2);
+        android::LYNQ_RIL_respSocket_sp(p,pRI);
+        /*Warren add for t800 ril service 2021/12/23 end*/
+        free(pRI);
+        return -1;
+    }
+    //paramter is from 0 to 36
+    dtmf_volume = setValue;
+    printf(">>>>set dtmf Volume<<<< success value is %d!\n",setValue);
+    /*Warren add for t800 ril service 2021/12/23 start*/
+    android::lynqAssemblyParcelheader(p,socket_id,pRI->uToken,LYNQ_REQUEST_SET_DTMF_VOLUME,0,0);
+    printf(">>>>set dtmf Volume<<<< success value is %d!\n",setValue);
+    /*Warren add for t800 ril service 2021/12/23 end*/
+    android::LYNQ_RIL_respSocket_sp(p,pRI);
+    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 %ld", g_DL_mute_name, is_mute);
+    } else {
+        is_mute = get_mixer_ctrl_value_int(g_UL_mute_name);
+        RLOGD("The ctrl \"%s\" is set to %ld", g_UL_mute_name, is_mute);
+    }
+
+    return is_mute;
+}
+
+static 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: %ld", cc_mute);
+    return cc_mute;
+}
+
+void resetMute() {
+    if (getCallMute() > 0) {
+        setCallMute(false);
+    }
+}
+
+void callRing(RIL_SOCKET_ID soc_id)
+{
+    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;
+}
+#ifdef GSW_RIL_CFG
+
+/*hqing add for Geely demand on 11/07/2022, after cs call, codec should sleep*/
+void set_codec(int open)
+{
+    RLOGD("set_codec %d",open);
+    
+    if(open==0)
+    {
+        system("echo out 201 0 >/sys/devices/platform/10005000.pinctrl/mt_gpio");    
+        system("echo out 181 0 >/sys/devices/platform/10005000.pinctrl/mt_gpio");
+    }
+    else
+    {
+        system("echo out 181 1 >/sys/devices/platform/10005000.pinctrl/mt_gpio");
+        usleep(10);//just open need usleep 10us
+        system("echo out 201 1 >/sys/devices/platform/10005000.pinctrl/mt_gpio");        
+        system("echo 0x00 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x01 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x02 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x03 0x80 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x04 0x04 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x05 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x06 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x07 0xa0 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x08 0x20 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x09 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x0a 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x0b 0x32 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x0c 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x0d 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x0f 0x10 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x10 0x20 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x11 0xf8 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x12 0xff > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x13 0x04 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x14 0x78 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x15 0x78 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x16 0x04 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x17 0x78 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x18 0x78 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x19 0x80 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x1a 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x1b 0xfe > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x1c 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x1d 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x1e 0xfe > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x1f 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x20 0x18 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x21 0x18 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x22 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x23 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x24 0xc0 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x25 0xc0 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x26 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x27 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x28 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x29 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x2a 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x2b 0x02 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x2c 0x02 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x2d 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x2e 0x02 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x2f 0x85 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x30 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x31 0x80 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x32 0x85 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x33 0x9f > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x34 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x35 0x80 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x36 0x82 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x37 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x38 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x39 0x82 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x3a 0x9f > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x3b 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x3c 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x3d 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x3e 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x3f 0x80 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x40 0xaf > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x41 0x0d > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x42 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x43 0x80 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x44 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x45 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x46 0x02 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x47 0xaf > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x48 0x0d > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x49 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x4a 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x4b 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x4c 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x4d 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x4e 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x4f 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x50 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x51 0x02 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x52 0xbf > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x53 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x54 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x55 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x56 0x9b > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x57 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x58 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x59 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x5a 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x5b 0x02 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x5c 0xbf > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x5d 0x08 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x5e 0xde > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x5f 0x0c > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x60 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x61 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x62 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x63 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x64 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x65 0x01 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x66 0xa2 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x67 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x68 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x69 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x6a 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x6b 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x6c 0x40 > /sys/kernel/debug/regmap/0-0018/registers");
+        system("echo 0x6d 0x00 > /sys/kernel/debug/regmap/0-0018/registers");
+    }
+}
+#endif
+
+//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;
+#ifdef GSW_RIL_CFG
+    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");
+        set_codec(1); //hqing add for Geely demand on 11/07/2022, init cs call, open codec
+#endif
+
+#ifdef MOBILETEK_RIL_CFG
+    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");
+#endif
+        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);
+        dtmf_handle = NULL;
+        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();
+#ifdef GSW_RIL_CFG
+        set_codec(0); //hqing add for Geely demand on 11/07/2022, after cs call, close codec for power Manager
+#endif
+        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)
+{
+    android::Parcel p;
+    printf("WARREN TEST002!!!\n");
+    if(argc<2)
+    {
+        if(pRI)
+        {
+            free(pRI);
+        }
+        return -1;
+    }
+    bool mute = (atoi(argv[1]) > 0) ? true: false;
+    RLOGD("set mute %s", ((atoi(argv[1]) > 0) ? "on": "off"));
+    int ret = setCallMute(mute);
+    if(ret) {
+        /*Warren add for t800 ril service 2021/12/23 start*/
+        android::lynqAssemblyParcelheader(p,socket_id,pRI->uToken,RIL_REQUEST_SET_MUTE,0,2);
+        /*Warren add for t800 ril service 2021/12/23 start*/
+        printf("set mute fail, please try agian\n");
+    } else {
+        /*Warren add for t800 ril service 2021/12/23 start*/
+        android::lynqAssemblyParcelheader(p,socket_id,pRI->uToken,RIL_REQUEST_SET_MUTE,0,0);
+        /*Warren add for t800 ril service 2021/12/23 start*/
+    }
+    /*Warren add for t800 ril service 2021/12/23 start*/
+    printf("set mute %s\n", ((atoi(argv[1]) > 0) ? "on": "off"));
+    android::LYNQ_RIL_respSocket(p,(void *)pRI);
+    /*Warren add for t800 ril service 2021/12/23 start*/
+    if(pRI) {
+        free(pRI);
+    }
+    return 0;
+}
+
+//RIL_REQUEST_GET_MUTE
+int getMute(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+
+    android::Parcel p;
+    printf("WARREN TEST001!!!\n");
+    int mute = getCallMute();
+    //TBC -200 fail status
+    if(mute < 0) {
+        printf("get mute state fail, please check whether does call exsit.\n");
+        /*Warren add for t800 ril service 2021/12/23 start*/
+        android::lynqAssemblyParcelheader(p,socket_id,pRI->uToken,RIL_REQUEST_GET_MUTE,0,2);
+        /*Warren add for t800 ril service 2021/12/23 end*/
+    } else {
+        /*Warren add for t800 ril service 2021/12/23 start*/
+        android::lynqAssemblyParcelheader(p,socket_id,pRI->uToken,RIL_REQUEST_GET_MUTE,0,0);
+        /*Warren add for t800 ril service 2021/12/23 end*/
+    }
+    printf("current mute state is%s",((mute == 1) ? "on\n" : "off\n"));
+    p.writeInt32(mute);
+    if(pRI) {
+        android::LYNQ_RIL_respSocket(p,(void *)pRI);
+        free(pRI);
+    }
+    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 < 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 < 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);
+    dtmf_handle = NULL;
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/cc.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/cc.h
new file mode 100755
index 0000000..a1176ae
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/cc.h
@@ -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.
+ */
+#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 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 getSpeechVolume(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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/commands.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/commands.h
new file mode 100755
index 0000000..c1686ed
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/commands.h
@@ -0,0 +1,261 @@
+/* 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},
+    {"RIL_REQUEST_QUERY_SIM_RETRY_COUNT", querySimRetryCount, "", RIL_REQUEST_QUERY_SIM_RETRY_COUNT},
+//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},
+    {"RIL_REQUEST_MODIFY_APN",modifyApnRecord, "modify apn db", RIL_REQUEST_MODIFY_APN},
+    {"RIL_REQUEST_RESET_APN",resetApnRecord, "reset apn db", RIL_REQUEST_RESET_APN},
+//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",LYNQ_REQUEST_RECORD},
+
+    #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_GET_SPEECH_VOLUME",getSpeechVolume,"get Speech Volume",LYNQ_REQUEST_GET_SPEECH_VOLUME},
+    {"RIL_REQUEST_SET_SPEECH_VOLUME",setSpeechVolume,"set Speech Volume",LYNQ_REQUEST_SET_SPEECH_VOLUME},
+    /*Warren change for t800 ril service 2021/12/24 start*/
+    {"RIL_REQUEST_SET_DTMF_VOLUME",setDtmfVolume,"set dtmf Volume",LYNQ_REQUEST_SET_DTMF_VOLUME},
+    /*Warren change for t800 ril service 2021/12/24 start*/
+//    {"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},
+    /*Warren change for t800 ril service 2022/1/18 start*/
+    {"LYNQ_REQUEST_READ_SMS_FROM_MEMORY",readSmsToMemory, "write sms to memory",LYNQ_REQUEST_READ_SMS_FROM_MEMORY},
+    {"LYNQ_REQUEST_DELETE_SMS_FROM_MEMORY",deleteSmsToMemory, "write sms to memory",LYNQ_REQUEST_DELETE_SMS_FROM_MEMORY},
+    {"LYNQ_REQUEST_LIST_SMS_FROM_MEMORY",listSmsToMemory, "write sms to memory",LYNQ_REQUEST_LIST_SMS_FROM_MEMORY},
+    {"LYNQ_REQUEST_CHANGE_SCREEN_STATE",getScreenState,"lynq get Screen State",LYNQ_REQUEST_CHANGE_SCREEN_STATE},/*jb.qi change for two sim suspend 2022/9/19 */
+    {"LYNQ_REQUEST_CHANGE_RADIO",setRadioPower,"setRadioPower",LYNQ_REQUEST_CHANGE_RADIO},/*lei add for both radio on/off */
+    /*Warren change for t800 ril service 2022/1/18 end*/
+
+    #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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/common.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/common.cpp
new file mode 100755
index 0000000..9132652
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/common.cpp
@@ -0,0 +1,1135 @@
+// SPDX-License-Identifier: MediaTekProprietary
+/*
+ * 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 "include/lynq_systime.h"
+#include <include/lynq_uci.h>
+#ifdef LED_SUPPORT
+#include "led.h"
+#endif
+#include "lynq_shm.h"
+static pthread_mutex_t s_DataMutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t s_DataCond = PTHREAD_COND_INITIALIZER;
+
+#undef LOG_TAG
+#define LOG_TAG "DEMO_COMMON"
+
+#define UNKOWN_VALUE  (-1)
+
+/*Warren add for FAW 2021/11/1 start*/
+extern int ttyGS3_fd = -1;
+/*Warren add for FAW 2021/11/1 end*/
+
+
+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;
+
+pthread_mutex_t s_state_change_mutex = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t s_state_change_cond = PTHREAD_COND_INITIALIZER;
+
+/*Warren add for SZZT 2021/11/14 start*
+** record data registration
+*/
+extern int current_data_reg = -1;
+extern int modemStatus = 0;
+int g_lynq_sim_state = -1;
+
+/*Warren add for SZZT 2021/11/14 end*/
+
+
+/*hq add for key information output start 2022/03/01*/
+// extern int lynq_output_LINFO_enable =0;
+
+// typedef enum {
+//     RADIO_NW_2G = 0,
+//     RADIO_NW_3G = 1,
+//     RADIO_NW_4G = 2, 
+// #ifdef TELEMATIC_5G_SUPPORT
+//     RADIO_NW_5G = 3,    
+// #endif
+// } RIL_RadioNW;
+
+// const char * cardStateToString(int cardStatus)
+// {
+//     switch(cardStatus) {
+//         case RIL_CARDSTATE_ABSENT:
+//             return "absent";
+//         case RIL_CARDSTATE_PRESENT:
+//             return "present";        
+//         case RIL_CARDSTATE_ERROR:
+//             return "error";
+//         default:
+//             return "unknown";
+//     }
+// }
+// const char * serviceStateToString(int service_state)
+// {
+//     switch(service_state) {
+//         case STATE_IN_SERVICE:
+//             return "IN SERVICE";
+//         case STATE_OUT_OF_SERVICE:
+//             return "OUT OF SERVICE";
+//         case STATE_POWER_OFF:
+//             return "POWER_OFF";
+//         case STATE_EMERGENCY_ONLY:
+//             return "EMERGENCY_ONLY";
+//         case UNKOWN_VALUE:
+//             return "unDefined";
+//         default:
+//             return "unDefined";
+//     }
+// }
+// const char * RadioNwToString(int radio_nw)
+// {
+//     switch(radio_nw) {
+//         case RADIO_NW_2G:
+//             return "2G";
+//         case RADIO_NW_3G:
+//             return "3G";
+//         case RADIO_NW_4G:
+//             return "4G";
+// #ifdef TELEMATIC_5G_SUPPORT
+//         case RADIO_NW_5G:
+//             return "5G";
+// #endif
+//         case UNKOWN_VALUE:          
+//             return "unknown";        
+//         default:
+//             return "unknown";
+//     }
+// }
+// const char * preferredNetworkTypeToString(int preferred_network_type)
+// {
+//     switch(preferred_network_type) {
+//         case PREF_NET_TYPE_GSM_WCDMA      /*0*/     :  return " GSM/WCDMA (WCDMA case PREFerred)";
+//         case PREF_NET_TYPE_GSM_ONLY                 :  return " GSM only";
+//         case PREF_NET_TYPE_WCDMA                    :  return " WCDMA ";
+//         case PREF_NET_TYPE_GSM_WCDMA_AUTO           :  return " GSM/WCDMA (auto mode, according to PRL)";
+//         case PREF_NET_TYPE_CDMA_EVDO_AUTO           :  return " CDMA and EvDo (auto mode, according to PRL)";
+//         case PREF_NET_TYPE_CDMA_ONLY                :  return " CDMA only";
+//         case PREF_NET_TYPE_EVDO_ONLY                :  return " EvDo only";
+//         case PREF_NET_TYPE_GSM_WCDMA_CDMA_EVDO_AUTO :  return " GSM/WCDMA, CDMA, and EvDo (auto mode, according to PRL)";
+//         case PREF_NET_TYPE_LTE_CDMA_EVDO            :  return " LTE, CDMA and EvDo";
+//         case PREF_NET_TYPE_LTE_GSM_WCDMA            :  return " LTE, GSM/WCDMA";
+//         case PREF_NET_TYPE_LTE_CMDA_EVDO_GSM_WCDMA  :  return " LTE, CDMA, EvDo, GSM/WCDMA";
+//         case PREF_NET_TYPE_LTE_ONLY                 :  return " LTE only";
+//         case PREF_NET_TYPE_LTE_WCDMA     /*12*/     :  return " LTE/WCDMA";
+//         case PREF_NET_TYPE_LTE_GSM       /*30*/     :  return " LTE/GSM";
+//         case PREF_NET_TYPE_LTE_TDD_ONLY  /*31*/     :  return " LTE only";
+//         case 13:                                       return "TD-SCDMA only"; 
+//         case 14:                                       return "TD-SCDMA and WCDMA"; 
+//         case 15:                                       return "TD-SCDMA and LTE"; 
+//         case 16:                                       return "TD-SCDMA and GSM"; 
+//         case 17:                                       return "TD-SCDMA,GSM and LTE"; 
+//         case 18:                                       return "TD-SCDMA, GSM/WCDMA"; 
+//         case 19:                                       return "TD-SCDMA, WCDMA and LTE";
+//         case 20:                                       return "TD-SCDMA, GSM/WCDMA and LTE"; 
+//         case 21:                                       return "TD-SCDMA,EvDo,CDMA,GSM/WCDMA";
+//         case 22:                                       return "TD-SCDMA/LTE/GSM/WCDMA, CDMA, and EvDo";
+//       //case 30:                                       return "LTE/GSM";
+//       //case 31:                                       return "LTE TDD Only mode";
+//         case 32:                                       return "CDMA,GSM(2G Global)";
+//         case 33:                                       return "CDMA,EVDO,GSM";
+//         case 34:                                       return "LTE,CDMA,EVDO,GSM(4G Global, 4M)";        
+//         default:
+//             return "unDefined";
+//     }
+// }
+/*hq add for key information output end*/
+
+static int regCodeToRadioTechnology(int request, int code, int slot);
+
+void lynq_output_info(const char* format,...)
+{
+    if(ttyGS3_fd < 0)
+    {
+        return;
+    }
+    char buf[1024] = {0};
+    int n;
+    va_list args;
+    va_start(args, format);
+    vsnprintf(buf, sizeof(buf), format, args);
+    va_end(args);
+    n=write(ttyGS3_fd, buf, strlen(buf));
+    if(n < 0)
+    {
+        perror("lynq resp write:");
+    }
+    return;
+}
+
+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);           
+        }
+    }
+}
+
+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;
+}
+
+void lynq_send_result_already(void)
+{
+    RLOGD("send_imei_state_change");
+    pthread_mutex_lock(&s_state_change_mutex);
+    pthread_cond_signal(&s_state_change_cond);
+    pthread_mutex_unlock(&s_state_change_mutex);
+}
+
+int lynq_wait_result_comeback(int mtime)
+{
+    RLOGD("wait_call_state");
+    int sec = 0;
+    int ms = 0;
+    struct timeval now;
+    struct timespec timeout;
+    gettimeofday(&now,NULL);
+    sec = mtime/1000;
+    ms = mtime%1000;
+    timeout.tv_sec = now.tv_sec+sec;
+    unsigned long long ns;
+    ns = now.tv_usec*1000ull + ms*1000000ull;
+    timeout.tv_sec += ns/1000000000;
+    timeout.tv_nsec = ns % 1000000000;
+    pthread_mutex_lock(&s_state_change_mutex);
+    int ret = pthread_cond_timedwait(&s_state_change_cond,&s_state_change_mutex,&timeout);
+    pthread_mutex_unlock(&s_state_change_mutex);
+    RLOGD("wait_call_state end");
+    return ret;
+}
+
+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);
+
+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);
+    }
+#ifdef LED_SUPPORT
+    mbtk_netled_state_update(GPIO_NETLED_REFLASH_NORMAL);  
+#endif
+}
+
+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);
+    }
+#ifdef LED_SUPPORT
+    mbtk_netled_state_update(GPIO_NETLED_REFLASH_NORMAL);  
+#endif
+}
+
+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);
+        /*Warren change for SZZT 2021//11/14 start*/
+        int status = regCodeToServiceState(request, atoi(code), slot);           
+        current_data_reg = status;       
+        /*Warren change for SZZT 2021//11/14 end*/
+    }
+#ifdef LED_SUPPORT
+    mbtk_netled_state_update(GPIO_NETLED_REFLASH_NORMAL);  
+#endif
+}
+
+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 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;
+    }
+#ifdef TELEMATIC_5G_SUPPORT
+    case RADIO_TECH_NR://5G
+    {
+        if(request == RIL_REQUEST_VOICE_REGISTRATION_STATE) {
+            printf("[QUERY][VOICE REG_STATUS][SIM%d] The registered radio technology is 5G\n", slot);
+        } else {
+            printf("[QUERY][DATA  REG_STATUS][SIM%d] The registered radio technology is 5G\n", slot);
+        }
+        break;
+    }
+#endif
+    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;
+    char modem_sync_enable[24] = "";
+
+    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);
+
+    lynq_get_value("lynq_uci", "lynq_sync_time", "lynq_modem_sync_time_enable" , modem_sync_enable);
+    if(!atoi(modem_sync_enable))
+        return ;
+
+    stime(&t);
+    system("hwclock -w -f /dev/rtc0");
+    return;
+}
+void notifyDataSignal() {
+    RLOGE("notifyDataSignal()");
+    pthread_mutex_lock(&s_DataMutex);
+    pthread_cond_broadcast(&s_DataCond);
+    pthread_mutex_unlock(&s_DataMutex);
+}
+
+bool mtkItTest(const char* data) {
+    std::string str("");
+    str.append(data);
+    RLOGD("%s, data: %s", __FUNCTION__, str.c_str());
+    std::vector<std::string> all;
+    RequestInfo* pRI = NULL;
+    utils::tokenize(str, ',', all);
+    if(all[0] != std::string("TEST")) {
+        return false;
+    }
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    for(int i = 1 ; i < all.size(); i++) {
+        std::string str = all[i];
+        RLOGD("%s, all[%d]: %s", __FUNCTION__, i, str.c_str());
+        std::vector<std::string> items;
+        utils::tokenize(str, '=', items);
+        if(items.size() == 2) {
+            if(items[0] == std::string("INT")) {
+                int para = std::stoi(items[1]);
+                p.writeInt32(para);
+            } else if(items[0] == std::string("STR")) {
+                writeStringToParcel(p, items[1].c_str());
+            } else if(items[0] == std::string("REQ")) {
+                int request = std::stoi(items[1]);
+
+                // For loop, free before reassign to avoid memory leak
+                if (pRI != NULL) {
+                    free(pRI);
+                }
+                pRI = creatRILInfoAndInit(request, UDP, (RIL_SOCKET_ID) ((0)));
+            }
+        } else {
+            RLOGD("%s, too many \"=\"");
+        }
+    }
+
+    if(pRI && pRI->pCI) {
+        p.setDataPosition(pos);
+        pRI->pCI->dispatchFunction(p, pRI);
+    }
+
+    // Free to avoid memory leak
+    if(pRI != NULL) {
+        free(pRI);
+        pRI = NULL;
+    }
+
+    return true;
+}
+int lynqSocketSendto(int fd,struct sockaddr *dest_addr,int addr_len,char msg[])
+{
+    int ret = 0;
+    ret = sendto(fd,msg,strlen(msg),0,dest_addr,addr_len);
+    if(ret>0)
+    {
+        RLOGD("[lynqSocketSendto] send msg success!!!");
+        return 0;
+    }
+    else
+    {
+        RLOGD("[lynqSocketSendto] send msg fail!!!");
+        return -1;
+    }
+}
+
+void lynq_exit()
+{
+    ril_deinit_mem();
+#ifdef LED_SUPPORT
+    mbtk_netled_deinit();
+#endif
+}
+
+#ifdef LED_SUPPORT
+bool ril_get_if_insert_simcard()
+{
+    int slot_id=get_default_sim_voice();
+
+    if(slot_id==0 || slot_id ==1)
+    {
+        if(cur_CardS_Status[slot_id]!=NULL)
+        {
+            return  cur_CardS_Status[slot_id]->card_state == RIL_CARDSTATE_PRESENT;
+        }
+        
+    }
+    return false;	
+}
+
+bool ril_get_if_3gpp_reg_success()
+{
+    int slot_id=get_default_sim_voice();
+
+    if(slot_id==0 || slot_id ==1)
+    {
+        return reg_voice_service_state[slot_id] ==1;
+    }
+    return false;	
+}
+
+bool ril_get_if_3gpp_data_reg_success()
+{
+    int slot_id=get_default_sim_data();
+
+    if(slot_id==0 || slot_id ==1)
+    {
+        return reg_data_service_state[slot_id] ==1;
+    }
+    return false;	
+}
+
+#endif
+/*hq add for key info output 2022/03/01 begin*/
+// void lynq_output_LINFO_all()
+// {
+//     int slot,startSlot=0,slotNum=SIM_COUNT;     
+
+//     if(default_sim_voice==default_sim_data && default_sim_voice==default_sim_sms){
+//         startSlot=default_sim_voice;
+//         slotNum=1;        
+//     }   
+
+//     lynq_output_info("+LINFO: Report switch when key information changed is set: %d\n",lynq_output_LINFO_enable);          
+//     lynq_output_info("+LINFO: Default voice SIM card is set : [SIM%d]\n", default_sim_voice+1);    
+//     lynq_output_info("+LINFO: Default data SIM card is set : [SIM%d]\n", default_sim_data+1);
+//     lynq_output_info("+LINFO: Default sms SIM card is set : [SIM%d]\n", default_sim_sms+1);
+   
+//     for(slot=startSlot;slot<startSlot+slotNum;slot++){   
+//         lynq_output_info("+LINFO: [SIM%d] Card State is %s\n",slot+1,cardStateToString((cur_CardS_Status[slot]!=NULL ? cur_CardS_Status[slot]->card_state:UNKOWN_VALUE)));                  
+//         lynq_output_info("+LINFO: [SIM%d] Preferred network_type: is %s\n", slot+1, preferredNetworkTypeToString(preferred_network_type[slot]));
+//         lynq_output_info("+LINFO: [SIM%d] Voice Registration State is %s\n",slot+1,serviceStateToString(regCodeToServiceState(reg_voice_service_state[slot])));
+//         lynq_output_info("+LINFO: [SIM%d] Voice Radio Access Network is %s\n",slot+1,RadioNwToString(regCodeToRadioTechnology(reg_voice_radio_tech[slot])));
+//         lynq_output_info("+LINFO: [SIM%d] Data Registration State is %s\n",slot+1,serviceStateToString(regCodeToServiceState(reg_data_service_state[slot])));
+//         lynq_output_info("+LINFO: [SIM%d] Data Radio Access Network is %s\n",slot+1,RadioNwToString(regCodeToRadioTechnology(reg_data_radio_tech[slot])));          
+//     }  
+//     return;
+// }
+// void lynq_output_LINFO(const char* format,...)
+// {
+//     char buf[1024] = {0};
+//     int n;
+//     char ebuf[1024] = {0};
+
+//     if(lynq_output_LINFO_enable)
+//     {
+//         va_list args;
+//         va_start(args, format);
+//         vsnprintf(buf, sizeof(buf), format, args);
+//         va_end(args);
+
+//         printf("hq %s",buf);
+//         n=snprintf(ebuf,sizeof(ebuf),"+LINFO: %s", buf);
+
+//         n=write(ttyGS3_fd, ebuf, strlen(ebuf));
+//         if(n < 0)
+//         {
+//             perror("lynq resp write:");
+//         }
+//     }
+//     return;
+// }
+// void lynq_output_info(const char* format,...)
+// {
+//     char buf[1024] = {0};
+//     int n;   
+    
+//     va_list args;
+//     va_start(args, format);
+//     vsnprintf(buf, sizeof(buf), format, args);
+//     va_end(args);     
+       
+//     n=write(ttyGS3_fd, buf, strlen(buf));
+//     if(n < 0)
+//     {
+//         perror("lynq resp write:");
+//     }
+
+//     return;
+// }
+/*hq add for key info output 2022/03/01 end*/
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/common.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/common.h
new file mode 100755
index 0000000..b0bdb3e
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/common.h
@@ -0,0 +1,294 @@
+/* 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 "powerManager.h"
+#include "rfdesense/RfDesenseTxTest.h"
+#include "util/AtLine.h"
+/*Warren add for t800 ril service 2021/12/15 start*/
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+/*Warren add for t800 ril service 2021/12/15 start*/
+
+
+#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
+//Warren add for plantform 2021_08_11 start
+#define MAX_LEN 101
+#define MAX_QUEST_LEN 12
+//Warren add for plantform 2021_08_11 end
+#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"
+//Warren add for plantform 2021_08_11 start
+/* 
+**The range of error values unique to LYNQ is 8000 to 10000.
+**The sim card state is error.
+*/
+typedef enum{
+    LYNQ_E_CARDSTATE_ERROR=8000,
+    /* The voice service state is out of service*/
+    LYNQ_E_STATE_OUT_OF_SERVICE=8001,
+    /* The voice service state is EMERGENCY_ONLY*/
+    LYNQ_E_STATE_EMERGENCY_ONLY=8002,
+    /* The radio power is power off*/
+    LYNQ_E_STATE_POWER_OFF=8003,
+    LYNQ_E_TIME_OUT=8004,
+    /*create or open sms DB fail */
+    LYNQ_E_SMS_DB_FAIL=8005,
+    /*Failed to execute sql statement*/
+    LYNQ_E_SMS_SQL_FAIL = 8006,
+    LYNQ_E_SMS_NOT_FIND = 8007,
+    /* The logic conflict*/
+    LYNQ_E_CONFLICT=9000,
+    /*Null anomaly*/
+    LYNQ_E_NULL_ANONALY=9001
+}LYNQ_E;
+/*Warren add for t800 RIL Service 2021/12/10 start*/
+
+typedef struct{
+    int uToken;
+    int request;
+    int paramLen;
+    char param[1024*8];
+}lynq_client_t;
+/*Warren add for t800 RIL Service 2021/12/10 end*/
+
+
+#define UNSET -1
+
+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
+    /*Warren add for t800 ril service 2021/12/15 start*/
+    int uToken;
+    int lynqEvent;    // 1:This request comes from AT client
+                      // 2:This request comes from lynq client
+                      // 3:This request comes from factory client
+    struct sockaddr_in uClient_addr;
+    /*Warren add for t800 ril service 2021/12/15 end*/
+    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;
+
+/*Warren add for FAW 2021/11/1 start*/
+extern int ttyGS3_fd;
+/*Warren add for FAW 2021/11/1 end*/
+/*Warren add for SZZT 2021/11/14 start*
+** record data registration
+*/
+extern int current_data_reg;
+extern int modemStatus;
+extern int g_lynq_sim_state;
+/*Warren add for SZZT 2021/11/14 end*/
+
+// extern int lynq_output_LINFO_enable;
+// void lynq_output_info(const char* format,...);
+// void lynq_output_LINFO(const char* format,...);
+//void lynq_output_LINFO_all();
+    
+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;
+
+/**
+ * @brief lei add for output imformation on elt(at port)
+ * 
+ * @param format 
+ * @param ... 
+ */
+void lynq_output_info(const char* format,...);
+
+void lynq_send_result_already(void);
+int lynq_wait_result_comeback(int mtime);
+
+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);
+
+#ifdef LED_SUPPORT
+/*for led add by hq 20221202*/
+bool ril_get_if_insert_simcard();
+bool ril_get_if_3gpp_reg_success();
+bool ril_get_if_3gpp_data_reg_success();
+#endif
+
+/*for urc broad cast optimission by hq 20221216*/
+void lynq_exit();
+
+#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();
+bool mtkItTest(const char* data);
+
+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 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);
+    /*Warren add for FAW platform 2021/9/27 start*/
+    void startUsbLoop(void);
+    int sendRespToUsb(char *cmd);
+    int sendUrcToUsb(char *cmd);
+    int lynqSendToRil(int argc,char *argv[],int uToken);
+    /*Warren add for FAW platform 2021/9/27 end*/
+    /*Warren add for t800 RIL Service 2021/12/10 start*/
+    int lynqSocketSendto(int fd,struct sockaddr *dest_addr,int addr_len,char msg[]);
+/*Warren add for t800 RIL Service 2021/12/10 end*/
+/*Warren add for t800 ril service 2021/12/23 start*/
+    int lynqAssemblyParcelheader(Parcel &p,int slot,int utoken,int request,int respType,int error);
+    int LYNQ_RIL_respSocket(Parcel &p,RIL_Token t);
+    int LYNQ_RIL_respSocket_sp(Parcel &p,RequestInfo *pRI);
+    int LYNQ_RIL_urcBroadcast(Parcel &p,int urc_id=0);
+/*Warren add for t800 ril service 2021/12/23 end*/
+
+
+
+}
+
+#endif
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/data/data.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/data/data.cpp
new file mode 100755
index 0000000..8d81825
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/data/data.cpp
@@ -0,0 +1,1698 @@
+//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 <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"
+
+/*Warren add forT800 platform 2021/12/25 start*/
+#include "lynq_common.h"
+#include "lynq_interface.h"
+using android::Parcel;
+/*Warren add for t800 ril service  2021/12/25 end*/
+#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 = false;
+    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;
+    }
+
+    memset(dns,0,4*40);
+    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 NULL;
+}
+
+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)
+{
+    Parcel p;
+    /*jb.qi change for switch card after dial on 20221025 start*/
+    if((argc == 0) && (pRI == NULL))
+    {
+        printf("pRI is null, argc is zero !!!\n");
+        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 */
+        return ret;
+    }
+    /*jb.qi change for switch card after dial on 20221025 end*/
+    if(argc > 2)
+    {
+        /*Warren add for t800 ril service 2021/12/25 start*/
+        char* apnType = argv[1];
+        int result=0;
+        RLOGD("[setupDataCall] apn_count1:%d\n",apn_count);
+        for(int i = 0;i< LYNQ_APN_CHANNEL_MAX;i++)//代表已经有argv[1]类型的APN 已经被建立,
+        {
+            RLOGD("apnType:%s,argv[1]:%s\n",apn_table[i].apntype,argv[1]);
+            if(strcmp(apn_table[i].apntype,argv[1])==0)
+            {
+                /*此处直接返回response,给client成功的结果码,并返回iface*/
+                Parcel urc_p;
+                p.writeInt32(0);
+                p.writeInt32(pRI->pCI->requestNumber);
+                p.writeInt32(socket_id);
+                p.writeInt32(0);
+                android::LYNQ_RIL_respSocket(p, (void *)pRI);
+                urc_p.writeInt32(1);
+                urc_p.writeInt32(LYNQ_URC_DATA_CALL_STATUS_IND);
+                urc_p.writeInt32(socket_id);
+                urc_p.writeInt32(apn_table[i].apnstatus);
+                writeStringToParcel(urc_p, apn_table[i].apn);
+                writeStringToParcel(urc_p, apn_table[i].apntype);
+                writeStringToParcel(urc_p, apn_table[i].ifaceName);
+                android::LYNQ_RIL_urcBroadcast(urc_p,LYNQ_URC_DATA_CALL_STATUS_IND);
+                RLOGD("apn:%s,apntype:%s",apn_table[i].apn,apn_table[i].apntype);
+                return -1;
+            }
+        }
+        result = setupDataCallargc(argc,argv,socket_id,pRI);
+        p.writeInt32 (0);
+        p.writeInt32 (pRI->pCI->requestNumber);
+        p.writeInt32(socket_id);
+        p.writeInt32 (0);
+        android::LYNQ_RIL_respSocket(p, (void *)pRI);
+        if (pRI != NULL)
+        {
+            free(pRI);
+        }
+        return result;
+        /*Warren add for t800 ril service 2021/12/25 end*/
+    }
+    RLOGD("[setupDataCall] apn_count2:%d\n",apn_count);
+    for(int i = 0;i< LYNQ_APN_CHANNEL_MAX;i++)
+    {
+        RLOGD("id:%dapnType:%s,default\n",i,apn_table[i].apntype);
+        if(strcmp(apn_table[i].apntype,"default")==0)//代表已经有default类型的APN 已经被建立,
+        {
+            /*此处直接返回response,给client成功的结果码,并返回iface*/
+            Parcel urc_p;
+            p.writeInt32 (0);
+            p.writeInt32 (pRI->pCI->requestNumber);
+            p.writeInt32(socket_id);
+            p.writeInt32 (0);
+            android::LYNQ_RIL_respSocket(p, (void *)pRI);
+            urc_p.writeInt32(1);
+            urc_p.writeInt32(LYNQ_URC_DATA_CALL_STATUS_IND);
+            urc_p.writeInt32(socket_id);
+            urc_p.writeInt32(apn_table[i].apnstatus);
+            writeStringToParcel(urc_p, apn_table[i].apn);
+            writeStringToParcel(urc_p, apn_table[i].apntype);
+            writeStringToParcel(urc_p, apn_table[i].ifaceName);
+            android::LYNQ_RIL_urcBroadcast(urc_p,LYNQ_URC_DATA_CALL_STATUS_IND);
+            RLOGD("apn:%s,apntype:%s",apn_table[i].apn,apn_table[i].apntype);
+            return -1;
+        }
+    }
+    char cmd[256];
+    getCellularService();
+    findCellularName(line);
+    sprintf(cmd, "connmanctl connect %s", csname);
+    int ret = system(cmd);
+    memset(line, 0, LEN*sizeof(char));
+
+    updataDataConnectState(get_default_sim_data(), true);
+    p.writeInt32 (0);
+    p.writeInt32 (pRI->pCI->requestNumber);
+    p.writeInt32(socket_id);
+    p.writeInt32 (0);
+    android::LYNQ_RIL_respSocket(p, (void *)pRI);
+    /* 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);//Warren chenge for t800 ril service 2021/12/28 start
+        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)
+{
+    bool hasDeactivate = TRUE;
+    Parcel p;
+    /*jb.qi change for swtich card after dial on 20221025 start*/
+    if((pRI == NULL) && (argc == 0))
+    {
+        for(int i = 0;i< LYNQ_APN_CHANNEL_MAX;i++)
+        {
+            memset(apn_table[i].apntype,0,sizeof(apn_table[i].apntype));
+            memset(apn_table[i].ifaceName,0,sizeof(apn_table[i].ifaceName));
+            memset(apn_table[i].apn,0,sizeof(apn_table[i].apn));
+            apn_table[i].apnstatus = 0;
+            apn_table[i].netId = 0;
+            apn_table[i].used = 0;
+        }
+        apn_count = 0;
+        printf("pRI is null, argc is zero !!!\n");
+        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);
+        return ret;
+    }
+    /*jb.qi change for swtich card after dial on 20221025 end*/
+    if(argc == 2)
+    {
+        char* apnType = argv[1];
+        int re=0;
+        RLOGD("[deactivateDataCall] apn_count1:%d\n",apn_count);
+        if(apn_count>0)
+        {
+            for(int i = 0;i< LYNQ_APN_CHANNEL_MAX;i++)
+            {
+                RLOGD("[deactivateDataCall] apnType:%s,argv[1]:%s\n",apn_table[i].apntype,argv[1]);
+                if(strcmp(apn_table[i].apntype,argv[1])==0)
+                {
+                    apn_table[i].apnstatus=0;
+                    RLOGD("need remove apn:%s,apntype:%s",apn_table[i].apn,apn_table[i].apntype);
+                    hasDeactivate = FALSE;
+                    break;
+                }
+            }
+            if(hasDeactivate)
+            {
+                 p.writeInt32 (0);
+                 p.writeInt32 (pRI->pCI->requestNumber);
+                 p.writeInt32(socket_id);
+                 p.writeInt32 (2);//RIL_E_GENERIC_FAILURE
+                 android::LYNQ_RIL_respSocket(p, (void *)pRI);
+                 return -1;
+            }
+        }
+        else
+        {
+            p.writeInt32 (0);
+            p.writeInt32 (pRI->pCI->requestNumber);
+            p.writeInt32(socket_id);
+            p.writeInt32 (2);//RIL_E_GENERIC_FAILURE
+            android::LYNQ_RIL_respSocket(p, (void *)pRI);
+            return -1;
+        }
+        re = deactivateDataCallarc(argc,argv,socket_id,pRI);
+        p.writeInt32 (0);
+        p.writeInt32 (pRI->pCI->requestNumber);
+        p.writeInt32(socket_id);
+        p.writeInt32 (0);//RIL_E_GENERIC_FAILURE
+        android::LYNQ_RIL_respSocket(p, (void *)pRI);
+        if (pRI != NULL)
+        {
+            free(pRI);
+        }
+        return re;
+    }
+    RLOGD("[deactivateDataCall] apn_count2:%d\n",apn_count);
+    if(apn_count>0)
+    {
+        for(int i = 0;i< LYNQ_APN_CHANNEL_MAX;i++)
+        {
+            RLOGD("id:%dapnType:%s,default\n",i,apn_table[i].apntype);
+            if(strcmp(apn_table[i].apntype,"default")==0)
+            {
+                apn_table[i].apnstatus=0;
+                RLOGD("remove apn:%s,apntype:%s",apn_table[i].apn,apn_table[i].apntype);
+                hasDeactivate = FALSE;
+                break;
+            }
+        }
+        if(hasDeactivate)
+        {
+             p.writeInt32 (0);
+             p.writeInt32 (pRI->pCI->requestNumber);
+             p.writeInt32(socket_id);
+             p.writeInt32 (2);//RIL_E_GENERIC_FAILURE
+             android::LYNQ_RIL_respSocket(p, (void *)pRI);
+             return -1;
+        }
+    }
+    else
+    {
+        p.writeInt32 (0);
+        p.writeInt32 (pRI->pCI->requestNumber);
+        p.writeInt32(socket_id);
+        p.writeInt32 (2);//RIL_E_GENERIC_FAILURE
+        android::LYNQ_RIL_respSocket(p, (void *)pRI);
+        return -1;
+    }
+    char cmd[256];
+    getCellularService();
+    findCellularName(line);
+    sprintf(cmd, "connmanctl disconnect %s", csname);
+    int ret = system(cmd);
+    memset(line, 0, LEN*sizeof(char));
+    memset(csname, 0, 27*sizeof(char));
+    updataDataConnectState(get_default_sim_data(), false);
+    p.writeInt32 (0);
+    p.writeInt32 (pRI->pCI->requestNumber);
+    p.writeInt32(socket_id);
+    p.writeInt32 (0);//RIL_E_GENERIC_FAILURE
+    android::LYNQ_RIL_respSocket(p, (void *)pRI);
+    /* 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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/data/data.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/data/data.h
new file mode 100755
index 0000000..657f8be
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/data/data_gdbus.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/data/data_gdbus.cpp
new file mode 100755
index 0000000..dafea1a
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/data/data_gdbus.cpp
@@ -0,0 +1,592 @@
+//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 <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"
+/*Warren add for t800 ril service 2021/12/25 start*/
+#include "lynq_common.h"
+#include "lynq_interface.h"
+#include <binder/Parcel.h>
+#include "ATCI.h"
+#include "atci_lynq_data_cmd.h"
+#ifdef LED_SUPPORT
+#include "led.h"
+#endif
+using android::Parcel;
+
+/*Warren add for t800 ril service 2021/12/25 end*/
+
+#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*/
+#define DEBUG 0
+
+GMainLoop *loop = NULL;
+GDBusProxy *proxy = NULL;
+MTK_Data_Call_Response_v1 req_response;
+MTK_Data_Call_Response_v1 urc_response;
+
+
+/*Typethree add for t800 ril service 2022/04/14 start*/
+
+int lynq_data_modify_apn(gchar *reason,int lynq_request_id)
+{
+    Parcel p; 
+    if(reason == NULL)
+    {
+        RLOGD("modify apn reason apn");
+        return -1;
+    }
+    p.writeInt32(1);
+    p.writeInt32(lynq_request_id);
+    p.writeInt32(0);
+    writeStringToParcel(p,reason);
+    android::LYNQ_RIL_urcBroadcast(p,lynq_request_id);
+    return 0;
+}
+
+/*Typethree add for t800 ril service 2022/04/14 end*/
+
+/*Warren add for t103 szzt atsvc 2022/1/5 start*/
+/*lei modify on 2022/11/16*/
+
+/*lei modify on 2022/11/16*/
+/*Warren add for t103 szzt atsvc 2022/1/5 end*/
+
+/*Warren add for t800 ril service 2021/12/25 start*/
+int lynq_data_management(MTK_Data_Call_Response_v1 *urc_response)
+{
+    char apn_t[LYNQ_APN_LEN_MAX] = {};
+    char apnType_t[LYNQ_APNTPYE_LEN_MAX] = {};
+    char iface_t[LYNQ_APNTPYE_LEN_MAX] = {};
+    if(!urc_response)
+    {
+        RLOGD("urc_response is null!!!");
+        return -1;
+    }
+    bool apnHasCreated = FALSE;
+    Parcel p;
+    if(urc_response->cId > 0)
+    {
+        if(urc_response->pdnState==PDN_DISCONNECTED)//if user disable data call,the pdn state wiil change to disconnected.
+        {
+            for(int i = 0;i < LYNQ_APN_CHANNEL_MAX;i++)
+            {
+                #if DEBUG
+                printf("line %d [PDN_DISCONNECTED]apn_table[%d],apntype:%s,apnstatus:%d,,,urc_response->apnName:%s\n",__LINE__, i,apn_table[i].apntype,apn_table[i].apnstatus,urc_response->apnType);
+                #endif
+                RLOGD("[PDN_DISCONNECTED]apn_table[%d],apntype:%s,apnstatus:%d,,,urc_response->apnName:%s\n",i,apn_table[i].apntype,apn_table[i].apnstatus,urc_response->apnType);
+                if((strcmp(apn_table[i].apntype,urc_response->apnType)==0)&&(apn_table[i].apnstatus==0))
+                {
+                    bzero(apn_table[i].apn,LYNQ_APN_LEN_MAX);
+                    bzero(apn_table[i].apntype,LYNQ_APNTPYE_LEN_MAX);
+                    apn_table[i].used = 0;
+                    apn_table[i].netId = 0;
+                    apn_table[i].pdpstate = PDN_DISCONNECTED;
+                    apn_count--;
+                    p.writeInt32 (1);
+                    p.writeInt32 (LYNQ_URC_DATA_CALL_STATUS_IND);
+                    p.writeInt32 (0);//temporary plan
+                    p.writeInt32(PDN_DISCONNECTED);
+                    writeStringToParcel(p,urc_response->apnType);
+                    android::LYNQ_RIL_urcBroadcast(p,LYNQ_URC_DATA_CALL_STATUS_IND);
+                    RLOGD("removed apn:%s,apntype:%s",apn_table[i].apn,apn_table[i].apntype);
+#ifdef LED_SUPPORT
+                    if(apn_count==0)
+                    {
+                        mbtk_netled_state_update(GPIO_NETLED_PPP_CLOSED);  
+                    }
+#endif
+                    break;
+                }
+            }
+            for(int i = 0;i < LYNQ_APN_CHANNEL_MAX;i++)
+            {
+                RLOGD("for apn_table[%d].apn:%s,apntype:%s,used:%d,apnstatus:%d\n",i,apn_table[i].apn,
+                apn_table[i].apntype,apn_table[i].used,apn_table[i].apnstatus);
+            }
+        }
+        else
+        {
+            /*if the pdn status change,tele-fwk will send pdn status to me.
+            **The reason for the status change may be that enable data call, 
+            **the user disable the data call, and the signal is interrupted.
+            */
+            if(apn_count==0)//first new apn has created 
+            {
+                RLOGD("first apn_count:%d\n",apn_count);
+                memcpy(apn_table[apn_count].apn,urc_response->apnName,strlen(urc_response->apnName)+1);
+                memcpy(apn_table[apn_count].apntype,urc_response->apnType,strlen(urc_response->apnType)+1);
+                memcpy(apn_table[apn_count].ifaceName,urc_response->ifname,strlen(urc_response->ifname)+1);
+                memcpy(apn_table[apn_count].address,urc_response->addresses,strlen(urc_response->addresses)+1);
+                apn_table[apn_count].pdpstate = urc_response->pdnState;
+                #if DEBUG
+                printf("line %d apn_table[%d].apn:%s,apntype:%s,,,urc_response->apnName:%s,urc_response->apntype:%s\n",__LINE__,apn_count,apn_table[apn_count].apn,apn_table[apn_count].apntype,urc_response->apnName,urc_response->apnType);
+                #endif
+                RLOGD("apn_table[%d].apn:%s,apntype:%s,,,urc_response->apnName:%s,urc_response->apntype:%s\n",apn_count,apn_table[apn_count].apn,apn_table[apn_count].apntype,urc_response->apnName,urc_response->apnType);
+                apn_table[apn_count].apnstatus=1;
+                apn_table[apn_count].used=1;
+                apn_table[apn_count].netId=urc_response->netId;
+                apn_count++;
+                p.writeInt32(1);
+                p.writeInt32(LYNQ_URC_DATA_CALL_STATUS_IND);
+                p.writeInt32(0);//temporary plan
+                p.writeInt32(PDN_CONNECTED);
+                writeStringToParcel(p,urc_response->apnName);
+                writeStringToParcel(p,urc_response->apnType);
+                writeStringToParcel(p,urc_response->ifname);
+                android::LYNQ_RIL_urcBroadcast(p,LYNQ_URC_DATA_CALL_STATUS_IND);
+#ifdef LED_SUPPORT
+                mbtk_netled_state_update(GPIO_NETLED_PPP_CONNECT); 
+#endif
+            }
+            else
+            {
+                for(int i = 0;i < LYNQ_APN_CHANNEL_MAX;i++)//means apn state changed,need update
+                {
+                    #if DEBUG
+                    printf("line %d for apn_table[%d].apn:%s,,,,urc_response->apnName:%s\n",__LINE__,i,apn_table[i].apn,urc_response->apnName);
+                    #endif
+                    RLOGD("for apn_table[%d].apn:%s,,,,urc_response->apnName:%s\n",i,apn_table[i].apn,urc_response->apnName);
+                    if(strcmp(apn_table[i].apn,urc_response->apnName)==0)
+                    {
+                        #if DEBUG
+                        printf("line %d This apn has been created update???!!!\n",__LINE__);
+                        #endif
+                        RLOGD("This apn has been created!!!");
+                        apnHasCreated = TRUE;
+                        if(apn_table[i].netId!=urc_response->netId)
+                        {
+                            #if DEBUG
+                            printf("update???\n");
+                            #endif
+                            apn_table[i].netId = urc_response->netId;
+                            apn_table[i].pdpstate = urc_response->pdnState;
+                            memcpy(apn_table[i].ifaceName,urc_response->ifname,strlen(urc_response->ifname)+1);
+                            memcpy(apn_table[i].address,urc_response->addresses,strlen(urc_response->addresses)+1);
+                            memcpy(iface_t,apn_table[i].ifaceName,strlen(apn_table[i].ifaceName)+1);
+                            memcpy(apnType_t,apn_table[i].apntype,strlen(apn_table[i].apntype)+1);
+                            memcpy(apn_t,apn_table[i].apn,strlen(apn_table[i].apn)+1);
+                            /*send urc to client
+                            send apn_t,apnType_t,urc_response->pdnState,iface_t to client 
+                            */
+                            p.writeInt32(1);
+                            p.writeInt32(LYNQ_URC_DATA_CALL_STATUS_IND);
+                            p.writeInt32(0);//temporary plan
+                            p.writeInt32(urc_response->pdnState);
+                            writeStringToParcel(p,apn_t);
+                            writeStringToParcel(p,apnType_t);
+                            writeStringToParcel(p,iface_t);
+                            android::LYNQ_RIL_urcBroadcast(p,LYNQ_URC_DATA_CALL_STATUS_IND);
+                        }
+                        break;
+                    }
+                }
+                if(!apnHasCreated)//Multiple APNs are established new apn has created         
+                {
+                    bool getLable = FALSE;
+                    int lable = 0;
+                    for(lable;lable < LYNQ_APN_CHANNEL_MAX;lable++)//to find not used array element subscript
+                    {
+                        if(apn_table[lable].used==0)
+                        {
+                            getLable = TRUE;
+                            break;
+                        }
+                    }
+                    if(getLable)
+                    {
+                        #if DEBUG
+                        printf("line %d Multiple APNs are established\n", __LINE__);
+                        #endif
+                        RLOGD("[getLable]:label==%d\n",lable);
+                        memcpy(apn_table[lable].apn,urc_response->apnName,strlen(urc_response->apnName)+1);
+                        memcpy(apn_table[lable].apntype,urc_response->apnType,strlen(urc_response->apnType)+1);
+                        memcpy(apn_table[lable].ifaceName,urc_response->ifname,strlen(urc_response->ifname)+1);
+                        apn_table[lable].pdpstate = urc_response->pdnState;
+                        memcpy(apn_table[lable].address,urc_response->addresses,strlen(urc_response->addresses)+1);
+                        RLOGD("new apn_table[%d].apn:%s,apntype:%s,,,urc_response->apnName:%s,urc_response->apntype:%s\n",lable,apn_table[lable].apn,apn_table[lable].apntype,urc_response->apnName,urc_response->apnType);
+                        apn_table[lable].apnstatus=1;
+                        apn_table[lable].used=1;
+                        apn_table[lable].netId=urc_response->netId;
+                        apn_count++;
+                        p.writeInt32(1);
+                        p.writeInt32(LYNQ_URC_DATA_CALL_STATUS_IND);
+                        p.writeInt32(0);//temporary plan
+                        p.writeInt32(urc_response->pdnState);
+                        writeStringToParcel(p,urc_response->apnName);
+                        writeStringToParcel(p,urc_response->apnType);
+                        writeStringToParcel(p,urc_response->ifname);
+                        android::LYNQ_RIL_urcBroadcast(p,LYNQ_URC_DATA_CALL_STATUS_IND);
+                    }
+                    else
+                    {
+                        RLOGD("unkown error");
+                    }
+                }
+            }
+        }
+    }
+    else  //cid < 0 it means:when at+cfun=0 will into this or when connecting
+    {
+        apnHasCreated = FALSE;
+        RLOGD("[cid < 0] apn_count:%d\n",apn_count);
+        if(apn_count>0)
+        {
+            int i = 0;
+            for(i;i < LYNQ_APN_CHANNEL_MAX;i++)
+            {
+                #if DEBUG
+                printf("line %d don't know\n", __LINE__);
+                #endif
+                RLOGD("[cid<0]apn_table[%d].apntype:%s,,,,urc_response->apntype:%s\n",i,apn_table[i].apntype,urc_response->apnType);
+                if(strcmp(apn_table[i].apntype,urc_response->apnType)==0)
+                {
+                    RLOGD("apntype:%s PDN status has changed!!!\n",urc_response->apnType);
+                    apnHasCreated = TRUE;
+                    break;
+                }
+            }
+            if(apnHasCreated)
+            {
+                #if DEBUG
+                printf("line %d don't know\n", __LINE__);
+                #endif
+                apn_table[i].pdpstate = urc_response->pdnState;
+                char ptr[1] = "";
+                if(NULL == urc_response->ifname)
+                {
+                    memcpy(apn_table[i].ifaceName, ptr,strlen(ptr)+1);
+                }
+                if(NULL == urc_response->addresses)
+                {
+                    memcpy(apn_table[i].address, ptr, strlen(ptr)+1);
+                }
+                memcpy(iface_t,apn_table[i].ifaceName,strlen(apn_table[i].ifaceName)+1);
+                memcpy(apnType_t,apn_table[i].apntype,strlen(apn_table[i].apntype)+1);
+                memcpy(apn_t,apn_table[i].apn,strlen(apn_table[i].apn)+1);
+                p.writeInt32(1);
+                p.writeInt32(LYNQ_URC_DATA_CALL_STATUS_IND);
+                p.writeInt32(0);//temporary plan
+                p.writeInt32(urc_response->pdnState);
+                writeStringToParcel(p,apn_t);
+                writeStringToParcel(p,apnType_t);
+                writeStringToParcel(p,iface_t);
+                android::LYNQ_RIL_urcBroadcast(p,LYNQ_URC_DATA_CALL_STATUS_IND);
+            }
+        }
+    }
+    return 0;
+}
+/*Warren add for t800 ril service 2021/12/25 end*/
+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;
+}
+/*Typethree add for t800 RIL Service 2022/04/14 start*/
+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);
+        /*lei add for AT+LEAPNMOD*/
+        if(g_flag_apn)
+        {
+            char apn_buf[256];
+            sprintf(apn_buf, "+LEAPNMOD:%s", error->message);
+            ATCIResponseNoToken(100, apn_buf, 666);//tmp plan
+        }
+        /*lei add for AT+LEAPNMOD*/
+        lynq_data_modify_apn(error->message,LYNQ_URC_MODIFY_APNDB);
+        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));
+    /*lei add for AT+LEAPNMOD*/
+    if(g_flag_apn)
+    {
+        char apn_buf[256];
+        sprintf(apn_buf, "+LEAPNMOD:%s", ((reason == NULL)? "":reason));
+        ATCIResponseNoToken(0, apn_buf, 666);//tmp plan
+    }
+    /*lei add for AT+LEAPNMOD*/
+    g_variant_unref(result);
+    lynq_data_modify_apn(reason,LYNQ_URC_MODIFY_APNDB);
+}
+
+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);
+        lynq_data_modify_apn(error->message,LYNQ_URC_RESET_APNDB);
+        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);
+    lynq_data_modify_apn(reason,LYNQ_URC_RESET_APNDB);
+}
+/*Typethree add for t800 RIL Service 2022/04/14 end*/
+
+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);
+    printf("signal_name: %s\n", signal_name);
+    freeMem(urc_response);
+    parse(parameters, &urc_response);
+    dumpResponse(&urc_response);
+    if(g_strcmp0(signal_name, "lynq_data_resp") == 0)
+    {
+        printf("[lynq_data_resp]do something\n");
+        return;
+    }
+    lynq_data_management(&urc_response);
+    if(g_strcmp0(signal_name, "LYNQ_TEST") == 0)
+    {
+        printf("do something\n");
+    }
+    if(g_strcmp0(signal_name, "default") == 0)
+    {
+        if(urc_response.pdnState == RIL_Data_Call_PdnState::PDN_DISCONNECTED) {
+            notifyDataSignal();
+        } else if (urc_response.pdnState == RIL_Data_Call_PdnState::PDN_FAILED) {
+            updataDataConnectState(get_default_sim_data(), false);
+        }
+    }
+    return;
+
+}
+
+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);
+    }
+    return NULL;
+}
+
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/data/data_gdbus.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/data/data_gdbus.h
new file mode 100755
index 0000000..a6928ea
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/eCall.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/eCall.cpp
new file mode 100755
index 0000000..5d1ea71
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/eCall.cpp
@@ -0,0 +1,1680 @@
+//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 <binder/Parcel.h>
+
+#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"
+#include "lynq_interface.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;
+
+static int act_fecall_socid = -1;
+static 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 sAutoAnsTimer_ims;
+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 autoAns_sig_value_ims = 10;
+static int gost_resend_msd_value = 11;
+static int gost_deregistration_value = 12;
+
+static int g_ecall_test=0;
+static int g_reset_timer =6;
+
+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;
+    }
+    if(timer_gettime(sAutoAnsTimer_ims, &timespec) == -1) {
+        RLOGD("%s(), get ims_time fail(%s)", __FUNCTION__, strerror(errno));
+        return true;
+    }
+    RLOGD("%s(), ims tv_sec=%ld, tv_nsec=%ld", __FUNCTION__,timespec.it_value.tv_sec, timespec.it_value.tv_nsec);
+    if((timespec.it_value.tv_sec == 0)  && (timespec.it_value.tv_nsec == 0) ) {
+        RLOGD("%s(),ims timer_id(%ld) had stopped", __FUNCTION__, (long)sAutoAnsTimer_ims);
+        return true;
+    }
+    return false;
+}
+
+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);
+}
+
+int ecall_setRadioPower (int enable) {
+    
+    RequestInfo* pRI = creatRILInfoAndInit(RIL_REQUEST_RADIO_POWER, UDP, RIL_SOCKET_ID(act_fecall_socid));
+    char* id = const_cast<char*>(std::to_string(enable).c_str());
+    char* argv[2] = { "RIL_REQUEST_RADIO_POWER", "" };
+    argv[1] = id;
+    setRadioPower(2, argv, RIL_SOCKET_ID(act_fecall_socid), pRI);
+
+    return 0;
+}
+
+int lynq_is_msd_suc(int lynqIncomingEcallIndication)
+{
+    if(RIL_UNSOL_ECALL_ALACK_POSITIVE_RECEIVED == lynqIncomingEcallIndication ||
+       RIL_UNSOL_ECALL_LLACK_RECEIVED == lynqIncomingEcallIndication ||
+       RIL_UNSOL_ECALL_ALACK_CLEARDOWN_RECEIVED == lynqIncomingEcallIndication ||
+       RIL_UNSOL_ECALL_T5_TIMER_OUT  == lynqIncomingEcallIndication ||
+       RIL_UNSOL_ECALL_T6_TIMER_OUT  == lynqIncomingEcallIndication ||
+       RIL_UNSOL_ECALL_T7_TIMER_OUT  == lynqIncomingEcallIndication)
+    {
+        return 1;
+    }
+
+    return 0;
+}
+
+void ecall_test_sub_set(int eCall_Indication)
+{
+    if(g_ecall_test==1 && eCall_Indication == RIL_UNSOL_ECALL_ACTIVE)
+    {
+        ecall_setRadioPower(0);
+    }
+    else if(g_ecall_test==2 && lynq_is_msd_suc(eCall_Indication))
+    {
+        ecall_setRadioPower(0);
+    }
+    else if(g_ecall_test==3 && eCall_Indication == RIL_UNSOL_ECALL_PSAP_CALLBACK_START)
+    {
+        ecall_setRadioPower(0);
+    }
+    else if(g_ecall_test==4 && eCall_Indication == RIL_UNSOL_ECALL_SENDING_START)
+    {
+        ecall_setRadioPower(0);
+    }      
+    else if(g_ecall_test==5 && eCall_Indication == RIL_UNSOL_ECALL_SENDING_MSD)
+    {
+        ecall_setRadioPower(0);
+    }  
+    else if(g_ecall_test==6 && eCall_Indication == RIL_UNSOL_ECALL_T5_TIMER_OUT)
+    {
+        ecall_setRadioPower(0);
+    }     
+}
+
+void ecall_test_sub_recover()
+{
+    if(g_ecall_test!=0)
+    {
+        g_ecall_test=0;
+        ecall_setRadioPower(1);
+        sleep(g_reset_timer);
+    }    
+}
+
+void SendEcallTimerOutIndication(int sival_int, int soc_id, int call_id)
+{
+    android::Parcel p;
+    int timer_out_id;
+
+    if(sival_int == sT2_sig_value)
+    {
+        timer_out_id=RIL_UNSOL_ECALL_T2_TIMER_OUT;
+    }
+    else if(sival_int == sT5_sig_value)
+    {
+        timer_out_id=RIL_UNSOL_ECALL_T5_TIMER_OUT;
+    }
+    else if(sival_int == sT6_sig_value)
+    {
+        timer_out_id=RIL_UNSOL_ECALL_T6_TIMER_OUT;
+    }
+    else if(sival_int == sT7_sig_value)
+    {
+        timer_out_id=RIL_UNSOL_ECALL_T7_TIMER_OUT;
+    }
+    else if(sival_int == redial_sig_value)
+    {
+        timer_out_id=RIL_UNSOL_ECALL_REDIAL_TIMER_OUT;
+    }
+    else if(sival_int == autoAns_sig_value)
+    {
+        timer_out_id=RIL_UNSOL_ECALL_AUTO_ANS_TIMER_OUT;
+    }
+    else if(sival_int == autoAns_sig_value_ims)
+    {
+        timer_out_id=RIL_UNSOL_ECALL_AUTO_ANS_IMS_TIMER_OUT;
+    }
+    else 
+    {
+        return;
+    }
+
+    p.writeInt32(RESPONSE_UNSOLICITED);
+    p.writeInt32(RIL_UNSOL_ECALL_INDICATIONS);
+    p.writeInt32(soc_id);
+    p.writeInt32(timer_out_id);
+    p.writeInt32(call_id);
+
+    android::LYNQ_RIL_urcBroadcast(p);
+
+    ecall_test_sub_set(timer_out_id);
+
+    return;
+}
+
+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 ecall_timer_handler(sigval_t sig) {    
+    RLOGD("ecall_timer_handler, sig_value: %d, soc id : %d, call id %d", sig.sival_int,act_fecall_socid,act_feCall_Id);
+    int s;
+    int soc_id;
+    int call_id;
+    s = pthread_mutex_lock(&mtx);
+    if(s != 0) {
+        RLOGE("ecall_timer_handler, pthead_mutex_lock fail");
+    }
+    soc_id = act_fecall_socid;
+    call_id = act_feCall_Id;
+    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) {
+            act_fecall_socid = -1;
+            act_feCall_Id = -1;
+            goto done;
+        }
+        stop_ecall_timer(sT5,sT5_sig_value);
+        stop_ecall_timer(sT6,sT6_sig_value);
+        stop_ecall_timer(sT7,sT7_sig_value);
+        stop_ecall_timer(sRedialTimer, redial_sig_value);
+
+        redial_tag = REDIAL_SUCCESS;
+        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) {        
+        resetEcallIVSandAudio(UDP, RIL_SOCKET_ID(fast_ecall_socket_id));
+        start_ecll_timer(sT7,sT7_sig_value,T7_TIMEOUT);
+    } 
+    else if(sig.sival_int == sT6_sig_value
+            || sig.sival_int == sT7_sig_value) {
+        stop_ecall_timer(sRedialTimer, redial_sig_value);
+        redial_tag = REDIAL_SUCCESS;
+        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();
+     
+        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);
+        if(act_feCall_Id!=-1 &&  act_fecall_socid != -1)
+        {
+              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;
+
+        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 == autoAns_sig_value_ims) {
+        autoAnswerEcall(false);
+    } else if(sig.sival_int == gost_resend_msd_value) {
+        //send msd
+        char** argv = new char*[gost_sms_argv.size()];
+        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:       
+    SendEcallTimerOutIndication(sig.sival_int,soc_id,call_id);
+    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(&sAutoAnsTimer_ims,autoAns_sig_value_ims);
+    init_ecall_timer(&gostResendMsdTimer,gost_resend_msd_value);
+    init_ecall_timer(&gostDeregistrationTimer, gost_deregistration_value);
+}
+
+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);
+        }
+        act_fecall_socid = soc_id;
+        act_feCall_Id = p_cur->call_id;
+        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(sT5,sT5_sig_value);
+        stop_ecall_timer(sT7, sT7_sig_value);
+        start_ecll_timer(sT6, sT6_sig_value, T6_TIMEOUT);
+        stop_ecall_timer(sRedialTimer, redial_sig_value);
+     
+        redial_tag = REDIAL_SUCCESS;
+        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,
+    {
+        fast_argc = 0;
+        fast_argv.clear();
+        stop_ecall_timer(sT5,sT5_sig_value);
+        stop_ecall_timer(sT6,sT6_sig_value);
+        stop_ecall_timer(sT7,sT7_sig_value);
+        stop_ecall_timer(sRedialTimer, redial_sig_value);
+		
+        redial_tag = REDIAL_SUCCESS;
+        resetEcallIVSandAudio(RSPD, soc_id);
+        saveEcallRecord(p_cur->ind);
+
+        act_fecall_socid = soc_id;
+        act_feCall_Id = p_cur->call_id;
+        break;
+    }
+    case RIL_UNSOL_ECALL_ALACK_CLEARDOWN_RECEIVED: // = 5,
+    {
+	    fast_argc = 0;
+        fast_argv.clear();
+        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);
+        stop_ecall_timer(sRedialTimer, redial_sig_value);
+
+        redial_tag = REDIAL_SUCCESS;
+        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,
+    {
+        stop_ecall_timer(sAutoAnsTimer, autoAns_sig_value);
+        stop_ecall_timer(sAutoAnsTimer_ims, autoAns_sig_value_ims);
+        autoAnswerEcall(false);
+        start_ecll_timer(sT2, sT2_sig_value,T2_TIMEOUT);
+
+        // Start T5 only when need send inband MSD.
+        if (fast_argc)
+        {
+            if(redial_tag == REDIAL_SUCCESS)
+            {
+                redial_tag = REDIAL_UNKNOWN; //after recv RIL_UNSOL_ECALL_ACTIVE, do redail
+            }                
+            start_ecll_timer(sT5,sT5_sig_value, T5_TIMEOUT);
+        }
+        else 
+        {            
+            stop_ecall_timer(sRedialTimer, redial_sig_value);
+            redial_tag = REDIAL_SUCCESS;
+        }
+
+        act_fecall_socid = soc_id;
+        act_feCall_Id = p_cur->call_id;       
+        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);
+        stop_ecall_timer(sT5,sT5_sig_value);
+        stop_ecall_timer(sT6,sT6_sig_value);
+        stop_ecall_timer(sT7,sT7_sig_value);
+        stop_ecall_timer(sRedialTimer, redial_sig_value);
+        redial_tag = REDIAL_SUCCESS;
+
+        act_fecall_socid = -1;
+        act_feCall_Id = -1;
+        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 || redial_tag == REDIAL_UNKNOWN){
+            if(redial_tag == REDIAL_UNKNOWN) {                
+                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);
+                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);
+            ecall_test_sub_recover();
+            RequestInfo* pRI = creatRILInfoAndInit(RIL_REQUEST_ECALL_RESET_IVS, UDP, soc_id);
+            resetIVS(0, NULL, soc_id, pRI);
+            redialFastEcall(soc_id);
+        }
+        else {   /* redial_tag == REDIAL_SUCCESS || redial_tag == REDIAL_EXPIRES */
+            /*same as RIL_UNSOL_ECALL_DISCONNECTED*/
+            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);
+            start_ecll_timer(sAutoAnsTimer,autoAns_sig_value, AUTOANS_TIMEOUT);
+            autoAnswerEcall(true);       
+            ecall_test_sub_recover();
+        }
+        break;
+    }
+#if defined(TARGET_PLATFORM_MT2735)
+    case RIL_UNSOL_ECALL_IMS_ACTIVE: // 13 ,
+    {
+        act_fecall_socid = soc_id;
+        act_feCall_Id = p_cur->call_id;
+        stop_ecall_timer(sAutoAnsTimer, autoAns_sig_value);
+        stop_ecall_timer(sAutoAnsTimer_ims, autoAns_sig_value_ims);
+        autoAnswerEcall(false);
+        start_ecll_timer(sT2, sT2_sig_value,T2_TIMEOUT);
+        break;
+    }
+    case RIL_UNSOL_ECALL_IMS_DISCONNECTED: // 14
+    {
+        fast_argc = 0;
+        fast_argv.clear();
+        stop_ecall_timer(sT2, sT2_sig_value);
+        autoAnswerEcall(true);
+        start_ecll_timer(sAutoAnsTimer_ims, autoAns_sig_value_ims, 12*AUTOANS_TIMEOUT);
+        break;
+    }
+    case RIL_UNSOL_ECALL_IMS_MSD_ACK: // 20
+    {
+        saveEcallRecord(p_cur->ind);
+        break;
+    }
+    case RIL_UNSOL_ECALL_IMS_UPDATE_MSD: // 21,
+    {
+        RLOGD("update ims ecall msd_data: %s", msd_data==NULL ? "":msd_data);
+        if(msd_data != NULL) {
+            RequestInfo* pRI = creatRILInfoAndInit(RIL_REQUEST_ECALL_SET_MSD, RSPD, soc_id);
+            char* argv[3] = {"RIL_REQUEST_ECALL_SET_MSD", "", "" };
+            argv[1] = const_cast<char*>(std::to_string(p_cur->call_id).c_str());
+            argv[2] = msd_data;
+            setMSD(3, argv, soc_id, pRI);
+        }
+        break;
+    }
+    case RIL_UNSOL_ECALL_IMS_IN_BAND_TRANSFER: // 22
+    {
+        start_ecll_timer(sT5,sT5_sig_value, T5_TIMEOUT);
+        break;
+    }
+    case RIL_UNSOL_ECALL_IMS_MSD_NACK: // 23
+    {
+        saveEcallRecord(p_cur->ind);
+        break;
+    }
+    case RIL_UNSOL_ECALL_IMS_SRVCC: // 24
+    {
+        start_ecll_timer(sT5,sT5_sig_value, T5_TIMEOUT);
+        break;
+    }
+    case RIL_UNSOL_ECALL_PSAP_CALLBACK_START: // 40
+    {
+        // Similar to receive 11 + 1
+        redial_tag = REDIAL_SUCCESS;
+        
+        stop_ecall_timer(sAutoAnsTimer, autoAns_sig_value);
+        stop_ecall_timer(sAutoAnsTimer_ims, autoAns_sig_value_ims);		
+        autoAnswerEcall(false);  
+
+        fast_argc = 0;
+        fast_argv.clear();
+     
+        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);
+        stop_ecall_timer(sRedialTimer, redial_sig_value);
+        
+        act_fecall_socid = soc_id;
+        act_feCall_Id = p_cur->call_id;
+        start_ecll_timer(sT2, sT2_sig_value,T2_TIMEOUT);            
+
+        RLOGD("msd_data: %s", msd_data==NULL ? "":msd_data);
+        if(msd_data != NULL) {
+            RequestInfo* pRI = creatRILInfoAndInit(RIL_REQUEST_ECALL_SET_MSD, RSPD, soc_id);
+            char* argv[3] = {"RIL_REQUEST_ECALL_SET_MSD", "", "" };
+            argv[1] = const_cast<char*>(std::to_string(p_cur->call_id).c_str());
+            argv[2] = msd_data;
+            setMSD(3, argv, soc_id, pRI);
+        }
+        break;
+    }
+    case RIL_UNSOL_ECALL_PSAP_CALLBACK_IMS_UPDATE_MSD: // 41
+    {
+        // Similar to receive 13 + 21
+        act_fecall_socid = soc_id;
+        act_feCall_Id = p_cur->call_id;
+        stop_ecall_timer(sAutoAnsTimer, autoAns_sig_value);
+        stop_ecall_timer(sAutoAnsTimer_ims, autoAns_sig_value_ims);
+        autoAnswerEcall(false);
+        start_ecll_timer(sT2, sT2_sig_value,T2_TIMEOUT);
+
+        RLOGD("update ims ecall msd_data: %s", msd_data==NULL ? "":msd_data);
+        if(msd_data != NULL) {
+            RequestInfo* pRI = creatRILInfoAndInit(RIL_REQUEST_ECALL_SET_MSD, RSPD, soc_id);
+            char* argv[3] = {"RIL_REQUEST_ECALL_SET_MSD", "", "" };
+            argv[1] = const_cast<char*>(std::to_string(p_cur->call_id).c_str());
+            argv[2] = msd_data;
+            setMSD(3, argv, soc_id, pRI);
+        }
+        break;
+    }
+#endif    
+    default:
+        RLOGD("handleEcallIndication don't handle the value(%d)", p_cur->ind);
+        break;
+    }
+    
+    ecall_test_sub_set(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();
+  int enable = atoi(argv[1]);
+  if(enable<0 && enable> -100)
+  {
+     g_ecall_test=-enable;
+     android::lynqAssemblyParcelheader(p,socket_id,pRI->uToken,RIL_REQUEST_ECALL_SET_IVS,0,0);
+     android::LYNQ_RIL_respSocket_sp(p,pRI);
+     free(pRI);
+     return 0;
+  }
+  else if(-200 < enable &&  enable<=-100){
+     g_reset_timer=-enable-100;
+     android::lynqAssemblyParcelheader(p,socket_id,pRI->uToken,RIL_REQUEST_ECALL_SET_IVS,0,0);
+     android::LYNQ_RIL_respSocket_sp(p,pRI);
+     free(pRI);
+     return 0;
+  }
+
+  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] = {0};
+  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);
+    act_fecall_socid = -1;
+    act_feCall_Id = -1;
+    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);
+    return 1;
+}
+
+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))
+    {
+        if(argv) {
+            delete []argv;
+        }
+        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)
+        {
+            if(argv) {
+                delete []argv;
+            }
+            RLOGD("%s:testCase(%s) not need send sms", __FUNCTION__, testCase);
+            return -1;
+        }
+
+
+        if(fast_argv.size() < 5) {
+            if(argv) {
+                delete []argv;
+            }
+            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;
+    }
+
+    if(argv) {
+        delete []argv;
+    }
+    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 = 0;
+    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 - 1);
+    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;
+}
+
+void init_redial_flag()
+{
+    redial_tag = REDIAL_SUCCESS;//only after recv RIL_UNSOL_ECALL_ACTIVE, do redial
+}
+#endif /*ECALL_SUPPORT*/
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/eCall.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/eCall.h
new file mode 100755
index 0000000..7c5e668
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/eCall.h
@@ -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.
+ */
+#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);
+void init_redial_flag();
+#endif /*ECALL_SUPPORT*/
+#endif
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/IndividualRecord.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/IndividualRecord.cpp
new file mode 100755
index 0000000..d1940ab
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/IndividualRecord.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/IndividualRecord.h
new file mode 100755
index 0000000..7c83693
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/IndividualSubRecord.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/IndividualSubRecord.cpp
new file mode 100755
index 0000000..17f62f2
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/IndividualSubRecord.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/IndividualSubRecord.h
new file mode 100755
index 0000000..b6e9ba3
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/SslpManager.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/SslpManager.cpp
new file mode 100755
index 0000000..95310cf
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/SslpManager.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/SslpManager.h
new file mode 100755
index 0000000..8a6905c
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/commands/CmdUtils.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/commands/CmdUtils.cpp
new file mode 100755
index 0000000..b0afece
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/commands/CmdUtils.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/commands/CmdUtils.h
new file mode 100755
index 0000000..45b3380
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/commands/CommandAck.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/commands/CommandAck.cpp
new file mode 100755
index 0000000..1167a0b
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/commands/CommandAck.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/commands/CommandAck.h
new file mode 100755
index 0000000..d3286fa
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/commands/CommandBody.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/commands/CommandBody.cpp
new file mode 100755
index 0000000..3bf5e20
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/commands/CommandBody.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/commands/CommandBody.h
new file mode 100755
index 0000000..7a791e4
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/commands/SrComDataFormat.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/commands/SrComDataFormat.cpp
new file mode 100755
index 0000000..79f3c3b
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/commands/SrComDataFormat.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/commands/SrComDataFormat.h
new file mode 100755
index 0000000..bab5e68
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/ecall/EcallUtils.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/ecall/EcallUtils.cpp
new file mode 100755
index 0000000..e23174f
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/ecall/EcallUtils.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/ecall/EcallUtils.h
new file mode 100755
index 0000000..d34604e
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/ecall/SrRawMsdData.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/ecall/SrRawMsdData.cpp
new file mode 100755
index 0000000..086d27e
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/ecall/SrRawMsdData.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/ecall/SrRawMsdData.h
new file mode 100755
index 0000000..de88ee7
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/ecall/SrRecResp.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/ecall/SrRecResp.cpp
new file mode 100755
index 0000000..62fa3e9
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/ecall/SrRecResp.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/ecall/SrRecResp.h
new file mode 100755
index 0000000..1883bd0
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/ecall/SrTrackData.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/ecall/SrTrackData.cpp
new file mode 100755
index 0000000..281d90a
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/ecall/SrTrackData.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/ecall/SrTrackData.h
new file mode 100755
index 0000000..313b6af
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/ecall/srTrackDataTds.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/ecall/srTrackDataTds.cpp
new file mode 100755
index 0000000..06bc1e1
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/ecall/srTrackDataTds.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/ecall/srTrackDataTds.h
new file mode 100755
index 0000000..40ed83f
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/firmware/FirmwareUtils.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/firmware/FirmwareUtils.h
new file mode 100755
index 0000000..9439ea9
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/firmware/SrServiceFullData.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/firmware/SrServiceFullData.cpp
new file mode 100755
index 0000000..982a279
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/firmware/SrServiceFullData.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/firmware/SrServiceFullData.h
new file mode 100755
index 0000000..bcab11f
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/firmware/SrServicePartData.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/firmware/SrServicePartData.cpp
new file mode 100755
index 0000000..a2b489b
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/firmware/SrServicePartData.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/firmware/SrServicePartData.h
new file mode 100755
index 0000000..e840bdf
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/firmware/srSerPartDtObjHeader.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/firmware/srSerPartDtObjHeader.cpp
new file mode 100755
index 0000000..6a9e94e
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/firmware/srSerPartDtObjHeader.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/sslp/firmware/srSerPartDtObjHeader.h
new file mode 100755
index 0000000..cfd83fd
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/utils/GostEcallUtils.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/utils/GostEcallUtils.cpp
new file mode 100755
index 0000000..24936fe
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/utils/GostEcallUtils.cpp
@@ -0,0 +1,203 @@
+//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 "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");
+        delete [] hex;
+        hex = NULL;
+        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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/utils/GostEcallUtils.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/utils/GostEcallUtils.h
new file mode 100755
index 0000000..7cf7334
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/utils/GsmUtils.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/utils/GsmUtils.cpp
new file mode 100755
index 0000000..3ac4391
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/utils/GsmUtils.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ecall/gost/utils/GsmUtils.h
new file mode 100755
index 0000000..2a28f95
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/em.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/em.cpp
new file mode 100755
index 0000000..67fc7e7
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/em.cpp
@@ -0,0 +1,895 @@
+// 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 "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},
+#ifdef C2K_SUPPORT
+    {"EL1",0,NULL,1,1},
+#endif
+#ifdef TARGET_PLATFORM_MT2735
+    {"NR L1 Info",0,NULL,1,1},
+#endif
+    //{"Timer Information",0,NULL,1,1},
+    //{"TDD TAS",0,NULL,1,1},
+    //{"GSM TAS",0,NULL,1,1},
+    //{"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},
+#ifndef TARGET_PLATFORM_MT2735
+    {"sms_support",2,ims_setting,0,0},
+    {"voice_support",2,ims_setting,0,0}
+#endif
+};
+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_iot[] = {
+    {"General",0,NULL,1,1},
+    {"NSN",0,NULL,1,1},
+    {"DCM CB",0,NULL,1,1},
+    {"ERICSSON",0,NULL,1,1},
+};
+
+em_arry_t modem_operator[] = {
+    {"MS_USIM_COMPATIPLE",0,NULL,1,1},
+    {"ATNT",0,NULL,1,1},
+    {"TMOBILE",0,NULL,1,1},
+    {"ORANGE",0,NULL,1,1},
+    {"VODAFONE",0,NULL,1,1},
+    {"O2",0,NULL,1,1},
+    {"TELEFONICA",0,NULL,1,1},
+    {"DOCOMO",0,NULL,1,1},
+    {"SOFTBANK",0,NULL,1,1},
+    {"VIVO",0,NULL,1,1},
+    {"CLARO",0,NULL,1,1},
+    {"TIM",0,NULL,1,1},
+    {"CU",0,NULL,1,1},
+    {"KDDI",0,NULL,1,1},
+    {"CT IR LAB TEST",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},
+#ifdef TARGET_PLATFORM_MT2735
+    {"Integrity OFF",0,NULL,1,1},
+    {"FTA",NUM_ITEMS(modem_fta),modem_fta,1,1},
+    {"IOT",NUM_ITEMS(modem_iot),modem_iot,1,1},
+    {"OPERATOR",NUM_ITEMS(modem_operator),modem_operator,1,1},
+#else
+    {"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},
+#endif
+    {"FACTORY",0,NULL,1,1},
+#ifdef C2K_SUPPORT
+    {"CDMA Test Mode", NUM_ITEMS(modem_C2K_Test_MODEM),modem_C2K_Test_MODEM,1,1},
+#endif
+};
+em_arry_t hspa[] = {
+    {"QUERY",0,NULL,1,1},
+#ifdef TARGET_PLATFORM_MT2735
+    {"QUERY_CAINFO",0,NULL,1,1},
+#endif
+};
+em_arry_t cfu[] = {
+    {"Default",0,NULL,1,1},
+    {"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 getGSMSupportBand",0,NULL,1,1},
+#ifdef TARGET_PLATFORM_MT2735
+    {"getcurrentNRband",0,NULL,1,1},
+#endif
+//    {"[NR]setBand(eg: 1.1=1 add band, 1.1=0 remove band) or getGSMSupportBand",0,NULL,1,1},
+};
+em_arry_t networkinfo[] = {
+    {"RR Cell Sel",0,NULL,1,1},
+    {"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},
+#ifdef TARGET_PLATFORM_MT2735
+    {"setmode",0,NULL,1,1},
+#else
+    {"setmode",NUM_ITEMS(antenna_setmodes_4g),antenna_setmodes_4g,1,1},
+#endif
+};
+
+em_arry_t antenna_3Gmode[] = {
+    {"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 antenna_NRmode[] = {
+    {"getmode",0,NULL,1,1},
+    {"setmode",0,NULL,1,1},
+};
+
+em_arry_t antennatest[] = {
+    {"4G",NUM_ITEMS(antenna_4Gmode),antenna_4Gmode,1,1},
+#ifdef C2K_SUPPORT
+    {"3G",NUM_ITEMS(antenna_3Gmode),antenna_3Gmode,1,1},
+    {"CDMA",NUM_ITEMS(antenna_c2kmode),antenna_c2kmode,1,1},
+#endif
+#ifdef TARGET_PLATFORM_MT2735
+    {"NR",NUM_ITEMS(antenna_NRmode),antenna_NRmode,1,1},
+#endif
+};
+
+em_arry_t time_reg[] = {
+    { "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 rfdesense_nr_tx_mode[] = {
+        {"Tone",0,NULL,0,0},
+        {"PUSCH",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_nr_band[] = {
+        {"1",0,NULL,0,0},
+        {"3",0,NULL,0,0},
+        {"7",0,NULL,0,0},
+        {"8",0,NULL,0,0},
+        {"20",0,NULL,0,0},
+        {"28",0,NULL,0,0},
+        {"38",0,NULL,0,0},
+        {"41",0,NULL,0,0},
+        {"77",0,NULL,0,0},
+        {"78",0,NULL,0,0},
+        {"79",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_nr_bandwidth[] = {
+        {"5M",0,NULL,0,0},
+        {"10M",0,NULL,0,0},
+        {"15M",0,NULL,0,0},
+        {"20M",0,NULL,0,0},
+        {"25M",0,NULL,0,0},
+        {"30M",0,NULL,0,0},
+        {"35M",0,NULL,0,0},
+        {"40M",0,NULL,0,0},
+        {"45M",0,NULL,0,0},
+        {"50M",0,NULL,0,0},
+        {"55M",0,NULL,0,0},
+        {"60M",0,NULL,0,0},
+        {"65M",0,NULL,0,0},
+        {"70M",0,NULL,0,0},
+        {"75M",0,NULL,0,0},
+        {"82M",0,NULL,0,0},
+        {"85M",0,NULL,0,0},
+        {"90M",0,NULL,0,0},
+        {"95M",0,NULL,0,0},
+        {"100M",0,NULL,0,0},
+};
+
+em_arry_t  rfdesense_nr_mcs[] = {
+        {"DFT-S BPSK",0,NULL,0,0},
+        {"CP QPSK",0,NULL,0,0},
+        {"DFT-S QPSK",0,NULL,0,0},
+        {"CP 16QAM",0,NULL,0,0},
+        {"DFT-S 16QAM",0,NULL,0,0},
+        {"CP 64QAM",0,NULL,0,0},
+        {"DFT-S 64QAM",0,NULL,0,0},
+        {"CP 256QAM",0,NULL,0,0},
+        {"DFT-S 256QAM",0,NULL,0,0},
+};
+
+em_arry_t  rfdesense_nr_scs[] = {
+        {"15KHZ(0)",0,NULL,0,0},
+        {"30KHZ(1)",0,NULL,0,0},
+        {"60KHZ(2)",0,NULL,0,0},
+        {"120KHZ(3)",0,NULL,0,0},
+        {"240KHZ(4)",0,NULL,0,0},
+};
+
+em_arry_t rfdesense_nr_sub[] = {
+        {"Tx mode",NUM_ITEMS(rfdesense_nr_tx_mode),rfdesense_nr_tx_mode,0,0},
+        {"Band",NUM_ITEMS(rfdesense_nr_band),rfdesense_nr_band,0,0},
+        {"UL bandwidth",NUM_ITEMS(rfdesense_nr_bandwidth),rfdesense_nr_bandwidth,0,0},
+        {"UL freq(1kHz)",NUM_ITEMS(set_get),set_get,0,0},
+        {"VRB start(0-272)",NUM_ITEMS(set_get),set_get,0,0},
+        {"VRB length(1-273)",NUM_ITEMS(set_get),set_get,0,0},
+        {"MCS",NUM_ITEMS(rfdesense_nr_mcs),rfdesense_nr_mcs,0,0},
+        {"SCS",NUM_ITEMS(rfdesense_nr_scs),rfdesense_nr_scs,0,0},
+        {"Power level(dbm)(-50-23)",NUM_ITEMS(set_get),set_get,0,0},
+        {"Tdd slot config(1-44)",NUM_ITEMS(set_get),set_get,0,0},
+};
+
+em_arry_t rfdesense_nr[] = {
+        {"start",0,NULL,0,0},
+        {"Parameters_set",NUM_ITEMS(rfdesense_nr_sub),rfdesense_nr_sub,0,0},
+        {"show default",0,NULL,0,0},
+};
+
+em_arry_t sub_tx_test[] = {
+    { "GSM", NUM_ITEMS(rfdesense_gsm),rfdesense_gsm, 1, 1 },
+#ifndef TARGET_PLATFORM_MT2735
+    { "TDSCDMA", NUM_ITEMS(rfdesense_tdscdma), rfdesense_tdscdma, 1, 1 },
+#endif
+    { "WCDMA", NUM_ITEMS(rfdesense_wcdma), rfdesense_wcdma, 1, 1 },
+    { "LTE(FDD)", NUM_ITEMS(rfdesense_lte_fdd), rfdesense_lte_fdd, 1, 1 },
+    { "LTE(TDD)", NUM_ITEMS(rfdesense_lte_tdd), rfdesense_lte_tdd, 1, 1 },
+#ifdef TARGET_PLATFORM_MT2735
+    { "NR", NUM_ITEMS(rfdesense_nr), rfdesense_nr, 1, 1 },
+#endif
+#ifdef C2K_SUPPORT
+    { "CDMA(EVDO)", NUM_ITEMS(rfdesense_cdma), rfdesense_cdma, 1, 1 },
+    { "CDMA(1x)", NUM_ITEMS(rfdesense_cdma), rfdesense_cdma, 1, 1 },
+#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[] = {
+#ifdef C2K_SUPPORT
+    {"CDMA modem setting",NUM_ITEMS(c2k_modem_setting),c2k_modem_setting,0,0},
+#endif
+    {"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},
+#ifndef TARGET_PLATFORM_MT2735
+    {"CFU",NUM_ITEMS(cfu),cfu,0,0},
+#endif
+    {"Antenna Test",NUM_ITEMS(antennatest),antennatest,0,0},
+    {"Band Mode",NUM_ITEMS(bandmode),bandmode,0,0},
+    {"IMS",NUM_ITEMS(ims),ims,0,0},
+#ifndef TARGET_PLATFORM_MT2735
+    {"Network Info",NUM_ITEMS(no_support),no_support,0,0},
+#endif
+    {"LTE",NUM_ITEMS(lte_info),lte_info,0,0},
+};
+typedef enum {
+#ifdef C2K_SUPPORT
+    C2K_MODEM_SETTING = 0,
+    RF_DESENSE_TEST,
+#else
+    RF_DESENSE_TEST = 0,
+#endif
+    MODEM_TEST_ITEM,
+    HSPA_ITEM,
+#ifndef TARGET_PLATFORM_MT2735
+    CFU_ITEM,
+#endif
+    ANTENNATEST_ITEM,
+    BANDMODE_ITEM,
+    IMS_ITEM,
+#ifndef TARGET_PLATFORM_MT2735
+    NO_SUPPORT,
+#endif
+    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) {
+#ifndef TARGET_PLATFORM_MT2735
+    case C2K_MODEM_SETTING:
+        emC2kModemSettingStart(len - 1, multilen, &item[1]);
+        break;
+    case CFU_ITEM:
+        emCfuStart(len - 1, &item[1]);
+        break;
+#endif
+    case RF_DESENSE_TEST:
+        emRfDesenseStart(len - 1, &item[1], multilen, value);
+        break;
+    case MODEM_TEST_ITEM:
+        emModemtestStart(len - 1, multilen, &item[1]);
+        break;
+    case HSPA_ITEM:
+        emHspaStart(len - 1, &item[1]);
+        break;
+    case ANTENNATEST_ITEM:
+        emAntennaTestStart(len - 1, &item[1], multilen, value);
+        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 LTE_ITEM:
+        em_el1_start(len - 1, multilen, &item[1]);
+        break;
+#ifndef TARGET_PLATFORM_MT2735
+    case NO_SUPPORT:
+        android::emResultNotify("don't support\n");
+        break;
+#endif
+    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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/em.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/em.h
new file mode 100755
index 0000000..debdb4a
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/em.h
@@ -0,0 +1,157 @@
+// 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.
+ */
+#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 rfdesense_nr_tx_mode[];
+extern em_arry_t rfdesense_nr_band[];
+extern em_arry_t rfdesense_nr_bandwidth[];
+extern em_arry_t rfdesense_nr_mcs[];
+extern em_arry_t rfdesense_nr_scs[];
+extern em_arry_t rfdesense_nr_sub[];
+extern em_arry_t rfdesense_nr[];
+extern em_arry_t sub_tx_test[];
+extern em_arry_t desense_test[];
+extern em_arry_t emmain[];
+
+#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,int multilen,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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/em_EL1.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/em_EL1.cpp
new file mode 100755
index 0000000..9551698
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/em_EL1.cpp
@@ -0,0 +1,578 @@
+// SPDX-License-Identifier: MediaTekProprietary
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include <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"
+#include "../util/utils.h"
+
+#if EM_MODE_SUPPORT
+
+#undef LOG_TAG
+#define LOG_TAG "EM_EL1"
+
+#define MAX_RAN_CELL_SIZE 32
+
+static int mItemCount = 0;
+static int mFlag = 0;// at cmd flag
+static int mCurrentFlag = 0; // at cmd handle flag
+
+static const int MSG_NW_INFO = 1;
+static const int MSG_NW_INFO_OPEN = 4;
+static const int MSG_NW_INFO_CLOSE = 5;
+static const int MSG_NW_CA_INFO_LTE_NR = 6;
+
+
+static const int IDX_EL1 = -1;
+static const int IDX_CA_INFO_LTE_NR = 0;
+int intput_idx = 0;
+
+static const std::string CMD_SAME_EDMFAPP = "+EDMFAPP: 6,3,";
+
+struct cell_band_bandwidth_struct {
+    /** @brief Cell Identity. */
+    int cid;
+    int c_state;        /*1: SCELL_STATUS_NOTACTIVE 2: SCELL_STATUS_ACTIVE */
+    int cell_band;      /* cell band: 1~1024 */
+    int cell_bandwidth; /* cell bandwidth index */
+    int cc_cw0_cqi;     /*0~15*/
+    int cc_cw1_cqi;     /*0~15*/
+    int cc_pci;         /*0~1024*/
+    int cc_arfcn;       /*22bit*/
+};
+
+struct all_cell_band_bandwidth_struct{
+    int num_serving_lte_cell_dl;
+    int num_serving_lte_cell_ul;
+    int num_serving_nr_cell_dl;
+    int num_serving_nr_cell_ul;
+    cell_band_bandwidth_struct lte_band_bandwidth_dl[MAX_RAN_CELL_SIZE];
+    cell_band_bandwidth_struct lte_band_bandwidth_ul[MAX_RAN_CELL_SIZE];
+    cell_band_bandwidth_struct nr_band_bandwidth_dl[MAX_RAN_CELL_SIZE];
+    cell_band_bandwidth_struct nr_band_bandwidth_ul[MAX_RAN_CELL_SIZE];
+};
+
+static void sendATCommand(const char *cmd,int msg)
+{
+    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 parseCAInfo(char* data) {
+    RLOGD("parseCAInfo, rsp=%s", data);
+    std::vector<std::string> out;
+    utils::tokenize(string(data), "\n", out);
+    int cell_idx = 0, at_idx = 0;
+    std::string str;
+    str.clear();
+    char tmp[1024] = {0};
+
+    for(auto i: out) {
+        if(i.find(CMD_SAME_EDMFAPP) != std::string::npos) {
+            std::string splitString = i.substr(std::string(CMD_SAME_EDMFAPP).size());
+            std::vector<std::string> getDigitalVal;
+            utils::tokenize(string(splitString), ",\n", getDigitalVal);
+            RLOGD("parseCurrentMode splitString: %s, getDigitalVal.size()=%d",
+                    splitString.c_str(), getDigitalVal.size());
+
+            try {
+                all_cell_band_bandwidth_struct cells_info;
+                memset(&cells_info, 0, sizeof(all_cell_band_bandwidth_struct));
+                str.append("[Cell Info]\n");
+
+                // LTE DL
+                cells_info.num_serving_lte_cell_dl = std::stoi(getDigitalVal[at_idx]);
+                RLOGW("cells_info.num_serving_lte_cell_dl=%d", cells_info.num_serving_lte_cell_dl);
+                sprintf(tmp, "num_serving_lte_cell_dl:%d\n", cells_info.num_serving_lte_cell_dl);
+                str.append(tmp);
+                memset(tmp, 0, sizeof(char)*1024);
+                at_idx++;
+
+                if (cells_info.num_serving_lte_cell_dl != 0) {
+                    for (cell_idx = 0; cell_idx < cells_info.num_serving_lte_cell_dl; cell_idx++) {
+
+                        if (cell_idx >= MAX_RAN_CELL_SIZE) {
+                            RLOGW("cell_idx=%d > MAX_RAN_CELL_SIZE=%d, ignore", cell_idx, MAX_RAN_CELL_SIZE);
+                            continue;
+                        }
+
+                        cells_info.lte_band_bandwidth_dl[cell_idx].cid = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.lte_dl[%d].cid=%d", cell_idx, cells_info.lte_band_bandwidth_dl[cell_idx].cid);
+                        at_idx++;
+
+                        cells_info.lte_band_bandwidth_dl[cell_idx].c_state = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.lte_dl[%d].c_state=%d", cell_idx, cells_info.lte_band_bandwidth_dl[cell_idx].c_state);
+                        at_idx++;
+
+                        cells_info.lte_band_bandwidth_dl[cell_idx].cell_band = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.lte_dl[%d].cell_band=%d", cell_idx, cells_info.lte_band_bandwidth_dl[cell_idx].cell_band);
+                        at_idx++;
+
+                        cells_info.lte_band_bandwidth_dl[cell_idx].cell_bandwidth = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.lte_dl[%d].cell_bandwidth=%d", cell_idx, cells_info.lte_band_bandwidth_dl[cell_idx].cell_bandwidth);
+                        at_idx++;
+
+                        cells_info.lte_band_bandwidth_dl[cell_idx].cc_cw0_cqi = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.lte_dl[%d].cc_cw0_cqi=%d", cell_idx, cells_info.lte_band_bandwidth_dl[cell_idx].cc_cw0_cqi);
+                        at_idx++;
+
+                        cells_info.lte_band_bandwidth_dl[cell_idx].cc_cw1_cqi = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.lte_dl[%d].cc_cw1_cqi=%d", cell_idx, cells_info.lte_band_bandwidth_dl[cell_idx].cc_cw1_cqi);
+                        at_idx++;
+
+                        cells_info.lte_band_bandwidth_dl[cell_idx].cc_pci = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.lte_dl[%d].cc_pci=%d", cell_idx, cells_info.lte_band_bandwidth_dl[cell_idx].cc_pci);
+                        at_idx++;
+
+                        cells_info.lte_band_bandwidth_dl[cell_idx].cc_arfcn = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.lte_dl[%d].cc_arfcn=%d", cell_idx, cells_info.lte_band_bandwidth_dl[cell_idx].cc_arfcn);
+                        at_idx++;
+
+                        sprintf(tmp,
+                                "lte_dl[%d]:\n"
+                                " - cid: %d\n"
+                                " - c_state: %d\n"
+                                " - cell_band: %d\n"
+                                " - cell_bandwidth: %d\n"
+                                " - cc_cw0_cqi: %d\n"
+                                " - cc_cw1_cqi: %d\n"
+                                " - cc_pci: %d\n"
+                                " - cc_arfcn: %d\n",
+                                cell_idx,
+                                cells_info.lte_band_bandwidth_dl[cell_idx].cid,
+                                cells_info.lte_band_bandwidth_dl[cell_idx].c_state,
+                                cells_info.lte_band_bandwidth_dl[cell_idx].cell_band,
+                                cells_info.lte_band_bandwidth_dl[cell_idx].cell_bandwidth,
+                                cells_info.lte_band_bandwidth_dl[cell_idx].cc_cw0_cqi,
+                                cells_info.lte_band_bandwidth_dl[cell_idx].cc_cw1_cqi,
+                                cells_info.lte_band_bandwidth_dl[cell_idx].cc_pci,
+                                cells_info.lte_band_bandwidth_dl[cell_idx].cc_arfcn);
+                        str.append(tmp);
+                        RLOGD("result1 str=%s", str.c_str());
+                        memset(tmp, 0, sizeof(char)*1024);
+                    }
+                }
+
+                // LTE UL
+                cells_info.num_serving_lte_cell_ul = std::stoi(getDigitalVal[at_idx]);
+                RLOGW("cells_info.num_serving_lte_cell_ul=%d", cells_info.num_serving_lte_cell_ul);
+                sprintf(tmp, "num_serving_lte_cell_ul:%d\n", cells_info.num_serving_lte_cell_ul);
+                str.append(tmp);
+                memset(tmp, 0, 1024);
+                at_idx++;
+
+                if (cells_info.num_serving_lte_cell_ul != 0) {
+                    for (cell_idx = 0; cell_idx < cells_info.num_serving_lte_cell_ul; cell_idx++) {
+
+                        if (cell_idx >= MAX_RAN_CELL_SIZE) {
+                            RLOGW("cell_idx=%d >= MAX_RAN_CELL_SIZE=%d, ignore", cell_idx, MAX_RAN_CELL_SIZE);
+                            continue;
+                        }
+
+                        cells_info.lte_band_bandwidth_ul[cell_idx].cid = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.lte_ul[%d].cid=%d", cell_idx, cells_info.lte_band_bandwidth_ul[cell_idx].cid);
+                        at_idx++;
+
+                        cells_info.lte_band_bandwidth_ul[cell_idx].c_state = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.lte_ul[%d].c_state=%d", cell_idx, cells_info.lte_band_bandwidth_ul[cell_idx].c_state);
+                        at_idx++;
+
+                        cells_info.lte_band_bandwidth_ul[cell_idx].cell_band = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.lte_ul[%d].cell_band=%d", cell_idx, cells_info.lte_band_bandwidth_ul[cell_idx].cell_band);
+                        at_idx++;
+
+                        cells_info.lte_band_bandwidth_ul[cell_idx].cell_bandwidth = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.lte_ul[%d].cell_bandwidth=%d", cell_idx, cells_info.lte_band_bandwidth_ul[cell_idx].cell_bandwidth);
+                        at_idx++;
+
+                        cells_info.lte_band_bandwidth_ul[cell_idx].cc_pci = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.lte_ul[%d].cc_pci=%d", cell_idx, cells_info.lte_band_bandwidth_ul[cell_idx].cc_pci);
+                        at_idx++;
+
+                        cells_info.lte_band_bandwidth_ul[cell_idx].cc_arfcn = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.lte_ul[%d].cc_arfcn=%d", cell_idx, cells_info.lte_band_bandwidth_ul[cell_idx].cc_arfcn);
+                        at_idx++;
+
+                        sprintf(tmp,
+                                "lte_ul[%d]:\n"
+                                " - cid: %d\n"
+                                " - c_state: %d\n"
+                                " - cell_band: %d\n"
+                                " - cell_bandwidth: %d\n"
+                                " - cc_pci: %d\n"
+                                " - cc_arfcn: %d\n",
+                                cell_idx,
+                                cells_info.lte_band_bandwidth_ul[cell_idx].cid,
+                                cells_info.lte_band_bandwidth_ul[cell_idx].c_state,
+                                cells_info.lte_band_bandwidth_ul[cell_idx].cell_band,
+                                cells_info.lte_band_bandwidth_ul[cell_idx].cell_bandwidth,
+                                cells_info.lte_band_bandwidth_ul[cell_idx].cc_pci,
+                                cells_info.lte_band_bandwidth_ul[cell_idx].cc_arfcn);
+                        str.append(tmp);
+                        RLOGD("result2 str=%s", str.c_str());
+                        memset(tmp, 0, sizeof(char)*1024);
+                    }
+                }
+
+                // NR DL
+                cells_info.num_serving_nr_cell_dl = std::stoi(getDigitalVal[at_idx]);
+                RLOGW("cells_info.num_serving_nr_cell_dl=%d", cells_info.num_serving_nr_cell_dl);
+                sprintf(tmp, "num_serving_nr_cell_dl:%d\n", cells_info.num_serving_nr_cell_dl);
+                str.append(tmp);
+                memset(tmp, 0, 1024);
+                at_idx++;
+
+                if (cells_info.num_serving_nr_cell_dl != 0) {
+                    for (cell_idx = 0; cell_idx < cells_info.num_serving_nr_cell_dl; cell_idx++) {
+
+                        if (cell_idx >= MAX_RAN_CELL_SIZE) {
+                            RLOGW("cell_idx=%d > MAX_RAN_CELL_SIZE=%d, ignore", cell_idx, MAX_RAN_CELL_SIZE);
+                            continue;
+                        }
+
+                        cells_info.nr_band_bandwidth_dl[cell_idx].cid = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.nr_dl[%d].cid=%d", cell_idx, cells_info.nr_band_bandwidth_dl[cell_idx].cid);
+                        at_idx++;
+
+                        cells_info.nr_band_bandwidth_dl[cell_idx].c_state = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.nr_dl[%d].c_state=%d", cell_idx, cells_info.nr_band_bandwidth_dl[cell_idx].c_state);
+                        at_idx++;
+
+                        cells_info.nr_band_bandwidth_dl[cell_idx].cell_band = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.nr_dl[%d].cell_band=%d", cell_idx, cells_info.nr_band_bandwidth_dl[cell_idx].cell_band);
+                        at_idx++;
+
+                        cells_info.nr_band_bandwidth_dl[cell_idx].cell_bandwidth = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.nr_dl[%d].cell_bandwidth=%d", cell_idx, cells_info.nr_band_bandwidth_dl[cell_idx].cell_bandwidth);
+                        at_idx++;
+
+                        cells_info.nr_band_bandwidth_dl[cell_idx].cc_cw0_cqi = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.nr_dl[%d].cc_cw0_cqi=%d", cell_idx, cells_info.nr_band_bandwidth_dl[cell_idx].cc_cw0_cqi);
+                        at_idx++;
+
+                        cells_info.nr_band_bandwidth_dl[cell_idx].cc_cw1_cqi = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.nr_dl[%d].cc_cw1_cqi=%d", cell_idx, cells_info.nr_band_bandwidth_dl[cell_idx].cc_cw1_cqi);
+                        at_idx++;
+
+                        cells_info.nr_band_bandwidth_dl[cell_idx].cc_pci = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.nr_dl[%d].cc_pci=%d", cell_idx, cells_info.nr_band_bandwidth_dl[cell_idx].cc_pci);
+                        at_idx++;
+
+                        cells_info.nr_band_bandwidth_dl[cell_idx].cc_arfcn = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.nr_dl[%d].cc_arfcn=%d", cell_idx, cells_info.nr_band_bandwidth_dl[cell_idx].cc_arfcn);
+                        at_idx++;
+
+                        sprintf(tmp,
+                                "nr_dl[%d]:\n"
+                                " - cid: %d\n"
+                                " - c_state: %d\n"
+                                " - cell_band: %d\n"
+                                " - cell_bandwidth: %d\n"
+                                " - cc_cw0_cqi: %d\n"
+                                " - cc_cw1_cqi: %d\n"
+                                " - cc_pci: %d\n"
+                                " - cc_arfcn: %d\n",
+                                cell_idx,
+                                cells_info.nr_band_bandwidth_dl[cell_idx].cid,
+                                cells_info.nr_band_bandwidth_dl[cell_idx].c_state,
+                                cells_info.nr_band_bandwidth_dl[cell_idx].cell_band,
+                                cells_info.nr_band_bandwidth_dl[cell_idx].cell_bandwidth,
+                                cells_info.nr_band_bandwidth_dl[cell_idx].cc_cw0_cqi,
+                                cells_info.nr_band_bandwidth_dl[cell_idx].cc_cw1_cqi,
+                                cells_info.nr_band_bandwidth_dl[cell_idx].cc_pci,
+                                cells_info.nr_band_bandwidth_dl[cell_idx].cc_arfcn);
+                        str.append(tmp);
+                        RLOGD("result3 str=%s", str.c_str());
+                        memset(tmp, 0, 1024);
+                    }
+                }
+
+                // NR UL
+                cells_info.num_serving_nr_cell_ul = std::stoi(getDigitalVal[at_idx]);
+                RLOGW("cells_info.num_serving_nr_cell_ul=%d", cells_info.num_serving_nr_cell_ul);
+                sprintf(tmp, "num_serving_nr_cell_ul:%d\n", cells_info.num_serving_nr_cell_ul);
+                str.append(tmp);
+                memset(tmp, 0, 1024);
+
+                at_idx++;
+
+                if (cells_info.num_serving_nr_cell_ul != 0) {
+                    for (cell_idx = 0; cell_idx < cells_info.num_serving_nr_cell_ul; cell_idx++) {
+
+                        if (cell_idx >= MAX_RAN_CELL_SIZE) {
+                            RLOGW("cell_idx=%d > MAX_RAN_CELL_SIZE=%d, ignore", cell_idx, MAX_RAN_CELL_SIZE);
+                            continue;
+                        }
+
+                        cells_info.nr_band_bandwidth_ul[cell_idx].cid = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.nr_ul[%d].cid=%d", cell_idx, cells_info.nr_band_bandwidth_ul[cell_idx].cid);
+                        at_idx++;
+
+                        cells_info.nr_band_bandwidth_ul[cell_idx].c_state = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.nr_ul[%d].c_state=%d", cell_idx, cells_info.nr_band_bandwidth_ul[cell_idx].c_state);
+                        at_idx++;
+
+                        cells_info.nr_band_bandwidth_ul[cell_idx].cell_band = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.nr_ul[%d].cell_band=%d", cell_idx, cells_info.nr_band_bandwidth_ul[cell_idx].cell_band);
+                        at_idx++;
+
+                        cells_info.nr_band_bandwidth_ul[cell_idx].cell_bandwidth = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.nr_ul[%d].cell_bandwidth=%d", cell_idx, cells_info.nr_band_bandwidth_ul[cell_idx].cell_bandwidth);
+                        at_idx++;
+
+                        cells_info.nr_band_bandwidth_ul[cell_idx].cc_pci = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.nr_ul[%d].cc_pci=%d", cell_idx, cells_info.nr_band_bandwidth_ul[cell_idx].cc_pci);
+                        at_idx++;
+
+                        cells_info.nr_band_bandwidth_ul[cell_idx].cc_arfcn = std::stoi(getDigitalVal[at_idx]);
+                        RLOGD("cells_info.nr_ul[%d].cc_arfcn=%d", cell_idx, cells_info.nr_band_bandwidth_ul[cell_idx].cc_arfcn);
+                        at_idx++;
+
+                        sprintf(tmp,
+                                "nr_ul[%d]:\n"
+                                " - cid: %d\n"
+                                " - c_state: %d\n"
+                                " - cell_band: %d\n"
+                                " - cell_bandwidth: %d\n"
+                                " - cc_pci: %d\n"
+                                " - cc_arfcn: %d\n",
+                                cell_idx,
+                                cells_info.nr_band_bandwidth_ul[cell_idx].cid,
+                                cells_info.nr_band_bandwidth_ul[cell_idx].c_state,
+                                cells_info.nr_band_bandwidth_ul[cell_idx].cell_band,
+                                cells_info.nr_band_bandwidth_ul[cell_idx].cell_bandwidth,
+                                cells_info.nr_band_bandwidth_ul[cell_idx].cc_pci,
+                                cells_info.nr_band_bandwidth_ul[cell_idx].cc_arfcn);
+                        str.append(tmp);
+                        RLOGD("result4 str=%s", str.c_str());
+                        memset(tmp, 0, 1024);
+                    }
+                }
+
+                str.append("\ndone\n");
+                RLOGD("final result str=%s", str.c_str());
+                android::emResultNotify(str.c_str());
+
+            } catch (const out_of_range &e) {
+                android::emResultNotify(RET_STRING_LTE_FAIL);
+                RLOGD("out of range: %s", e.what());
+                return;
+            } catch (const invalid_argument &e) {
+                android::emResultNotify(RET_STRING_LTE_FAIL);
+                RLOGD("invalid argument: %s", e.what());
+                return;
+            }
+        }
+    }
+}
+
+static void el1_at_cmd_handle(char*response, int responselen) {
+    switch (mCurrentFlag) {
+        case MSG_NW_INFO:
+            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;
+        case MSG_NW_CA_INFO_LTE_NR:
+            if ((responselen > 0) && (response != NULL)) {
+                RLOGD("Get response %s", response);
+                parseCAInfo(response);
+            } else {
+                RLOGE("Query CA info fail failed.");
+                android::emResultNotify(RET_STRING_LTE_FAIL);
+            }
+            break;
+        default:
+            break;
+    }
+}
+
+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);
+    }
+}
+
+//create thread to send command
+void * emEl1Thread(void* arg)
+{
+    // EL1
+    if (lte_info[intput_idx].name == "EL1") {
+        RLOGD("emEl1Thread, MSG_NW_INFO");
+
+        //sendATCommand("AT+EINFO?",MSG_NW_INFO);
+        mFlag = 8;
+        char atcommand[32] = {0};
+        sprintf(atcommand,"AT+EINFO=%d,%d,0",mFlag,EM_EL1_INFO);
+        sendATCommand(atcommand, MSG_NW_INFO_OPEN);
+
+    // Send AT+ECAINFO
+    } else if (lte_info[intput_idx].name == "NR L1 Info") {
+        RLOGD("emEl1Thread, query the latest CA information of LTE/NR");
+
+        char atcommand[32] = {0};
+        sprintf(atcommand,"AT+EDMFAPP=6,3");
+        sendATCommand(atcommand, MSG_NW_CA_INFO_LTE_NR);
+    }
+
+    pthread_exit(0);
+}
+
+int em_el1_start(int argc, int multicnt,int *item)
+{
+    RLOGD("em_el1_start called, item[0]=%d", item[0]);
+
+    intput_idx = item[0];
+    if(argc < 1)
+    {
+        RLOGD("em_el1_start: please select page to show info");
+        android::emResultNotify(RET_STRING_LTE_FAIL);
+        return -1;
+    }
+
+    if (lte_info[intput_idx].name == "EL1") {
+        mItemCount = multicnt + 1;
+        RLOGD("mItemCount: %d, item[%d]: %d", mItemCount, multicnt, item[multicnt]);
+        android::registerForNetworkInfo(el1_urc_handle);
+    }
+
+    android::registerForATcmdResponse(el1_at_cmd_handle);
+    pthread_t emEl1_thread;
+    pthread_create(&emEl1_thread,NULL, emEl1Thread, NULL);
+    return (0);
+}
+#endif
+
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/em_antennatest.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/em_antennatest.cpp
new file mode 100755
index 0000000..d804a96
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/em_antennatest.cpp
@@ -0,0 +1,613 @@
+// 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 <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 MSG_QUERY_ANTENNA_EGMC_NR = 8;
+static const int MSG_SET_ANTENNA_EGMC_NR = 9;
+
+static const int MODE_INDEX_BASE_3G = 10;
+static const int MODE_INDEX_BASE_2G = 20;
+static const int MODE_EPCM_VALID = 0xFF;
+static const int CELL_2RX_LENGTH = 2;
+static const int CELL_4RX_LENGTH = 4;
+
+static int RAT_4G  = 0;
+#ifdef C2K_SUPPORT
+static int RAT_3G  = 1;
+static int RAT_C2K = 2;
+static int RAT_NR  = 3;
+#else
+static int RAT_3G  = -1;
+static int RAT_C2K = -1;
+static int RAT_NR  = 1;
+#endif
+
+static const std::string CMD_INIT_EGMC_4G = "AT+EGMC=1,\"rx_path\",1,0,3,15,3,15";
+static const std::string CMD_SET_EGMC_4G = "AT+EGMC=1,\"rx_path\"";
+static const std::string CMD_SET_EGMC_NR = "AT+EGMC=1,\"nr_rx_path\"";
+static const std::string CMD_SAME_EGMC = "+EGMC:";
+
+int mCurrentEmantennaFlag = 0;
+bool fgAntennaRead = true;
+int mAntennaMode = 0;
+char antennaretstring[128] = {0};
+int inputRat = -1;
+std::vector<int> gEgmcParam;
+
+static const std::vector<std::string> antenna_modes_egmc_4rx {
+    "None",             // 0
+    "RX1",              // 1
+    "RX2",              // 2
+    "RX1&RX2",          // 3
+    "RX3",              // 4
+    "RX1&RX3",          // 5
+    "RX2&RX3",          // 6
+    "RX1&RX2&RX3",      // 7
+    "RX4",              // 8
+    "RX1&RX4",          // 9
+    "RX2&RX4",          // 10
+    "RX1&RX2&RX4",      // 11
+    "RX3&RX4",          // 12
+    "RX1&RX3&RX4",      // 13
+    "RX2&RX3&RX4",      // 14
+    "RX1&RX2&RX3&RX4",  // 15
+};
+
+static const std::vector<std::string> antenna_modes_egmc_2rx {
+    "None",
+    "RX1",
+    "RX2",
+    "RX1&RX2",
+};
+
+static const std::vector<std::string> antenna_modes_4g {
+    "RX1&RX2",
+    "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 queryEgmcAntNR() {
+    char cmd_str[32] = {0};
+    sprintf(cmd_str,"%s","AT+EGMC=0,\"nr_rx_path\"");
+    sendATCommand(cmd_str, MSG_QUERY_ANTENNA_EGMC_NR);
+}
+
+static void queryEgmcAnt4G() {
+    char cmd_str[32] = {0};
+    sprintf(cmd_str,"%s","AT+EGMC=0,\"rx_path\"");
+    sendATCommand(cmd_str, MSG_QUERY_ANTENNA_EGMC_4G);
+}
+
+static void queryCurrentMode() {
+    char cmd_str[32] = {0};
+    sprintf(cmd_str,"%s","AT+ERXPATH?");
+    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 initEgmcAnt4G() {
+    sendATCommand(CMD_INIT_EGMC_4G.c_str(), MSG_INIT_ANTENNA_EGMC_4G);
+}
+
+static void setEgmcAnt4G(int force_mode, int scc_follow_pcc, int pcell_2rx, int pcell_4rx, int scell_2rx, int scell_4rx) {
+    char cmd_str[64] = {0};
+    sprintf(cmd_str,"%s,%d,%d,%d,%d,%d,%d",
+        CMD_SET_EGMC_4G.c_str(), force_mode, scc_follow_pcc, pcell_2rx, pcell_4rx, scell_2rx, scell_4rx);
+    RLOGD("setEgmcAnt4G, cmd:%s", cmd_str);
+    sendATCommand(cmd_str, MSG_SET_ANTENNA_EGMC_4G);
+}
+
+static void setEgmcAntNR(int force_mode, int scc_follow_pcc, int pcell_2rx, int pcell_4rx, int scell_2rx, int scell_4rx) {
+    char cmd_str[64] = {0};
+    sprintf(cmd_str,"%s,%d,%d,%d,%d,%d,%d",
+        CMD_SET_EGMC_NR.c_str(), force_mode, scc_follow_pcc, pcell_2rx, pcell_4rx, scell_2rx, scell_4rx);
+    RLOGD("setEgmcAntNR, cmd:%s", cmd_str);
+    sendATCommand(cmd_str, MSG_SET_ANTENNA_EGMC_NR);
+}
+
+static void setMode(int mode) {
+    char cmd_str[32] = {0};
+    sprintf(cmd_str,"%s%d","AT+ERXPATH=",mode);
+    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 parseEgmcData(char* data) {
+    RLOGD("parseEGMCData(rat=%d), data=%s", inputRat, data);
+    std::vector<std::string> out;
+    utils::tokenize(string(data), "\n", out);
+    std::string str;
+    str.clear();
+
+    // 4G response: +EGMC: "rx_path",1,0,3,15,3,12
+    // NR response: +EGMC: "nr_rx_path",3,15,3,12
+    for(auto i: out) {
+        if(i.find(CMD_SAME_EGMC) != std::string::npos) {
+            std::string splitString = i.substr(std::string(CMD_SAME_EGMC).size());
+            std::vector<std::string> getDigitalVal;
+            utils::tokenize(string(splitString), ",\n", getDigitalVal);
+            RLOGD("parseCurrentMode splitString: %s, getDigitalVal.size()=%d",
+                    splitString.c_str(), getDigitalVal.size());
+
+            if (getDigitalVal.size() < 5 &&
+                !((inputRat == RAT_NR) && getDigitalVal.size() == 1)) {
+                android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
+                RLOGD("Modem returned invalid getDigitalVal(%d): %s", getDigitalVal.size(), data);
+                return ;
+            }
+
+            try {
+                int idx_pcell_2rx = 3;
+                // Show result
+                if (inputRat == RAT_4G) {
+                    str.append("4G:");
+
+                } else if (inputRat == RAT_NR){
+                    str.append("NR:");
+                    idx_pcell_2rx = 1;
+                }
+
+                int pcell_2rx = 0, pcell_4rx = 0, scell_2rx = 0, scell_4rx = 0;
+                if ((inputRat == RAT_NR) && (getDigitalVal.size() == 1)) {
+                    pcell_2rx = 0;
+                    pcell_4rx = 0;
+                    scell_2rx = 0;
+                    scell_4rx = 0;
+
+                } else {
+                    pcell_2rx = std::stoi(getDigitalVal[idx_pcell_2rx]);
+                    pcell_4rx = std::stoi(getDigitalVal[++idx_pcell_2rx]);
+                    scell_2rx = std::stoi(getDigitalVal[++idx_pcell_2rx]);
+                    scell_4rx = std::stoi(getDigitalVal[++idx_pcell_2rx]);
+                }
+
+                RLOGD("pcell_2rx=%d, pcell_4rx=%d, scell_2rx=%d, scell_4rx=%d",
+                        pcell_2rx, pcell_4rx, scell_2rx, scell_4rx);
+
+                if (pcell_2rx >= 0 && pcell_2rx < antenna_modes_egmc_2rx.size()) {
+                    str.append("\npcell_2rx: ");
+                    str.append(antenna_modes_egmc_2rx[pcell_2rx]);
+                }
+                if (pcell_4rx >= 0 && pcell_4rx < antenna_modes_egmc_4rx.size()) {
+                    str.append("\npcell_4rx: ");
+                    str.append(antenna_modes_egmc_4rx[pcell_4rx]);
+                }
+                if (scell_2rx >= 0 && scell_2rx < antenna_modes_egmc_2rx.size()) {
+                    str.append("\nscell_2rx: ");
+                    str.append(antenna_modes_egmc_2rx[scell_2rx]);
+                }
+                if (scell_4rx >= 0 && scell_4rx < antenna_modes_egmc_4rx.size()) {
+                    str.append("\nscell_4rx: ");
+                    str.append(antenna_modes_egmc_4rx[scell_4rx]);
+                }
+
+            } catch (const out_of_range &e) {
+                android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
+                RLOGD("out of range: %s", e.what());
+                return;
+            } catch (const invalid_argument &e) {
+                android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
+                RLOGD("invalid argument: %s", e.what());
+                return;
+            }
+        }
+    }
+
+    str.append("\ndone\n");
+    RLOGD("result str=%s", str.c_str());
+    android::emResultNotify(str.c_str());
+}
+
+static void parseCurrentMode(char* data) {
+    RLOGD("parseCurrentMode(rat=%d), rsp=%s", inputRat, data);
+    std::vector<std::string> out;
+    utils::tokenize(string(data), "\n", out);
+    std::string str;
+    str.clear();
+
+    if((inputRat == RAT_4G && !utils::is97Modem())|| inputRat == RAT_3G) {
+        for(auto i: out) {
+            if(i.find("+ERXPATH:") != std::string::npos) {
+                try {
+                    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("Antenna test EPCM(255)\ndone\n");
+                        } else if (mode >= MODE_INDEX_BASE_2G) {
+                            RLOGD("Modem 2G mode (%d): %s",mode);
+                        } else if (mode >= MODE_INDEX_BASE_3G) {
+                            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 {
+                            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 (inputRat == RAT_C2K) {
+        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 if (inputRat == RAT_4G && utils::is97Modem()) {
+        parseEgmcData(data);
+
+    } else if(inputRat == RAT_NR) {
+        parseEgmcData(data);
+
+    } else {
+        RLOGE("error choose!!!");
+        android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
+    }
+    return;
+}
+
+
+static void emAntennaAtCmdHandle(char*response, int responselen) {
+    switch (mCurrentEmantennaFlag) {
+    case MSG_QUERY_ANTENNA_MODE:
+    case MSG_QUERY_ANTENNA_MODE_C2K:
+    case MSG_QUERY_ANTENNA_EGMC_4G:
+    case MSG_QUERY_ANTENNA_EGMC_NR:
+        //parse antenna mode.
+        if ((responselen > 0) && (response != NULL)) {
+            RLOGD("Get response %s", response);
+            parseCurrentMode(response);
+        } else {
+            RLOGD("Query antenna mode (rat=%d) failed.", inputRat);
+            sprintf(antennaretstring, "%s%s (rat=%d)", ("Query antenna mode failed."),
+            RET_STRING_ANTENNATEST_FAIL, inputRat);
+            android::emResultNotify(antennaretstring);
+        }
+        android::unregisterNetwork();
+        break;
+    case MSG_INIT_ANTENNA_EGMC_4G:
+        if ((responselen > 0) && (response != NULL)) {
+            setEgmcAnt4G(gEgmcParam[0], gEgmcParam[1], gEgmcParam[2], gEgmcParam[3], gEgmcParam[4], gEgmcParam[5]);
+
+        } else {
+            RLOGD("Init EGMC antenna mode (rat=%d) failed.", inputRat);
+            sprintf(antennaretstring, "%s%s (rat=%d)", ("Init antenna mode failed."),
+            RET_STRING_ANTENNATEST_FAIL, inputRat);
+            android::emResultNotify(antennaretstring);
+        }
+
+        break;
+    case MSG_SET_ANTENNA_MODE:
+    case MSG_SET_ANTENNA_EGMC_4G:
+    case MSG_SET_ANTENNA_EGMC_NR:
+        memset(antennaretstring, 0, sizeof(antennaretstring));
+        if ((responselen > 0) && (response != NULL)) {
+            RLOGD("Set successful.");
+            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::emResultNotify(antennaretstring);
+        break;
+    default:
+        RLOGD("error(%d)", mCurrentEmantennaFlag);
+        break;
+    }
+}
+
+
+//create thread to send command
+static void * emAntennaTestThread(void* arg)
+{
+    if(fgAntennaRead){
+        if(inputRat == RAT_4G) {
+            if (ModemCategory::isLteSupport()) {
+                if(utils::is97Modem()) {
+                    queryEgmcAnt4G();
+
+                } else {
+                    queryCurrentMode();
+                }
+
+            } else {
+                android::emResultNotify("Antenna test don't support for 4G \ndone\n");
+            }
+
+        } else if (inputRat == RAT_3G){
+            if (ModemCategory::getModemType() == ModemCategory::MODEM_TD) {
+                android::emResultNotify("Antenna test don't support for 3G \ndone\n");
+            } else {
+                queryCurrentMode();
+            }
+
+        } else if (inputRat == RAT_C2K) {
+            if(ModemCategory::isCdma()) {
+                queryCurrentCdmaMode();
+            } else {
+                android::emResultNotify("Antenna test don't support for C2K \ndone\n");
+            }
+
+        } else if(inputRat == RAT_NR) {
+            if (ModemCategory::isNrSupport()) {
+                queryEgmcAntNR();
+            } else {
+                android::emResultNotify("Antenna test don't support for NR \ndone\n");
+            }
+
+        } else {
+            android::emResultNotify("Antenna test index error \ndone\n");
+        }
+
+    }else{
+        if(inputRat == RAT_4G) {
+            if (ModemCategory::isLteSupport()) {
+                if(utils::is97Modem()) {
+                    initEgmcAnt4G();
+                } else {
+                    setMode(mAntennaMode);
+                }
+            } else {
+                android::emResultNotify("Antenna test don't support for 4G \ndone\n");
+            }
+        } else if (inputRat == RAT_3G){
+            if (ModemCategory::getModemType() == ModemCategory::MODEM_TD) {
+                android::emResultNotify("Antenna test don't support for 3G \ndone\n");
+            } else {
+                setMode(mAntennaMode);
+            }
+        } else if (inputRat == RAT_C2K) {
+            if(ModemCategory::isCdma()) {
+                setCdmaMode(mAntennaMode);
+            } else {
+                android::emResultNotify("Antenna test don't support for C2K \ndone\n");
+            }
+        } else if(inputRat == RAT_NR) {
+            if (ModemCategory::isNrSupport() && gEgmcParam.size() == 6) {
+                setEgmcAntNR(gEgmcParam[0], gEgmcParam[1], gEgmcParam[2], gEgmcParam[3], gEgmcParam[4], gEgmcParam[5]);
+            } else {
+                RLOGE("Antenna test don't support for NR or gEgmcParam size=%d", gEgmcParam.size());
+                android::emResultNotify("Antenna test don't support for NR \ndone\n");
+            }
+
+        } else {
+            android::emResultNotify("Antenna test index error \ndone\n");
+        }
+    }
+    pthread_exit(0);
+}
+
+bool handleInputValue(int multilen, char *value[])
+{
+    if (multilen != 6) {
+        RLOGE("error input parameter");
+        android::emResultNotify("Antenna test parameter error, must count=6 \ndone\n");
+        printf("Please reference AT+EGMC = 1,\"rx_path\"[,<force mode>,<scc follow pcc>,<pcell_2rx>,<pcell_4rx>,<scell_2rx>,<scell_4rx>]\n");
+        printf("Example: 2 1 0 3 15 3 12\n");
+        return false;
+    }
+
+    for(int i=0; i< multilen; i++) {
+        printf("value[%d]=%d\n", i, atoi(value[i]));
+        gEgmcParam.push_back(atoi(value[i]));
+    }
+    return true;
+}
+
+int emAntennaTestStart(int argc, int *item, int multilen,char *value[])
+{
+    RLOGD("emAntennaTestStart called");
+    if(argc < 2){
+        RLOGD("please select AntennaTest get or set :");
+        return -1;
+    }
+
+    mCurrentEmantennaFlag = 0;
+    gEgmcParam.clear();
+    inputRat = item[0];
+    int operatorid = item[1];
+    bool ret = false;
+
+    RLOGD("argc: %d, inputRat: %d, operatorid: %d\n", argc, inputRat, operatorid);
+
+    if((inputRat != RAT_NR) && (inputRat != RAT_4G) && (inputRat != RAT_3G)
+#ifdef C2K_SUPPORT
+        && (inputRat != RAT_C2K)
+#endif
+        ){
+        RLOGD("emAntennaTestStart: invalid inputRat %d, operatorid: %d", inputRat, operatorid);
+        android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
+        return -1;
+    }
+
+    switch(operatorid){
+        case 0://get
+        {
+            fgAntennaRead = true;
+            break;
+        }
+        case 1://set
+        {
+            printf("argc: %d, inputRat: %d, multilen: %d\n", argc, inputRat, multilen);
+
+            if(inputRat == RAT_4G){
+                if(utils::is97Modem()) {
+                    if(!handleInputValue(multilen, value)) {
+                        return (0);
+                    }
+
+                } else {
+                    printf("itme[2]: %d\n", item[2]);
+                    mAntennaMode = item[2];
+                }
+
+            } else if(inputRat == RAT_3G) {
+                mAntennaMode = item[2]+ MODE_INDEX_BASE_3G;
+
+            } else if (inputRat == RAT_C2K) {
+                mAntennaMode = item[2];
+
+            } else if(inputRat == RAT_NR){
+                if(!handleInputValue(multilen, value)) {
+                    return (0);
+                }
+
+            } else {
+                RLOGE("error input rat");
+                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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/em_bandmode.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/em_bandmode.cpp
new file mode 100755
index 0000000..9fecc19
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/em_bandmode.cpp
@@ -0,0 +1,1257 @@
+// 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 <pthread.h>
+#include <vendor-ril/telephony/ril.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <algorithm>
+#include <cutils/jstring.h>
+#include <log/log.h>
+#include <unistd.h>
+#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 INDEX_NR_BAND = 12;
+static const int BAND_SET_INVALID = 1000;
+static int mSimType = -1;
+
+static const int NR_VALUES = 3;
+
+/** GSM mode bit. */
+static const int GSM_EGSM900_BIT = 1;
+static const int GSM_DCS1800_BIT = 3;
+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_GSM = 100;
+static const int EVENT_QUERY_CURRENT_GSM = 101;
+static const int EVENT_QUERY_CURRENT_CDMA = 102;
+static const int EVENT_QUERY_SUPPORTED_NR = 103;
+static const int EVENT_QUERY_CURRENT_NR = 104;
+
+static const int EVENT_SET_GSM = 110;
+static const int EVENT_SET_CDMA = 111;
+static const int EVENT_SET_NR = 112;
+
+static const int EVENT_SET_FAIL = 1;
+static const int EVENT_RESET = 2;
+
+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 std::string QUERY_CURRENT_COMMAND_CDMA = "AT+ECBANDCFG?";
+static const std::string SET_COMMAND_CDMA = "AT+ECBANDCFG=";
+static const std::string SAME_COMMAND_CDMA = "+ECBANDCFG:";
+
+static const std::string QUERY_SUPPORT_COMMAND_NR = "AT+EPBSEH=?";
+static const std::string QUERY_CURRENT_COMMAND_NR = "AT+EPBSEH?";
+static const std::string SET_COMMAND_NR = "AT+EPBSEH=";
+static const std::string SAME_COMMAND_NR = "+EPBSEH:";
+
+static pthread_mutex_t s_band_Mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t s_band_Cond = PTHREAD_COND_INITIALIZER;
+#define BLOCK_LOCK() pthread_mutex_lock(&s_band_Mutex)
+#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);
+std::vector<long> nrValues(NR_VALUES);
+
+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> mGsmModeArray;
+static std::vector<BandModeMap> mCdmaModeArray;
+static std::vector<BandModeMap> mNRModeArray;
+
+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", "Band 45",
+        "Band 46", "Band 47", "Band 48", "Band 49", "Band 50",
+        "Band 51", "Band 52", "Band 53"};
+
+static const std::vector<std::string> band_mode_lte_96 { "Band 65", "Band 66",
+        "Band 67", "Band 68", "Band 69", "Band 70", "Band 71", "Band 72",
+        "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)" };
+
+static const std::vector<std::string> band_mode_nr {
+        "Band 1",  "Band 2",  "Band 3",  "Band 4",  "Band 5",
+        "Band 6",  "Band 7",  "Band 8",  "Band 9",  "Band 10",
+        "Band 11", "Band 12", "Band 13", "Band 14", "Band 15",
+        "Band 16", "Band 17", "Band 18", "Band 19", "Band 20",
+        "Band 21", "Band 22", "Band 23", "Band 24", "Band 25",
+        "Band 26", "Band 27", "Band 28", "Band 29", "Band 30",
+        "Band 31", "Band 32", "Band 33", "Band 34", "Band 35",
+        "Band 36", "Band 37", "Band 38", "Band 39", "Band 40",
+        "Band 41", "Band 42", "Band 43", "Band 44", "Band 45",
+        "Band 46", "Band 47", "Band 48", "Band 49", "Band 50",
+        "Band 51", "Band 52", "Band 53", "Band 54", "Band 55",
+        "Band 56", "Band 57", "Band 58", "Band 59", "Band 60",
+        "Band 61", "Band 62", "Band 63", "Band 64", "Band 65",
+        "Band 66", "Band 67", "Band 68", "Band 69", "Band 70",
+        "Band 71", "Band 72", "Band 73", "Band 74", "Band 75",
+        "Band 76", "Band 77", "Band 78", "Band 79", "Band 80",
+        "Band 81", "Band 82", "Band 83", "Band 84", "Band 85",
+        "Band 86", "Band 87", "Band 88", "Band 89", "Band 90",
+        "Band 91", "Band 92", "Band 93", "Band 94", "Band 95",
+        "Band 96"};
+
+bool fgset = false;
+bool isNR = false;
+
+int len_count = -1;
+std::vector<std::string> choose_vals;
+
+static void sendATCommand(const char *cmd,int msg)
+{
+    BLOCK_LOCK();
+    mCurrentEmbandmodeFlag = msg;
+    emSendATCommand(cmd,mSimType);
+    RLOGD("sendATCommand: wait start");
+    BLOCK_WAIT();
+    RLOGD("sendATCommand: wait end");
+    BLOCK_UNLOCK();
+    return ;
+}
+
+static void setCurrentModeGsm(std::vector<long> values) {
+    for (auto& m : mGsmModeArray) {
+        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 setSupportedModeGsm(std::vector<long> values) {
+    for (auto& m : mGsmModeArray) {
+        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 setCurrentModeNR(std::vector<long> values) {
+    int temp = 0;
+    for (auto& m : mNRModeArray) {
+        if (m.mBit < 32) {
+            if ((values[0] & (1L << m.mBit)) == 0) {
+                m.mCheck = false;
+            } else {
+                if (m.mEnable) {
+                    m.mCheck = true;
+                }
+            }
+        } else if (m.mBit < 64) {
+            temp = m.mBit - 32;
+            if ((values[1] & (1L << temp)) == 0) {
+                m.mCheck = false;
+            } else {
+                if (m.mEnable) {
+                    m.mCheck = true;
+                }
+            }
+        } else {
+            temp = m.mBit - 64;
+            if ((values[2] & (1L << temp)) == 0) {
+                m.mCheck = false;
+            } else {
+                if (m.mEnable) {
+                    m.mCheck = true;
+                }
+            }
+        }
+        //RLOGD("setCurrentModeNR labels: %s, enable: %d, check: %d", m.mName.c_str(), m.mEnable, m.mCheck);
+    }
+}
+
+static void setSupportedModeNR(std::vector<long> values) {
+    int temp = 0;
+    for (auto& m : mNRModeArray) {
+        if (m.mBit < 32) {
+            if ((values[0] & (1L << m.mBit)) == 0) {
+                m.mEnable = false;
+            } else {
+                m.mEnable = true;
+            }
+        } else if (m.mBit < 64) {
+            temp = m.mBit - 32;
+            if ((values[1] & (1L << temp)) == 0) {
+                m.mEnable = false;
+            } else {
+                m.mEnable = true;
+            }
+        } else {
+            temp = m.mBit - 64;
+            if ((values[2] & (1L << temp)) == 0) {
+                m.mEnable = false;
+            } else {
+                m.mEnable = true;
+            }
+        }
+        //RLOGD("setSupportedModeNR labels: %s, enable: %d", m.mName.c_str(), m.mEnable);
+    }
+}
+
+static void showBandModeCdma(char* response, int msg) {
+    std::vector<std::string> out;
+    utils::tokenize(string(response), "\n", out);
+    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) {
+    // Support/Current: +EPBSE: 154,262331,2316241119,482,0,0,0,0,0,0
+    std::vector<std::string> out;
+    utils::tokenize(string(response), "\n", out);
+    for(auto i: out) {
+        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_GSM) {
+                    setSupportedModeGsm(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 {
+                    setCurrentModeGsm(values);
+                }
+            } else {
+                android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+                RLOGD("getDigitalVal is null");
+            }
+        }
+    }
+}
+
+static void showBandModeNR(char* response, int msg) {
+   // Support: +EPBSEH: "0000009a","000400bb","8A0F08DF000001E200000000","080800D50000012000007000"
+   // Current: +EPBSEH: "0000009a","000400bb","8A0F08DF000001E200000000","080800D50000012000007000"^M OK^M
+   std::vector<std::string> out;
+   utils::tokenize(string(response), "\n", out);
+   for(auto i: out) {
+       if(i.find(SAME_COMMAND_NR) != std::string::npos) {
+           std::string splitString = i.substr(std::string(SAME_COMMAND_NR).size());
+           RLOGD("showBandModeNR splitString: %s", splitString.c_str());
+           std::vector<std::string> getDigitalVal;
+           utils::tokenize(string(splitString), ",\n", getDigitalVal);
+           if (getDigitalVal.size() > 0) {
+               getDigitalVal[3].erase(remove(getDigitalVal[3].begin(), getDigitalVal[3].end(),'\"'));
+               std::string info = utils::addZeroForNum(string(getDigitalVal[3]), 24);
+               RLOGD("showBandModeNR tmpInfo=%s, info=%s", getDigitalVal[3].c_str(), info.c_str());
+
+               std::string string1 = info.substr(0, 8);
+               std::string string2 = info.substr(8, 8);
+               std::string string3 = info.substr(16, 8);
+
+               RLOGD("showBandModeNR string1=%s, string2=%s, string3=%s,",
+                       string1.c_str(), string2.c_str(), string3.c_str());
+
+               std::vector<long> values;
+               try {
+                   values.push_back(std::stol(string1, 0 ,16));
+                   values.push_back(std::stol(string2, 0 ,16));
+                   values.push_back(std::stol(string3, 0 ,16));
+
+                   RLOGD("showBandModeNR values[0]=%ld, values[1]=%ld, values[2]=%ld,",
+                           values[0], values[1], values[2]);
+
+               } catch (const out_of_range &e) {
+                   values.push_back(0);
+                   RLOGD("out of range: %s", e.what());
+               } catch (const invalid_argument &e) {
+                   values.push_back(0);
+                   RLOGD("invalid argument: %s", e.what());
+               }
+
+               if (msg == EVENT_QUERY_SUPPORTED_NR) {
+                   setSupportedModeNR(values);
+               } else {
+                   setCurrentModeNR(values);
+               }
+
+           } else {
+               android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+               RLOGD("getDigitalVal is null");
+           }
+       }
+   }
+}
+
+static void printGetBand(int flag) {
+    RLOGD("printGetBand(%d), fgset(%d)", flag, fgset);
+
+    if(fgset) {
+        return;
+    }
+    if(flag == EVENT_QUERY_CURRENT_GSM) {
+        RLOGD("printGetBand GSM start");
+        std::string msg;
+        for (auto& i : mGsmModeArray) {
+            if (i.mEnable && i.mCheck) {
+                if ((i.mIndex == INDEX_GSM_BAND) && (msg.find("GSM Mode:") == std::string::npos)) {
+                    msg.append("GSM Mode:\n");
+                } 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");
+            }
+        }
+
+        if (ModemCategory::isCdma()) {
+            for (auto& i : mCdmaModeArray) {
+                if (i.mEnable && i.mCheck) {
+                    if ((i.mIndex == INDEX_CDMA_BAND) && (msg.find("CDMA Mode:") == std::string::npos)) {
+                        msg.append("\nCDMA Mode: \n");
+                    }
+                    msg.append("....");
+                    msg.append(i.mName);
+                    msg.append("\n");
+                }
+            }
+        }
+
+        msg.append("done\n");
+        android::emResultNotify(msg.c_str());
+
+    } else if (flag == EVENT_QUERY_CURRENT_NR) {
+        RLOGD("printGetBand NR start");
+        std::string msg;
+        for (auto& i : mNRModeArray) {
+            if (i.mEnable && i.mCheck) {
+                if ((i.mIndex == INDEX_NR_BAND) && (msg.find("NR Mode:") == std::string::npos)) {
+                    msg.append("\nNR Mode:\n");
+                }
+                msg.append("....");
+                msg.append(i.mName);
+                msg.append("\n");
+            }
+        }
+
+        msg.append("done\n");
+        android::emResultNotify(msg.c_str());
+    }
+}
+
+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);
+}
+
+static void setBandModeNR(std::vector<long> values_gsm, std::vector<long> values_nr) {
+    RLOGD("setBandModeNR gsmValues: %ld,%ld,%ld,%ld,%ld",
+            values_gsm[0],values_gsm[1],values_gsm[2],values_gsm[3],values_gsm[4]);
+    RLOGD("setBandModeNR nrValues: %ld,%ld,%ld",
+            values_nr[0],values_nr[1],values_nr[2]);
+
+    char cmd_str[1280] = {0};
+    sprintf(cmd_str,"%s\"%08x\",\"%08x\",\"%08x%08x%08x\",\"%08x%08x%08x\"",
+            SET_COMMAND_NR,
+            values_gsm[0], values_gsm[1],
+            values_gsm[2], values_gsm[3], values_gsm[4],
+            values_nr[0],  values_nr[1],  values_nr[2]);
+
+    RLOGD("setBandModeNR AT String:%s", cmd_str);
+    sendATCommand(cmd_str, EVENT_SET_NR);
+}
+
+/**
+ * Set the selected modes.
+ *
+ * @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> getValFromBoxGsm(bool judge) {
+    std::vector<long> values(INDEX_BAND_MAX,0);
+    std::vector<long> values_temp(INDEX_BAND_MAX,0);
+    for (auto& m : mGsmModeArray) {
+        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;
+}
+
+/**
+ * Get the selected mode values.
+ *
+ * @return values from the selected boxes
+ */
+static std::vector<long> getValFromBoxNR() {
+    std::vector<long> values(NR_VALUES,0);
+
+    int temp = 0;
+    for (auto& m : mNRModeArray) {
+        if (m.mBit < 32) {
+            if (m.mCheck) {
+                values[0] |= 1L << m.mBit;
+            }
+        } else if (m.mBit < 64) {
+            temp = m.mBit - 32;
+            if (m.mCheck) {
+                values[1] |= 1L << temp;
+            }
+        } else {
+            temp = m.mBit - 64;
+            if (m.mCheck) {
+                values[2] |= 1L << temp;
+            }
+        }
+    }
+
+    RLOGD("getValFromBoxNR values[0]=%ld, values[1]=%ld, values[2]=%ld,",
+            values[0], values[1], values[2]);
+    return values;
+}
+
+static void printSupportBand(int flag) {
+    RLOGD("printSupportBand, fgset(%d), len_count(%d), flag(%d)",fgset, len_count, flag);
+    if(fgset && (len_count == 0) && (flag == EVENT_QUERY_CURRENT_GSM)) {
+        RLOGD("printSupportBand GSM start");
+        std::string msg;
+        for (auto& i : mGsmModeArray) {
+            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");
+            }
+        }
+
+        if (ModemCategory::isCdma()) {
+            for (auto& i : mCdmaModeArray) {
+                if (i.mEnable) {
+                    if ((i.mIndex == INDEX_CDMA_BAND) && (msg.find("CDMA Mode:") == std::string::npos)) {
+                        msg.append("\nCDMA Mode: \n");
+                    }
+                    msg.append("....");
+                    msg.append("(");
+                    msg.append(std::to_string(i.mIndex));
+                    msg.append(".");
+                    msg.append(std::to_string(i.mBit));
+                    msg.append("): ");
+                    msg.append(i.mName);
+                    msg.append("....");
+                    msg.append(i.mIndex ? "true":"false");
+                    msg.append("\n");
+                }
+            }
+        }
+
+        msg.append("done\n");
+        android::emResultNotify(msg.c_str());
+
+    } else if(fgset && (len_count == 0) && (flag == EVENT_QUERY_CURRENT_NR)) {
+        RLOGD("printSupportBand NR start");
+        std::string msg;
+        for (auto& i : mNRModeArray) {
+            if (i.mEnable) {
+                if ((i.mIndex == INDEX_NR_BAND) && (msg.find("NR Mode:") == std::string::npos)) {
+                    msg.append("\nNR Mode:\n");
+                }
+
+                msg.append("....");
+                msg.append("(");
+                msg.append(std::to_string(i.mIndex));
+                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");
+            }
+        }
+
+        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* setNRBandMode(void* arg) {
+    setBandModeNR(gsmValues, nrValues);
+    return NULL;
+}
+
+static void emBandmodeAtCmdHandle(char* response, int responselen) {
+    RLOGD("emBandmodeAtCmdHandle, mCurrentEmbandmodeFlag=%d, rsp=%s", mCurrentEmbandmodeFlag, response);
+    switch (mCurrentEmbandmodeFlag) {
+    case EVENT_QUERY_SUPPORTED_GSM:
+    {
+        if ((responselen > 0) && (response != NULL)) {
+            showBandModeGsm(response, EVENT_QUERY_SUPPORTED_GSM);
+        } else {
+            android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+            RLOGD("don't support(%d)", EVENT_QUERY_SUPPORTED_GSM);
+        }
+        BLOCK_WAKEUP();
+        break;
+    }
+    case EVENT_QUERY_SUPPORTED_NR:
+    {
+        if ((responselen > 0) && (response != NULL)) {
+            showBandModeNR(response, EVENT_QUERY_SUPPORTED_NR);
+        } else {
+            android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+            RLOGD("don't support(%d)", EVENT_QUERY_SUPPORTED_NR);
+        }
+        BLOCK_WAKEUP();
+        break;
+    }
+    case EVENT_QUERY_CURRENT_GSM:
+    {
+        if ((responselen > 0) && (response != NULL)) {
+            showBandModeGsm(response, EVENT_QUERY_CURRENT_GSM);
+        } else {
+            android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+            RLOGD("don't support(%d)", EVENT_QUERY_CURRENT_GSM);
+        }
+
+        if (!isNR) {
+            printGetBand(EVENT_QUERY_CURRENT_GSM);
+            printSupportBand(EVENT_QUERY_CURRENT_GSM);
+        }
+        BLOCK_WAKEUP();
+
+        if(fgset && !isNR && (len_count > 0)) {
+            for(auto& val : choose_vals) {
+                RLOGD("handle values: %s", val.c_str());
+                std::vector<std::string> out;
+                utils::tokenize(val, "=", out);
+                if(out.size() == 2) {
+                    std::vector<std::string> indexs;
+                    utils::tokenize(out[0], ".", indexs);
+                    if(indexs.size() == 2) {
+                        try {
+                            int index = std::stoi(indexs[0]);
+                            int bit = std::stoi(indexs[1]);
+                            bool check = std::stoi(out[1]) > 0 ? true : false;
+                            for (auto& i : mGsmModeArray) {
+                                if((i.mIndex == index) && (i.mBit == bit)) {
+                                    i.mCheck = check;
+                                    RLOGD("set gsm band: lales=%s, index=%d, bit=%d, enable=%d, check=%d",
+                                            i.mName.c_str(),i.mIndex, i.mBit, i.mEnable, i.mCheck);
+                                }
+                            }
+                            if (ModemCategory::isCdma()) {
+                                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;
+                }
+            }
+
+            if (ModemCategory::isCdma()) {
+                cdmaValues = getValFromBoxCdma();
+            }
+            gsmValues = getValFromBoxGsm(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_QUERY_CURRENT_NR:
+    {
+        if ((responselen > 0) && (response != NULL)) {
+            showBandModeNR(response, EVENT_QUERY_CURRENT_NR);
+        } else {
+            android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+            RLOGD("don't support(%d)", EVENT_QUERY_CURRENT_NR);
+        }
+
+        if (isNR) {
+            printGetBand(EVENT_QUERY_CURRENT_NR);
+            printSupportBand(EVENT_QUERY_CURRENT_NR);
+        }
+        BLOCK_WAKEUP();
+
+        if(fgset && isNR && (len_count > 0)) {
+            for(auto& val : choose_vals) {
+                RLOGD("handle values: %s", val.c_str());
+                std::vector<std::string> out;
+                utils::tokenize(val, "=", out);
+                if(out.size() == 2) {
+                    std::vector<std::string> indexs;
+                    utils::tokenize(out[0], ".", indexs);
+                    if(indexs.size() == 2) {
+                        try {
+                            int index = std::stoi(indexs[0]);
+                            int bit = std::stoi(indexs[1]);
+                            bool check = std::stoi(out[1]) > 0 ? true : false;
+                            for (auto& i : mNRModeArray) {
+                                if((i.mIndex == index) && (i.mBit == bit)) {
+                                    i.mCheck = check;
+                                    RLOGD("set NR band: lales=%s, index=%d, bit=%d, enable=%d, check=%d",
+                                            i.mName.c_str(),i.mIndex, i.mBit, i.mEnable, i.mCheck);
+                                }
+                            }
+                        } catch (const out_of_range &e) {
+                            RLOGD("out of range: %s", e.what());
+                        } catch (const invalid_argument &e) {
+                            RLOGD("invalid argument: %s", e.what());
+                        }
+                    }else {
+                        RLOGD("invalid parameters: %s", out[0].c_str());
+                        android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+                        return;
+                    }
+
+                } else {
+                    RLOGD("invalid parameters: %s", val.c_str());
+                    android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+                    return;
+                }
+            }
+            nrValues = getValFromBoxNR();
+            gsmValues = getValFromBoxGsm(true);
+            pthread_t setBandMode_thread;
+            pthread_create(&setBandMode_thread,NULL, setNRBandMode, NULL);
+        }
+
+        break;
+    }
+    case EVENT_SET_NR:
+    {
+        BLOCK_WAKEUP();
+        if ((responselen > 0) && (response != NULL)) {
+            RLOGD("Set NR bandmode success: %s", response);
+            android::emResultNotify(RET_STRING_BANDMODE_SUCCESS);
+        } else {
+            RLOGD("Set NR bandmode fail ");
+            android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+        }
+        break;
+    }
+    case EVENT_QUERY_CURRENT_CDMA: {
+        if ((responselen > 0) && (response != NULL)) {
+            showBandModeCdma(response, EVENT_QUERY_CURRENT_CDMA);
+        } else {
+            android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+            RLOGD("don't support(%d)", EVENT_QUERY_CURRENT_CDMA);
+        }
+        BLOCK_WAKEUP();
+        break;
+    }
+    case EVENT_SET_CDMA:
+    {
+        BLOCK_WAKEUP();
+        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 querySupportModeGSM() {
+    //SAME_COMMAND
+    RLOGD("querySupportModeGSM AT String: %s", QUERY_SUPPORT_COMMAND.c_str());
+    sendATCommand(QUERY_SUPPORT_COMMAND.c_str(), EVENT_QUERY_SUPPORTED_GSM);
+}
+
+/**
+ * Query Modem is being used band modes.
+ */
+static void queryCurrentModeGSM() {
+    //SAME_COMMAND
+    RLOGD("queryCurrentModeGSM AT String: %s", QUERY_CURRENT_COMMAND.c_str());
+    sendATCommand(QUERY_CURRENT_COMMAND.c_str(), EVENT_QUERY_CURRENT_GSM);
+}
+
+/**
+ * Query NR Modem supported band modes.
+ */
+static void querySupportModeNR() {
+    //SAME_COMMAND
+    RLOGD("querySupportModeNR AT String: %s", QUERY_SUPPORT_COMMAND_NR.c_str());
+    sendATCommand(QUERY_SUPPORT_COMMAND_NR.c_str(), EVENT_QUERY_SUPPORTED_NR);
+}
+
+/**
+ * Query NR Modem is being used band modes.
+ */
+static void queryCurrentModeNR() {
+    //SAME_COMMAND
+    RLOGD("queryCurrentModeNR AT String: %s", QUERY_CURRENT_COMMAND_NR.c_str());
+    sendATCommand(QUERY_CURRENT_COMMAND_NR.c_str(), EVENT_QUERY_CURRENT_NR);
+}
+
+static void initGsmArray() {
+    for (int i = 0; i < band_mode_gsm.size(); i++) {
+        mGsmModeArray.emplace_back(band_mode_gsm[i], INDEX_GSM_BAND, GSM_BAND_BIT[i], false, false);
+    }
+}
+
+static void initLteArray() {
+    for (int i = 0; i < band_mode_lte_fdd.size(); i++) {
+        mGsmModeArray.emplace_back(band_mode_lte_fdd[i], INDEX_LTE_FDD_BAND, i, false, false);
+    }
+    for (int i = 0; i < band_mode_lte_tdd.size(); i++) {
+        mGsmModeArray.emplace_back(band_mode_lte_tdd[i], INDEX_LTE_TDD_BAND, i, false, false);
+    }
+    for (int i = 0; i < band_mode_lte_96.size(); i++) {
+        mGsmModeArray.emplace_back(band_mode_lte_96[i], INDEX_LTE_BAND_96, i, false, false);
+    }
+    for (int i = 0; i < band_mode_lte_128.size(); i++) {
+        mGsmModeArray.emplace_back(band_mode_lte_128[i], INDEX_LTE_BAND_128, i, false, false);
+    }
+    for (int i = 0; i < band_mode_lte_160.size(); i++) {
+        mGsmModeArray.emplace_back(band_mode_lte_160[i], INDEX_LTE_BAND_160, i, false, false);
+    }
+    for (int i = 0; i < band_mode_lte_192.size(); i++) {
+        mGsmModeArray.emplace_back(band_mode_lte_192[i], INDEX_LTE_BAND_192, i, false, false);
+    }
+    for (int i = 0; i < band_mode_lte_224.size(); i++) {
+        mGsmModeArray.emplace_back(band_mode_lte_224[i], INDEX_LTE_BAND_224, i, false, false);
+    }
+    for (int i = 0; i < band_mode_lte_256.size(); i++) {
+        mGsmModeArray.emplace_back(band_mode_lte_256[i], INDEX_LTE_BAND_256, i, false, false);
+    }
+}
+
+static void initTdscdmaArray() {
+    for (int i = 0; i < band_mode_tdscdma.size(); i++) {
+        mGsmModeArray.emplace_back(band_mode_tdscdma[i], INDEX_UMTS_BAND, i, false, false);
+    }
+}
+
+static void initWcdmaArray() {
+    for (int i = 0; i < band_mode_wcdma.size(); i++) {
+        mGsmModeArray.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 initNRArray() {
+    for (int i = 0; i < band_mode_nr.size(); i++) {
+        mNRModeArray.emplace_back(band_mode_nr[i], INDEX_NR_BAND, i, false, false);
+    }
+}
+
+static void * emBandmodeThread(void* arg)
+{
+    mGsmModeArray.clear();
+    mCdmaModeArray.clear();
+    mNRModeArray.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();
+            }
+        }
+    }
+
+#ifdef C2K_SUPPORT
+    if (mSimType == 0 && ModemCategory::isCdma() && !utils::is90Modem()) {
+        initCdmaArray();
+    }
+    if (ModemCategory::isCdma() && !utils::is90Modem() && (mSimType == 0)) {
+        queryCurrentCdmaMode();
+    }
+#endif
+
+    querySupportModeGSM();
+    queryCurrentModeGSM();
+
+    if (utils::isMt2735()/* && ModemCategory.CheckViceSimNRCapability(mSimType)*/) {
+        initNRArray();
+        querySupportModeNR();
+        queryCurrentModeNR();
+    }
+
+    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, len=%d, item[0]=%d, multilen=%d",
+            mSimType, len, item[0], multilen);
+
+    //1. reset to default: select all supported bands: AT+EPBSE=255,63355
+    if(len < 1)
+    {
+        RLOGD("emBandmodeStart: please select mode to test: 0: get, 1: set ");
+        android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+        return -1;
+    }
+    if((item[0] > 2 ) || (item[0] < 0)){
+        RLOGD("emBandmodeStart: invalid parameter %d",item[0]);
+        android::emResultNotify(RET_STRING_BANDMODE_FAIL);
+        return -1;
+    }
+
+    int INDEX_GSM_GET=0, INDEX_GSM_SET=1, INDEX_NR_GET=2, INDEX_NR_SET=3;
+
+    // 1. Get current GSM band
+    if(item[0] == INDEX_GSM_GET){
+        fgset = false;
+        isNR = false;
+
+    // 2. Set GSM band
+    } else if(item[0] == INDEX_GSM_SET){
+        fgset = true;
+        isNR = false;
+
+        len_count = multilen;
+        RLOGD("emBandmodeStart count = %d", len_count);
+        choose_vals.clear();
+        if(len_count > 0){
+            for(int i=0; i< len_count; i++) {
+                choose_vals.push_back(value[i]);
+            }
+        }
+
+    // 3. Get current NR band
+    } else if(item[0] == INDEX_NR_GET){
+        fgset = false;
+        isNR = true;
+
+    // 4. Set NR band
+    } else if(item[0] == INDEX_NR_SET){
+        fgset = true;
+        isNR = true;
+
+        len_count = multilen;
+        RLOGD("emBandmodeStart count = %d", len_count);
+        choose_vals.clear();
+        if(len_count > 0){
+            for(int i=0; i< len_count; i++) {
+                choose_vals.push_back(value[i]);
+            }
+        }
+    }
+
+    mCurrentEmbandmodeFlag = 0;
+    android::registerForATcmdResponse(emBandmodeAtCmdHandle);
+    pthread_t embandmode_thread;
+    pthread_create(&embandmode_thread,NULL, emBandmodeThread, NULL);
+    return (0);
+}
+#endif
+
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/em_c2kmodemsetting.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/em_c2kmodemsetting.cpp
new file mode 100755
index 0000000..e577c39
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/em_cfu.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/em_cfu.cpp
new file mode 100755
index 0000000..7b382d8
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/em_el1_public_struct.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/em_el1_public_struct.h
new file mode 100755
index 0000000..1c44d29
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/em_hspa.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/em_hspa.cpp
new file mode 100755
index 0000000..0782990
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/em_hspa.cpp
@@ -0,0 +1,287 @@
+//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 <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",
+};
+
+char *ca_info_state_array[] = {
+    "0 CA_CONFIGURED: NW configure CA\n",
+    "1 CA_NOT_CONFIGURED: NW remove CA configuration or CA configured is invalid\n",
+    "2 CA_ACTIVATED: Lower layer use CA to transfer data\n",
+    "3 CA_DEACTIVATED: Lower layer does not use CA to transfer data\n",
+};
+
+const int EVENT_HSPA_INFO = 1;
+//const int EVENT_DC_HSPA_INFO = 2;
+const int EVENT_SET_HSPA = 3;
+const int EVENT_CA_INFO = 4;
+
+#define HSPA_QUERY_CMD "AT+EHSM?"
+#define HSPA_SET_CMD "AT+EHSM="
+#define HSPA_RESPONSE_CMD "+EHSM:"
+int mCurrentFlag = 0;
+int hspamode = 0;
+int intput_index = 0;
+
+#define ECAINFO_QUERY_CMD "AT+ECAINFO?"
+#define ECAINFO_RESPONSE_CMD "+ECAINFO:"
+
+void  sendATCommand_ehspa(const char *cmd,int msg)
+{
+    mCurrentFlag = msg;
+    emSendATCommand(cmd, Radio_capability_switch_util::get_main_capability_phone_id());
+    return ;
+}
+
+void showHspa(int mode) {
+    std::string str;
+    RLOGD("showHspa, mode=%d", mode);
+
+    if (mode < 0 || mode >= 4) {
+        RLOGD("Modem return invalid mode: %d", mode);
+        android::emResultNotify(RET_STRING_HSPA_FAIL);
+        return;
+    }
+    if (WorldPhoneUtil::getModemType() == WorldPhoneUtil::MODEM_TD) {
+        str = hspa_info_mode_array_td[mode];
+    } else {
+        str = hspa_info_mode_array_fd[mode];
+    }
+    str += "\ndone\n";
+    android::emResultNotify(str.c_str());
+}
+
+void parseHspaAtCmd(const char* line) {
+    if (strstr(line, HSPA_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");
+            delete atLine;
+            return;
+        }
+        int mode = atLine->atTokNextint(&err);
+        if (err < 0) {
+            RLOGW("parse rat fail");
+            delete atLine;
+            return;
+        }
+        showHspa(mode);
+        delete atLine;
+    }
+}
+
+void parseCAInfoAtCmd(const char* line) {
+    AtLine* atLine = new AtLine(line, NULL);
+    int err, ca_info, pcell_bw, scell_bw1, scell_bw2, scell_bw3, scell_bw4;
+    char cainfo_str[1024] = {0};
+
+    atLine->atTokStart(&err);
+    if (err < 0) {
+        RLOGW("this is not a valid response string");
+        goto invalid;
+    }
+
+    //+ECAINFO: <ca_info>,<pcell_bw>,<scell_bw1>, <scell_bw2>,<scell_bw3>,<scell_bw4>
+    ca_info = atLine->atTokNextint(&err);
+    if (err < 0) {
+        RLOGW("parse ca_info fail");
+        goto invalid;
+    }
+    if (ca_info < 0 || ca_info >= 4) {
+        RLOGW("ca_info return invalid state: %d", ca_info);
+        goto invalid;
+    }
+    pcell_bw = atLine->atTokNextint(&err);
+    if (err < 0) {
+        RLOGW("parse pcell_bw fail");
+        goto invalid;
+    }
+    scell_bw1 = atLine->atTokNextint(&err);
+    if (err < 0) {
+        RLOGW("parse scell_bw1 fail");
+        goto invalid;
+    }
+    scell_bw2 = atLine->atTokNextint(&err);
+    if (err < 0) {
+        RLOGW("parse scell_bw2 fail");
+        goto invalid;
+    }
+    scell_bw3 = atLine->atTokNextint(&err);
+    if (err < 0) {
+        RLOGW("parse scell_bw3 fail");
+        goto invalid;
+    }
+    scell_bw4= atLine->atTokNextint(&err);
+    if (err < 0) {
+        RLOGW("parse scell_bw4 fail");
+        goto invalid;
+    }
+
+    sprintf(cainfo_str, "\n%s\npcell_bw=%d\nscell_bw1=%d\nscell_bw2=%d\nscell_bw3=%d\nscell_bw4=%d\ndone\n",
+            ca_info_state_array[ca_info], pcell_bw, scell_bw1, scell_bw2, scell_bw3, scell_bw4);
+    android::emResultNotify(cainfo_str);
+    delete atLine;
+    return;
+
+invalid:
+    android::emResultNotify(RET_STRING_HSPA_FAIL);
+    delete atLine;
+}
+
+
+void emAtCmdHandle(char*response, int responselen) {
+    switch (mCurrentFlag) {
+        case EVENT_HSPA_INFO:
+        {
+            //parse hspa mode.
+            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;
+        }
+        case EVENT_CA_INFO:
+        {
+            if ((responselen > 0) && (response != NULL)) {
+                RLOGD("+ECAINFO response: %s\n",response);
+                parseCAInfoAtCmd(response);
+            }
+            else {
+                android::emResultNotify(RET_STRING_HSPA_FAIL);
+                RLOGD("send fail ");
+            }
+        }
+        default:
+            break;
+    }
+}
+
+
+//create thread to send command
+void * emHspaThread(void* arg)
+{
+    // HSPA
+    if (intput_index == 0) {
+        RLOGD("emHspaThread, query HSPA");
+
+        //char cmd_str[32] = {0};
+        //sprintf(cmd_str,"%s%d,0", HSPA_SET_CMD,hspamode);
+        //sendATCommand_ehspa(cmd_str,EVENT_SET_HSPA);
+        sendATCommand_ehspa(HSPA_QUERY_CMD,EVENT_HSPA_INFO);
+        //android::unregisterNetwork();
+        //android::emResultNotify(RET_STRING_HSPA_SUCCESS);
+
+    // Send AT+ECAINFO
+    } else if (intput_index == 1) {
+        RLOGD("emHspaThread, query CA information");
+        sendATCommand_ehspa(ECAINFO_QUERY_CMD, EVENT_CA_INFO);
+    }
+
+    pthread_exit(0);
+}
+
+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;
+    }
+
+    intput_index = item[0];
+    RLOGD("emHspaStart, intput_index=%d", intput_index);
+    if((intput_index > 1 ) || (intput_index < 0)){
+        RLOGD("emHspaStart: invalid parameter %d", intput_index);
+        android::emResultNotify(RET_STRING_HSPA_FAIL);
+        return -1;
+    }
+
+    //int modemapping[2] = {0,2};
+    mCurrentFlag = 0;
+    //hspamode = modemapping[item[0]];
+    android::registerForATcmdResponse(emAtCmdHandle);
+    pthread_t emhspa_thread;
+    pthread_create(&emhspa_thread,NULL, emHspaThread, NULL);
+    return (0);
+}
+#endif
+
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/em_ims.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/em_ims.cpp
new file mode 100755
index 0000000..048ffa9
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/em_modemtest.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/em_modemtest.cpp
new file mode 100755
index 0000000..ba4b5eb
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/em_modemtest.cpp
@@ -0,0 +1,500 @@
+// 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 <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 <thread>
+#include <chrono>
+
+#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);
+}
+#ifdef C2K_SUPPORT
+void setCdmaOption() {
+    if (modem_option[0] == INDEX_SPIRENT) {
+        sendATCommandCdma("\"SPIRENT\"", MODEM_CDMA);
+    } else {
+        sendATCommandCdma("\"NONE\"", MODEM_CDMA);
+    }
+}
+#endif
+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("checkNetworkType");
+    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) {
+    RLOGD("setGprsTransferType %d" ,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
+{
+    RLOGD("modemTestProcess id: %d, mCurrentMode: %d", id, mCurrentMode);
+    switch(id){
+        case MODEM_NONE:
+        {
+            RLOGD("modemTestProcess MODEM_NONE");
+            sendATCommand_modemtest("0", 0, MODEM_NONE);
+            if (mCurrentMode == MODEM_FTA) {
+                setGprsTransferType(PCH_CALL_PREFER);
+            }
+            break;
+        }
+        case MODEM_CTA:
+        {
+            RLOGD("modemTestProcess MODEM_CTA");
+            mCtaOption = 0;
+#ifndef TARGET_PLATFORM_MT2735
+            for(int i = 0; i < ButtonCount; i++){
+                mCtaOption += (1 << whichButton[i]);
+            }
+#endif
+            sendATCommand_modemtest("1", mCtaOption, MODEM_CTA);
+#ifndef TARGET_PLATFORM_MT2735
+            turnoffWCMAPreferred();
+#endif
+            if (mCurrentMode == MODEM_FTA) {
+                setGprsTransferType(PCH_CALL_PREFER);
+            }
+            break;
+        }
+        case MODEM_FTA:
+        {
+            RLOGD("modemTestProcess 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);
+#ifndef TARGET_PLATFORM_MT2735
+            turnoffWCMAPreferred();
+#endif
+            sendATCommand_modemtest("2", mFtaOption, MODEM_FTA);
+            //enableIPO(false);
+            setGprsTransferType(PCH_DATA_PREFER);
+            break;
+        }
+        case MODEM_IOT:
+        {
+            RLOGD("modemTestProcess 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:
+        {
+            RLOGD("modemTestProcess MODEM_OPERATOR");
+            mOperatorOption = 0;
+            for(int i = 0; i < ButtonCount; i++){
+                mOperatorOption += (1 << whichButton[i]);
+            }
+#ifndef TARGET_PLATFORM_MT2735
+            turnoffWCMAPreferred();
+#endif
+            attachOrDetachGprs();
+            sendATCommand_modemtest("4", mOperatorOption, MODEM_OPERATOR);
+            if (mCurrentMode == MODEM_FTA) {
+                setGprsTransferType(PCH_CALL_PREFER);
+            }
+            break;
+        }
+#ifdef C2K_SUPPORT
+        case MODEM_CDMA:
+        {
+            RLOGD("modemTestProcess MODEM_CDMA");
+            setCdmaOption();
+            break;
+        }
+#endif
+        case MODEM_FACTORY:
+        {
+            RLOGD("modemTestProcess MODEM_FACTORY");
+#ifndef TARGET_PLATFORM_MT2735
+            turnoffWCMAPreferred();
+#endif
+            sendATCommand_modemtest("5", 0, MODEM_FACTORY);
+            if (mCurrentMode == MODEM_FTA) {
+                setGprsTransferType(PCH_CALL_PREFER);
+            }
+            break;
+        }
+        default:
+            RLOGD("modemTestProcess default");
+            break;
+    }
+    return 0;
+}
+
+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) {
+    RLOGD("emModemtestAtCmdHandle mCurrentEmmodemtestFlag : %d",mCurrentEmmodemtestFlag);
+    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(int n)
+{
+    RLOGD("Modem Test wait 2s");
+    std::this_thread::sleep_for(std::chrono::seconds(2));
+    RLOGD("Modem Test: %s, ",getToastString(modem_id));
+    modemTestProcess(modem_id,modem_option,modem_option_cnt);
+    RLOGD("Modem Test: unregisterNetwork() ");
+    android::unregisterNetwork();
+    android::emResultNotify(RET_STRING_MODEMTEST_SUCCESS);
+    RLOGD("Modem Test done");
+}
+
+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_OPERATOR,MODEM_FACTORY, MODEM_CDMA};
+    RLOGD("emModemtestStart called item[0]: %d", item[0]);
+    modem_id = idmapping[item[0]];
+    modem_option_cnt = multicnt;
+    modem_option[0] = item[1];
+    RLOGD("emModemtestStart modem_option[0]: %d", item[1]);
+
+    for(int i = 0; i < modem_option_cnt ; i++){
+        modem_option[i+1] = item[2+i];
+        RLOGD("emModemtestStart modem_option[%d]: %d", 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) {
+#ifndef TARGET_PLATFORM_MT2735
+        setCurrentTestFlag(EVENT_QUERY_PREFERRED_TYPE_DONE);
+        checkNetworkType();
+#endif
+        std::this_thread::sleep_for(std::chrono::seconds(2));
+        sendATCommand_modemtest("AT+EPCT?",MODEM_QUERY);
+    }
+
+    std::thread em_modem_test(emModemtestThread, 0);
+    em_modem_test.join();
+    return (0);
+}
+#endif
+
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/networkinfo/Content.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/networkinfo/Content.cpp
new file mode 100755
index 0000000..b351b6e
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/networkinfo/Content.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/networkinfo/Content.h
new file mode 100755
index 0000000..a027aec
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/networkinfo/NetworkInfoUrcParser.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/networkinfo/NetworkInfoUrcParser.cpp
new file mode 100755
index 0000000..a9b3658
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/networkinfo/NetworkInfoUrcParser.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/networkinfo/NetworkInfoUrcParser.h
new file mode 100755
index 0000000..9842497
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseRatInfo.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseRatInfo.cpp
new file mode 100755
index 0000000..d9d3629
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseRatInfo.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseRatInfo.h
new file mode 100755
index 0000000..5bc106f
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTest.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTest.cpp
new file mode 100755
index 0000000..94afa42
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTest.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTest.cpp
new file mode 100755
index 0000000..1b08166
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTest.cpp
@@ -0,0 +1,1648 @@
+//SPDX-License-Identifier: MediaTekProprietary
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include "rfdesense/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 "rfdesense/RfDesenseTxTestNr.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_CONTINUE_TX = 2;
+const int RfDesenseTxTest::MSG_NEXT_RAT = 4;
+const int RfDesenseTxTest::MSG_READ_POWER = 10;
+const int RfDesenseTxTest::MSG_EWMPOLICY_TDSCDMA = 12;
+const int RfDesenseTxTest::MSG_EWMPOLICY_WCDMA = 13;
+const int RfDesenseTxTest::MSG_ECSRA = 14;
+const int RfDesenseTxTest::MSG_SWITCH_RAT_DONE = 15;
+const int RfDesenseTxTest::MSG_NR_READ_POWER = 20;
+
+int RfDesenseTxTest::INDEX_GSM = -1;
+int RfDesenseTxTest::INDEX_TDSCDMA = -1;
+int RfDesenseTxTest::INDEX_WCDMA = -1;
+int RfDesenseTxTest::INDEX_LTE_FDD = -1;
+int RfDesenseTxTest::INDEX_LTE_TDD = -1;
+int RfDesenseTxTest::INDEX_NR = -1;
+int RfDesenseTxTest::INDEX_CDMA_EVDO = -1;
+int RfDesenseTxTest::INDEX_CDMA_1X = -1;
+
+int RfDesenseTxTest::mState = STATE_NONE;
+
+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 static std::string CMD_SAME_EGMC = "+EGMC:";
+
+const std::string RfDesenseTxTest::KEY_GSM_ATCMD = "gsm_at_cmd";
+const std::string RfDesenseTxTest::KEY_TDSCDMA_ATCMD = "tdscdma_at_cmd";
+const std::string RfDesenseTxTest::KEY_WCDMA_ATCMD = "wcdma_at_cmd";
+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_NR_ATCMD = "AT+EGMC=1,\"NrForcedTx\",2,1,1950000,23";
+const std::string RfDesenseTxTest::DEFAULT_CDMA_EVDO_ATCMD = "AT+ERFTX=13,4,384,0,83";
+const std::string RfDesenseTxTest::DEFAULT_CDMA_1X_ATCMD = "AT+ECRFTX=1,384,0,83,0";
+
+const std::string RfDesenseTxTest::DEFAULT_CDMA_EVDO_ATCMD_93before =
+            "AT+ERFTX=1,384,0,83,1";
+
+const std::vector<std::string> RfDesenseTxTest::mRatName = {
+            "GSM"
+#ifndef TARGET_PLATFORM_MT2735
+            , "TDSCDMA"
+#endif
+            , "WCDMA"
+            , "LTE(FDD)", "LTE(TDD)"
+#ifdef TARGET_PLATFORM_MT2735
+            , "NR"
+#endif
+#ifdef C2K_SUPPORT
+            ,"CDMA(EVDO)", "CDMA(1X)"
+#endif
+            };
+std::vector<std::string> RfDesenseTxTest::mRatCmdStart = {
+            DEFAULT_GSM_ATCMD
+#ifndef TARGET_PLATFORM_MT2735
+            , DEFAULT_TDSCDMA_ATCMD
+#endif
+            , DEFAULT_WCDMA_ATCMD
+            , DEFAULT_LTE_FDD_ATCMD, DEFAULT_LTE_TDD_ATCMD
+#ifdef TARGET_PLATFORM_MT2735
+            , DEFAULT_NR_ATCMD
+#endif
+#ifdef C2K_SUPPORT
+            , DEFAULT_CDMA_EVDO_ATCMD, DEFAULT_CDMA_1X_ATCMD
+#endif
+            };
+
+std::vector<std::string> RfDesenseTxTest::mRatCmdStop = {
+            "AT+ERFTX=2,0"
+#ifndef TARGET_PLATFORM_MT2735
+            , "AT+ERFTX=0,1"
+#endif
+            , "AT+ERFTX=0,1"
+            , "AT+ERFTX=6,0,0", "AT+ERFTX=6,0,0"
+#ifdef TARGET_PLATFORM_MT2735
+            , "AT+EGMC=1,\"NrForcedTx\",0"
+#endif
+#ifdef C2K_SUPPORT
+            ,"AT+ERFTX=13,5", "AT+ECRFTX=0"
+#endif
+            };
+
+ std::vector<std::string> RfDesenseTxTest::mRatCmdSwitch = {
+            "AT+ERAT=0"
+#ifndef TARGET_PLATFORM_MT2735
+            , "AT+ERAT=1"
+#endif
+            , "AT+ERAT=1"
+            , "AT+ERAT=6,4", "AT+ERAT=6,4"
+#ifdef TARGET_PLATFORM_MT2735
+            , "AT+ERAT=22,128"
+#endif
+#ifdef C2K_SUPPORT
+            , "AT+ERAT=7,64", "AT+ERAT=7,32"
+#endif
+            };
+
+std::vector<std::string> RfDesenseTxTest::mRatCmdPowerRead = {
+            ""
+#ifndef TARGET_PLATFORM_MT2735
+            , "AT+ERFTX=0,3"
+#endif
+            , "AT+ERFTX=0,3"
+            , "AT+ERFTX=6,1", "AT+ERFTX=6,1"
+#ifdef TARGET_PLATFORM_MT2735
+            , "AT+EGMC=0,\"NrFetchTxPwr\""
+#endif
+#ifdef C2K_SUPPORT
+            , "AT+ERFTX=13,3", "AT+ERFTX=13,3"
+#endif
+            };
+
+std::vector<std::string> RfDesenseTxTest::mRatBand = {
+            "19"
+#ifndef TARGET_PLATFORM_MT2735
+            , "1"
+#endif
+            , "1"
+            , "3", "38"
+#ifdef TARGET_PLATFORM_MT2735
+            , "1"
+#endif
+#ifdef C2K_SUPPORT
+            , "0", "0"
+#endif
+            };
+
+std::vector<std::string> RfDesenseTxTest::mRatPowerSet = {
+            "19"
+#ifndef TARGET_PLATFORM_MT2735
+            , "10"
+#endif
+            , "24"
+            , "23", "23"
+#ifdef TARGET_PLATFORM_MT2735
+            , "23"
+#endif
+#ifdef C2K_SUPPORT
+            , "23", "23"
+#endif
+            };
+
+std::vector<bool> RfDesenseTxTest::mRatCheck = {false, false, false, false, false, false, false, false};
+std::vector<bool> RfDesenseTxTest::mSendState = {false, false, false, false, false, false, false, false};
+std::string RfDesenseTxTest::str_msg = "";
+bool RfDesenseTxTest::trm_flag = false;
+int RfDesenseTxTest::phone_id = 0;
+
+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();
+                }
+                //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:Ratname=%s, RatCmd=%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;
+}
+
+char* RfDesenseTxTest::msg_type_to_str(int msgType) {
+    switch (msgType) {
+        case MSG_START_TX:
+            return "MSG_START_TX";
+        case MSG_CONTINUE_TX:
+            return "MSG_CONTINUE_TX";
+        case MSG_NEXT_RAT:
+            return "MSG_NEXT_RAT";
+        case MSG_READ_POWER:
+            return "MSG_READ_POWER";
+        case MSG_EWMPOLICY_TDSCDMA:
+            return "MSG_EWMPOLICY_TDSCDMA";
+        case MSG_EWMPOLICY_WCDMA:
+            return "MSG_EWMPOLICY_WCDMA";
+        case MSG_ECSRA:
+            return "MSG_ECSRA";
+        case MSG_SWITCH_RAT_DONE:
+            return "MSG_SWITCH_RAT_DONE";
+        case MSG_NR_READ_POWER:
+            return "MSG_NR_READ_POWER";
+        default:
+            return "unknown type";
+    }
+}
+
+void RfDesenseTxTest::emRfDesenseAtCmdHandle(sp<RfRequestMessage> msg){
+    LOG_D(LOG_TAG, "emRfDesenseAtCmdHandle(), %s", msg_type_to_str(msg->mMsgType));
+    int responselen = msg->responselen;
+    std::string response = msg->response;
+    switch (msg->mMsgType) {
+    case MSG_SWITCH_RAT_DONE: {
+        if (msg->e == RIL_E_SUCCESS) {
+            LOG_D(LOG_TAG, "switch rat=%s succeed", mCurrectRatInfo->getRatName().c_str());
+#ifndef TARGET_PLATFORM_MT2735
+            if (mCurrectRatInfo->getRatName() == mRatName[INDEX_TDSCDMA]) { // tdscdma
+                LOG_D(LOG_TAG, "end AT+EWMPOLICY=0");
+                rf_send_at_cmd("AT+EWMPOLICY=0", MSG_EWMPOLICY_TDSCDMA);
+            } else
+#endif
+            if (mCurrectRatInfo->getRatName() == mRatName[INDEX_WCDMA]) { // wcdma
+                LOG_D(LOG_TAG,  "send AT+EWMPOLICY=0");
+                rf_send_at_cmd("AT+EWMPOLICY=0", MSG_EWMPOLICY_WCDMA);
+            } else { // other rat
+                registerRadioOffOrNotAvailable(m_instance);
+                turnOffRf();
+            }
+
+        } else {
+            LOG_D(LOG_TAG, "switch rat failed");
+            emResultNotifyWithDone(mCurrectRatInfo->getRatName() + " switch rat failed\n");
+        }
+        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::is93ModemAndAbove() && mCurrectRatInfo && !mCurrectRatInfo->getRatCmdPowerRead().empty()) {
+#ifdef TARGET_PLATFORM_MT2735
+                // For NR, need send get power after 5s, 10s (2 times)
+                if (mCurrectRatInfo->getRatName() == sub_tx_test[INDEX_NR].name) {
+                    LOG_D(LOG_TAG, "For NR, wait and start read cmd");
+                    sp<RfRequestMessage> nr_msg = new RfRequestMessage(this);
+                    nr_msg->mMsgType = MSG_CONTINUE_TX;
+                    nr_msg->response = msg->response;
+                    nr_msg->responselen = msg->responselen;
+                    nr_msg->slot = msg->slot;
+                    nr_msg->e = RIL_E_SUCCESS;
+                    sendMessage(nr_msg, 1000);
+
+                } else {
+#endif
+                    LOG_D(LOG_TAG,"start read cmd: %s", mCurrectRatInfo->getRatCmdPowerRead().c_str());
+                    rf_send_at_cmd(mCurrectRatInfo->getRatCmdPowerRead(), MSG_READ_POWER);
+#ifdef TARGET_PLATFORM_MT2735
+                }
+#endif
+            } else {
+                LOG_D(LOG_TAG, "don't read");
+                txTestStop(MSG_NEXT_RAT);
+            }
+        } else {
+            LOG_D(LOG_TAG, "start cmd failed");
+            emResultNotifyWithDone(mCurrectRatInfo->getRatName() + " start cmd failed\n");
+        }
+        break;
+    }
+
+    case MSG_CONTINUE_TX:{
+        mTestDurationSended += mReadbackInterval;
+        if (mTestDurationSended >= mTestDuration) {
+            LOG_D(LOG_TAG, "read tx power succeed");
+            txTestStop(MSG_NEXT_RAT);
+            mTestDurationSended = 0;
+
+        } else {
+            LOG_D(LOG_TAG, "Wait again for mTestDurationSended=%d < %d", mTestDurationSended, mTestDuration);
+            sp<RfRequestMessage> nr_msg = new RfRequestMessage(this);
+            nr_msg->mMsgType = MSG_CONTINUE_TX;
+            nr_msg->response = msg->response;
+            nr_msg->responselen = msg->responselen;
+            nr_msg->slot = msg->slot;
+            nr_msg->e = msg->e;
+            sendMessage(msg, mReadbackInterval*1000);
+
+            if (utils::is93ModemAndAbove() && mCurrectRatInfo && !mCurrectRatInfo->getRatCmdPowerRead().empty()) {
+                LOG_D(LOG_TAG,"start read cmd: %s", mCurrectRatInfo->getRatCmdPowerRead().c_str());
+                rf_send_at_cmd(mCurrectRatInfo->getRatCmdPowerRead(), MSG_NR_READ_POWER);
+            } else {
+                LOG_D(LOG_TAG,"start read cmd fail");
+            }
+        }
+        break;
+    }
+
+    case MSG_NR_READ_POWER:{
+        if ((msg->e == RIL_E_SUCCESS) && (responselen > 0)) {
+            RLOGD("Get response %s", msg->response.c_str());
+            parse_read_power(response);
+
+        } else {
+            LOG_D(LOG_TAG, "read tx power failed");
+            emResultNotifyWithDone(mCurrectRatInfo->getRatName() + " read tx power failed\n");
+        }
+
+        break;
+    }
+
+    case MSG_READ_POWER:{
+        mTestDurationSended += mReadbackInterval;
+        if (mTestDurationSended >= mTestDuration) {
+            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::is93ModemAndAbove() && mCurrectRatInfo && !mCurrectRatInfo->getRatCmdPowerRead().empty()) {
+                LOG_D(LOG_TAG,"(sencond)start read cmd: %s", mCurrectRatInfo->getRatCmdPowerRead().c_str());
+                rf_send_at_cmd(mCurrectRatInfo->getRatCmdPowerRead(), MSG_READ_POWER);
+            } 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::is93ModemAndAbove()){
+//                    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::parse_read_power(std::string response) {
+    std::vector<std::string> out;
+    utils::tokenize(response, "\n", out);
+    std::string str;
+    str.clear();
+
+    for(auto i: out) {
+        if(i.find(CMD_SAME_EGMC) != std::string::npos) {
+            std::string splitString = i.substr(std::string(CMD_SAME_EGMC).size());
+            std::vector<std::string> getDigitalVal;
+            utils::tokenize(string(splitString), ",\n", getDigitalVal);
+            RLOGD("parseCurrentMode splitString: %s, getDigitalVal.size()=%d",
+                    splitString.c_str(), getDigitalVal.size());
+
+            if (getDigitalVal.size() <= 0 || getDigitalVal.size() > 2) {
+                LOG_D(LOG_TAG, "read tx power size failed");
+                emResultNotifyWithDone(mCurrectRatInfo->getRatName() + " read tx power failed\n");
+                return ;
+            }
+
+            try {
+                float getPower = std::stof(getDigitalVal[1]);
+                LOG_D(LOG_TAG, "Readback tx power = %f", getPower);
+
+                std::string result = "";
+                std::string rat = "";
+
+                if (std::abs(std::stoi(mCurrectRatInfo->getRatPowerSet()) - getPower) > mCheckLimit) {
+                    result = "failed\n";
+                } else {
+                    result = "succeed\n";
+                }
+
+                std::string s = std::string("Start TX:\n")
+                        + std::string("Rat(band)          ") + std::string("Power_Set   ")
+                        + std::string("Power_Get    ") + std::string("Result\n");
+                rat = utils::format("%-20s   %-15s   %-10s",
+                        (mCurrectRatInfo->getRatName()+ "(b" + mCurrectRatInfo->getRatband() + ")").c_str(),
+                        mCurrectRatInfo->getRatPowerSet().c_str(),
+                        std::to_string(getPower).c_str()
+                );
+
+                std::string ret;
+                if (!result.compare("failed\n")) {
+                    ret = utils::format("%10s", result.c_str());
+                } else {
+                    ret = utils::format("%10s", result.c_str());
+                }
+                str_msg += s + rat + ret;
+
+                RLOGD("%s", str_msg.c_str());
+
+            } catch (const out_of_range &e) {
+                emResultNotifyWithDone(mCurrectRatInfo->getRatName() + " read tx power failed\n");
+                RLOGD("out of range: %s", e.what());
+                return;
+            } catch (const invalid_argument &e) {
+                emResultNotifyWithDone(mCurrectRatInfo->getRatName() + " read tx power failed\n");
+                RLOGD("invalid argument: %s", e.what());
+                return;
+            }
+
+        }
+    }
+}
+
+void RfDesenseTxTest::handle_gsm_para(const std::string& name, int last_pos,
+        const std::string& sub_name) {
+    bool flag = false;
+    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_nr_para(const std::string& name, int last_pos,
+        const std::string& sub_name) {
+    //NR
+    bool flag = false;
+    std::shared_ptr<RfDesenseTxTestNr> nr =
+            RfDesenseTxTestNr::get_instance();
+
+    if (name == rfdesense_nr_sub[INDEX_NR_SUB_MODE].name) {
+        flag = nr->set_tx_mode(last_pos);
+
+    } else if (name == rfdesense_nr_sub[INDEX_NR_SUB_BAND].name) {
+        flag = nr->set_band_idx(last_pos);
+
+    } else if (name == rfdesense_nr_sub[INDEX_NR_SUB_BANDWIDTH].name) {
+        flag = nr->set_bandwith_idx(last_pos);
+
+    } else if (name == rfdesense_nr_sub[INDEX_NR_SUB_FREQ].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            nr->show_freq();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = nr->set_freq(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+            em_result_notify_error("get/set input error");
+        }
+
+    } else if (name == rfdesense_nr_sub[INDEX_NR_SUB_START].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            nr->show_start();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = nr->set_vrb_start(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+            em_result_notify_error("get/set input error");
+        }
+
+    } else if (name == rfdesense_nr_sub[INDEX_NR_SUB_LENGTH].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            nr->show_length();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = nr->set_vrb_length(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+            em_result_notify_error("get/set input error");
+        }
+
+    } else if (name == rfdesense_nr_sub[INDEX_NR_SUB_MCS].name) {
+        flag = nr->set_mcs(last_pos);
+
+    } else if (name == rfdesense_nr_sub[INDEX_NR_SUB_SCS].name) {
+        flag = nr->set_scs(last_pos);
+
+    } else if (name == rfdesense_nr_sub[INDEX_NR_SUB_POWER].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            nr->show_power();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = nr->set_power(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+            em_result_notify_error("get/set input error");
+        }
+
+    } else if (name == rfdesense_nr_sub[INDEX_NR_SUB_CONFIG].name) {
+        if (sub_name == set_get[0].name) {
+            //get
+            nr->show_config();
+        } else if (sub_name == set_get[1].name) {
+            // set
+            if (mCurrentSettingsValues.size() > 0) {
+                flag = nr->set_tdd_slot_config(mCurrentSettingsValues[0]);
+            } else {
+                LOG_D(LOG_TAG, "mCurrentSettingsValues size is 0");
+                em_result_notify_error("please input set values, now, only select the set item. value is empty");
+            }
+        } else {
+            LOG_D(LOG_TAG, "error");
+            em_result_notify_error("get/set input error");
+        }
+    } else {
+        LOG_D(LOG_TAG, "No name=%s", name.c_str());
+        em_result_notify_error("get/set input error");
+    }
+
+    if (flag) {
+        mRatList[INDEX_NR]->setRatCmdStart(nr->get_command());
+        mRatList[INDEX_NR]->setRatband(nr->get_band());
+        mRatList[INDEX_NR]->setRatPowerSet(nr->get_power());
+        save(INDEX_NR);
+    }
+}
+
+void RfDesenseTxTest::handle_cdma_evdo_para(const std::string& name,
+        int last_pos, const std::string& sub_name) {
+    //CDMA(EVDO)
+    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();
+#ifndef TARGET_PLATFORM_MT2735
+    } else if (standard == sub_tx_test[INDEX_TDSCDMA].name) {
+        //"TDSCDMA"
+        std::shared_ptr<RfDesenseTxTestTd> tdscdma = std::make_shared<
+                RfDesenseTxTestTd>(utils::MODEM_TDSCDMA);
+        tdscdma->show_default();
+#endif
+    } else if (standard == sub_tx_test[INDEX_WCDMA].name) {
+        //"WCDMA"
+        std::shared_ptr<RfDesenseTxTestTd> wcdma = std::make_shared<
+                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();
+#ifdef TARGET_PLATFORM_MT2735
+    } else if (standard == sub_tx_test[INDEX_NR].name) {
+        //NR
+        std::shared_ptr<RfDesenseTxTestNr> nr =
+                RfDesenseTxTestNr::get_instance();
+        nr->show_default();
+#endif
+#ifdef C2K_SUPPORT
+    } else if ((standard == sub_tx_test[INDEX_CDMA_EVDO].name)
+            && utils::isC2KSupport()) {
+        //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();
+#endif
+    } 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);
+#ifndef TARGET_PLATFORM_MT2735
+    } else if (standard == sub_tx_test[INDEX_TDSCDMA].name) {
+        //"TDSCDMA"
+        handle_tdscdma_para(name, last_pos, sub_name);
+#endif
+    } else if (standard == sub_tx_test[INDEX_WCDMA].name) {
+        //"WCDMA"
+        handle_wcdma_para(name, last_pos, sub_name);
+    } 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);
+#ifdef TARGET_PLATFORM_MT2735
+    } else if (standard == sub_tx_test[INDEX_NR].name) {
+        //NR
+        handle_nr_para(name, last_pos, sub_name);
+#endif
+#ifdef C2K_SUPPORT
+    } else if ((standard == sub_tx_test[INDEX_CDMA_EVDO].name)
+            && utils::isC2KSupport()) {
+        //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);
+#endif
+    } 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);
+#ifndef TARGET_PLATFORM_MT2735
+    } else if (standard == sub_tx_test[INDEX_TDSCDMA].name) {
+        //"TDSCDMA"
+        mRatList[INDEX_TDSCDMA]->setRatCheckState(true);
+#endif
+    } else if (standard == sub_tx_test[INDEX_WCDMA].name) {
+        //"WCDMA"
+        mRatList[INDEX_WCDMA]->setRatCheckState(true);
+    } 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);
+#ifdef TARGET_PLATFORM_MT2735
+    } else if (standard == sub_tx_test[INDEX_NR].name) {
+        //NR
+        mRatList[INDEX_NR]->setRatCheckState(true);
+#endif
+#ifdef C2K_SUPPORT
+    } else if ((standard == sub_tx_test[INDEX_CDMA_EVDO].name)
+            && utils::isC2KSupport()) {
+        //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);
+#endif
+    } 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 manu index
+    int idx_count = 0;
+    INDEX_GSM = idx_count;
+#ifndef TARGET_PLATFORM_MT2735
+    INDEX_TDSCDMA = ++idx_count;
+#endif
+    INDEX_WCDMA = ++idx_count;
+    INDEX_LTE_FDD = ++idx_count;
+    INDEX_LTE_TDD = ++idx_count;
+#ifdef TARGET_PLATFORM_MT2735
+    INDEX_NR = ++idx_count;
+#endif
+#ifdef C2K_SUPPORT
+    INDEX_CDMA_EVDO = ++idx_count;
+    INDEX_CDMA_1X = ++idx_count;
+#endif
+    LOG_D(LOG_TAG, "Manu index: GSM=%d, TDSCDMA=%d, WCDMA=%d, LTE_FDD=%d, LTE_TDD=%d, NR=%d, CDMA_EVDO=%d, CDMA_1X=%d",
+            INDEX_GSM, INDEX_TDSCDMA, INDEX_WCDMA, INDEX_LTE_FDD, INDEX_LTE_TDD, INDEX_NR, INDEX_CDMA_EVDO, INDEX_CDMA_1X);
+
+    update_rat();
+    if (len < 3) {
+        LOG_D(LOG_TAG, "please select redesense get or set");
+        return -1;
+    }
+    int classid = item[0];
+    int propertyid = item[1];
+    int operatorid = item[2];
+    LOG_D(LOG_TAG, "classid=%d, propertyid=%d, operatorid=%d", classid, propertyid, operatorid);
+
+    mCurrentSettingsValues.clear();
+    for(int i = 0; i < multilen; i++ ) {
+        mCurrentSettingsValues.push_back(value[i]);
+        LOG_D(LOG_TAG, "value[%d]: %s", i, value[i]);
+    }
+    LOG_D(LOG_TAG, "mCurrentSettingsValues size: %d" + mCurrentSettingsValues.size());
+
+    em_arry_t *subarry = &(desense_test[classid].subarray[propertyid]);
+    std::string standard = subarry->name;
+    LOG_D(LOG_TAG,"rfdesense property name: %s, operatorid: %d",subarry->name, operatorid);
+    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::is93ModemAndAbove()){
+        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);
+    }
+}
+
+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);
+    }
+}
+void RfDesenseTxTest::save(int index) {
+    mRatCmdStart[index] = mRatList[index]->getRatCmdStart();
+    mRatBand[index] = mRatList[index]->getRatband();
+    mRatPowerSet[index] = mRatList[index]->getRatPowerSet();
+}
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTest.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTest.h
new file mode 100755
index 0000000..8250064
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTest.h
@@ -0,0 +1,277 @@
+// SPDX-License-Identifier: MediaTekProprietary
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef 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_CONTINUE_TX;
+    static const int MSG_NEXT_RAT;
+    static const int MSG_READ_POWER;
+    static const int MSG_EWMPOLICY_TDSCDMA;
+    static const int MSG_EWMPOLICY_WCDMA;
+    static const int MSG_ECSRA;
+    static const int MSG_SWITCH_RAT_DONE;
+    static const int MSG_NR_READ_POWER;
+
+    static const std::string KEY_GSM_ATCMD;
+    static const std::string KEY_TDSCDMA_ATCMD;
+    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_NR_ATCMD;
+    static const std::string DEFAULT_CDMA_EVDO_ATCMD;
+    static const std::string DEFAULT_CDMA_1X_ATCMD;
+    static const std::string DEFAULT_CDMA_EVDO_ATCMD_93before;
+    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 int INDEX_GSM;
+    static int INDEX_TDSCDMA;
+    static int INDEX_WCDMA;
+    static int INDEX_LTE_FDD;
+    static int INDEX_LTE_TDD;
+    static int INDEX_NR;
+    static int INDEX_CDMA_EVDO;
+    static int INDEX_CDMA_1X;
+
+    static constexpr int INDEX_GSM_SUB_BAND = 0;
+    static constexpr int INDEX_GSM_SUB_CHANNEL = 1;
+    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;
+
+    static constexpr int INDEX_NR_SUB_MODE = 0;
+    static constexpr int INDEX_NR_SUB_BAND = 1;
+    static constexpr int INDEX_NR_SUB_BANDWIDTH = 2;
+    static constexpr int INDEX_NR_SUB_FREQ = 3;
+    static constexpr int INDEX_NR_SUB_START = 4;
+    static constexpr int INDEX_NR_SUB_LENGTH = 5;
+    static constexpr int INDEX_NR_SUB_MCS = 6;
+    static constexpr int INDEX_NR_SUB_SCS = 7;
+    static constexpr int INDEX_NR_SUB_POWER = 8;
+    static constexpr int INDEX_NR_SUB_CONFIG = 9;
+
+    class RequestHandleThread: public Thread {
+    public:
+        RequestHandleThread(RfDesenseTxTest* tx);
+        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_nr_para(const std::string& name, int last_pos,const std::string& sub_name);
+    void handle_cdma_evdo_para(const std::string& name, int last_pos,const std::string& sub_name);
+    void handle_cdma_1X_para(const std::string& name, int last_pos,const std::string& sub_name);
+    bool handle_show_default(const std::string& standard);
+    bool handle_para(int len, int classid, int propertyid, int operatorid,const std::string& standard, int* item);
+    bool handle_start(const std::string& standard);
+    void parse_read_power(std::string response);
+    char* msg_type_to_str(int msgType);
+
+    static int mState;
+    static std::string str_msg;
+    static int phone_id;
+    bool mIsModemEnabled = true;
+    bool mIsModemNotEnabled = true;
+private:
+    void init();
+    void deInit();
+};
+
+#endif /* RFDESENSETXTEST_H_ */
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestBase.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestBase.cpp
new file mode 100755
index 0000000..1faa8ae
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestBase.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestBase.h
new file mode 100755
index 0000000..94b08de
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestCdma.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestCdma.cpp
new file mode 100755
index 0000000..b9fc283
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestCdma.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestCdma.h
new file mode 100755
index 0000000..26cc2ff
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestGsm.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestGsm.cpp
new file mode 100755
index 0000000..8bbe469
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestGsm.cpp
@@ -0,0 +1,311 @@
+//SPDX-License-Identifier: MediaTekProprietary
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include "rfdesense/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);
+    if (band_index > 5 || band_index < 0) {
+        LOG_W(LOG_TAG, "show_default, band_index=%d, out of range\n" , band_index);
+        band_index = 0;
+    }
+
+    int pattern_index = std::stoi(pattern);
+    std::string temp = "GSM parameter: Band: " + std::string(rfdesense_gsm_band[band_index].name) +
+            ", Channel(ARFCN): " + channel + ", Power Level: " + power + ", AFC: " + afc + ", TSC: " + tsc +
+            ", PATTERN: " + std::string(rfdesense_gsm_pattern[pattern_index > 6 ? 0 : pattern_index].name);
+    emResultNotifyWithDone(temp);
+}
+
+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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestGsm.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestGsm.h
new file mode 100755
index 0000000..0963e49
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestLte.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestLte.cpp
new file mode 100755
index 0000000..56c6275
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestLte.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestLte.h
new file mode 100755
index 0000000..8b0f53a
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestNr.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestNr.cpp
new file mode 100755
index 0000000..1d49366
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestNr.cpp
@@ -0,0 +1,412 @@
+// SPDX-License-Identifier: MediaTekProprietary
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include "rfdesense/RfDesenseTxTestNr.h"
+
+#include <algorithm>
+#include <iterator>
+#include <stdexcept>
+
+#include "rfdesense/RfDesenseTxTestBase.h"
+#include "util/log_extra.h"
+#include "em.h"
+
+#undef LOG_TAG
+#define LOG_TAG "EM_RfDesenseTxTestNr"
+
+const int RfDesenseTxTestNr::INDEX_TX_MODE = 0;
+const int RfDesenseTxTestNr::INDEX_BAND = 1;
+const int RfDesenseTxTestNr::INDEX_BAND_WIDTH = 2;
+const int RfDesenseTxTestNr::INDEX_FREQ = 3;
+const int RfDesenseTxTestNr::INDEX_VRB_START = 4;
+const int RfDesenseTxTestNr::INDEX_VRB_LENGTH = 5;
+const int RfDesenseTxTestNr::INDEX_MCS = 6;
+const int RfDesenseTxTestNr::INDEX_SCS = 7;
+const int RfDesenseTxTestNr::INDEX_POWER = 8;
+const int RfDesenseTxTestNr::INDEX_TDD_SLOT_CONFIG = 9;
+const int RfDesenseTxTestNr::INDEX_ANT_MODE = 10;
+
+std::string RfDesenseTxTestNr::mTxMode="";
+int RfDesenseTxTestNr::mBandIdx=0;
+std::string RfDesenseTxTestNr::mBand="";
+int RfDesenseTxTestNr::mBandWidthIdx=0;
+std::string RfDesenseTxTestNr::mBandWidth="";
+std::string RfDesenseTxTestNr::mFreq="";
+std::string RfDesenseTxTestNr::mVrbStart="";
+std::string RfDesenseTxTestNr::mVrbLength="";
+std::string RfDesenseTxTestNr::mMcs="";
+std::string RfDesenseTxTestNr::mScs="";
+std::string RfDesenseTxTestNr::mPower="";
+std::string RfDesenseTxTestNr::mTddSlotConfig="";
+int RfDesenseTxTestNr::mAntMode=0;
+
+std::shared_ptr<RfDesenseTxTestNr> RfDesenseTxTestNr::m_instance;
+std::mutex RfDesenseTxTestNr::mutex;
+
+std::string RfDesenseTxTestNr::DEFAULT_TX_MODE = "0";//TONE
+int RfDesenseTxTestNr::DEFAULT_BAND_IDX = 0;//BAND1
+int RfDesenseTxTestNr::DEFAULT_BAND_WIDTH_IDX = 1;//10MHZ
+std::string RfDesenseTxTestNr::DEFAULT_NR_FREQ = "1950000";
+std::string RfDesenseTxTestNr::DEFAULT_VRB_START = "0";
+std::string RfDesenseTxTestNr::DEFAULT_VRB_LENGTH = "1";
+std::string RfDesenseTxTestNr::DEFAULT_MCS = "0";//DFT-S BPSK
+std::string RfDesenseTxTestNr::DEFAULT_SCS_CONFIG = "0";//15KHZ
+std::string RfDesenseTxTestNr::DEFAULT_POWER = "23";
+std::string RfDesenseTxTestNr::DEFAULT_TDD_SLOT_CONFIG = "1";
+int RfDesenseTxTestNr::DEFAULT_ANT_MODE= 0;
+
+int VRB_START_MIN = 0;
+int VRB_START_MAX = 272;
+int VRB_LENGTH_MIN = 0;
+int VRB_LENGTH_MAX = 273;
+int POWER_MIN = -50;
+int POWER_MAX_PUSCH = 23;
+int POWER_MAX_TONE = 26;
+int TDD_SLOT_CONFIG_MIN = 1;
+int TDD_SLOT_CONFIG_MAX = 44;
+
+const std::vector<std::string> RfDesenseTxTestNr::mBandMapping = {"1", "3", "7", "8", "20", "28", "38", "41", "77", "78", "79"};
+const std::vector<std::string> RfDesenseTxTestNr::mBandWidthMapping = {"5000", "10000", "15000", "20000", "25000", "30000",
+        "35000", "40000", "45000", "50000", "55000", "60000", "65000", "70000", "75000", "80000", "85000", "90000",
+        "95000", "100000"};
+
+RfDesenseTxTestNr::RfDesenseTxTestNr() {
+    LOG_D(LOG_TAG, "RfDesenseTxTestNr()");
+
+    mTxMode = DEFAULT_TX_MODE;
+    mBandIdx = DEFAULT_BAND_IDX;
+    mBand = mBandMapping[mBandIdx];
+    mBandWidthIdx = DEFAULT_BAND_WIDTH_IDX;
+    mBandWidth = mBandWidthMapping[mBandWidthIdx];
+    mFreq = DEFAULT_NR_FREQ;
+    mVrbStart = DEFAULT_VRB_START;
+    mVrbLength = DEFAULT_VRB_LENGTH;
+    mMcs = DEFAULT_MCS;
+    mScs = DEFAULT_SCS_CONFIG;
+    mPower = DEFAULT_POWER;
+    mTddSlotConfig = DEFAULT_TDD_SLOT_CONFIG;
+    mAntMode = DEFAULT_ANT_MODE;
+}
+
+void RfDesenseTxTestNr::show_default() {
+    std::string str;
+    std::string tx_mode_str(rfdesense_nr_tx_mode[std::stoi(mTxMode)].name);
+    std::string band_str(rfdesense_nr_band[mBandIdx].name);
+    std::string band_width_str(rfdesense_nr_bandwidth[mBandWidthIdx].name);
+    std::string mcs_str(rfdesense_nr_mcs[std::stoi(mMcs)].name);
+    std::string scs_str(rfdesense_nr_scs[std::stoi(mScs)].name);
+
+    str = "\nTx mode: " + tx_mode_str
+            + "\nBand: " + band_str
+            + "\nUL Bandwidth: " + band_width_str
+            + "\nUL Freq(1kHz): " + mFreq
+            + "\nVRB Start(0~272): " + mVrbStart
+            + "\nVRB Length(0~273): " + mVrbLength
+            + "\nMCS: " + mcs_str
+            + "\nSCS: " + scs_str
+            + "\nPower Level(dBm)(-50-23): " + mPower
+            + "\nTDD Slot Config: " + mTddSlotConfig;
+
+    LOG_D(LOG_TAG, "show_default, str=%s", str.c_str());
+    emResultNotifyWithDone(str);
+}
+
+RfDesenseTxTestNr::~RfDesenseTxTestNr() {
+    // TODO Auto-generated destructor stub
+}
+
+std::shared_ptr<RfDesenseTxTestNr> RfDesenseTxTestNr::get_instance() {
+    if(!m_instance) {
+        mutex.lock();
+        if(!m_instance) {
+            m_instance = std::make_shared<RfDesenseTxTestNr>();
+        }
+        mutex.unlock();
+    }
+    return m_instance;
+}
+
+std::string RfDesenseTxTestNr::get_command() {
+    std::string command;
+
+    //Tone mode
+    if (mTxMode == "0") {
+        command = "AT+EGMC=1,\"NrForcedTx\",2,";
+        command += mBand + "," + mFreq + "," + mPower;
+
+    //PUSCH mode
+    } else {
+        command = "AT+EGMC=1,\"NrForcedTx\",1,";
+        command += mBand + "," + mBandWidth + "," + mFreq + "," +
+                mVrbStart + "," + mVrbLength + "," + mMcs + ","
+                + mScs + "," + mPower + "," + mTddSlotConfig;
+    }
+
+    LOG_D(LOG_TAG, "NR command: %s\n", command.c_str());
+    return command;
+}
+
+std::string RfDesenseTxTestNr::get_band() {
+    return mBand;
+}
+std::string RfDesenseTxTestNr::get_power() {
+    return mPower;
+}
+
+std::string RfDesenseTxTestNr::get_ant_mode() {
+    std::string ant_str;
+    int antStatustx = DEFAULT_ANT_MODE, antStatusrx = DEFAULT_ANT_MODE;
+
+    if (mAntMode == 1)
+        ant_str = utils::format("AT+EGMC=1,\"NrForceTxRx\",1,%d,%d,0", antStatustx, antStatusrx);
+    else {
+        ant_str = utils::format("AT+EGMC=1,\"NrForceTxRx\",0,,,0");
+    }
+
+    LOG_D(LOG_TAG, "ant_str: %s\n", ant_str.c_str());
+    return ant_str;
+}
+
+bool RfDesenseTxTestNr::set_tx_mode(int mode){
+    std::string s;
+    if(mode !=0 && mode != 1) {
+        s = utils::format("set_mode: mode(%d) is out of range", mode);
+        LOG_E(LOG_TAG, "%s", s.c_str());
+        em_result_notify_fail(s);
+        return false;
+    }
+
+    mTxMode = std::to_string(mode);
+    // For PUSCH mode, we adjust parameter to pass tx
+    if (mTxMode == "1") {
+        mBandIdx = 7;
+        mBand = mBandMapping[mBandIdx]; //Band 41
+        mFreq = "2593010";
+        LOG_D(LOG_TAG, "For PUSCH mode, adjust parameter band=%s, freq=%s", mBand.c_str(), mFreq.c_str());
+    }
+
+    std::string tx_mode_str(rfdesense_nr_tx_mode[std::stoi(mTxMode)].name);
+    em_result_notify_ok("Tx mode=" + tx_mode_str);
+
+    return true;
+}
+
+bool RfDesenseTxTestNr::set_band_idx(int bandidx){
+    std::string s;
+
+    if(bandidx < 0 || bandidx >= mBandMapping.size()){
+        s = utils::format("set_band_idx: bandidx(%d) is out of range", bandidx);
+        LOG_E(LOG_TAG, "%s", s.c_str());
+        em_result_notify_fail(s);
+        return false;
+    }
+
+    mBandIdx = bandidx;
+    mBand = mBandMapping[bandidx];
+
+    em_result_notify_ok("mBand=" + mBand);
+    return true;
+}
+
+bool RfDesenseTxTestNr::set_bandwith_idx(int bandwidthidx){
+    std::string s;
+    if (bandwidthidx < 0 || bandwidthidx >= mBandWidthMapping.size()) {
+        s = utils::format("set_bandwith_idx value range is [%d, %d], input value is %d", 0, mBandWidthMapping.size(), bandwidthidx);
+        LOG_E(LOG_TAG, "%s", s.c_str());
+        em_result_notify_fail(s);
+        return false;
+    }
+
+    mBandWidthIdx = bandwidthidx;
+    mBandWidth = mBandWidthMapping[mBandWidthIdx];
+
+    em_result_notify_ok("mBandWidth=" + mBandWidth);
+    return true;
+}
+
+bool RfDesenseTxTestNr::set_freq(std::string str){
+    mFreq = str;
+    em_result_notify_ok("freq=" + mFreq);
+    return true;
+}
+
+bool RfDesenseTxTestNr::set_vrb_start(std::string start){
+    std::string s;
+    int value = -1;
+    try {
+        value = std::stoi(start);
+    } catch (std::invalid_argument &err) {
+        s = utils::format("set_vrb_start, vrb_start=%s is invalid, reason: %s", start.c_str(), err.what());
+        LOG_E(LOG_TAG, "%s", s.c_str());
+        em_result_notify_fail(s);
+        return false;
+    }
+
+    if (value < VRB_START_MIN || value > VRB_START_MAX) {
+        s = utils::format("set_vrb_start value range is [%d, %d], input value is %d", VRB_START_MIN, VRB_START_MAX, value);
+        LOG_E(LOG_TAG, "%s", s.c_str());
+        em_result_notify_fail(s);
+        return false;
+    }
+
+    mVrbStart = start;
+    em_result_notify_ok("vrb_start=" + mVrbStart);
+    return true;
+}
+
+bool RfDesenseTxTestNr::set_vrb_length(std::string length){
+    std::string s;
+    int value = -1;
+    try {
+        value = std::stoi(length);
+    } catch (std::invalid_argument &err) {
+        s = utils::format("set_vrb_length, vrb_length=%s is invalid, reason: %s", length.c_str(), err.what());
+        LOG_E(LOG_TAG, "%s", s.c_str());
+        em_result_notify_fail(s);
+        return false;
+    }
+
+    if (value < VRB_LENGTH_MIN || value > VRB_LENGTH_MAX) {
+        s = utils::format("set_vrb_length value range is [%d, %d], input value is %d", VRB_LENGTH_MIN, VRB_LENGTH_MAX, value);
+        LOG_E(LOG_TAG, "%s", s.c_str());
+        em_result_notify_fail(s);
+        return false;
+    }
+
+    mVrbLength = length;
+    em_result_notify_ok("vrb_length=" + mVrbLength);
+    return true;
+}
+
+bool RfDesenseTxTestNr::set_mcs(int mcs) {
+    if (mcs < 0 || mcs > 8) {
+        std::string s;
+        s = utils::format("check_mcs value range is [%d, %d], input value is %d", 0, 8, mcs);
+        LOG_E(LOG_TAG, "%s", s.c_str());
+        em_result_notify_fail(s);
+        return false;
+    }
+
+    mMcs = std::to_string(mcs);
+    em_result_notify_ok(std::string("mcs=") + rfdesense_nr_mcs[mcs].name);
+    return true;
+}
+
+bool RfDesenseTxTestNr::set_scs(int scs) {
+    if (scs < 0 || scs > 4) {
+        std::string s;
+        s = utils::format("check_mcs value range is [%d, %d], input value is %d", 0, 4, scs);
+        LOG_E(LOG_TAG, "%s", s.c_str());
+        em_result_notify_fail(s);
+        return false;
+    }
+
+    mScs = std::to_string(scs);
+    em_result_notify_ok(std::string("scs=") + rfdesense_nr_scs[scs].name);
+    return true;
+}
+
+bool RfDesenseTxTestNr::set_power(std::string power){
+    std::string s;
+    int value = -1, powerMax = POWER_MAX_TONE;
+
+    powerMax = (mTxMode == "0")? POWER_MAX_TONE: POWER_MAX_PUSCH;
+
+    try {
+        value = std::stoi(power);
+    } catch (std::invalid_argument &err) {
+        s = utils::format("set_power,check_power(%s) is invalid, reason: %s", power.c_str(), err.what());
+        LOG_E(LOG_TAG, "%s", s.c_str());
+        em_result_notify_fail(s);
+        return false;
+    }
+
+    if (value < POWER_MIN || value > powerMax) {
+        s = utils::format("check_power value range is [%d, %d], input value is %d", POWER_MIN, powerMax, value);
+        LOG_E(LOG_TAG, "%s", s.c_str());
+        em_result_notify_fail(s);
+        return false;
+    }
+
+    mPower = power;
+    em_result_notify_ok("power=" + power);
+    return true;
+}
+
+bool RfDesenseTxTestNr::set_tdd_slot_config(std::string config){
+    std::string s;
+    int value = -1;
+
+    try {
+        value = std::stoi(config);
+    } catch (std::invalid_argument &err) {
+        s = utils::format("set_tdd_slot_config, config(%s) is invalid, reason: %s", config.c_str(), err.what());
+        LOG_E(LOG_TAG, "%s", s.c_str());
+        em_result_notify_fail(s);
+        return false;
+    }
+
+    if(value < TDD_SLOT_CONFIG_MIN || value > TDD_SLOT_CONFIG_MAX){
+        s = utils::format("check_tdd_config value range is [%d, %d], input value is %d", TDD_SLOT_CONFIG_MIN, TDD_SLOT_CONFIG_MAX, value);
+        LOG_E(LOG_TAG, "%s", s.c_str());
+        em_result_notify_fail(s);
+        return false;
+    }
+
+    mTddSlotConfig = config;
+    em_result_notify_ok("tdd_config=" + mTddSlotConfig);
+    return true;
+}
+
+void RfDesenseTxTestNr::show_freq(){
+    emResultNotifyWithDone("UL Freq(1kHZ): " + mFreq);
+}
+
+void RfDesenseTxTestNr::show_start(){
+    emResultNotifyWithDone("VRB Start(0~272): " + mVrbStart);
+}
+
+void RfDesenseTxTestNr::show_length(){
+    emResultNotifyWithDone("VRB Length(0~273): " + mVrbLength);
+}
+
+void RfDesenseTxTestNr::show_power(){
+    emResultNotifyWithDone("Power Level(dBm)(-50~23): " + mPower);
+}
+
+void RfDesenseTxTestNr::show_config(){
+    emResultNotifyWithDone("TDD slot config(1~44): " + mTddSlotConfig);
+}
+
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestNr.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestNr.h
new file mode 100755
index 0000000..9026bf9
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestNr.h
@@ -0,0 +1,127 @@
+// SPDX-License-Identifier: MediaTekProprietary
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef RFDESENSETXTESTNR_H_
+#define RFDESENSETXTESTNR_H_
+
+#include <string>
+#include <vector>
+#include <map>
+#include <memory>
+#include <mutex>
+
+#include "util/utils.h"
+
+class RfDesenseTxTestNr {
+public:
+    RfDesenseTxTestNr();
+    virtual ~RfDesenseTxTestNr();
+
+    static std::shared_ptr<RfDesenseTxTestNr> get_instance();
+
+    void show_default();
+    std::string get_command();
+    std::string get_band();
+    std::string get_power();
+    std::string get_ant_mode();
+
+    bool set_tx_mode(int mode);
+    bool set_band_idx(int bandidx);
+    bool set_bandwith_idx(int bandwidthidx);
+    bool set_freq(std::string freq);
+    bool set_vrb_start(std::string start);
+    bool set_vrb_length(std::string length);
+    bool set_mcs(int mcs);
+    bool set_scs(int scs);
+    bool set_power(std::string power);
+    bool set_tdd_slot_config(std::string config);
+
+    void show_freq();
+    void show_start();
+    void show_length();
+    void show_power();
+    void show_config();
+
+private:
+    static std::shared_ptr<RfDesenseTxTestNr> m_instance;
+    static std::mutex mutex;
+    std::string command;
+
+    static const int INDEX_TX_MODE;
+    static const int INDEX_BAND;
+    static const int INDEX_BAND_WIDTH;
+    static const int INDEX_FREQ;
+    static const int INDEX_VRB_START;
+    static const int INDEX_VRB_LENGTH;
+    static const int INDEX_MCS;
+    static const int INDEX_SCS;
+    static const int INDEX_POWER;
+    static const int INDEX_TDD_SLOT_CONFIG;
+    static const int INDEX_ANT_MODE;
+
+    static std::string DEFAULT_TX_MODE;
+    static int DEFAULT_BAND_IDX;
+    static std::string DEFAULT_BAND;
+    static int DEFAULT_BAND_WIDTH_IDX;
+    static std::string DEFAULT_BAND_WIDTH;//40MHZ
+    static std::string DEFAULT_NR_FREQ;
+    static std::string DEFAULT_VRB_START;
+    static std::string DEFAULT_VRB_LENGTH;
+    static std::string DEFAULT_MCS;
+    static std::string DEFAULT_SCS_CONFIG;
+    static std::string DEFAULT_POWER;
+    static std::string DEFAULT_TDD_SLOT_CONFIG;
+    static int DEFAULT_ANT_MODE;
+
+    static std::string mTxMode;
+    static int mBandIdx;
+    static std::string mBand;
+    static int mBandWidthIdx;
+    static std::string mBandWidth;
+    static std::string mFreq;
+    static std::string mVrbStart;
+    static std::string mVrbLength;
+    static std::string mMcs;
+    static std::string mScs;
+    static std::string mPower;
+    static std::string mTddSlotConfig;
+    static int mAntMode;
+
+    static const std::vector<std::string> mBandMapping;
+    static const std::vector<std::string> mBandWidthMapping;
+};
+
+#endif /* RFDESENSETXTESTNR_H_ */
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestTd.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestTd.cpp
new file mode 100755
index 0000000..2afe62e
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestTd.cpp
@@ -0,0 +1,344 @@
+//SPDX-License-Identifier: MediaTekProprietary
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include "rfdesense/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);
+        int index = 0;
+        if(band_index < 2 && band_index > -1) {
+            index = band_index;
+        } else {
+            index = 0;
+        }
+        temp = "TDSCDMA parameters: Band: " + std::string(rfdesense_tdscdma_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);
+        int index = 0;
+        if(band_index < 18 && band_index > -1) {
+            index = band_index;
+        } else {
+            index = 0;
+        }
+        temp = "WCDMA parameters: Band: " + std::string(rfdesense_wcdma_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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestTd.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/em/rfdesense/RfDesenseTxTestTd.h
new file mode 100755
index 0000000..e00508c
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/factory/lynq_factory.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/factory/lynq_factory.cpp
new file mode 100755
index 0000000..e040eb4
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/factory/lynq_factory.cpp
@@ -0,0 +1,731 @@
+#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 <telephony/record_stream.h>
+#include <utils/SystemClock.h>
+#include <binder/Parcel.h>
+#include <cutils/jstring.h>
+#include <sys/types.h>
+#include <limits.h>
+#include <pwd.h>
+
+#include <stdlib.h>
+#include <stdarg.h>
+
+#include <unistd.h>
+
+#include <errno.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 "cc.h"
+#include "network.h"
+#include "stk.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 "Radio_capability_switch_util.h"
+
+#include <stdio.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "common.h"
+#include "utils.h"
+#include "Phone_utils.h"
+#include <time.h>
+#include "sim.h"
+#include <string.h>
+#include<pthread.h>
+#include <cutils/properties.h>
+#include "lynq_at.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include <pthread.h>
+#define SIM_COUNT 2
+#define RIL_REQUEST_GET_SIM_STATUS 1
+int already_gps = 0;
+int enable_nema = 0;
+char rgmii[32] = {0};
+char sgmii[32] = {0};
+int gps_set = 2;
+int g_set_output = 0;
+int ttyGS0_fd;
+pthread_t lynq_gps_tid;
+// static pthread_mutex_t s_gps_state_change_mutex = PTHREAD_MUTEX_INITIALIZER;
+// static pthread_cond_t s_gps_change_cond = PTHREAD_COND_INITIALIZER;
+typedef enum {
+    sim1,
+#if (SIM_COUNT >= 2)
+    sim2,
+#if (SIM_COUNT >= 3)
+    RIL_SOCKET_3,
+#endif
+#if (SIM_COUNT >= 4)
+    RIL_SOCKET_4,
+#endif
+#endif
+    //RIL_SOCKET_NUM
+} RIL_SIM_COUNT;
+
+#include "lynq_factory.h"
+
+static const char *usb3_speed = "super-speed";
+static const char *usb2_speed = "high-speed";
+pthread_mutex_t lynq_audio_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+
+static void lynq_factory_response_ttyGS3(char *buf){
+    write(ttyGS3_fd,buf,strlen(buf));
+    return;
+}
+
+void *thread_test(void *arg){
+    char gnss_buf[128] = {0};
+    lynq_factory_response_ttyGS3("+GPS OPEN:OK\n");
+    sprintf(gnss_buf, "%s%d%s", "echo \"GNSS_MODE=", gps_set, "\">>/etc/gnss/mnl.prop");
+    system(gnss_buf);
+    sleep(1);
+    FILE *fp;
+    char test[100] = {0};
+    sprintf(test, "lynq-gnss-test cold %s", "2>&1");
+    char lynq_factory_buf[1024] = {0};
+    fp=popen(test, "r");
+    if(NULL == fp){
+        lynq_factory_response_ttyGS3("popen errorn\n");
+        return 0;
+    }
+    /*open vcom port*/
+    ttyGS0_fd = open("/dev/ttyGS0",O_RDWR);
+    if(ttyGS0_fd == -1)
+    {
+        lynq_factory_response_ttyGS3("\n+open /dev/ttyGS0:ERROR\n");
+        return NULL;
+    }
+    /*open vcom port*/
+    while (NULL != fgets(lynq_factory_buf,sizeof(lynq_factory_buf),fp))
+    {
+        if(enable_nema == 1){
+            if(g_set_output == 0)
+            {
+                lynq_factory_response_ttyGS3(lynq_factory_buf);
+            }
+            /*output nema into vcom port*/
+            if(g_set_output == 1)
+            {
+                write(ttyGS0_fd,lynq_factory_buf,strlen(lynq_factory_buf));
+            }
+            /*output nema into vcom port*/
+        }
+    }
+    close(ttyGS0_fd);
+    pclose(fp);
+    return 0;
+}
+
+/**
+ * @brief parse ipv4 eg:192.168.131.222 ->192.168.131.1
+ * @param  buf              My Param doc
+ */
+static void parse_ipv4(char *buf)
+{
+    char *p = buf;
+    int cnt = 0;
+    while(*p != '\0')
+    {
+        if(*p == '.')
+        {
+            cnt++;
+            if(cnt == 3)
+            {
+                *p++;
+                *p = '1';
+                *p++;
+                *p = '\0';
+            }
+        }
+        *p++;
+    }
+
+}
+
+void *thread_test_RGMII(void *arg){
+    char cmd[128] = {0};
+    FILE *fp;
+    sprintf(cmd, "%s %s %s %s", "ping -I eth2", rgmii, "-c4", "2>&1");
+    fp=popen(cmd, "r");
+    if(NULL == fp){
+        lynq_factory_response_ttyGS3("popen errorn\n");
+        return NULL;
+    }
+    char lynq_factory_buf[1024] = {0};
+    while (NULL != fgets(lynq_factory_buf,sizeof(lynq_factory_buf),fp))
+    {
+        if(strstr(lynq_factory_buf, "Usage"))
+        {
+            lynq_factory_response_ttyGS3("RGMII cannot recognize IP addresses\n");
+            lynq_factory_response_ttyGS3("ERROR\n");
+            pclose(fp);
+            return NULL;
+        }
+        lynq_factory_response_ttyGS3(lynq_factory_buf);
+    }
+    lynq_factory_response_ttyGS3("OK\n");
+    pclose(fp);
+    return NULL;
+}
+
+static void lynq_test_RGMII(char *argv){
+    if(argv == NULL)
+    {
+        lynq_factory_response_ttyGS3("\nERROR\n");
+        return;
+    }
+    strcpy(rgmii, argv);
+    pthread_t thid;
+    pthread_attr_t a;
+    pthread_attr_init(&a);
+    pthread_attr_setdetachstate(&a, PTHREAD_CREATE_DETACHED);
+    if(pthread_create(&thid, &a, thread_test_RGMII, NULL) != 0) {
+        return;
+    }
+    //pthread_join(thid, NULL);
+    return;
+}
+
+/**
+ * @brief factory test for sgmii
+ * 
+ */
+void *thread_test_SGMII_wtf(void *arg){
+    FILE *fp;
+    char cmd[128] = {0};
+    sprintf(cmd, "%s %s %s %s", "ping -I eth1", sgmii, "-c4", "2>&1");
+    fp=popen(cmd, "r");
+    if(NULL == fp){
+        lynq_factory_response_ttyGS3("popen errorn\n");
+        return NULL;
+    }
+    char lynq_factory_buf[1024] = {0};
+    while (NULL != fgets(lynq_factory_buf,sizeof(lynq_factory_buf),fp))
+    {
+        if(strstr(lynq_factory_buf, "Usage"))
+        {
+            lynq_factory_response_ttyGS3("SGMII cannot recognize IP addresses\n");
+            lynq_factory_response_ttyGS3("ERROR\n");
+            pclose(fp);
+            return NULL;
+        }
+        lynq_factory_response_ttyGS3(lynq_factory_buf);
+    }
+    lynq_factory_response_ttyGS3("OK\n");
+    pclose(fp);
+    return NULL;
+}
+
+/**
+ * @brief factory test for sgmii
+ * 
+ */
+static void lynq_test_SGMII(char *argv){
+    if(argv == NULL)
+    {
+        lynq_factory_response_ttyGS3("\nERROR\n");
+        return;
+    }
+    strcpy(sgmii, argv);
+    pthread_t thid;
+    pthread_attr_t a;
+    pthread_attr_init(&a);
+    pthread_attr_setdetachstate(&a, PTHREAD_CREATE_DETACHED);
+    if(pthread_create(&thid, &a, thread_test_SGMII_wtf, NULL) != 0) {
+        return;
+    }
+    //pthread_join(thid, NULL);
+    return;
+}
+
+
+static void lynq_gps_open(char *num){
+    if(already_gps == 1){
+        lynq_factory_response_ttyGS3("gps already open\n");
+        return;
+    }
+    if(num == NULL)
+    {
+        return;
+    }
+    gps_set = atoi(num);
+    pthread_attr_t attr;
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+    int ret = pthread_create(&lynq_gps_tid, NULL, thread_test, NULL);
+    if(ret < 0)
+    {
+        lynq_factory_response_ttyGS3("gps thread create failure!!!\n");
+        return;
+    }
+    already_gps = 1;
+    return;
+}
+
+static void lynq_gps_enable(void){
+   
+    enable_nema = 1;
+    lynq_factory_response_ttyGS3("+GPS ENABLE:OK\n");
+    return;
+}
+
+static void lynq_gps_disable(void)
+{
+    enable_nema = 0;
+    lynq_factory_response_ttyGS3("+GPS DISABLE:OK\n");
+    return;
+}
+
+static void lynq_gps_close(void)
+{
+    already_gps = 0;
+    enable_nema = 0;
+    system("killall lynq-gnss-test");
+    lynq_factory_response_ttyGS3("+GPS CLOSE:OK\n");
+    return;
+}
+
+int lynq_dispose_factory_adc(int num,char *argv[MAX_ARGS])
+{
+    if(num != 5)
+    {
+        lynq_factory_response_ttyGS3("+ADC ERROR: 100");
+        return -1;
+    }
+    FILE *fp;
+    char lynq_adc_dev[126] = {0};
+    char lynq_adc_buf[32] = {0};
+    int lynq_adc_num = atoi(argv[4]);
+    char flag[64] = {0};
+    if(lynq_adc_num == 0)
+    {
+        sprintf(lynq_adc_dev,"cat /sys/bus/iio/devices/iio:device1/in_voltage0_input  2>&1");
+    }
+    else if(lynq_adc_num == 1)
+    {
+        sprintf(lynq_adc_dev,"cat /sys/bus/iio/devices/iio:device1/in_voltage1_input  2>&1");
+    }
+    else if(lynq_adc_num == 2)
+    {
+        sprintf(lynq_adc_dev,"cat /sys/bus/iio/devices/iio:device1/in_voltage2_input  2>&1");
+    }
+    else if(lynq_adc_num == 3)
+    {
+        sprintf(lynq_adc_dev,"cat /sys/bus/iio/devices/iio:device1/in_voltage3_input  2>&1");
+    }
+    fp=popen(lynq_adc_dev, "r");
+    fgets(lynq_adc_buf,sizeof(lynq_adc_buf),fp);
+    sprintf(flag,"%s %s", "ADC:", lynq_adc_buf);
+    lynq_factory_response_ttyGS3(flag);
+    lynq_factory_response_ttyGS3("OK\n");
+    pclose(fp);
+    return 1;
+}
+
+int lynq_dispose_factory_usb(int num,char *argv[MAX_ARGS])
+{
+    FILE *fp;
+    char lynq_usb_dev[512] = {0};
+    char lynq_usb_buf[512];
+    bzero(lynq_usb_buf, 512);
+    bzero(lynq_usb_dev,512);
+    sprintf(lynq_usb_dev,"cat /sys/devices/platform/11201000.usb/udc/11201000.usb/current_speed  2>&1");
+    fp=popen(lynq_usb_dev, "r");
+    fgets(lynq_usb_buf,sizeof(lynq_usb_buf),fp);
+    if(!strncmp(lynq_usb_buf,usb3_speed,strlen(usb3_speed)))
+    {   
+        lynq_factory_response_ttyGS3("[usb][result],3.0 \n");
+        lynq_factory_response_ttyGS3("OK\n");
+    }
+    else if(!strncmp(lynq_usb_buf,usb2_speed,strlen(usb2_speed)))
+    {
+        lynq_factory_response_ttyGS3("[usb][result],2.0 \n");
+        lynq_factory_response_ttyGS3("OK\n");
+    }
+    pclose(fp);
+    return 1;
+}
+
+void *lynq_deal_witch_audio(void *arg)
+{
+    char lynq_adudio_time_arr[128] = {0};
+    char *lynq_argv  = (char *)arg;
+    pthread_mutex_lock(&lynq_audio_mutex);
+    lynq_factory_response_ttyGS3("OK\n");
+    system("echo write_reg,0x002c,0x0008 > /sys/kernel/debug/mtksocaudio");
+    system("echo write_reg,0x0030,0x0010 > /sys/kernel/debug/mtksocaudio");
+    sprintf(lynq_adudio_time_arr,"arecord -D plughw:0,1 --buffer-size=1024 -r 16000 -d %s -f S16_LE -c1 | aplay -D plughw:0,7 --buffer-size=1024 -r 16000 -d %s -f S16_LE -c1",lynq_argv,lynq_argv);
+//    system("arecord -D plughw:0,1 --buffer-size=1024 -r 16000 -d 2 -f S16_LE -c1 | aplay -D plughw:0,7 --buffer-size=1024 -r 16000 -d 2 -f S16_LE -c1 ");
+    system(lynq_adudio_time_arr);
+    free(lynq_argv);
+    lynq_argv = NULL;
+    pthread_mutex_unlock(&lynq_audio_mutex);
+    pthread_exit(0);
+}
+
+int lynq_dispose_factory_audio(int num,char *argv[MAX_ARGS])
+{
+    pthread_t id;
+    int i,ret;
+    char *lynq_audio_time = (char *)malloc(16);
+    bzero(lynq_audio_time, 16);
+    if(lynq_audio_time != NULL)
+    {
+        memcpy(lynq_audio_time,argv[4],strlen(argv[4]));
+    } 
+    ret=pthread_create(&id,NULL,lynq_deal_witch_audio,(char *)lynq_audio_time); 
+    if(ret!=0)
+    {
+        return ret;
+    }
+    //pthread_join(id,NULL);
+    return 0;
+}
+
+int lynq_check_emmc()
+{
+    FILE *fp;
+    char emmc_buf[100] = {0};
+    char buf[100] = {0};
+    sprintf(emmc_buf, "ls /dev | grep mmcblk0  2>&1");
+    fp=popen(emmc_buf, "r");
+    if(!fp){
+        lynq_factory_response_ttyGS3("\n+CME: POPEN ERROR\n");
+        return -1;
+    }
+    while(fgets(buf, sizeof(buf), fp) != NULL){
+        lynq_factory_response_ttyGS3("+EMMC: OK \n"); 
+        pclose(fp);
+        return 0;   
+    }
+    lynq_factory_response_ttyGS3("\033[47;31m+EMMC: ERROR\033[0m\n");
+    pclose(fp);
+    return 0;
+}
+
+int lynq_check_gpio()
+{
+    #if 1
+    FILE *fp;
+    
+    int lynq_gpio_arr[85] = {230,231,232,233,234,102,104,103,101,186 ,188 ,187 ,185 ,194 ,196 ,195 ,193 ,205 ,204 ,203 ,202, 201 ,190 ,192 ,191 ,189 ,173 ,174 ,175 ,176 ,170 ,169 ,184 ,183 ,182 ,181 ,24 ,25 ,157 ,158 ,155 ,156 ,143 ,144 ,140 ,141 ,153 ,154 ,180 ,179 ,29 ,30 ,178, 177, 7 ,5 ,4 ,113 ,112, 116 ,115 ,114, 107, 108, 105, 106, 100 ,99 ,98, 97, 94, 93, 92, 91, 1 ,130 ,41 ,67 ,69, 68, 63, 22, 23, 199, 200};
+    char lynq_set_gpio_arr[256] = {0};
+    char lynq_get_gpio_state[512] = {0};
+    char lynq_show_gpio_state[64] = {0};
+    int lynq_gpio_low = 0;
+    int lynq_gpio_hig = 0;
+    int i = 0,m = 0;
+    int lynq_gpio_beta_state = 1;
+
+    for(m = 0; m < 85; m++)
+    {
+        bzero(lynq_set_gpio_arr, 256);
+        sprintf(lynq_set_gpio_arr,"echo mode %d 0 > /sys/devices/platform/10005000.pinctrl/mt_gpio",(char*)lynq_gpio_arr[m]);
+        system(lynq_set_gpio_arr);
+        bzero(lynq_set_gpio_arr, 256);
+        sprintf(lynq_set_gpio_arr,"echo out %d 0 > /sys/devices/platform/10005000.pinctrl/mt_gpio",(char*)lynq_gpio_arr[m]);
+        system(lynq_set_gpio_arr);
+    }
+
+    for(i = 0; i < 85; i++)
+    {
+        lynq_gpio_low = 0;
+        lynq_gpio_hig = 0;
+
+        bzero(lynq_set_gpio_arr, 256);
+        sprintf(lynq_set_gpio_arr,"echo mode %d 0 > /sys/devices/platform/10005000.pinctrl/mt_gpio",(char*)lynq_gpio_arr[i]);
+        system(lynq_set_gpio_arr);
+
+        bzero(lynq_set_gpio_arr, 256);
+        sprintf(lynq_set_gpio_arr,"echo out %d 1 > /sys/devices/platform/10005000.pinctrl/mt_gpio",(char*)lynq_gpio_arr[i]);
+        system(lynq_set_gpio_arr);
+
+        bzero(lynq_set_gpio_arr, 256);
+        sprintf(lynq_set_gpio_arr,"cat /sys/devices/platform/10005000.pinctrl/mt_gpio | grep 006");
+        fp=popen(lynq_set_gpio_arr, "r");
+        bzero(lynq_get_gpio_state, 512);
+        fgets(lynq_get_gpio_state,sizeof(lynq_get_gpio_state),fp);
+/*     
+        if(strlen(lynq_get_gpio_state) > 0)
+        {
+            lynq_factory_response_ttyGS3(lynq_get_gpio_state);
+            lynq_factory_response_ttyGS3("\n");
+        }
+*/
+        pclose(fp);
+        if(lynq_get_gpio_state[7] == '1')
+        {
+            lynq_gpio_hig = 1;
+        }
+
+        bzero(lynq_set_gpio_arr, 256);
+        sprintf(lynq_set_gpio_arr,"echo out %d 0 > /sys/devices/platform/10005000.pinctrl/mt_gpio",(char*)lynq_gpio_arr[i]);
+        system(lynq_set_gpio_arr);
+        
+        bzero(lynq_set_gpio_arr, 256);
+        sprintf(lynq_set_gpio_arr,"cat /sys/devices/platform/10005000.pinctrl/mt_gpio | grep 006");
+        fp=popen(lynq_set_gpio_arr, "r");
+        bzero(lynq_get_gpio_state, 512);
+        fgets(lynq_get_gpio_state,sizeof(lynq_get_gpio_state),fp);
+        pclose(fp);
+        if(lynq_get_gpio_state[7] == '0')
+        {
+            lynq_gpio_low = 1;
+        }
+        bzero(lynq_show_gpio_state, 64);
+        if((lynq_gpio_low != 1) || (lynq_gpio_hig != 1))
+        {
+            lynq_gpio_beta_state = 0;
+            sprintf(lynq_show_gpio_state,"[gpio%d][result]:FAIL \n",(char *)lynq_gpio_arr[i]);
+            lynq_factory_response_ttyGS3(lynq_show_gpio_state);
+        }
+        else
+        {
+            sprintf(lynq_show_gpio_state,"gpio%d\n",(char *)lynq_gpio_arr[i]);
+            lynq_factory_response_ttyGS3(lynq_show_gpio_state);
+        }
+    }
+    if(lynq_gpio_beta_state == 1)
+    {
+        sprintf(lynq_show_gpio_state,"[gpio][result]:PASS \n");
+        lynq_factory_response_ttyGS3(lynq_show_gpio_state);
+    }
+    return 0;
+    #endif
+}
+
+int lynq_test_sink(){
+    FILE *fp;
+    char lynq_usb_dev[512] = {0};
+    char lynq_usb_buf[512] = {0};
+    char buf[512] = {0};
+    int sink[3][3] = {{255,0,0},{0,255,0},{0,0,255}};
+    char dev_buf[][40]={{"green:cellular-radio/brightness"},{"green:cellular-quality/brightness"},{"red:system/brightness"}};
+    int i;
+    int j;
+    int k = 15;
+    char flag_buf[64] = {0};
+    for(i = 0;i < 3;i++){
+        bzero(flag_buf, 64);
+        bzero(lynq_usb_buf, 512);
+        bzero(buf, 512);
+        k = 15;
+        for(j = 0;j < 3;j++){
+            bzero(lynq_usb_dev, 512);
+            sprintf(lynq_usb_dev,"echo %d >  /sys/class/leds/led95%d:%s  2>&1", sink[i][j], k++, dev_buf[j]);
+            fp=popen(lynq_usb_dev, "r");
+        }
+        usleep(10000);
+        sprintf(lynq_usb_buf,"cat /sys/bus/iio/devices/iio:device1/in_voltage4_input  2>&1");
+        fp=popen(lynq_usb_buf, "r");
+        
+        fgets(buf, sizeof(buf), fp);
+        sprintf(flag_buf, "%s%d%s%s%s", "SINK[", i+1, "]: ", buf, "\n");
+        lynq_factory_response_ttyGS3(flag_buf);
+    }
+    lynq_factory_response_ttyGS3("OK\n");
+    pclose(fp);
+    return 1;
+}
+
+int lynq_check_pcie(void){
+    FILE *fp;
+    char lynq_usb_dev[128] = {0};
+    char lynq_get_gpio_state[512] = {0};
+    sprintf(lynq_usb_dev,"cat sys/devices/platform/10005000.pinctrl/mt_gpio |grep 097  2>&1");
+    fp=popen(lynq_usb_dev, "r");
+    fgets(lynq_get_gpio_state,sizeof(lynq_get_gpio_state),fp);
+    pclose(fp);
+    if(lynq_get_gpio_state[6] == '1')
+    {
+        lynq_factory_response_ttyGS3("+PCIE: OK\n");
+    }
+    else
+    {
+        lynq_factory_response_ttyGS3("+PCIE: ERROR\n");
+    }
+    return 0;
+}
+
+void lynq_switch_card(char *card)
+{
+    char *sim_argv[3] = {};
+    sim_argv[0] = "SET_DEFAULT_SIM_ALL";
+    sim_argv[1] = card;
+    sim_argv[2] = "sleep";
+    android::lynqSendToRil(2,sim_argv,8888);
+    sleep(1);
+    return;
+}
+
+static void lynq_get_imei(int argc, char *argv[MAX_ARGS])
+{
+    lynqSendAt(argc,argv,1010);
+    /*switch card 1*/
+    lynq_switch_card("1");
+    lynqSendAt(argc,argv,1010);
+    /*switch card 0*/
+    lynq_switch_card("0");
+    return;
+}
+
+void lynq_nema_set(char *choice)
+{
+    if(choice == NULL)
+    {
+        lynq_factory_response_ttyGS3("INPUT ERROR\n");
+    }
+    g_set_output = atoi(choice);
+    lynq_factory_response_ttyGS3("+SET NEMA:OK\n");
+    return;
+}
+
+void lynq_sendRequestToMd(int request, int id) {
+    RequestInfo* info = creatRILInfoAndInit(request, INIT, (RIL_SOCKET_ID) ((id)));
+    info->lynqEvent = 1;
+    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);
+            }
+    }
+}
+
+int lynq_get_factory_data(int num,char *argv[MAX_ARGS]){
+    if(!strcmp(argv[1],"AT+CGSN"))
+    {
+        for(int i = 0; i < 2; i++)
+        {
+            lynq_sendRequestToMd(RIL_REQUEST_DEVICE_IDENTITY,i);
+        }
+    }
+    if(num < 4)
+        return -1;
+    else if(!strcmp(argv[3], "gps_open")){
+        lynq_gps_open(argv[4]);
+    }
+    else if(!strcmp(argv[3], "gps_enable")){
+        lynq_gps_enable();
+    }
+    else if(!strcmp(argv[3], "gps_disable")){
+        lynq_gps_disable();
+    }
+    else if(!strcmp(argv[3], "gps_close")){
+        lynq_gps_close();
+    }
+    else if(!strcmp(argv[3], "sink")){
+        lynq_test_sink();
+    }
+    else if(!strcmp(argv[3], "rgmii")){
+        lynq_test_RGMII(argv[4]);
+    }
+    else if(!strcmp(argv[3], "sgmii")){
+        lynq_test_SGMII(argv[4]);
+    }
+    else if((!strcmp(argv[3],"adc")))
+    {
+        lynq_dispose_factory_adc(num,argv);
+    }
+    else if((!strcmp(argv[3],"usb")))
+    {
+         lynq_dispose_factory_usb(num,argv);
+    }
+    else if((!strcmp(argv[3], "emmc")))
+    {
+        lynq_check_emmc();
+    }
+    else if((!strcmp(argv[3],"gpio")))
+    {
+        lynq_check_gpio();
+    }
+    else if((!strcmp(argv[3],"pcie")))
+    {
+        lynq_check_pcie();
+    }
+    else if((!strcmp(argv[3],"nema_set")))
+    {
+        lynq_nema_set(argv[4]);
+    }
+    else{
+        lynq_factory_response_ttyGS3("invalid command\n"); 
+    }
+    return 0;
+}
+
+#ifdef __cplusplus
+}
+#endif
\ No newline at end of file
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/factory/lynq_factory.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/factory/lynq_factory.h
new file mode 100755
index 0000000..bc14687
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/factory/lynq_factory.h
@@ -0,0 +1,14 @@
+#ifndef __LYNQ_FACTORY_H__
+#define __LYNQ_FACTORY_H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MAX_ARGS 101
+int lynq_get_factory_data(int num,char *argv[MAX_ARGS]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
\ No newline at end of file
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/led/include/led.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/led/include/led.h
new file mode 100755
index 0000000..d8d6508
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/led/include/led.h
@@ -0,0 +1,44 @@
+/**

+ * @file led.h

+ * @author hq

+ * @brief 

+ * @version 1.0

+ * @date 2022-11-28

+ * 

+ * @copyright Copyright (c) 2022

+ * 

+ */

+#ifdef LED_SUPPORT 

+#ifndef LED_H

+#define LED_H 1

+

+#define wait_led_update_effective_timer_ms 20

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+typedef enum

+{

+    GPIO_NETLED_REFLASH_NORMAL,

+    GPIO_NETLED_CS_CALLING,

+    GPIO_NETLED_CS_CALLEND,

+    GPIO_NETLED_PPP_CONNECT,

+    GPIO_NETLED_PPP_CLOSED,

+    GPIO_NETLED_AP_GOINGSLEEP,

+    GPIO_NETLED_AP_WAKEUP,

+    GPIO_NETLED_WWAN_CONNECT,

+    GPIO_NETLED_WWAN_CLOSED,

+} mbtk_netled_reflash_type;

+

+void mbtk_netled_state_update(mbtk_netled_reflash_type flag);

+

+void mbtk_netled_init();

+

+void mbtk_netled_deinit();

+

+#ifdef __cplusplus

+}

+#endif

+#endif

+#endif

diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/led/led.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/led/led.cpp
new file mode 100755
index 0000000..a252764
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/led/led.cpp
@@ -0,0 +1,577 @@
+#ifdef LED_SUPPORT

+#include <stdio.h>

+#include <stdlib.h>

+#include <string.h>

+#include <binder/Parcel.h>

+#include <sys/socket.h>

+#include <errno.h>

+#include <unistd.h>

+#include <cutils/jstring.h>

+#include <sys/types.h>

+#include <time.h>
+#include <signal.h>

+#include "led.h"

+#include "led_inner.h"

+#include <liblog/lynq_deflog.h>

+#include "common.h"

+

+#undef LOG_TAG

+#define LOG_TAG "LED"

+

+

+/*************************************************************

+    Constants and Macros

+*************************************************************/

+#define GPIO_NETLED_CONNECT_REFLASH_TIMER   200

+#define GPIO_NETLED_CREG_REFLASH_TIMER   800

+#define MBTK_GPIO_NETLED_N            77

+

+/*************************************************************

+    Extern Function Declaration

+*************************************************************/

+void mbtk_netled_reflash_handle();

+

+/*************************************************************

+    Variables:local,extern

+*************************************************************/

+//static rex_timer_type mbtk_gpio_netled_timer;

+static mbtk_netled_state_t  mbtk_netled_state;

+/*************************************************************

+    Definitions:enum,struct,union

+*************************************************************/

+

+/*=============================================

+FUNCTION

+    mbtk_get_netled_state

+    

+DESCRIPTION

+    This function to return pointer of mbtk_netled_state.

+

+DEPENDENCIES

+    None

+

+PARAMETERS

+    None

+

+RETURN VALUE

+    &mbtk_netled_state

+

+SIDE EFFECTS

+    None

+=============================================*/

+

+mbtk_netled_state_t * mbtk_get_netled_state()

+{

+    return &mbtk_netled_state;

+}

+

+/*=============================================

+FUNCTION

+    mbtk_init_netled_state

+    

+DESCRIPTION

+    This function to init mbtk_netled_state.

+

+DEPENDENCIES

+    None

+

+PARAMETERS

+    None

+

+RETURN VALUE

+    None

+

+SIDE EFFECTS

+    None

+=============================================*/

+

+void mbtk_init_netled_state()

+{

+    mbtk_netled_state_t * netled_state = NULL;

+    netled_state = mbtk_get_netled_state();

+    

+    netled_state->gpio_netled_cs_flag = false;

+    netled_state->gpio_netled_goingsleep_flag = false;

+    netled_state->gpio_netled_ppp_flag = false;

+    netled_state->gpio_netled_wwan_flag = false;

+    

+}

+

+static timer_t s_mbtk_gpio_netled_timer;

+

+static int s_mbtk_gpio_netled_timer_sig_value = 11;  /* 2,3,4 are used by network */

+

+void start_led_timer(timer_t timer, int signal_value, int milliseconds) 

+{

+    RLOGD("start_led_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_led_timer(timer_t timer, int signal_value) {

+    RLOGD("stop_led_timer(), timer_id=%ld, signal_value=%d", (long)timer, signal_value);

+    struct itimerspec timespec;
+    if(timer_gettime(timer, &timespec) == -1) {
+        RLOGE("stop_led_timer(), get time fail(%s)", strerror(errno));

+        return;
+    }
+    RLOGD("stop_led_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_led_timer(), timer_id(%ld) had stopped, just return", (long)timer);

+        return;
+    } else {
+        start_led_timer(timer, signal_value, 0);

+    }
+}

+

+static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;

+void led_timer_handler(sigval_t sig) 

+{    

+    RLOGD("led_timer_handler, sig_value: %d", sig.sival_int);

+    int s;   

+    s = pthread_mutex_lock(&mtx);

+    if(s != 0) {

+        RLOGE("led_timer_handler, pthead_mutex_lock fail");

+    }   

+    if(sig.sival_int == s_mbtk_gpio_netled_timer_sig_value) 

+    {

+        mbtk_netled_reflash_handle();

+    }    

+    s = pthread_mutex_unlock(&mtx);

+    if(s != 0) {

+        RLOGE("led_timer_handler, pthead_mutex_unlock fail");

+    }   

+}

+

+void init_led_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 = led_timer_handler;

+
+    if(timer_create(CLOCK_MONOTONIC, &sevp, timer) == -1) {
+        RLOGE("init_led_timer()  failed reason=[%s]", strerror(errno));

+    }
+    RLOGD("init_led_timer(), timer_Id = %ld, signal_value=%d", (long)(*timer), signal_value);

+}
+
+void init_led_timer_all() 

+{

+    init_led_timer(&s_mbtk_gpio_netled_timer,s_mbtk_gpio_netled_timer_sig_value);   

+}

+

+void deinit_led_timer_all() 

+{

+    stop_led_timer(s_mbtk_gpio_netled_timer,s_mbtk_gpio_netled_timer_sig_value);    

+}

+

+/*=============================================

+FUNCTION

+    mbtk_netled_init

+    

+DESCRIPTION

+    This function to init timer

+

+DEPENDENCIES

+    None

+

+PARAMETERS

+    param    not used

+

+RETURN VALUE

+    None

+

+SIDE EFFECTS

+    None

+=============================================*/

+void mbtk_netled_init()

+{

+    mbtk_init_netled_state();

+    init_led_timer_all();   

+}

+

+/*=============================================

+FUNCTION

+    mbtk_netled_deinit

+    

+DESCRIPTION

+    This function to init timer

+

+DEPENDENCIES

+    None

+

+PARAMETERS

+    param    not used

+

+RETURN VALUE

+    None

+

+SIDE EFFECTS

+    None

+=============================================*/

+void mbtk_netled_deinit()

+{

+    deinit_led_timer_all();   

+}

+

+

+/*=============================================

+FUNCTION

+    mbtk_get_at_netled_cmd

+    

+DESCRIPTION

+    This function to return netled switch value.

+

+DEPENDENCIES

+    None

+

+PARAMETERS

+    None

+

+RETURN VALUE

+    int

+

+SIDE EFFECTS

+    None

+=============================================*/

+

+int mbtk_get_at_netled_cmd(void)

+{

+    return 1;

+//    return (int) dsatutil_get_val(MBTK_AT_GPIO_CGNETLED_IDX,0,0,NUM_TYPE);

+}

+

+/*=============================================

+FUNCTION

+    mbtk_get_reg_net_status

+    

+DESCRIPTION

+    This function that determine if net registers successfully.

+    

+DEPENDENCIES

+    None

+

+PARAMETERS

+    param    not used

+

+RETURN VALUE

+    mbtk_netled_reg_net_status

+

+SIDE EFFECTS

+    None

+=============================================*/

+

+mbtk_netled_reg_net_status  mbtk_get_reg_net_status(void)

+{

+    if(false  == ril_get_if_insert_simcard())

+    {

+        RLOGE("ril_get_if_insert_simcard false" );

+        return NET_REG_FAIL;

+    }

+   

+    if(true == ril_get_if_3gpp_reg_success())

+    {

+        RLOGD("ril_get_if_3gpp_reg_success true");

+        return NET_REG_SUCCESS;

+    }

+

+    if(true == ril_get_if_3gpp_data_reg_success())

+    {

+        RLOGD("ril_get_if_3gpp_data_reg_success true");

+        return NET_REG_SUCCESS;

+    }	

+

+    return NET_REG_FAIL;

+}

+

+/*=============================================

+FUNCTION

+    mbtk_netled_get_socket_conn_status

+    

+DESCRIPTION

+    This function that socket connects successfully.

+

+DEPENDENCIES

+    None

+

+PARAMETERS

+    param    not used

+

+RETURN VALUE

+    mbtk_netled_socket_conn_status

+

+SIDE EFFECTS

+    None

+=============================================*/

+

+mbtk_netled_socket_conn_status  mbtk_netled_get_socket_conn_status(void)

+{

+    mbtk_netled_socket_conn_status  socket_conn_status = MBTK_SOCKET_DISCONNECT; 

+    mbtk_netled_state_t * netled_state =  mbtk_get_netled_state();    

+

+    if(netled_state->gpio_netled_ppp_flag || netled_state->gpio_netled_wwan_flag)

+    {

+        RLOGD("GPIO: ppp wwan netled state sockNum %d,%d",

+        netled_state->gpio_netled_ppp_flag, netled_state->gpio_netled_wwan_flag);

+        

+        socket_conn_status = MBTK_SOCKET_CONNECTED;

+        return socket_conn_status;

+    }   

+

+    return socket_conn_status;

+

+}

+

+/*=============================================

+FUNCTION

+    mbtk_netled_get_current_state

+    

+DESCRIPTION

+    get the netled status .

+

+DEPENDENCIES

+    None

+

+PARAMETERS

+    param    not used

+

+RETURN VALUE

+    mbtk_netled_status_type

+

+SIDE EFFECTS

+    None

+=============================================*/

+mbtk_netled_status_type mbtk_netled_get_current_state(void)

+{

+    mbtk_netled_reg_net_status reg_net_status = NET_REG_FAIL;

+    mbtk_netled_status_type netled_status_type = GPIO_NETLED_OFF;

+    mbtk_netled_socket_conn_status socket_conn_status = MBTK_SOCKET_DISCONNECT;

+    int mbtk_netled_at_cmd_value = mbtk_get_at_netled_cmd();  //  0 -- close netled / 1 -- open netled

+    mbtk_netled_state_t * netled_state =  mbtk_get_netled_state();

+    

+    if(mbtk_netled_at_cmd_value == 0 || 

+       netled_state->gpio_netled_goingsleep_flag == true)

+    {

+        netled_status_type = GPIO_NETLED_OFF;

+        return netled_status_type;

+    }

+

+    reg_net_status = mbtk_get_reg_net_status();

+    if( NET_REG_FAIL == reg_net_status || true == netled_state->gpio_netled_cs_flag )

+    {

+        netled_status_type = GPIO_NETLED_LIGHT;

+    }

+    else if( NET_REG_SUCCESS == reg_net_status )

+    {

+        socket_conn_status = mbtk_netled_get_socket_conn_status();

+        

+        if( MBTK_SOCKET_CONNECTED == socket_conn_status )

+        {

+            netled_status_type = GPIO_NETLED_CONNECT;

+        }

+        else if( MBTK_SOCKET_DISCONNECT == socket_conn_status )

+        {

+            netled_status_type = GPIO_NETLED_REG;

+        }

+    } 

+    return netled_status_type;

+}

+

+

+

+bool is_mbtk_timer_finish() {

+    struct itimerspec timespec;
+    if(timer_gettime(s_mbtk_gpio_netled_timer, &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)s_mbtk_gpio_netled_timer);

+        return true;
+    }

+	return false;

+}

+

+/*=============================================

+FUNCTION

+    mbtk_netled_state_update

+    

+DESCRIPTION

+    This function to reflash network led status and write gpio value

+

+DEPENDENCIES

+    None

+

+PARAMETERS

+    param     flag

+

+RETURN VALUE

+    None

+

+SIDE EFFECTS

+    None

+=============================================*/

+void mbtk_netled_state_update(mbtk_netled_reflash_type flag)

+{

+//  rex_timer_cnt_type prev_value;

+    mbtk_netled_state_t * netled_state = NULL;

+    netled_state = mbtk_get_netled_state();

+    

+    switch (flag)

+    {

+        case GPIO_NETLED_REFLASH_NORMAL:

+             break;

+        case GPIO_NETLED_CS_CALLING:

+             netled_state->gpio_netled_cs_flag = true;

+             break;

+        case GPIO_NETLED_PPP_CONNECT:

+             netled_state->gpio_netled_ppp_flag = true;

+             break;

+        case GPIO_NETLED_PPP_CLOSED:

+             netled_state->gpio_netled_ppp_flag = false;

+             break;

+        case GPIO_NETLED_CS_CALLEND:

+             netled_state->gpio_netled_cs_flag = false;

+             break;

+        case GPIO_NETLED_AP_GOINGSLEEP:

+             netled_state->gpio_netled_goingsleep_flag = true;

+             break;

+        case GPIO_NETLED_AP_WAKEUP:

+             netled_state->gpio_netled_goingsleep_flag = false;

+             break;

+        case GPIO_NETLED_WWAN_CONNECT:

+             netled_state->gpio_netled_wwan_flag = true;

+             break;

+        case GPIO_NETLED_WWAN_CLOSED:

+             netled_state->gpio_netled_wwan_flag = false;

+             break;

+

+    }

+

+    //prev_value = rex_get_timer(&mbtk_gpio_netled_timer);

+//    prev_value = timer_get_64(&mbtk_gpio_netled_timer, T_MSEC);

+//    if( prev_value == 0)

+	if((flag== GPIO_NETLED_AP_GOINGSLEEP) || is_mbtk_timer_finish())

+    {

+ //     MBTK_MSG1_HIGH("GPIO: rex_get_timer prev_value =%d",prev_value);

+       //rex_set_timer(&mbtk_gpio_netled_timer, 1);

+       //timer_set_64(&mbtk_gpio_netled_timer,1,0,T_MSEC);

+        start_led_timer(s_mbtk_gpio_netled_timer, s_mbtk_gpio_netled_timer_sig_value, 1);        

+    }

+

+    return ;

+}

+

+/*=============================================

+FUNCTION

+    mbtk_netled_reflash_handle

+    

+DESCRIPTION

+    This function to reflash network led status and write gpio value

+

+DEPENDENCIES

+    None

+

+PARAMETERS

+    param    not used

+

+RETURN VALUE

+    None

+

+SIDE EFFECTS

+    None

+=============================================*/

+

+void mbtk_gpio_write_output(int gpio_port, int value)

+{

+    if(value==1)

+    {

+        system("echo 255 > /sys/class/leds/led9515:green:cellular-radio/brightness");

+    }  

+	else 

+	{

+	    system("echo 0 > /sys/class/leds/led9515:green:cellular-radio/brightness");

+	}

+}

+

+/*=============================================

+FUNCTION

+    mbtk_netled_reflash_handle

+    

+DESCRIPTION

+    This function to reflash network led status and write gpio value

+

+DEPENDENCIES

+    None

+

+PARAMETERS

+    param    not used

+

+RETURN VALUE

+    None

+

+SIDE EFFECTS

+    None

+=============================================*/

+void mbtk_netled_reflash_handle()

+{

+    mbtk_netled_status_type state = GPIO_NETLED_MAX;

+    state = mbtk_netled_get_current_state();

+    RLOGD("mbtk_netled_get_current_state  state = %d",state);

+    static int led_val = 0;

+

+    switch(state)

+    {

+        case GPIO_NETLED_OFF:

+             {

+                 if( 0 != led_val )

+                 {

+                     led_val = 0;

+                     mbtk_gpio_write_output(MBTK_GPIO_NETLED_N, 0);

+                 }

+             }

+             break;

+        case GPIO_NETLED_REG:

+             {

+                led_val = ( (1 == led_val)? 0:1 );

+                mbtk_gpio_write_output(MBTK_GPIO_NETLED_N, led_val);

+                start_led_timer(s_mbtk_gpio_netled_timer, s_mbtk_gpio_netled_timer_sig_value, GPIO_NETLED_CREG_REFLASH_TIMER);

+				

+              //  timer_set_64(&mbtk_gpio_netled_timer,GPIO_NETLED_CREG_REFLASH_TIMER,0,T_MSEC);

+                //rex_set_timer(&mbtk_gpio_netled_timer, GPIO_NETLED_CREG_REFLASH_TIMER);

+             }

+             break;

+        case GPIO_NETLED_CONNECT:

+             {

+                 led_val = ( (1 == led_val)? 0:1 );

+                 mbtk_gpio_write_output(MBTK_GPIO_NETLED_N, led_val);

+        		 start_led_timer(s_mbtk_gpio_netled_timer, s_mbtk_gpio_netled_timer_sig_value, GPIO_NETLED_CONNECT_REFLASH_TIMER);

+                // timer_set_64(&mbtk_gpio_netled_timer,GPIO_NETLED_CONNECT_REFLASH_TIMER,0,T_MSEC);

+                 //rex_set_timer(&mbtk_gpio_netled_timer, GPIO_NETLED_CONNECT_REFLASH_TIMER);

+             }

+             break;

+        case GPIO_NETLED_LIGHT:

+             {

+                 if( 1 != led_val )

+                 {

+                     led_val = 1;

+                     mbtk_gpio_write_output(MBTK_GPIO_NETLED_N, 1);

+                 }

+             }

+             break;

+        default:

+             RLOGE("GPIO: Unkown netled state !");

+    }

+}

+#endif

diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/led/led_inner.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/led/led_inner.h
new file mode 100755
index 0000000..5b0750d
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/led/led_inner.h
@@ -0,0 +1,61 @@
+/**

+ * @file led_inner.h

+ * @author hq

+ * @brief 

+ * @version 1.0

+ * @date 2022-11-28

+ * 

+ * @copyright Copyright (c) 2022

+ * 

+ */

+#ifdef LED_SUPPORT 

+#ifndef LED_INNER_H

+#define LED_INNER_H 1

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+/*************************************************************

+    Definitions:enum,struct,union,class

+*************************************************************/

+typedef struct {

+    bool gpio_netled_cs_flag;

+    bool gpio_netled_ppp_flag;

+    bool gpio_netled_wwan_flag;

+    bool gpio_netled_goingsleep_flag;

+}mbtk_netled_state_t;

+

+typedef enum

+{

+    GPIO_NETLED_OFF,

+    GPIO_NETLED_REG,

+    GPIO_NETLED_CONNECT,

+    GPIO_NETLED_LIGHT,

+    GPIO_CS_REG,

+    GPIO_NETLED_MAX

+}mbtk_netled_status_type;

+

+typedef enum

+{

+    NET_REG_SUCCESS,

+    NET_REG_FAIL,

+    NET_REG_MAX

+}mbtk_netled_reg_net_status;

+

+typedef enum

+{

+    MBTK_SOCKET_CONNECTED,

+    MBTK_SOCKET_DISCONNECT,

+    MBTK_SOCKET_CONN_MAX

+}mbtk_netled_socket_conn_status;

+

+/*************************************************************

+    Function Declaration

+*************************************************************/

+

+#ifdef __cplusplus

+}

+#endif

+#endif

+#endif

diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_at.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_at.cpp
new file mode 100755
index 0000000..6ff642c
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_at.cpp
@@ -0,0 +1,40 @@
+/*============================================================================= 
+**     FileName: lynq_at.cpp
+**     Desc: lynq Send at to modem directly
+**     Author: Warren
+**     Version: V1.0
+**     LastChange: 2021-09-28 
+**     History: 
+**=============================================================================*/

+#include "lynq_at.h"

+#include "common.h"

+#include "stateManager/stateManager.h"
+#include "Phone_utils.h"
+#include "utils.h"
+

+int lynqSendAt(int argc,char *argv[],int uToken)

+{

+    int request = RIL_REQUEST_OEM_HOOK_RAW;
+    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 || (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));

+    pRI->lynqEvent=1;

+    printf("Warren test ====> argv[1]=%s\n",argv[1]);

+    sendATCMD(2, argv,id,pRI);

+    return 0;

+}

+

diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_at.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_at.h
new file mode 100755
index 0000000..52bc79c
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_at.h
@@ -0,0 +1,12 @@
+/*============================================================================= 
+**     FileName: lynq_at.h
+**     Desc: lynq Send at to modem directly
+**     Author: Warren
+**     Version: V1.0
+**     LastChange: 2021-09-28 
+**     History: 
+**=============================================================================*/

+#ifndef LYNQ_AT
+#define LYNQ_AT

+int lynqSendAt(int argc,char *argv[],int uToken);

+#endif

diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_at_transfer_table.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_at_transfer_table.h
new file mode 100755
index 0000000..46b73fc
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_at_transfer_table.h
@@ -0,0 +1,22 @@
+{LYNQ_REQUEST_ATD,"ATD",7},

+{LYNQ_REQUEST_CGCMOD,"CGCMOD",0},

+{LYNQ_REQUEST_CGAUTO,"CGAUTO",0},

+{LYNQ_REQUEST_CGACT,"CGACT",4},

+{LYNQ_REQUEST_CGDCONT,"CGDCONT",4},

+{LYNQ_USER_REQUEST_GNSS,"LYNQGNSS",7},

+{LYNQ_USER_REQUEST_OTHRE,"LYNQOTHER",7},

+{LYNQ_REQUEST_LAPNACT,"LAPNACT",7},

+{LYNQ_REQUEST_ELAPNACT,"ELAPNACT",7},

+{LYNQ_REQUEST_SWITCH_SIM,"LCSUS",7},

+{LYNQ_REQUEST_SCREEN_STATE,"SCREEN",7},

+{LYNQ_REQUEST_SEND_LOG_DATA,"LOGS",7},

+{LYNQ_PLAT_LGMDS,"LGMDS",7},

+{LYNQ_REQUEST_RNDIS,"LRNDISHANDLE",7},

+{LYNQ_REQUEST_FACTORY,"LYNQFACTORY",7},

+{LYNQ_REQUEST_LINFO,"LINFO",7},

+{LYNQ_REQUEST_FOTA,"LYNQFOTA",7},

+{LYNQ_REQUEST_INSIDE_VERSION,"CGIR",7},

+{LYNQ_REQUEST_FACTORY,"CGSN",7},

+{LYNQ_REQUEST_TEMP,"LYNQMTSM",1},

+{LYNQ_REQUEST_APN,"LEAPNMOD",7},

+{-1,NULL,0},
\ No newline at end of file
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_commands.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_commands.h
new file mode 100755
index 0000000..8537ae7
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_commands.h
@@ -0,0 +1,22 @@
+/*============================================================================= 
+**     FileName: lynq_command.h
+**     Desc: lynq commands table
+**     Author: Warren
+**     Version: V1.0
+**     LastChange: 2021-10-27 
+**     History: 
+**=============================================================================*/
+{LYNQ_REQUEST_CGMI,NULL,"CGMI",CGMI,NULL},
+{LYNQ_REQUEST_ATD,"RIL_REQUEST_DIAL","ATD",dialACall,NULL},
+{LYNQ_REQUEST_LAPNACT,"RIL_REQUEST_SETUP_DATA_CALL","LAPNACT",setupData,NULL},
+{LYNQ_REQUEST_ELAPNACT,"RIL_REQUEST_SETUP_DATA_CALL","ELAPNACT",setupData_e,NULL},
+{LYNQ_USER_REQUEST_GNSS,NULL,"LYNQGNSS",NULL,lynqGnss},
+{LYNQ_USER_REQUEST_OTHRE,NULL,"LYNQOTHER",NULL,lynqOther},
+{LYNQ_REQUEST_SWITCH_SIM,"SET_DEFAULT_SIM_ALL","LCSUS",lynq_dsds_support,NULL},
+/*lei modify :Low power consumption for factory test only*/
+{LYNQ_REQUEST_SCREEN_STATE,"RIL_REQUEST_RADIO_POWER","SCREEN",lynq_screen,NULL},
+/*lei modify :Low power consumption for factory test only*/
+{LYNQ_PLAT_LGMDS,"LYNQ_PLAT_LGMDS","LGMDS",NULL,getMDstate},
+{LYNQ_REQUEST_INSIDE_VERSION,"LYNQ_PLAT_LGMDS","CGIR",NULL,lynq_get_inside_version},
+{LYNQ_REQUEST_APN,"RIL_REQUEST_MODIFY_APN","LEAPNMOD",lynq_modify_apn_info,NULL},
+{-1,NULL,NULL,NULL,NULL},
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_common.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_common.cpp
new file mode 100755
index 0000000..a5338bc
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_common.cpp
@@ -0,0 +1,943 @@
+/*============================================================================= 
+**     FileName: lynq_common.cpp
+**     Desc: lynq common
+**     Author: Warren
+**     Version: V1.0
+**     LastChange: 2021-09-27 
+**     History: 
+**=============================================================================*/
+
+#include <stdio.h>
+#include <string.h>
+#include <log/log.h>
+#include "lynq_common.h"
+#include "lynq_user.h"
+#include "common.h"
+#include <pthread.h>
+#define USB_BUF_SIZE 8192
+#include <liblog/lynq_deflog.h>
+#include <sys/time.h>
+#include "Phone_utils.h"
+#include "utils.h"
+#include "data_gdbus.h"
+usb_cmd_t Usb_commands[] = {
+#include "lynq_commands.h"
+};
+
+usb_at_transfer_t Usb_transfer_commands[] = {
+#include "lynq_at_transfer_table.h"
+};
+#undef LOG_TAG
+#define LOG_TAG "LYNQ_COMMON"
+
+extern apn_table_t apn_table[LYNQ_APN_CHANNEL_MAX] = {};
+extern int apn_count = 0;
+extern char lynq_at[LYNQ_AT_LEN_MAX]= {};
+char mccmnc[8] = {0};
+pthread_cond_t lynq_at_cond = PTHREAD_COND_INITIALIZER;
+pthread_mutex_t lynq_at_mutex= PTHREAD_MUTEX_INITIALIZER;
+
+
+//int lynqSendToRil(int argc,char *argv[],int uToken);
+usb_at_transfer_t *lynqFindId(char *cmd)
+{
+    if(cmd==NULL)
+    {
+        RLOGD("lynqFindId CMD is NULL!!!");
+        return ((usb_at_transfer_t*)NULL);
+    }
+    for(int i=0;Usb_transfer_commands[i].cmdName;i++)
+    {
+        if (strcmp (cmd, Usb_transfer_commands[i].cmdName) == 0)
+        return (&Usb_transfer_commands[i]);
+    }
+    return ((usb_at_transfer_t*)NULL);
+}
+
+usb_cmd_t * lynqFindUsbEvent(char *cmd)
+{
+    if(cmd==NULL)
+    {
+        RLOGD("lynqFindUsbEvent CMD is NULL!!!");
+        return ((usb_cmd_t*)NULL);
+    }
+    printf("cmd =%s\n",cmd);
+    for(int i=0;Usb_commands[i].cmdName;i++)
+    {
+        if (strcmp (cmd, Usb_commands[i].cmdName) == 0)
+        return (&Usb_commands[i]);
+    }
+    return ((usb_cmd_t *)NULL);
+}
+
+int routeCmd(int request)
+{
+    switch (request)
+    {
+        case LYNQ_REQUEST_CGMI:
+        case LYNQ_REQUEST_GMI:
+        case LYNQ_REQUEST_CGACT:
+        case LYNQ_REQUEST_CGDCONT:
+        {
+             return LYNQ_GOTO_AT;
+        }
+        case LYNQ_REQUEST_ATD:
+        case LYNQ_REQUEST_LAPNACT:
+        case LYNQ_REQUEST_ELAPNACT:
+        case LYNQ_REQUEST_SCREEN_STATE:
+        case LYNQ_REQUEST_APN:
+        case LYNQ_REQUEST_SWITCH_SIM:
+        {
+            return LYNQ_GOTO_TELE_REQ;
+        }
+        case LYNQ_REQUEST_SEND_LOG_DATA:
+        {
+            return LYNQ_GOTO_PLAT_REQ;
+        }
+        case LYNQ_USER_REQUEST_GNSS:
+        case LYNQ_USER_REQUEST_OTHRE:
+        case LYNQ_REQUEST_INSIDE_VERSION:
+        case LYNQ_PLAT_LGMDS:
+        {
+            return LYNQ_GOTO_USER_REQ;
+        }
+        case LYNQ_REQUEST_RNDIS:
+        {
+
+            return LYNQ_GOTO_RNDIS_REQ;
+        }
+        case LYNQ_REQUEST_LINFO:
+            return LYNQ_GOTO_LINFO_REQ;
+        case LYNQ_REQUEST_FACTORY:
+            return LYNQ_GOTO_FACTORY;
+        case LYNQ_REQUEST_FOTA:
+            return LYNQ_GOTO_FOTA;
+        case LYNQ_REQUEST_TEMP:
+            return LYNQ_GOTO_TEMP;
+        default:
+            return -1;
+    }
+}
+int g_number(const char *p){
+    int cnt = 0;
+    while(*p != '\0'){
+        if(*p == ','){
+            cnt++;
+        }
+        *p++;
+    }
+    return cnt+4;//for count character string
+
+}
+int syncRespToUsb(int error_code)
+{
+    char BUF[32] = {};
+    int ret = -1;
+    int len = 0;
+    if(error_code==0)
+    {
+        len = write(ttyGS3_fd,"OK\n",3);
+    }
+    else
+    {
+        sprintf(BUF,"+CME ERROR: %d\n\0",error_code);
+        len = write(ttyGS3_fd,BUF,strlen(BUF));
+    }
+    if(len < 0)
+    {
+        perror("lynq resp write:");
+        return -1;
+    }
+    return 0;
+}
+void lynqSetArgv(char **argv, char** Point,const char* value)
+{
+    *argv=*Point;
+     sprintf(*argv, "%s", value);    
+     (*Point) += (strlen(value)+1);
+}
+//argv[2]:0 send,1 list,2 get
+int lynqParseUsbCommand(const char* cmd,char *argv[],char test[],char* parser_buf,int maxArgc)
+{
+    char *token;
+    char *str = test;
+    char *string;
+    char *parameter;
+    char* Point=parser_buf;
+    int cnt = g_number(cmd);
+    memcpy(test, cmd, strlen(cmd));
+    test[strlen(cmd)] = '\0';
+    argv[1] = (char *)cmd;
+    if(strstr(cmd,"=?"))
+    {
+        token = strtok(str, "=?");
+        //argv[0] = token;
+        argv[0] = strstr(token, "+")+1; 
+        lynqSetArgv(&(argv[2]),&Point,"1");
+        while (token != NULL)
+        {
+            string = token;
+            token = strtok(NULL, "=?");
+        }
+        parameter = strtok(string, ",");
+        int i = 3;
+        while (parameter != NULL)
+        {
+            argv[i++] = parameter;
+            parameter = strtok(NULL, ",");
+        }
+    }
+    else if(strstr(cmd,"="))
+    {
+        lynqSetArgv(&(argv[2]),&Point,"0");
+        token = strtok(str, "=");
+        //argv[0] = token;
+        if(strstr(token, "+"))
+        {
+            argv[0] = strstr(token, "+")+1;
+            while (token != NULL)
+            {
+                string = token;
+                token = strtok(NULL, "=");
+            }
+            parameter = strtok(string, ",");
+            int i = 3;
+            while (parameter != NULL)
+            {
+                argv[i++] = parameter;
+                parameter = strtok(NULL, ",");
+            }
+        }
+        else
+        {
+            argv[0] = token;
+        }
+    }
+    else if(strstr(cmd,"?"))
+    {
+        lynqSetArgv(&(argv[2]),&Point,"2");
+        token = strtok(str, "?");
+        //argv[0] = token;
+        argv[0] = strstr(token, "+")+1;
+        while (token != NULL)
+        {
+            string = token;
+            token = strtok(NULL, "?");
+        }
+        parameter = strtok(string, ",");
+        int i = 3;
+        while (parameter != NULL)
+        {
+            argv[i++] = parameter;
+            parameter = strtok(NULL, ",");
+        }
+    }
+    else
+    {
+        lynqSetArgv(&(argv[2]),&Point,"0");
+        if(strstr(cmd,"+"))
+        {
+            argv[0] = test+3;
+            return 3;
+        }
+        else
+        {
+            RLOGD("sp test 01");
+            if(!strcmp(cmd, "ATA")){
+                lynqSetArgv(&(argv[0]),&Point,"ATA");
+                return 3;
+            }
+            if(!strcmp(cmd, "AT")){
+                lynqSetArgv(&(argv[0]),&Point,"AT");
+                return 3;
+            }
+            /*UNKNOW*/
+            else if(!strncmp(cmd, "ATD", 3)){
+                lynqSetArgv(&(argv[0]),&Point,"ATD");
+                argv[3] = test+3;
+                return 4;
+            }
+            else if(!strncmp(cmd, "ATE", 3)){
+                lynqSetArgv(&(argv[0]),&Point,"ATE");
+                argv[3] = test+3;
+                return 4;
+            }
+            else if(!strcmp(cmd, "ATH")){
+                lynqSetArgv(&(argv[0]),&Point,"ATH");
+                return 3;
+            }
+            else if(!strncmp(cmd, "ATI", 3)){
+                lynqSetArgv(&(argv[0]),&Point,"ATI");
+                argv[3] = test+3;
+                return 4;
+            }
+            else if(!strncmp(cmd, "ATL", 3)){
+                lynqSetArgv(&(argv[0]),&Point,"ATL");
+                argv[3] = test+3;
+                return 4;
+            }
+            else if(!strncmp(cmd, "ATO", 3)){
+                lynqSetArgv(&(argv[0]),&Point,"ATO");
+                argv[3] = test+3;
+                return 3;
+            }
+            /*ATP*/
+            /*
+            */
+            else if(!strncmp(cmd, "ATQ", 3)){
+                lynqSetArgv(&(argv[0]),&Point,"ATQ");
+                argv[3] = test+3;
+                return 4;
+            }
+            else if(!strncmp(cmd, "ATS3", 4)){
+                lynqSetArgv(&(argv[0]),&Point,"ATS3");
+                argv[3] = test+4;
+                return 4;
+            }
+            else if(!strncmp(cmd, "ATS4", 4)){
+                lynqSetArgv(&(argv[0]),&Point,"ATS4");
+                argv[3] = test+4;
+                return 4;
+            }
+            else if(!strncmp(cmd, "ATS5", 4)){
+                lynqSetArgv(&(argv[0]),&Point,"ATS5");
+                argv[3] = test+4;
+                return 4;
+            }
+            /*ATS6*/
+            /*
+            */
+            else if(!strncmp(cmd, "ATS7", 4)){
+                lynqSetArgv(&(argv[0]),&Point,"ATS7");
+                argv[3] = test+4;
+                return 4;
+            }
+            else if(!strncmp(cmd, "ATS8", 4)){
+                lynqSetArgv(&(argv[0]),&Point,"ATS8");
+                argv[3] = test+4;
+                return 4;
+            }
+            else if(!strncmp(cmd, "ATS10", 5)){
+                lynqSetArgv(&(argv[0]),&Point,"ATS10");
+                argv[3] = test+5;
+                return 4;
+            }
+            /*ATT*/
+            /*
+
+
+
+            */
+            else if(!strncmp(cmd, "ATV", 3)){
+                lynqSetArgv(&(argv[0]),&Point,"ATV");
+                argv[3] = test+3;
+                return 4;
+            }
+            /*ATX*/
+            /*
+
+
+
+            */
+            else if(!strncmp(cmd, "ATZ", 3)){
+                lynqSetArgv(&(argv[0]),&Point,"ATZ");
+                argv[3] = test+3;
+                return 4;
+            }
+            else if(!strncmp(cmd, "AT&F", 4)){
+                lynqSetArgv(&(argv[0]),&Point,"AT&F");
+                argv[3] = test+4;
+                return 4;
+            }
+            else
+            {
+                RLOGD("can't find this command");
+                return -1;
+            }
+        }
+    }
+    //char *testtest = strstr(argv[0], "+")+1;
+    //printf("testtest:%s\n", testtest);
+    //argv[0] = testtest;
+    //printf("%d\n", __FUNCTION__);
+    if(cnt > maxArgc)
+        return -1;
+    return cnt;
+}
+
+int CGMI(int argc,char*argv[],char *rilReq, int uToken)
+{
+    return 0;
+}
+int dialACall(int argc,char*argv[],char *rilReq, int uToken)
+{
+    if(argc < 4)
+    {
+        RLOGD("parameter error!!!");
+        return 1;
+    }
+    char *new_argv[3] = {};
+    new_argv[0] = (char *)rilReq;
+    new_argv[1] = argv[3];
+    new_argv[2] = "0";
+    android::lynqSendToRil(3,new_argv,uToken);
+    return 0;
+}
+int checkDataRegistration(int uToken)
+{
+    /*chech radio status*/
+    int ret = -1;
+    char *argv_temp[3]={};
+    argv_temp[0] = "RIL_REQUEST_DATA_REGISTRATION_STATE";
+    android::lynqSendToRil(1,argv_temp,uToken);
+    if(lynqATWaitWithTime(2000))
+    {
+        RLOGD("function %s line %d time out", __FUNCTION__, __LINE__);
+        return -1;
+    }
+    /*
+    if(ret == ETIMEDOUT)
+    {
+        int n = write(ttyGS3_fd,"+CME:ERROR 8004\n",strlen("+CME:ERROR 8004\n"));
+        if(n<0)
+        {
+            perror("lynq resp write:");
+        }
+        return -1;
+    }
+    */
+    if(current_data_reg!=0)
+    {
+        return -1;
+    }
+    return 0;
+}
+int setupData(int argc,char*argv[],char *rilReq, int uToken)
+{
+    int status = 0;
+    int ret = -1;
+    if(argc < 4)
+    {
+        RLOGD("parameter error!!!");
+        return -1;
+    }
+    bzero(lynq_at,LYNQ_AT_LEN_MAX);
+    sprintf(lynq_at,"LAPNACT");
+    status = atoi(argv[3]);
+    char *new_argv[3] = {};
+    if(status==1)
+    {
+        ret = checkDataRegistration(uToken);
+        if(ret != 0)
+        {
+            RLOGD("[setupData] radio is not available!!!");
+            return -1;
+        }
+        new_argv[0] = (char *)rilReq;
+        android::lynqSendToRil(1,new_argv,uToken);
+        syncRespToUsb(0);
+    }
+    else if(status == 0)
+    {
+        new_argv[0] = "RIL_REQUEST_DEACTIVATE_DATA_CALL";
+        android::lynqSendToRil(1,new_argv,uToken);
+    }
+    return 0;
+}
+
+static void lynq_display_pdnstate(void)
+{
+    lynq_output_info("\n");
+    for(int i = 0;i < apn_count; i ++)
+    {
+        lynq_output_info("+ELAPNACT:%s,%s,%d,%s,%s\n", apn_table[i].apn, apn_table[i].apntype ,apn_table[i].pdpstate, apn_table[i].ifaceName, apn_table[i].address);
+    }
+    lynq_output_info("OK\n");
+    return;
+}
+
+int setupData_e(int argc,char*argv[],char *rilReq, int uToken)
+{
+    int status = 0;
+    int ret = -1;
+    char *new_argv[10] = {};
+    if(NULL == argv[2])
+    {
+        lynq_output_info("\n+ELAPNACT: 10\n");
+        return -1;
+    }
+    int type = atoi(argv[2]);
+    if(type == 0)
+    {
+        if(argc < 5)
+        {
+            RLOGD("parameter error!!!");
+            return 1;
+        }
+        status = atoi(argv[3]);
+        if(status == 1 )
+        {
+            ret = checkDataRegistration(uToken);
+            if(ret != 0)
+            {
+                RLOGD("[setupData] radio is not available!!!");
+                return -1;
+            }
+            new_argv[0] = (char *)rilReq;
+            new_argv[1] = argv[4];//apn
+            new_argv[2] = argv[5];//apntype
+            new_argv[3] = argv[6];//user
+            new_argv[4] = argv[7];//password
+            new_argv[5] = argv[8];//authType
+            new_argv[6] = argv[9];//normalprotocol
+            new_argv[7] = argv[10];//roamingprotocol
+            //memcpy(apn_table[apn_count].apn,argv[4],strlen(argv[4]));
+            //apn_count++;
+            android::lynqSendToRil(8,new_argv,uToken);
+            syncRespToUsb(0);
+        }
+        else if(status == 0)
+        {
+            new_argv[0] = "RIL_REQUEST_DEACTIVATE_DATA_CALL";
+            new_argv[1] = argv[4];//apntype
+            android::lynqSendToRil(2,new_argv,uToken);
+        }
+    }
+    else if (type == 1)
+    {
+        lynq_output_info("\n+ELAPNACT: (0-7)\n");
+        lynq_output_info("OK\n\n");
+    }
+    else if (type == 2)
+    {
+        lynq_display_pdnstate();
+    }
+    return 0;
+}
+
+int insert_apn_char(char *agc, char *id,char *mcc, char *mnc, char *apn, char *apntype, char *user, char *password, char *normalprotocol, char *roamingprotocol, char *carrier)
+{
+    char strtmp[10][64];
+    if (!strcmp(id,"null"))
+    {
+        sprintf(strtmp[0], "id=;");
+    }
+    else
+    {
+        sprintf(strtmp[0], "id=%s;", id);
+    }
+    if (!strcmp(mcc,"null"))
+    {
+        char mcc[8] = {0};
+        if(strlen(mccmnc))
+        {
+            strncpy(mcc, mccmnc, 3);
+            sprintf(strtmp[1], "mcc=%s;", mcc);
+        }
+        else
+        {
+            sprintf(strtmp[2], "mcc=;");
+        }
+    }
+    else
+    {
+        sprintf(strtmp[1], "mcc=%s;", mcc);
+    }
+    if (!strcmp(mnc,"null"))
+    {
+        if(strlen(mccmnc))
+        {
+            sprintf(strtmp[2], "mnc=%s;", mccmnc+3);
+        }
+        else
+        {
+            sprintf(strtmp[2], "mnc=;");
+        }
+    }
+    else
+    {
+        sprintf(strtmp[2], "mnc=%s;", mnc);
+    }
+    if (!strcmp(apn,"null"))
+    {
+        sprintf(strtmp[3], "apn=;");
+    }
+    else
+    {
+        sprintf(strtmp[3], "apn=%s;", apn);
+    }
+    if (!strcmp(apntype,"null"))
+    {
+        sprintf(strtmp[4], "apntype=;");
+    }
+    else
+    {
+        sprintf(strtmp[4], "type=%s;", apntype);
+    }
+    if (!strcmp(user,"null"))
+    {
+        sprintf(strtmp[5], "user=;");
+    }
+    else
+    {
+        sprintf(strtmp[5], "user=%s;", user);
+    }
+    if (!strcmp(password,"null"))
+    {
+        sprintf(strtmp[6], "password=;");
+    }
+    else
+    {
+        sprintf(strtmp[6], "password=%s;", password);
+    }
+    if (!strcmp(normalprotocol,"null"))
+    {
+        sprintf(strtmp[7], "protocol=;");
+    }
+    else
+    {
+        sprintf(strtmp[7], "normalprotocol=%s;", normalprotocol);
+    }
+    if (!strcmp(roamingprotocol,"null"))
+    {
+        sprintf(strtmp[8], "roamingprotocol=;");
+    }
+    else
+    {
+        sprintf(strtmp[8], "roamingprotocol=%s;", roamingprotocol);
+    }
+    if (!strcmp(carrier,"null"))
+    {
+        sprintf(strtmp[9], "carrier=;");
+    }
+    else
+    {
+        sprintf(strtmp[9], "carrier=%s;", carrier);
+    }
+    sprintf(agc, "%s%s%s%s%s%s%s%s%s%s",strtmp[0], strtmp[1], strtmp[2], strtmp[3], strtmp[4], strtmp[5], strtmp[6], strtmp[7], strtmp[8], strtmp[9]);
+    return 0;
+}
+
+void lynq_req_mccmnc(int uToken)
+{
+    char *new_argv[10] = {};
+    new_argv[0] = "RIL_REQUEST_OPERATOR";
+    android::lynqSendToRil(1,new_argv,uToken);//for get mccmnc
+}
+
+int lynq_modify_apn_info(int argc,char*argv[],char *rilReq, int uToken)
+{
+    /*
+        argv[4];//id argv[5];//mcc argv[6];//mnc argv[7];//apn argv[8];//apntype argv[9];//user
+        argv[10];//password  argv[11] normalprotocol argv[12] roamingprotocol
+    */
+    int operate = 0;
+    int ret = -1;
+    if(argc < 3)
+    {
+        RLOGD("parameter error!!!");
+        return 1;
+    }
+    if(argv[3] == NULL)
+    {
+        syncRespToUsb(100);
+        return -1;
+    }
+    char *new_argv[10] = {};
+    char apn_info[512];
+    operate = atoi(argv[3]);
+    new_argv[0] = (char *)rilReq;
+    if(operate == 0)//insert apn db
+    {
+        for(int i = 4; i < 14; i++)
+        {
+            if(argv[i] == NULL)
+            {
+                syncRespToUsb(100);
+                return -1;
+            }
+        }
+        lynq_req_mccmnc(uToken);
+        usleep(500*1000);
+        insert_apn_char(apn_info, argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13]);
+        new_argv[1] = "0";
+        new_argv[2] = apn_info;
+        android::lynqSendToRil(3,new_argv,uToken);
+        usleep(100*1000);
+        syncRespToUsb(0);
+    }
+    else if(operate == 1)//delete apn db
+    {
+        if(argv[4] == NULL)
+        {
+            syncRespToUsb(100);
+            return -1;
+        }
+        sprintf(apn_info, "id=%s", argv[4]);
+        new_argv[1] = "1";
+        new_argv[2] = apn_info;
+        android::lynqSendToRil(3,new_argv,uToken);
+        usleep(100*1000);
+        syncRespToUsb(0);
+    }
+    else if(operate == 2)//query apn db
+    {
+        if(argv[4] == NULL)
+        {
+            syncRespToUsb(100);
+            return -1;
+        }
+        sprintf(apn_info, "id=%s", argv[4]);
+        new_argv[1] = "2";
+        new_argv[2] = apn_info;
+        android::lynqSendToRil(3,new_argv,uToken);
+        usleep(100*1000);
+        syncRespToUsb(0);
+    }
+    else if(operate == 3)//modify apn db
+    {
+        for(int i = 4; i < 14; i++)
+        {
+            printf("argv[%d] %s\n", i,argv[i]);
+            if(argv[i] == NULL)
+            {
+                syncRespToUsb(100);
+                return -1;
+            }
+        }
+        insert_apn_char(apn_info, argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13]);
+        //sprintf(new_argv[1], "%d", operate);
+        new_argv[1] = "3";
+        new_argv[2] = apn_info;
+        android::lynqSendToRil(3,new_argv,uToken);
+        usleep(100*1000);
+        syncRespToUsb(0);
+    }
+    return 0;
+}
+
+static void lynq_get_current_card(void)
+{
+    int id = get_default_sim_all();
+    lynq_output_info("+LCSUS: %d\n", id);
+    lynq_output_info("OK\n");
+    return;
+}
+
+static void lynq_switch_card(char*argv[], char *rilReq, int uToken)
+{
+    int slot = 0;
+    int ret = -1;
+    char *new_argv[10] = {};
+    slot = atoi(argv[3]);
+    new_argv[0] = (char *)rilReq;
+    new_argv[1] = argv[3];
+    android::lynqSendToRil(2,new_argv,uToken);
+    return;
+}
+
+static void lynq_display_dsds_mode(void)
+{
+    lynq_output_info("+LCSUS: (0-1)\n");
+    lynq_output_info("OK\n");
+    return;
+}
+
+int lynq_dsds_support(int argc,char*argv[],char *rilReq, int uToken)
+{
+    if(argc < 4)
+    {
+        RLOGD("parameter error!!!");
+        return 1;
+    }
+    int type = atoi(argv[2]);
+    if(type == 2)//get mode
+    {
+        RLOGD("lynq_dsds_support get mode\n");
+        lynq_get_current_card();
+    }
+    else if(type == 0)//set mode
+    {
+        RLOGD("lynq_dsds_support set mode\n");
+        lynq_switch_card(argv, rilReq, uToken);
+    }
+    else if(type == 1)//get list mode
+    {
+        RLOGD("lynq_dsds_support get list mode\n");
+        lynq_display_dsds_mode();
+    }
+    return 0;
+}
+
+void * thread_test(void * arg)
+{
+    FILE *fp;
+    char buf[1024*3] = {0};
+    sprintf(buf, "echo 7 | emdlogger_ctrl 2>&1");
+    fp=popen(buf, "r");
+    if(!fp){
+        perror("popen:");
+    }
+    while(fgets(buf, 4072, fp) != NULL){}
+    pclose(fp);
+    return 0;
+}
+
+/*lei modify :Low power consumption for factory test only*/
+int lynq_screen(int argc,char*argv[],char *rilReq, int uToken){
+    pthread_t thid;
+    int ret = pthread_create(&thid, NULL, thread_test, NULL);
+    if(ret != 0){
+        RLOGD("pthread_create error!!!");
+        return ret;
+    }
+    #if 0
+    char eBuf[64] = {0};
+    sprintf(eBuf,"\nOK\n\0");
+    int n = write(ttyGS3_fd,eBuf,strlen(eBuf));
+    if(n<0)
+    {
+        perror("lynq resp write:");
+    }
+    #endif
+    /*lei modify*/
+    system("echo \"Sys flight mode\" >/dev/console");
+    /*lei modify*/
+    char *new_argv[2] = {};
+    if(argc < 4)
+    {
+        RLOGD("parameter error!!!");
+        return -1;
+    }
+    /*Cut to SIM2*/
+    new_argv[0] = "SET_DEFAULT_SIM_ALL";
+    new_argv[1] = "1";
+    android::lynqSendToRil(2,new_argv,uToken);
+    sleep(1);
+    new_argv[0] = (char *)rilReq;
+    new_argv[1] = argv[3];
+    android::lynqSendToRil(2,new_argv,uToken);
+    sleep(1);
+    /*Cut to SIM1*/
+    new_argv[0] = "SET_DEFAULT_SIM_ALL";
+    new_argv[1] = "0";
+    android::lynqSendToRil(2,new_argv,uToken);
+    sleep(1);
+    new_argv[0] = (char *)rilReq;
+    new_argv[1] = argv[3];
+    android::lynqSendToRil(2,new_argv,uToken);
+    system("echo reg_netsys_srcclkena_mask_b 0 > /sys/power/spm/suspend_ctrl");
+    system("echo reg_netsys_infra_req_mask_b 0 > /sys/power/spm/suspend_ctrl");
+    system("echo reg_netsys_apsrc_req_mask_b 0 > /sys/power/spm/suspend_ctrl");
+    system("echo reg_netsys_vrf18_req_mask_b 0 > /sys/power/spm/suspend_ctrl");
+    system("echo reg_netsys_ddr_en_mask_b 0 > /sys/power/spm/suspend_ctrl");
+    system("echo mem > /sys/power/autosleep");
+    ret = pthread_join(thid,NULL);
+    if(ret != 0){
+        RLOGD("pthread_join error!!!");
+        return ret;
+    }
+    return 0;
+}
+/*lei modify :Low power consumption for factory test only*/
+
+void* getMDstate(int argc,char*argv[],int uToken)
+{
+    FILE *FP;
+    char BUFFER[64]={};
+    char BUF[32] = {};
+    int ret = -1;
+    int len = 0;
+    FP = popen("cat /sys/kernel/ccci/boot","r");
+    fgets(BUFFER,sizeof(BUFFER),FP);
+    printf("buffer %s",BUFFER);
+    modemStatus = atoi(&BUFFER[4]);
+    sprintf(BUF,"+LGMDS:%d\n\0",modemStatus);
+    len = write(ttyGS3_fd,BUF,strlen(BUF));
+    if(len < 0)
+    {
+        perror("lynq resp write:");
+        return 0;
+    }
+    syncRespToUsb(0);
+    return 0;
+}
+
+void* lynq_get_inside_version(int argc,char*argv[],int uToken)
+{
+    int request = RIL_REQUEST_OEM_HOOK_RAW;
+    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));
+    //only for factory test
+    /*lei add for factory test*/
+    pRI->lynqEvent=3;
+    argv[1] = "AT+CGMR";
+    /*lei add for factory test*/
+    sendATCMD(2, argv,id,pRI);
+    return 0;
+}
+
+int lynqATWaitWithTime(int mtime)
+{
+    RLOGD("wait_call_state");
+    int sec = 0;
+    int usec = 0;
+    struct timeval now;
+    struct timespec outtime;
+    gettimeofday(&now,NULL);
+    sec = mtime/1000;
+    outtime.tv_sec = now.tv_sec+sec;
+    unsigned long long ns;
+    ns = now.tv_usec*1000ull + (mtime%1000)*1000000ull;
+    outtime.tv_sec += ns/1000000000;
+    outtime.tv_nsec = ns%1000000000;
+    pthread_mutex_lock(&lynq_at_mutex);
+    int ret = pthread_cond_timedwait(&lynq_at_cond,&lynq_at_mutex,&outtime);
+    pthread_mutex_unlock(&lynq_at_mutex);
+    RLOGD("wait_call_state end");
+    return ret;
+}
+void lynqAtRespWatingEvent()
+{
+    pthread_mutex_lock(&lynq_at_mutex);
+    pthread_cond_signal(&lynq_at_cond);
+    pthread_mutex_unlock(&lynq_at_mutex);
+    return;
+}
+void lynqInfo(char*argv[])
+{
+    int type = atoi(argv[2]);
+   
+    if(type==2){                            
+        //lynq_output_LINFO_all();     
+        syncRespToUsb(0);
+    }
+    else if(type==0){                           
+        int status = atoi(argv[3]);
+        if(status==1 || status==0){
+            //lynq_output_LINFO_enable=status;
+            //lynq_output_info("+LINFO: Report switch when key information changed is set: %d\n",lynq_output_LINFO_enable);    
+            syncRespToUsb(0);
+        }   
+        else {
+            //lynq_output_info("parameter error\n"); 
+            syncRespToUsb(100);    
+        }
+    }
+    else if(type==1){        
+        //lynq_output_info("+LINFO: (0-1)\n");         
+        syncRespToUsb(0);
+    }
+    else {   
+        //lynq_output_info("parameter error\n"); 
+        syncRespToUsb(100);
+    }
+}
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_common.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_common.h
new file mode 100755
index 0000000..16b6403
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_common.h
@@ -0,0 +1,126 @@
+/*============================================================================= 
+**     FileName: lynq_common.h
+**     Desc: lynq common
+**     Author: Warren
+**     Version: V1.0
+**     LastChange: 2021-09-27 
+**     History: 
+**=============================================================================*/
+#ifndef LYNQ_COMMON
+#define LYNQ_COMMON
+#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>
+# include <pthread.h>
+
+#define LYNQ_GOTO_AT 1
+/*telephony*/
+#define LYNQ_GOTO_TELE_REQ 2
+/*Other-for-User*/
+#define LYNQ_GOTO_USER_REQ 3
+/*audio/etc*/
+#define LYNQ_GOTO_PLAT_REQ 4
+/*rndis/*/
+#define LYNQ_GOTO_RNDIS_REQ 5
+/*factory*/
+#define LYNQ_GOTO_FACTORY 6
+/*info output*/
+#define LYNQ_GOTO_LINFO_REQ 7
+/*fota*/
+#define LYNQ_GOTO_FOTA 8
+/*TEMP*/
+#define LYNQ_GOTO_TEMP 10
+
+#define LYNQ_APN_LEN_MAX 100
+#define LYNQ_APNTPYE_LEN_MAX 50
+#define LYNQ_APN_CHANNEL_MAX 7//max is 7
+#define LYNQ_AT_LEN_MAX 20
+#define LYNQ_EVENT_WAIT_TIME_MAX 25 //m
+
+#define LYNQ_VERSION 8500
+#define LYNQ_REQUEST_CGMI (LYNQ_VERSION+1)
+#define LYNQ_REQUEST_GMI (LYNQ_VERSION+2)
+#define LYNQ_REQUEST_CGMM (LYNQ_VERSION +3)
+#define LYNQ_REQUEST_GMM (LYNQ_VERSION +4)
+#define LYNQ_REQUEST_ATD (LYNQ_VERSION +5)
+#define LYNQ_REQUEST_CGCMOD (LYNQ_VERSION +6)
+#define LYNQ_REQUEST_CGAUTO (LYNQ_VERSION +7)
+#define LYNQ_REQUEST_CGACT (LYNQ_VERSION +8)
+#define LYNQ_REQUEST_CGDCONT (LYNQ_VERSION +9)
+#define LYNQ_REQUEST_LAPNACT (LYNQ_VERSION +10)
+#define LYNQ_REQUEST_ELAPNACT (LYNQ_VERSION +11)
+#define LYNQ_REQUEST_SWITCH_SIM (LYNQ_VERSION +12)
+#define LYNQ_REQUEST_SEND_LOG_DATA (LYNQ_VERSION +13)
+#define LYNQ_PLAT_LGMDS (LYNQ_VERSION +14)
+#define LYNQ_REQUEST_RNDIS (LYNQ_VERSION +15)
+#define LYNQ_REQUEST_FACTORY (LYNQ_VERSION +16)
+#define LYNQ_REQUEST_LINFO (LYNQ_VERSION +17)
+#define LYNQ_REQUEST_SCREEN_STATE (LYNQ_VERSION +18)
+#define LYNQ_REQUEST_FOTA (LYNQ_VERSION +19)
+#define LYNQ_REQUEST_INSIDE_VERSION (LYNQ_VERSION +20)
+/*rita add*/
+#define LYNQ_REQUEST_TEMP (LYNQ_VERSION +26)
+#define LYNQ_REQUEST_APN (LYNQ_VERSION +27)
+#define LYNQ_USER_REQUEST_GNSS (LYNQ_VERSION +100)
+#define LYNQ_USER_REQUEST_OTHRE (LYNQ_VERSION +101)
+
+typedef struct
+{
+    int cmdId;
+    char * cmdName;
+    int support;
+}usb_at_transfer_t;
+
+typedef struct
+{
+    int cmdId;
+    char* rilRequest;
+    char * cmdName;
+    int (*fun)(int argc,char*argv[],char *rilReq,int uToken);
+    void* (*ufun)(int argc,char *argv[],int uToken);
+}usb_cmd_t;
+typedef struct
+{
+    char apn[LYNQ_APN_LEN_MAX];
+    char apntype[LYNQ_APNTPYE_LEN_MAX];
+    char ifaceName[LYNQ_APNTPYE_LEN_MAX];
+    int netId;
+    int used;//0:not use,1:used.
+    int apnstatus;//1:has enable;0:need disable.
+    int pdpstate;//lei add for at+elapnact?  refer to T800 AT COMMANDS:+lapnact
+    char address[LYNQ_APNTPYE_LEN_MAX];
+}apn_table_t;
+extern apn_table_t apn_table[LYNQ_APN_CHANNEL_MAX];
+extern int apn_count;
+extern char lynq_at[LYNQ_AT_LEN_MAX];
+extern char mccmnc[8];
+usb_at_transfer_t *lynqFindId(char *cmd);
+usb_cmd_t * lynqFindUsbEvent(char *cmd);
+int transferAtToRequest(char *cmd);
+//argv[2]:0 send,1 list,2 get
+int lynqParseUsbCommand(const char* cmd,char *argv[],char test[],char* parser_buf,int maxArgc);
+void lynq_req_mccmnc(int uToken);
+int routeCmd(int request);
+
+int CGMI(int argc,char*argv[],char *rilReq, int uToken);
+int dialACall(int argc,char*argv[],char *rilReq, int uToken);
+int setupData(int argc,char*argv[],char *rilReq, int uToken);
+int setupData_e(int argc,char*argv[],char *rilReq, int uToken);
+int lynq_dsds_support(int argc,char*argv[],char *rilReq, int uToken);
+int lynq_screen(int argc,char*argv[],char *rilReq, int uToken);
+void* getMDstate(int argc,char*argv[],int uToken);
+void* lynq_get_inside_version(int argc,char*argv[],int uToken);
+int lynqATWaitWithTime(int time);//time(s)
+void lynqAtRespWatingEvent();
+int syncRespToUsb(int error_code);
+void lynqInfo(char*argv[]);
+int lynq_modify_apn_info(int argc,char*argv[],char *rilReq, int uToken);
+void sendSignalApnChange();
+int waitApnResult();
+int checkDataRegistration(int uToken);
+#endif
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_interface.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_interface.cpp
new file mode 100755
index 0000000..f0943aa
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_interface.cpp
@@ -0,0 +1 @@
+#include "lynq_interface.h"
\ No newline at end of file
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_interface.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_interface.h
new file mode 100755
index 0000000..4a94b10
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_interface.h
@@ -0,0 +1,40 @@
+#define LYNQ_REQUEST_VENDOR_BASE 8000
+#define LYNQ_URC_VENDOR_BASE 9000
+#define LYNQ_AT_SNED (LYNQ_REQUEST_VENDOR_BASE +1)
+#define LYNQ_URC_CALL_STATUS_IND (LYNQ_URC_VENDOR_BASE+1)
+#define LYNQ_URC_DATA_STATUS_IND (LYNQ_URC_VENDOR_BASE+2)
+#define LYNQ_URC_DATA_CALL_STATUS_IND (LYNQ_URC_VENDOR_BASE+3)
+#define LYNQ_AUTO_ANSWER_CALL (LYNQ_REQUEST_VENDOR_BASE +2)
+#define LYNQ_REQUEST_SET_DTMF_VOLUME (LYNQ_REQUEST_VENDOR_BASE +3)
+#define LYNQ_URC_MODIFY_APNDB (LYNQ_URC_VENDOR_BASE+4)
+#define LYNQ_URC_RESET_APNDB (LYNQ_URC_VENDOR_BASE+5)
+
+
+#define LYNQ_REQUEST_WRITE_SMS_TO_MEMORY (LYNQ_REQUEST_VENDOR_BASE +4)
+#define LYNQ_REQUEST_READ_SMS_FROM_MEMORY (LYNQ_REQUEST_VENDOR_BASE + 5)
+#define LYNQ_REQUEST_DELETE_SMS_FROM_MEMORY (LYNQ_REQUEST_VENDOR_BASE + 6)
+#define LYNQ_REQUEST_LIST_SMS_FROM_MEMORY (LYNQ_REQUEST_VENDOR_BASE + 7)
+#define LYNQ_REQUEST_SET_DEFAULT_SIM_ALL (LYNQ_REQUEST_VENDOR_BASE + 8)
+
+#define LYNQ_REQUEST_SET_SPEECH_VOLUME (LYNQ_REQUEST_VENDOR_BASE +9)
+#define LYNQ_REQUEST_GET_SPEECH_VOLUME (LYNQ_REQUEST_VENDOR_BASE +10)
+#define LYNQ_REQUEST_RECORD  (LYNQ_REQUEST_VENDOR_BASE +11)
+#define LYNQ_REQUEST_OOS_RECOVER_TIMER_INTERVAL (LYNQ_REQUEST_VENDOR_BASE +12)
+#define LYNQ_REQUEST_OOS_DEEP_SLEEP_RECOVER_TIMER_INTERVAL (LYNQ_REQUEST_VENDOR_BASE +13)
+#define LYNQ_REQUEST_CHANGE_SCREEN_STATE (LYNQ_REQUEST_VENDOR_BASE + 14)/*jb.qi add for two sim suspend 2022/9/19*/
+#define LYNQ_REQUEST_CHANGE_RADIO (LYNQ_REQUEST_VENDOR_BASE + 15)
+#ifdef ECALL_SUPPORT
+#define RIL_UNSOL_ECALL_T2_TIMER_OUT  9000
+#define RIL_UNSOL_ECALL_T5_TIMER_OUT  9001
+#define RIL_UNSOL_ECALL_T6_TIMER_OUT  9002
+#define RIL_UNSOL_ECALL_T7_TIMER_OUT  9003
+#define RIL_UNSOL_ECALL_REDIAL_TIMER_OUT 9004
+#define RIL_UNSOL_ECALL_AUTO_ANS_TIMER_OUT 9005
+#define RIL_UNSOL_ECALL_AUTO_ANS_IMS_TIMER_OUT 9006
+#endif
+
+typedef struct{
+    int request;
+    int waitTime;
+    char * name;
+}lynq_sp_command_t;
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_ril_service.service b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_ril_service.service
new file mode 100755
index 0000000..86df0f9
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_ril_service.service
@@ -0,0 +1,19 @@
+[Unit]
+Description=lynq ril service
+After=mtkfusionrild.service
+Requires=mtkfusionrild.service
+
+[Service]
+StandardOutput=kmsg+console
+Type=simple
+RemainAfterExit=no
+ExecStart=/usr/bin/lynq-ril-service
+Restart=always
+RestartSec=500ms
+StartLimitInterval=0
+User=root
+Group=root
+
+[Install]
+Alias=rilsvc
+WantedBy=multi-user.target
\ No newline at end of file
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_user.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_user.cpp
new file mode 100755
index 0000000..7078df7
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_user.cpp
@@ -0,0 +1,20 @@
+/*============================================================================= 
+**     FileName: lynq_user.cpp
+**     Desc: handle data from user
+**     Author: Warren
+**     Version: V1.0
+**     LastChange: 2021-09-28 
+**     History: 
+**=============================================================================*/

+#include <stdio.h>

+#include "lynq_user.h"

+void* lynqGnss(int argc,char *argv[],int uToken)

+{

+    printf("[lynqGnss] this is user space !!!\n");

+    return 0;

+}

+void* lynqOther(int argc,char *argv[],int uToken)

+{

+    printf("[lynqOther] this is user space !!!\n");

+    return 0;

+}

diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_user.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_user.h
new file mode 100755
index 0000000..6ad7361
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_user.h
@@ -0,0 +1,14 @@
+/*============================================================================= 
+**     FileName: lynq_user.h
+**     Desc: handle data from user
+**     Author: Warren
+**     Version: V1.0
+**     LastChange: 2021-09-28 
+**     History: 
+**=============================================================================*/

+#ifndef LYNQ_USER
+#define LYNQ_USER

+

+void* lynqGnss(int argc,char *argv[],int uToken);

+void* lynqOther(int argc,char *argv[],int uToken);

+#endif

diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_user_commands.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_user_commands.h
new file mode 100755
index 0000000..d3f5a12
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_user_commands.h
@@ -0,0 +1 @@
+

diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/main.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/main.cpp
new file mode 100755
index 0000000..0b2c2a3
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/main.cpp
@@ -0,0 +1,197 @@
+/*
+*  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 <signal.h>
+#include "common.h"
+#include "lynq_shm.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 struct RIL_Env s_rilEnv = {
+    RIL_onRequestComplete,
+    RIL_onUnsolicitedResponse,
+    NULL
+};
+
+/**
+ * @brief success return 1 else return 0
+ * 
+ * @return int 
+ */
+static int lynq_check_modem_state(void)
+{
+    FILE *fp;
+    char buffer[64]={};
+    fp = popen("cat /sys/kernel/ccci/boot","r");
+    fgets(buffer,sizeof(buffer),fp);
+    if(buffer[4] == '4')
+    {
+        pclose(fp);
+        return 1;
+    }
+    else
+    {
+        pclose(fp);
+        return 0;
+    }
+}
+
+static void signal_handler(int signum)
+{
+    switch(signum)
+    {
+        case SIGABRT:
+            RLOGD("function %s recv SIGABRT\n", __FUNCTION__);
+            break;
+        case SIGBUS:
+            RLOGD("recv %s SIGBUS\n", __FUNCTION__);
+            break;
+        case SIGFPE:
+            RLOGD("recv %sSIGFPE\n", __FUNCTION__);
+            break;
+        case SIGILL:
+            RLOGD("recv %sSIGILL\n", __FUNCTION__);
+            break;
+        case SIGSEGV:
+            RLOGD("recv %sSIGSEGV\n", __FUNCTION__);
+            break;
+        case SIGHUP:
+            RLOGD("recv %s SIGHUP\n", __FUNCTION__);
+            if(ttyGS3_fd > 0)
+            {
+                close(ttyGS3_fd);
+                RLOGE("reopen need close");
+            }
+            ttyGS3_fd = open("/dev/ttyGS3",O_RDWR);
+            if(ttyGS3_fd==-1)
+            {
+                RLOGE("open ttyGS3 failure!!!");
+            }
+            break;
+         default:
+            RLOGD("recv unknown signal\n");
+            break;
+    }
+}
+
+
+int main(int argc, char **argv) {
+    /*lei add for gsw
+    reason:Socket sending failed at GSW
+    */
+    //signal(SIGHUP, signal_handler);
+    atexit (lynq_exit);
+    system("route add -host 255.255.255.255 dev lo");
+    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);
+        }
+    }
+
+    if(ril_init_mem()!=0)
+    {
+        printf("Error: cannot ril_init_mem\n");
+        RLOGD("Error: cannot ril_init_mem");
+        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**");
+    //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);
+
+    android::startGdbusLoop();
+    RLOGD("RIL_Init RIL_register completed");
+    printf("DemoApp launch done!\n");
+    while (true) {
+        sleep(UINT32_MAX);
+    }
+    close(lock_file);
+}
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/makefile b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/makefile
new file mode 100755
index 0000000..7eaf082
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/makefile
@@ -0,0 +1,166 @@
+SHELL = /bin/sh
+RM = rm -f
+
+LOCAL_CFLAGS := -Wall \
+                -std=gnu++14 \
+                -g -Os \
+                -flto \
+                -DRIL_SHLIB \
+                -DATCI_PARSE \
+                -DKEEP_ALIVE \
+                -DECALL_SUPPORT
+
+ifeq ($(strip $(MOBILETEK_FOTA_CFG)), PLATFORM)
+    LOCAL_CFLAGS += -DMOBILETEK_FOTA_CFG
+endif
+
+ifeq ($(strip $(MOBILETEK_FOTA_CFG)), GSW)
+    LOCAL_CFLAGS += -DGSW_FOTA_CFG
+endif
+
+$(warning ################# C2K support: $(RAT_CONFIG_C2K_SUPPORT))
+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 $(MTK_LED_SUPPORT)), yes)
+    LOCAL_CFLAGS += -DLED_SUPPORT
+endif
+
+$(warning ################# TARGET_PLATFORM: $(TARGET_PLATFORM))
+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 -DTELEMATIC_5G_SUPPORT
+endif
+
+ifeq ($(strip $(MOBILETEK_RIL_CFG)), GSW)
+    LOCAL_CFLAGS += -DGSW_RIL_CFG
+
+endif
+
+ifeq ($(strip $(MOBILETEK_RIL_CFG)), PLATFORM)
+    LOCAL_CFLAGS += -DMOBILETEK_RIL_CFG
+
+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)/sms/lynqSmsManager \
+  -I$(LOCAL_PATH)/atci \
+  -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$(LOCAL_PATH)/rndis \
+  -I$(LOCAL_PATH)/factory \
+  -I$(LOCAL_PATH)/temp \
+  -I$(LOCAL_PATH)/led/include \
+  -I$(ROOT)$(includedir)/logger \
+  -I$(ROOT)$(includedir)/liblog \
+  -I$(ROOT)$(includedir)/liblynq-thermal \
+  -I$(ROOT)$(includedir)/include  \
+  -I$(ROOT)$(includedir)/ftp \
+  -I$(ROOT)$(includedir)/logger \
+  -I$(ROOT)$(includedir)/vendor-ril \
+  -I$(ROOT)$(includedir)/gstreamer-1.0 \
+  -I$(ROOT)$(includedir)/glib-2.0 \
+  -I$(ROOT)$(includedir)/lynq_shm \
+  -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 \
+  -I$(ROOT)$(includedir) \
+
+
+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 \
+    -llynq-log \
+    -lsqlite3 \
+    -lnandapi  \
+    -llynq-thermal  \
+    -llynq-systime \
+    -llynq-uci \
+    -llynq-protcl \
+    -llynq-shm  \
+
+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 sms/lynqSmsManager/*.cpp  rndis/*.cpp factory/*.cpp  temp/*.cpp led/*.cpp)
+
+EXECUTABLE = lynq-ril-service
+
+OBJECTS=$(SOURCES:.cpp=.o)
+all: $(EXECUTABLE)
+
+$(EXECUTABLE): $(OBJECTS)
+	$(CXX) $(OBJECTS) $(LOCAL_LIBS) $(LOCAL_CFLAGS) $(LOCAL_C_INCLUDES) -o $@
+
+%.o : %.cpp
+	$(CXX) $(LOCAL_C_INCLUDES) $(LOCAL_CFLAGS) $(LOCAL_LIBS) -o $@ -c $<
+
+.PHONY: clean
+clean:
+	$(RM) $(OBJECTS) $(EXECUTABLE)
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/mtk_ril_commands.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/mtk_ril_commands.h
new file mode 100755
index 0000000..eb1f8d0
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/mtk_ril_commands.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.
+ */
+
+{ 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 },
+{RIL_REQUEST_QUERY_SIM_RETRY_COUNT, dispatchVoid, responseInts },
+{RIL_REQUEST_QUERY_EID, dispatchVoid, responseString },
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/mtk_ril_unsol_commands.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/mtk_ril_unsol_commands.h
new file mode 100755
index 0000000..5c461f4
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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_RESPONSE_PS_NETWORK_STATE_CHANGED, responseVoid, WAKE_PARTIAL},
+{ 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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/network.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/network.cpp
new file mode 100755
index 0000000..17ba150
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/network.cpp
@@ -0,0 +1,422 @@
+//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 <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);
+    return 0;
+}
+//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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/network.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/network.h
new file mode 100755
index 0000000..19387fd
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/powerManager.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/powerManager.cpp
new file mode 100755
index 0000000..9a2551e
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/powerManager.cpp
@@ -0,0 +1,508 @@
+//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) 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;
+    buf[49]='\0';
+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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/powerManager.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/powerManager.h
new file mode 100755
index 0000000..c54d61d
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/resp_timeout.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/resp_timeout.cpp
new file mode 100755
index 0000000..f93a65e
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/resp_timeout.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/resp_timeout.h
new file mode 100755
index 0000000..31b30bf
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ril.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ril.cpp
new file mode 100755
index 0000000..6bce06e
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ril.cpp
@@ -0,0 +1,7765 @@
+//SPDX-License-Identifier: MediaTekProprietary
+/*
+**
+** 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"
+/*Warren add for t800 RIL service 2021_12_10 start*/
+#include <sys/epoll.h>
+#include "lynq_interface.h"
+#include "lynq_common.h"
+#include "lynq_sms_manager.h"
+/*lei add*/
+#include <stdbool.h>
+#include "lynq_at.h"
+#include "lynq_user.h"
+#include "lynq_rndis.h"
+#include "lynq_factory.h"
+#include <sys/stat.h>
+/*lei add*/
+/*rita add start*/
+#include "lynq_at_temp.h"
+/*rita add end*/
+/*lt add start*/
+/*lt add end*/
+/*Warren add for t800 RIL service 2021_12_10 end*/
+#ifdef LED_SUPPORT
+#include "led.h"
+#endif
+#include "lynq_shm.h"
+
+#define LOG_TAG "DEMO_RIL"
+#define WAIT_TIME_FOR_SIM_SWITCH 30
+
+extern void ARspRequest (int request, RIL_SOCKET_ID socket_id);
+extern void responseDispatch();
+
+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
+/*Warren add for t800 RIL service 2021_12_10 start*/
+#define LYNQ_SOCKET_ENVNT_FD_MAX 100
+#define LYNQ_SERVICE_PORT 8088
+#define LYNQ_AT_SERVICE_PORT 8087
+#define LYNQ_BRODCAST_PORT 8086
+#define LYNQ_SOCKET_BUFFER (1024*8+sizeof(int)*3+10)
+/*lei add*/
+#define DSET_IP_ADDRESS  "127.0.0.1"
+#define LYNQ_AT_SOCKET_BUFFER 1024
+#define MAX_AT_CMD 50
+/*lei add*/
+//int LYNQ_RIL_respSocket(Parcel &p,RIL_Token t);
+//int LYNQ_RIL_urcBroadcast(Parcel &p);
+
+/*hq add for urc broadcast opti 2023/01/06 */
+#define SHM_BUFFER_INDEX_OFFSET 1
+#define SHM_BUFFER_SIZE_OFFSET 16
+#define urc_broadcase_shm_size_limit 20
+
+int lynq_urc_socket_fd = 0;
+struct sockaddr_in urc_broadcast_addr;
+/*Warren add for t800 RIL service 2021_12_10 end*/
+
+
+/*lei add*/
+char buffer_at[LYNQ_AT_SOCKET_BUFFER] = {0};
+/*For at extension to receive at buffer*/
+char *at_buf_ext[MAX_AT_CMD];
+int sockfd = 0;
+int imei_cnt = 0;
+bool sdk_ready = true;
+/*lei add*/
+#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
+
+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);
+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 = 0;
+
+        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 = -1;
+    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 = -1;
+    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 = -1;
+    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 = -1;
+    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 = -1;
+    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 = -1;
+    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 = -1;
+    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 = -1;
+    uint32_t ut;
+    uint8_t  uct = 0;
+    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 = -1;
+    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 = -1;
+    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 = -1;
+    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 = -1;
+    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 = -1;
+    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);
+        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);
+        if(p_cur->isMT) {
+            printf("[EVENT][MT_CALL] phone number is %s\n",p_cur->number);
+        }
+    }
+    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)) {
+#ifdef TELEMATIC_5G_SUPPORT
+        RIL_SignalStrength_v14 *p_cur = ((RIL_SignalStrength_v14 *) response);
+#else
+        RIL_SignalStrength_v10 *p_cur = ((RIL_SignalStrength_v10 *) response);
+#endif
+        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);
+#ifdef TELEMATIC_5G_SUPPORT
+        p.writeInt32(p_cur->NR_SignalStrength.ssRsrp);
+        p.writeInt32(p_cur->NR_SignalStrength.ssRsrq);
+        p.writeInt32(p_cur->NR_SignalStrength.ssSinr);
+        p.writeInt32(p_cur->NR_SignalStrength.csiRsrp);
+        p.writeInt32(p_cur->NR_SignalStrength.csiRsrq);
+        p.writeInt32(p_cur->NR_SignalStrength.csiSinr);
+#endif
+        startResponse;
+
+#ifdef TELEMATIC_5G_SUPPORT
+        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,\
+                NR_SignalStrength.ssRsrp=%d,NR_SignalStrength.ssRsrq=%d,NR_SignalStrength.ssSinr=%d,\
+                NR_SignalStrength.csiRsrp=%d,NR_SignalStrength.csiRsrq=%d,NR_SignalStrength.csiSinr=%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,
+                p_cur->NR_SignalStrength.ssRsrp,
+                p_cur->NR_SignalStrength.ssRsrq,
+                p_cur->NR_SignalStrength.ssSinr,
+                p_cur->NR_SignalStrength.csiRsrp,
+                p_cur->NR_SignalStrength.csiRsrq,
+                p_cur->NR_SignalStrength.csiSinr);
+#else
+        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);
+#endif
+        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: {
+                /*Typethree add for T800 earfcn 2022/06/09 start*/
+                appendPrintBuf("%s LTE id: mcc=%d,mnc=%d,ci=%d,pci=%d,tac=%d,earfcn=%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_cur->CellInfo.lte.cellIdentityLte.earfcn);
+
+                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);
+                p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.earfcn);
+                /*Typethree add for T800 earfcn 2022/06/09 end*/
+                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;
+            }
+#ifdef TELEMATIC_5G_SUPPORT
+            case RIL_CELL_INFO_TYPE_NR: {
+                /*Typethree add for T800 5G cid 2022/06/09 start*/
+                appendPrintBuf("%s NR id: mcc=%d,mnc=%d,nci=%llu,pci=%d,tac=%d", printBuf,
+                    p_cur->CellInfo.nr.cellidentity.mcc,
+                    p_cur->CellInfo.nr.cellidentity.mnc,
+                    p_cur->CellInfo.nr.cellidentity.nci,
+                    p_cur->CellInfo.nr.cellidentity.pci,
+                    p_cur->CellInfo.nr.cellidentity.tac,
+                    p_cur->CellInfo.nr.cellidentity.nrarfcn);
+
+                p.writeInt32(p_cur->CellInfo.nr.cellidentity.mcc);
+                p.writeInt32(p_cur->CellInfo.nr.cellidentity.mnc);
+                p.writeUint64(p_cur->CellInfo.nr.cellidentity.nci);
+                p.writeInt32(p_cur->CellInfo.nr.cellidentity.pci);
+                p.writeInt32(p_cur->CellInfo.nr.cellidentity.tac);
+                p.writeInt32(p_cur->CellInfo.nr.cellidentity.nrarfcn);
+                /*Typethree add for T800 5G cid 2022/06/09 end*/
+                appendPrintBuf("%s NRSS: ssRsrp=%d,ssRsrq=%d,ssSinr=%d,csiRsrp=%d,csiRsrq=%d,csiSinr=%d", printBuf,
+                    p_cur->CellInfo.nr.signalStrength.ssRsrp,
+                    p_cur->CellInfo.nr.signalStrength.ssRsrq,
+                    p_cur->CellInfo.nr.signalStrength.ssSinr,
+                    p_cur->CellInfo.nr.signalStrength.csiRsrp,
+                    p_cur->CellInfo.nr.signalStrength.csiRsrq,
+                    p_cur->CellInfo.nr.signalStrength.csiSinr);
+                p.writeInt32(p_cur->CellInfo.nr.signalStrength.ssRsrp);
+                p.writeInt32(p_cur->CellInfo.nr.signalStrength.ssRsrq);
+                p.writeInt32(p_cur->CellInfo.nr.signalStrength.ssSinr);
+                p.writeInt32(p_cur->CellInfo.nr.signalStrength.csiRsrp);
+                p.writeInt32(p_cur->CellInfo.nr.signalStrength.csiRsrq);
+                p.writeInt32(p_cur->CellInfo.nr.signalStrength.csiSinr);
+                break;
+            }
+#endif
+        }
+        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
+
+static void parse_version_buf(char *buf){
+    char *p = buf;
+    int flag = 0;
+    int recv = 0;
+    int tmp = -1;
+    while (*p != '\0')
+    {   
+        recv++;
+        if(*p == '"'){
+            tmp = recv;        
+        }
+        if(tmp >= 0){
+            buf[flag++] = buf[tmp++];
+            if(buf[flag-1] == '\"'){
+                buf[flag-1] = '\0';
+            }
+        }
+        *p++;
+    }
+    return;
+}
+
+static int lynq_get_version(){
+    FILE *fp;
+    char buf[128] = {0};
+    char cgmr[128] = {0};
+    sprintf(buf, "uci get lynq_uci_ro.lynq_version.LYNQ_SW_VERSION 2>&1");
+    fp=popen(buf, "r");
+    int n;
+    while(fgets(buf, sizeof(buf), fp) != NULL)
+    {
+    }
+    //parse_version_buf(buf);
+    sprintf(cgmr, "%s %s", "+CGMR:", buf);
+    n = write(ttyGS3_fd,cgmr,strlen(cgmr));
+    if(n<0)
+    {
+        perror("lynq resp write:");
+    }
+    pclose(fp);
+    return 0;
+}
+
+static int lynq_get_inside_version(){
+    FILE *fp;
+    char buf[128] = {0};
+    char cgmr[128] = {0};
+    sprintf(buf, "uci get lynq_uci_ro.lynq_version.LYNQ_SW_INSIDE_VERSION 2>&1");
+    fp=popen(buf, "r");
+    int n;
+    while(fgets(buf, sizeof(buf), fp) != NULL)
+    {
+    }
+    //parse_version_buf(buf);
+    sprintf(cgmr, "%s %s", "+CGIR:", buf);
+    n = write(ttyGS3_fd,cgmr,strlen(cgmr));
+    if(n<0)
+    {
+        perror("lynq resp write:");
+    }
+    pclose(fp);
+    return 0;
+}
+
+/**
+ * @brief cgmr ---> cgir
+ * 
+ * @param response 
+ */
+static void parse_inside_version(void *response)
+{
+    char *p = (char *)response;
+    while (*p != 0)
+    {
+        if(*p == 'M')
+        {
+            *p = 'I';
+            break;
+        }
+        else
+        {
+            *p ++;
+        }
+    }
+    return;
+}
+
+/**
+ * @brief To handle comma-separated strings, take the character before the first comma  eg:123456,78 ->123456
+ * 
+ * @param buf Type:[IN]
+ */
+static void parse_imei(char buf[])
+{
+    if(NULL == buf)
+    {
+        return;
+    }
+    const char s[2] = ",";
+    char *token;
+    token = strtok(buf, s);
+    return;
+}
+
+static char * lynqStrdupReadString(Parcel &p) {
+    size_t stringlen;
+    const char16_t *s16;
+
+    s16 = p.readString16Inplace(&stringlen);
+    return strndup16to8(s16, stringlen);
+}
+
+static void lynq_get_mccmnc(Parcel &p, char *mccmnc)
+{
+    p.setDataPosition(0);
+    if(p.dataAvail() > 0)
+    {
+        int resp_type;
+        int token;
+        int request;
+        int slot_id;
+        int error1;
+        int num;
+        char *resp[128];
+        p.readInt32(&resp_type);
+        p.readInt32(&token);
+        p.readInt32(&request);
+        p.readInt32(&slot_id);
+        p.readInt32(&error1);
+        if(!error1)
+        {
+            p.readInt32(&num);
+            if(num == 0 || num > 128)
+            {
+                LYERRLOG("no paramters or num %d too great",num);
+            }
+            else
+            {
+                int i;
+                for(i = 0; i<num;i++)
+                {
+                    resp[i] = lynqStrdupReadString(p);
+                }
+                if(NULL != resp[2])
+                {
+                    strcpy(mccmnc,resp[2]);
+                    printf("mcc mnc %s\n", mccmnc);
+                }
+                for(i = 0; i<num;i++)
+                {
+                    if(resp[i]!=NULL)
+                    {
+                        free(resp[i]);
+                    }  
+                }
+            }
+        }
+        else
+        {
+            LYERRLOG("lynq_get_mccmnc error");
+        }
+    }
+}
+
+static void lynq_sdk_ready(Parcel &p)
+{
+    int resp_type;
+    int token;
+    int request;
+    int slot_id;
+    int error1;
+    int num;
+    char imei[32] = {0};
+    if(sdk_ready == true)
+    {
+        p.setDataPosition(0);
+        if(p.dataAvail() > 0)
+        {
+            p.readInt32(&resp_type);
+            p.readInt32(&token);
+            p.readInt32(&request);
+            p.readInt32(&slot_id);
+            p.readInt32(&error1);
+            if(!error1)
+            {
+                system("uci set lynq_uci.sdk_ready=0");
+            }
+            else
+            {
+                system("uci set lynq_uci.sdk_ready=2");
+            }
+        }
+        sdk_ready = false;
+    }
+}
+
+static void lynq_get_sim_state(RIL_CardStatus_v6 *card_status)
+{
+    g_lynq_sim_state = card_status->card_state;
+}
+
+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;
+#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));
+
+    if (pRI->cancelled == 0) {
+        Parcel p;
+
+        p.writeInt32 (RESPONSE_SOLICITED);
+        p.writeInt32 (pRI->uToken);
+        p.writeInt32 (pRI->pCI->requestNumber);
+        /*warren add for t800 ril servie 2021/12/15 start*/
+        p.writeInt32(socket_id);
+        /*warren add for t800 ril servie 2021/12/15 end*/
+        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);
+#ifdef TELEMATIC_5G_SUPPORT
+                       } else if(tempVal == RADIO_TECH_NR) { //5G
+                           sprintf(respStr,"%s radioTech is 5G!",respStr);
+#endif
+                       } 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);
+                   }
+                   /*Warren add for SZZT 2021/11/14 start*/
+                   lynqAtRespWatingEvent();
+                   /*Warren add for SZZT 2021/11/14 end*/
+                   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);
+                   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_ANSWER:
+               {
+                   if(e==RIL_E_SUCCESS)
+                   {
+                       resetMute();
+                   }                   
+                   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);
+                       lynq_get_sim_state(p_cur);
+                   }
+                   lynq_send_result_already();
+                   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;
+               }
+               /*lei add for sdk ready 2022/8/17*/
+                case RIL_REQUEST_DEVICE_IDENTITY:
+                {
+                    lynq_sdk_ready(p);
+                    break;
+                }
+                /*lei add for sdk ready 2022/8/17*/
+                case RIL_REQUEST_OPERATOR:
+                {
+                    lynq_get_mccmnc(p, mccmnc);
+                    lynq_send_result_already();
+                    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
+        LYNQ_RIL_respSocket(p,t);
+        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("wait and recreate PDN with sim switch");
+                resetConnect();
+                sleep(WAIT_TIME_FOR_SIM_SWITCH);
+                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;
+    int temp = 0;
+    char *tempChar=NULL;
+    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);
+    /*Warren add for t800 ril service 2021/12/16 start*/
+    p.writeInt32 (soc_id);
+    /*Warren add for t800 ril service 2021/12/16 end*/
+    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) {
+#ifdef LED_SUPPORT
+    case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:   //add this for API-720
+        ARspRequest(RIL_REQUEST_GET_CURRENT_CALLS, soc_id);
+        break;
+#endif
+    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:
+        ARspRequest(RIL_REQUEST_VOICE_REGISTRATION_STATE,soc_id);
+        break;
+    case RIL_UNSOL_RESPONSE_PS_NETWORK_STATE_CHANGED:
+        ARspRequest(RIL_REQUEST_DATA_REGISTRATION_STATE,soc_id);
+        break;
+    case RIL_UNSOL_RESPONSE_NEW_SMS:
+        responseNewSMS((const char*)data, datalen,soc_id,unsolResponse,p);
+        unreadStatusWriteSMSToSim((const char*)data, datalen, soc_id);
+        sendSMSACK(soc_id);
+        break;
+    case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS:
+    {
+        RLOGD("Receive RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS data: %s, length: %d", (char*)data, datalen);
+        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;
+    }
+    /*Warren add for t800 ril service 2021/12/16 start*/
+    ret = LYNQ_RIL_urcBroadcast(p,unsolResponse);
+    /*Warren add for t800 ril service 2021/12/16 end*/
+#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 *lynq_requset_to_string(int request)
+{
+    switch(request) {
+        case RIL_REQUEST_GET_SIM_STATUS: return "RIL_REQUEST_GET_SIM_STATUS";
+        case RIL_REQUEST_ENTER_SIM_PIN: return "RIL_REQUEST_ENTER_SIM_PIN";
+        case RIL_REQUEST_ENTER_SIM_PUK: return "RIL_REQUEST_ENTER_SIM_PUK";
+        case RIL_REQUEST_ENTER_SIM_PIN2: return "RIL_REQUEST_ENTER_SIM_PIN2";
+        case RIL_REQUEST_ENTER_SIM_PUK2: return "RIL_REQUEST_ENTER_SIM_PUK2";
+        case RIL_REQUEST_CHANGE_SIM_PIN: return "RIL_REQUEST_CHANGE_SIM_PIN";
+        case RIL_REQUEST_CHANGE_SIM_PIN2: return "RIL_REQUEST_CHANGE_SIM_PIN2";
+        case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION: return "RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION";
+        case RIL_REQUEST_GET_CURRENT_CALLS: return "RIL_REQUEST_GET_CURRENT_CALLS";
+        case RIL_REQUEST_DIAL: return "RIL_REQUEST_DIAL";
+        case RIL_REQUEST_GET_IMSI: return "RIL_REQUEST_GET_IMSI";
+        case RIL_REQUEST_HANGUP: return "RIL_REQUEST_HANGUP";
+        case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: return "RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND";
+        case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: return "RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND";
+        case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: return "RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE";
+        case RIL_REQUEST_CONFERENCE: return "RIL_REQUEST_CONFERENCE";
+        case RIL_REQUEST_UDUB: return "RIL_REQUEST_UDUB";
+        case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: return "RIL_REQUEST_LAST_CALL_FAIL_CAUSE";
+        case RIL_REQUEST_SIGNAL_STRENGTH: return "RIL_REQUEST_SIGNAL_STRENGTH";
+        case RIL_REQUEST_VOICE_REGISTRATION_STATE: return "RIL_REQUEST_VOICE_REGISTRATION_STATE";
+        case RIL_REQUEST_DATA_REGISTRATION_STATE: return "RIL_REQUEST_DATA_REGISTRATION_STATE";
+        case RIL_REQUEST_OPERATOR: return "RIL_REQUEST_OPERATOR";
+        case RIL_REQUEST_RADIO_POWER: return "RIL_REQUEST_RADIO_POWER";
+        case RIL_REQUEST_DTMF: return "RIL_REQUEST_DTMF";
+        case RIL_REQUEST_SEND_SMS: return "RIL_REQUEST_SEND_SMS";
+        case RIL_REQUEST_SEND_SMS_EXPECT_MORE: return "RIL_REQUEST_SEND_SMS_EXPECT_MORE";
+        case RIL_REQUEST_SETUP_DATA_CALL: return "RIL_REQUEST_SETUP_DATA_CALL";
+        case RIL_REQUEST_SIM_IO: return "RIL_REQUEST_SIM_IO";
+        case RIL_REQUEST_SEND_USSD: return "RIL_REQUEST_SEND_USSD";
+        case RIL_REQUEST_CANCEL_USSD: return "RIL_REQUEST_CANCEL_USSD";
+        case RIL_REQUEST_GET_CLIR: return "RIL_REQUEST_GET_CLIR";
+        case RIL_REQUEST_SET_CLIR: return "RIL_REQUEST_SET_CLIR";
+        case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS: return "RIL_REQUEST_QUERY_CALL_FORWARD_STATUS";
+        case RIL_REQUEST_SET_CALL_FORWARD: return "RIL_REQUEST_SET_CALL_FORWARD";
+        case RIL_REQUEST_QUERY_CALL_WAITING: return "RIL_REQUEST_QUERY_CALL_WAITING";
+        case RIL_REQUEST_SET_CALL_WAITING: return "RIL_REQUEST_SET_CALL_WAITING";
+        case RIL_REQUEST_SMS_ACKNOWLEDGE: return "RIL_REQUEST_SMS_ACKNOWLEDGE";
+        case RIL_REQUEST_GET_IMEI: return "RIL_REQUEST_GET_IMEI";
+        case RIL_REQUEST_GET_IMEISV: return "RIL_REQUEST_GET_IMEISV";
+        case RIL_REQUEST_ANSWER: return "RIL_REQUEST_ANSWER";
+        case RIL_REQUEST_DEACTIVATE_DATA_CALL: return "RIL_REQUEST_DEACTIVATE_DATA_CALL";
+        case RIL_REQUEST_QUERY_FACILITY_LOCK: return "RIL_REQUEST_QUERY_FACILITY_LOCK";
+        case RIL_REQUEST_SET_FACILITY_LOCK: return "RIL_REQUEST_SET_FACILITY_LOCK";
+        case RIL_REQUEST_CHANGE_BARRING_PASSWORD: return "RIL_REQUEST_CHANGE_BARRING_PASSWORD";
+        case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: return "RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE";
+        case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: return "RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC";
+        case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: return "RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL";
+        case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS : return "RIL_REQUEST_QUERY_AVAILABLE_NETWORKS";
+        case RIL_REQUEST_DTMF_START: return "RIL_REQUEST_DTMF_START";
+        case RIL_REQUEST_DTMF_STOP: return "RIL_REQUEST_DTMF_STOP";
+        case RIL_REQUEST_BASEBAND_VERSION: return "RIL_REQUEST_BASEBAND_VERSION";
+        case RIL_REQUEST_SEPARATE_CONNECTION: return "RIL_REQUEST_SEPARATE_CONNECTION";
+        case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: return "RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE";
+        case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: return "RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE";
+        case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: return "RIL_REQUEST_GET_NEIGHBORING_CELL_IDS";
+        case RIL_REQUEST_SET_MUTE: return "RIL_REQUEST_SET_MUTE";
+        case RIL_REQUEST_GET_MUTE: return "RIL_REQUEST_GET_MUTE";
+        case RIL_REQUEST_QUERY_CLIP: return "RIL_REQUEST_QUERY_CLIP";
+        case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE: return "RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE";
+        case RIL_REQUEST_DATA_CALL_LIST: return "RIL_REQUEST_DATA_CALL_LIST";
+        case RIL_REQUEST_RESET_RADIO: return "RIL_REQUEST_RESET_RADIO";
+        case RIL_REQUEST_OEM_HOOK_RAW: return "RIL_REQUEST_OEM_HOOK_RAW";
+        case RIL_REQUEST_OEM_HOOK_STRINGS: return "RIL_REQUEST_OEM_HOOK_STRINGS";
+        case RIL_REQUEST_SET_BAND_MODE: return "RIL_REQUEST_SET_BAND_MODE";
+        case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: return "RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE";
+        case RIL_REQUEST_STK_GET_PROFILE: return "RIL_REQUEST_STK_GET_PROFILE";
+        case RIL_REQUEST_STK_SET_PROFILE: return "RIL_REQUEST_STK_SET_PROFILE";
+        case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: return "RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND";
+        case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: return "RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE";
+        case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: return "RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM";
+        case RIL_REQUEST_SCREEN_STATE: return "RIL_REQUEST_SCREEN_STATE";
+        case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: return "RIL_REQUEST_EXPLICIT_CALL_TRANSFER";
+        case RIL_REQUEST_SET_LOCATION_UPDATES: return "RIL_REQUEST_SET_LOCATION_UPDATES";
+        case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE:return"RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE";
+        case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE:return"RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE";
+        case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE:return"RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE";
+        case RIL_REQUEST_SET_TTY_MODE:return"RIL_REQUEST_SET_TTY_MODE";
+        case RIL_REQUEST_QUERY_TTY_MODE:return"RIL_REQUEST_QUERY_TTY_MODE";
+        case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE:return"RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE";
+        case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE:return"RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE";
+        case RIL_REQUEST_CDMA_FLASH:return"RIL_REQUEST_CDMA_FLASH";
+        case RIL_REQUEST_CDMA_BURST_DTMF:return"RIL_REQUEST_CDMA_BURST_DTMF";
+        case RIL_REQUEST_CDMA_SEND_SMS:return"RIL_REQUEST_CDMA_SEND_SMS";
+        case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE:return"RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE";
+        case RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG:return"RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG";
+        case RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG:return"RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG";
+        case RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION:return "RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION";
+        case RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG:return "RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG";
+        case RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG:return "RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG";
+        case RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION:return "RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION";
+        case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY: return"RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY";
+        case RIL_REQUEST_CDMA_SUBSCRIPTION: return"RIL_REQUEST_CDMA_SUBSCRIPTION";
+        case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM: return "RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM";
+        case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM: return "RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM";
+        case RIL_REQUEST_DEVICE_IDENTITY: return "RIL_REQUEST_DEVICE_IDENTITY";
+        case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: return "RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE";
+        case RIL_REQUEST_GET_SMSC_ADDRESS: return "RIL_REQUEST_GET_SMSC_ADDRESS";
+        case RIL_REQUEST_SET_SMSC_ADDRESS: return "RIL_REQUEST_SET_SMSC_ADDRESS";
+        case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: return "RIL_REQUEST_REPORT_SMS_MEMORY_STATUS";
+        case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: return "RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING";
+        case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: return "RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE";
+        case RIL_REQUEST_ISIM_AUTHENTICATION: return "RIL_REQUEST_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 "RIL_REQUEST_VOICE_RADIO_TECH";
+        case RIL_REQUEST_GET_CELL_INFO_LIST: return"RIL_REQUEST_GET_CELL_INFO_LIST";
+        case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE: return"RIL_REQUEST_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 "RIL_REQUEST_IMS_REGISTRATION_STATE";
+        case RIL_REQUEST_IMS_SEND_SMS: return "RIL_REQUEST_IMS_SEND_SMS";
+        case RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC: return "RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC";
+        case RIL_REQUEST_SIM_OPEN_CHANNEL: return "RIL_REQUEST_SIM_OPEN_CHANNEL";
+        case RIL_REQUEST_SIM_CLOSE_CHANNEL: return "RIL_REQUEST_SIM_CLOSE_CHANNEL";
+        case RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL: return "RIL_REQUEST_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 "RIL_REQUEST_SET_UICC_SUBSCRIPTION";
+        case RIL_REQUEST_ALLOW_DATA: return "RIL_REQUEST_ALLOW_DATA";
+        case RIL_REQUEST_GET_HARDWARE_CONFIG: return "RIL_REQUEST_GET_HARDWARE_CONFIG";
+        case RIL_REQUEST_SIM_AUTHENTICATION: return "RIL_REQUEST_SIM_AUTHENTICATION";
+        case RIL_REQUEST_GET_DC_RT_INFO: return "RIL_REQUEST_GET_DC_RT_INFO";
+        case RIL_REQUEST_SET_DC_RT_INFO_RATE: return "RIL_REQUEST_SET_DC_RT_INFO_RATE";
+        case RIL_REQUEST_SET_DATA_PROFILE: return "RIL_REQUEST_SET_DATA_PROFILE";
+        case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: return "RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED";
+        case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: return "RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED";
+        case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: return "RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED";
+        case RIL_UNSOL_RESPONSE_NEW_SMS: return "RIL_UNSOL_RESPONSE_NEW_SMS";
+        case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: return "RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT";
+        case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: return "RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM";
+        case RIL_UNSOL_ON_USSD: return "RIL_UNSOL_ON_USSD";
+        case RIL_UNSOL_ON_USSD_REQUEST: return "RIL_UNSOL_ON_USSD_REQUEST";
+        case RIL_UNSOL_NITZ_TIME_RECEIVED: return "RIL_UNSOL_NITZ_TIME_RECEIVED";
+        case RIL_UNSOL_SIGNAL_STRENGTH: return "RIL_UNSOL_SIGNAL_STRENGTH";
+        case RIL_UNSOL_STK_SESSION_END: return "RIL_UNSOL_STK_SESSION_END";
+        case RIL_UNSOL_STK_PROACTIVE_COMMAND: return "RIL_UNSOL_STK_PROACTIVE_COMMAND";
+        case RIL_UNSOL_STK_EVENT_NOTIFY: return "RIL_UNSOL_STK_EVENT_NOTIFY";
+        case RIL_UNSOL_STK_CALL_SETUP: return "RIL_UNSOL_STK_CALL_SETUP";
+        case RIL_UNSOL_SIM_SMS_STORAGE_FULL: return "RIL_UNSOL_SIM_SMS_STORAGE_FULL";
+        case RIL_UNSOL_SIM_REFRESH: return "RIL_UNSOL_SIM_REFRESH";
+        case RIL_UNSOL_DATA_CALL_LIST_CHANGED: return "RIL_UNSOL_DATA_CALL_LIST_CHANGED";
+        case RIL_UNSOL_CALL_RING: return "RIL_UNSOL_CALL_RING";
+        case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: return "RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED";
+        case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: return "RIL_UNSOL_RESPONSE_CDMA_NEW_SMS";
+        case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: return "RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS";
+        case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL: return "RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL";
+        case RIL_UNSOL_RESTRICTED_STATE_CHANGED: return "RIL_UNSOL_RESTRICTED_STATE_CHANGED";
+        case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: return "RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE";
+        case RIL_UNSOL_CDMA_CALL_WAITING: return "RIL_UNSOL_CDMA_CALL_WAITING";
+        case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: return "RIL_UNSOL_CDMA_OTA_PROVISION_STATUS";
+        case RIL_UNSOL_CDMA_INFO_REC: return "RIL_UNSOL_CDMA_INFO_REC";
+        case RIL_UNSOL_OEM_HOOK_RAW: return "RIL_UNSOL_OEM_HOOK_RAW";
+        case RIL_UNSOL_RINGBACK_TONE: return "RIL_UNSOL_RINGBACK_TONE";
+        case RIL_UNSOL_RESEND_INCALL_MUTE: return "RIL_UNSOL_RESEND_INCALL_MUTE";
+        case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED: return "RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED";
+        case RIL_UNSOL_CDMA_PRL_CHANGED: return "RIL_UNSOL_CDMA_PRL_CHANGED";
+        case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: return "RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE";
+        case RIL_UNSOL_RIL_CONNECTED: return "RIL_UNSOL_RIL_CONNECTED";
+        case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED: return "RIL_UNSOL_VOICE_RADIO_TECH_CHANGED";
+        case RIL_UNSOL_CELL_INFO_LIST: return "RIL_UNSOL_CELL_INFO_LIST";
+        case RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED: return "RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED";
+        case RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED: return "RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED";
+        case RIL_UNSOL_SRVCC_STATE_NOTIFY: return "RIL_UNSOL_SRVCC_STATE_NOTIFY";
+        case RIL_UNSOL_HARDWARE_CONFIG_CHANGED: return "RIL_UNSOL_HARDWARE_CONFIG_CHANGED";
+        case RIL_UNSOL_DC_RT_INFO_CHANGED: return "RIL_UNSOL_DC_RT_INFO_CHANGED";
+        case RIL_REQUEST_SHUTDOWN: return "RIL_REQUEST_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 "RIL_REQUEST_SET_AUDIO_PATH";
+        case RIL_REQUEST_HANGUP_ALL: return "RIL_REQUEST_HANGUP_ALL";
+        case RIL_REQUEST_FORCE_RELEASE_CALL: return "RIL_REQUEST_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 "RIL_REQUEST_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 "RIL_REQUEST_ADD_IMS_CONFERENCE_CALL_MEMBER";
+        case RIL_REQUEST_REMOVE_IMS_CONFERENCE_CALL_MEMBER: return "RIL_REQUEST_REMOVE_IMS_CONFERENCE_CALL_MEMBER";
+        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_HOLD_CALL: return "RIL_REQUEST_HOLD_CALL";
+        case RIL_REQUEST_RESUME_CALL: return "RIL_REQUEST_RESUME_CALL";
+        case RIL_UNSOL_ECONF_SRVCC_INDICATION : return "RIL_UNSOL_ECONF_SRVCC_INDICATION";
+        case RIL_UNSOL_ECONF_RESULT_INDICATION : return "RIL_UNSOL_ECONF_RESULT_INDICATION";
+        case RIL_UNSOL_MAL_AT_INFO : return "RIL_UNSOL_MAL_AT_INFO";
+        case RIL_REQUEST_MODEM_POWEROFF: return "RIL_REQUEST_MODEM_POWEROFF";
+        case RIL_REQUEST_MODEM_POWERON: return "RIL_REQUEST_MODEM_POWERON";
+        case RIL_REQUEST_WRITE_SMS_TO_SIM: return "RIL_REQUEST_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 "RIL_REQUEST_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 "RIL_REQUEST_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 "RIL_UNSOL_ECALL_MSDHACK";
+        case RIL_REQUEST_ECALL_SET_MSD: return "RIL_REQUEST_ECALL_SET_MSD";
+        case RIL_REQUEST_ECALL_CTRL_SEQUENCE: return "RIL_REQUEST_ECALL_CTRL_SEQUENCE";
+        case RIL_UNSOL_ECALL_INDICATIONS : return "RIL_UNSOL_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 "RIL_REQUEST_SEND_USSI";
+        case RIL_REQUEST_CANCEL_USSI: return "RIL_REQUEST_CANCEL_USSI";
+        case RIL_REQUEST_GET_SMS_SIM_MEM_STATUS: return "RIL_REQUEST_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";
+/*Typethree add for t800 RIL Service 2022/04/14 start*/
+//#ifdef TARGET_PLATFORM_MT2731
+        case RIL_REQUEST_MODIFY_APN: return "RIL_REQUEST_MODIFY_APN";
+        case RIL_REQUEST_RESET_APN: return "RIL_REQUEST_RESET_APN";
+//#endif
+/*Typethree add for t800 RIL Service 2022/04/14 end*/
+        case RIL_REQUEST_QUERY_SIM_RETRY_COUNT: return "RIL_REQUEST_QUERY_SIM_RETRY_COUNT";
+        case RIL_REQUEST_QUERY_EID: return "RIL_REQUEST_QUERY_EID";
+        /*LYNQ CMD*/
+        case LYNQ_AUTO_ANSWER_CALL: return "LYNQ_AUTO_ANSWER_CALL";
+        case LYNQ_REQUEST_SET_DTMF_VOLUME: return "RIL_REQUEST_SET_DTMF_VOLUME";
+        case LYNQ_REQUEST_SET_SPEECH_VOLUME: return "RIL_REQUEST_SET_SPEECH_VOLUME";
+        case LYNQ_REQUEST_GET_SPEECH_VOLUME: return "RIL_REQUEST_GET_SPEECH_VOLUME";
+        case LYNQ_REQUEST_RECORD: return "RIL_REQUEST_RECORD";       
+        case LYNQ_REQUEST_WRITE_SMS_TO_MEMORY: return "LYNQ_REQUEST_WRITE_SMS_TO_MEMORY";
+        case LYNQ_REQUEST_READ_SMS_FROM_MEMORY: return "LYNQ_REQUEST_READ_SMS_FROM_MEMORY";
+        case LYNQ_REQUEST_DELETE_SMS_FROM_MEMORY: return "LYNQ_REQUEST_DELETE_SMS_FROM_MEMORY";
+        case LYNQ_REQUEST_LIST_SMS_FROM_MEMORY: return "LYNQ_REQUEST_LIST_SMS_FROM_MEMORY";
+        case LYNQ_REQUEST_SET_DEFAULT_SIM_ALL:return "SET_DEFAULT_SIM_ALL";
+        case LYNQ_REQUEST_CHANGE_SCREEN_STATE:return "LYNQ_REQUEST_CHANGE_SCREEN_STATE";/*jb.qi add for two sim sleep 2022/9/19*/
+        case LYNQ_REQUEST_CHANGE_RADIO:return "LYNQ_REQUEST_CHANGE_RADIO";/*lei add for factory test of sleep 2022/9/19*/
+        /*warren add for t800 ril service 2022/1/22 end*/
+        default: return "<unknown request>";
+    }
+}
+
+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_PS_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";
+        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";
+        case RIL_REQUEST_QUERY_EID: return "RIL_REQUEST_QUERY_EID";
+        case LYNQ_REQUEST_SET_DTMF_VOLUME: return "RIL_REQUEST_SET_DTMF_VOLUME";
+        case LYNQ_REQUEST_SET_SPEECH_VOLUME: return "RIL_REQUEST_SET_SPEECH_VOLUME";
+        case LYNQ_REQUEST_GET_SPEECH_VOLUME: return "RIL_REQUEST_GET_SPEECH_VOLUME";
+        case LYNQ_REQUEST_RECORD: return "RIL_REQUEST_RECORD";
+        /*warren add for t800 ril service 2022/1/22 start*/
+        case LYNQ_REQUEST_WRITE_SMS_TO_MEMORY: return "LYNQ_REQUEST_WRITE_SMS_TO_MEMORY";
+        case LYNQ_REQUEST_READ_SMS_FROM_MEMORY: return "LYNQ_REQUEST_READ_SMS_FROM_MEMORY";
+        case LYNQ_REQUEST_DELETE_SMS_FROM_MEMORY: return "LYNQ_REQUEST_DELETE_SMS_FROM_MEMORY";
+        case LYNQ_REQUEST_LIST_SMS_FROM_MEMORY: return "LYNQ_REQUEST_LIST_SMS_FROM_MEMORY";
+        case LYNQ_REQUEST_SET_DEFAULT_SIM_ALL:return "SET_DEFAULT_SIM_ALL";
+        case LYNQ_REQUEST_CHANGE_SCREEN_STATE:return "LYNQ_REQUEST_CHANGE_SCREEN_STATE";/*jb.qi add for two sim sleep 2022/9/19*/
+        case LYNQ_REQUEST_CHANGE_RADIO:return "LYNQ_REQUEST_CHANGE_RADIO";/*lei add for factory test of sleep 2022/9/19*/
+        /*warren add for t800 ril service 2022/1/22 end*/
+        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);
+            }
+    }
+}
+
+/**@brief pass the change screen state request to the executing function
+*@param   request  type: [IN] requestID
+*@param   slot_id  type: [IN] simID
+*@param   argv  type: [IN] getScreenState's argv 
+*@author  jb.qi
+*@date    2022/09/19
+*/
+void lynq_sendRequestToMd(int request, int slot_id, char **argv, struct sockaddr_in lynqClient_addr, int utoken)
+{
+    RequestInfo* info = creatRILInfoAndInit(request, UDP, (RIL_SOCKET_ID) ((slot_id)));
+    info->uToken = utoken;
+    info->lynqEvent = 2;
+    info->uClient_addr.sin_family = lynqClient_addr.sin_family;
+    info->uClient_addr.sin_addr.s_addr = lynqClient_addr.sin_addr.s_addr;
+    info->uClient_addr.sin_port = lynqClient_addr.sin_port;
+    switch(request){
+        case RIL_REQUEST_SCREEN_STATE:
+        {
+            int waittoken = info->token;
+            RLOGD("getScreenState\n");
+            getScreenState(2, argv, (RIL_SOCKET_ID) ((slot_id)), info);
+            waitResponse(waittoken);
+            break;
+        }
+        case RIL_REQUEST_RADIO_POWER:
+        {
+            int waittoken = info->token;
+            RLOGD("LYNQ_REQUEST_CHANGE_RADIO\n");
+            setRadioPower(2, argv, (RIL_SOCKET_ID) ((slot_id)), info);
+            waitResponse(waittoken);
+            break;
+        }
+        default:
+            RLOGD("dont support %d in init", slot_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));
+    updataDataConnectState(id, false);
+    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()
+{
+#ifdef LED_SUPPORT
+    mbtk_netled_init();
+#endif
+    mixer_init();
+    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);
+    }	
+}
+
+
+//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_PS_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;
+    printf("warren test cmd=%s\n",cmd);
+    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;
+                while (*pos != '\0' && *pos != '\n') {
+                    pos++;
+                }
+                *pos++ = '\0';
+                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* 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;
+}
+/*Warren add for t800 RIL Service 2021/12/10 start*/
+int lynqAssemblyParcelheader(Parcel &p,int slot,int utoken, int request,int respType,int error)
+{
+   p.writeInt32 (respType);
+   p.writeInt32 (utoken);
+   p.writeInt32 (request);
+   /*warren add for t800 ril servie 2021/12/15 start*/
+   p.writeInt32(slot);
+   /*warren add for t800 ril servie 2021/12/15 end*/
+   p.writeInt32 (error);
+   return 0;
+}
+void LYNQ_RIL_urcClientInit()
+{
+    int len = 0;
+    int on=1;
+    int ret = 0;
+    lynq_urc_socket_fd = socket(AF_INET,SOCK_DGRAM,0);
+    if(lynq_urc_socket_fd < 0)
+    {
+        perror("creaet socket for udp fail");
+        return;
+    }
+    /* 设置socket允许重复使用地址与端口,SO_REUSEADDR值为2 */
+    //setsockopt(socket_fd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof on);
+    /* 使能广播功能,SO_BROADCAST值为6 */
+    ret= setsockopt(lynq_urc_socket_fd,SOL_SOCKET,SO_BROADCAST,&on,sizeof(on));
+    if(ret<0)
+    {
+        RLOGD("set broadcast fail!!!\n");
+        exit(1);
+    }
+    urc_broadcast_addr.sin_family = AF_INET;        //IPv4
+    urc_broadcast_addr.sin_port = htons(LYNQ_BRODCAST_PORT);
+    urc_broadcast_addr.sin_addr.s_addr = inet_addr("255.255.255.255" );//255.255.255.255 broadcast addrress.
+    printf("LYNQ_RIL_urcClientInit success!!!\n");
+    return;
+    /*
+    while(1)
+    {
+        len = sendto(lynq_urc_socket_fd,"hello world",11,0,(struct sockaddr *)&urc_broadcast_addr,sizeof(urc_broadcast_addr));
+        if(len > 0)
+        {
+            printf("sendto success,len=%d\n",len);
+        }
+        else
+        {
+            printf("sendto fail\n");
+        }
+        sleep(1);
+    }
+    */
+}
+
+//add by hq for bug 760 2023/02/09
+static int setnonblocking(int sockfd) {
+    int flag = fcntl(sockfd, F_GETFL, 0);  //get current flag
+    if (flag < 0) {
+        RLOGE("fcntl F_GETFL fail");
+        return -1;
+    }
+    if (fcntl(sockfd, F_SETFL, flag | O_NONBLOCK) < 0) {  //add O_NONBLOCK
+        RLOGE("fcntl F_SETFL fail");
+        return -1;
+    }
+    return 0;
+}
+
+void LYNQ_RIL_RecSocket()
+{
+    RLOGD("LYNQ_RIL_RecSocket start\n");
+    char *argv[MAX_ARGS];
+    int argc = 0;
+    int ep_fd = 0;
+    int en_fd = 0;
+    struct epoll_event lynq_ev;
+    struct epoll_event lynq_events[LYNQ_SOCKET_ENVNT_FD_MAX];
+    //prctl(PR_SET_NAME,(unsigned long)"UDP_Thr");
+
+    /*listen UPD SOCKET port */
+    struct sockaddr_in server_addr;
+    struct sockaddr_in lynqClient_addr;
+    bzero(&server_addr, sizeof(server_addr));
+    server_addr.sin_family = AF_INET;
+    server_addr.sin_addr.s_addr = inet_addr(DSET_IP_ADDRESS);
+    server_addr.sin_port = htons(LYNQ_SERVICE_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);
+    }
+
+    if(setnonblocking(server_socket_fd)!=0)
+    {
+        RLOGE("setnonblocking Failed");
+        exit(1);
+    }
+	
+    /* create epoll fd,add socket to epoll */
+    ep_fd = epoll_create(LYNQ_SOCKET_ENVNT_FD_MAX);
+    //int len = sizeof(struct sockaddr_in);
+    lynq_ev.events = EPOLLIN | EPOLLET;
+    lynq_ev.data.fd = server_socket_fd;
+    if(epoll_ctl(ep_fd, EPOLL_CTL_ADD, server_socket_fd, &lynq_ev) < 0) 
+    {
+        fprintf(stderr, "epoll set insertion error: fd=%d\n", server_socket_fd);
+        return;
+    }
+    else
+    {
+        printf("monitor socket add epoll success!!!\n");
+    }
+    char buffer[LYNQ_SOCKET_BUFFER];
+    lynq_client_t *client_tmp = NULL;
+    /* tranlate data */
+    while(true)
+    {
+        if(!s_registerCalled)
+        {
+            sleep(1);
+            continue;
+        }
+        en_fd = epoll_wait(ep_fd, lynq_events, 10000, -1);//###Check  valid
+        if(en_fd <=0 )
+        {
+            continue;
+        }
+        for (int n = 0; n < en_fd; ++n)
+        {
+            if (lynq_events[n].data.fd == server_socket_fd)
+            {
+                /* define address to catch the client addreess*/
+                //struct sockaddr_in client_addr;
+                socklen_t client_addr_length = sizeof(lynqClient_addr);
+                /* receive the data */
+                bzero(buffer, LYNQ_SOCKET_BUFFER);
+                while(recvfrom(server_socket_fd, buffer, LYNQ_SOCKET_BUFFER,0,(struct sockaddr*)&lynqClient_addr, &client_addr_length) != -1)//add while by hq for bug 760 2023/02/09
+                {
+                    client_tmp = (lynq_client_t*)buffer;
+                    RLOGD("[LYNQ socketId] utoken=%d,request=%d,len=%d,param=%s",client_tmp->uToken,client_tmp->request,client_tmp->paramLen,client_tmp->param);
+                    //char test[36] = {};
+                    //sprintf(test,"test okay len = %d",client_tmp->paramLen);
+                    //sendto(server_socket_fd,test,strlen(test),0,(struct sockaddr*)&client_addr,client_addr_length);
+                    argv[0] = (char *)lynq_requset_to_string(client_tmp->request);
+                    argc = 0;
+                    if(client_tmp->paramLen > 0)
+                    {
+                        /*transfer struct*/
+                        argc = parse_param(client_tmp->param, argv+1, MAX_ARGS);
+                        if(argc < 1)
+                        {
+                            RLOGE("%s: error input.", buffer);
+                            continue;
+                        }
+                    }
+                    printf("argc =%d\n",argc);
+                    argc = argc+1;
+                    for(int t = 0;t<argc;t++)
+                    {
+                        RLOGD("warren test argv[%d]=%s\n",t,argv[t]);
+                    }
+                    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;
+                    }
+                    /*jb.qi add for two sim suspend 2022/9/19 start  lei modify for factory test of sleep*/
+                    if(request == LYNQ_REQUEST_CHANGE_SCREEN_STATE || request == LYNQ_REQUEST_CHANGE_RADIO)
+                    {
+                        int i;
+                        RLOGD("lynq_request_change_screen_state");
+                        if(request == LYNQ_REQUEST_CHANGE_SCREEN_STATE)
+                        {
+                            for(i=0;i<2;i++) //suspend sim0 and sim1
+                            {
+                                lynq_sendRequestToMd(RIL_REQUEST_SCREEN_STATE, i, argv, lynqClient_addr, client_tmp->uToken);
+                            }
+                        }
+                        /*lei modify for factory test of sleep*/
+                        if(request == LYNQ_REQUEST_CHANGE_RADIO)
+                        {
+                            for(i=0;i<2;i++) //both radio on/off
+                            {
+                                lynq_sendRequestToMd(RIL_REQUEST_RADIO_POWER, i, argv, lynqClient_addr, client_tmp->uToken);
+                            }
+                        }
+                        continue;
+                    }
+                    /*jb.qi add for two sim suspend 2022/9/19 end*/
+                    RLOGD("REQUEST: %s ParamterNum:%d", requestToString(request), argc);
+                    RequestInfo *pRI  = creatRILInfoAndInit(request, UDP, (RIL_SOCKET_ID)(id));
+                    pRI->uToken = client_tmp->uToken;
+                    pRI->lynqEvent = 2;
+                    pRI->uClient_addr.sin_family = lynqClient_addr.sin_family;
+                    pRI->uClient_addr.sin_addr.s_addr = lynqClient_addr.sin_addr.s_addr;
+                    pRI->uClient_addr.sin_port = lynqClient_addr.sin_port;
+                    //sendto(server_socket_fd,test,strlen(test),0,(struct sockaddr*)&pRI->uClient_addr,client_addr_length);
+                    //pRI->uClient_addr.sa_family = (struct sockaddr)client_addr.sa_family;
+                    //memcpy(pRI->uClient_addr.sa_data,&client_addr
+                    //Radio on/off only allow one thread operate.
+                    if(request == RIL_REQUEST_RADIO_POWER)
+                    {
+                        speciaRequest_wait();
+                    }
+    #ifdef ECALL_SUPPORT
+                    else if(request == RIL_REQUEST_ECALL_FAST_MAKE_ECALL)
+                    {
+                        init_redial_flag();
+                    }
+    #endif
+                    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));          
+                    bzero(buffer, LYNQ_SOCKET_BUFFER);
+
+                }
+                RLOGE("process Receive Data end");
+             //   continue;                
+            }
+        }
+     }
+     RLOGD("close socket fd");
+     close(server_socket_fd);
+#ifdef LED_SUPPORT
+     mbtk_netled_deinit();
+#endif
+     return ;
+}
+int LYNQ_RIL_respSocket(Parcel &p,RIL_Token t)
+{
+    RLOGD("LYNQ_RIL_respSocket send start");
+    ssize_t sent = 0;
+    RequestInfo *pRI = (RequestInfo *)t;
+    if(pRI->lynqEvent!=2)
+    {
+        RLOGD("this is internal event!!!");
+        return -1;
+    }
+    int dataSize = p.dataSize();
+    const uint8_t* data = p.data();
+    RLOGD("lynqSocketSend RESPONSE!!!! ");
+    sent = sendto(server_socket_fd, data, dataSize, 0, (struct sockaddr *)&pRI->uClient_addr, sizeof(pRI->uClient_addr));
+    if( sent < 0 )
+    {
+        RLOGE("lynqSocketSend send datalen fail (sent=%d, sendFD=%d, dataSize=%d)",
+                sent,server_socket_fd, dataSize);
+        return -1;
+    }
+    return 0;
+}
+int LYNQ_RIL_respSocket_sp(Parcel &p,RequestInfo *pRI)
+{
+    RLOGD("LYNQ_RIL_respSocket send start");
+    int ret =0;
+    bool sendResult =false;
+    ssize_t sent = 0;
+    uint8_t dataLength[4];
+    int verify = 0x55aa;
+    int dataSize = p.dataSize();
+    const uint8_t* data = p.data();
+    if(pRI->lynqEvent!=2)
+    {
+        RLOGD("this is internal event!!!");
+        return -1;
+    }
+    RLOGD("lynqSocketSend RESPONSE!!!! ");
+
+    sent = sendto(server_socket_fd, data, dataSize, 0, (struct sockaddr *)&pRI->uClient_addr, sizeof(pRI->uClient_addr));
+    if( sent < 0 )
+    {
+        RLOGE("lynqSocketSend send datalen fail (sent=%d, sendFD=%d, dataSize=%d)",
+                sent,server_socket_fd, dataSize);
+        return -1;
+    }
+    return 0;
+}
+
+bool is_need_use_shm(int dataSize, int urc_id)
+{
+    switch(urc_id)
+    {
+        /*network*/
+        case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED:
+        case RIL_UNSOL_RESPONSE_PS_NETWORK_STATE_CHANGED:
+        case RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED:
+        case RIL_UNSOL_SIGNAL_STRENGTH:
+        /*sms*/
+        case RIL_UNSOL_RESPONSE_NEW_SMS:
+        /*sim*/
+        //case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED:   Not supported at present
+        /*call*/
+        case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:
+        case RIL_UNSOL_CALL_RING:
+        case RIL_UNSOL_RINGBACK_TONE:
+        case RIL_UNSOL_CALL_INFO_INDICATION:
+#ifdef ECALL_SUPPORT
+        case RIL_UNSOL_ECALL_INDICATIONS://9502        
+#endif       
+       /*Data*/
+        case LYNQ_URC_DATA_CALL_STATUS_IND: 
+        case LYNQ_URC_MODIFY_APNDB:
+        case LYNQ_URC_RESET_APNDB:
+            break;
+        default:
+            return false;
+    }
+    if(dataSize>urc_broadcase_shm_size_limit && dataSize <= get_max_shem_buffer_size())
+    {
+        return true;
+    }
+    return false;
+}
+
+int LYNQ_RIL_urcBroadcast(Parcel &p, int urc_id)
+{
+    RLOGD("LYNQ_RIL_urcBroadcast send start");
+    int ret =0;   
+    ssize_t sent = 0;   
+    p.setDataPosition(0);    
+    int dataSize = p.dataSize();
+    const uint8_t* data = p.data();
+    RLOGD("LYNQ_RIL_urcBroadcast urc_id is %d, dataSize=%d, msg is %s", urc_id, dataSize, requestToString(urc_id));
+    if(is_need_use_shm(dataSize,urc_id))
+    {
+        int index,level;
+        if(get_cur_shem_buffer_index(dataSize,&level,&index))
+        {
+            char* p_shm_buffer=get_shem_buffer(level,index);
+            memcpy(p_shm_buffer,data,dataSize);
+            uint32_t* pFirstInt = (uint32_t*) const_cast<uint8_t*> (data);
+               *pFirstInt=*pFirstInt+((index+1)<<SHM_BUFFER_INDEX_OFFSET)+((dataSize)<<SHM_BUFFER_SIZE_OFFSET);          
+            dataSize=sizeof(int32_t)*2;
+            RLOGD("LYNQ_RIL_urcBroadcast use share mem level is %d, index is %d,pointer is %p",level,index,p_shm_buffer);
+        }        
+    }
+    sent = sendto(lynq_urc_socket_fd, data, dataSize, 0, (struct sockaddr *)&urc_broadcast_addr, sizeof(urc_broadcast_addr));
+    if( sent < 0 )
+    {
+        RLOGE("LYNQ_RIL_urcBroadcast send datalen fail (sent=%d, sendFD=%d, dataSize=%d)",
+                sent,lynq_urc_socket_fd, dataSize);
+        return -1;
+    }
+    
+    return 0;
+}
+/*Warren add for t800 RIL Service 2021/12/10 end*/
+
+void
+RIL_StartRevSocket()
+{
+    RLOGD("RIL_StartRevSocket start\n");
+    char *argv[MAX_ARGS] = {0};
+    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);
+        if(mtkItTest(buffer)) {
+            RLOGD("mtkItTest() handle.");
+            continue;
+        }
+        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;
+}
+
+/**
+ * @brief check at input in at_buffer
+ * @param buf type:in at port input
+ * @return int 
+ */
+static int lynq_inside_at_buffer(char *buf)
+{
+    for(int i = 0; i < MAX_AT_CMD; i++)
+    {
+        if(at_buf_ext[i] == NULL)
+        {
+            break;
+        }
+        else
+        {
+            if(strstr(buf, at_buf_ext[i]))
+            {
+                return 1;
+            }
+        }
+    }
+    return 0;
+}
+
+/**
+ * @brief send input to client
+ * @param buffer type:in buffer from at port
+ * @param len_buf type:in strlen(buffer)
+ * @param client type:in sockaddr client
+ * @return int 
+ */
+static int lynq_send_info(char *buffer, int len_buf, struct sockaddr* client)
+{
+    socklen_t len = sizeof(*client);
+    int sent = sendto(sockfd,buffer,len_buf,0,client,len);
+    if( sent < 0 )
+    {
+        RLOGE("lynq_send_info send fail (sent=%d, sendFD=%d, dataSize=%d)",
+                sent,sockfd, len);
+        return sent;
+    }
+    return 0;
+}
+
+/**
+ * @brief Fetch data from a one-dimensional array into a two-dimensional array
+ * 
+ * @param cmd type:in buffer from client
+ * @param argv type:in two-dimensional array
+ * @param cnt type:in Two dimensional array subscript
+ * @return int 
+ */
+static int lynq_parse_at_cmd(char *cmd, char *argv[], int cnt)
+{
+    if(NULL == cmd || NULL == argv)
+    {
+        return -1;
+    }
+    if(cnt > MAX_AT_CMD)
+    {
+        return -1;
+    }
+    const char s[2] = ";";
+    char *token;
+    int argc = cnt;
+    token = strtok(cmd, s);
+    while( token != NULL ) {
+        argv[argc++] = token;
+        token = strtok(NULL, s);
+    }
+    return 0;
+}
+
+/**
+ * @brief count at cmd amount
+ * 
+ * @param type:in buffer 
+ * @return int 
+ */
+static int lynq_count_at(char *buffer)
+{
+    char *p = buffer;
+    int count = 0;
+    while(*p != '\0')
+    {
+        if(*p == ';')
+        {
+            count++;
+        }
+        *p++;
+    }
+    return count+1;
+}
+
+/**
+ * @brief receive registion and display on at port
+ * @param parm type:in
+ * @return void* 
+ */
+void *receive_at(void *parm)
+{
+    RLOGE("receive_at thread start\n");
+    struct sockaddr* cli = (struct sockaddr*)parm;
+    socklen_t len;
+    int recv = 0;
+    char display[1024] = {0};
+    /*For at extension to receive at buffer*/
+    bool flag = false;
+    int count_at_cmd = 0;
+    len = sizeof(*cli);
+    while(1)
+    {
+        if(!flag)
+        {
+            RLOGE("receive third at cmd\n");
+            recv = recvfrom(sockfd, buffer_at, LYNQ_AT_SOCKET_BUFFER, 0, cli, &len);
+            if(recv < 0)
+            {
+                RLOGE("recv fail\n");
+                continue;
+            }
+            RLOGE("recvfrom from client\n");
+            /*parse buffer for at command*/
+            count_at_cmd = lynq_count_at(buffer_at);
+            if(count_at_cmd > MAX_AT_CMD)
+            {
+                RLOGE("too many at cmd\n");
+                continue;;
+            }
+            lynq_parse_at_cmd(buffer_at, at_buf_ext, 0);
+            flag = true;
+        }
+        else
+        {
+            RLOGE("display output on at port\n");
+            bzero(display, 1024);
+            recv = recvfrom(sockfd, display, LYNQ_AT_SOCKET_BUFFER, 0, cli, &len);
+            if(recv < 0)
+            {
+                RLOGE("recv fail\n");
+                continue;
+            }
+            /*display on at port*/
+            else
+            {
+                strcat(display, "\n");
+                int n = write(ttyGS3_fd,display,strlen(display));
+                if(n<0)
+                {
+                    RLOGE("lynq resp write error");
+                }
+            }
+        }
+    }
+    return NULL;
+}
+
+static void wait_reset_mipc_response(void)
+{
+    int outfd = open("/data/tp",O_RDONLY);
+    if(outfd == -1){
+        RLOGD("open error");
+        return;
+    }
+    char rst[1024];
+    char response[2048];
+    int s;
+    s = read(outfd,rst,sizeof(rst));
+    if (s>0)
+    {
+        RLOGD("lei buf: %s \n", rst);
+        /*respone ok or error*/
+        if(rst[0] = '0')
+        {
+            sprintf(response,"%s%s","+LRSTMD:",rst);
+            /*check fd can or can't write*/
+            write(ttyGS3_fd,response,strlen(response));
+            write(ttyGS3_fd,"\nOK\n",4);
+        }
+        else
+        {
+            sprintf(response,"%s%s","+CME ERROR:",rst);
+            /*check fd can or can't write*/
+            write(ttyGS3_fd,response,strlen(response));
+        }
+    }
+    else
+    {
+        RLOGD("wait_reset_mipc_response unknow error\n");
+    }
+    usleep(1);
+    close(outfd);
+    return;
+}
+
+void startUsbLoop(void)
+{
+    /*lei add*/
+    //Create a network communication object
+    struct sockaddr_in addr_serv;
+    struct sockaddr_in addr_clie;
+    //Creating a Socket object
+    sockfd=socket(AF_INET,SOCK_DGRAM,0);
+    memset(&addr_serv, 0, sizeof(addr_serv));
+    addr_serv.sin_family =AF_INET;
+    addr_serv.sin_port =htons(LYNQ_AT_SERVICE_PORT);
+    addr_serv.sin_addr.s_addr=htonl(INADDR_ANY);
+    bind(sockfd,(struct sockaddr*)&addr_serv,sizeof(addr_serv));
+    //receive registion and display on at port
+    pthread_t thid;
+    if(pthread_create(&thid, NULL, receive_at, (struct sockaddr*)&addr_clie) != 0) {
+        RLOGE("thread creation failed\n");
+        exit(1);
+    }
+    RLOGE("thread creation\n");
+    /*lei add*/
+    int nread=-1;
+    int n = -1;
+    int routeId = -1;
+    char buffer[1024]={};
+    char tempbuf[1024]={};
+    char buf_parser[64] = {};
+    int argc = 0;
+    char *argv[MAX_ARGS];//argv[0]:at name,argv[1]:raw data,argv[2]:at type,argv[3]:paramter1,argv[4]:paramter2 ....
+    char eBuf[1024];
+    if(ttyGS3_fd > 0)
+    {
+        close(ttyGS3_fd);
+        RLOGE("reopen need close");
+    }
+    ttyGS3_fd = open("/dev/ttyGS3",O_RDWR);
+    if(ttyGS3_fd==-1)
+    {
+        RLOGE("open ttyGS3 failure!!!");
+        printf("open ttyGS3 failure!!!\n");
+        //printf("%s\n",strerr(errno));
+        perror("--test--");
+        //kill(0, SIGKILL);
+    }
+    RLOGD("[%s]open %s successfully ttyGS3_d %d!!!\n",__FUNCTION__,ttyname(ttyGS3_fd), ttyGS3_fd);
+    while(1)
+    {
+        bzero(buffer, 1024);
+        bzero(tempbuf, 1024);
+        bzero(buf_parser, 64);
+        if((nread=read(ttyGS3_fd,buffer,1024))>0)
+        {
+            if(nread<2)
+            {
+                //RLOGD("input is space!!!");
+                continue;
+            }
+            buffer[nread-1] = '\0';
+            //printf("buffer is %s\n",buffer);
+            for(int i = 0 ; i < nread ; i++)
+            {
+                if(buffer[i]=='=')
+                {
+                    break;
+                }
+                if(buffer[i]>='a'&&buffer[i]<='z')
+                {
+                    buffer[i] = buffer[i]-32;
+                }
+            }
+            RLOGD("buffer is %s\n",buffer);
+            /*lei add*/
+            /*check third cmd in buffer*/
+            if(lynq_inside_at_buffer(buffer))
+            {
+                lynq_send_info(buffer, nread, (struct sockaddr*)&addr_clie);
+            }
+            /*lei add*/
+            else
+            {
+                argc = lynqParseUsbCommand(buffer,argv,tempbuf,buf_parser,MAX_ARGS);
+                if(argc<0)
+                {  
+                bzero(eBuf, 1024);
+                sprintf(eBuf,"LYNQ:%s not support!!!\n",buffer);
+                int n = write(ttyGS3_fd,eBuf,strlen(eBuf));
+                if(n<0)
+                {
+                    perror("lynq resp write:");
+                }
+                RLOGD("n = %d\n",n);
+                continue;
+                }
+                usb_at_transfer_t *atCmd = lynqFindId(argv[0]);
+                if(atCmd==NULL)
+                {
+                    RLOGD("LYNQ send ATCMD:%s!!!",argv[1]);
+                    lynqSendAt(argc,argv,1010);
+                    usleep(50*1000);
+                    if(!strcmp(buffer, "AT+LRSTMD"))
+                    {
+                        wait_reset_mipc_response();
+                    }
+                    continue;
+                }
+                if(!((1<<atoi(argv[2])) & (atCmd->support)))
+                {
+                    RLOGD("LYNQ %s not support!!!",atCmd->cmdName);
+                    int n = write(ttyGS3_fd,"\n+CME ERROR: 100\n",strlen("\n+CME ERROR: 100\n"));
+                    if(n<0)
+                    {
+                        perror("lynq resp write:");
+                    }
+                    continue;
+                }
+                routeId = routeCmd(atCmd->cmdId);
+                //routeId = routeCmd(atcmd->cmdId);
+                //routeId = LYNQ_GOTO_AT;
+                switch(routeId)
+                {
+                    case LYNQ_GOTO_AT:
+                    {
+                        lynqSendAt(argc,argv,1010);
+                        break;
+                    }
+                    case LYNQ_GOTO_TELE_REQ:
+                    {
+                        usb_cmd_t *atCmdEvn = lynqFindUsbEvent(argv[0]);
+                        if(!atCmdEvn)
+                        {
+                            RLOGD("can not find at cmd event!!!");
+                            continue;
+                        }
+                        atCmdEvn->fun(argc,argv,atCmdEvn->rilRequest,1011);
+                        break;
+                    }
+                    case LYNQ_GOTO_USER_REQ:
+                    {
+                        usb_cmd_t *atCmdEvn = lynqFindUsbEvent(argv[0]);
+                        if(!atCmdEvn)
+                        {
+                            RLOGD("can not find at cmd event!!!");
+                            continue;
+                        }
+                        atCmdEvn->ufun(argc,argv,1012);
+                        break;
+                    }
+                    case LYNQ_GOTO_LINFO_REQ:
+                    {
+                        lynqInfo(argv);
+                        break;
+                    }
+                    // case LYNQ_GOTO_PLAT_REQ:
+                    // {
+                    //     lynq_deal_with_log_at(&argv[3]);
+                    //     break;
+                    // }
+                    case LYNQ_GOTO_RNDIS_REQ:
+                    {
+                        lynq_get_rndis_data(buffer);
+                        break;
+                    }
+                    case LYNQ_GOTO_FACTORY:
+                    {
+                        lynq_get_factory_data(argc,argv);
+                        break;
+                    }
+                    /*rita add start*/
+                    case LYNQ_GOTO_TEMP:
+                    {
+                        //write(ttyGS3_fd,"\n+CME ERROR: 1\n",strlen("\n+CME ERROR: 1\n"));
+                        lynq_at_get_temp(argc, argv);
+                        break;
+                     }                    
+                    default:
+                        break;
+                }
+            }
+            
+        }
+    }
+    close(ttyGS3_fd);
+    return;
+}
+
+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
+    /*warren add for t800 ril service 2021/12/13 start*/
+    //RIL_StartRevSocket();
+    LYNQ_RIL_urcClientInit();
+    LYNQ_RIL_RecSocket();
+    /*warren add for t800 ril service 2021/12/13 end*/
+    RLOGD("error in event_loop_base errno:%d", errno);
+    // kill self to restart on error
+    kill(0, SIGKILL);
+
+    return NULL;
+}
+
+
+void *
+eventLoop_at(void *param) {
+    pthread_mutex_lock(&s_startupMutex);
+    s_started = 1;
+    pthread_cond_broadcast(&s_startupCond);
+    pthread_mutex_unlock(&s_startupMutex);
+    //RIL_StartRevSocket();
+    startUsbLoop();
+    //startUsbLoop_test();
+    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:
+        if(pRI) {
+            free(pRI);
+            pRI = NULL;
+        }
+        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)
+{
+    if(t == NULL) {
+        RLOGE("ATCIRequest t is null");
+        return;
+    }
+    RequestInfo *pRI = (RequestInfo *)t;
+    int waittoken;
+    if (request < RIL_REQUEST_VENDOR_BASE) {
+        pRI->pCI = &(s_commands[request]);
+    } else {
+        pRI->pCI = find_mtk_command(request);
+    }
+    /*lei modify for Some requests that are not in the ril_commands.h and mtk_ril_commands.h but in commands.h*/
+    COMMAND *command = find_command(reqString);
+    if(pRI->pCI == NULL){
+        if(command == NULL)
+        {
+            RLOGE("pCI command & command not found!");
+            if(pRI) {
+                free(pRI);
+            }
+            return;
+        }
+    }
+    /*lei modify for Some requests that are not in the ril_commands.h and mtk_ril_commands.h but in commands.h*/
+
+    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;
+
+    
+    RLOGD("function %s line %d reqString %s", __FUNCTION__, __LINE__, reqString);
+    if(command == NULL) {
+        RLOGE("ATCI request command find error!");
+        if(pRI) {
+            free(pRI);
+        }
+        return;
+    } 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);
+}
+/*Warren add for  FAW 2021/09/23 start
+** use ttyGS0 port
+*/
+int lynqSendToRil(int argc,char *argv[],int uToken)
+{
+    if(argc < 1)
+    {
+        RLOGE("lynqSendToRil error input.");
+        return 1;
+    }
+    for(int i =0;i<argc;i++)
+    {
+        printf("argv[%d]=%s\n",i,argv[i]);
+    }
+    COMMAND *command = find_command(argv[0]);
+    if(!command)
+    {
+        RLOGE("%s: No such command for DemoApp", argv[0]);
+        return 1;
+    }
+
+    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);
+        return 1;
+    }
+
+    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
+        return 1;
+    }
+
+    RLOGD("REQUEST: %s ParamterNum:%d", requestToString(request), argc);
+
+
+    RequestInfo *pRI  = creatRILInfoAndInit(request, UDP, (RIL_SOCKET_ID)(id));
+    pRI->lynqEvent = 1;
+    //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));
+    return 0;
+}
+
+int sendRespToUsb(char *cmd)
+{
+    return 0;
+}
+int sendUrcToUsb(char *cmd)
+{
+    return 0;
+}
+/*Warren add for  FAW 2021/09/23 end*/
+
+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()");
+    lynq_init_sms_manager();
+    /* 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);
+    }
+    //warren delete,beacuse of update at fwk.
+    /*mobiletek add*
+    s_started = 0;
+    result = pthread_create(&s_tid_dispatch, &attr, eventLoop_at, 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);
+    }
+    *mobiletek add*/ 
+    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
+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 = -1;
+    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;
+    serial = 0;
+    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 = -1;
+    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, digitLimit);
+#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 = -1;
+    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 = -1;
+    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 = -1;
+    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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ril_commands.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ril_commands.h
new file mode 100755
index 0000000..85878ee
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ril_unsol_commands.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ril_unsol_commands.h
new file mode 100755
index 0000000..debe4a7
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/rndis/lynq_rndis.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/rndis/lynq_rndis.cpp
new file mode 100755
index 0000000..c7849c7
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/rndis/lynq_rndis.cpp
@@ -0,0 +1,156 @@
+/*============================================================================= 

+**     FileName: lynq_send_log_data

+**     Desc: send log data

+**     Author: victor

+**     Version: V1.0

+**     LastChange: 2021-12-23

+**     History: 

+=============================================================================*/

+

+#include "common.h"

+#include <stdio.h>

+#include <string.h>

+#include <stdlib.h>

+#include <malloc.h>

+#include<unistd.h>

+

+#include <pthread.h>

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+#include <log/log.h>

+#include "lynq_rndis.h"

+

+#define LYNQ_RNDIS_MALLOC_LEN 64

+

+void lynq_rndis_response_ttyGS3(char *log_buf)

+{

+//    sprintf(log_buf,"LYNQ_GOTO_LOGS_REQ\n");

+    write(ttyGS3_fd,log_buf,strlen(log_buf));

+    return ;

+}

+

+int lynqParseRndisCommand(const char* cmd,char **argv)

+{

+    char test[1024];

+    char *token;

+    char *str = test;

+    char *string;

+    char *lynq_str_buf;

+    char *parameter;

+    int cnt = 0;

+    memcpy(test, cmd, strlen(cmd));  

+    if(strstr(cmd,"="))

+    {

+        token = strtok(str, "=");

+        lynq_str_buf = strstr(token, "+");

+    cnt++;

+    if((strlen(lynq_str_buf)) <LYNQ_RNDIS_MALLOC_LEN)

+        {

+             bzero(argv[0], LYNQ_RNDIS_MALLOC_LEN);

+             memcpy(argv[0],lynq_str_buf,strlen(lynq_str_buf));

+        }   

+    

+        while (token != NULL)

+        {

+            string = token;

+            token = strtok(NULL, "=");

+        }

+        parameter = strtok(string, ",");

+        int i = 1;

+        while (parameter != NULL)

+        {

+         if(((strlen(parameter)) <LYNQ_RNDIS_MALLOC_LEN) && (cnt < MAX_RNDIS_NUM))

+             {

+                 cnt++;

+                     bzero(argv[i], LYNQ_RNDIS_MALLOC_LEN);

+                 memcpy(argv[i++],parameter,strlen(parameter));

+         }

+            parameter = strtok(NULL, ",");

+        }

+    }

+    if(cnt > MAX_RNDIS_NUM)

+        return -1;

+    return cnt;

+}

+

+

+int lynq_deal_with_rndis(int cmd_num,char **lynq_rndis_arr)

+{

+    FILE *fp;

+    char lynq_rndis_dev[LYNQ_RNDIS_MALLOC_LEN+32] = {0};

+    char lynq_rndis_buf[1024];

+    char lynq_rndis_log_buf[256];

+    int m = 1;

+    if(0 == strcmp(lynq_rndis_arr[0], "+LRNDISHANDLE"))

+    {

+//            lynq_rndis_response_ttyGS3("##############\n");

+        for(m = 1; m < cmd_num; m++)

+        {

+/*                bzero(lynq_rndis_log_buf, 256);

+            sprintf(lynq_rndis_log_buf,"cmd_num:%d,m=%d:%s\n",cmd_num,m,lynq_rndis_arr[m]);

+            lynq_rndis_response_ttyGS3(lynq_rndis_log_buf);

+*/        

+            bzero(lynq_rndis_buf, 1024);

+

+            bzero(lynq_rndis_dev, (LYNQ_RNDIS_MALLOC_LEN+32));

+            sprintf(lynq_rndis_dev,"%s  2>&1",lynq_rndis_arr[m]);

+            fp=popen(lynq_rndis_dev, "r");

+            usleep(500);

+//                sleep(2);

+            fgets(lynq_rndis_buf,sizeof(lynq_rndis_buf),fp);

+            pclose(fp);

+            if(strlen(lynq_rndis_buf) > 0)

+            {

+                lynq_rndis_response_ttyGS3(lynq_rndis_buf);

+                lynq_rndis_response_ttyGS3("\n");

+            }

+        }

+

+    }

+    return 1;

+}

+

+int lynq_open_rndis(int cmd_num,char **lynq_argv)

+{

+    for(int j = 0;j<cmd_num;j++)

+        {

+            lynq_rndis_response_ttyGS3(lynq_argv[j]);

+        lynq_rndis_response_ttyGS3("\n");

+        }

+    return 1;

+}

+

+int lynq_get_rndis_data(char *rndis_data)

+{

+    int lynq_argc_num = 0;

+    char *lynq_str_argv[MAX_RNDIS_NUM];

+

+for(int i = 0;i < MAX_RNDIS_NUM; i++)

+{

+    lynq_str_argv[i] = (char*)calloc(1,LYNQ_RNDIS_MALLOC_LEN); 

+    if(lynq_str_argv[i] == NULL)

+    {

+        return -1;

+    }    

+}

+

+    lynq_argc_num = lynqParseRndisCommand(rndis_data,lynq_str_argv);

+//    lynq_open_rndis(lynq_argc_num,lynq_str_argv);

+    lynq_deal_with_rndis(lynq_argc_num,lynq_str_argv);

+for(int mm= 0;mm < MAX_RNDIS_NUM; mm++)

+{

+    if(lynq_str_argv[mm] != NULL)

+    {

+        free(lynq_str_argv[mm]);

+        lynq_str_argv[mm] = NULL;

+    }    

+}

+    return 1;

+}

+

+#ifdef __cplusplus

+}

+#endif

diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/rndis/lynq_rndis.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/rndis/lynq_rndis.h
new file mode 100755
index 0000000..a6d9009
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/rndis/lynq_rndis.h
@@ -0,0 +1,16 @@
+#ifndef __LYNQ_RNDIS_H__

+#define __LYNQ_RNDIS_H__

+#ifdef __cplusplus
+extern "C" {
+#endif

+

+#define MAX_RNDIS_NUM 10

+

+int lynq_open_rndis(int cmd_num,char **lynq_argv);

+int lynq_get_rndis_data(char *rndis_data);

+

+#ifdef __cplusplus
+}
+#endif
+

+#endif //__LYNQ_LOGSEND_TEST_H__

diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sim.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sim.cpp
new file mode 100755
index 0000000..f1bba40
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sim.cpp
@@ -0,0 +1,488 @@
+/* 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"
+
+int g_switch_card_error = 0;
+
+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");
+        //lei modify: elt port is no longer used
+        //lynq_output_info("\nCME ERROR:2\n");
+        g_switch_card_error = 2;
+        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");
+        //lei modify: elt port is no longer used
+        //lynq_output_info("\nOK\n");
+        g_switch_card_error = 0;
+        free(pRI);
+    } else {
+        RLOGD("Set default all fail, SIM card absent");
+        android::emResultNotify("Set default all fail, SIM card absent.\n");
+        //lei modify: elt port is no longer used
+        //lynq_output_info("\nCME ERROR:11\n");
+        g_switch_card_error = 11;
+        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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sim.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sim.h
new file mode 100755
index 0000000..54d2564
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sim.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 YOCTO_SIM_H
+#define YOCTO_SIM_H 1
+
+#include <vendor-ril/telephony/ril.h>
+#include  "common.h"
+
+extern int g_switch_card_error;
+
+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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/BearerData.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/BearerData.cpp
new file mode 100755
index 0000000..27dbe9b
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/BearerData.cpp
@@ -0,0 +1,1625 @@
+//SPDX-License-Identifier: MediaTekProprietary
+/*
+ * 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)) >= 95 ? 0 : (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)) >= 95 ? 0 : (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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/BearerData.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/BearerData.h
new file mode 100755
index 0000000..23502f3
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/BitwiseInputStream.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/BitwiseInputStream.cpp
new file mode 100755
index 0000000..9e8d626
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/BitwiseInputStream.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/BitwiseInputStream.h
new file mode 100755
index 0000000..b436540
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/BitwiseOutputStream.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/BitwiseOutputStream.cpp
new file mode 100755
index 0000000..5d12dee
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/BitwiseOutputStream.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/BitwiseOutputStream.h
new file mode 100755
index 0000000..b30910a
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/CdmaSmsAddress.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/CdmaSmsAddress.cpp
new file mode 100755
index 0000000..67eeb86
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/CdmaSmsAddress.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/CdmaSmsAddress.h
new file mode 100755
index 0000000..8e1c2c2
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/CdmaSmsCbProgramData.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/CdmaSmsCbProgramData.cpp
new file mode 100755
index 0000000..fa1936c
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/CdmaSmsCbProgramData.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/CdmaSmsCbProgramData.h
new file mode 100755
index 0000000..22dfb14
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/CdmaSmsSubaddress.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/CdmaSmsSubaddress.cpp
new file mode 100755
index 0000000..9b4bb94
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/CdmaSmsSubaddress.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/CdmaSmsSubaddress.h
new file mode 100755
index 0000000..a21d29c
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/GsmAlphabet.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/GsmAlphabet.cpp
new file mode 100755
index 0000000..948fec6
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/GsmAlphabet.cpp
@@ -0,0 +1,673 @@
+//SPDX-License-Identifier: MediaTekProprietary
+/*
+ * 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 = 0;
+        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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/GsmAlphabet.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/GsmAlphabet.h
new file mode 100755
index 0000000..bbb9bb8
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/HexDump.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/HexDump.cpp
new file mode 100755
index 0000000..8dc01cf
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/HexDump.cpp
@@ -0,0 +1,219 @@
+//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 <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] = {0};
+  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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/HexDump.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/HexDump.h
new file mode 100755
index 0000000..d9676d9
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/IccUtils.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/IccUtils.cpp
new file mode 100755
index 0000000..75386ca
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/IccUtils.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/IccUtils.h
new file mode 100755
index 0000000..b94e12d
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/SmsAddress.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/SmsAddress.cpp
new file mode 100755
index 0000000..a6e690b
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/SmsAddress.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/SmsAddress.h
new file mode 100755
index 0000000..6d9cfd9
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/SmsCbCmasInfo.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/SmsCbCmasInfo.cpp
new file mode 100755
index 0000000..834d2d6
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/SmsCbCmasInfo.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/SmsCbCmasInfo.h
new file mode 100755
index 0000000..9711619
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/SmsConstants.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/SmsConstants.cpp
new file mode 100755
index 0000000..dcd0d4c
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/SmsConstants.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/SmsConstants.h
new file mode 100755
index 0000000..740e33f
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/SmsEnvelope.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/SmsEnvelope.cpp
new file mode 100755
index 0000000..f229b0c
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/SmsEnvelope.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/SmsEnvelope.h
new file mode 100755
index 0000000..e3c0f02
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/SmsHeader.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/SmsHeader.cpp
new file mode 100755
index 0000000..4c38581
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/SmsHeader.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/SmsHeader.h
new file mode 100755
index 0000000..cd1369c
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/SmsMessage.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/SmsMessage.cpp
new file mode 100755
index 0000000..771e861
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/SmsMessage.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/SmsMessage.h
new file mode 100755
index 0000000..f003146
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/SmsMessageBase.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/SmsMessageBase.cpp
new file mode 100755
index 0000000..14a173a
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/SmsMessageBase.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/SmsMessageBase.h
new file mode 100755
index 0000000..445e2f6
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/SmsMessageConverter.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/SmsMessageConverter.cpp
new file mode 100755
index 0000000..fdc7b8b
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/SmsMessageConverter.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/SmsMessageConverter.h
new file mode 100755
index 0000000..cf70a9a
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/UserData.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/UserData.cpp
new file mode 100755
index 0000000..6bf4ef4
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/UserData.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/UserData.h
new file mode 100755
index 0000000..0712e55
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/ril_cdma_sms.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/ril_cdma_sms.h
new file mode 100755
index 0000000..a147d21
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/sms_pdu_cdma.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/sms_pdu_cdma.cpp
new file mode 100755
index 0000000..5d9325c
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/sms_pdu_cdma.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/cdma/sms_pdu_cdma.h
new file mode 100755
index 0000000..d56939e
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/gsm/sms_pdu.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/gsm/sms_pdu.cpp
new file mode 100755
index 0000000..4cb12d9
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/gsm/sms_pdu.cpp
@@ -0,0 +1,2330 @@
+//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 <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 *curr_pack,
+                            kal_int32 *total_pack)
+{
+
+
+    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;
+                }
+                /*lei modify for gsw 2022/5/12*/
+                sms->total_pack = internal_mdapi_hex2int(ptr);
+                RLOGD("sms->total_pack = [%d]", sms->curr_pack);
+                *total_pack = sms->total_pack;
+                sms->curr_pack  = internal_mdapi_hex2int(ptr+2);
+                RLOGD("sms->curr_pack = [%d]", sms->curr_pack);
+                *curr_pack = sms->curr_pack;
+                /*lei modify for gsw 2022/5/12*/
+                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, int *curr_pack, int *total_pack)
+{
+    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;
+    /*lei modify for gsw 2022/5/11*/
+    status = _mdapi_sms_decode_pdu(&record, smsc, (kal_int8 *)pdu_str,
+                            pdu_len, &out_len, curr_pack, total_pack);
+    /*lei modify for gsw 2022/5/11*/
+    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;
+        #if 0
+        /*lei modify for gsw 2022/5/11*/
+        *curr_pack = record.curr_pack;
+        *total_pack = record.total_pack;
+        /*lei modify for gsw 2022/5/11*/
+        #endif
+    } 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);
+    return 0;
+}
+
+#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[3]={0};
+    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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/gsm/sms_pdu.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/gsm/sms_pdu.h
new file mode 100755
index 0000000..438663a
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/gsm/sms_pdu.h
@@ -0,0 +1,471 @@
+/* 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);
+/*lei modify for gsw 2022/5/11*/
+int smsPduDecode(const char *pdu_str, kal_int32 pdu_len,
+                        char *da_num, char *smsc, char *msg, int *charset, int *curr_pack, int *total_pack);
+/*lei modify for gsw 2022/5/11*/
+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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/lynqSmsManager/lynq_sms_manager.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/lynqSmsManager/lynq_sms_manager.cpp
new file mode 100755
index 0000000..95b5d13
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/lynqSmsManager/lynq_sms_manager.cpp
@@ -0,0 +1,543 @@
+#include <pthread.h>

+#include "lynq_sms_manager.h"

+#include <liblog/lynq_deflog.h>

+#include <sqlite3.h>

+#include <log/log.h>

+#include <stdlib.h>

+#include <string.h>

+#include "common.h"

+sms_manager * g_smsManagement;

+int sms_indexs[LYNQ_MAX_SMS_LIST]={0};

+int next_index = 0;

+

+sms_manager::sms_manager()

+{

+    set_sms_total(0);

+    return;

+}

+sms_manager:: ~ sms_manager(){}

+int lynq_sms_callback(void *data, int argc, char **argv, char **azColName){

+    int i;

+    if(next_index < LYNQ_MAX_SMS_LIST)

+    {

+        sms_indexs[next_index++] = atoi(argv[0]);

+    }

+    LYVERBLOG("next_index=%d",next_index);

+    for(i=0; i<argc; i++){

+       LYDBGLOG("%s = %s", azColName[i], argv[i] ? argv[i] : "NULL");

+    }

+    return 0;

+}

+

+/**

+ * @brief Check whether the ID exists in the database

+ * 

+ * @param index 

+ * @return int 

+ * find:turn 1 

+ * not find:turn 0

+ */

+int sms_manager::lynq_check_index(int index)

+{

+    memset(sms_indexs,0,LYNQ_MAX_SMS_LIST);

+    next_index = 0;

+    char *zErrMsg = 0;

+    int rc;

+    char sql[128]={0};

+    /* Open database */

+    rc = sqlite3_open(SMS_DB_PATH, &smsDb);

+    if( rc )

+    {

+        LYVERBLOG("[%s] Can't open database: %s\n", __FUNCTION__,sqlite3_errmsg(smsDb));

+        return LYNQ_E_SMS_DB_FAIL;

+    }

+    sprintf(sql,"%s", "SELECT * from LYNQSMS");

+    rc = sqlite3_exec(smsDb, sql, lynq_sms_callback, NULL, &zErrMsg);

+    if( rc != SQLITE_OK )

+    {

+        LYVERBLOG("SQL error: %s\n", zErrMsg);

+        sqlite3_free(zErrMsg);

+        sqlite3_close(smsDb);

+        return LYNQ_E_SMS_SQL_FAIL;

+    }

+    for(int cnt = 0; cnt < next_index;cnt++)

+    {

+        if(index == sms_indexs[cnt])

+        {

+            return 1;

+        }

+    }

+    return 0;

+}

+

+int read_sms_from_memory_cb(void *data, int argc, char **argv, char **azColName)

+{

+    if(data==NULL)

+    {

+        return 1;

+    }

+    sms_indexs[next_index] = atoi(argv[0]);

+    next_index++;

+    LYVERBLOG("next_index=%d",next_index);

+    lynq_sms_t* temp = (lynq_sms_t *)data;

+    for(int i=0; i<argc; i++){

+       LYVERBLOG("[%s]%s = %s", __FUNCTION__,azColName[i], argv[i] ? argv[i] : "NULL");

+    }

+    temp->index = atoi(argv[0]);

+    temp->slot_id = atoi(argv[1]);

+    temp->lynq_sms_status=(lynq_sms_status_t)atoi(argv[2]);

+    memcpy(temp->address,argv[3],LYNQ_TELEPHONE_NUM_LEN);

+    temp->addrLen = strlen(argv[3]);

+    memcpy(temp->smsc,argv[4],LYNQ_SMS_MAX_SCA_NUMBER_LEN);

+    temp->smscLen = strlen(argv[4]);

+    temp->charset = atoi(argv[5]);

+    memcpy(temp->pdu,argv[6],LYNQ_SMS_MAX_PDU_NUMBER_LEN);

+    temp->pduLen = strlen(argv[6]);

+    memcpy(temp->sms_text,argv[7],LYNQ_SMS_MAX_TEXT_NUMBER_LEN);

+    temp->sms_text_len = strlen(argv[7]);

+    /*lei add for gsw 2022/5/12*/

+    temp->current = atoi(argv[8]);

+    RLOGD("temp->current = %d", temp->current);

+    temp->total = atoi(argv[9]);

+    RLOGD("temp->total = %d", temp->total);

+    /*lei add for gsw 2022/5/12*/

+    return 0;

+}

+

+/*

+int list_sms_from_memory_cb(void *data, int argc, char **argv, char **azColName)

+{

+    if(data==NULL)

+    {

+        return 1;

+    }

+    lynq_sms_list_t* temp = (lynq_sms_list_t *)data;

+    for(int i=0; i<argc; i++){

+       LYVERBLOG("[%s]%s = %s", __FUNCTION__,azColName[i], argv[i] ? argv[i] : "NULL");

+    }

+}

+*/

+int callback(void *NotUsed, int argc, char **argv, char **azColName){

+   int i;

+   for(i=0; i<argc; i++){

+      LYVERBLOG("[%s]%s = %s", __FUNCTION__,azColName[i], argv[i] ? argv[i] : "NULL");

+   }

+   return 0;

+}

+

+int sms_manager::find_unuse_sms_index(char *path)

+{

+    char *zErrMsg = 0;

+    int rc;

+    int count =1;

+    bool sms_usable = false;

+    char *sql;

+    //const char* data = "Callback function called";

+    //int indexs[LYNQ_MAX_SMS_LIST]={0};

+    memset(sms_indexs,0,LYNQ_MAX_SMS_LIST);

+    next_index = 0;

+    LYVERBLOG("index = %p",sms_indexs);

+    /* Open database */

+    rc = sqlite3_open(SMS_DB_PATH, &smsDb);

+    if( rc )

+    {

+       LYERRLOG("Can't open database: %s\n", sqlite3_errmsg(smsDb));

+       return -1;

+    }

+    else

+    {

+       LYDBGLOG("Opened database successfully\n");

+    }

+

+    /* Create SQL statement */

+    sql = "SELECT ID from LYNQSMS";

+    /* Execute SQL statement */

+    //int* temp_index = indexs;

+    rc = sqlite3_exec(smsDb, sql, lynq_sms_callback,NULL, &zErrMsg);

+    if( rc != SQLITE_OK )

+    {

+        LYERRLOG("SQL error: %s\n", zErrMsg);

+        sqlite3_free(zErrMsg);

+        return -1;

+    }

+    else

+    {

+       LYDBGLOG("Operation done successfully\n");

+    }

+    //indexs = temp_index;

+    LYVERBLOG("index = %p",sms_indexs);

+    for(count;count<=LYNQ_MAX_SMS_LIST;count++)

+    {

+        if(sms_indexs[count-1]!=count)

+        {

+            sms_usable=true;

+            break;

+        }

+    }

+    if((!sms_usable)&&(count==LYNQ_MAX_SMS_LIST))

+    {

+       set_sms_full(true);

+    }

+    sqlite3_close(smsDb);

+    return count;

+}

+int sms_manager::lynq_write_sms_to_memory(const char* data,const char *num,const char *smsc,const char *msg,const int charset,const int slot_id,int current,int total)

+{

+    int id = find_unuse_sms_index(SMS_DB_PATH);

+    RLOGD("[%s] id = %d\n",__FUNCTION__,id);

+    //lynq_sms_list_t * sms_list = (lynq_sms_list_t * )malloc(sizeof(lynq_sms_list_t *));

+    if(!get_sms_full())

+    {

+        RLOGD("[%s] sms full is false\n",__FUNCTION__);

+        lynq_write_sms_to_sms_db(id, slot_id,0,smsc, charset,data,msg,SMS_DB_PATH,num,current,total);

+        return id;//sms story index

+    }

+    LYERRLOG("sms storage space is full!!!");

+    return -1;

+}

+int sms_manager::lynq_delete_sms_from_memory(const int index)

+{

+    char *zErrMsg = 0;

+    int rc;

+    char sql[128]={0};

+    /* Open database */

+    rc = sqlite3_open(SMS_DB_PATH, &smsDb);

+    if(index == -1)

+    {

+        sprintf(sql,"DELETE  from LYNQSMS");

+        if( rc )

+        {

+            LYVERBLOG("[%s] Can't open database: %s\n", __FUNCTION__,sqlite3_errmsg(smsDb));

+            return LYNQ_E_SMS_DB_FAIL;

+        }

+        LYVERBLOG("[%s] Opened database successfully\n",__FUNCTION__);

+        rc = sqlite3_exec(smsDb, sql, NULL, NULL, &zErrMsg);

+        if( rc != SQLITE_OK )

+        {

+            LYVERBLOG("SQL error: %s\n", zErrMsg);

+            sqlite3_free(zErrMsg);

+            sqlite3_close(smsDb);

+            return LYNQ_E_SMS_SQL_FAIL;

+        }

+        LYVERBLOG("delete sms %d successfully\n",index);

+        sqlite3_close(smsDb);

+        return 0;

+    }

+    else

+    {

+        /*lei add*/

+        if(!lynq_check_index(index))

+        {

+            return LYNQ_E_SMS_SQL_FAIL;

+        }

+        /*lei add*/

+        if( rc )

+        {

+            LYVERBLOG("[%s] Can't open database: %s\n", __FUNCTION__,sqlite3_errmsg(smsDb));

+            return LYNQ_E_SMS_DB_FAIL;

+        }

+        LYVERBLOG("[%s] Opened database successfully\n",__FUNCTION__);

+        /* Create SQL statement */

+        //sql = "SELECT * from LYNQSMS";

+        sprintf(sql,"DELETE  from LYNQSMS WHERE ID=%d",index);

+        /* Execute SQL statement */

+        rc = sqlite3_exec(smsDb, sql, NULL, NULL, &zErrMsg);

+        if( rc != SQLITE_OK )

+        {

+            LYVERBLOG("SQL error: %s\n", zErrMsg);

+            sqlite3_free(zErrMsg);

+            sqlite3_close(smsDb);

+            return LYNQ_E_SMS_SQL_FAIL;

+        }

+        LYVERBLOG("delete sms %d successfully\n",index);

+        sqlite3_close(smsDb);

+        return 0;

+    }

+}

+int sms_manager::lynq_read_sms_from_memory(const int index, lynq_sms_t *sms)

+{

+    /*lei add*/

+    if(!lynq_check_index(index))

+    {

+        return LYNQ_E_SMS_SQL_FAIL;

+    }

+    /*lei add*/

+    char *zErrMsg = 0;

+    int rc;

+    char sql[128]={0};

+    /* Open database */

+    rc = sqlite3_open(SMS_DB_PATH, &smsDb);

+    if( rc )

+    {

+        LYVERBLOG("[%s] Can't open database: %s\n", __FUNCTION__,sqlite3_errmsg(smsDb));

+        return LYNQ_E_SMS_DB_FAIL;

+    }

+    LYVERBLOG("[%s] Opened database successfully\n",__FUNCTION__);

+    /* Create SQL statement */

+    //sql = "SELECT * from LYNQSMS";

+    sprintf(sql,"SELECT * from LYNQSMS WHERE ID=%d",index);

+   /* Execute SQL statement */

+    rc = sqlite3_exec(smsDb, sql, read_sms_from_memory_cb, (void *)sms, &zErrMsg);

+    if( rc != SQLITE_OK )

+    {

+        LYVERBLOG("SQL error: %s\n", zErrMsg);

+        sqlite3_free(zErrMsg);

+        sqlite3_close(smsDb);

+        return LYNQ_E_SMS_SQL_FAIL;

+    }

+    memset(sql,0,128);

+    sprintf(sql,"UPDATE LYNQSMS set STATUS = 1 WHERE ID=%d",index);

+    rc = sqlite3_exec(smsDb, sql, NULL,NULL, &zErrMsg);

+    if( rc != SQLITE_OK )

+    {

+        LYVERBLOG("update SQL error: %s\n", zErrMsg);

+        sqlite3_free(zErrMsg);

+        sqlite3_close(smsDb);

+        return LYNQ_E_SMS_SQL_FAIL;

+    }

+    LYVERBLOG("read sms %d successfully\n",index);

+    sqlite3_close(smsDb);

+    return 0;

+}

+int sms_manager::lynq_list_sms_from_memory(const int status,lynq_sms_list_t * sms_list)

+{

+    if(sms_list==NULL)

+    {

+        return 1;

+    }

+    char *zErrMsg = 0;

+    int rc;

+    char sql[128]={0};

+    memset(sms_indexs,0,LYNQ_MAX_SMS_LIST);

+    next_index = 0;

+    /* Open database */

+    rc = sqlite3_open(SMS_DB_PATH, &smsDb);

+    if( rc )

+    {

+        LYVERBLOG("[%s] Can't open database: %s\n", __FUNCTION__,sqlite3_errmsg(smsDb));

+        return LYNQ_E_SMS_DB_FAIL;

+    }

+    LYVERBLOG("[%s] Opened database successfully\n",__FUNCTION__);

+    /* Create SQL statement */

+    //sql = "SELECT * from LYNQSMS";

+    if(status==0)

+    {

+        sprintf(sql,"SELECT ID from LYNQSMS");

+    }

+    else

+    {

+        sprintf(sql,"SELECT ID from LYNQSMS WHERE STATUS=%d",status);

+    }

+   /* Execute SQL statement */

+    rc = sqlite3_exec(smsDb, sql, lynq_sms_callback,NULL, &zErrMsg);

+    if( rc != SQLITE_OK )

+    {

+        LYVERBLOG("SQL error: %s\n", zErrMsg);

+        sqlite3_free(zErrMsg);

+        sqlite3_close(smsDb);

+        return LYNQ_E_SMS_SQL_FAIL;

+    }

+    for(int i=0;i<next_index;i++)

+    {

+        sms_list->index[sms_indexs[i]-1]=sms_indexs[i];

+        LYVERBLOG("test index =%d\n", sms_list->index[i]);

+        RLOGD("test index =%d   sms_indexs %d i %d\n", sms_list->index[sms_indexs[i]-1], sms_indexs[i], i);

+    }

+    sms_list->num_of_indexs = next_index;

+    LYVERBLOG("list sms successfully");

+    sqlite3_close(smsDb);

+    return 0;

+}

+int has_sms_db_created(char *path,sqlite3* smsDb_l)

+{

+    if (path == NULL || strlen(path) == 0)

+    {

+        LYVERBLOG("initSmsDb error with null path!");

+        return SMS_DB_ERR;

+    }

+    int rc = sqlite3_open_v2(path, &smsDb_l, SQLITE_OPEN_READWRITE,NULL);

+    if (rc == SQLITE_OK) 

+    {

+        LYVERBLOG("check init success!");

+        return SMS_DB_READED;

+    } 

+    else 

+    {

+        LYVERBLOG("db has not create %s!", sqlite3_errmsg(smsDb_l));

+        sqlite3_close_v2(smsDb_l);

+        return SMS_DB_ERR;

+    }

+}

+int sms_manager::create_sms_db(char *path)

+{

+    if (path == NULL || strlen(path) == 0) {

+        LYVERBLOG("initSmsDb error with null path!");

+        return SMS_DB_ERR;

+    }

+    if(SMS_DB_READED==has_sms_db_created(path,smsDb))

+    {

+        return SMS_DB_READED;

+    }

+    int rc = sqlite3_open(path, &smsDb);

+    if (rc != SQLITE_OK) {

+        LYVERBLOG("initDb failed %s", sqlite3_errcode(smsDb));

+        return SMS_DB_ERR;

+    } else {

+        LYVERBLOG("create db in %s", path);

+    }

+    sqlite3_close(smsDb);

+    return SMS_DB_CREATE;

+}

+int sms_manager::create_sms_table(char*path)

+{

+    char *zErrMsg = 0;

+    int rc;

+    char *sql;

+

+    /* Open database */

+    rc = sqlite3_open(path, &smsDb);

+    if( rc )

+    {

+        LYVERBLOG("[%s] Can't open database: %s\n", __FUNCTION__,sqlite3_errmsg(smsDb));

+        return 1;

+    }

+    LYVERBLOG("[%s] Opened database successfully\n",__FUNCTION__);

+    /* Create SQL statement */

+    /*lei modify for gsw 2022/5/11*/

+    sql = "CREATE TABLE LYNQSMS( \

+         ID                       INT PRIMARY KEY      NOT NULL, \

+         SLOT                 INT                                 NOT NULL, \

+         STATUS            INT                                 NOT NULL, \

+         ADDRESS         NONE                                 NOT NULL, \

+         SMSC                NONE                             NOT NULL,\

+         CHARSET         INT                                 NOT NULL, \

+         PDU                   NONE                             NOT NULL, \

+         CONTENT         TEXT                             NOT NULL, \

+         CURRENT         INT                             NOT NULL, \

+         TOTAL         INT                             NOT NULL)";

+   /* Execute SQL statement */

+   /*lei modify for gsw 2022/5/11*/

+    rc = sqlite3_exec(smsDb, sql, NULL, 0, &zErrMsg);

+    if( rc != SQLITE_OK )

+    {

+        LYVERBLOG("SQL error: %s\n", zErrMsg);

+        sqlite3_free(zErrMsg);

+        sqlite3_close(smsDb);

+        return 1;

+    }

+    LYVERBLOG("Table LYNQSMS created successfully\n");

+    sqlite3_close(smsDb);

+    return 0;

+}

+int sms_manager::create_sms_number_table(char * path)

+{

+    char *zErrMsg = 0;

+    int rc;

+    char *sql;

+

+    /* Open database */

+    rc = sqlite3_open(path, &smsDb);

+    if( rc )

+    {

+        LYVERBLOG("[%s] Can't open database: %s", __FUNCTION__,sqlite3_errmsg(smsDb));

+        return 1;

+    }

+    LYVERBLOG("[%s] Opened database successfully",__FUNCTION__);

+    /* Create SQL statement */

+    sql = "CREATE TABLE LYNQ_SMS_TOTAL(" \

+         "ID                      INT PRIMARY KEY      NOT NULL," \

+         "TOTAL             INT                                 NOT NULL);";

+   /* Execute SQL statement */

+    rc = sqlite3_exec(smsDb, sql, callback, 0, &zErrMsg);

+    if( rc != SQLITE_OK )

+    {

+        LYVERBLOG("SQL error: %s", zErrMsg);

+        sqlite3_free(zErrMsg);

+        sqlite3_close(smsDb);

+        return 1;

+    }

+    LYDBGLOG("LYNQ_SMS_TOTAL table created successfully");

+    sqlite3_close(smsDb);

+    return 0;

+}

+/*lei modify for gsw 2022/5/11*/

+int sms_manager::lynq_write_sms_to_sms_db(int id,int slot_id,int status,const char *smsc,int charset,const char *pdu,const char *content,char *path,const char*address,int current,int total)

+{

+    char *zErrMsg = 0;

+    int rc;

+    //char sql[LYNQ_SMS_MAX_SCA_NUMBER_LEN+LYNQ_SMS_MAX_PDU_NUMBER_LEN+LYNQ_SMS_MAX_TEXT_NUMBER_LEN+3+1+100]={0};

+    /* Open database */

+    rc = sqlite3_open(path, &smsDb);

+    if( rc )

+    {

+        RLOGD("[%s] Can't open database: %s",__FUNCTION__,sqlite3_errmsg(smsDb));

+        LYERRLOG("[%s] Can't open database: %s",__FUNCTION__,sqlite3_errmsg(smsDb));

+        return 1;

+    }

+    LYDBGLOG("[%s] Opened database successfully",__FUNCTION__);

+    /* Create SQL statement */

+    //sprintf(sql,"INSERT INTO LYNQSMS (ID,SLOT,STATUS,ADDRESS,SMSC,CHARSET,PDU,CONTENT,CURRENT,TOTAL) VALUES (%d,%d,%d,'%s','%s',%d,'%s','%s',%d,%d);",id,slot_id,status,address,smsc,charset,pdu,content,current,total);

+    /* Execute SQL statement */

+    //printf("%s\n",sql);

+    char *sql = sqlite3_mprintf("INSERT INTO LYNQSMS VALUES('%d','%d','%d','%q','%q','%d','%q','%q','%d','%d')",id,slot_id,status,address,smsc,charset,pdu,content,current,total);

+    rc = sqlite3_exec(smsDb, sql, NULL,NULL, &zErrMsg);

+    if( rc != SQLITE_OK )

+    {

+        RLOGD("SQL error: %s", zErrMsg);

+        LYVERBLOG( "SQL error: %s", zErrMsg);

+        sqlite3_free(zErrMsg);

+        sqlite3_close(smsDb);

+        return 1;

+    }

+    LYDBGLOG("write sms to sms db successfully");

+    //printf("write sms to sms db successfully\n");

+    return 0;

+}

+/*lei modify for gsw 2022/5/11*/

+int sms_manager::initSmsManager()

+{

+    int db_ret=0;

+    int table_ret=0;

+    db_ret = create_sms_db(SMS_DB_PATH);

+    if(db_ret==SMS_DB_CREATE)

+    {

+        table_ret = create_sms_table(SMS_DB_PATH);

+        if(table_ret!=0)

+        {

+            LYERRLOG("create sms table fail!!!");

+            return 1;

+        }

+        table_ret = create_sms_number_table(SMS_DB_PATH);

+        if(table_ret!=0)

+        {

+            LYERRLOG("create sms number table fail!!!");

+            return 1;

+        }

+    }

+    else if(db_ret==SMS_DB_READED)

+    {

+        LYDBGLOG("[%s] sms db has be build!!!",__FUNCTION__);

+    }

+    else

+    {

+        LYDBGLOG("init sms db fail!!!");

+    }

+    set_sms_full(false);

+    //get_sms_total();

+    return 0;

+}

+

+int lynq_init_sms_manager()

+{

+    g_smsManagement = new sms_manager();

+    if(g_smsManagement==NULL)

+    {

+        RLOGE("init class sms manager fail!!!");

+        exit(EXIT_FAILURE);

+    }

+    RLOGD("init class sms manager success!!!");

+    g_smsManagement->initSmsManager();

+    return 0;

+}

+

+

diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/lynqSmsManager/lynq_sms_manager.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/lynqSmsManager/lynq_sms_manager.h
new file mode 100755
index 0000000..c62d562
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/lynqSmsManager/lynq_sms_manager.h
@@ -0,0 +1,119 @@
+/*============================================================================= 

+#     FileName: lynq_sms_manager.cpp

+#     Desc: about SMS API

+#     Author: Warren

+#     Version: V1.0

+#     LastChange: 2021-08-27 

+#     History: 

+=============================================================================*/

+#ifndef __LYNQ_SMS_MANAGER__

+#define __LYNQ_SMS_MANAGER__

+#include <sqlite3.h>

+#ifdef __cplusplus

+extern "C" {

+#endif

+#define LYNQ_MAX_SMS_LIST 255

+#define LYNQ_SMS_MAX_SCA_NUMBER_LEN   22

+#define LYNQ_SMS_MAX_PDU_NUMBER_LEN 2504

+#define LYNQ_SMS_MAX_TEXT_NUMBER_LEN 512

+#define LYNQ_TELEPHONE_NUM_LEN 64

+#define SMS_DB_PATH "/system/etc/tele/sms.db"

+#define SMS_DB_READED 0

+#define SMS_DB_ERR 1

+#define SMS_DB_CREATE 2

+

+typedef enum {

+    LYNQ_SMS_GSM=0,

+    LYNQ_SMS_CDMA

+}lynq_sms_technology_t;

+typedef enum{

+    LYNQ_SMS_ALL=0,

+    LYNQ_SMS_UREA,

+    LYNQ_SMS_READ,

+    LYNQ_SMS_UNSENT,

+    LYNQ_SMS_SENT

+}lynq_sms_status_t;

+

+typedef struct

+{

+    int index;//Maximum number of SMS that can be storaged.

+    int slot_id;

+    int charset;

+    char address[LYNQ_TELEPHONE_NUM_LEN];

+    int addrLen;

+    char smsc[LYNQ_SMS_MAX_SCA_NUMBER_LEN];

+    int smscLen;

+    char pdu[LYNQ_SMS_MAX_PDU_NUMBER_LEN];

+    int pduLen;

+    char sms_text[LYNQ_SMS_MAX_TEXT_NUMBER_LEN];

+    int sms_text_len;

+    lynq_sms_technology_t lynq_sms_technology;

+    lynq_sms_status_t lynq_sms_status;

+    /*lei add for gsw 2022/5/12*/

+    int current;

+    int total;

+    /*lei add for gsw 2022/5/12*/

+}lynq_sms_t;

+

+typedef struct{

+    int index[LYNQ_MAX_SMS_LIST];

+    int num_of_indexs;

+}lynq_sms_list_t;

+class sms_manager

+{

+    public:

+        sms_manager(void );

+        virtual ~ sms_manager();

+        int initSmsManager();

+        int lynq_write_sms_to_memory(const char* data,const char *num,const char *smsc,const char *msg,const int charset,const int slot_id,int current, int total);

+        int lynq_delete_sms_from_memory(const int index);

+        int lynq_read_sms_from_memory(const int index, lynq_sms_t *sms);

+        int lynq_list_sms_from_memory(const int status,lynq_sms_list_t * sms_list);

+        int get_sms_total()

+        {

+            return sms_total;

+        }

+        int set_sms_total(int smsTotal)

+        {

+            sms_total = smsTotal;

+            return 0;

+        }

+        bool get_sms_full()

+        {

+            return sms_full;

+        }

+        int set_sms_full(bool status)

+        {

+            sms_full = status;

+            return 0;

+        }

+        int get_sms_usable_id()

+        {

+            return sms_usable_id;

+        }

+        int set_sms_usable_id(int index)

+        {

+             sms_usable_id = index;

+             return 0;

+        }

+    private:

+        int create_sms_db(char *path);

+        int create_sms_table(char*path);

+        int create_sms_number_table(char * path);

+        int lynq_write_sms_to_sms_db(int id,int slot_id,int status,const char *smsc,int charset,const char *pdu,const char *content,char *path,const char*address,int current,int total);

+        int find_unuse_sms_index(char *path);

+        int lynq_check_index(int total);

+        int sms_total;

+        int sms_usable_id;

+        bool sms_full;

+        sqlite3* smsDb;

+};

+extern sms_manager *g_smsManagement;

+int lynq_init_sms_manager();

+#ifdef __cplusplus

+}

+#endif

+

+#endif

+

+

diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/sms.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/sms.cpp
new file mode 100755
index 0000000..e1e6919
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/sms.cpp
@@ -0,0 +1,1048 @@
+// 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 "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"
+/*Warren add for T800 platform 2021/11/19 start*/
+#include "lynq_common.h"
+#include "lynq_sms_manager.h"
+#include "lynq_interface.h"
+#include <cutils/jstring.h>//temp
+
+/*Warren add for T800 platform 2021/11/19 end*/
+
+
+#define GSM_PHONE 1
+
+#undef LOG_TAG
+#define LOG_TAG "DEMO_SMS"
+
+#define PROP_ECALL_NUM "vendor.gost.ecall.ecall_sms_fallback_number"
+
+extern sms_manager * g_smsManagement;
+
+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__);
+            return 0;
+        } 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));
+                if(pRI_backup != NULL) {
+                pRI_backup->token = pRI->token;
+                pRI_backup->pCI = pRI->pCI;
+                pRI_backup->socket_id = pRI->socket_id;
+                pRI_backup->p_next = pRI->p_next;
+                pRI_backup->uToken = pRI->uToken;
+                pRI_backup->lynqEvent = pRI->lynqEvent;
+                pRI_backup->uClient_addr.sin_family = pRI->uClient_addr.sin_family;
+                pRI_backup->uClient_addr.sin_addr.s_addr = pRI->uClient_addr.sin_addr.s_addr;
+                pRI_backup->uClient_addr.sin_port = pRI->uClient_addr.sin_port;
+                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__);
+            return 0;
+        } 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));
+                if(pRI_backup != NULL) {
+                    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);
+    }
+
+    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__);
+            return 0;
+        } 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));
+                if(pRI_backup != NULL) {
+                    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);
+    }
+
+    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__);
+            return 0;
+        } 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));
+                if(pRI_backup != NULL) {
+                    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);
+    }
+    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,android::Parcel &p){
+    char smsc[512] = {0};
+    char msg[512] = {0};
+    char num[512] = {0};
+    int charset = 0;
+    int index = -1;
+    /*lei modify for gsw 2022/5/11*/
+    /*Set the initial value to 1, because the short message, MTK did not process, 
+    so short message, also set the current message subscript and the total number of messages 
+    */
+    int curr_pack = 1;
+    int total_pack = 1;
+    /*lei modify for gsw 2022/5/11*/
+    RLOGD("slot: %d, len: %d, sms: %s",soc_id, datalen, data);
+    smsPduDecode(data, datalen, num, smsc, msg, &charset, &curr_pack, &total_pack);
+    RLOGD("SMS :%s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__);
+    RLOGD("[EVENT][MT_SMS][SIM%d]PDU decode:smsc: %s, phone number: %s , charset: %d, msg_len: %d, message content: %s curr_pack: %d total_pack: %d", soc_id, smsc, num, charset, strlen(msg), msg, curr_pack, total_pack);
+    if(isGostEcall() && (MDAPI_SMS_CHARSET_GSM_8BIT == charset))
+    {
+        gostParseSmsHandle(soc_id, num, msg);
+    }
+    /*Warren change for t800 ril service 2022/1/18 start
+    **By default, the SMS is stored in the memory after receiving it
+    */
+    /*lei modify for gsw 2022/5/11*/
+    index = g_smsManagement->lynq_write_sms_to_memory(data,(const char*)num,(const char*)smsc,(const char*)msg,charset,soc_id,curr_pack,total_pack);
+    /*lei modify for gsw 2022/5/11*/
+    p.writeInt32(index);//if index == -1 ,it means sms storage space is full.
+    /*Warren change for t800 ril service 2022/1/18 end*/
+    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%5) != 1) {
+        RLOGE("%s parameter error!",__func__);
+        free(pRI);
+        return -1;
+    }
+    int num = argc/5;
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    p.writeInt32(num);
+    RLOGD("%s write group num of input parameter to parcel: %d",__func__, num);
+    for (int i = 1; i < argc; i++) {
+        p.writeInt32(atoi(argv[i]));
+        RLOGD("%s write input parameter to parcel: [%d] %d",__func__, i, atoi(argv[i]));
+    }
+    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)
+{
+    //MTK add [start]
+    if (auto_save_sms_to_sim == false || strlen(msg) > MAX_PDU_SIZE)
+    {
+        RLOGE("%s:auto_save_sms_to_sim is false, msg len = %d, return directly", __FUNCTION__, strlen(msg));
+        return 0;
+    }
+    //MTK add [end]
+	
+    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));
+        if(pRI_backup == NULL) {
+            free(pRI);
+            return 0;
+        }
+        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;
+}
+/*Warren change for t800 ril service 2022/1/18 start*/
+int readSmsToMemory(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    int error = -1;
+    if(argc != 2)
+    {
+        RLOGE("%s parameter error!",__func__);
+        android::lynqAssemblyParcelheader(p,socket_id,pRI->uToken,LYNQ_REQUEST_READ_SMS_FROM_MEMORY,0,2);//RIL_E_GENERIC_FAILURE
+        android::LYNQ_RIL_respSocket(p,(void *)pRI);
+        free(pRI);
+        return -1;
+    }
+    lynq_sms_t smsInfo;
+    error = g_smsManagement->lynq_read_sms_from_memory(atoi(argv[1]),&smsInfo);
+    android::lynqAssemblyParcelheader(p,socket_id,pRI->uToken,LYNQ_REQUEST_READ_SMS_FROM_MEMORY,0,error);
+    RLOGD("addr=%s,smsc=%s,msg=%s\n",smsInfo.address,smsInfo.smsc,smsInfo.sms_text);
+    if(error==0)
+    {
+        p.writeInt32(smsInfo.index);
+        p.writeInt32(smsInfo.lynq_sms_status);
+        p.writeInt32(smsInfo.charset);
+        /*lei add for gsw 2022/5/12*/
+        p.writeInt32(smsInfo.current);
+        p.writeInt32(smsInfo.total);
+        /*lei add for gsw 2022/5/12*/
+        writeStringToParcel(p,smsInfo.address);
+        writeStringToParcel(p,smsInfo.smsc);
+        writeStringToParcel(p,smsInfo.sms_text);
+    }
+    android::LYNQ_RIL_respSocket(p,(void *)pRI);
+    free(pRI);
+    return 0;
+}
+int deleteSmsToMemory(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    int error = -1;
+    if(argc != 2)
+    {
+        RLOGE("%s parameter error!",__func__);
+        android::lynqAssemblyParcelheader(p,socket_id,pRI->uToken,LYNQ_REQUEST_DELETE_SMS_FROM_MEMORY,0,2);//RIL_E_GENERIC_FAILURE
+        android::LYNQ_RIL_respSocket(p,(void *)pRI);
+        free(pRI);
+        return -1;
+    }
+    error = g_smsManagement->lynq_delete_sms_from_memory(atoi(argv[1]));
+    android::lynqAssemblyParcelheader(p,socket_id,pRI->uToken,LYNQ_REQUEST_DELETE_SMS_FROM_MEMORY,0,error);
+    android::LYNQ_RIL_respSocket(p,(void *)pRI);
+    free(pRI);
+    return 0;
+}
+static char *strdupReadString(android::Parcel &p) {
+    size_t stringlen;
+    const char16_t *s16;
+
+    s16 = p.readString16Inplace(&stringlen);
+
+    return strndup16to8(s16, stringlen);
+}
+
+int listSmsToMemory(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    int error = -1;
+    char indexBuf[256]={0};
+    lynq_sms_list_t sms_list;
+    memset(&sms_list, 0, sizeof(lynq_sms_list_t));
+    if(argc<1)
+    {
+        RLOGE("%s parameter error!",__func__);
+        android::lynqAssemblyParcelheader(p,socket_id,pRI->uToken,LYNQ_REQUEST_LIST_SMS_FROM_MEMORY,0,2);//RIL_E_GENERIC_FAILURE
+        android::LYNQ_RIL_respSocket(p,(void *)pRI);
+        free(pRI);
+        return -1;
+    }
+    error = g_smsManagement->lynq_list_sms_from_memory(0,&sms_list);//list all
+    bzero(indexBuf,256);
+    for(int n=0;n<255;n++)
+    {
+        indexBuf[n] = '0';
+    }
+    indexBuf[255]='\0';
+    if(error==0)
+    {
+        int valid = 0;
+        for(int i = 0;valid < sms_list.num_of_indexs && i < 255;i++)
+        {
+            if(sms_list.index[i] != 0 && sms_list.index[i] < 255)
+            {
+                RLOGD("TEST %d i %d", sms_list.index[i], i);
+                indexBuf[i]='1';
+                valid++;
+            }
+        }
+        //writeStringToParcel(p,indexBuf);
+    }
+    //printf("indexbuf=%s\n",indexBuf);
+    android::lynqAssemblyParcelheader(p,socket_id,pRI->uToken,LYNQ_REQUEST_LIST_SMS_FROM_MEMORY,0,error);
+    writeStringToParcel(p,indexBuf);
+    android::LYNQ_RIL_respSocket(p,(void *)pRI);
+    free(pRI);
+    return 0;
+}
+
+/*Warren change for t800 ril service 2022/1/18 end*/
+
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/sms.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/sms.h
new file mode 100755
index 0000000..82f747b
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/sms/sms.h
@@ -0,0 +1,106 @@
+/* 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);
+/*Warren chenge for t800 ril service 2022/1/19 start*/
+int responseNewSMS(const char *data, size_t datalen, int soc_id,int32_t unsol,android::Parcel &p);
+/*Warren chenge for t800 ril service 2022/1/19 end*/
+
+//#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);
+/*Warren change for t800 ril service 2022/1/18 start*/
+int readSmsToMemory(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int deleteSmsToMemory(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int listSmsToMemory(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+/*Warren change for t800 ril service 2022/1/18 end*/
+
+
+#endif
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ss.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ss.cpp
new file mode 100755
index 0000000..3b726ad
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ss.cpp
@@ -0,0 +1,718 @@
+//SPDX-License-Identifier: MediaTekProprietary
+/*
+ * 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");
+        iconv_close(cd);
+        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");
+        iconv_close(cd);
+        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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ss.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ss.h
new file mode 100755
index 0000000..b21966e
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/stateManager/stateManager.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/stateManager/stateManager.cpp
new file mode 100755
index 0000000..d4f3ce3
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/stateManager/stateManager.cpp
@@ -0,0 +1,362 @@
+/* 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>
+#ifdef LED_SUPPORT
+#include "led.h"
+#endif
+#undef LOG_TAG
+#define LOG_TAG "DEMO_MANAGER"
+
+//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);
+
+    int screen_state= atoi(argv[1]);
+    p.writeInt32(screen_state);
+#ifdef LED_SUPPORT
+    mbtk_netled_state_update(screen_state==0 ? GPIO_NETLED_AP_GOINGSLEEP : GPIO_NETLED_AP_WAKEUP);	
+    usleep(wait_led_update_effective_timer_ms*1000);
+#endif
+
+    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;
+}
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/stateManager/stateManager.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/stateManager/stateManager.h
new file mode 100755
index 0000000..b96b5ec
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/stateManager/stateManager.h
@@ -0,0 +1,56 @@
+/* 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"
+
+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);
+#endif /*KEEP_ALIVE*/
+#endif
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/stk.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/stk.cpp
new file mode 100755
index 0000000..29643db
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/stk.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/stk.h
new file mode 100755
index 0000000..122f459
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/temp/lynq_at_temp.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/temp/lynq_at_temp.cpp
new file mode 100755
index 0000000..4a32035
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/temp/lynq_at_temp.cpp
@@ -0,0 +1,59 @@
+/*============================================================================= 

+**     FileName: lynq_at_temp

+**     Desc: lynq at temp

+**     Author: rita

+**     Version: V1.0

+**     LastChange: 2022-06-13

+**     History: 

+=============================================================================*/

+

+#include "common.h"

+#include <stdio.h>

+#include <string.h>

+#include <stdlib.h>

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+//#include <log/log.h>

+#include "liblynq-thermal/lynq_get_thermal.h"

+

+static void lynq_response_ttyGS3(char *log_buf)

+{

+//    sprintf(log_buf,"LYNQ_GOTO_LOGS_REQ\n");

+    write(ttyGS3_fd,log_buf,strlen(log_buf));

+    return;  

+}

+

+int lynq_at_get_temp(int argc, char *argv[])

+{

+    int temp = 0;

+    char buf[20] = "";

+

+

+    

+    if(NULL == argv[3] || argc<4){

+        lynq_response_ttyGS3("+CME ERROR: no such device,please reinput!!\n");

+        return -1;

+    }

+    

+    int ret = lynq_get_zone_tmp(ZONE_NUM(atoi(argv[3])), &temp);

+       

+    

+    if(ret!=0){

+        lynq_response_ttyGS3("+CME ERROR: no such device,please reinput!!\n");

+    }

+    else{

+       //lynq_response_ttyGS3("+temp:%d\n");

+       sprintf(buf,"+LYNQMTSM: %d\n", temp);

+       lynq_response_ttyGS3(buf);

+    }

+

+    return ret;

+}

+

+

+#ifdef __cplusplus

+}

+#endif

diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/temp/lynq_at_temp.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/temp/lynq_at_temp.h
new file mode 100755
index 0000000..d2c5b87
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/temp/lynq_at_temp.h
@@ -0,0 +1,36 @@
+#ifndef __LYNQ_AT_TEMP_H__

+#define __LYNQ_AT_TEMP_H__

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+typedef enum {

+    soc_max=0,

+    cpu0,

+    cpu1,

+    cpu2,

+    cpu3,

+    gpu0,

+    gpu1,

+    dramc,

+    mmsys,

+    md_5g,

+    md_4g,

+    md_3g,

+    soc_dram_ntc,

+    pa_5g,

+    pa_4g,

+    rf_ntc,

+    pmic,

+    pmic_vcore,

+    pmic_vpro,

+    pmic_vgpu=19,

+} ZONE_NUM;

+

+int lynq_at_get_temp(int argc, char *argv[]);

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif //__LYNQ_AT_TEMP_H__

diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/AtLine.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/AtLine.cpp
new file mode 100755
index 0000000..7abba8a
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/AtLine.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/AtLine.h
new file mode 100755
index 0000000..8768ac6
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/Misc.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/Misc.cpp
new file mode 100755
index 0000000..0536a68
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/Misc.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/Misc.h
new file mode 100755
index 0000000..06ce1b3
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/ModemCategory.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/ModemCategory.cpp
new file mode 100755
index 0000000..31ef0b6
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/ModemCategory.cpp
@@ -0,0 +1,128 @@
+// SPDX-License-Identifier: MediaTekProprietary
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include <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::isNrSupport() {
+    return (RatConfiguration::isNrSupported());
+}
+
+bool ModemCategory::isCapabilitySim(int type) {
+    int mainCard = Radio_capability_switch_util::get_main_capability_phone_id();
+    bool isCapability = (type == mainCard) ? true : false;
+    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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/ModemCategory.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/ModemCategory.h
new file mode 100755
index 0000000..4ce826d
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/ModemCategory.h
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: MediaTekProprietary
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef 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 isNrSupport();
+    static bool isCapabilitySim(int type);
+    static bool checkViceSimCapability(int simType, int capability);
+};
+
+#endif /* SRC_UTIL_MODEMCATEGORY_H_ */
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/MtkRadioAccessFamily.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/MtkRadioAccessFamily.cpp
new file mode 100755
index 0000000..6fa8dc0
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/MtkRadioAccessFamily.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/MtkRadioAccessFamily.h
new file mode 100755
index 0000000..537f622
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/Phone_utils.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/Phone_utils.cpp
new file mode 100755
index 0000000..06b4917
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/Phone_utils.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/Phone_utils.h
new file mode 100755
index 0000000..b05e5a0
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/Proxycontroller.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/Proxycontroller.cpp
new file mode 100755
index 0000000..d173c71
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/Proxycontroller.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/Proxycontroller.h
new file mode 100755
index 0000000..da3ce2f
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/Radio_capability_switch_util.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/Radio_capability_switch_util.cpp
new file mode 100755
index 0000000..0147650
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/Radio_capability_switch_util.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/Radio_capability_switch_util.h
new file mode 100755
index 0000000..c16ee4d
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/RatConfiguration.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/RatConfiguration.cpp
new file mode 100755
index 0000000..8337193
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/RatConfiguration.cpp
@@ -0,0 +1,312 @@
+// SPDX-License-Identifier: MediaTekProprietary
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include <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::NR = "N";
+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_NR = (1 << 6);
+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;
+    }
+    if (rat.find(NR) != std::string::npos) {
+        iRat = iRat | MASK_NR;
+    }
+    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_NR) == MASK_NR) {
+        rat += (DELIMITER + NR);
+    }
+    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;
+}
+
+/*
+ * check NR suppport
+ * @return boolean, cases as following
+ *       true, rat is active and project config supports it.
+ *       false, rat is inactive no matter project config supports.
+ */
+bool RatConfiguration::isNrSupported() {
+    return (getMaxRat() & getRatConfig() & MASK_NR) == MASK_NR ? true : false;
+}
+
+/*
+ * get the active rat
+ * @return String, the rat in format like C/Lf/Lt/T/W/G
+ */
+std::string RatConfiguration::getActiveRatConfig() {
+    std::string rat = ratToString(getRatConfig());
+    RLOGD("getActiveRatConfig: %s", rat.c_str());
+    return rat;
+}
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/RatConfiguration.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/RatConfiguration.h
new file mode 100755
index 0000000..fd87693
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/RatConfiguration.h
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: MediaTekProprietary
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef 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 NR;
+    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_NR;
+    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 bool isNrSupported();
+    static std::string getActiveRatConfig();
+
+};
+
+#endif /* SRC_UTIL_RATCONFIGURATION_H_ */
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/WorldPhoneUtil.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/WorldPhoneUtil.cpp
new file mode 100755
index 0000000..0b7f05e
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/WorldPhoneUtil.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/WorldPhoneUtil.h
new file mode 100755
index 0000000..2b215cd
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/log_extra.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/log_extra.h
new file mode 100755
index 0000000..ead0d50
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/utils.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/utils.cpp
new file mode 100755
index 0000000..2a301b9
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/utils.cpp
@@ -0,0 +1,354 @@
+ // SPDX-License-Identifier: MediaTekProprietary
+ /*
+ * 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::is93ModemAndAbove() {
+#if defined(MD_93_SUPPORT) || defined(MD_97_SUPPORT)
+    return true;
+#else
+    return false;
+#endif
+}
+
+bool utils::is97Modem() {
+#ifdef MD_97_SUPPORT
+    return true;
+#else
+    return false;
+#endif
+}
+
+bool utils::is93Modem() {
+#ifdef MD_93_SUPPORT
+    return true;
+#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::isMt2735(){
+#ifdef TARGET_PLATFORM_MT2735
+    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);
+    }
+}
+
+std::string utils::addZeroForNum(std::string const &str, int strLength) {
+    std::string result_str;
+    result_str.append(str);
+
+    while (result_str.length() < strLength) {
+        result_str.append("0");
+    }
+
+    LOG_D(LOG_TAG,"addZeroForNum- result_str=%s", result_str.c_str());
+
+    return result_str;
+}
+
+void utils::setMSimProperty(int phoneId, char *pPropertyName, char *pUpdateValue) {
+    #define MAX_PHONE_NUM 10
+    #define MIN(a,b) ((a)<(b) ? (a) : (b))
+
+    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/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/utils.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/utils.h
new file mode 100755
index 0000000..593a626
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/util/utils.h
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: MediaTekProprietary
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef MODEMCATEGORY_H_
+#define MODEMCATEGORY_H_
+
+#include <string>
+#include <vector>
+#include <sstream>
+#include <cstring>
+
+class utils {
+public:
+    utils();
+    virtual ~utils();
+    static bool is97Modem();
+    static bool is93ModemAndAbove();
+    static bool is93Modem();
+    static bool is90Modem();
+    static bool isC2KSupport();
+    static bool isMt2635();
+    static bool isMt2731();
+    static bool isMt2735();
+    static bool is_support_dsds();
+    static bool is_suppport_dsss();
+    static int find_index(std::vector<std::string> v, std::string& str);
+    static std::string format(const std::string& format, ...);
+    static void tokenize(std::string const &str, const char delim, std::vector<std::string> &out);
+    static void tokenize(std::string const &str, const char* delim, std::vector<std::string> &out);
+    static std::string addZeroForNum(std::string const &str, int strLength);
+    static int mtk_property_set(const char *key, const char *value);
+    static int mtk_property_get(const char *key, char *value, const char *default_value);
+    static bool mtk_property_get_bool(const char *key, bool default_value);
+    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/cap/zx297520v3/src/lynq/lib/liblynq-log/LICENSE b/cap/zx297520v3/src/lynq/lib/liblynq-log/LICENSE
new file mode 100755
index 0000000..77f59ed
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-log/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/cap/zx297520v3/src/lynq/lib/liblynq-log/Makefile b/cap/zx297520v3/src/lynq/lib/liblynq-log/Makefile
new file mode 100755
index 0000000..06b216e
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-log/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 ########## log-riltel BB_TELEFWK_OPTION $(BB_TELEFWK_OPTION) ##########)
+
+		   
+
+SUBDIRS +=  log-riltel
+
+
+
+
+
+$(warning ########## log-riltel 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/cap/zx297520v3/src/lynq/lib/liblynq-log/NOTICE b/cap/zx297520v3/src/lynq/lib/liblynq-log/NOTICE
new file mode 100755
index 0000000..c5b1efa
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-log/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/cap/zx297520v3/src/lynq/lib/liblynq-log/README b/cap/zx297520v3/src/lynq/lib/liblynq-log/README
new file mode 100755
index 0000000..9a7e82f
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-log/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/cap/zx297520v3/src/lynq/lib/liblynq-log/include/liblog/liblog.h b/cap/zx297520v3/src/lynq/lib/liblynq-log/include/liblog/liblog.h
new file mode 100755
index 0000000..dd8c7c0
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-log/include/liblog/liblog.h
@@ -0,0 +1,39 @@
+#ifndef __LIBLOG_H__
+#define __LIBLOG_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LOG_ENABLE  0      
+
+//#if LOG_ENABLE
+#if !LOG_ENABLE
+
+#define ENABLE(X)               (1<<(X))
+#define LOG_LEVEL_ENABLE      	  ENABLE(LOG_VERBOSE)
+
+typedef enum
+{
+    LOG_VERBOSE = 0,   
+    LOG_ERROR,  
+    LOG_WARNING,
+    LOG_INFO,
+    LOG_DEBUG,  
+    LOG_LEVEL_MAX
+}log_level_enum;
+
+const static char * LogLevelNameInfoTable[LOG_LEVEL_MAX] =
+{
+    "[VERBOSE]","[ERROR]","[WARNING]","[INFO]","[DEBUG]" //lt add @2021.7.22 for []
+};
+#endif //LOG_ENABLE
+
+void lynq_log_global_output(log_level_enum Level,const char *format,...);
+void lynq_log_configuration_set(char *log_name,char log_data_arr);
+void lynq_log_configuration_init(char *log_name);
+#ifdef __cplusplus
+}
+#endif
+
+#endif  //__LOG_H__
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-log/include/liblog/lynq_deflog.h b/cap/zx297520v3/src/lynq/lib/liblynq-log/include/liblog/lynq_deflog.h
new file mode 100755
index 0000000..667ae1a
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-log/include/liblog/lynq_deflog.h
@@ -0,0 +1,41 @@
+#ifndef __LYNQ_DEFLOG_H__

+#define __LYNQ_DEFLOG_H__

+#include "liblog.h"

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+void lynq_log_configuration_init(char *log_name);

+void lynq_log_configuration_set(char *log_name,char log_data_arr);

+void lynq_log_verbose(const char *format,...);

+void lynq_log_error(const char *format,...);

+void lynq_log_warning(const char *format,...);

+void lynq_log_info(const char *format,...);

+void lynq_log_debug(const char *format,...);

+

+

+#ifndef USER_LOG_TAG 

+#define LYVERBLOG(X...)  lynq_log_global_output(LOG_VERBOSE,X)

+#define LYERRLOG(X...)  lynq_log_global_output(LOG_ERROR,X)

+#define LYWARNLOG(X...)  lynq_log_global_output(LOG_WARNING,X)

+#define LYINFLOG(X...)  lynq_log_global_output(LOG_INFO,X)

+#define LYDBGLOG(X...)  lynq_log_global_output(LOG_DEBUG,X)

+#define LYLOGSET(a) lynq_log_configuration_set(USER_LOG_TAG,a)

+#define LYLOGEINIT(Y) lynq_log_configuration_init(Y)

+#else

+#define LYVERBLOG(X...)  

+#define LYERRLOG(X...)  

+#define LYWARNLOG(X...)  

+#define LYINFLOG(X...)  

+#define LYDBGLOG(X...)  

+#define LYLOGSET(a)

+#define LYLOGEINIT(Y)

+#endif

+

+char* lynq_read_log_version();

+#ifdef __cplusplus

+}

+#endif

+

+#endif  //__LYNQ_DEFLOG_H__
\ No newline at end of file
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-log/log-riltel/log.c b/cap/zx297520v3/src/lynq/lib/liblynq-log/log-riltel/log.c
new file mode 100755
index 0000000..7bbbeac
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-log/log-riltel/log.c
@@ -0,0 +1,367 @@
+#include "liblog.h"
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h> 
+#include <unistd.h>
+#include <string.h>
+//#include <log/log.h>
+#include <include/lynq_uci.h>
+
+#define LOG_NAME_LEN 128
+#define LOG_OUT_LEN 2*1024+100 //lt add @2021.9.22 for write outbuf define len 
+#define LOG_LEN 2*1024 //lt add @2021.9.22 for write buf define len 
+#define LOG_UCI_MODULE "lynq_log"
+#define LOG_UCI_FILE "lynq_uci"
+static unsigned int log_level = 0; 
+static unsigned char log_name_arr[LOG_NAME_LEN] = {0};
+
+int lynq_log_set_value(char *key, char *value);
+int lynq_log_get_value(char *key, char *tmp);
+
+void lynq_log_global_output(log_level_enum Level,const char *format,...)
+{
+#if LOG_ENABLE
+
+    char out_buf[LOG_OUT_LEN] = {0};    
+    char buf[LOG_LEN] = {0};
+	
+    if(Level >=  LOG_LEVEL_MAX)
+        return;
+    if((log_level >> Level)&0x00000001)
+    {
+        va_list args;
+        //TagName
+        if(log_name_arr[0]  > 0)
+        {
+		printf("[%s]",log_name_arr);
+	 }
+        
+        //LevelName
+        printf("%s:",LogLevelNameInfoTable[Level]); //lt dele @2021.7.22 for []
+
+        va_start(args,format);
+        vprintf(format,args);
+        vsnprintf(buf, sizeof(buf), format, args);  //lt add @2021.7.22 for write buf
+        va_end(args);
+        printf("\r\n");
+
+        sprintf(out_buf, "%s %s", LogLevelNameInfoTable[Level], buf);//lt add @2021.7.22 for write outbuf
+        switch(Level) //lt mod @2021.9.22 for matching MTK log level 
+        {
+            case LOG_VERBOSE:
+                __android_log_print(ANDROID_LOG_VERBOSE,log_name_arr, "%s",out_buf); //lt add @2021.9.22 for write syslog.log		
+                break;
+            case LOG_ERROR:
+                __android_log_print(ANDROID_LOG_ERROR,log_name_arr, "%s",out_buf); //lt add @2021.9.22 for write syslog.log		
+                break;
+            case LOG_WARNING:
+                __android_log_print(ANDROID_LOG_WARN,log_name_arr, "%s",out_buf); //lt add @2021.9.22 for write syslog.log		
+                break;		
+            case LOG_INFO:
+                __android_log_print(ANDROID_LOG_INFO,log_name_arr, "%s",out_buf); //lt add @2021.9.22 for write syslog.log		
+                break;
+            case LOG_DEBUG:
+                __android_log_print(ANDROID_LOG_DEBUG,log_name_arr, "%s",out_buf); //lt add @2021.7.22 for write syslog.log		
+                break;
+            default :
+                __android_log_print(ANDROID_LOG_DEBUG,log_name_arr, "Log Level is Error!!!!!!"); //lt add @2021.9.22 for write syslog.log		
+                break;
+        }
+	
+    }
+    return ;
+#endif //LOG_ENABLE
+}
+
+void lynq_log_configuration_set(char *log_name,char log_data_arr)
+{
+    char log_data_str[32] = {0};
+    if(log_name == NULL)
+    {
+        return ;
+    }
+    if(log_data_arr < LOG_LEVEL_MAX)
+    {
+        sprintf(log_data_str,"%d",log_data_arr);
+        if((strlen(log_name)) < LOG_NAME_LEN)
+        {
+            lynq_log_set_value(log_name, log_data_str);//lt mod @2021.8.3 for uci
+        }
+    }
+    lynq_log_configuration_init(log_name);  
+    return ;
+}
+
+void lynq_deal_with_level(unsigned int get_log_level)
+{
+    switch(get_log_level)
+    {
+        case LOG_DEBUG:
+            log_level |= ENABLE(LOG_DEBUG);
+        case LOG_INFO:
+            log_level |= ENABLE(LOG_INFO);
+        case LOG_WARNING:
+            log_level |= ENABLE(LOG_WARNING);
+        case LOG_ERROR:
+            log_level |= ENABLE(LOG_ERROR);
+        case LOG_VERBOSE:
+            log_level |= ENABLE(LOG_VERBOSE);
+            break;
+        default:
+            log_level |= ENABLE(LOG_VERBOSE);
+            break;
+    }
+    return ;
+}
+
+void lynq_log_configuration_init(char *log_name)
+{
+    char get_propty_log_data[32] ={0};
+    unsigned int get_log_level = 0;
+    if(log_name == NULL)
+    {
+        return ;
+    }
+    if((strlen(log_name)) < LOG_NAME_LEN)
+    {
+        strcpy(log_name_arr,log_name);
+        if(0 == lynq_log_get_value(log_name,get_propty_log_data))//lt mod @2021.8.3 for uci
+        {
+            get_log_level = atoi(get_propty_log_data);
+        }
+        else
+        {
+            lynq_log_configuration_set(log_name, get_log_level);//lt add @2021.09.06 for uci
+        }
+    }
+    lynq_deal_with_level(get_log_level);
+    return ;
+}
+
+//lt add @2021.8.3 for in encapsulating the UCI set function
+int lynq_log_set_value(char *key, char *value)
+{
+    return lynq_set_value(LOG_UCI_MODULE, key, value);
+}
+
+//lt add @2021.8.3 for in encapsulating the UCI get function
+int lynq_log_get_value(char *key, char *tmp)
+{
+	return lynq_get_value(LOG_UCI_FILE, LOG_UCI_MODULE, key, tmp);
+}
+
+//lt add @2022.1.5 for  add fota lib name.
+char* lynq_read_log_version()
+{
+	return "LOG-V1.0";
+}
+
+/**
+ * @brief Verbose logs are printed and stored
+ * 
+ * @param log data
+ * @return void 
+ */
+void lynq_log_verbose(const char *format,...)
+{
+#if LOG_ENABLE
+
+    char out_buf[LOG_OUT_LEN] = {0};    
+    char buf[LOG_LEN] = {0};
+    log_level_enum lynq_level = LOG_VERBOSE;
+    
+    if(lynq_level >=  LOG_LEVEL_MAX)
+        return;
+    if((log_level >> lynq_level)&0x00000001)
+    {
+        va_list args;
+        //TagName
+        if(log_name_arr[0]  > 0)
+        {
+            printf("[%s]",log_name_arr);
+        }
+
+        //LevelName
+        printf("%s:",LogLevelNameInfoTable[lynq_level]); //lt dele @2021.7.22 for []
+
+        va_start(args,format);
+        vprintf(format,args);
+        vsnprintf(buf, sizeof(buf), format, args);  //lt add @2021.7.22 for write buf
+        va_end(args);
+        printf("\r\n");
+
+        sprintf(out_buf, "%s %s",LogLevelNameInfoTable[lynq_level], buf);//lt add @2021.7.22 for write outbuf
+        __android_log_print(ANDROID_LOG_VERBOSE,log_name_arr, "%s",out_buf); //lt add @2021.9.22 for write syslog.log		
+    }
+    return ;
+#endif //LOG_ENABLE
+}
+
+/**
+ * @brief Error logs are printed and stored
+ * 
+ * @param log data
+ * @return void 
+ */
+void lynq_log_error(const char *format,...)
+{
+#if LOG_ENABLE
+
+    char out_buf[LOG_OUT_LEN] = {0};    
+    char buf[LOG_LEN] = {0};
+    log_level_enum lynq_level = LOG_ERROR;
+
+    if(lynq_level >=  LOG_LEVEL_MAX)
+        return;
+    if((log_level >> lynq_level)&0x00000001)
+    {
+        va_list args;
+        //TagName
+        if(log_name_arr[0]  > 0)
+        {
+            printf("[%s]",log_name_arr);
+        }
+
+        //LevelName
+        printf("%s:",LogLevelNameInfoTable[lynq_level]); //lt dele @2021.7.22 for []
+
+        va_start(args,format);
+        vprintf(format,args);
+        vsnprintf(buf, sizeof(buf), format, args);  //lt add @2021.7.22 for write buf
+        va_end(args);
+        printf("\r\n");
+
+        sprintf(out_buf, "%s %s",LogLevelNameInfoTable[lynq_level], buf);//lt add @2021.7.22 for write outbuf
+        __android_log_print(ANDROID_LOG_ERROR,log_name_arr, "%s",out_buf); //lt add @2021.9.22 for write syslog.log		
+    }
+    return ;
+#endif //LOG_ENABLE
+    return ;
+}
+
+/**
+ * @brief Warning logs are printed and stored
+ * 
+ * @param log data
+ * @return void 
+ */
+void lynq_log_warning(const char *format,...)
+{
+ #if LOG_ENABLE
+
+    char out_buf[LOG_OUT_LEN] = {0};    
+    char buf[LOG_LEN] = {0};
+    log_level_enum lynq_level = LOG_WARNING;
+
+    if(lynq_level >=  LOG_LEVEL_MAX)
+        return;
+    if((log_level >> lynq_level)&0x00000001)
+    {
+        va_list args;
+        //TagName
+        if(log_name_arr[0]  > 0)
+        {
+            printf("[%s]",log_name_arr);
+        }
+
+        //LevelName
+        printf("%s:",LogLevelNameInfoTable[lynq_level]); //lt dele @2021.7.22 for []
+
+        va_start(args,format);
+        vprintf(format,args);
+        vsnprintf(buf, sizeof(buf), format, args);  //lt add @2021.7.22 for write buf
+        va_end(args);
+        printf("\r\n");
+
+        sprintf(out_buf, "%s %s",LogLevelNameInfoTable[lynq_level], buf);//lt add @2021.7.22 for write outbuf
+        __android_log_print(ANDROID_LOG_WARN,log_name_arr, "%s",out_buf); //lt add @2021.9.22 for write syslog.log		
+    }
+    return ;
+#endif //LOG_ENABLE
+    return ;
+}
+
+/**
+ * @brief Info logs are printed and stored
+ * 
+ * @param log data
+ * @return void 
+ */
+void lynq_log_info(const char *format,...)
+{
+ #if LOG_ENABLE
+
+    char out_buf[LOG_OUT_LEN] = {0};    
+    char buf[LOG_LEN] = {0};
+    log_level_enum lynq_level = LOG_INFO;
+
+    if(lynq_level >=  LOG_LEVEL_MAX)
+        return;
+    if((log_level >> lynq_level)&0x00000001)
+    {	
+        va_list args;
+        //TagName
+        if(log_name_arr[0]  > 0)
+        {
+            printf("[%s]",log_name_arr);
+        }
+
+        //LevelName
+        printf("%s:",LogLevelNameInfoTable[lynq_level]); //lt dele @2021.7.22 for []
+
+        va_start(args,format);
+        vprintf(format,args);
+        vsnprintf(buf, sizeof(buf), format, args);  //lt add @2021.7.22 for write buf
+        va_end(args);
+        printf("\r\n");
+
+        sprintf(out_buf, "%s %s",LogLevelNameInfoTable[lynq_level], buf);//lt add @2021.7.22 for write outbuf
+        __android_log_print(ANDROID_LOG_INFO,log_name_arr, "%s",out_buf); //lt add @2021.9.22 for write syslog.log		
+    }
+    return ;
+#endif //LOG_ENABLE
+    return ;
+}
+
+/**
+ * @brief debug logs are printed and stored
+ * 
+ * @param log data
+ * @return void 
+ */
+void lynq_log_debug(const char *format,...)
+{
+#if LOG_ENABLE
+
+    char out_buf[LOG_OUT_LEN] = {0};    
+    char buf[LOG_LEN] = {0};
+    log_level_enum lynq_level = LOG_DEBUG;
+
+    if(lynq_level >=  LOG_LEVEL_MAX)
+        return;
+    if((log_level >> lynq_level)&0x00000001)
+    {	
+        va_list args;
+        //TagName
+        if(log_name_arr[0]  > 0)
+        {
+            printf("[%s]",log_name_arr);
+        }
+
+        //LevelName
+        printf("%s:",LogLevelNameInfoTable[lynq_level]); //lt dele @2021.7.22 for []
+
+        va_start(args,format);
+        vprintf(format,args);
+        vsnprintf(buf, sizeof(buf), format, args);  //lt add @2021.7.22 for write buf
+        va_end(args);
+        printf("\r\n");
+
+        sprintf(out_buf, "%s %s",LogLevelNameInfoTable[lynq_level], buf);//lt add @2021.7.22 for write outbuf
+        __android_log_print(ANDROID_LOG_DEBUG,log_name_arr, "%s",out_buf); //lt add @2021.9.22 for write syslog.log		
+    }
+    return ;
+#endif //LOG_ENABLE
+    return ;
+}
+
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-log/log-riltel/makefile b/cap/zx297520v3/src/lynq/lib/liblynq-log/log-riltel/makefile
new file mode 100755
index 0000000..37d7896
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-log/log-riltel/makefile
@@ -0,0 +1,62 @@
+SHELL = /bin/sh
+RM = rm -f
+
+LOCAL_CFLAGS := -Wall \
+                -g -Os \
+                -flto \
+                -fPIC \
+                -DRIL_SHLIB \
+                -DATCI_PARSE \
+                -DKEEP_ALIVE \
+                -DECALL_SUPPORT \
+
+CFLAGS += -fPIC -O2 $(INCLUDE) -D_LARGEFILE64_SOURCE
+$(warning ################# RITA ROOT: $(ROOT),includedir:$(includedir))
+LOCAL_PATH   = .
+
+LOCAL_C_INCLUDES = \
+  -I. \
+  -I$(LOCAL_PATH)/../include/liblog \
+  -I$(ROOT)$(includedir) \
+ -I$(ROOT)$(includedir)/logger \
+
+
+LOCAL_LIBS := \
+    -L. \
+    -ldl \
+    -llynq-uci \
+
+SOURCES = $(wildcard *.c wildcard *.h)
+
+EXECUTABLE = liblynq-log.so
+
+OBJECTS=$(SOURCES:.c=.o)
+
+
+.PHONY: build clean install pack_rootfs 
+
+all: build
+$(EXECUTABLE): $(OBJECTS)
+	$(CXX) -shared -Wl,--no-undefined $(OBJECTS) $(LOCAL_LIBS) $(CFLAGS) $(LOCAL_CFLAGS) $(LOCAL_C_INCLUDES) -o $@
+
+%.o : %.c
+	$(CC) $(LOCAL_C_INCLUDES) $(CFLAGS) $(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/cap/zx297520v3/src/lynq/lib/liblynq-shm/LICENSE b/cap/zx297520v3/src/lynq/lib/liblynq-shm/LICENSE
new file mode 100755
index 0000000..605b7ea
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-shm/LICENSE
@@ -0,0 +1,31 @@
+Copyright Statement:
+
+This software/firmware and related documentation ("MobileTek Software") are
+protected under relevant copyright laws. The information contained herein is
+confidential and proprietary to MobileTek Inc. and/or its licensors. Without
+the prior written permission of MobileTek inc. and/or its licensors, any
+reproduction, modification, use or disclosure of MobileTek Software, and
+information contained herein, in whole or in part, shall be strictly
+prohibited.
+
+MobileTek Inc. (C) 2015. All rights reserved.
+
+BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MobileTek SOFTWARE")
+RECEIVED FROM MobileTek AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ON AN "AS-IS" BASIS ONLY. MobileTek 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 MobileTek PROVIDE ANY WARRANTY WHATSOEVER WITH
+RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+INCORPORATED IN, OR SUPPLIED WITH THE MobileTek 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 MobileTek
+SOFTWARE. MobileTek SHALL ALSO NOT BE RESPONSIBLE FOR ANY MobileTek SOFTWARE
+RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MobileTek'S
+ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MobileTek SOFTWARE
+RELEASED HEREUNDER WILL BE, AT MobileTek'S OPTION, TO REVISE OR REPLACE THE
+MobileTek SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+CHARGE PAID BY RECEIVER TO MobileTek FOR SUCH MobileTek SOFTWARE AT ISSUE.
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-shm/include/lynq_shm.h b/cap/zx297520v3/src/lynq/lib/liblynq-shm/include/lynq_shm.h
new file mode 100755
index 0000000..bbac100
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-shm/include/lynq_shm.h
@@ -0,0 +1,26 @@
+/**

+ * @file shm.h

+ * @author hq

+ * @brief 

+ * @version 1.0

+ * @date 2022-12-16

+ * 

+ * @copyright Copyright (c) 2022

+ * 

+ */

+#ifndef __LYNQ_SHM_H__

+#define __LYNQ_SHM_H__

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+int ril_init_mem();
+void ril_deinit_mem();

+bool get_cur_shem_buffer_index(int size, int* level, int* index);

+bool get_shem_buffer_level(int size, int* level);

+char* get_shem_buffer(int level,int index);

+int get_max_shem_buffer_size();

+#ifdef __cplusplus

+}

+#endif 

+#endif //#ifndef __TEST_SHARED_MEMORY_INCLUDE__

diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-shm/lynq_shm.cpp b/cap/zx297520v3/src/lynq/lib/liblynq-shm/lynq_shm.cpp
new file mode 100755
index 0000000..bc1b25a
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-shm/lynq_shm.cpp
@@ -0,0 +1,195 @@
+#include <stdio.h>

+#include <stdlib.h>

+#include <string.h>

+//#include <binder/Parcel.h>

+//#include <sys/socket.h>

+#include <errno.h>

+#include <stdbool.h>

+#include <sys/types.h>

+#include <unistd.h>

+#include <sys/shm.h>

+#include <liblog/lynq_deflog.h>

+#include <pthread.h>

+#include "lynq_shm.h"

+

+#undef LOG_TAG

+#define LOG_TAG "SHM"

+

+#define shm_key "shm_key"    

+

+int shmid=-1; 

+

+static int s_use_count=0;

+

+typedef struct{

+    int num_of_buffer;

+    int size_of_buffer;

+    int cur_index;

+}lynq_shm_type_config;

+

+typedef enum{

+    shm_buf_type_256,

+    shm_buf_type_1k,

+    shm_buf_type_max,

+}lynq_shm_buf_type;

+

+lynq_shm_type_config s_lynq_shm_config[shm_buf_type_max]={

+    {10,256,0},

+    {5,1024,0}

+};

+

+static void * s_ril_shm_buf=(void*) -1L;

+

+static pthread_mutex_t s_shm_mtx = PTHREAD_MUTEX_INITIALIZER;

+

+bool get_cur_shem_buffer_index(int size, int* level, int* index)

+{

+    pthread_mutex_lock(&s_shm_mtx);

+    for(int i=0;i<shm_buf_type_max;i++)

+    {

+        if(size<=s_lynq_shm_config[i].size_of_buffer)

+        {

+            (*level)=i;

+            (*index)=(s_lynq_shm_config[i].cur_index)%s_lynq_shm_config[i].num_of_buffer;

+            s_lynq_shm_config[i].cur_index++;    

+            pthread_mutex_unlock(&s_shm_mtx);

+            return true;

+        }

+    }    

+    pthread_mutex_unlock(&s_shm_mtx);

+    return false;

+}

+

+bool get_shem_buffer_level(int size, int* level)

+{

+    for(int i=0;i<shm_buf_type_max;i++)

+    {

+        if(size<=s_lynq_shm_config[i].size_of_buffer)

+        {

+            (*level)=i;

+            return true;

+        }

+    }    

+    return false;

+}

+

+

+char* get_shem_buffer(int level,int index)

+{    

+    int offset=0;

+    for(int i=0;i<level;i++)

+    {

+        offset+=s_lynq_shm_config[i].num_of_buffer*s_lynq_shm_config[i].size_of_buffer;

+    }

+    offset+=s_lynq_shm_config[level].size_of_buffer*index;

+    return ((char*) s_ril_shm_buf)+offset;

+}

+

+int get_max_shem_buffer_size()

+{

+    return s_lynq_shm_config[shm_buf_type_max-1].size_of_buffer;

+}

+

+int get_total_shem_buffer_size()

+{

+    int total_size=0;

+    for(int i=0;i<shm_buf_type_max;i++)

+    {

+        total_size+=s_lynq_shm_config[i].num_of_buffer*s_lynq_shm_config[i].size_of_buffer;

+    }

+    return total_size;

+}

+

+static int create_shm_common(int size,int flags)

+{

+    LYDBGLOG("create shared memory\n");

+ 

+//  key_t key = ftok(shm_key, 's');

+    key_t key=0x123456;

+    if (key == -1) 

+    {

+        LYERRLOG("ftok error.\n");

+        return -1;

+    }

+    LYDBGLOG("key is 0x%x\n", key);

+ 

+    int shmid = shmget(key,size , flags);

+    if (shmid == -1) 

+    {

+        LYERRLOG("shmget error.\n");

+        return -1;

+    }

+    LYDBGLOG("shmid is %d\n", shmid);

+ 

+    return shmid;

+}

+

+int create_shm()

+{

+    shmid = create_shm_common(get_total_shem_buffer_size(),IPC_CREAT|0644);

+

+    if(shmid==-1)

+    {

+        return -1;

+    }

+    s_ril_shm_buf = shmat(shmid, NULL, 0);

+    if (s_ril_shm_buf == (void*) -1L) 

+    {

+        LYERRLOG("shmat error.\n");

+        return -1;

+    }

+    return 0;    

+}

+ 

+void remove_shm()

+{

+    if(shmid!=-1)

+    {

+        if (shmdt(s_ril_shm_buf) != 0) 

+        {

+            LYERRLOG("shmdt error.\n");      

+        }        

+        shmid = -1;

+    }

+    s_ril_shm_buf = (void*) -1L;

+    return ;

+}

+

+int ril_init_mem()

+{   

+    pthread_mutex_lock(&s_shm_mtx);

+    LYERRLOG("init begin, use count is %d.\n",s_use_count);      

+    if(s_use_count==0)

+    {

+        if(create_shm()!=0)

+        {

+            LYERRLOG("init end, use count is %d.\n",s_use_count);       

+            pthread_mutex_unlock(&s_shm_mtx);

+            return -1;

+        }    

+    }

+    s_use_count++;

+    LYERRLOG("init end, use count is %d.\n",s_use_count);       

+    pthread_mutex_unlock(&s_shm_mtx);

+    return 0;

+}

+

+void ril_deinit_mem()

+{

+    pthread_mutex_lock(&s_shm_mtx);

+

+    LYERRLOG("de-init begin, use count is %d.\n",s_use_count);      

+    if(s_use_count==1)

+    {

+        remove_shm();        

+    }

+

+    if(s_use_count>0)

+    {

+        s_use_count--;    

+    }

+    LYERRLOG("de-init end, use count is %d.\n",s_use_count);      

+    pthread_mutex_unlock(&s_shm_mtx);

+    return ;

+}

+

diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-shm/makefile b/cap/zx297520v3/src/lynq/lib/liblynq-shm/makefile
new file mode 100755
index 0000000..115eb9f
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-shm/makefile
@@ -0,0 +1,65 @@
+SHELL = /bin/sh
+RM = rm -f
+
+LOCAL_CFLAGS := -Wall \
+                -g -Os \
+                -flto \
+                -fPIC       
+
+PWD := $(shell pwd)
+
+$(warning ################# lynq shm ROOT: $(ROOT),includedir:$(includedir), PWD :$(PWD))
+LOCAL_PATH   = .
+
+LOCAL_C_INCLUDES = \
+  -I. \
+  -I$(LOCAL_PATH)/include \
+  -I$(ROOT)$(includedir) \
+  -I$(ROOT)$(includedir)/liblog \
+
+LOCAL_LIBS := \
+    -L. \
+    -ldl \
+    -llynq-log \
+    -lpthread \
+
+
+#   -lbinder \
+#   -lutils \
+#   -lcutils \
+
+SOURCES = $(wildcard *.cpp)
+
+EXECUTABLE = liblynq-shm.so
+
+OBJECTS=$(SOURCES:.c=.o)
+all: $(EXECUTABLE)
+
+$(EXECUTABLE): $(OBJECTS)
+	$(CXX) -shared -Wl,--no-undefined $(OBJECTS) $(LOCAL_LIBS) $(LOCAL_CFLAGS) $(LOCAL_C_INCLUDES) -o $@
+
+%.o : %.c
+	$(CC) $(LOCAL_C_INCLUDES) $(LOCAL_CFLAGS) $(LOCAL_LIBS) -o $@ -c $<
+
+build:  $(EXECUTABLE)
+	$(warning ########## build $(EXECUTABLE)  ##########)
+
+install:
+	$(warning ################# lynq shm EXECUTABLE: $(EXECUTABLE),base:$(base_libdir))
+	mkdir -p $(ROOT)$(base_libdir)/
+	install $(EXECUTABLE) $(ROOT)$(base_libdir)/
+
+pack_rootfs:
+	$(warning ################# lynq shm PACK: $(PACK_INITRAMFS_TO),base:$(base_libdir))
+	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/cap/zx297520v3/src/lynq/lib/liblynq-uci/LICENSE b/cap/zx297520v3/src/lynq/lib/liblynq-uci/LICENSE
new file mode 100755
index 0000000..77f59ed
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-uci/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/cap/zx297520v3/src/lynq/lib/liblynq-uci/include/lynq_uci.h b/cap/zx297520v3/src/lynq/lib/liblynq-uci/include/lynq_uci.h
new file mode 100755
index 0000000..0e9ec37
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-uci/include/lynq_uci.h
@@ -0,0 +1,35 @@
+#ifndef _LYNQ_UCI_H_

+#define _LYNQ_UCI_H_

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+#include <uci.h>

+

+#define LYNQ_UCI_MAX_LEN  128

+#define LYNQ_UCI_SUCCESS 0

+#define LYNQ_UCI_ERROR 1

+#define LYNQ_UCI_FILE "lynq_uci"

+#define LYNQ_UCI_RO_FILE "lynq_uci_ro"

+

+//static struct uci_context * ctx = NULL;

+

+int lynq_del(char *option);

+#if UCI_SUPPORT

+    static int uci_get_value(struct uci_option *o, char *out_buf);

+#endif //uci_support

+int lynq_uci_get(const char *arg, char *out_buf);

+

+int lynq_uci_set(const char *arg);

+

+int lynq_add_section(char *section_type, char *section);

+

+int lynq_set_value(char *section, char *key, char *value);

+

+int lynq_get_value(char *file, char *section, char *key, char *tmp);

+

+#ifdef __cplusplus

+}

+#endif

+#endif

diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-uci/lynq_uci.config b/cap/zx297520v3/src/lynq/lib/liblynq-uci/lynq_uci.config
new file mode 100755
index 0000000..3ac501d
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-uci/lynq_uci.config
@@ -0,0 +1,28 @@
+config  lynq_ril_rw  'lynq_ril'

+        option serverport '8000'

+

+config  lynq_log_rw  'lynq_log'

+        option thhandle_level '0'

+        option function_test_level '0'

+

+config  lynq_wifi_rw  'lynq_wifi'

+        option gateway '192.168.11.1'

+

+config  lynq_sync_time_rw  'lynq_sync_time'

+

+config  lynq_autosuspend  'lynq_autosuspend'

+        option auto_enable '0'

+        option debug '1'

+

+config  lynq_fota_rw  'lynq_fota'

+

+config  service 'adb'

+

+config  adb 'tcp'

+        option port '5555'

+

+config lynq_apn 'lynq_apn_info'

+        option insertId '0'

+

+config  rndis_status 'rndis'

+        option status '0'

diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-uci/lynq_uci_ro.config b/cap/zx297520v3/src/lynq/lib/liblynq-uci/lynq_uci_ro.config
new file mode 100755
index 0000000..4aa92ac
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-uci/lynq_uci_ro.config
@@ -0,0 +1,4 @@
+config lynq_version_ro 'lynq_version'

+

+config  lynq_wifi_ro  'lynq_wifi'

+        option serverport '8000'
\ No newline at end of file
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-uci/makefile b/cap/zx297520v3/src/lynq/lib/liblynq-uci/makefile
new file mode 100755
index 0000000..209bf03
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-uci/makefile
@@ -0,0 +1,85 @@
+SHELL = /bin/sh
+RM = rm -f
+
+LOCAL_CFLAGS := -Wall \
+                -g -Os \
+                -flto \
+                -fPIC \
+
+$(warning ################# C2K support: $(RAT_CONFIG_C2K_SUPPORT))
+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
+
+$(warning ################# TARGET_PLATFORM: $(TARGET_PLATFORM))
+ifeq ($(strip $(TARGET_PLATFORM)), mt2731)
+#$(warning #################add for debug $(ROOT), $(includedir))
+$(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
+
+$(warning ################# RITA ROOT: $(ROOT),includedir:$(includedir))
+LOCAL_PATH   = .
+
+LOCAL_C_INCLUDES = \
+  -I. \
+  -I$(LOCAL_PATH)/include \
+
+
+LOCAL_LIBS := \
+    -L. \
+    -ldl \
+    -lpthread \
+    -luci \
+
+SOURCES = $(wildcard *.c wildcard *.h src/*.c)
+
+EXECUTABLE = liblynq-uci.so
+
+OBJECTS=$(SOURCES:.c=.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 : %.c
+	$(CC) $(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/cap/zx297520v3/src/lynq/lib/liblynq-uci/src/lynq_uci.c b/cap/zx297520v3/src/lynq/lib/liblynq-uci/src/lynq_uci.c
new file mode 100755
index 0000000..b557c08
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-uci/src/lynq_uci.c
@@ -0,0 +1,223 @@
+#include <stdio.h>

+#include <stdlib.h>

+#include <string.h>

+#include <lynq_uci.h>

+#define UCI_SUPPORT 1

+int lynq_del(char *option)

+{

+    printf("this is lynq uci module,fun:%s,line:%d\n",__FUNCTION__,__LINE__);

+    #if UCI_SUPPORT

+    int ret;

+    char buf[LYNQ_UCI_MAX_LEN];

+    struct uci_context *ctx = uci_alloc_context();

+    struct uci_ptr ptr;

+

+    sprintf(buf, "%s", option);

+    if(uci_lookup_ptr(ctx, &ptr, buf, true) == UCI_OK)

+    {

+        uci_delete(ctx, &ptr);

+        uci_save(ctx, ptr.p);

+        ret = LYNQ_UCI_SUCCESS;

+    }

+    else

+        ret = LYNQ_UCI_ERROR;

+

+    uci_free_context(ctx);

+    return ret;

+    #endif //#if UCI_SUPPORT

+    return 0;//#if UCI_SUPPORT add

+}

+#if UCI_SUPPORT

+static int uci_get_value(struct uci_option *o, char *out_buf)

+{

+    printf("this is lynq uci module,fun:%s,line:%d\n",__FUNCTION__,__LINE__);

+    #if UCI_SUPPORT

+	struct uci_element *e;

+	const char *delimiter = " ";

+	int lynq_uci_flag = 0;

+	

+	switch(o->type) {

+		case UCI_TYPE_STRING:

+			strcpy(out_buf, o->v.string);

+			break;

+		case UCI_TYPE_LIST:

+			uci_foreach_element(&o->v.list, e) 

+			{

+				if(lynq_uci_flag)

+					strcat(out_buf, delimiter);

+				

+				strcat(out_buf, e->name);

+				lynq_uci_flag = 1;

+			}

+			break;

+		default:

+			return UCI_ERR_INVAL;

+		break;

+	}

+    	return UCI_OK;

+    #endif //#if UCI_SUPPORT

+    return 0;//#if UCI_SUPPORT add

+}

+#endif //#if UCI_SUPPORT

+int lynq_uci_get(const char *arg, char *out_buf)

+{

+    printf("this is lynq uci module,fun:%s,line:%d\n",__FUNCTION__,__LINE__);

+    #if UCI_SUPPORT

+	struct uci_context *ctx;

+	struct uci_element *e;

+	struct uci_ptr ptr;

+	

+	int ret = UCI_OK;

+	char *para_name = NULL;

+	

+	if(arg == NULL || out_buf == NULL) return UCI_ERR_INVAL;

+

+    	para_name = strdup(arg);

+    	if(para_name == NULL) return UCI_ERR_INVAL;

+	

+    	ctx = uci_alloc_context();

+	if (!ctx) {

+        	free(para_name);

+			return UCI_ERR_MEM;

+	}

+

+	if (uci_lookup_ptr(ctx, &ptr, para_name, true) != UCI_OK) {

+		uci_free_context(ctx);

+		free(para_name);

+		return UCI_ERR_NOTFOUND;

+	}

+

+	if(UCI_LOOKUP_COMPLETE & ptr.flags)

+	{

+		e = ptr.last;

+		switch(e->type)

+		{

+		    case UCI_TYPE_SECTION:

+		        ret = UCI_ERR_INVAL;

+		    break;

+		    case UCI_TYPE_OPTION:

+		        ret = uci_get_value(ptr.o, out_buf);

+		    break;

+		    default:

+		        ret = UCI_ERR_NOTFOUND;

+		    break;

+		}

+	}

+	else

+		ret = UCI_ERR_NOTFOUND;

+

+	uci_free_context(ctx);

+	free(para_name);

+	return ret;

+    #endif //#if UCI_SUPPORT

+    return 0;//#if UCI_SUPPORT add

+}

+

+int lynq_uci_set(const char *arg)

+{

+    printf("this is lynq uci module,fun:%s,line:%d\n",__FUNCTION__,__LINE__);

+    #if UCI_SUPPORT

+	struct uci_context *ctx;

+	struct uci_element *e;

+	struct uci_ptr ptr;

+	int ret = UCI_OK;

+	char *name = NULL;

+	

+	if(arg == NULL) return UCI_ERR_INVAL;

+

+	name = strdup(arg);

+	if(name == NULL) return UCI_ERR_MEM;

+

+	ctx = uci_alloc_context();

+	if (!ctx) {

+		free(name);

+		return UCI_ERR_MEM;

+	}

+

+	if (uci_lookup_ptr(ctx, &ptr, name, true) != UCI_OK) {

+		uci_free_context(ctx);

+		free(name);

+		return UCI_ERR_NOTFOUND;

+	}

+

+	ret = uci_set(ctx, &ptr);

+	if(ret != UCI_OK)

+	{

+	    uci_free_context(ctx);

+	    free(name);

+	    return ret;

+	}

+	

+	ret = uci_save(ctx, ptr.p);

+	if(ret != UCI_OK)

+	{

+		uci_free_context(ctx);

+		free(name);

+		return ret;

+	}

+

+	ret = uci_commit(ctx, &ptr.p, false);

+	if(ret != UCI_OK)

+	{

+		uci_free_context(ctx);

+		free(name);

+		return ret;

+	}

+

+	uci_free_context(ctx);

+	free(name);

+	return ret;

+    #endif //#if UCI_SUPPORT

+    return 0;//#if UCI_SUPPORT add

+}

+

+int lynq_add_section(char *section_type, char *section)//rita add @2021.7.30 for adding section

+{

+    printf("this is lynq uci module,fun:%s,line:%d\n",__FUNCTION__,__LINE__);

+    #if UCI_SUPPORT

+	char buf[128] = "";

+	sprintf(buf,"lynq_uci.%s=%s", section, section_type);

+	//printf("[%s-%d] buf = %s\n", __FUNCTION__, __LINE__, buf);

+	int ret = lynq_uci_set(buf);

+

+	return ret;

+    #endif //#if UCI_SUPPORT

+    return 0;//#if UCI_SUPPORT add

+}

+

+int lynq_set_value(char *section, char *key, char *value)//rita add @2021.7.30 for setting value

+{

+    printf("this is lynq uci module,fun:%s,line:%d\n",__FUNCTION__,__LINE__);

+    #if UCI_SUPPORT

+	char buf[LYNQ_UCI_MAX_LEN] = "";

+

+	sprintf(buf,"%s.%s.%s=%s", LYNQ_UCI_FILE, section, key, value);

+	//printf("[%s-%d] buf = %s\n", __FUNCTION__, __LINE__, buf);

+	int ret = lynq_uci_set(buf);

+	

+	return ret;

+    #endif //#if UCI_SUPPORT

+    return 0;//#if UCI_SUPPORT add

+}

+

+int lynq_get_value(char *file, char *section, char *key, char *tmp)//rita add @2021.7.30 for getting value

+{

+    printf("this is lynq uci module,fun:%s,line:%d\n",__FUNCTION__,__LINE__);

+    #if UCI_SUPPORT

+	char buf[LYNQ_UCI_MAX_LEN] = "";

+	int ret = 0;

+	

+	if(strcmp(file, LYNQ_UCI_RO_FILE) && strcmp(file, LYNQ_UCI_FILE))

+	{

+		printf("[%s-%d] invalid file %s!!!\n", __FUNCTION__, __LINE__, file);

+		return LYNQ_UCI_ERROR;

+	}

+	

+	sprintf(buf,"%s.%s.%s", file, section, key);

+	//printf("[%s-%d] buf = %s\n", __FUNCTION__, __LINE__, buf);

+	

+	ret = lynq_uci_get(buf, tmp);

+	return ret;

+    #endif //#if UCI_SUPPORT

+    return 0;//#if UCI_SUPPORT add

+}

diff --git a/cap/zx297520v3/src/lynq/lib/libpal/LICENSE b/cap/zx297520v3/src/lynq/lib/libpal/LICENSE
new file mode 100755
index 0000000..77f59ed
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/libpal/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/cap/zx297520v3/src/lynq/lib/libpal/Makefile b/cap/zx297520v3/src/lynq/lib/libpal/Makefile
new file mode 100755
index 0000000..b0ce89a
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/libpal/Makefile
@@ -0,0 +1,67 @@
+SHELL = /bin/sh
+RM = rm -f
+
+LOCAL_CFLAGS := -Wall \
+                -g -Os \
+                -flto \
+                -fPIC \
+
+CFLAGS += -fPIC -O2 $(INCLUDE) -D_LARGEFILE64_SOURCE
+LOCAL_PATH   = .
+
+LOCAL_C_INCLUDES = \
+  -I. \
+  -I$(LOCAL_PATH)/include \
+  -I$(LOCAL_PATH)/include/liblog \
+  -I$(LIB_DIR)/binder/include/log \
+  -I$(LIB_DIR)/binder/include \
+
+
+LOCAL_LIBS := \
+    -L. \
+    -L$(zte_lib_path)/binder/liblog \
+    -L$(zte_lib_path)/binder/libcutils \
+    -ldl \
+    -lstdc++ \
+    -llog \
+    -lcutils \
+
+SOURCES = $(wildcard *.c wildcard *.h)
+
+EXECUTABLE = libpal.so
+
+OBJECTS=$(SOURCES:.c=.o)
+H_FILE = ${wildcard *.h}
+CUR_SOURCE=$(wildcard ./src/*.c)
+CUR_OBJS=${patsubst %.c, %.o, $(CUR_SOURCE)}
+
+.PHONY: build clean install pack_rootfs 
+
+all: build
+$(EXECUTABLE): $(CUR_OBJS)
+	$(CXX) -shared -Wl,--no-undefined $(CUR_OBJS) $(LOCAL_LIBS) $(CFLAGS) $(LOCAL_CFLAGS) $(LOCAL_C_INCLUDES) -o $@
+
+%.o : %.c
+	$(CC) $(LOCAL_C_INCLUDES) $(CFLAGS) $(LOCAL_CFLAGS) $(LOCAL_LIBS) -o $@ -c $< 
+
+build:  $(EXECUTABLE)
+	$(warning ########## build $(EXECUTABLE)  ##########)
+
+romfs:
+	$(ROMFSINST) $(EXECUTABLE) /lib/$(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/cap/zx297520v3/src/lynq/lib/libpal/Makefile.mt2735 b/cap/zx297520v3/src/lynq/lib/libpal/Makefile.mt2735
new file mode 100755
index 0000000..0ff7ca8
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/libpal/Makefile.mt2735
@@ -0,0 +1,29 @@
+CANLIB=libpal
+VERSION=1
+TARGET= $(CANLIB).so
+
+
+SO_CFLAGS= -shared
+CFLAGS?= -O2
+H_FILE = ${wildcard *.h}
+CUR_SOURCE=${wildcard *.c}
+CUR_OBJS=${patsubst %.c, %.o, $(CUR_SOURCE)}
+
+
+all: $(TARGET)
+
+install:
+	@mkdir -p $(DEST_DIR)/lib64
+	install -m 0644 $(CANLIB).so $(DEST_DIR)/lib64/
+
+%.o: %.c
+	$(CC)  -Wall -fPIC $(CFLAGS) -c $^ -o $@
+$(TARGET).$(VERSION) : $(CUR_OBJS)
+	$(CC) -shared -nostartfiles -Wl,-soname,$@ $^ -o $@ $(LDFLAGS)
+
+$(TARGET): $(CANLIB).so.$(VERSION)
+	ln -s $< $@
+
+.PHONY: clean
+clean:
+	rm -f $(CANLIB).* $(CUR_OBJS)
diff --git a/cap/zx297520v3/src/lynq/lib/libpal/include/pal_nm.h b/cap/zx297520v3/src/lynq/lib/libpal/include/pal_nm.h
new file mode 100755
index 0000000..844fb1f
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/libpal/include/pal_nm.h
@@ -0,0 +1,132 @@
+//SPDX-License-Identifier: MediaTekProprietary
+#ifndef __PAL_NM_H__
+#define __PAL_NM_H__
+
+/**
+ * @file pal_nm.h
+ * @brief
+ * @author MediaTek
+ * @version v0.1
+ * @date 2016-07-11
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define NM_INTERFACE_FLAG_UP   			(0x1<<0) //IFF_UP
+#define NM_INTERFACE_FLAG_LOOPBACK  	(0x1<<2) //IPP_LOOPBACK
+
+typedef enum {
+    NM_IP_TYPE_UNKNOWN = 0,
+    NM_IP_TYPE_V6_UNSPEC = 0x1,
+    NM_IP_TYPE_V6_LOOPBACK = 0x2,
+    NM_IP_TYPE_V6_MULTICAST = 0x4,
+    NM_IP_TYPE_V6_LINKLOCAL = 0x8,
+	NM_IP_TYPE_V6_SITELOCAL = 0x10,
+
+    NM_IP_TYPE_V6_GLOBAL_PERNAMENT = 0x20,
+    NM_IP_TYPE_V6_GLOBAL_TEMP = 0x40,
+    NM_IP_TYPE_V6_GLOBAL_DYNAMIC =0x80,
+	NM_IP_TYPE_V6_GLOBAL = NM_IP_TYPE_V6_GLOBAL_PERNAMENT | NM_IP_TYPE_V6_GLOBAL_TEMP | NM_IP_TYPE_V6_GLOBAL_DYNAMIC,
+    NM_IP_TYPE_V6_UNIQUE = 0x100,
+
+	NM_IP_TYPE_V6_ALLCONFIG = NM_IP_TYPE_V6_GLOBAL | NM_IP_TYPE_V6_UNIQUE,
+	NM_IP_TYPE_V6_VALIDIP = NM_IP_TYPE_V6_GLOBAL_PERNAMENT | NM_IP_TYPE_V6_GLOBAL_DYNAMIC | NM_IP_TYPE_V6_UNIQUE, /*For App use*/
+
+} NM_IP_TYPE_V6;
+
+typedef enum {
+    NM_NETWORK_TYPE_UNKNOW = 0,
+    NM_NETWORK_TYPE_IMS = 1,
+    NM_NETWORK_TYPE_INTERNET = 2
+} NM_NETWORK_TYPE;
+
+/*interface ipv4 related APIs*/
+int nm_interface_ipv4_set(const char *intf_name, const char* addr, int prefix_len);
+int nm_interface_ipv4_up(const char *intf_name);
+int nm_interface_ipv4_down(const char *intf_name);
+int nm_interface_ipv4_mtu_set(const char *intf_name, int mtu);
+int nm_interface_ipv4_info_get(const char *intf_name, unsigned long *addr,
+                                                   int *prefix_len, int *mtu, unsigned int*flags);
+int nm_interface_ipv4_hwaddr_get(const char *intf_name, unsigned char *hw_addr);
+int nm_interface_ipv4_addr_clear(const char *intf_name);
+
+
+/*interface ipv6 related APIs*/
+int nm_interface_ipv6_mtu_set(const char *intf_name, int mtu);
+int nm_interface_ipv6_addr_clear(const char *intf_name);
+int nm_interface_ipv6_set(const char *intf_name, int on);
+int nm_interface_ipv6_privacyextenstion_enable_set(const char *intf_name, int on);
+int nm_interface_ipv6_ndoffload_enable_set(const char *intf_name, int on);
+int nm_interface_ipv6_addr_set(const char *intf_name, const char *addr, int prefix_len);
+int nm_interface_ipv6_addr_get(const char *intf_name, int addr_type, char *addr, int *prefix_len);
+
+
+/*network related APIs*/
+int nm_network_create(unsigned net_id, const char *permission);
+int nm_network_destroy(unsigned net_id);
+int nm_network_default_set(unsigned net_id);
+int nm_network_default_clear();
+int nm_network_interface_add(unsigned net_id, const char* intf_name);
+int nm_network_interface_remove(unsigned net_id, const char* intf_name);
+int nm_network_route_add(unsigned net_id, const char* intf_name,
+                                      const char  *destination, const char *nexthop,
+                                      int legacy, unsigned int uid);
+int nm_network_route_remove( unsigned net_id, const char* intf_name,
+                                            const char *destination, const char *nexthop,
+                                            int legacy, unsigned int uid);
+
+
+
+/*ipfwd related APIs*/
+int nm_fwd_ipv4_set(int enable, const char *requestor);
+int nm_fwd_ipv4_get(int *enable);
+int nm_fwd_ipv6_set(int enable, const char *requestor);
+int nm_fwd_ipv6_get(int *enable);
+
+
+/*DNS related APIs*/
+//set ipv6 dns name server
+int nm_resolver_ipv6_dns_set(unsigned net_id, const char *domains, const char* const* servers,  int numservers, NM_NETWORK_TYPE type);
+
+//set ipv4 dns name server
+int nm_resolver_ipv4_dns_set(unsigned net_id, const char *domains, const char* const* servers,  int numservers, NM_NETWORK_TYPE type);
+
+//set ipv4 && ipv6 dns name server
+int nm_resolver_dns_set(unsigned net_id, const char *domains, const char* const* servers,  int numservers, NM_NETWORK_TYPE type);
+
+
+//clear name server for both ipv4/ipv6
+int nm_resolver_dns_clear(unsigned net_id);
+
+//flush dns cache
+int nm_resolver_dns_cache_flush(unsigned net_id);
+
+int nm_command_test(char *intf);
+
+int nm_interface_get_netid(const char *intf_name,unsigned int *netid);
+
+
+void nm_network_policy_route_init();
+int nm_network_ipv6_policy_route_modify(uint16_t action, uint32_t table, const char* interface);
+int nm_network_ipv6_policy_rule_modify(uint16_t action, uint32_t priority, uint32_t table, uint32_t fwmark, uint32_t mask, const char* iif, const char* oif);
+int nm_network_ipv4_policy_route_modify(uint16_t action, uint32_t table, const char* interface);
+int nm_network_ipv4_policy_rule_modify(uint16_t action, uint32_t priority, uint32_t table, uint32_t fwmark, uint32_t mask, const char* iif, const char* oif);
+struct Stats {
+    uint64_t rxBytes;
+    uint64_t rxPackets;
+    uint64_t txBytes;
+    uint64_t txPackets;
+    uint64_t tcpRxPackets;
+    uint64_t tcpTxPackets;
+};
+
+int parseIfaceStats(const char* iface, struct Stats* stats);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __PAL_NM_H__*/
diff --git a/cap/zx297520v3/src/lynq/lib/libpal/script/dns.script b/cap/zx297520v3/src/lynq/lib/libpal/script/dns.script
new file mode 100755
index 0000000..fa4c1e6
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/libpal/script/dns.script
@@ -0,0 +1,107 @@
+#!/bin/sh
+#		dns event handling script
+#
+
+RESOLV_CONF="/etc/resolv.conf"
+
+usage() {
+	echo "Usage: $0 {set/clean} dns..."
+	exit 1
+}
+
+clean() {
+  # clean /etc/resolv.conf 
+  cat /dev/null > $RESOLV_CONF
+}
+
+show() {  
+  cat $RESOLV_CONF
+}
+ 
+takelock()
+{
+   while [ -f "/tmp/dns_lock_fd" ]; do
+   :
+   echo "lock dns file now!"
+   sleep 1;
+   done
+   echo 1 > "/tmp/dns_lock_fd"
+} 
+
+givelock()
+{
+   rm /tmp/dns_lock_fd
+}
+
+
+rmV4DNS(){
+   cat /etc/resolv.conf | grep : > /var/dns6   
+   cat /var/dns6 > /etc/resolv.conf
+}
+ 
+rmV6DNS(){
+   cat /etc/resolv.conf | grep -v : > /var/dns4 
+   cat /var/dns4 > /etc/resolv.conf
+}
+
+ 
+count=1
+if [ $# \< $count ] ; then
+	usage
+fi
+
+
+
+	  takelock;     
+case "$1" in 
+	
+	set)	 
+	
+    rmV4DNS;
+		i=2
+		total=$#		
+		while [ $i -le $total ];
+		do
+		  shift
+		  dns=$1
+		  echo "adding dns " $dns
+		  echo nameserver "$dns" >> $RESOLV_CONF
+		  i=`expr $i + 1`		   
+		done		
+		show
+		;;		
+		
+	setv6)	 
+	
+    rmV6DNS;
+		i=2
+		total=$#		
+		while [ $i -le $total ];
+		do
+		  shift
+		  dns=$1
+		  echo "adding dns " $dns
+		  echo nameserver "$dns" >> $RESOLV_CONF
+		  i=`expr $i + 1`		   
+		done		
+		show
+		;;
+
+
+  rmv4)
+    rmV4DNS
+   ;;
+  rmv6)
+    rmV6DNS
+   ;; 
+  
+     
+	clean)
+		clean
+		;;
+		
+	*)
+		usage
+	;;	
+esac
+  givelock;
diff --git a/cap/zx297520v3/src/lynq/lib/libpal/src/pal_nm.c b/cap/zx297520v3/src/lynq/lib/libpal/src/pal_nm.c
new file mode 100755
index 0000000..d958efe
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/libpal/src/pal_nm.c
@@ -0,0 +1,1812 @@
+//SPDX-License-Identifier: MediaTekProprietary
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <net/if.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <linux/if_addr.h>
+#include <../include/pal_nm.h>
+#include <syslog.h>
+
+#include <cutils/sockets.h>
+
+#include <linux/fib_rules.h>
+#include <asm/types.h>
+#include <sys/uio.h>
+#include <errno.h>
+
+#include <inttypes.h>
+
+
+#define	PAL_NM_CMD_BUF_SIZE			256
+#define	PAL_NM_DIGTAL_STRING_SIZE	10
+#define ETH_ALEN                        6
+#define IPV6_PTRADDR_LEN                46
+#define MAX_DNS_NUMS                     2
+
+const char sys_net_path[] = "/sys/class/net";
+static const char IPV4_FORWARDING_PROC_FILE[] = "/proc/sys/net/ipv4/ip_forward";
+static const char IPV6_FORWARDING_PROC_FILE[] = "/proc/sys/net/ipv6/conf/all/forwarding";
+
+static const char* QTAGUID_IFACE_STATS = "/proc/net/xt_qtaguid/iface_stat_fmt";
+//static const char* QTAGUID_UID_STATS = "/proc/net/xt_qtaguid/stats";
+
+const uint16_t FRA_UID_START = 18;
+const uint16_t FRA_UID_END   = 19;
+
+struct rtattr FRATTR_PRIORITY;
+struct rtattr FRATTR_TABLE;
+struct rtattr FRATTR_FWMARK;
+struct rtattr FRATTR_FWMASK;
+struct rtattr FRATTR_UID_START;
+struct rtattr FRATTR_UID_END;
+
+struct rtattr RTATTR_TABLE;
+struct rtattr RTATTR_OIF;
+
+const uint16_t NETLINK_REQUEST_FLAGS = NLM_F_REQUEST | NLM_F_ACK;
+const uint16_t NETLINK_CREATE_REQUEST_FLAGS = NLM_F_REQUEST | NLM_F_ACK | NLM_F_CREATE | NLM_F_EXCL;
+
+uint8_t PADDING_BUFFER[RTA_ALIGNTO] = {0, 0, 0, 0};
+
+
+struct in6_ifreq{
+	struct in6_addr ifr6_addr;
+	int ifr6_prefixlen;
+	int ifr6_ifindex;
+};
+
+#define PAL_DEBUG_TRACE	5
+int pal_nm_debug = PAL_DEBUG_TRACE;
+
+#if 0
+#define PAL_DEBUG_PRINT(level, str, args...)               	\
+	do {                                                    \
+        if(level<=pal_nm_debug)                         	\
+        {   												\
+			printf("\n\r[PAL-NM] %s - ", __FUNCTION__); 	\
+    		printf(str, ##args);                            \
+        }                                                   \
+	} while(0)
+#else
+
+#define PAL_DEBUG_PRINT(level, str, args...)               	\
+	do {                                                    \
+        if(level<=pal_nm_debug)                         	\
+        {   												\
+			syslog(LOG_DEBUG, "[PAL-NM][%s:%d:]--- " str "\n", __FUNCTION__, __LINE__,  ## args);\
+        }                                                   \
+	} while(0)
+
+
+#endif
+static int get_ifindex(const char *dev, int *index)
+{
+   int fd;
+   struct ifreq req={{{0}}};
+   int ret;
+
+   strncpy(req.ifr_name, dev, strlen(dev));
+
+   if((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+   {
+      PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "create socket fail:%s", strerror(errno));
+      return -1;
+   }
+
+   ret = ioctl(fd, SIOCGIFINDEX, &req);
+
+   if(ret == -1)
+   {
+        *index = 0;
+        close(fd);
+        PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "ioctl fail:%s", strerror(errno));
+        return ret;
+   }
+   *index = req.ifr_ifindex;
+   PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "req.ifr_ifindex[%d]", req.ifr_ifindex);
+   close(fd);
+   return 0;
+}
+static int ipv4NetmaskToPrefixLength(in_addr_t mask)
+{
+    int prefixLength = 0;
+    uint32_t m = (uint32_t)ntohl(mask);
+    while (m & 0x80000000) {
+        prefixLength++;
+        m = m << 1;
+    }
+    return prefixLength;
+}
+
+static NM_IP_TYPE_V6 _net_ip_scope_v6(const char* ip_in)
+{
+    if (ip_in == NULL) return NM_IP_TYPE_UNKNOWN;
+    if (strchr(ip_in, ':') == NULL) return NM_IP_TYPE_UNKNOWN;
+    if (strcmp(ip_in, "::") == 0) return NM_IP_TYPE_V6_UNSPEC;
+    if (strcmp(ip_in, "::1") == 0) return NM_IP_TYPE_V6_LOOPBACK;
+    if (!strncmp(ip_in, "2", 1) || !strncmp(ip_in, "3", 1))  return NM_IP_TYPE_V6_GLOBAL;
+
+    if (strncmp(ip_in, "ff00", 4) == 0) return NM_IP_TYPE_V6_MULTICAST;
+    if (strncmp(ip_in, "fe80", 4) == 0) return NM_IP_TYPE_V6_LINKLOCAL;
+    if (strncmp(ip_in, "fec0", 4) == 0) return NM_IP_TYPE_V6_SITELOCAL;
+    if (!strncmp(ip_in, "fc", 2) || !strncmp(ip_in, "fd", 2))  return NM_IP_TYPE_V6_UNIQUE;
+
+    return NM_IP_TYPE_UNKNOWN;
+}
+
+static NM_IP_TYPE_V6 _net_ip_type_v6(int scope, int ifa_flags)
+{
+    if(NM_IP_TYPE_V6_GLOBAL != scope)
+		return scope;
+
+	if(ifa_flags & IFA_F_PERMANENT)
+		return NM_IP_TYPE_V6_GLOBAL_PERNAMENT;
+
+	if(ifa_flags & IFA_F_SECONDARY)
+		return NM_IP_TYPE_V6_GLOBAL_TEMP;
+
+	return NM_IP_TYPE_V6_GLOBAL_DYNAMIC;
+}
+int nm_interface_ipv4_set(const char *intf_name, const char* addr, int prefix_len)
+{
+	char	cmd_buf[PAL_NM_CMD_BUF_SIZE];
+	int 	len;
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+	if (!intf_name || !addr)
+		return	-1;
+	if(strlen(intf_name)==0 || strlen(addr)==0)
+		return -1;
+	//interface setcfg <interface> [addr | prefixLength] [up | down]
+
+	len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc interface setcfg %s %s %d", intf_name, addr, prefix_len);
+	if (len >= PAL_NM_CMD_BUF_SIZE)
+		return	-1;
+
+	PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+	return	system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+
+
+int nm_interface_ipv4_up(const char *intf_name)
+{
+	char	cmd_buf[PAL_NM_CMD_BUF_SIZE];
+	int		len;
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+	if (!intf_name)
+		return	-1;
+
+	//interface setcfg <interface> [addr | prefixLength] [up | down]
+
+	len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc interface setcfg %s up", intf_name);
+	if (len >= PAL_NM_CMD_BUF_SIZE)
+		return	-1;
+
+	PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+	return  system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_interface_ipv4_down(const char *intf_name)
+{
+	char	cmd_buf[PAL_NM_CMD_BUF_SIZE];
+	int		len;
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+	if (!intf_name)
+		return	-1;
+
+	//interface setcfg <interface> [addr | prefixLength] [up | down]
+
+	len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc interface setcfg %s down", intf_name);
+	if (len >= PAL_NM_CMD_BUF_SIZE)
+		return	-1;
+
+	PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+	return  system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+int nm_interface_ipv4_mtu_set(const char *intf_name, int mtu)
+{
+	char	cmd_buf[PAL_NM_CMD_BUF_SIZE];
+	int		len;
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+	if (!intf_name)
+		return	-1;
+
+	//interface setmtu <interface> <mtu>
+
+	len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc interface setmtu %s %d", intf_name, mtu);
+	if (len >= PAL_NM_CMD_BUF_SIZE)
+		return	-1;
+
+	PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+	return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_interface_ipv4_info_get(const char *intf_name, unsigned long *addr,
+                                                   int *prefix_len, int *mtu, unsigned int*flags)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+    int sockfd;
+    struct ifreq ifr;
+    char mtuPath[30] = {0};
+    char chmtu[11] = {0};
+    FILE *fp = NULL;
+	if (!intf_name || !addr ||
+		!intf_name || !mtu || !flags)
+	{
+		return	-1;
+	}
+
+    if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+    {
+        PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "create socket fail");
+        return -1;
+    }
+
+    memset(&ifr, 0, sizeof(struct ifreq));
+    PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "IFNAMSIZ[%d]", IFNAMSIZ);
+    strncpy(ifr.ifr_name, intf_name, IFNAMSIZ);
+    ifr.ifr_name[IFNAMSIZ - 1] = 0;
+
+    if (addr != NULL) {
+        if(ioctl(sockfd, SIOCGIFADDR, &ifr) < 0) {
+            PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "SIOCGIFADDR fail");
+            *addr = 0;
+        } else {
+            *addr = ((struct sockaddr_in*) &ifr.ifr_addr)->sin_addr.s_addr;
+            PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "*addr[%lu]", *addr);
+        }
+    }
+
+    if (prefix_len != NULL) {
+        if(ioctl(sockfd, SIOCGIFNETMASK, &ifr) < 0) {
+            PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "SIOCGIFNETMASK fail");
+            *prefix_len = 0;
+        } else {
+            *prefix_len = ipv4NetmaskToPrefixLength(
+                    ((struct sockaddr_in*) &ifr.ifr_addr)->sin_addr.s_addr);
+            PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "*prefix_len[%u]", *prefix_len);
+        }
+    }
+
+    if (flags != NULL) {
+        if(ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {
+            *flags = 0;
+        } else {
+            *flags = ifr.ifr_flags;
+            PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "*flags[%u]", *flags);
+        }
+    }
+
+    snprintf(mtuPath, 29, "%s/%s/mtu", sys_net_path, intf_name);
+    PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "mtuPath[%s]", mtuPath);
+
+    fp = fopen(mtuPath , "r");
+    if (NULL == fp)
+    {
+        PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "open %s fail", mtuPath);
+        *mtu = 0;
+    }else
+    {
+        fread(chmtu, 1, 10, fp);
+		chmtu[10] = '\0';
+        PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "chmtu[%s]", chmtu);
+        *mtu = atoi(chmtu);
+        PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "*mtu[%u]", *mtu);
+        fclose(fp);
+    }
+    close(sockfd);
+
+	return	0;
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+}
+
+int nm_interface_ipv4_hwaddr_get(const char *intf_name, unsigned char *hw_addr)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+    int ret;
+    int sockfd;
+    struct ifreq ifr;
+	if (!intf_name || !hw_addr)
+	{
+		return	-1;
+	}
+
+    if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+    {
+        PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "create socket fail");
+        return -1;
+    }
+
+    bzero(&ifr, sizeof(ifr));
+    ifr.ifr_name[IFNAMSIZ -1] = '\0';
+    strncpy(ifr.ifr_name, intf_name, IFNAMSIZ);
+    ifr.ifr_name[IFNAMSIZ -1] = '\0';
+
+    ret = ioctl(sockfd, SIOCGIFHWADDR, &ifr);
+    if(ret < 0) {
+        close(sockfd);
+        return -1;
+    }
+
+    memcpy(hw_addr, &ifr.ifr_hwaddr.sa_data, ETH_ALEN);
+
+    close(sockfd);
+	return	0;
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+}
+
+int nm_interface_ipv4_addr_clear(const char *intf_name)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+	char	cmd_buf[PAL_NM_CMD_BUF_SIZE];
+	int 	len;
+
+	if (!intf_name)
+		return	-1;
+
+	// interface clearaddrs <interface>
+
+	len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc interface clearaddrs %s", intf_name);
+	if (len >= PAL_NM_CMD_BUF_SIZE)
+		return	-1;
+
+	PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+	return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+}
+
+
+/*interface ipv6 related APIs*/
+int nm_interface_ipv6_mtu_set(const char *intf_name, int mtu)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+	char	cmd_buf[PAL_NM_CMD_BUF_SIZE];
+	int		len;
+
+	if (!intf_name)
+		return	-1;
+
+	//interface setmtu <interface> <mtu>
+
+	len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc interface setmtu %s %d", intf_name, mtu);
+	if (len >= PAL_NM_CMD_BUF_SIZE)
+		return	-1;
+
+	PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+	return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_interface_ipv6_addr_clear(const char *intf_name)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+	char	cmd_buf[PAL_NM_CMD_BUF_SIZE];
+	int 	len;
+
+	if (!intf_name)
+		return	-1;
+
+	// interface clearaddrs <interface>
+
+	len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc interface clearaddrs %s", intf_name);
+	if (len >= PAL_NM_CMD_BUF_SIZE)
+		return	-1;
+
+	PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+	return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_interface_ipv6_set(const char *intf_name, int on)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+	char	cmd_buf[PAL_NM_CMD_BUF_SIZE];
+	int 	len;
+
+	if (!intf_name)
+		return	-1;
+
+	// interface ipv6 <interface> <enable | disable>
+
+	if (on)
+		len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc interface ipv6 %s enable", intf_name);
+	else
+		len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc interface ipv6 %s disable", intf_name);
+
+	if (len >= PAL_NM_CMD_BUF_SIZE)
+		return	-1;
+
+	PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+	return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_interface_ipv6_privacyextenstion_enable_set(const char *intf_name, int on)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+	char	cmd_buf[PAL_NM_CMD_BUF_SIZE];
+	int 	len;
+
+	if (!intf_name)
+		return	-1;
+
+	// interface ipv6privacyextensions <interface> <enable | disable>
+
+	if (on)
+		len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc interface ipv6privacyextensions %s enable", intf_name);
+	else
+		len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc interface ipv6privacyextensions %s disable", intf_name);
+
+	if (len >= PAL_NM_CMD_BUF_SIZE)
+		return	-1;
+
+	PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+	return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_interface_ipv6_ndoffload_enable_set(const char *intf_name, int on)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+	char	cmd_buf[PAL_NM_CMD_BUF_SIZE];
+	int 	len;
+
+	if (!intf_name)
+		return	-1;
+
+	// interface ipv6ndoffload <interface> <enable | disable>
+
+	if (on)
+		len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc interface ipv6ndoffload %s enable", intf_name);
+	else
+		len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc interface ipv6ndoffload %s disable", intf_name);
+
+	if (len >= PAL_NM_CMD_BUF_SIZE)
+		return	-1;
+
+	PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+	return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_interface_ipv6_addr_set(const char *intf_name, const char *addr, int prefix_len)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+	int fd;
+	int ret;
+    int index = 0;
+    struct in6_ifreq v6_ifreq = {0};
+	if (!intf_name || !addr)
+	{
+		return	-1;
+	}
+
+    ret = get_ifindex(intf_name, &index);
+    if (ret)
+    {
+        PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "get_ifindex");
+        return ret;
+    }
+
+    PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "get_ifindex index[%d]", index);
+
+	fd = socket(AF_INET6, SOCK_DGRAM,0);
+    if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
+    {
+        PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "open socket fail:%s", strerror(errno));
+
+    }
+
+	ret = inet_pton(AF_INET6, addr, &v6_ifreq.ifr6_addr.s6_addr);
+	if(ret != 1)
+	{
+		PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "inet_pton fail:%s", strerror(errno));
+		close(fd);
+		return -1;
+	}
+
+	v6_ifreq.ifr6_ifindex = index;
+	v6_ifreq.ifr6_prefixlen = prefix_len;
+
+	ret = ioctl(fd, SIOCSIFADDR, &v6_ifreq);
+	if(ret == -1)
+	{
+		PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "ioctl SIOCSIFADDR fail:%s", strerror(errno));
+		close(fd);
+		return -1;
+	}
+	close(fd);
+	return	0;
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+}
+
+int nm_interface_ipv6_addr_get(const char *intf_name, int addr_type, char *addr, int *prefix_len)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+	int status;
+	char *buf = NULL;
+	struct nlmsghdr *nlmp;
+	int nlmsgLen;
+	struct ifaddrmsg *rt_ifmsg;
+	struct rtattr *rta;
+	int rtattrlen;
+	struct in6_addr *in6p;
+	int ifidx;
+	int ip_scope, ip_type=0;
+	struct{
+		  struct nlmsghdr n;
+		  struct ifaddrmsg r;
+	}req;
+	if (!intf_name || !addr || !prefix_len)
+	{
+		return	-1;
+	}
+
+    PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "intf_name[%s], addr[%s], prefix[%d], addr_type[%u]", intf_name, addr, *prefix_len, addr_type);
+	status = get_ifindex(intf_name, &ifidx);
+    if (status)
+    {
+        PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "get_ifindex fail");
+		return -1;
+    }
+
+    buf = (char *)malloc(16384);
+    if (NULL == buf)
+    {
+		return -1;
+    }
+
+    memset(buf, 0, 16384);
+
+	int fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
+
+	memset(&req, 0, sizeof(req));
+	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
+	req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT;
+	req.n.nlmsg_type = RTM_GETADDR;
+	req.r.ifa_family = AF_INET6;
+
+
+	/* Time to send and recv the message from kernel */
+	status = send(fd, &req, req.n.nlmsg_len, 0);
+	if (status < 0) {
+        PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "send fail:%s", strerror(errno));
+		close(fd);
+        if (buf)
+        {
+            free(buf);
+            buf = NULL;
+        }
+		return -1;
+	}
+
+
+
+	status = recv(fd, buf, 16384, 0);
+	if (status <= 0) {
+        PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "send fail:%s", strerror(errno));
+		close(fd);
+        if (buf)
+        {
+            free(buf);
+            buf = NULL;
+        }
+		return -1;
+	}
+
+	/* Typically the message is stored in buf, so we need to parse the message to get the required data*/
+	for(nlmp = (struct nlmsghdr *)buf; status  > sizeof(struct nlmsghdr);)
+	{
+		nlmsgLen = nlmp->nlmsg_len;
+		if (!NLMSG_OK(nlmp, status))
+		{
+			PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "NLMSG not OK");
+            if (buf)
+            {
+                free(buf);
+                buf = NULL;
+            }
+			close(fd);
+			return 1;
+		}
+		rt_ifmsg = (struct ifaddrmsg *)NLMSG_DATA(nlmp);
+		rta = (struct rtattr *)IFA_RTA(rt_ifmsg);
+		rtattrlen = IFA_PAYLOAD(nlmp);
+
+		status -= NLMSG_ALIGN(nlmsgLen);
+		nlmp = (struct nlmsghdr*)((char*)nlmp + NLMSG_ALIGN(nlmsgLen));
+		/*Device not match, to next*/
+		if(ifidx != rt_ifmsg->ifa_index)
+			continue;
+
+		for (; RTA_OK(rta, rtattrlen); rta = RTA_NEXT(rta, rtattrlen))
+		{
+			if(rta->rta_type == IFA_CACHEINFO)
+				continue;
+			if(rta->rta_type == IFA_LOCAL||rta->rta_type == IFA_BROADCAST||rta->rta_type == IFA_ANYCAST)
+				PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "Find curious ipv6-address!\n");
+			if(rta->rta_type == IFA_ADDRESS)
+			{
+				in6p = (struct in6_addr *)RTA_DATA(rta);
+				inet_ntop(AF_INET6, in6p, addr, IPV6_PTRADDR_LEN);
+				/*Get type match address*/
+				ip_scope = _net_ip_scope_v6(addr);
+                PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "ip:ip_scope[%d]\n", ip_scope);
+				ip_type  = _net_ip_type_v6(ip_scope, rt_ifmsg->ifa_flags);
+                PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "ip:ip_type[%d]\n", ip_type);
+				*prefix_len =  rt_ifmsg->ifa_prefixlen;
+				PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "ip: %s, prefix: %d, type: %d==\n", addr, *prefix_len, ip_type);
+				if(ip_type & addr_type)/*addr type is we need, and may have a fix of several. Just return the first valid*/
+				{
+					close(fd);
+                    if (buf)
+                    {
+                        free(buf);
+                        buf = NULL;
+                    }
+                    PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "return success\n");
+					return 0;
+				}
+			}
+		}
+	}
+
+	close(fd);
+    if (buf)
+    {
+        free(buf);
+        buf = NULL;
+    }
+
+    PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "return fail\n");
+	return -1;
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+}
+
+
+/*network related APIs*/
+int nm_network_create(unsigned net_id, const char *permission)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+	char	cmd_buf[PAL_NM_CMD_BUF_SIZE];
+	int 	len;
+
+	/*
+	* network create <netId> [permission]
+	* permisstion: NETWORK / SYSTEM
+	*/
+	if (permission)
+		len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc network create %d %s", net_id, permission);
+	else
+		len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc network create %d", net_id);
+	if (len >= PAL_NM_CMD_BUF_SIZE)
+		return	-1;
+
+	PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+	return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_network_destroy(unsigned net_id)
+{
+	char	cmd_buf[PAL_NM_CMD_BUF_SIZE];
+	int 	len;
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+	//network destroy <netId>
+
+	len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc network destroy %d", net_id);
+	if (len >= PAL_NM_CMD_BUF_SIZE)
+		return	-1;
+
+	PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+	return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_network_default_set(unsigned net_id)
+{
+	char	cmd_buf[PAL_NM_CMD_BUF_SIZE];
+	int 	len;
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+	//network default set <netId>
+
+	len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc network default set %d", net_id);
+	if (len >= PAL_NM_CMD_BUF_SIZE)
+		return	-1;
+
+	PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+	return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_network_default_clear()
+{
+	char	cmd_buf[PAL_NM_CMD_BUF_SIZE];
+	int 	len;
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+	//network default clear
+
+	len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc network default clear");
+	if (len >= PAL_NM_CMD_BUF_SIZE)
+		return	-1;
+
+	PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+	return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_network_interface_add(unsigned net_id, const char* intf_name)
+{
+	char	cmd_buf[PAL_NM_CMD_BUF_SIZE];
+	int 	len;
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+	//network interface add <netId> <interface>
+
+	len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc network interface add %d %s", net_id, intf_name);
+	if (len >= PAL_NM_CMD_BUF_SIZE)
+		return	-1;
+
+	PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+	return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_network_interface_remove(unsigned net_id, const char* intf_name)
+{
+	char	cmd_buf[PAL_NM_CMD_BUF_SIZE];
+	int 	len;
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+	//network interface remove <netId> <interface>
+
+	len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc network interface remove %d %s", net_id, intf_name);
+	if (len >= PAL_NM_CMD_BUF_SIZE)
+		return	-1;
+
+	PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+	return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_network_route_add(unsigned net_id, const char* intf_name,
+                                      const char  *destination, const char *nexthop,
+                                      int legacy, unsigned int uid)
+{
+
+	char	cmd_buf[PAL_NM_CMD_BUF_SIZE];
+	int		len;
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+	if (!intf_name || !destination)
+	{
+		return	-1;
+	}
+
+	/* network route [legacy <uid>] add <netId> <interface> <dst> [nexthop] */
+	if (legacy && nexthop)
+	{
+		len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc network route legacy %d add %d %s %s %s",
+													 uid, net_id, intf_name, destination, nexthop);
+	}
+	else if (!legacy && nexthop)
+	{
+		len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc network route add %d %s %s %s",
+													 net_id, intf_name, destination, nexthop);
+
+	}
+	else if (legacy && !nexthop)
+	{
+		len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc network route legacy %d add %d %s %s",
+													 uid, net_id, intf_name, destination);
+
+	}
+	else
+	{
+		len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc network route add %d %s %s",
+													 net_id, intf_name, destination);
+
+	}
+
+	if (len >= PAL_NM_CMD_BUF_SIZE)
+		return	-1;
+
+	PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+	return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_network_route_remove( unsigned net_id, const char* intf_name,
+                                            const char *destination, const char *nexthop,
+                                            int legacy, unsigned int uid)
+{
+	char	cmd_buf[PAL_NM_CMD_BUF_SIZE];
+	int		len;
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+	if (!intf_name || !destination)
+	{
+		return	-1;
+	}
+
+	/*network route [legacy <uid>] remove <netId> <interface> <dst> [nexthop]*/
+	if (legacy && nexthop)
+	{
+		len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc network route legacy %d remove %d %s %s %s",
+													 uid, net_id, intf_name, destination, nexthop);
+	}
+	else if (!legacy && nexthop)
+	{
+		len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc network route remove %d %s %s %s",
+													 net_id, intf_name, destination, nexthop);
+
+	}
+	else if (legacy && !nexthop)
+	{
+		len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc network route legacy %d remove %d %s %s",
+													 uid, net_id, intf_name, destination);
+
+	}
+	else
+	{
+		len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc network route remove %d %s %s",
+													 net_id, intf_name, destination);
+
+	}
+
+
+	if (len >= PAL_NM_CMD_BUF_SIZE)
+		return	-1;
+
+
+	PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+	return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+
+/*ipfwd related APIs*/
+int nm_fwd_ipv4_set(int enable, const char *requestor)
+{
+	char	cmd_buf[PAL_NM_CMD_BUF_SIZE];
+	int 	len;
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+	// ipfwd <status | enable | disable> <requestor>
+
+	if (enable)
+		len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc ipfwd enable %s", requestor);
+	else
+		len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc ipfwd disable %s", requestor);
+	if (len >= PAL_NM_CMD_BUF_SIZE)
+		return	-1;
+
+	PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+	return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_fwd_ipv4_get(int *enable)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+	FILE *fp = NULL;
+    char fwd[11] = {0};
+	if (!enable)
+	{
+		return	-1;
+	}
+
+    fp = fopen(IPV4_FORWARDING_PROC_FILE, "r");
+
+    if (NULL == fp) {
+        PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "Failed to open ipv6_forward (%s)", strerror(errno));
+        *enable = 0;
+        return -1;
+    }
+
+    fread(fwd, 1, 10, fp);
+
+    *enable = atoi(fwd);
+
+    fclose(fp);
+	return	0;
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_fwd_ipv6_set(int enable, const char *requestor)
+{
+	char	cmd_buf[PAL_NM_CMD_BUF_SIZE];
+	int 	len;
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+	// ipv6fwd <status | enable | disable> <requestor>
+
+	if (enable)
+		len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc ipv6fwd enable %s", requestor);
+	else
+		len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc ipv6fwd disable %s", requestor);
+	if (len >= PAL_NM_CMD_BUF_SIZE)
+		return	-1;
+
+	PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+	return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_fwd_ipv6_get(int *enable)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+    FILE *fp = NULL;
+    char fwd[11] = {0};
+	if (!enable)
+	{
+		return	-1;
+	}
+
+    fp = fopen(IPV6_FORWARDING_PROC_FILE, "r");
+
+    if (NULL == fp) {
+        PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "Failed to open ipv6_forward (%s)", strerror(errno));
+        *enable = 0;
+        return -1;
+    }
+
+    fread(fwd, 1, 10, fp);
+
+    *enable = atoi(fwd);
+
+    fclose(fp);
+	return	0;
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+/*DNS related APIs*/
+int nm_resolver_ipv6_dns_set(unsigned net_id, const char *domains, const char* const* servers,  int numservers, NM_NETWORK_TYPE type)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+	char	cmd_buf[PAL_NM_CMD_BUF_SIZE];
+	int 	len, total_len;
+	int		index;
+	char	*temp_ptr = cmd_buf;
+    char    dns[200] = "/usr/bin/dns.script setv6";
+
+	if (!domains)
+		return	-1;
+
+    if (numservers > MAX_DNS_NUMS)
+    {
+        numservers = MAX_DNS_NUMS;
+    }
+
+	//resolver setnetdns <netId> <domains> <dns1> <dns2>
+
+	len = snprintf(temp_ptr, PAL_NM_CMD_BUF_SIZE, "ndc resolver setnetdns %d %s", net_id, domains);
+	if (len >= PAL_NM_CMD_BUF_SIZE)
+		return	-1;
+
+	total_len = len;
+
+	for (index=0; index<numservers; index++)
+	{
+        if (NM_NETWORK_TYPE_INTERNET == type)
+            snprintf(&(dns[strlen(dns)]), 200-strlen(servers[index]), " %s", servers[index]);
+
+		len = snprintf(temp_ptr+total_len, PAL_NM_CMD_BUF_SIZE-total_len, " %s", servers[index]);
+		if ((total_len+len) >= PAL_NM_CMD_BUF_SIZE)
+			return	-1;
+
+		total_len += len;
+
+	}
+
+    if (NM_NETWORK_TYPE_INTERNET == type)
+    {
+        if (system(dns) == -1)
+        {
+            PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "dns:%s:%s", dns, strerror(errno));
+        }
+    }
+
+	PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+	return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_resolver_ipv4_dns_set(unsigned net_id, const char *domains, const char* const* servers,  int numservers, NM_NETWORK_TYPE type)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+	char	cmd_buf[PAL_NM_CMD_BUF_SIZE];
+	int 	len, total_len;
+	int		index;
+	char	*temp_ptr = cmd_buf;
+    char    dns[201] = "/usr/bin/dns.script set";
+
+	if (!domains)
+		return	-1;
+
+    if (numservers > MAX_DNS_NUMS)
+    {
+        numservers = MAX_DNS_NUMS;
+    }
+
+	//resolver setnetdns <netId> <domains> <dns1> <dns2>
+
+	len = snprintf(temp_ptr, PAL_NM_CMD_BUF_SIZE, "ndc resolver setnetdns %d %s", net_id, domains);
+	if (len >= PAL_NM_CMD_BUF_SIZE)
+		return	-1;
+
+	total_len = len;
+
+	for (index=0; index<numservers; index++)
+	{
+        if (NM_NETWORK_TYPE_INTERNET == type)
+            snprintf(&(dns[strlen(dns)]), 200-strlen(servers[index]), " %s", servers[index]);
+
+		len = snprintf(temp_ptr+total_len, PAL_NM_CMD_BUF_SIZE-total_len, " %s", servers[index]);
+		if ((total_len+len) >= PAL_NM_CMD_BUF_SIZE)
+			return	-1;
+
+
+		total_len += len;
+
+	}
+
+	PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+    if (NM_NETWORK_TYPE_INTERNET == type)
+    {
+        if (system(dns) == -1)
+        {
+            PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "dns:%s:%s", dns, strerror(errno));
+        }
+    }
+
+	return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_resolver_dns_set(unsigned net_id, const char *domains, const char* const* servers,  int numservers, NM_NETWORK_TYPE type)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+    char    cmd_buf[PAL_NM_CMD_BUF_SIZE];
+    int     len, total_len = 0;
+    int     index;
+    char    *temp_ptr = cmd_buf;
+
+        if (!domains)
+            return  -1;
+    //resolver setnetdns <netId> <domains> <dns1> <dns2>
+
+	len = snprintf(temp_ptr, PAL_NM_CMD_BUF_SIZE, "ndc resolver setnetdns %d %s", net_id, domains);
+
+	total_len = len;
+
+	if (len >= PAL_NM_CMD_BUF_SIZE)
+		return	-1;
+
+    for (index=0; index<numservers; index++)
+	{
+	    len = snprintf(temp_ptr+total_len, PAL_NM_CMD_BUF_SIZE-total_len, " %s", servers[index]);
+		if ((total_len+len) >= PAL_NM_CMD_BUF_SIZE)
+			return	-1;
+
+
+		total_len += len;
+	}
+
+    PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+    return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+int nm_resolver_dns_clear(unsigned net_id)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+	char	cmd_buf[PAL_NM_CMD_BUF_SIZE];
+	int 	len;
+
+	//resolver clearnetdns <netId>
+
+	len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc resolver clearnetdns %d", net_id);
+	if (len >= PAL_NM_CMD_BUF_SIZE)
+		return	-1;
+
+	PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+	return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_resolver_dns_cache_flush(unsigned net_id)
+{
+	char	cmd_buf[PAL_NM_CMD_BUF_SIZE];
+	int 	len;
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+	//resolver flushnet <netId>
+	len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc resolver flushnet %d", net_id);
+	if (len >= PAL_NM_CMD_BUF_SIZE)
+		return	-1;
+
+	PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+	return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_command_test(char *intf)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+	char	*dns_servier[] =
+							{"192.168.0.1",
+							 "192.168.0.2",
+							 "192.168.0.3",
+							 "192.168.0.4",
+							 "192.168.0.5",
+							 " "};
+	char	**dns_ptr = &(dns_servier[0]);
+	pal_nm_debug = 6;
+
+	/*interface command*/
+	nm_interface_ipv4_up(intf);
+	nm_interface_ipv4_down(intf);
+	nm_interface_ipv4_mtu_set(intf, 512);
+	nm_interface_ipv4_addr_clear(intf);
+	nm_interface_ipv6_mtu_set(intf, 512);
+	nm_interface_ipv6_set(intf, 1);
+	nm_interface_ipv6_set(intf, 0);
+	nm_interface_ipv6_privacyextenstion_enable_set(intf, 1);
+	nm_interface_ipv6_privacyextenstion_enable_set(intf, 0);
+	nm_interface_ipv6_ndoffload_enable_set(intf, 1);
+	nm_interface_ipv6_ndoffload_enable_set(intf, 0);
+
+	/*net_id network*/
+	nm_network_create(3, "enable");
+	nm_network_destroy(3);
+	nm_network_default_set(3);
+	nm_network_interface_add(3, intf);
+	nm_network_interface_remove(3, intf);
+	nm_network_route_add(3, intf, "192.168.0.11", NULL, 0, 1);
+	nm_network_route_add(3, intf, "192.168.0.11", "192.168.0.22", 0, 1);
+	nm_network_route_add(3, intf, "192.168.0.11", NULL, 1, 1);
+	nm_network_route_add(3, intf, "192.168.0.11", "192.168.0.22", 1, 1);
+	nm_network_route_remove(3, intf, "192.168.0.11", NULL, 0, 1);
+	nm_network_route_remove(3, intf, "192.168.0.11", "192.168.0.22", 0, 1);
+	nm_network_route_remove(3, intf, "192.168.0.11", NULL, 1, 1);
+	nm_network_route_remove(3, intf, "192.168.0.11", "192.168.0.22", 1, 1);
+
+	/*ipfwd*/
+	nm_fwd_ipv4_set(1, "abc");
+	nm_fwd_ipv4_set(0, "abc");
+	nm_fwd_ipv6_set(1, "abc");
+	nm_fwd_ipv6_set(0, "abc");
+
+	/*dns*/
+	nm_resolver_ipv4_dns_set(1, "my_domains", (const char* const*)dns_ptr, 5, NM_NETWORK_TYPE_INTERNET);
+	nm_resolver_dns_clear(1);
+
+
+	return	0;
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+int do_cmd(char *cmd_buf,char *ret_buf)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+    int sock;
+	char buffer[1024];
+	int offset = 0;
+	char tmp[4];
+    int i = 0;
+	int code=0;
+	if ((sock = socket_local_client("netd",
+									 ANDROID_SOCKET_NAMESPACE_RESERVED,
+									 SOCK_STREAM)) < 0) {
+		close(sock);
+		PAL_DEBUG_PRINT(PAL_DEBUG_TRACE,"Error connecting (%s)\n",strerror(errno));
+		return -1;
+	}
+    if (write(sock, cmd_buf, strlen(cmd_buf) + 1) < 0) {
+		close(sock);
+		PAL_DEBUG_PRINT(PAL_DEBUG_TRACE,"write error\n");
+        return -1;
+    }
+
+	fd_set read_fds;
+	struct timeval to;
+	int rc = 0;
+
+	to.tv_sec = 10;
+	to.tv_usec = 0;
+
+	FD_ZERO(&read_fds);
+	FD_SET(sock, &read_fds);
+
+	if ((rc = select(sock +1, &read_fds, NULL, NULL, &to)) < 0) {
+		close(sock);
+		PAL_DEBUG_PRINT(PAL_DEBUG_TRACE,"Error in select (%s)\n", strerror(errno));
+		return -1;
+	} else if (!rc) {
+
+		close(sock);
+		PAL_DEBUG_PRINT(PAL_DEBUG_TRACE,"TIMEDOUT (%s)\n", strerror(errno));
+		return ETIMEDOUT;
+	} else if (FD_ISSET(sock, &read_fds)) {
+		memset(buffer, 0, 1024);
+		while ((rc = read(sock, buffer, 1024)) ) {
+			if (rc == 0)
+			{
+				close(sock);
+				PAL_DEBUG_PRINT(PAL_DEBUG_TRACE,"Lost connection to Netd - did it crash?\n");
+				return -1;
+			}
+			else if(rc<0)
+			{
+				close(sock);
+				PAL_DEBUG_PRINT(PAL_DEBUG_TRACE,"Error reading data (%s)\n", strerror(errno));
+				return -1;
+			}
+			else
+			{
+				offset=0;
+				for (i = 0; i < rc; i++) {
+					if (buffer[i] == '\0') {
+						strncpy(tmp, buffer + offset, 3);
+						tmp[3] = '\0';
+						code = atoi(tmp);
+						offset = i + 1;
+						if (code >= 200 && code < 600)
+						{
+							strncpy(ret_buf, buffer + 4, offset);
+							close(sock);
+							PAL_DEBUG_PRINT(PAL_DEBUG_TRACE,"code (%d)\n", code);
+							return code;
+						}
+					}
+				}
+			}
+		}
+	}
+	close(sock);
+	return -1;
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+}
+int nm_interface_get_netid(const char *intf_name,unsigned int *netid)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+	char	cmd_buf[PAL_NM_CMD_BUF_SIZE];
+	int 	len;
+	char	ret_buf[1024];
+	len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "0 network interface get %s", intf_name);
+	PAL_DEBUG_PRINT(PAL_DEBUG_TRACE,"nm_interface_get start \n");
+	if (len >= PAL_NM_CMD_BUF_SIZE)
+		return	-1;
+
+	if(do_cmd(cmd_buf,ret_buf)!=200)
+	{
+		PAL_DEBUG_PRINT(PAL_DEBUG_TRACE,"nm_interface_get return error \n");
+		return -1;
+	}
+
+	*netid=atoi(ret_buf);
+	PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "*netid:%d", *netid);
+	return 0;
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+}
+
+void nm_network_policy_route_init()
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+    FRATTR_PRIORITY.rta_len = RTA_LENGTH(sizeof(uint32_t));
+    FRATTR_PRIORITY.rta_type = FRA_PRIORITY;
+
+    FRATTR_TABLE.rta_len = RTA_LENGTH(sizeof(uint32_t));
+    FRATTR_TABLE.rta_type = FRA_TABLE;
+
+    FRATTR_FWMARK.rta_len = RTA_LENGTH(sizeof(uint32_t));
+    FRATTR_FWMARK.rta_type = FRA_FWMARK;
+
+    FRATTR_FWMASK.rta_len = RTA_LENGTH(sizeof(uint32_t));
+    FRATTR_FWMASK.rta_type = FRA_FWMASK;
+
+    FRATTR_UID_START.rta_len = RTA_LENGTH(sizeof(uid_t));
+    FRATTR_UID_START.rta_type = FRA_UID_START;
+
+    FRATTR_UID_END.rta_len = RTA_LENGTH(sizeof(uid_t));
+    FRATTR_UID_END.rta_type = FRA_UID_END;
+
+    RTATTR_TABLE.rta_len = RTA_LENGTH(sizeof(uint32_t));
+    RTATTR_TABLE.rta_type = RTA_TABLE;
+
+    RTATTR_OIF.rta_len = RTA_LENGTH(sizeof(uint32_t));
+    RTATTR_OIF.rta_type = RTA_OIF;
+#endif //LYNQ_MAY_SUPPORT
+return NULL;//LYNQ_MAY_SUPPORT add
+}
+
+const struct sockaddr_nl NETLINK_ADDRESS = {AF_NETLINK, 0, 0, 0};
+
+int sendNetlinkRequest(uint16_t action, uint16_t flags, struct iovec* iov, int iovlen) {
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+    struct nlmsghdr nlmsg = {
+        .nlmsg_type = action,
+        .nlmsg_flags = flags,
+    };
+    iov[0].iov_base = &nlmsg;
+    iov[0].iov_len = sizeof(nlmsg);
+    for (int i = 0; i < iovlen; ++i) {
+        nlmsg.nlmsg_len += iov[i].iov_len;
+    }
+
+    int ret;
+    struct {
+        struct nlmsghdr msg;
+        struct nlmsgerr err;
+    } response;
+
+    int sock = socket(AF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_ROUTE);
+    if (sock == -1) {
+		PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "socket error");
+        ret=-1;
+		goto fail;
+    }
+
+    if (connect(sock, (struct sockaddr *)&NETLINK_ADDRESS, sizeof(NETLINK_ADDRESS)) == -1) {
+		PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "connect error");
+        ret=-1;
+		goto fail;
+    }
+
+    if (writev(sock, iov, iovlen) == -1) {
+		PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "writev error");
+        ret=-1;
+		goto fail;
+    }
+
+    if ((ret = recv(sock, &response, sizeof(response), 0)) == -1) {
+		PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "recv error");
+        ret=-1;
+		goto fail;
+    }
+
+
+    if (ret == sizeof(response)) {
+        ret = response.err.error;  // Netlink errors are negative errno.
+        if (ret) {
+            PAL_DEBUG_PRINT(PAL_DEBUG_TRACE,"netlink response contains error (%s)", strerror(-ret));
+        }
+    } else {
+        PAL_DEBUG_PRINT(PAL_DEBUG_TRACE,"bad netlink response message size (%d != %zu)", ret, sizeof(response));
+        ret = -999;
+    }
+fail:
+    if (sock != -1) {
+        close(sock);
+    }
+
+    return ret;
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+}
+
+
+int nm_network_ipv6_policy_route_modify(uint16_t action, uint32_t table, const char* interface)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+    uint8_t rawAddress[sizeof(struct in6_addr)];
+    uint8_t rawNexthop[sizeof(struct in6_addr)];
+    int rawLength = sizeof(rawAddress);
+
+    if (!interface) return -1;
+
+    memset(rawAddress, 0, rawLength);
+
+    struct rtmsg route = {
+        .rtm_protocol = RTPROT_STATIC,
+        .rtm_type = RTN_UNICAST,
+        .rtm_family = AF_INET6,
+        .rtm_dst_len = 0,
+        .rtm_scope = RT_SCOPE_UNIVERSE,
+        .rtm_flags = 0,
+    };
+
+    struct rtattr rtaDst;;
+    struct rtattr rtaGateway;
+
+    rtaDst.rta_len = RTA_LENGTH(rawLength);
+    rtaDst.rta_type = RTA_DST;
+
+    rtaGateway.rta_len = RTA_LENGTH(rawLength);
+    rtaGateway.rta_type = RTA_GATEWAY;
+
+    uint32_t ifindex = if_nametoindex(interface);
+
+    struct iovec iov[] = {
+        { NULL,          0 },
+        { &route,        sizeof(route) },
+        { &RTATTR_TABLE, sizeof(RTATTR_TABLE) },
+        { &table,        sizeof(table) },
+#if 0
+        { &rtaDst,       sizeof(rtaDst) },
+        { rawAddress,    16 },
+#else
+        { &rtaDst,       0 },
+        { rawAddress,    0 },
+#endif
+        { &RTATTR_OIF,   sizeof(RTATTR_OIF)},
+        { &ifindex,      sizeof(ifindex)},
+        { &rtaGateway,   0 },
+        { rawNexthop,    0},
+    };
+
+    uint16_t flags = (action == RTM_NEWROUTE) ? NETLINK_CREATE_REQUEST_FLAGS : NETLINK_REQUEST_FLAGS;
+    return sendNetlinkRequest(action, flags, iov, 10);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+}
+
+int nm_network_ipv4_policy_route_modify(uint16_t action, uint32_t table, const char* interface)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+    uint8_t rawAddress[sizeof(struct in_addr)];
+    uint8_t rawNexthop[sizeof(struct in_addr)];
+    int rawLength = sizeof(rawAddress);
+
+    if (!interface) return -1;
+
+    memset(rawAddress, 0, rawLength);
+
+    struct rtmsg route = {
+        .rtm_protocol = RTPROT_STATIC,
+        .rtm_type = RTN_UNICAST,
+        .rtm_family = AF_INET,
+        .rtm_dst_len = 0,
+        .rtm_scope = RT_SCOPE_UNIVERSE,
+        .rtm_flags = 0,
+    };
+
+    struct rtattr rtaDst;;
+    struct rtattr rtaGateway;
+
+    rtaDst.rta_len = RTA_LENGTH(rawLength);
+    rtaDst.rta_type = RTA_DST;
+
+    rtaGateway.rta_len = RTA_LENGTH(rawLength);
+    rtaGateway.rta_type = RTA_GATEWAY;
+
+    uint32_t ifindex = if_nametoindex(interface);
+
+    struct iovec iov[] = {
+        { NULL,          0 },
+        { &route,        sizeof(route) },
+        { &RTATTR_TABLE, sizeof(RTATTR_TABLE) },
+        { &table,        sizeof(table) },
+#if 0
+        { &rtaDst,       sizeof(rtaDst) },
+        { rawAddress,    16 },
+#else
+        { &rtaDst,       0 },
+        { rawAddress,    0 },
+#endif
+        { &RTATTR_OIF,   sizeof(RTATTR_OIF)},
+        { &ifindex,      sizeof(ifindex)},
+        { &rtaGateway,   0 },
+        { rawNexthop,    0},
+    };
+
+    uint16_t flags = (action == RTM_NEWROUTE) ? NETLINK_CREATE_REQUEST_FLAGS : NETLINK_REQUEST_FLAGS;
+    return sendNetlinkRequest(action, flags, iov, 10);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+}
+
+int nm_network_ipv6_policy_rule_modify(uint16_t action, uint32_t priority, uint32_t table, uint32_t fwmark, uint32_t mask, const char* iif, const char* oif)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+    char iif_name[16], oif_name[16];
+    int iif_name_len, iif_name_padding;
+    int oif_name_len, oif_name_padding;
+    struct rtattr FRATTR_IIFNAME;
+    struct rtattr FRATTR_OIFNAME;
+    uid_t uidStart = 0, uidEnd = 0;
+
+    if (iif) {
+        snprintf(iif_name, sizeof(iif_name), "%s", iif);
+        iif_name_len = strlen(iif_name) + 1;
+        iif_name_padding = RTA_SPACE(iif_name_len) - RTA_LENGTH(iif_name_len);
+    } else {
+        iif_name_len = 0;
+        iif_name_padding = 0;
+    }
+    FRATTR_IIFNAME.rta_len =  RTA_LENGTH(iif_name_len);
+    FRATTR_IIFNAME.rta_type = FRA_IIFNAME;
+
+    if (oif) {
+        snprintf(oif_name, sizeof(oif_name), "%s", oif);
+        oif_name_len = strlen(oif_name) + 1;
+        oif_name_padding = RTA_SPACE(oif_name_len) - RTA_LENGTH(oif_name_len);
+    } else {
+        oif_name_len = 0;
+        oif_name_padding = 0;
+    }
+    FRATTR_OIFNAME.rta_len =  RTA_LENGTH(oif_name_len);
+    FRATTR_OIFNAME.rta_type = FRA_OIFNAME;
+
+    struct fib_rule_hdr rule = {
+        .action = FR_ACT_TO_TBL,
+    };
+
+    struct iovec iov[] = {
+        { NULL,              0 },
+        { &rule,             sizeof(rule) },
+        { &FRATTR_PRIORITY,  sizeof(FRATTR_PRIORITY) },
+        { &priority,         sizeof(priority) },
+        { &FRATTR_TABLE,     table != RT_TABLE_UNSPEC ? sizeof(FRATTR_TABLE) : 0 },
+        { &table,            table != RT_TABLE_UNSPEC ? sizeof(table) : 0 },
+        { &FRATTR_FWMARK,    mask ? sizeof(FRATTR_FWMARK) : 0 },
+        { &fwmark,           mask ? sizeof(fwmark) : 0 },
+        { &FRATTR_FWMASK,    mask ? sizeof(FRATTR_FWMASK) : 0 },
+        { &mask,             mask ? sizeof(mask) : 0 },
+        { &FRATTR_UID_START, 0 },
+        { &uidStart,         0 },
+        { &FRATTR_UID_END,   0 },
+        { &uidEnd,           0 },
+        { &FRATTR_IIFNAME,   iif != NULL ? sizeof(FRATTR_IIFNAME) : 0 },
+        { iif_name,          iif_name_len },
+        { PADDING_BUFFER,    iif_name_padding },
+        { &FRATTR_OIFNAME,   oif != NULL ? sizeof(FRATTR_OIFNAME) : 0 },
+        { oif_name,          oif_name_len },
+        { PADDING_BUFFER,    oif_name_padding },
+    };
+
+    uint16_t flags = (action == RTM_NEWROUTE) ? NETLINK_CREATE_REQUEST_FLAGS : NETLINK_REQUEST_FLAGS;
+
+    rule.family = AF_INET6;
+    return sendNetlinkRequest(action, flags, iov, 20);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+}
+
+int nm_network_ipv4_policy_rule_modify(uint16_t action, uint32_t priority, uint32_t table, uint32_t fwmark, uint32_t mask, const char* iif, const char* oif)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+    char iif_name[16], oif_name[16];
+    int iif_name_len, iif_name_padding;
+    int oif_name_len, oif_name_padding;
+    struct rtattr FRATTR_IIFNAME;
+    struct rtattr FRATTR_OIFNAME;
+    uid_t uidStart = 0, uidEnd = 0;
+
+    if (iif) {
+        snprintf(iif_name, sizeof(iif_name), "%s", iif);
+        iif_name_len = strlen(iif_name) + 1;
+        iif_name_padding = RTA_SPACE(iif_name_len) - RTA_LENGTH(iif_name_len);
+    } else {
+        iif_name_len = 0;
+        iif_name_padding = 0;
+    }
+    FRATTR_IIFNAME.rta_len =  RTA_LENGTH(iif_name_len);
+    FRATTR_IIFNAME.rta_type = FRA_IIFNAME;
+
+    if (oif) {
+        snprintf(oif_name, sizeof(oif_name), "%s", oif);
+        oif_name_len = strlen(oif_name) + 1;
+        oif_name_padding = RTA_SPACE(oif_name_len) - RTA_LENGTH(oif_name_len);
+    } else {
+        oif_name_len = 0;
+        oif_name_padding = 0;
+    }
+    FRATTR_OIFNAME.rta_len =  RTA_LENGTH(oif_name_len);
+    FRATTR_OIFNAME.rta_type = FRA_OIFNAME;
+
+    struct fib_rule_hdr rule = {
+        .action = FR_ACT_TO_TBL,
+    };
+
+    struct iovec iov[] = {
+        { NULL,              0 },
+        { &rule,             sizeof(rule) },
+        { &FRATTR_PRIORITY,  sizeof(FRATTR_PRIORITY) },
+        { &priority,         sizeof(priority) },
+        { &FRATTR_TABLE,     table != RT_TABLE_UNSPEC ? sizeof(FRATTR_TABLE) : 0 },
+        { &table,            table != RT_TABLE_UNSPEC ? sizeof(table) : 0 },
+        { &FRATTR_FWMARK,    mask ? sizeof(FRATTR_FWMARK) : 0 },
+        { &fwmark,           mask ? sizeof(fwmark) : 0 },
+        { &FRATTR_FWMASK,    mask ? sizeof(FRATTR_FWMASK) : 0 },
+        { &mask,             mask ? sizeof(mask) : 0 },
+        { &FRATTR_UID_START, 0 },
+        { &uidStart,         0 },
+        { &FRATTR_UID_END,   0 },
+        { &uidEnd,           0 },
+        { &FRATTR_IIFNAME,   iif != NULL ? sizeof(FRATTR_IIFNAME) : 0 },
+        { iif_name,          iif_name_len },
+        { PADDING_BUFFER,    iif_name_padding },
+        { &FRATTR_OIFNAME,   oif != NULL ? sizeof(FRATTR_OIFNAME) : 0 },
+        { oif_name,          oif_name_len },
+        { PADDING_BUFFER,    oif_name_padding },
+    };
+
+    uint16_t flags = (action == RTM_NEWROUTE) ? NETLINK_CREATE_REQUEST_FLAGS : NETLINK_REQUEST_FLAGS;
+
+    rule.family = AF_INET;
+    return sendNetlinkRequest(action, flags, iov, 20);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+}
+
+static const uint64_t UNKNOWN = -1;
+
+int parseIfaceStats(const char* iface, struct Stats* stats) {
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+    FILE *fp = fopen(QTAGUID_IFACE_STATS, "r");
+    if (fp == NULL) {
+        return -1;
+    }
+
+    char buffer[384];
+    char cur_iface[32];
+    bool foundTcp = false;
+    uint64_t rxBytes, rxPackets, txBytes, txPackets, tcpRxPackets, tcpTxPackets;
+
+    while (fgets(buffer, sizeof(buffer), fp) != NULL) {
+        int matched = sscanf(buffer, "%31s %" SCNu64 " %" SCNu64 " %" SCNu64
+                " %" SCNu64 " " "%*u %" SCNu64 " %*u %*u %*u %*u "
+                "%*u %" SCNu64 " %*u %*u %*u %*u", cur_iface, &rxBytes,
+                &rxPackets, &txBytes, &txPackets, &tcpRxPackets, &tcpTxPackets);
+        if (matched >= 5) {
+            if (matched == 7) {
+                foundTcp = true;
+            }
+            if (!iface || !strcmp(iface, cur_iface)) {
+                stats->rxBytes += rxBytes;
+                stats->rxPackets += rxPackets;
+                stats->txBytes += txBytes;
+                stats->txPackets += txPackets;
+                if (matched == 7) {
+                    stats->tcpRxPackets += tcpRxPackets;
+                    stats->tcpTxPackets += tcpTxPackets;
+                }
+            }
+        }
+    }
+
+    if (!foundTcp) {
+        stats->tcpRxPackets = UNKNOWN;
+        stats->tcpTxPackets = UNKNOWN;
+    }
+
+    if (fclose(fp) != 0) {
+        return -1;
+    }
+    return 0;
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+}
+
+
+