[Feature][ZXW-13]support liblynq-sim

Change-Id: I8e8c65ee2279a76a0434420ea4579a8ce480e221
diff --git a/cap/zx297520v3/sources/meta-zxic-custom/conf/distro/vehicle_dc.conf b/cap/zx297520v3/sources/meta-zxic-custom/conf/distro/vehicle_dc.conf
index 0ef3377..1d009f1 100755
--- a/cap/zx297520v3/sources/meta-zxic-custom/conf/distro/vehicle_dc.conf
+++ b/cap/zx297520v3/sources/meta-zxic-custom/conf/distro/vehicle_dc.conf
@@ -141,6 +141,7 @@
         libpal \
         libvendor-ril \
         liblynq-call \
+        liblynq-sim \
         liblynq-network \
         liblynq-sms \	
 	"
diff --git a/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/liblynq-sim/liblynq-sim.bb b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/liblynq-sim/liblynq-sim.bb
new file mode 100755
index 0000000..245b5f8
--- /dev/null
+++ b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/liblynq-sim/liblynq-sim.bb
@@ -0,0 +1,60 @@
+inherit externalsrc package
+
+DESCRIPTION = "lynq sim"
+LICENSE = "MobileTekProprietary"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=e1696b147d49d491bcb4da1a57173fff"
+DEPENDS += "libpal gstreamer1.0 glib-2.0 libapn liblynq-log libvendor-ril liblynq-shm libbinder"
+inherit workonsrc
+WORKONSRC = "${TOPDIR}/../src/lynq/lib/liblynq-sim/"
+
+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/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 () {
+	if [ "${PACKAGE_ARCH}" = "cortexa7hf-vfp-vfpv4-neon" ]; then
+		oe_runmake all ROOT=${STAGING_DIR_HOST} OFLAGS="--sysroot=${STAGING_DIR_HOST} -Os -mfpu=neon-vfpv4 -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 -mfpu=neon-vfpv4 -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 -mfpu=neon-vfpv4 -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}/
+    fi 
+}
+
+addtask bachclean
+do_bachclean () {
+    oe_runmake clean
+}
diff --git a/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/mobiletek-tester-rdit/mobiletek-tester-rdit.bb b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/mobiletek-tester-rdit/mobiletek-tester-rdit.bb
index c6ae48a..21ae078 100755
--- a/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/mobiletek-tester-rdit/mobiletek-tester-rdit.bb
+++ b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/mobiletek-tester-rdit/mobiletek-tester-rdit.bb
@@ -4,7 +4,7 @@
 LICENSE = "MobileTekProprietary"
 LICENSE = "CLOSED"
 LIC_FILES_CHKSUM = "file://LICENSE;md5=b1e07e8d88e26263e71d3a9e2aa9a2ff"
-DEPENDS += "liblynq-call liblynq-sms liblynq-network"
+DEPENDS += "liblynq-call liblynq-sms liblynq-network liblynq-sim"
 inherit workonsrc
 WORKONSRC = "${TOPDIR}/../src/lynq/packages/apps/Mobiletek_Tester_RDIT"
 
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
index f647e4e..0602326 100755
--- 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
@@ -11,5 +11,6 @@
     liblynq-call \
     liblynq-network \
     liblynq-sms \
+    liblynq-sim \
     "
 
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-sim/LICENSE b/cap/zx297520v3/src/lynq/lib/liblynq-sim/LICENSE
new file mode 100755
index 0000000..77f59ed
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-sim/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-sim/include/lynq_sim.h b/cap/zx297520v3/src/lynq/lib/liblynq-sim/include/lynq_sim.h
new file mode 100755
index 0000000..325d52f
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-sim/include/lynq_sim.h
@@ -0,0 +1,94 @@
+/*============================================================================= 
+#     FileName: lynq_sim.h
+#     Desc: about SIMAPI
+#     Author: lei 
+#     Version: V2.0
+#     LastChange: 2023-03-13 
+#     History: 
+# If you need to use any API under lynq_sim, you must first call the lynq_sim_init() function to initialize these functions.
+=============================================================================*/
+#ifndef __LYNQ_SIM__
+#define __LYNQ_SIM__
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int lynq_get_sim_status(int *card_status);
+int lynq_get_imsi(char buf[]);
+int lynq_sim_init(int utoken);
+int lynq_sim_deinit(void);
+int lynq_enable_pin(char pin[]);
+int lynq_disable_pin(char pin[]);
+int lynq_get_iccid(char buf[]);
+int lynq_query_pin_lock(char *pin,int buf[]);
+int lynq_verify_pin(char *pin);
+int lynq_change_pin(char *old_pin, char *new_pin);
+int lynq_unlock_pin(char *puk, char *pin);
+int lynq_query_phone_number(char buf[]);
+int lynq_switch_card(int slot);
+int lynq_screen(int num);
+int lynq_get_imei(char buf[]);
+int lynq_get_imei_and_sv(char imei[],char sv[]);
+
+/**
+ * @brief                   Request SIM I/O operation.
+ *                          This is similar to the TS 27.007 "restricted SIM" operation
+ *                          where it assumes all of the EF selection will be done by the callee.
+ * @param  list             type: [IN] list[0]:one of the commands listed for TS 27.007 +CRSM.(command)
+ *                          type: [IN] list[1]:EF id(fileid)
+ *                          type: [IN] list[2]:offset(p1)
+ *                          type: [IN] list[3]:offset(p2)
+ *                          type: [IN] list[4]:response len,sometimes needn't care(p3)
+ * @param  path             type: [IN] "pathid" from TS 27.007 +CRSM command.
+                            type: [IN] Path is in hex asciii format eg "7f205f70"
+                            type: [IN] Path must always be provided.
+ * @param  data             type: [IN] May be NULL
+ * @param  pin2             type: [IN] May be NULL
+ * @param  aidPtr           type: [IN] AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value.
+ * @param  sw               type: [OUT] 
+ * @param  simResponse      type: [OUT] response
+ * @return int
+ */
+int lynq_req_sim_io(int list[5], char *path, char *data, char *pin2, char *aidPtr, int sw[2], char *simResponse);
+
+/**
+ * @brief 
+ * @param  options         type: [IN] [options] define whether you want to halt, power-off, or reboot the machine.May be NULL
+ * @param  time            type: [IN] [time] specifies when you want the shutdown to perform.May be NULL
+ * @param  message         type: [IN] [message] adds a message that announces the shutdown.May be NULL
+ * @return int 
+ */
+int lynq_shutdown(char options[], char time[], char message[]);
+
+/**
+ * @brief                   get currnet version of mobiletek
+ * @param  buf              type: [out] My Param doc
+ * @return int 
+ */
+int lynq_get_version(char buf[]);
+
+/**
+ * @brief sim power on/off
+ * 
+ */
+int lynq_sim_power(int mode);
+
+/**
+ * @brief reset modem
+ * 
+ */
+int lynq_reset_modem(void);
+
+/**
+ * @brief factory test to both radio on/off
+ * 
+ */
+int lynq_factory_radio_state(int num);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-sim/makefile b/cap/zx297520v3/src/lynq/lib/liblynq-sim/makefile
new file mode 100755
index 0000000..5e40ec5
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-sim/makefile
@@ -0,0 +1,78 @@
+SHELL = /bin/sh
+RM = rm -f
+
+LOCAL_CFLAGS := -Wall \
+                -std=c++11 \
+                -g -Os \
+                -flto \
+                -DRIL_SHLIB \
+                -DATCI_PARSE \
+                -fPIC \
+                -DKEEP_ALIVE \
+                -DECALL_SUPPORT \
+                -fpermissive \
+
+
+ifeq ($(strip $(TARGET_PLATFORM)), T106)
+LOCAL_CFLAGS += -DBINDER_IPC_32BIT=1 -DHAVE_ENDIAN_H -DHAVE_PTHREADS -DHAVE_SYS_UIO_H -DHAVE_POSIX_FILEMAP -DHAVE_STRLCPY -DHAVE_PRCTL -DHAVE_MEMSET16 -DHAVE_MEMSET32 -DANDROID_SMP=0
+endif
+
+$(warning ################# lynq sim ROOT: $(ROOT),includedir:$(includedir))
+LOCAL_PATH   = .
+
+LOCAL_C_INCLUDES = \
+  -I. \
+  -I$(LOCAL_PATH)/include \
+  -I$(ROOT)$(includedir)/vendor-ril \
+  -I$(ROOT)$(includedir)/logger \
+  -I$(ROOT)$(includedir)/liblog \
+  -I$(ROOT)$(includedir)/lynq_shm \
+
+
+LOCAL_LIBS := \
+    -L. \
+    -ldl \
+    -lstdc++ \
+    -llog \
+    -lcutils \
+    -lutils \
+    -lbinder \
+    -lpthread \
+    -llynq-log \
+    -llynq-shm \
+
+SOURCES = $(wildcard *.c wildcard *.h src/*.cpp)
+
+EXECUTABLE = liblynq-sim.so
+
+OBJECTS=$(SOURCES:.cpp=.o)
+
+
+.PHONY: build clean install pack_rootfs 
+
+all: build
+$(EXECUTABLE): $(OBJECTS)
+	$(CXX) -shared -Wl,--no-undefined $(OBJECTS) $(LOCAL_LIBS) $(LOCAL_CFLAGS) $(LOCAL_C_INCLUDES) -o $@
+
+%.o : %.cpp
+	$(CXX) $(LOCAL_C_INCLUDES) $(LOCAL_CFLAGS) $(LOCAL_LIBS) -o $@ -c $<
+
+build:  $(EXECUTABLE)
+	$(warning ########## build $(EXECUTABLE)  ##########)
+
+install:
+	mkdir -p $(ROOT)$(base_libdir)/
+	install $(EXECUTABLE) $(ROOT)$(base_libdir)/
+	mkdir -p $(ROOT)$(includedir)/$(NAME)/sdk
+pack_rootfs:
+	mkdir -p $(PACK_INITRAMFS_TO)$(base_libdir)/
+	cp -af $(EXECUTABLE) $(PACK_INITRAMFS_TO)$(base_libdir)/
+	$(CROSS)strip $(PACK_INITRAMFS_TO)$(base_libdir)/$(EXECUTABLE)
+	mkdir -p $(PACK_TO)$(base_libdir)/
+	cp -af $(EXECUTABLE) $(PACK_TO)$(base_libdir)/
+	$(CROSS)strip $(PACK_TO)$(base_libdir)/$(EXECUTABLE)
+
+.PHONY: clean
+clean:
+	$(RM) $(OBJECTS) $(EXECUTABLE)
+	-find . -name "*.o" -delete
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-sim/src/lynq_sim.cpp b/cap/zx297520v3/src/lynq/lib/liblynq-sim/src/lynq_sim.cpp
new file mode 100755
index 0000000..433764a
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-sim/src/lynq_sim.cpp
@@ -0,0 +1,876 @@
+/*============================================================================= 
+#     FileName: lynq_sim.cpp
+#     Desc: about SIM API
+#     Author: mobiletek 
+#     Version: V1.0
+#     LastChange: 2021-12-29 
+#     History: 
+=============================================================================*/
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <string.h>
+#include <unistd.h>
+#include <binder/Parcel.h>
+#include <log/log.h>
+#include <cutils/jstring.h>
+#include <pthread.h>
+#include <vendor-ril/telephony/ril.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <errno.h> /*add for get recvfrom errorid on 20220921*/
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "lynq_sim.h"
+#define MAX_BUF 20
+#define MAX_NUM 80
+#define LYNQ_REQUEST_SET_DEFAULT_SIM_ALL 8008
+#define LYNQ_REQUEST_CHANGE_SCREEN_STATE 8014 /*add for two sim suspend on 20220919*/
+#define LYNQ_REQUEST_CHANGE_RADIO 8015
+#define MAX_LEN 1024*8
+#define MAX_NUM 10
+#define LOG_TAG "LYNQ_SIM"
+#define FLAG_TESS 0
+using ::android::Parcel;
+#define DEST_PORT 8088
+#define DSET_IP_ADDRESS  "127.0.0.1"
+
+typedef struct{
+    int uToken;
+    int request;
+    int paramLen;
+    char param[MAX_LEN];
+}lynq_client_t;
+
+/* socket文件描述符 */ 
+int len_addr_serv;
+struct sockaddr_in addr_serv;
+static int sock_fd = 0;
+int Global_uToken = 0;
+static pthread_mutex_t g_lynq_sim_sendto_mutex;
+/**
+ * @brief mark call initialization state
+ * 0: deinit state
+ * 1: init state
+ */
+int g_lynq_sim_init_flag = 0;
+
+/**
+ * @brief lynq_req_sim_io need to send request
+ */
+char data_buf[32] = {0};
+char pin2_buf[32] = {0};
+char aidPtr_buf[32] = {0};
+
+/**
+ * @brief lynq_shutdown need
+ */
+char options_buf[32] = {0};
+char time_buf[32] = {0};
+char message_buf[32] = {0};
+
+typedef struct{
+    int resp_type;
+    int token;
+    int request;
+    int slot_id;
+    int error;
+}lynq_resp_t;
+
+#define RESULT_OK (0)
+#define RESULT_ERROR (-1)
+
+typedef enum{
+    /*base abnormal*/
+    LYNQ_E_PARAMETER_ANONALY=7000,
+    LYNQ_E_SEND_REQUEST_FAIL=7001,
+    LYNQ_E_GET_HEAD_ERROR=7002,
+    LYNQ_E_INNER_ERROR=7100,
+    LYNQ_E_MALLOC_ERROR=7101,
+    /**/
+    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,
+     /*Invalid id anomaly*/
+    LYNQ_E_INVALID_ID_ANONALY=9002,
+#ifdef ECALL_SUPPORT
+    LYNQ_E_ECALL_BEING_RUNNING =9003,
+    LYNQ_E_ECALL_MSD_LENGTH_ERROR =9004,
+    LYNQ_E_ECALL_DAILING_NO_ANSWER =9005,
+#endif
+}LYNQ_E;
+
+/**@brief print solicied response msg's head information
+* @param head [IN]: head information
+* @return none
+*/
+void PrintHeader(lynq_resp_t& head)
+{
+    RLOGD("resp_type=%d,token=%d,request=%d,slot_id=%d,error_code=%d",head.resp_type,head.token,head.request,head.slot_id,head.error);
+}
+
+int GetHeader(Parcel* &p, lynq_resp_t& head, int request_id)
+{
+    RLOGD("get header");
+    if(p->dataAvail() > 0)
+    {
+        p->readInt32(&(head.resp_type));
+        p->readInt32(&(head.token));
+        p->readInt32(&(head.request));
+        RLOGD("%s %d", __FUNCTION__, head.request);
+        p->readInt32(&(head.slot_id));
+        p->readInt32(&(head.error));
+        PrintHeader(head);
+        return head.error;
+    }
+    else
+    {
+        return RESULT_ERROR;
+    }
+}
+
+int lynq_send_common_request(Parcel* p, int request_id, int argc, int cnt, const char* format,...)
+{
+    lynq_client_t client;
+    int ret;
+    int send_num;
+    int recv_num;
+    char res_data[MAX_LEN] = {0};
+    client.uToken = Global_uToken;
+    if(request_id == RIL_REQUEST_SCREEN_STATE)
+    {
+        client.request = LYNQ_REQUEST_CHANGE_SCREEN_STATE;
+    }
+    else if(request_id == RIL_REQUEST_RADIO_POWER)
+    {
+        client.request = LYNQ_REQUEST_CHANGE_RADIO;
+    }
+    else
+    {
+        client.request = request_id;
+    }
+    client.paramLen = argc;
+    bzero(client.param,MAX_LEN);
+    if(argc!=0)
+    {
+        va_list args;
+        va_start(args, format);
+        vsnprintf(client.param, MAX_LEN, format, args);
+        va_end(args);
+    }
+    RLOGD("uToken=%d,request=%d,paralen=%d,param=%s",client.uToken,client.request,client.paramLen,client.param);
+    pthread_mutex_lock(&g_lynq_sim_sendto_mutex);
+    send_num = sendto(sock_fd,&client,sizeof(client),0,(struct sockaddr *)&addr_serv,len_addr_serv);
+    if(send_num <= 0)
+    {
+        RLOGD("send request fail, send num is %d", send_num);
+        pthread_mutex_unlock(&g_lynq_sim_sendto_mutex);
+        return LYNQ_E_SEND_REQUEST_FAIL;
+    }
+    lynq_resp_t head;
+    head.request = -1;
+    for(int i = 0; i < cnt;)
+    {
+        recv_num = recvfrom(sock_fd,res_data,sizeof(char)*MAX_LEN, 0, (struct sockaddr *)&addr_serv,(socklen_t*)&len_addr_serv);
+        if(recv_num <= 0)
+        {
+            RLOGD("recv request fail, recv num is %d", recv_num);
+            pthread_mutex_unlock(&g_lynq_sim_sendto_mutex);
+            return recv_num;
+        }
+        p->setData((uint8_t *)res_data,sizeof(char)*recv_num);
+        p->setDataPosition(0);
+        ret=GetHeader(p,head,request_id);
+        if(ret!=0)
+        {
+            RLOGD("%s %d get head error %d",__FUNCTION__,client.uToken,ret);
+            pthread_mutex_unlock(&g_lynq_sim_sendto_mutex);
+            return ret;
+        }
+        if(request_id == head.request)
+        {
+            i++;
+        }
+    }
+    pthread_mutex_unlock(&g_lynq_sim_sendto_mutex);
+    return ret;
+}
+
+int lynq_sim_init(int utoken){
+    if(g_lynq_sim_init_flag == 1)
+    {
+        RLOGD("lynq_sim_init  failed");
+        return -1;
+    }
+    g_lynq_sim_init_flag = 1;
+    if(utoken < 0){
+        return -1;
+    }
+    Global_uToken = utoken;
+    sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
+    if (-1 == sock_fd)
+    {
+        return sock_fd;
+    }
+    struct timeval timeOut;
+    timeOut.tv_sec = 60;
+    timeOut.tv_usec = 0;
+    if (setsockopt(sock_fd, SOL_SOCKET, SO_RCVTIMEO, &timeOut, sizeof(timeOut)) < 0) 
+    {
+        RLOGD("time out setting failed\n"); 
+        return -1;
+    }
+    /* 设置address */  
+    memset(&addr_serv, 0, sizeof(addr_serv));  
+    addr_serv.sin_family = AF_INET;  
+    addr_serv.sin_addr.s_addr = inet_addr(DSET_IP_ADDRESS);  
+    addr_serv.sin_port = htons(DEST_PORT);  
+    len_addr_serv = sizeof(addr_serv);  
+    /*test*/
+    return 0;
+}
+
+int lynq_sim_deinit(void){
+    if(g_lynq_sim_init_flag == 0)
+    {
+        RLOGD("lynq_sim_deinit  failed");
+        return -1;
+    }
+    g_lynq_sim_init_flag = 0;
+    close(sock_fd);
+    return 0;
+}
+
+static char * lynqStrdupReadString(Parcel &p) {
+    size_t stringlen;
+    const char16_t *s16;
+
+    s16 = p.readString16Inplace(&stringlen);
+    return strndup16to8(s16, stringlen);
+}
+
+/*If you need to use any API under lynq_sim, you mustfirst call the lynq_sim_init() function to initialize these functions.*/
+int lynq_get_sim_status(int *card_status)
+{   
+    if(g_lynq_sim_init_flag == 0)
+    {
+        return -1;
+    }
+    Parcel p;
+    int res = lynq_send_common_request(&p,RIL_REQUEST_GET_SIM_STATUS,0,1,"");
+    if(res != 0)
+    {
+        RLOGD("function %s execute error", __FUNCTION__);
+        return res;
+    }
+    p.readInt32(card_status);
+    return res;
+}
+
+int lynq_get_imsi(char buf[])
+{
+    if(g_lynq_sim_init_flag == 0)
+    {
+        return -1;
+    }
+    Parcel p;
+    int res = lynq_send_common_request(&p,RIL_REQUEST_GET_IMSI,0,1,"");
+    if(res != 0)
+    {
+        RLOGD("function %s execute error", __FUNCTION__);
+        return res;
+    }
+    char * test = lynqStrdupReadString(p);
+    memcpy(buf, test, strlen(test));
+    free(test);
+    return res;
+}
+
+
+/*add by lei*/
+
+int lynq_get_iccid(char buf[]){
+    if(g_lynq_sim_init_flag == 0)
+    {
+        return -1;
+    }
+    Parcel p;
+    int res = lynq_send_common_request(&p,RIL_REQUEST_QUERY_ICCID,0,1,"");
+    if(res != 0)
+    {
+        RLOGD("function %s execute error", __FUNCTION__);
+        return res;
+    }
+    char * test = lynqStrdupReadString(p);
+    memcpy(buf, test, strlen(test));
+    free(test);
+    return res;
+}
+
+int lynq_enable_pin(char *pin){
+    if(g_lynq_sim_init_flag == 0)
+    {
+        return -1;
+    }
+    Parcel p;
+    int res = lynq_send_common_request(&p,RIL_REQUEST_SET_FACILITY_LOCK,4,1,"%s %s %s %s\n", "SC", pin, "11", "1");
+    if(res != 0)
+    {
+        RLOGD("function %s execute error", __FUNCTION__);
+        return res;
+    }
+    return res;
+}
+
+int lynq_sim_power(int mode)
+{
+    if(g_lynq_sim_init_flag == 0)
+    {
+        return -1;
+    }
+    Parcel p;
+    int res = lynq_send_common_request(&p,RIL_REQUEST_OEM_HOOK_RAW,1,1,"%s%d", "AT+ESIMPOWER=", mode);
+    if(res != 0)
+    {
+        RLOGD("function %s execute error", __FUNCTION__);
+        return res;
+    }
+    return res;
+}
+
+int lynq_disable_pin(char *pin){
+    if(g_lynq_sim_init_flag == 0)
+    {
+        return -1;
+    }
+    Parcel p;
+    int res = lynq_send_common_request(&p,RIL_REQUEST_SET_FACILITY_LOCK,4,1,"%s %s %s %s\n", "SC", pin, "11", "0");
+    if(res != 0)
+    {
+        RLOGD("function %s execute error", __FUNCTION__);
+        return res;
+    }
+    return res;
+}
+
+int lynq_query_pin_lock(char *pin,int buf[]){
+    if(g_lynq_sim_init_flag == 0)
+    {
+        return -1;
+    }
+    Parcel p;
+    int res = lynq_send_common_request(&p,RIL_REQUEST_QUERY_FACILITY_LOCK,3,1,"%s %s %s\n", "SC", pin, "11");
+    if(res != 0)
+    {
+        RLOGD("function %s execute error", __FUNCTION__);
+        return res;
+    }
+    int num = -1;
+    p.readInt32(&num);
+    if(num > 0)
+    {
+        int *test = (int *)calloc(num, sizeof(int));
+        for(int i =0; i <num; i++){
+            p.readInt32(&test[i]);
+            buf[i] = test[i];
+        }
+        free(test);
+    }
+    return res;
+}
+
+int lynq_verify_pin(char *pin){
+    if(g_lynq_sim_init_flag == 0)
+    {
+        return -1;
+    }
+    Parcel p;
+    int res = lynq_send_common_request(&p,RIL_REQUEST_ENTER_SIM_PIN,1,1,"%s\n", pin);
+    if(res != 0)
+    {
+        RLOGD("function %s execute error", __FUNCTION__);
+        return res;
+    }
+    return res;
+}
+
+int lynq_change_pin(char *old_pin, char *new_pin){
+    if(g_lynq_sim_init_flag == 0)
+    {
+        return -1;
+    }
+    int res = -1;
+    if(old_pin == NULL || new_pin == NULL)
+        return res;
+    if(!strlen(new_pin))
+        return res;
+    if(!strlen(old_pin))
+        return res;
+    Parcel p;
+    res = lynq_send_common_request(&p,RIL_REQUEST_CHANGE_SIM_PIN,2,1,"%s %s\n", old_pin, new_pin);
+    if(res != 0)
+    {
+        RLOGD("function %s execute error", __FUNCTION__);
+        return res;
+    }
+    return res;
+}
+
+int lynq_unlock_pin(char *puk, char *pin){
+    if(g_lynq_sim_init_flag == 0)
+    {
+        return -1;
+    }
+    if(puk == NULL || pin == NULL)
+        return -1;
+    Parcel p;
+    int res = lynq_send_common_request(&p,RIL_REQUEST_ENTER_SIM_PUK,2,1,"%s %s\n", puk, pin);
+    if(res != 0)
+    {
+        RLOGD("function %s execute error", __FUNCTION__);
+        return res;
+    }
+    return res;
+}
+
+static void delete_char(char str[],char target){
+    if(str == NULL){
+        return;
+    }
+    int i,j;
+    for(i=j=0;str[i]!='\0';i++){
+        if(str[i]!=target){
+            str[j++]=str[i];
+        }
+    }
+    str[j]='\0';
+} 
+
+static int parse_param(char *cmd, char **argv, char buf[]){
+    if(cmd == NULL || argv == NULL || buf == NULL){
+        return -1;
+    }
+    if(strstr(cmd,"ERROR")){
+        return 3;
+    }
+    else{
+        int argc = 0;
+        char *token;
+        token = strtok(cmd, ",");
+        if(token == NULL)
+        {
+            return 9001;
+        }
+        if(strstr(token, "CNUM"))
+        {
+            char *string;
+            while (token != NULL)
+            {
+                if(argc == 5)
+                {
+                    if(NULL == argv[1])
+                    {
+                        return 9002;
+                    }
+                    int lengh = strlen(argv[1]);
+                    memcpy(buf, argv[1], lengh);
+                    delete_char(buf, '"');
+                    RLOGD("too many phone number return\n");
+                    return 0;
+                }
+                string = token;
+                argv[argc++] = string;
+                token = strtok(NULL, ",");
+            }
+            if(NULL == argv[1])
+            {
+                return 9001;
+            }
+            int lengh = strlen(argv[1]);
+            memcpy(buf, argv[1], lengh);
+            delete_char(buf, '"');
+            return 0;
+        }
+        return 9001;
+    }
+}
+
+int lynq_query_phone_number(char buf[]){
+    if(g_lynq_sim_init_flag == 0)
+    {
+        return -1;
+    }
+    Parcel p;
+    int res = lynq_send_common_request(&p,RIL_REQUEST_OEM_HOOK_RAW,1,1,"%s\n", "AT+CNUM");
+    if(res != 0)
+    {
+        RLOGD("function %s execute error", __FUNCTION__);
+        return res;
+    }
+    int num = -1;
+    p.readInt32(&num);
+    char test[128] = {0};
+    char *argv[5] = {0};
+    if(num != -1)
+    {
+        p.read(test, num);
+        num = parse_param(test, argv, buf);
+        return num;
+    }
+    return res;
+}
+
+int lynq_get_imei(char buf[])
+{
+    if(g_lynq_sim_init_flag == 0)
+    {
+        return -1;
+    }
+    Parcel p;
+    int res = lynq_send_common_request(&p,RIL_REQUEST_DEVICE_IDENTITY,0,1,"");
+    if(res != 0)
+    {
+        RLOGD("function %s execute error", __FUNCTION__);
+        return res;
+    }
+    int num = 0;
+    p.readInt32(&num);
+    char * test = lynqStrdupReadString(p);
+    memcpy(buf, test, strlen(test));
+    free(test);
+    return res;
+}
+
+int lynq_get_imei_and_sv(char imei[],char sv[])
+{
+    if(g_lynq_sim_init_flag == 0)
+    {
+        return -1;
+    }
+    Parcel p;
+    int res = lynq_send_common_request(&p,RIL_REQUEST_DEVICE_IDENTITY,0,1,"");
+    if(res != 0)
+    {
+        RLOGD("function %s execute error", __FUNCTION__);
+        return res;
+    }
+    int num = 0;
+    p.readInt32(&num);
+    if(num<2)
+    {
+        RLOGD("%s num %d error, should greater than 1",__func__,num);
+        return -1;
+    }
+    char *resp[2]={NULL,NULL};
+    int i;
+    for(i=0;i<2;i++)
+    {
+        resp[i]= lynqStrdupReadString(p);
+        if(resp[i]==NULL)
+        {
+            break;
+        }
+    }
+    if(i==2){
+        memcpy(imei, resp[0], strlen(resp[0])+1);
+        memcpy(sv, resp[1], strlen(resp[1])+1);
+    }
+    else
+    {
+        RLOGD("%s resp[%d] is null",__func__,i);
+    }
+    for(i=0;i<2;i++)
+    {
+        if(resp[i]!=NULL)
+        {
+            free(resp[i]);
+        }
+    }
+    return i==2? 0:-1;
+
+}
+
+static int judge(int slot){
+    switch(slot){
+        case 0:
+            return -1;
+        case 1:
+            return -1;
+    }
+    return 0;
+}
+
+int lynq_switch_card(int slot){
+    if(g_lynq_sim_init_flag == 0)
+    {
+        return -1;
+    }
+    if(!judge(slot))
+        return -1;
+    int send_num = 0;
+    lynq_client_t client_t;
+    client_t.request = LYNQ_REQUEST_SET_DEFAULT_SIM_ALL;
+    client_t.paramLen = 1;
+    client_t.uToken = Global_uToken;
+    sprintf(client_t.param, "%d\n", slot);
+    pthread_mutex_lock(&g_lynq_sim_sendto_mutex);
+    send_num = sendto(sock_fd, &client_t, sizeof(client_t), 0, (struct sockaddr *)&addr_serv, len_addr_serv); //because ril of id = -1
+    if(send_num < 0)  
+    {  
+        RLOGD("function %s sendto error:", __FUNCTION__);  
+        return send_num;
+    }
+    pthread_mutex_unlock(&g_lynq_sim_sendto_mutex);
+    return 0;
+}
+/**@breif    change screen state
+*param       num type: [IN]  screen_state,0:close,1:open
+*param       ret type: [OUT] result,0:success,other:fail
+*return int
+*/
+int lynq_screen(int num){
+    if(g_lynq_sim_init_flag == 0)
+    {
+        return -1;
+    }
+    if(!judge(num))
+        return -1;
+    Parcel p;
+    int res = lynq_send_common_request(&p,RIL_REQUEST_SCREEN_STATE,1,2,"%d\n",num);
+    if(res != 0)
+    {
+        RLOGD("function %s execute error", __FUNCTION__);
+        return res;
+    }
+    return res;
+}
+
+/**@breif    change screen state
+*param       num type: [IN]  screen_state,0:close,1:open
+*param       ret type: [OUT] result,0:success,other:fail
+*return int
+*/
+int lynq_factory_radio_state(int num){
+    if(g_lynq_sim_init_flag == 0)
+    {
+        return -1;
+    }
+    if(!judge(num))
+        return -1;
+    Parcel p;
+    int res = lynq_send_common_request(&p,RIL_REQUEST_RADIO_POWER,1,2,"%d\n",num);
+    if(res != 0)
+    {
+        RLOGD("function %s execute error", __FUNCTION__);
+        return res;
+    }
+    return res;
+}
+
+/**
+ * @brief                   Check whether the input is valid  for lynq_req_sim_io api
+ * @param  list             type: [IN] list[0]:one of the commands listed for TS 27.007 +CRSM.(command)
+ *                          type: [IN] list[1]:EF id(fileid)
+ *                          type: [IN] list[2]:offset(p1)
+ *                          type: [IN] list[3]:offset(p2)
+ *                          type: [IN] list[4]:response len,sometimes needn't care(p3)
+ * @param  path             type: [IN] "pathid" from TS 27.007 +CRSM command.
+                            type: [IN] Path is in hex asciii format eg "7f205f70"
+                            type: [IN] Path must always be provided.
+ * @param  data             type: [IN] May be NULL
+ * @param  pin2             type: [IN] May be NULL
+ * @param  aidPtr           type: [IN] AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value.
+ * @param  sw               type: [OUT] 
+ * @param  simResponse      type: [OUT] response
+ * @return int
+ */
+static int judge_illegal(int list[5], char *path, char *data, char *pin2, char *aidPtr, int sw[2], char *simResponse)
+{
+    if(list == NULL)
+    {
+        return -1;
+    }
+    if(path == NULL)
+    {
+        return -1;
+    }
+    if(sw == NULL){
+        return -1;
+    }
+    if(simResponse == NULL){
+        return -1;
+    }
+    if(data == NULL)
+    {
+        memcpy(data_buf, "null", 4);
+    }
+    else
+    {
+        bzero(data_buf,32);
+        memcpy(data_buf, data, strlen(data));
+    }
+    if(pin2 == NULL)
+    {
+        memcpy(pin2_buf, "null", 4);
+    }
+    else
+    {
+        bzero(pin2_buf,32);
+        memcpy(pin2_buf, data, strlen(data));
+    }
+    if(aidPtr == NULL)
+    {
+        memcpy(aidPtr_buf, "null", 4);
+    }
+    else
+    {
+        bzero(aidPtr_buf,32);
+        memcpy(aidPtr_buf, data, strlen(data));
+    }
+    return 0;
+}
+
+int lynq_req_sim_io(int list[5], char *path, char *data, char *pin2, char *aidPtr, int sw[2], char *simResponse)
+{
+    if(g_lynq_sim_init_flag == 0)
+    {
+        return -1;
+    }
+    if(judge_illegal(list, path, data, pin2, aidPtr, sw, simResponse))
+    {
+        return -1;
+    }
+    Parcel p;
+    int res = lynq_send_common_request(&p,RIL_REQUEST_SIM_IO,9,1,"%d %d %s %d %d %d %s %s %s\n", list[0], list[1], path, list[2], list[3], list[4], data_buf, pin2_buf, aidPtr_buf);
+    if(res != 0)
+    {
+        RLOGD("function %s execute error", __FUNCTION__);
+        return res;
+    }
+    p.readInt32(&sw[0]);
+    p.readInt32(&sw[1]);
+    char * test = lynqStrdupReadString(p);
+    memcpy(simResponse, test, strlen(test));
+    free(test);
+    return res;
+}
+
+static void wait_reset_mipc_response(int *response)
+{
+    usleep(500*1000);
+    int outfd = open("/data/tp",O_RDONLY);
+    if(outfd == -1){
+        RLOGD("open error");
+        return;
+    }
+    char rst[1024];
+    int s;
+    s = read(outfd,rst,sizeof(rst));
+    sscanf(rst,"%d",response);
+    usleep(1);
+    close(outfd);
+    return;
+}
+
+int lynq_reset_modem(void)
+{
+    if(g_lynq_sim_init_flag == 0)
+    {
+        return -1;
+    }
+    int ret = -1;
+    int send_num = 0;
+    lynq_client_t client_t;
+    client_t.request = RIL_REQUEST_OEM_HOOK_RAW;
+    client_t.paramLen = 1;
+    client_t.uToken = Global_uToken;
+    sprintf(client_t.param, "%s\n", "AT+LRSTMD");
+    pthread_mutex_lock(&g_lynq_sim_sendto_mutex);
+    send_num = sendto(sock_fd, &client_t, sizeof(client_t), 0, (struct sockaddr *)&addr_serv, len_addr_serv);//because response not by ril callback
+    if(send_num < 0)  
+    {  
+        RLOGD("function %s sendto error:", __FUNCTION__);
+        pthread_mutex_unlock(&g_lynq_sim_sendto_mutex);
+        return ret;
+    }
+    wait_reset_mipc_response(&ret);
+    pthread_mutex_unlock(&g_lynq_sim_sendto_mutex);
+    RLOGD("function %s ret %d",__FUNCTION__, ret);
+    return ret;
+}
+
+/**
+ * @brief                   handle shutdown buf
+ * @param  options          type: [IN]My Param doc
+ * @param  time             type: [IN]My Param doc
+ * @param  message          type: [IN]My Param doc
+ */
+static void handle_shutdown_buf(char options[], char time[], char message[])
+{
+    if(NULL == options)
+    {
+        bzero(options_buf, 32);
+        memcpy(options_buf," ", 1);
+    }
+    else
+    {
+        memcpy(options_buf,options, strlen(options));
+    }
+    if(NULL == time)
+    {
+        bzero(time_buf, 32);
+        memcpy(time_buf," ", 1);
+    }
+    else
+    {
+        memcpy(time_buf, time, strlen(time));
+    }
+    if(NULL == message)
+    {
+        bzero(message_buf, 32);
+        memcpy(message_buf," ", 1);
+    }
+    else
+    {
+        memcpy(message_buf, message, strlen(message));
+    }
+}
+
+int lynq_shutdown(char options[], char time[], char message[])
+{
+    char cmd[128] = {0};
+    handle_shutdown_buf(options, time, message);
+    sprintf(cmd, "%s %s %s %s", "shutdown", options_buf, time_buf, message_buf);
+    system(cmd);
+    return 0;
+}
+
+int lynq_get_version(char buf[])
+{
+    FILE * fp;
+    char buffer[128];
+    sprintf(buffer, "%s", "uci get lynq_uci_ro.lynq_version.LYNQ_SW_VERSION");
+    fp = popen(buffer, "r");
+    fgets(buffer, sizeof(buffer), fp);
+    memcpy(buf, buffer, strlen(buffer));
+    buf[strlen(buffer)] = '\0';
+    pclose(fp);
+    return 0;
+}
+