Add mbtk_ril V2 (Default close)
Change-Id: Iaa5921fd74aeeb394771110f0cec7aa7742dc83a
diff --git a/mbtk/mbtk_rild_v2/Makefile b/mbtk/mbtk_rild_v2/Makefile
new file mode 100755
index 0000000..5df9e1c
--- /dev/null
+++ b/mbtk/mbtk_rild_v2/Makefile
@@ -0,0 +1,47 @@
+BUILD_ROOT = $(shell pwd)/..
+include $(BUILD_ROOT)/Make.defines
+
+LOCAL_PATH=$(BUILD_ROOT)/mbtk_rild_v2
+
+INC_DIR += \
+ -I$(LOCAL_PATH)/inc \
+ -I$(BUILD_ROOT)/libmbtk_ril_v2/inc
+
+LIB_DIR +=
+
+LIBS += -lmbtk_lib -lmbtk_net -lmbtk_ril -lrilutil -lprop2uci -lmtel -laudio-apu -lcutils -ltinyalsa -lacm
+
+CFLAGS +=
+
+DEFINE +=
+
+MY_FILES_PATH:=$(LOCAL_PATH)/src
+#ifeq ($(CONFIG_MBTK_QL_SUPPORT),y)
+#MY_FILES_PATH += $(LOCAL_PATH)/ql
+#endif
+
+#ifeq ($(CONFIG_MBTK_PLATFORM),linux)
+#MY_FILES_PATH += $(LOCAL_PATH)/platform/linux
+#endif
+
+LOCAL_SRC_FILES = $(wildcard src/*.c) $(wildcard src/*.cpp)
+OBJS = $(patsubst %.c, %.o, $(patsubst %.cpp, %.o, $(LOCAL_SRC_FILES)))
+$(info OBJS = $(OBJS))
+
+dtarget := $(OUT_DIR)/bin/mbtk_rild
+
+all: $(dtarget)
+
+$(dtarget): $(OBJS)
+ @echo " BIN $@"
+ $(CC) $(CFLAGS) $(LIB_DIR) $(LIBS) $(OBJS) -o $@
+
+%.o:%.c
+ $(CC) $(CFLAGS) $(INC_DIR) $(DEFINE) -c $< -o $@
+
+%.o:%.cpp
+ $(CC) $(CFLAGS) $(INC_DIR) $(DEFINE) -c $< -o $@
+
+clean:
+ rm -f $(OBJS) $(dtarget)
+
diff --git a/mbtk/mbtk_rild_v2/inc/at_tok.h b/mbtk/mbtk_rild_v2/inc/at_tok.h
new file mode 100755
index 0000000..a9725c0
--- /dev/null
+++ b/mbtk/mbtk_rild_v2/inc/at_tok.h
@@ -0,0 +1,31 @@
+/* //device/system/reference-ril/at_tok.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 AT_TOK_H
+#define AT_TOK_H 1
+
+int at_tok_start(char **p_cur);
+int at_tok_nextint(char **p_cur, int *p_out);
+int at_tok_nexthexint(char **p_cur, int *p_out);
+
+int at_tok_nextbool(char **p_cur, char *p_out);
+int at_tok_nextstr(char **p_cur, char **out);
+
+int at_tok_hasmore(char **p_cur);
+
+#endif /*AT_TOK_H */
+
diff --git a/mbtk/mbtk_rild_v2/inc/atchannel.h b/mbtk/mbtk_rild_v2/inc/atchannel.h
new file mode 100755
index 0000000..b97cb27
--- /dev/null
+++ b/mbtk/mbtk_rild_v2/inc/atchannel.h
@@ -0,0 +1,148 @@
+/* //device/system/reference-ril/atchannel.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 ATCHANNEL_H
+#define ATCHANNEL_H 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include "mbtk_type.h"
+
+/* define AT_DEBUG to send AT traffic to /tmp/radio-at.log" */
+#define AT_DEBUG 0
+
+#if AT_DEBUG
+extern void AT_DUMP(const char* prefix, const char* buff, int len);
+#else
+#define AT_DUMP(prefix,buff,len) do{}while(0)
+#endif
+
+#define AT_ERROR_GENERIC (-1)
+#define AT_ERROR_COMMAND_PENDING (-2)
+#define AT_ERROR_CHANNEL_CLOSED (-3)
+#define AT_ERROR_TIMEOUT (-4)
+#define AT_ERROR_INVALID_THREAD (-5) /* AT commands may not be issued from
+ reader thread (or unsolicited response
+ callback */
+#define AT_ERROR_INVALID_RESPONSE (-6) /* eg an at_send_command_singleline that
+ did not get back an intermediate
+ response */
+#define AT_ERROR_TIMEOUT_CLOSE (-7)
+
+
+typedef enum
+{
+ NO_RESULT, /* no intermediate response expected */
+ NUMERIC, /* a single intermediate response starting with a 0-9 */
+ SINGLELINE, /* a single intermediate response starting with a prefix */
+ MULTILINE /* multiple line intermediate response
+ starting with a prefix */
+} ATCommandType;
+
+/** a singly-lined list of intermediate responses */
+typedef struct ATLine
+{
+ struct ATLine *p_next;
+ char *line;
+} ATLine;
+
+/** Free this with at_response_free() */
+typedef struct
+{
+ int success; /* true if final response indicates
+ success (eg "OK") */
+ char *finalResponse; /* eg OK, ERROR */
+ ATLine *p_intermediates; /* any intermediate responses */
+} ATResponse;
+
+typedef enum
+{
+ RIL_AT_STATE_CLOSED = 0,
+ RIL_AT_STATE_OPENED,
+ RIL_AT_STATE_CONNECTED,
+ RIL_AT_STATE_READY,
+ RIL_AT_STATE_BUSY
+} mbtk_ril_at_state_enum;
+
+/**
+ * a user-provided unsolicited response handler function
+ * this will be called from the reader thread, so do not block
+ * "s" is the line, and "sms_pdu" is either NULL or the PDU response
+ * for multi-line TS 27.005 SMS PDU responses (eg +CMT:)
+ */
+typedef void (*ATUnsolHandler)(const char *s, const char *sms_pdu);
+
+int at_open(int at_fd, int uart_fd, ATUnsolHandler h);
+void at_close();
+
+/* This callback is invoked on the command thread.
+ You should reset or handshake here to avoid getting out of sync */
+void at_set_on_timeout(void (*onTimeout)(void));
+/* This callback is invoked on the reader thread (like ATUnsolHandler)
+ when the input stream closes before you call at_close
+ (not when you call at_close())
+ You should still call at_close()
+ It may also be invoked immediately from the current thread if the read
+ channel is already closed */
+void at_set_on_reader_closed(void (*onClose)(void));
+
+int at_send_command_singleline (const char *command,
+ const char *responsePrefix,
+ ATResponse **pp_outResponse);
+int at_send_command_singleline_with_timeout (const char *command,
+ const char *responsePrefix,
+ ATResponse **pp_outResponse,long long timeoutMsec);
+
+int at_send_command_numeric (const char *command,
+ ATResponse **pp_outResponse);
+
+int at_send_command_multiline (const char *command,
+ const char *responsePrefix,
+ ATResponse **pp_outResponse);
+
+
+int at_handshake();
+
+int at_send_command (const char *command, ATResponse **pp_outResponse);
+
+int at_send_command_sms (const char *command, const char *pdu,
+ const char *responsePrefix,
+ ATResponse **pp_outResponse);
+
+void at_response_free(ATResponse *p_response);
+
+typedef enum
+{
+ CME_ERROR_NON_CME = -1,
+ CME_SUCCESS = 0,
+ CME_SIM_NOT_INSERTED = 10,
+ CME_ERROR_UNKNOWN
+} AT_CME_Error;
+
+AT_CME_Error at_get_cme_error(const ATResponse *p_response);
+
+mbtk_ril_at_state_enum at_state_get();
+void at_state_set(mbtk_ril_at_state_enum state);
+bool at_rsp_check(ATResponse *p_response);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*ATCHANNEL_H*/
+
diff --git a/mbtk/mbtk_rild_v2/inc/ril_info.h b/mbtk/mbtk_rild_v2/inc/ril_info.h
new file mode 100755
index 0000000..896a73c
--- /dev/null
+++ b/mbtk/mbtk_rild_v2/inc/ril_info.h
@@ -0,0 +1,124 @@
+/*
+* ril_info.h
+*
+* MBTK Ril information header.
+*
+* Author : lb
+* Date : 2024/8/6 10:53:08
+*/
+#ifndef _RIL_INFO_H
+#define _RIL_INFO_H
+#include <stdio.h>
+
+#include "mbtk_type.h"
+#include "mbtk_ril_api.h"
+#include "mbtk_log.h"
+#include "atchannel.h"
+#include "at_tok.h"
+#include "mbtk_list.h"
+#include "mbtk_device.h"
+#include "mbtk_queue.h"
+
+#define SOCK_CLIENT_MAX 100
+#define EPOLL_LISTEN_MAX 100
+#define IND_REGISTER_MAX 10
+#define PACK_PROCESS_QUEUE_MAX 20
+
+#define MBTK_APN_PROP "persist.mbtk.apn"
+#define MBTK_DEF_ROUTE_CID "persist.mbtk.def_route_cid"
+
+typedef struct
+{
+ int fd;
+
+ uint32 ind_num;
+ uint16 ind_register[IND_REGISTER_MAX];
+} sock_cli_info_t;
+
+typedef struct
+{
+ sock_cli_info_t *cli_info;
+ void* pack; // Refro to : ril_msg_pack_info_t
+} ril_msg_queue_info_t;
+
+typedef struct {
+ mbtk_radio_state_enum radio_state;
+ mbtk_sim_state_enum sim_state;
+ int sock_listen_fd;
+ int epoll_fd;
+ bool at_process;
+
+ list_node_t *sock_client_list; // Refor to : sock_cli_info_t
+ mbtk_queue_node_t msg_queue; // Refor to : ril_msg_queue_info_t
+ pthread_cond_t msg_cond;
+ pthread_mutex_t msg_mutex;
+} ril_info_t;
+
+typedef struct {
+ bool band_set_success;
+ mbtk_modem_band_area_enum band_area;
+ mbtk_band_info_t band_support;
+} ril_band_info_t;
+
+typedef enum {
+ RIL_URC_MSG_RADIO_STATE,
+ RIL_URC_MSG_CGEV,
+ RIL_URC_MSG_NET_CS_REG_STATE,
+ RIL_URC_MSG_NET_PS_REG_STATE,
+ RIL_URC_MSG_CALL_STATE,
+ RIL_URC_MSG_SIM_STATE,
+ RIL_URC_MSG_PDP_STATE,
+ RIL_URC_MSG_SMS_STATE,
+ RIL_URC_MSG_SET_BAND,
+ RIL_URC_MSG_GET_SIM_STATE, //check sim status
+ RIL_URC_MSG_NET_STATE_LOG // Save Network state into file.
+} ril_urc_msg_id_enum;
+
+/*
+0: unknown
+1: available
+2: current
+3: forbidden
+*/
+typedef enum
+{
+ MBTK_NET_AVIL_STATE_UNKNOWN = 0,
+ MBTK_NET_AVIL_STATE_AVAILABLE,
+ MBTK_NET_AVIL_STATE_CURRENT,
+ MBTK_NET_AVIL_STATE_FORBIDDEN
+} mbtk_net_avil_state_enum;
+
+typedef enum {
+ RIL_DATA_CALL_STATE_STOP,
+ RIL_DATA_CALL_STATE_STARTED,
+ RIL_DATA_CALL_STATE_STARTING, // Data dialing in progress
+ RIL_DATA_CALL_STATE_STOPPING // Ending data dialing
+} ril_data_call_state_enum;
+
+typedef struct {
+ ril_urc_msg_id_enum msg;
+
+ void *data;
+ int data_len;
+} ril_urc_msg_info_t;
+
+typedef struct {
+ mbtk_ril_cid_enum cid_for_def_route;
+
+ int num;
+ mbtk_apn_info_t apns[MBTK_APN_CID_MAX];
+} ril_apn_info_array_t;
+
+extern ril_info_t ril_info;
+
+
+mbtk_radio_state_enum ril_radio_state_get();
+mbtk_ril_err_enum ril_radio_state_set(mbtk_radio_state_enum state, bool reset);
+
+mbtk_sim_state_enum ril_sim_state_get();
+
+void apn_auto_conf_from_prop();
+
+bool is_ipv4(const char *ip);
+
+#endif /* _RIL_INFO_H */
diff --git a/mbtk/mbtk_rild_v2/src/at_tok.c b/mbtk/mbtk_rild_v2/src/at_tok.c
new file mode 100755
index 0000000..531afff
--- /dev/null
+++ b/mbtk/mbtk_rild_v2/src/at_tok.c
@@ -0,0 +1,194 @@
+/* //device/system/reference-ril/at_tok.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 "at_tok.h"
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+#include "mbtk_log.h"
+/**
+ * Starts tokenizing an AT response string
+ * returns -1 if this is not a valid response string, 0 on success.
+ * updates *p_cur with current position
+ */
+int at_tok_start(char **p_cur)
+{
+ if (*p_cur == NULL) {
+ return -1;
+ }
+
+ // skip prefix
+ // consume "^[^:]:"
+
+ *p_cur = strchr(*p_cur, ':');
+
+ if (*p_cur == NULL) {
+ return -1;
+ }
+
+ (*p_cur)++;
+/*
+ while(**p_cur == ' ') {
+ (*p_cur)++;
+ }
+*/
+ return 0;
+}
+
+static void skipWhiteSpace(char **p_cur)
+{
+ if (*p_cur == NULL) return;
+
+ while (**p_cur != '\0' && isspace(**p_cur)) {
+ (*p_cur)++;
+ }
+}
+
+static void skipNextComma(char **p_cur)
+{
+ if (*p_cur == NULL) return;
+
+ while (**p_cur != '\0' && **p_cur != ',') {
+ (*p_cur)++;
+ }
+
+ if (**p_cur == ',') {
+ (*p_cur)++;
+ }
+}
+
+static char * nextTok(char **p_cur)
+{
+ char *ret = NULL;
+
+ skipWhiteSpace(p_cur);
+
+ if (*p_cur == NULL) {
+ ret = NULL;
+ } else if (**p_cur == '"') {
+ (*p_cur)++;
+ ret = strsep(p_cur, "\"");
+ skipNextComma(p_cur);
+ } else {
+ ret = strsep(p_cur, ",");
+ }
+
+ return ret;
+}
+
+
+/**
+ * Parses the next integer in the AT response line and places it in *p_out
+ * returns 0 on success and -1 on fail
+ * updates *p_cur
+ * "base" is the same as the base param in strtol
+ */
+
+static int at_tok_nextint_base(char **p_cur, int *p_out, int base, int uns)
+{
+ char *ret;
+
+ if (*p_cur == NULL) {
+ return -1;
+ }
+
+ ret = nextTok(p_cur);
+
+ if (ret == NULL) {
+ return -1;
+ } 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 -1;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * Parses the next base 10 integer in the AT response line
+ * and places it in *p_out
+ * returns 0 on success and -1 on fail
+ * updates *p_cur
+ */
+int at_tok_nextint(char **p_cur, int *p_out)
+{
+ return at_tok_nextint_base(p_cur, p_out, 10, 0);
+}
+
+/**
+ * Parses the next base 16 integer in the AT response line
+ * and places it in *p_out
+ * returns 0 on success and -1 on fail
+ * updates *p_cur
+ */
+int at_tok_nexthexint(char **p_cur, int *p_out)
+{
+ return at_tok_nextint_base(p_cur, p_out, 16, 1);
+}
+
+int at_tok_nextbool(char **p_cur, char *p_out)
+{
+ int ret;
+ int result;
+
+ ret = at_tok_nextint(p_cur, &result);
+
+ if (ret < 0) {
+ return -1;
+ }
+
+ // booleans should be 0 or 1
+ if (!(result == 0 || result == 1)) {
+ return -1;
+ }
+
+ if (p_out != NULL) {
+ *p_out = (char)result;
+ }
+
+ return ret;
+}
+
+int at_tok_nextstr(char **p_cur, char **p_out)
+{
+ if (*p_cur == NULL) {
+ return -1;
+ }
+
+ *p_out = nextTok(p_cur);
+
+ return 0;
+}
+
+/** returns 1 on "has more tokens" and 0 if no */
+int at_tok_hasmore(char **p_cur)
+{
+ return ! (*p_cur == NULL || **p_cur == '\0');
+}
+
diff --git a/mbtk/mbtk_rild_v2/src/atchannel.c b/mbtk/mbtk_rild_v2/src/atchannel.c
new file mode 100755
index 0000000..bf0384c
--- /dev/null
+++ b/mbtk/mbtk_rild_v2/src/atchannel.c
@@ -0,0 +1,1337 @@
+/* //device/system/reference-ril/atchannel.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 "atchannel.h"
+#include "at_tok.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <pthread.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/time.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "mbtk_log.h"
+#include "mbtk_type.h"
+#include "mbtk_utils.h"
+
+#define MAX_AT_RESPONSE (8 * 1024)
+#define HANDSHAKE_RETRY_COUNT 20
+#define HANDSHAKE_TIMEOUT_MSEC 500
+#define AT_BUFF_MAX 100
+
+static pthread_t s_tid_reader;
+static int s_at_fd = -1; /* fd of the AT channel */
+static int s_uart_fd = -1; /* fd of the UART channel */
+
+static ATUnsolHandler s_unsolHandler;
+
+/* for input buffering */
+
+static char s_ATBuffer[MAX_AT_RESPONSE+1];
+static char *s_ATBufferCur = s_ATBuffer;
+static char s_UartBuffer[MAX_AT_RESPONSE+1];
+static char *s_UartBufferCur = s_UartBuffer;
+
+static mbtk_ril_at_state_enum at_state = RIL_AT_STATE_CLOSED;
+
+#if AT_DEBUG
+void AT_DUMP(const char* prefix, const char* buff, int len)
+{
+ if (len < 0)
+ len = strlen(buff);
+ LOGD("%.*s", len, buff);
+}
+#endif
+
+/*
+ * There is one reader thread |s_tid_reader| and potentially multiple writer
+ * threads. |s_commandmutex| and |s_commandcond| are used to maintain the
+ * condition that the writer thread will not read from |sp_response| until the
+ * reader thread has signaled itself is finished, etc. |s_writeMutex| is used to
+ * prevent multiple writer threads from calling at_send_command_full_nolock
+ * function at the same time.
+ */
+
+// "Wait" when AT process...
+static pthread_mutex_t s_commandmutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t s_commandcond = PTHREAD_COND_INITIALIZER;
+
+static ATCommandType s_type;
+static const char *s_responsePrefix = NULL;
+static const char *s_smsPDU = NULL;
+static ATResponse *sp_response = NULL;
+static char s_curr_at[AT_BUFF_MAX];
+
+static void (*s_onTimeout)(void) = NULL;
+static void (*s_onReaderClosed)(void) = NULL;
+static int s_readerClosed;
+
+static void onReaderClosed();
+static int writeCtrlZ (const char *s);
+static int writeline (const char *s);
+
+typedef struct
+{
+ char *at_command;
+ long long timeout; // ms
+ bool timeout_close; // Close AT or not while AT response timeout.
+} at_timeout_t;
+
+static at_timeout_t at_timeout_list[] =
+{
+ {"AT+CRSM", 10000, false},
+// {"AT+COPS", 60000, false}
+};
+
+#define NS_PER_S 1000000000
+static void setTimespecRelative(struct timespec *p_ts, long long msec)
+{
+ struct timeval tv;
+
+ gettimeofday(&tv, (struct timezone *) NULL);
+
+ p_ts->tv_sec = tv.tv_sec + (msec / 1000);
+ p_ts->tv_nsec = (tv.tv_usec + (msec % 1000) * 1000L ) * 1000L;
+ /* assuming tv.tv_usec < 10^6 */
+ if (p_ts->tv_nsec >= NS_PER_S)
+ {
+ p_ts->tv_sec++;
+ p_ts->tv_nsec -= NS_PER_S;
+ }
+}
+
+static void sleepMsec(long long msec)
+{
+ struct timespec ts;
+ int err;
+
+ ts.tv_sec = (msec / 1000);
+ ts.tv_nsec = (msec % 1000) * 1000 * 1000;
+
+ do
+ {
+ err = nanosleep (&ts, &ts);
+ }
+ while (err < 0 && errno == EINTR);
+}
+
+
+
+/** add an intermediate response to sp_response*/
+static void addIntermediate(const char *line)
+{
+ ATLine *p_new;
+
+ p_new = (ATLine *) malloc(sizeof(ATLine));
+
+ p_new->line = strdup(line);
+
+// LOGD("line:%s", line);
+// LOGD("line-1:%s", p_new->line);
+
+ /* note: this adds to the head of the list, so the list
+ will be in reverse order of lines received. the order is flipped
+ again before passing on to the command issuer */
+ p_new->p_next = sp_response->p_intermediates;
+ sp_response->p_intermediates = p_new;
+}
+
+
+/**
+ * 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! */ // Only for ATD ?
+ "NO ANSWER",
+ "NO DIALTONE",
+};
+static int isFinalResponseError(const char *line)
+{
+ size_t i;
+
+ for (i = 0 ; i < ARRAY_SIZE(s_finalResponsesError) ; i++)
+ {
+ if (strStartsWith(line, s_finalResponsesError[i]))
+ {
+ return 1;
+ }
+ }
+
+ if(!strncasecmp(s_curr_at, "ATD", 3) && strStartsWith(line, "NO CARRIER"))
+ {
+ return 1;
+ }
+
+ return 0;
+}
+
+/**
+ * returns 1 if line is a final response indicating success
+ * See 27.007 annex B
+ * WARNING: NO CARRIER and others are sometimes unsolicited
+ */
+static const char * s_finalResponsesSuccess[] =
+{
+ "OK",
+// "CONNECT" /* some stacks start up data on another channel */
+};
+static int isFinalResponseSuccess(const char *line)
+{
+ size_t i;
+
+ for (i = 0 ; i < ARRAY_SIZE(s_finalResponsesSuccess) ; i++)
+ {
+ if (strStartsWith(line, s_finalResponsesSuccess[i]))
+ {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * returns 1 if line is a final response, either error or success
+ * See 27.007 annex B
+ * WARNING: NO CARRIER and others are sometimes unsolicited
+ */
+static int isFinalResponse(const char *line)
+{
+ return isFinalResponseSuccess(line) || isFinalResponseError(line);
+}
+
+/**
+ * returns 1 if line is the first line in (what will be) a two-line
+ * SMS unsolicited response
+ */
+static const char * s_smsUnsoliciteds[] =
+{
+ "+CMT:",
+ "+CDS:",
+ "+CBM:"
+};
+static int isSMSUnsolicited(const char *line)
+{
+ size_t i;
+
+ for (i = 0 ; i < ARRAY_SIZE(s_smsUnsoliciteds) ; i++)
+ {
+ if (strStartsWith(line, s_smsUnsoliciteds[i]))
+ {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+
+/** assumes s_commandmutex is held */
+static void handleFinalResponse(const char *line)
+{
+ sp_response->finalResponse = strdup(line);
+
+ //LOGD("AT complete (pthread_cond_signal): %s",line);
+ pthread_cond_signal(&s_commandcond);
+}
+
+static void handleUnsolicited(const char *line)
+{
+ if (s_unsolHandler != NULL)
+ {
+ s_unsolHandler(line, NULL);
+ }
+}
+
+static void processLine(const char *line)
+{
+ pthread_mutex_lock(&s_commandmutex);
+// LOGD("LINE : %s", line);
+ if (sp_response == NULL)
+ {
+ /* no command pending */
+ handleUnsolicited(line);
+ }
+ else if (isFinalResponseSuccess(line))
+ {
+ sp_response->success = 1;
+ handleFinalResponse(line);
+ }
+ else if (isFinalResponseError(line))
+ {
+ sp_response->success = 0;
+ handleFinalResponse(line);
+ }
+ else if (s_smsPDU != NULL && 0 == strcmp(line, "> "))
+ {
+ // See eg. TS 27.005 4.3
+ // Commands like AT+CMGS have a "> " prompt
+ writeCtrlZ(s_smsPDU);
+ s_smsPDU = NULL;
+ }
+ else switch (s_type)
+ {
+ case NO_RESULT:
+ handleUnsolicited(line);
+ break;
+ case NUMERIC:
+ if (sp_response->p_intermediates == NULL
+ && isdigit(line[0])
+ )
+ {
+ addIntermediate(line);
+ }
+ else
+ {
+ /* either we already have an intermediate response or
+ the line doesn't begin with a digit */
+ handleUnsolicited(line);
+ }
+ break;
+ case SINGLELINE:
+ if (sp_response->p_intermediates == NULL
+ && strStartsWith (line, s_responsePrefix)
+ )
+ {
+ if(*line == '"')
+ {
+ char *line_temp = strdup(line);
+ line_temp++;
+ if(strlen(line_temp) > 0)
+ {
+ char *ptr = line_temp + strlen(line_temp) - 1;
+ while(ptr >= line_temp && *ptr == '"')
+ {
+ *ptr = '\0';
+ ptr--;
+ }
+ }
+ addIntermediate(line_temp);
+ free(line_temp);
+ }
+ else
+ {
+ addIntermediate(line);
+ }
+ }
+ else
+ {
+ /* we already have an intermediate response */
+ handleUnsolicited(line);
+ }
+ break;
+ case MULTILINE:
+ if (strStartsWith (line, s_responsePrefix))
+ {
+ addIntermediate(line);
+ }
+ else
+ {
+ handleUnsolicited(line);
+ }
+ break;
+
+ default: /* this should never be reached */
+ LOGE("Unsupported AT command type %d\n", s_type);
+ handleUnsolicited(line);
+ break;
+ }
+
+ pthread_mutex_unlock(&s_commandmutex);
+}
+
+
+/**
+ * Returns a pointer to the end of the next line
+ * special-cases the "> " SMS prompt
+ *
+ * returns NULL if there is no complete line
+ */
+static char * findNextEOL(char *cur)
+{
+ if (cur[0] == '>' && cur[1] == ' ' && cur[2] == '\0')
+ {
+ /* SMS prompt character...not \r terminated */
+ return cur+2;
+ }
+
+ // Find next newline
+ while (*cur != '\0' && *cur != '\r' && *cur != '\n') cur++;
+
+ return *cur == '\0' ? NULL : cur;
+}
+
+
+/**
+ * Reads a line from the AT channel, returns NULL on timeout.
+ * Assumes it has exclusive read access to the FD
+ *
+ * This line is valid only until the next call to readline
+ *
+ * This function exists because as of writing, android libc does not
+ * have buffered stdio.
+ */
+
+static const char *readline()
+{
+ ssize_t count;
+
+ char *p_read = NULL;
+ char *p_eol = NULL;
+ char *ret;
+
+ /* this is a little odd. I use *s_ATBufferCur == 0 to
+ * mean "buffer consumed completely". If it points to a character, than
+ * the buffer continues until a \0
+ */
+ if (*s_ATBufferCur == '\0')
+ {
+ /* empty buffer */
+ s_ATBufferCur = s_ATBuffer;
+ *s_ATBufferCur = '\0';
+ p_read = s_ATBuffer;
+ }
+ else /* *s_ATBufferCur != '\0' */
+ {
+ /* there's data in the buffer from the last read */
+
+ // skip over leading newlines
+ while (*s_ATBufferCur == '\r' || *s_ATBufferCur == '\n')
+ s_ATBufferCur++;
+
+ p_eol = findNextEOL(s_ATBufferCur);
+
+ if (p_eol == NULL)
+ {
+ /* a partial line. move it up and prepare to read more */
+ size_t len;
+
+ len = strlen(s_ATBufferCur);
+
+ memmove(s_ATBuffer, s_ATBufferCur, len + 1);
+ p_read = s_ATBuffer + len;
+ s_ATBufferCur = s_ATBuffer;
+ }
+ /* Otherwise, (p_eol !- NULL) there is a complete line */
+ /* that will be returned the while () loop below */
+ }
+
+ while (p_eol == NULL)
+ {
+ if (0 == MAX_AT_RESPONSE - (p_read - s_ATBuffer))
+ {
+ LOGE("ERROR: Input line exceeded buffer\n");
+ /* ditch buffer and start over again */
+ s_ATBufferCur = s_ATBuffer;
+ *s_ATBufferCur = '\0';
+ p_read = s_ATBuffer;
+ }
+
+ do
+ {
+ count = read(s_at_fd, p_read,
+ MAX_AT_RESPONSE - (p_read - s_ATBuffer));
+ usleep(10000);
+ }
+ while (count < 0 && errno == EINTR);
+
+ if (count > 0)
+ {
+ AT_DUMP( "<< ", p_read, count );
+
+ p_read[count] = '\0';
+
+ // skip over leading newlines
+ while (*s_ATBufferCur == '\r' || *s_ATBufferCur == '\n')
+ s_ATBufferCur++;
+
+ p_eol = findNextEOL(s_ATBufferCur);
+ p_read += count;
+ }
+ else if (count <= 0)
+ {
+ /* read error encountered or EOF reached */
+ if(count == 0)
+ {
+ LOGD("atchannel: EOF reached");
+ }
+ else
+ {
+ LOGD("atchannel: read error %s", strerror(errno));
+ }
+ return NULL;
+ }
+ }
+
+ /* a full line in the buffer. Place a \0 over the \r and return */
+
+ ret = s_ATBufferCur;
+ *p_eol = '\0';
+ s_ATBufferCur = p_eol + 1; /* this will always be <= p_read, */
+ /* and there will be a \0 at *p_read */
+
+ LOGD("AT< %s", ret);
+ return ret;
+}
+
+static const char *readlineUrc()
+{
+ ssize_t count;
+
+ char *p_read = NULL;
+ char *p_eol = NULL;
+ char *ret;
+
+ /* this is a little odd. I use *s_ATBufferCur == 0 to
+ * mean "buffer consumed completely". If it points to a character, than
+ * the buffer continues until a \0
+ */
+ if (*s_UartBufferCur == '\0')
+ {
+ /* empty buffer */
+ s_UartBufferCur = s_UartBuffer;
+ *s_UartBufferCur = '\0';
+ p_read = s_UartBuffer;
+ }
+ else /* *s_ATBufferCur != '\0' */
+ {
+ /* there's data in the buffer from the last read */
+
+ // skip over leading newlines
+ while (*s_UartBufferCur == '\r' || *s_UartBufferCur == '\n')
+ s_UartBufferCur++;
+
+ p_eol = findNextEOL(s_UartBufferCur);
+
+ if (p_eol == NULL)
+ {
+ /* a partial line. move it up and prepare to read more */
+ size_t len;
+
+ len = strlen(s_UartBufferCur);
+
+ memmove(s_UartBuffer, s_UartBufferCur, len + 1);
+ p_read = s_UartBuffer + len;
+ s_UartBufferCur = s_UartBuffer;
+ }
+ /* Otherwise, (p_eol !- NULL) there is a complete line */
+ /* that will be returned the while () loop below */
+ }
+
+ while (p_eol == NULL)
+ {
+ if (0 == MAX_AT_RESPONSE - (p_read - s_UartBuffer))
+ {
+ LOGE("ERROR: Input line exceeded buffer\n");
+ /* ditch buffer and start over again */
+ s_UartBufferCur = s_UartBuffer;
+ *s_UartBufferCur = '\0';
+ p_read = s_UartBuffer;
+ }
+
+ do
+ {
+ count = read(s_uart_fd, p_read,
+ MAX_AT_RESPONSE - (p_read - s_UartBuffer));
+ usleep(10000);
+ }
+ while (count < 0 && errno == EINTR);
+
+ if (count > 0)
+ {
+ AT_DUMP( "<< ", p_read, count );
+
+ p_read[count] = '\0';
+
+ // skip over leading newlines
+ while (*s_UartBufferCur == '\r' || *s_UartBufferCur == '\n')
+ s_UartBufferCur++;
+
+ p_eol = findNextEOL(s_UartBufferCur);
+ p_read += count;
+ }
+ else if (count <= 0)
+ {
+ /* read error encountered or EOF reached */
+ if(count == 0)
+ {
+ LOGD("atchannel: EOF reached");
+ }
+ else
+ {
+ LOGD("atchannel: read error %s", strerror(errno));
+ }
+ return NULL;
+ }
+ }
+
+ /* a full line in the buffer. Place a \0 over the \r and return */
+
+ ret = s_UartBufferCur;
+ *p_eol = '\0';
+ s_UartBufferCur = p_eol + 1; /* this will always be <= p_read, */
+ /* and there will be a \0 at *p_read */
+
+ LOGD("URC< %s", ret);
+ return ret;
+}
+
+
+
+static void onReaderClosed()
+{
+ LOGD("onReaderClosed()");
+ if (s_onReaderClosed != NULL && s_readerClosed == 0)
+ {
+
+ pthread_mutex_lock(&s_commandmutex);
+
+ s_readerClosed = 1;
+
+ pthread_cond_signal(&s_commandcond);
+
+ pthread_mutex_unlock(&s_commandmutex);
+
+ s_onReaderClosed();
+ }
+}
+
+static void *readerLoop(void *arg)
+{
+ UNUSED(arg);
+ for (;;)
+ {
+ const char * line;
+
+ line = readline();
+
+ if (line == NULL)
+ {
+ break;
+ }
+
+ if(strStartsWith(line, "MBTK_AT_READY")) {
+ //handleUnsolicited(line);
+ continue;
+ }
+
+ if(isSMSUnsolicited(line))
+ {
+ char *line1;
+ const char *line2;
+
+ // The scope of string returned by 'readline()' is valid only
+ // till next call to 'readline()' hence making a copy of line
+ // before calling readline again.
+ line1 = strdup(line);
+ line2 = readline();
+
+ if (line2 == NULL)
+ {
+ free(line1);
+ break;
+ }
+
+ if (s_unsolHandler != NULL)
+ {
+ s_unsolHandler (line1, line2);
+ }
+ free(line1);
+ }
+ else
+ {
+ processLine(line);
+ }
+ }
+
+ onReaderClosed();
+
+ return NULL;
+}
+
+static void *readerUrcLoop(void *arg)
+{
+ UNUSED(arg);
+ for (;;)
+ {
+ const char *line;
+
+ line = readlineUrc();
+
+ if (line == NULL)
+ {
+ break;
+ }
+
+ handleUnsolicited(line);
+ }
+
+ onReaderClosed();
+
+ return NULL;
+}
+
+
+/**
+ * Sends string s to the radio with a \r appended.
+ * Returns AT_ERROR_* on error, 0 on success
+ *
+ * This function exists because as of writing, android libc does not
+ * have buffered stdio.
+ */
+static int writeline (const char *s)
+{
+ size_t cur = 0;
+ size_t len = strlen(s);
+ ssize_t written;
+
+ if (s_at_fd < 0 || s_readerClosed > 0)
+ {
+ return AT_ERROR_CHANNEL_CLOSED;
+ }
+
+ LOGD("AT> %s", s);
+
+ AT_DUMP( ">> ", s, strlen(s) );
+
+ memset(s_curr_at, 0x0, AT_BUFF_MAX);
+ memcpy(s_curr_at, s, strlen(s));
+
+ /* the main string */
+ while (cur < len)
+ {
+ do
+ {
+ written = write (s_at_fd, s + cur, len - cur);
+ }
+ while (written < 0 && errno == EINTR);
+
+ if (written < 0)
+ {
+ return AT_ERROR_GENERIC;
+ }
+
+ cur += written;
+ }
+
+ /* the \r */
+
+ do
+ {
+ written = write (s_at_fd, "\r", 1);
+ }
+ while ((written < 0 && errno == EINTR) || (written == 0));
+
+ if (written < 0)
+ {
+ return AT_ERROR_GENERIC;
+ }
+
+ return 0;
+}
+
+static int writeCtrlZ (const char *s)
+{
+ size_t cur = 0;
+ size_t len = strlen(s);
+ ssize_t written;
+
+ if (s_at_fd < 0 || s_readerClosed > 0)
+ {
+ return AT_ERROR_CHANNEL_CLOSED;
+ }
+
+ LOGD("AT> %s^Z\n", s);
+
+ AT_DUMP( ">* ", s, strlen(s) );
+
+ /* the main string */
+ while (cur < len)
+ {
+ do
+ {
+ written = write (s_at_fd, s + cur, len - cur);
+ }
+ while (written < 0 && errno == EINTR);
+
+ if (written < 0)
+ {
+ return AT_ERROR_GENERIC;
+ }
+
+ cur += written;
+ }
+
+ /* the ^Z */
+
+ do
+ {
+ written = write (s_at_fd, "\032", 1);
+ }
+ while ((written < 0 && errno == EINTR) || (written == 0));
+
+ if (written < 0)
+ {
+ return AT_ERROR_GENERIC;
+ }
+
+ return 0;
+}
+
+static void clearPendingCommand()
+{
+ if (sp_response != NULL)
+ {
+ at_response_free(sp_response);
+ }
+
+ sp_response = NULL;
+ s_responsePrefix = NULL;
+ s_smsPDU = NULL;
+}
+
+
+/**
+ * Starts AT handler on stream "fd'
+ * returns 0 on success, -1 on error
+ */
+int at_open(int at_fd, int uart_fd, ATUnsolHandler h)
+{
+ int ret;
+ pthread_attr_t attr;
+
+ s_at_fd = at_fd;
+ s_uart_fd = uart_fd;
+ s_unsolHandler = h;
+ s_readerClosed = 0;
+ s_responsePrefix = NULL;
+ s_smsPDU = NULL;
+ sp_response = NULL;
+
+ pthread_attr_init (&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+ ret = pthread_create(&s_tid_reader, &attr, readerLoop, NULL);
+ if (ret < 0)
+ {
+ LOGE("AT thread create fail.");
+ return -1;
+ }
+
+ pthread_t uart_tid_reader;
+ ret = pthread_create(&uart_tid_reader, &attr, readerUrcLoop, NULL);
+ if (ret < 0)
+ {
+ LOGE("Uart thread create fail.");
+ return -1;
+ }
+
+ return 0;
+}
+
+/* FIXME is it ok to call this from the reader and the command thread? */
+void at_close()
+{
+ LOGD("at_close()");
+ if (s_at_fd >= 0)
+ {
+ close(s_at_fd);
+ }
+ if (s_uart_fd >= 0)
+ {
+ close(s_uart_fd);
+ }
+ s_at_fd = -1;
+ s_uart_fd = -1;
+
+ pthread_mutex_lock(&s_commandmutex);
+ s_readerClosed = 1;
+ pthread_cond_signal(&s_commandcond);
+ pthread_mutex_unlock(&s_commandmutex);
+ /* the reader thread should eventually die */
+
+ at_state = RIL_AT_STATE_CLOSED;
+}
+
+static ATResponse * at_response_new()
+{
+ return (ATResponse *) calloc(1, sizeof(ATResponse));
+}
+
+void at_response_free(ATResponse *p_response)
+{
+ ATLine *p_line;
+
+ if (p_response == NULL) return;
+
+ p_line = p_response->p_intermediates;
+
+ while (p_line != NULL)
+ {
+ ATLine *p_toFree;
+
+ p_toFree = p_line;
+ p_line = p_line->p_next;
+
+ free(p_toFree->line);
+ free(p_toFree);
+ }
+
+ free (p_response->finalResponse);
+ free (p_response);
+}
+
+/**
+ * The line reader places the intermediate responses in reverse order
+ * here we flip them back
+ */
+static void reverseIntermediates(ATResponse *p_response)
+{
+ ATLine *pcur,*pnext;
+
+ pcur = p_response->p_intermediates;
+ p_response->p_intermediates = NULL;
+
+ while (pcur != NULL)
+ {
+ pnext = pcur->p_next;
+ pcur->p_next = p_response->p_intermediates;
+ p_response->p_intermediates = pcur;
+ pcur = pnext;
+ }
+}
+
+static long long at_timeout_get(const char *at_command, bool *timeout_close)
+{
+ long long timeout = 0;
+ int i;
+ for(i = 0; i < ARRAY_SIZE(at_timeout_list); i++)
+ {
+ if(!strncasecmp(at_command, at_timeout_list[i].at_command, strlen(at_timeout_list[i].at_command)))
+ {
+ timeout = at_timeout_list[i].timeout;
+ *timeout_close = at_timeout_list[i].timeout_close;
+ break;
+ }
+ }
+
+ return timeout;
+}
+
+/**
+ * Internal send_command implementation
+ * Doesn't lock or call the timeout callback
+ *
+ * timeoutMsec == 0 means infinite timeout
+ */
+static int at_send_command_full_nolock (const char *command, ATCommandType type,
+ const char *responsePrefix, const char *smspdu,
+ long long timeoutMsec, ATResponse **pp_outResponse)
+{
+ int err = 0;
+ bool tiemout_close = true;
+ struct timespec ts;
+ if(at_state == RIL_AT_STATE_READY)
+ at_state = RIL_AT_STATE_BUSY;
+
+ if(sp_response != NULL)
+ {
+ err = AT_ERROR_COMMAND_PENDING;
+ goto error;
+ }
+
+ err = writeline (command);
+
+ if (err < 0)
+ {
+ goto error;
+ }
+
+ s_type = type;
+ s_responsePrefix = responsePrefix;
+ s_smsPDU = smspdu;
+ sp_response = at_response_new();
+
+ if(timeoutMsec == 0)
+ {
+ timeoutMsec = at_timeout_get(command, &tiemout_close);
+ }
+
+ if (timeoutMsec != 0)
+ {
+ setTimespecRelative(&ts, timeoutMsec);
+ }
+
+ while (sp_response->finalResponse == NULL && s_readerClosed == 0)
+ {
+ //LOGD("AT wait time:%lld",timeoutMsec);
+ if (timeoutMsec != 0)
+ {
+ err = pthread_cond_timedwait(&s_commandcond, &s_commandmutex, &ts);
+ }
+ else
+ {
+ err = pthread_cond_wait(&s_commandcond, &s_commandmutex);
+ }
+
+ //LOGD("AT continue:err - %d",err);
+ if (err == ETIMEDOUT)
+ {
+ if(tiemout_close)
+ {
+ err = AT_ERROR_TIMEOUT_CLOSE;
+ }
+ else
+ {
+ err = AT_ERROR_TIMEOUT;
+ }
+ goto error;
+ }
+ }
+
+ if (pp_outResponse == NULL)
+ {
+ at_response_free(sp_response);
+ }
+ else
+ {
+ /* line reader stores intermediate responses in reverse order */
+ reverseIntermediates(sp_response);
+ *pp_outResponse = sp_response;
+ }
+
+ sp_response = NULL;
+
+ if(s_readerClosed > 0)
+ {
+ err = AT_ERROR_CHANNEL_CLOSED;
+ goto error;
+ }
+
+ err = 0;
+error:
+ if(at_state == RIL_AT_STATE_BUSY)
+ at_state = RIL_AT_STATE_READY;
+ clearPendingCommand();
+
+ return err;
+}
+
+/**
+ * Internal send_command implementation
+ *
+ * timeoutMsec == 0 means infinite timeout
+ */
+static int at_send_command_full (const char *command, ATCommandType type,
+ const char *responsePrefix, const char *smspdu,
+ long long timeoutMsec, ATResponse **pp_outResponse)
+{
+ int err;
+
+ if (0 != pthread_equal(s_tid_reader, pthread_self()))
+ {
+ /* cannot be called from reader thread */
+ LOGE("cannot be called from reader thread.");
+ return AT_ERROR_INVALID_THREAD;
+ }
+
+ // Waitting for previous AT complete.
+ while(at_state == RIL_AT_STATE_BUSY)
+ {
+ usleep(10000);
+ }
+
+ pthread_mutex_lock(&s_commandmutex);
+
+ err = at_send_command_full_nolock(command, type,
+ responsePrefix, smspdu,
+ timeoutMsec, pp_outResponse);
+
+ pthread_mutex_unlock(&s_commandmutex);
+
+ if (err == AT_ERROR_TIMEOUT_CLOSE && s_onTimeout != NULL)
+ {
+ s_onTimeout();
+ }
+
+ return err;
+}
+
+
+/**
+ * Issue a single normal AT command with no intermediate response expected
+ *
+ * "command" should not include \r
+ * pp_outResponse can be NULL
+ *
+ * if non-NULL, the resulting ATResponse * must be eventually freed with
+ * at_response_free
+ */
+int at_send_command (const char *command, ATResponse **pp_outResponse)
+{
+ return at_send_command_full (command, NO_RESULT, NULL,
+ NULL, 0, pp_outResponse);
+}
+
+
+int at_send_command_singleline (const char *command,
+ const char *responsePrefix,
+ ATResponse **pp_outResponse)
+{
+ int err;
+
+ err = at_send_command_full (command, SINGLELINE, responsePrefix,
+ NULL, 0, pp_outResponse);
+
+ if (err == 0 && pp_outResponse != NULL
+ && (*pp_outResponse)->success > 0
+ && (*pp_outResponse)->p_intermediates == NULL
+ )
+ {
+ /* successful command must have an intermediate response */
+ at_response_free(*pp_outResponse);
+ *pp_outResponse = NULL;
+ return AT_ERROR_INVALID_RESPONSE;
+ }
+
+ return err;
+}
+
+int at_send_command_singleline_with_timeout (const char *command,
+ const char *responsePrefix,
+ ATResponse **pp_outResponse,long long timeoutMsec)
+{
+ int err;
+
+ err = at_send_command_full (command, SINGLELINE, responsePrefix,
+ NULL, timeoutMsec, pp_outResponse);
+
+ if (err == 0 && pp_outResponse != NULL
+ && (*pp_outResponse)->success > 0
+ && (*pp_outResponse)->p_intermediates == NULL
+ )
+ {
+ /* successful command must have an intermediate response */
+ at_response_free(*pp_outResponse);
+ *pp_outResponse = NULL;
+ return AT_ERROR_INVALID_RESPONSE;
+ }
+
+ return err;
+}
+
+
+
+int at_send_command_numeric (const char *command,
+ ATResponse **pp_outResponse)
+{
+ int err;
+
+ err = at_send_command_full (command, NUMERIC, NULL,
+ NULL, 0, pp_outResponse);
+
+ if (err == 0 && pp_outResponse != NULL
+ && (*pp_outResponse)->success > 0
+ && (*pp_outResponse)->p_intermediates == NULL
+ )
+ {
+ /* successful command must have an intermediate response */
+ at_response_free(*pp_outResponse);
+ *pp_outResponse = NULL;
+ return AT_ERROR_INVALID_RESPONSE;
+ }
+
+ return err;
+}
+
+
+int at_send_command_sms (const char *command,
+ const char *pdu,
+ const char *responsePrefix,
+ ATResponse **pp_outResponse)
+{
+ int err;
+
+ err = at_send_command_full (command, SINGLELINE, responsePrefix,
+ pdu, 0, pp_outResponse);
+
+ if (err == 0 && pp_outResponse != NULL
+ && (*pp_outResponse)->success > 0
+ && (*pp_outResponse)->p_intermediates == NULL
+ )
+ {
+ /* successful command must have an intermediate response */
+ at_response_free(*pp_outResponse);
+ *pp_outResponse = NULL;
+ return AT_ERROR_INVALID_RESPONSE;
+ }
+
+ return err;
+}
+
+
+int at_send_command_multiline (const char *command,
+ const char *responsePrefix,
+ ATResponse **pp_outResponse)
+{
+ int err;
+
+ err = at_send_command_full (command, MULTILINE, responsePrefix,
+ NULL, 0, pp_outResponse);
+
+ return err;
+}
+
+
+/** This callback is invoked on the command thread */
+void at_set_on_timeout(void (*onTimeout)(void))
+{
+ s_onTimeout = onTimeout;
+}
+
+/**
+ * This callback is invoked on the reader thread (like ATUnsolHandler)
+ * when the input stream closes before you call at_close
+ * (not when you call at_close())
+ * You should still call at_close()
+ */
+
+void at_set_on_reader_closed(void (*onClose)(void))
+{
+ s_onReaderClosed = onClose;
+}
+
+
+/**
+ * Periodically issue an AT command and wait for a response.
+ * Used to ensure channel has start up and is active
+ */
+int at_handshake()
+{
+ int i;
+ int err = 0;
+
+ if (0 != pthread_equal(s_tid_reader, pthread_self()))
+ {
+ /* cannot be called from reader thread */
+ return AT_ERROR_INVALID_THREAD;
+ }
+ pthread_mutex_lock(&s_commandmutex);
+
+#if 0
+ for (i = 0 ; i < HANDSHAKE_RETRY_COUNT ; i++)
+ {
+ /* some stacks start with verbose off */
+ err = at_send_command_full_nolock("ATE0Q0V1", NO_RESULT,
+ NULL, NULL, HANDSHAKE_TIMEOUT_MSEC, NULL);
+
+ if (err == 0)
+ {
+ break;
+ }
+ }
+#else
+ err = at_send_command_full_nolock("ATE0Q0V1", NO_RESULT,
+ NULL, NULL, 0, NULL);
+#endif
+
+ if (err == 0)
+ {
+ /* pause for a bit to let the input buffer drain any unmatched OK's
+ (they will appear as extraneous unsolicited responses) */
+ sleepMsec(HANDSHAKE_TIMEOUT_MSEC);
+ }
+
+ pthread_mutex_unlock(&s_commandmutex);
+
+
+ return err;
+}
+
+/**
+ * Returns error code from response
+ * Assumes AT+CMEE=1 (numeric) mode
+ */
+int at_get_cme_error(const ATResponse *p_response)
+{
+ int ret;
+ int err;
+ char *p_cur;
+
+ if (p_response->success > 0)
+ {
+ return CME_SUCCESS;
+ }
+
+ if (p_response->finalResponse == NULL
+ || !strStartsWith(p_response->finalResponse, "+CME ERROR:")
+ )
+ {
+ return CME_ERROR_NON_CME;
+ }
+
+ p_cur = p_response->finalResponse;
+ err = at_tok_start(&p_cur);
+
+ if (err < 0)
+ {
+ return CME_ERROR_NON_CME;
+ }
+
+ err = at_tok_nextint(&p_cur, &ret);
+
+ if (err < 0)
+ {
+ return CME_ERROR_NON_CME;
+ }
+
+ return ret;
+}
+
+mbtk_ril_at_state_enum at_state_get()
+{
+ return at_state;
+}
+
+void at_state_set(mbtk_ril_at_state_enum state)
+{
+ at_state = state;
+}
+
+bool at_rsp_check(ATResponse *p_response)
+{
+ if(!p_response || !p_response->success)
+ return false;
+
+ return true;
+}
+
+void unused_func()
+{
+ isFinalResponse(NULL);
+}
+
diff --git a/mbtk/mbtk_rild_v2/src/main.c b/mbtk/mbtk_rild_v2/src/main.c
new file mode 100755
index 0000000..45a30f6
--- /dev/null
+++ b/mbtk/mbtk_rild_v2/src/main.c
@@ -0,0 +1,2209 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <linux/un.h>
+#include <linux/netlink.h>
+#include <cutils/properties.h>
+#include <time.h>
+#include <sys/time.h>
+#include <signal.h>
+#include <sys/epoll.h>
+#include <pthread.h>
+
+
+//#include "cploader.h"
+#include "mbtk_log.h"
+#include "mbtk_ifc.h"
+#include "mbtk_type.h"
+#include "atchannel.h"
+#include "at_tok.h"
+#include "mbtk_utils.h"
+#include "mbtk_task.h"
+#include "ril_info.h"
+#include "mbtk_ntp.h"
+#include "mbtk_net_control.h"
+#include "mbtk_ril.h"
+#include "mbtk_str.h"
+#include "mbtk_queue.h"
+
+#define TEMP_FAILURE_RETRY(exp) ({ \
+ typeof (exp) _rc; \
+ do { \
+ _rc = (exp); \
+ } while (_rc == -1 && errno == EINTR); \
+ _rc; })
+
+#define BUFFER_SIZE 2048
+#define UEVENT_USIM_DEV "/devices/virtual/usim_event/usim0"
+#define MBTK_BOOT_SERVER_READY "/etc/init.d/mbtk_boot_server_ready"
+#define MBTK_BOOT_NET_READY "/etc/init.d/mbtk_boot_net_ready"
+#define MBTK_RILD_PID_FILE "/var/run/mbtk_rild.pid"
+#define MBTK_RILD_FILE_NET_READY "/tmp/mbtk_rild.net_ready"
+#define MBTK_RILD_FILE_SER_READY "/tmp/mbtk_rild.ser_ready"
+
+static bool ril_net_ready = FALSE; // Only one time.
+static bool ril_server_ready = FALSE; // Only one time.
+ril_band_info_t band_info;
+ril_info_t ril_info;
+
+// int urc_msg_distribute(bool async_process, info_urc_msg_id_enum msg, void *data, int data_len);
+// int mbtk_signal_log(char *data);
+int InProduction_Mode(void);
+mbtk_ril_err_enum dev_pack_req_process(sock_cli_info_t* cli_info, ril_msg_pack_info_t* pack);
+mbtk_ril_err_enum call_pack_req_process(sock_cli_info_t* cli_info, ril_msg_pack_info_t* pack);
+mbtk_ril_err_enum sim_pack_req_process(sock_cli_info_t* cli_info, ril_msg_pack_info_t* pack);
+mbtk_ril_err_enum net_pack_req_process(sock_cli_info_t* cli_info, ril_msg_pack_info_t* pack);
+mbtk_ril_err_enum pb_pack_req_process(sock_cli_info_t* cli_info, ril_msg_pack_info_t* pack);
+mbtk_ril_err_enum sms_pack_req_process(sock_cli_info_t* cli_info, ril_msg_pack_info_t* pack);
+
+/* Called on command thread */
+static void onATTimeout()
+{
+ LOGI("AT channel timeout; closing\n");
+ at_close();
+}
+
+/* Called on command or reader thread */
+static void onATReaderClosed()
+{
+ LOGI("AT channel closed\n");
+ at_close();
+}
+
+static void sock_cli_free_func(void *data)
+{
+ if (data)
+ {
+ sock_cli_info_t *info = (sock_cli_info_t*) data;
+ LOGD("Free Socket client[fd = %d].", info->fd);
+ free(info);
+ }
+}
+
+/*
+* Will exec mbtk_boot_server_ready and mbtk_boot_net_ready if is_first_boot is true.
+*/
+static int net_ready_set()
+{
+ int ret = -1;
+ int fd = open(MBTK_RILD_FILE_NET_READY, O_CREAT | O_WRONLY | O_TRUNC, 0644);
+ if(fd > 0) {
+ if(write(fd, "1", 1) == 1) {
+ ret = 0;
+ ril_net_ready = TRUE;
+ }
+ close(fd);
+ } else {
+ LOGE("Open %s fail:%d", MBTK_RILD_FILE_NET_READY, errno);
+ }
+
+ return ret;
+}
+
+/*
+* Will exec mbtk_boot_server_ready and mbtk_boot_net_ready if is_first_boot is true.
+*/
+static int ser_ready_set()
+{
+ int ret = -1;
+ int fd = open(MBTK_RILD_FILE_SER_READY, O_CREAT | O_WRONLY | O_TRUNC, 0644);
+ if(fd > 0) {
+ if(write(fd, "1", 1) == 1) {
+ ret = 0;
+ ril_server_ready = TRUE;
+ }
+ close(fd);
+ } else {
+ LOGE("Open %s fail:%d", MBTK_RILD_FILE_SER_READY, errno);
+ }
+
+ return ret;
+}
+
+/*
+* Will exec mbtk_boot_server_ready and mbtk_boot_net_ready if is_first_boot is true.
+*/
+static void ready_state_update()
+{
+ int fd = open(MBTK_RILD_FILE_NET_READY, O_RDONLY, 0644);
+ char buff[10];
+ if(fd > 0) {
+ if(read(fd, buff, sizeof(buff)) > 0) {
+ ril_net_ready = TRUE;
+ } else {
+ ril_net_ready = FALSE;
+ }
+
+ close(fd);
+ } else {
+ ril_net_ready = FALSE;
+ LOGE("Open %s fail:%d", MBTK_RILD_FILE_NET_READY, errno);
+ }
+
+ fd = open(MBTK_RILD_FILE_SER_READY, O_RDONLY, 0644);
+ if(fd > 0) {
+ if(read(fd, buff, sizeof(buff)) > 0) {
+ ril_server_ready = TRUE;
+ } else {
+ ril_server_ready = FALSE;
+ }
+
+ close(fd);
+ } else {
+ ril_server_ready = FALSE;
+ LOGE("Open %s fail:%d", MBTK_RILD_FILE_SER_READY, errno);
+ }
+}
+
+static void mbtk_net_ready()
+{
+ // /etc/init.d/mbtk_boot_net_ready
+ if(!ril_net_ready) {
+ if(access(MBTK_BOOT_NET_READY , X_OK) == 0) {
+ LOGD("Exec : %s", MBTK_BOOT_NET_READY);
+ system(MBTK_BOOT_NET_READY);
+ } else {
+ LOGE("%s can not exec.", MBTK_BOOT_NET_READY);
+ }
+ net_ready_set();
+ } else {
+ LOGD("No exec : %s", MBTK_BOOT_NET_READY);
+ }
+}
+
+static void mbtk_ril_ready()
+{
+ // /etc/init.d/mbtk_boot_server_ready
+ if(!ril_server_ready) {
+ if(access(MBTK_BOOT_SERVER_READY , X_OK) == 0) {
+ LOGD("Exec : %s", MBTK_BOOT_SERVER_READY);
+ system(MBTK_BOOT_SERVER_READY);
+ } else {
+ LOGE("%s can not exec.", MBTK_BOOT_SERVER_READY);
+ }
+ ser_ready_set();
+ } else {
+ LOGD("No exec : %s", MBTK_BOOT_SERVER_READY);
+ }
+}
+
+static sock_cli_info_t* cli_find(int fd)
+{
+ sock_cli_info_t *result = NULL;
+ list_first(ril_info.sock_client_list);
+ while ((result = (sock_cli_info_t*) list_next(ril_info.sock_client_list)))
+ {
+ if (result->fd == fd)
+ return result;
+ }
+
+ return NULL;
+}
+
+static void cli_close(sock_cli_info_t* client)
+{
+ struct epoll_event ev;
+ memset(&ev,0,sizeof(struct epoll_event));
+ ev.data.fd = client->fd;
+ ev.events = EPOLLIN | EPOLLERR | EPOLLET;
+ epoll_ctl(ril_info.epoll_fd, EPOLL_CTL_DEL, client->fd, &ev);
+
+ close(client->fd);
+
+ if(list_remove(ril_info.sock_client_list, client))
+ {
+ sock_cli_free_func(client);
+ }
+}
+
+static void ril_error_pack_send(int fd, int ril_id, int msg_index, int err)
+{
+ ril_msg_pack_info_t* pack = ril_msg_pack_creat(RIL_MSG_TYPE_RSP, ril_id, msg_index, NULL, 0);
+ if(pack)
+ {
+ pack->err = (uint16)err;
+ ril_pack_send(fd, pack);
+ ril_msg_pack_free(pack);
+ }
+ else
+ {
+ LOGW("ril_msg_pack_creat() fail.");
+ }
+}
+
+void ril_rsp_pack_send(int fd, int ril_id, int msg_index, const void* data, int data_len)
+{
+ ril_msg_pack_info_t* pack = ril_msg_pack_creat(RIL_MSG_TYPE_RSP, ril_id, msg_index, data, data_len);
+ if(pack)
+ {
+ pack->err = (uint16)MBTK_RIL_ERR_SUCCESS;
+#if 0
+ if(data != NULL && data_len > 0)
+ {
+ pack->data_len = (uint16)data_len;
+ pack->data = (uint8*)mbtk_memcpy(data, data_len);
+ }
+#endif
+ ril_pack_send(fd, pack);
+ ril_msg_pack_free(pack);
+ }
+ else
+ {
+ LOGW("ril_msg_pack_creat() fail.");
+ }
+}
+
+void ril_ind_pack_send(int fd, int msg_id, const void* data, int data_len)
+{
+ ril_msg_pack_info_t* pack = ril_msg_pack_creat(RIL_MSG_TYPE_IND, msg_id, RIL_MSG_INDEX_INVALID, data, data_len);
+ if(pack)
+ {
+ pack->err = (uint16)0;
+#if 0
+ if(data != NULL && data_len > 0)
+ {
+ pack->data_len = (uint16)data_len;
+ pack->data = (uint8*)mbtk_memcpy(data, data_len);
+ }
+#endif
+ ril_pack_send(fd, pack);
+ ril_msg_pack_free(pack);
+ }
+ else
+ {
+ LOGW("ril_msg_pack_creat() fail.");
+ }
+}
+
+
+static void onUnsolicited(const char *s, const char *sms_pdu)
+{
+ LOGD("URC : %s", s);
+#if 0
+ // MBTK_AT_READY
+ if (strStartsWith(s, "MBTK_AT_READY")) // AT ready.
+ {
+
+ }
+ else if(strStartsWith(s, "*RADIOPOWER:")) // "*RADIOPOWER: 1"
+ {
+ const char* ptr = s + strlen("*RADIOPOWER:");
+ while(*ptr != '\0' && *ptr == ' ' )
+ {
+ ptr++;
+ }
+
+ uint8 state;
+ if(*ptr == '1') {
+ //net_info.radio_state = MBTK_RADIO_STATE_ON;
+ // mbtk_radio_ready_cb();
+ state = (uint8)1;
+ } else {
+ //net_info.radio_state = MBTK_RADIO_STATE_OFF;
+ state = (uint8)0;
+ }
+ urc_msg_distribute(true, INFO_URC_MSG_RADIO_STATE, &state, sizeof(uint8));
+ }
+ // "CONNECT"
+ else if(strStartsWith(s, "CONNECT"))
+ {
+ if(cgact_wait.waitting && cgact_wait.act) {
+ cgact_wait.waitting = false;
+ }
+
+ uint8 data_pdp;
+ data_pdp = 1; //
+ urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));
+ }
+ // +CGEV:
+ // +CGEV: NW DEACT <cid>,<cid>
+ // +CGEV: ME DEACT <cid>,<cid>
+ // +CGEV: NW PDN DEACT <cid>
+ // +CGEV: ME PDN DEACT <cid>
+ // +CGEV: NW DETACH
+ // +CGEV: ME DETACH
+ //
+ // +CGEV: NW ACT <cid>,<cid>
+ // +CGEV: ME ACT <cid>,<cid>
+ // +CGEV: EPS PDN ACT <cid>
+ // +CGEV: ME PDN ACT <cid>,<reason>,<cid>
+ // +CGEV: ME PDN ACT <cid>,<reason>
+ // +CGEV: NW PDN ACT <cid>
+ // +CGEV: EPS ACT <cid>
+ // +CGEV: NW MODIFY <cid>,<reason>
+ // +CGEV: NW REATTACH
+ else if(strStartsWith(s, "+CGEV:"))
+ {
+ if(at_process) {
+ if(cgact_wait.act) {
+ if(strStartsWith(s, "+CGEV: ME PDN ACT ")) { // +CGEV: ME PDN ACT 15,4
+ if(cgact_wait.cid == atoi(s + 18)) {
+ cgact_wait.waitting = false;
+ }
+
+ uint8 data_pdp;
+ char* tmp_s = memdup(s + 18,strlen(s + 18));
+ char* free_ptr = tmp_s;
+ char *line = tmp_s;
+ int tmp_int;
+ if (at_tok_start(&line) < 0)
+ {
+ goto at_PDP_CREG_EXIT;
+ }
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ goto at_PDP_CREG_EXIT;
+ }
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ goto at_PDP_CREG_EXIT;
+ }
+ data_pdp = tmp_int;
+at_PDP_CREG_EXIT:
+ free(free_ptr);
+
+ //data_pdp = (uint8)atoi(s + 20); //reason
+ if(cgact_wait.cid >= 1 && cgact_wait.cid < 8)
+ {
+ if(data_pdp == 0)
+ {
+ data_pdp = 25;
+ urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));
+ //data_pdp = cgact_wait.cid + 200;
+ }
+ else if(data_pdp == 1)
+ {
+ data_pdp = 26;
+ urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));
+ }
+ else if(data_pdp == 2)
+ {
+ data_pdp = 27;
+ urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));
+ }
+ else if(data_pdp == 3)
+ {
+ data_pdp = 27;
+ urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));
+ }
+ else
+ {
+
+ }
+ if(cgact_wait.cid != 0)
+ {
+ data_pdp = cgact_wait.cid + 200;
+ urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));
+ }
+ }
+ } else if(strStartsWith(s, "+CGEV: NW MODIFY ")) { // +CGEV: NW MODIFY 1,4
+ if(cgact_wait.cid == atoi(s + 17)) {
+ cgact_wait.waitting = false;
+ }
+ }
+ } else {
+ if(strStartsWith(s, "+CGEV: ME PDN DEACT ")) { // +CGEV: ME PDN DEACT 1
+ if(cgact_wait.cid == atoi(s + 20)) {
+ cgact_wait.waitting = false;
+ }
+ uint8 data_pdp;
+ data_pdp = 0; //
+ urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));
+ if(cgact_wait.cid != 0)
+ {
+ data_pdp = cgact_wait.cid + 100;
+ urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));
+ }
+ }
+ }
+ } else {
+ // apn_state_set
+
+ // +CGEV: NW PDN DEACT <cid>
+
+ // +CGEV: EPS PDN ACT 1
+ // +CGEV: ME PDN ACT 8,1
+
+ // +CGEV: ME PDN ACT 2,4
+ uint8 data[2] = {0xFF};
+ if(strStartsWith(s, "+CGEV: NW PDN DEACT ")) { // +CGEV: NW PDN DEACT <cid>
+ //apn_state_set(atoi(s + 20), false);
+ data[0] = (uint8)0;
+ data[1] = (uint8)atoi(s + 20);
+
+ uint8 data_pdp;
+ data_pdp = 0; //
+ urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));
+ data_pdp = data[1] + 100;
+ urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));
+ } else if(strStartsWith(s, "+CGEV: EPS PDN ACT ")) { // +CGEV: EPS PDN ACT <cid>
+ //apn_state_set(atoi(s + 19), true);
+ data[0] = (uint8)1;
+ data[1] = (uint8)atoi(s + 19);
+ } else if(strStartsWith(s, "+CGEV: ME PDN DEACT ")) { // +CGEV: EPS PDN DEACT <cid>
+ //apn_state_set(atoi(s + 19), true);
+ data[0] = (uint8)0;
+ data[1] = (uint8)atoi(s + 20);
+
+ uint8 data_pdp;
+ data_pdp = 0; //
+ urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));
+ data_pdp = data[1] + 100;
+ urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));
+ } else if(strStartsWith(s, "+CGEV: ME PDN ACT ")) { // +CGEV: ME PDN ACT <cid>,1
+ //apn_state_set(atoi(s + 18), true);
+ data[0] = (uint8)1;
+ data[1] = (uint8)atoi(s + 18);
+
+ uint8 data_pdp;
+ char* tmp_s = memdup(s + 18,strlen(s + 18));
+ char* free_ptr = tmp_s;
+ char *line = tmp_s;
+ int tmp_int;
+ if (at_tok_start(&line) < 0)
+ {
+ goto PDP_CREG_EXIT;
+ }
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ goto PDP_CREG_EXIT;
+ }
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ goto PDP_CREG_EXIT;
+ }
+ data_pdp = tmp_int;
+PDP_CREG_EXIT:
+ free(free_ptr);
+ //data_pdp = (uint8)atoi(s + 20); //reason
+ if(data[1] >= 1 && data[1] < 8)
+ {
+ if(data_pdp == 0)
+ {
+ data_pdp = 25;
+ urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));
+ }
+ else if(data_pdp == 1)
+ {
+ data_pdp = 26;
+ urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));
+ }
+ else if(data_pdp == 2)
+ {
+ data_pdp = 27;
+ urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));
+ }
+ else if(data_pdp == 3)
+ {
+ data_pdp = 27;
+ urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));
+ }
+ else
+ {
+
+ }
+
+ data_pdp = data[1] + 200;
+ urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));
+ data[1] = 0;
+ }
+ } else {
+ LOGI("No process : %s", s);
+ }
+
+ urc_msg_distribute(true, INFO_URC_MSG_CGEV, data, sizeof(uint8) * 2);
+ }
+ }
+ // +CREG: 1, "8010", "000060a5", 0, 2, 0
+ // +CREG: 1, "8330", "06447347", 7, 2, 0
+ // +CEREG: 1, "8330", "06447347", 7
+ // $CREG: 1, "8330", "06447347", 7,"0d4", 2, 0
+ // $CREG: 1, "8010", "000060a7", 0,, 2, 0
+ // +CGREG: 1
+ else if(strStartsWith(s, "+CGREG:") // GMS/WCDMA data registed.
+ || strStartsWith(s, "+CEREG:")) // LTE data registed.
+ {
+ char* tmp_s = s + 7;
+ static bool net_led_gms_wcdma = FALSE;
+ static bool net_led_lte = FALSE;
+ while(*tmp_s && *tmp_s == ' ')
+ tmp_s++;
+ uint8 data[2];
+ data[0] = (uint8)atoi(tmp_s); // Reg State.
+
+ if(strStartsWith(s, "+CGREG:"))
+ {
+ data[1] = 0; // GMS/WCDMA
+ if(data[0] == 1)
+ {
+ net_led_gms_wcdma = TRUE;
+ }
+ else
+ {
+ net_led_gms_wcdma = FALSE;
+ }
+
+ }
+ else
+ {
+ data[1] = 1; // LTE
+ if(data[0] == 1)
+ {
+ net_led_lte = TRUE;
+ }
+ else
+ {
+ net_led_lte = FALSE;
+ }
+ }
+
+ if(FALSE == net_led_gms_wcdma && FALSE == net_led_lte)
+ {
+ //mbtk_net_led_set(MBTK_NET_LED_SEARCH_NETWORK);
+ }
+ else
+ {
+ //mbtk_net_led_set(MBTK_NET_LED_NET_CONNECT);
+ mbtk_net_ready();
+ }
+
+ urc_msg_distribute(true, INFO_URC_MSG_NET_PS_REG_STATE, data, sizeof(data));
+ urc_msg_distribute(true, INFO_URC_MSG_NET_STATE_LOG, NULL, 0);
+ }
+ // +CREG: 1, "8010", "000060a5", 0, 2, 0
+ // +CREG: 1, "8330", "06447347", 7, 2, 0
+ // +CREG: 0
+ else if(strStartsWith(s, "+CREG:")) // GMS/WCDMA/LTE CS registed.
+ {
+ uint8 data[3];
+ data[0] = (uint8)MBTK_NET_CS_STATE;
+ char* tmp_s = memdup(s,strlen(s));
+ char* free_ptr = tmp_s;
+ char *line = tmp_s;
+ int tmp_int;
+ char *tmp_str;
+ if (at_tok_start(&line) < 0)
+ {
+ goto CREG_EXIT;
+ }
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ goto CREG_EXIT;
+ }
+ data[1] = (uint8)tmp_int; // Reg State.
+ if (data[1])
+ {
+ if (at_tok_nextstr(&line, &tmp_str) < 0)
+ {
+ goto CREG_EXIT;
+ }
+ if (at_tok_nextstr(&line, &tmp_str) < 0)
+ {
+ goto CREG_EXIT;
+ }
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ goto CREG_EXIT;
+ }
+ data[2] = (uint8)tmp_int; // AcT
+ } else {
+ data[2] = (uint8)0xFF; // AcT
+ }
+ if(data[1] == 5)
+ {
+ uint8 data_pdp;
+ data_pdp = 5; //
+ urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));
+ }
+ urc_msg_distribute(false, INFO_URC_MSG_NET_CS_REG_STATE, data, sizeof(data));
+ urc_msg_distribute(true, INFO_URC_MSG_NET_STATE_LOG, NULL, 0);
+CREG_EXIT:
+ free(free_ptr);
+ }
+ // +CLCC: 1, 1, 6, 0, 0, "18981911691", 129, "",, 0
+ else if(strStartsWith(s, "+CLCC:"))
+ {
+ mbtk_call_info_t reg;
+ reg.call_wait = MBTK_CLCC;
+ char* tmp_s = memdup(s,strlen(s));
+ char* free_ptr = tmp_s;
+ char *line = tmp_s;
+ int tmp_int;
+ char *tmp_str;
+ int err;
+
+ err = at_tok_start(&line);
+ if (err < 0)
+ {
+ goto CLCC_EXIT;
+ }
+ err = at_tok_nextint(&line, &tmp_int); // dir1
+ if (err < 0)
+ {
+ goto CLCC_EXIT;
+ }
+ reg.dir1 = (uint8)tmp_int;
+ err = at_tok_nextint(&line, &tmp_int);// dir
+ if (err < 0)
+ {
+ goto CLCC_EXIT;
+ }
+ reg.dir = (uint8)tmp_int;
+ err = at_tok_nextint(&line, &tmp_int);// state
+ if (err < 0)
+ {
+ goto CLCC_EXIT;
+ }
+ reg.state = (uint8)tmp_int;
+ err = at_tok_nextint(&line, &tmp_int);// mode
+ if (err < 0)
+ {
+ goto CLCC_EXIT;
+ }
+ reg.mode = (uint8)tmp_int;
+ err = at_tok_nextint(&line, &tmp_int);// mpty
+ if (err < 0)
+ {
+ goto CLCC_EXIT;
+ }
+ reg.mpty = (uint8)tmp_int;
+ err = at_tok_nextstr(&line, &tmp_str); // phone_number
+ if (err < 0)
+ {
+ goto CLCC_EXIT;
+ }
+
+ memset(reg.phone_number,0,sizeof(reg.phone_number));
+ memcpy(reg.phone_number, tmp_str, strlen(tmp_str));
+ err = at_tok_nextint(&line, &tmp_int);// tpye
+ if (err < 0)
+ {
+ goto CLCC_EXIT;
+ }
+ reg.type = (uint8)tmp_int;
+ urc_msg_distribute(false, INFO_URC_MSG_CALL_STATE, ®, sizeof(mbtk_call_info_t));
+CLCC_EXIT:
+ free(free_ptr);
+ }
+ // +CPAS: 4
+ else if(strStartsWith(s, "+CPAS:"))
+ {
+ mbtk_call_info_t reg;
+ reg.call_wait = 0;
+ char* tmp_s = memdup(s,strlen(s));
+ char* free_ptr = tmp_s;
+ char *line = tmp_s;
+ int tmp_int;
+ int err;
+
+ memset(®,0,sizeof(reg));
+
+ err = at_tok_start(&line);
+ if (err < 0)
+ {
+ goto CPAS_EXIT;
+ }
+ err = at_tok_nextint(&line, &tmp_int);
+ if (err < 0)
+ {
+ goto CPAS_EXIT;
+ }
+ reg.pas = (uint8)tmp_int;
+ reg.call_wait = MBTK_CPAS;
+ urc_msg_distribute(false, INFO_URC_MSG_CALL_STATE, ®, sizeof(mbtk_call_info_t));
+CPAS_EXIT:
+ free(free_ptr);
+ }
+ // +CALLDISCONNECT: 1
+ else if(strStartsWith(s, "+CALLDISCONNECT:"))
+ {
+ mbtk_call_info_t reg;
+ reg.call_wait = 0;
+ char* tmp_s = memdup(s,strlen(s));
+ char* free_ptr = tmp_s;
+ char *line = tmp_s;
+ int tmp_int;
+ int err;
+
+ memset(®,0,sizeof(reg));
+
+ err = at_tok_start(&line);
+ if (err < 0)
+ {
+ goto CALLDISCONNECTED_EXIT;
+ }
+ err = at_tok_nextint(&line, &tmp_int);
+ if (err < 0)
+ {
+ goto CALLDISCONNECTED_EXIT;
+ }
+ reg.disconnected_id = tmp_int;
+ reg.call_wait = MBTK_DISCONNECTED;
+
+ if(reg.call_wait == MBTK_DISCONNECTED)
+ {
+ //mbtk_net_led_set(MBTK_NET_LED_CALL_DISCONNECT);
+ }
+
+ urc_msg_distribute(false, INFO_URC_MSG_CALL_STATE, ®, sizeof(mbtk_call_info_t));
+
+CALLDISCONNECTED_EXIT:
+ free(free_ptr);
+ }
+ // *SIMDETEC:1,SIM
+ else if(strStartsWith(s, "*SIMDETEC:"))
+ {
+ if(strStartsWith(s, "*SIMDETEC:1,NOS"))
+ {
+ net_info.sim_state = MBTK_SIM_ABSENT;
+ }
+
+ sim_info_reg.sim = -1;
+ if(strStartsWith(s, "*SIMDETEC:1,NOS"))
+ sim_info_reg.sim = 0;
+ else if(strStartsWith(s, "*SIMDETEC:1,SIM"))
+ sim_info_reg.sim = 1;
+ if(sim_info_reg.sim == 0)
+ {
+ uint8 data_pdp;
+ data_pdp = 11; //
+ urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));
+ }
+ urc_msg_distribute(false, INFO_URC_MSG_SIM_STATE, &sim_info_reg, sizeof(mbtk_sim_card_info));
+ }
+ // *EUICC:1
+/*0: SIM
+1: USIM
+2: TEST SIM
+3: TEST USIM
+4: UNKNOWN
+Note: *EUICC:
+*/
+ else if(strStartsWith(s, "*EUICC:"))
+ {
+ sim_info_reg.sim_card_type = -1;
+ if(strStartsWith(s, "*EUICC: 0"))
+ sim_info_reg.sim_card_type = 1;
+ else if(strStartsWith(s, "*EUICC: 1"))
+ sim_info_reg.sim_card_type = 2;
+ else if(strStartsWith(s, "*EUICC: 2"))
+ sim_info_reg.sim_card_type = 1;
+ else if(strStartsWith(s, "*EUICC: 3"))
+ sim_info_reg.sim_card_type = 2;
+ else if(strStartsWith(s, "*EUICC: 4"))
+ sim_info_reg.sim_card_type = 0;
+ urc_msg_distribute(false, INFO_URC_MSG_SIM_STATE, &sim_info_reg, sizeof(mbtk_sim_card_info));
+ }
+ // +CPIN: SIM PIN
+ else if(strStartsWith(s, "+CPIN:"))
+ {
+ sim_info_reg.sim = -1;
+ if(strStartsWith(s, "+CPIN: READY"))
+ {
+ sim_info_reg.sim = 1;
+ net_info.sim_state = MBTK_SIM_READY;
+ }
+ else if(strStartsWith(s, "+CPIN: SIM PIN"))
+ {
+ sim_info_reg.sim = 2;
+ net_info.sim_state = MBTK_SIM_PIN;
+ }
+ else if(strStartsWith(s, "+CPIN: SIM PUK"))
+ {
+ sim_info_reg.sim = 3;
+ net_info.sim_state = MBTK_SIM_PUK;
+ }
+ else if(strStartsWith(s, "+CPIN: PH-SIMLOCK PIN"))
+ {
+ sim_info_reg.sim = 4;
+ net_info.sim_state = MBTK_SIM_ABSENT;
+ }
+ else if(strStartsWith(s, "+CPIN: PH-SIMLOCK PUK"))
+ {
+ sim_info_reg.sim = 5;
+ net_info.sim_state = MBTK_SIM_ABSENT;
+ }
+ else if(strStartsWith(s, "+CPIN: PH-FSIM PIN"))
+ {
+ sim_info_reg.sim = 6;
+ net_info.sim_state = MBTK_SIM_ABSENT;
+ }
+ else if(strStartsWith(s, "+CPIN: PH-FSIM PUK"))
+ {
+ sim_info_reg.sim = 7;
+ net_info.sim_state = MBTK_SIM_ABSENT;
+ }
+ else if(strStartsWith(s, "+CPIN: SIM PIN2"))
+ {
+ sim_info_reg.sim = 8;
+ net_info.sim_state = MBTK_SIM_ABSENT;
+ }
+ else if(strStartsWith(s, "+CPIN: SIM PUK2"))
+ {
+ sim_info_reg.sim = 9;
+ net_info.sim_state = MBTK_SIM_ABSENT;
+ }
+ else if(strStartsWith(s, "+CPIN: PH-NET PIN"))
+ {
+ sim_info_reg.sim = 10;
+ net_info.sim_state = MBTK_SIM_NETWORK_PERSONALIZATION;
+ }
+ else if(strStartsWith(s, "+CPIN: PH-NET PUK"))
+ {
+ sim_info_reg.sim = 11;
+ net_info.sim_state = MBTK_SIM_ABSENT;
+ }
+ else if(strStartsWith(s, "+CPIN: PH-NETSUB PINMT"))
+ {
+ sim_info_reg.sim = 12;
+ net_info.sim_state = MBTK_SIM_ABSENT;
+ }
+ else if(strStartsWith(s, "+CPIN: PH-NETSUB PUK"))
+ {
+ sim_info_reg.sim = 13;
+ net_info.sim_state = MBTK_SIM_ABSENT;
+ }
+ else if(strStartsWith(s, "+CPIN: PH-SP PIN"))
+ {
+ sim_info_reg.sim = 14;
+ net_info.sim_state = MBTK_SIM_ABSENT;
+ }
+ else if(strStartsWith(s, "+CPIN: PH-SP PUK"))
+ {
+ sim_info_reg.sim = 15;
+ net_info.sim_state = MBTK_SIM_ABSENT;
+ }
+ else if(strStartsWith(s, "+CPIN: PH-CORP PIN"))
+ {
+ sim_info_reg.sim = 16;
+ net_info.sim_state = MBTK_SIM_ABSENT;
+ }
+ else if(strStartsWith(s, "+CPIN: PH-CORP PUK"))
+ {
+ sim_info_reg.sim = 17;
+ net_info.sim_state = MBTK_SIM_ABSENT;
+ }
+ else if(strStartsWith(s, "+CPIN: SIM REMOVED"))
+ {
+ sim_info_reg.sim = 18;
+ net_info.sim_state = MBTK_SIM_ABSENT;
+ }
+ else
+ sim_info_reg.sim = 20;
+
+ if(sim_info_reg.sim == 18)
+ {
+ uint8 data_pdp;
+ data_pdp = 11; //
+ urc_msg_distribute(false, INFO_URC_MSG_PDP_STATE, &data_pdp, sizeof(uint8));
+ }
+
+ urc_msg_distribute(false, INFO_URC_MSG_SIM_STATE, &sim_info_reg, sizeof(mbtk_sim_card_info));
+ }
+ // +CMT: ,23
+ // 0891683108200855F6240D91688189911196F10000221130717445230331D90C
+ else if(strStartsWith(s, "+CMT:") || sms_cmt)
+ {
+ if(!sms_cmt){
+ sms_cmt = true;
+ }else{
+ sms_cmt = false;
+ }
+ printf("+CMT() sms_cmt:%d, s:%s, len:%d\n",sms_cmt, s, strlen(s));
+ urc_msg_distribute(false, INFO_URC_MSG_SMS_STATE, s, strlen(s));
+ }
+#if 0
+ // LTE data registed.
+ // +CEREG: 1, "8330", "06447347", 7
+ else if(strStartsWith(s, "+CEREG:"))
+ {
+ char* tmp_s = memdup(s,strlen(s));
+ char* free_ptr = tmp_s;
+ char *line = tmp_s;
+ int tmp_int;
+ char *tmp_str;
+ if (at_tok_start(&line) < 0)
+ {
+ goto CREG_EXIT;
+ }
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ goto CREG_EXIT;
+ }
+ uint8 data = (uint8)tmp_int; // Reg State.
+
+ urc_msg_distribute(INFO_URC_MSG_NET_REG_STATE, &data, sizeof(uint8));
+CREG_EXIT:
+ free(free_ptr);
+ }
+#endif
+ /*
+ // <mcc>, <length of mnc>, <mnc>, <tac>, <PCI>, <dlEuarfcn>, < ulEuarfcn >, <band>, <dlBandwidth>,
+ // <rsrp>,<rsrq>, <sinr>,
+ // errcModeState,emmState,serviceState,IsSingleEmmRejectCause,EMMRejectCause,mmeGroupId,mmeCode,mTmsi,
+ // cellId,subFrameAssignType,specialSubframePatterns,transMode
+ // mainRsrp,diversityRsrp,mainRsrq,diversityRsrq,rssi,cqi,pathLoss,tb0DlTpt,tb1DlTpt,tb0DlPeakTpt,tb1DlPeakTpt,tb0UlPeakTpt,
+ // tb1UlPeakTpt,dlThroughPut,dlPeakThroughPut,averDlPRB,averCQITb0,averCQITb1,rankIndex,grantTotal,ulThroughPut,ulPeakThroughPut,currPuschTxPower,averUlPRB,
+ // dlBer, ulBer,
+ // diversitySinr, diversityRssi
+ +EEMLTESVC: 1120, 2, 0, 33584, 430, 40936, 40936, 41, 20,
+ 0, 0, 0,
+ 1, 10, 0, 1, 0, 1059, 78, 3959566565,
+ 105149248, 2, 7, 7,
+ 0, 0, 0, 0, 0, 0, 0, 1190919, 0, 0, 0, 16779777,
+ 0, 5112867, 3959566565, 2, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,
+ 7, 44
+ */
+ else if(strStartsWith(s, "+EEMLTESVC:")) // LTE Server Cell
+ {
+ // tac, PCI, dlEuarfcn, ulEuarfcn, band
+ if(cell_info.running) {
+ int tmp_int;
+ int i = 0;
+ char* tmp_s = memdup(s,strlen(s));
+ char* free_ptr = tmp_s;
+ char *line = tmp_s;
+ if (at_tok_start(&line) < 0)
+ {
+ goto EEMLTESVC_EXIT;
+ }
+
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ goto EEMLTESVC_EXIT;
+ }
+ cell_info.cell[cell_info.cell_num].value6 = (uint32)tmp_int; //mcc
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ goto EEMLTESVC_EXIT;
+ }
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ goto EEMLTESVC_EXIT;
+ }
+ cell_info.cell[cell_info.cell_num].value7 = (uint32)tmp_int; //mnc
+ /*
+ // Jump 2 integer.
+ i = 0;
+ while(i < 2) {
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ goto EEMLTESVC_EXIT;
+ }
+ i++;
+ }
+ */
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ goto EEMLTESVC_EXIT;
+ }
+ cell_info.cell[cell_info.cell_num].value1 = (uint32)tmp_int; //tac
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ goto EEMLTESVC_EXIT;
+ }
+ cell_info.cell[cell_info.cell_num].value2 = (uint32)tmp_int; //pci
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ goto EEMLTESVC_EXIT;
+ }
+ cell_info.cell[cell_info.cell_num].value3 = (uint32)tmp_int; //dl arfcn
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ goto EEMLTESVC_EXIT;
+ }
+ cell_info.cell[cell_info.cell_num].value4 = (uint32)tmp_int; //ul arfcn
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ goto EEMLTESVC_EXIT;
+ }
+ cell_info.cell[cell_info.cell_num].value5 = (uint32)tmp_int; //band
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ goto EEMLTESVC_EXIT;
+ }
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ goto EEMLTESVC_EXIT;
+ }
+ cell_info.cell[cell_info.cell_num].value8 = (uint32)tmp_int; //cid
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ goto EEMLTESVC_EXIT;
+ }
+ cell_info.cell[cell_info.cell_num].value9 = (uint32)tmp_int; //rsrp
+
+ for(i =0; i < 10; i++)
+ {
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ goto EEMLTESVC_EXIT;
+ }
+ }
+ cell_info.cell[cell_info.cell_num].value10 = (uint32)tmp_int; //cell identiy
+
+ cell_info.cell_num++;
+
+EEMLTESVC_EXIT:
+ free(free_ptr);
+ }
+ }
+ /*
+ // index,phyCellId,euArfcn,rsrp,rsrq
+ +EEMLTEINTER: 0, 65535, 38950, 0, 0
+ */
+ else if(strStartsWith(s, "+EEMLTEINTER:") || strStartsWith(s, "+EEMLTEINTRA:")) // LTE ÒìÆµ/Í¬ÆµÐ¡Çø
+ {
+ // phyCellId,euArfcn,rsrp,rsrq
+ if(cell_info.running) {
+ int tmp_int;
+ char* tmp_s = memdup(s,strlen(s));
+ char* free_ptr = tmp_s;
+ char *line = tmp_s;
+ if (at_tok_start(&line) < 0)
+ {
+ goto EEMLTEINTER_EXIT;
+ }
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ goto EEMLTEINTER_EXIT;
+ }
+ if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int <= 0 || tmp_int > 503)
+ {
+ goto EEMLTEINTER_EXIT;
+ }
+ cell_info.cell[cell_info.cell_num].value1 = (uint32)tmp_int;
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ goto EEMLTEINTER_EXIT;
+ }
+ cell_info.cell[cell_info.cell_num].value2 = (uint32)tmp_int;
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ goto EEMLTEINTER_EXIT;
+ }
+ cell_info.cell[cell_info.cell_num].value3 = (uint32)tmp_int;
+ LOG("cell line : %s", line);
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ goto EEMLTEINTER_EXIT;
+ }
+ cell_info.cell[cell_info.cell_num].value4 = (uint32)tmp_int;
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ LOG("cell tmp_int : %d", tmp_int);
+ goto EEMLTEINTER_EXIT;
+ }
+ cell_info.cell[cell_info.cell_num].value5 = (uint32)tmp_int;
+ LOG("cell value5 : %d", cell_info.cell[cell_info.cell_num].value5);
+ cell_info.cell_num++;
+EEMLTEINTER_EXIT:
+ free(free_ptr);
+ }
+ }
+ // Do nothing
+ else if(strStartsWith(s, "+EEMLTEINTERRAT:")) // LTE RATÐ¡ÇøÐÅÏ¢
+ {
+ if(cell_info.running) {
+
+ }
+ }
+ // WCDMA
+ /*
+ // Mode, sCMeasPresent, sCParamPresent, ueOpStatusPresent,
+
+ // if sCMeasPresent == 1
+ // cpichRSCP, utraRssi, cpichEcN0, sQual, sRxLev, txPower,
+ // endif
+
+ // if sCParamPresent == 1
+ // rac, nom, mcc, mnc_len, mnc, lac, ci,
+ // uraId, psc, arfcn, t3212, t3312, hcsUsed, attDetAllowed,
+ // csDrxCycleLen, psDrxCycleLen, utranDrxCycleLen, HSDPASupport, HSUPASupport,
+ // endif
+
+ // if ueOpStatusPresent == 1
+ // rrcState, numLinks, srncId, sRnti,
+ // algPresent, cipherAlg, cipherOn, algPresent, cipherAlg, cipherOn,
+ // HSDPAActive, HSUPAActive, MccLastRegisteredNetwork, MncLastRegisteredNetwork, TMSI, PTMSI, IsSingleMmRejectCause, IsSingleGmmRejectCause,
+ // MMRejectCause, GMMRejectCause, mmState, gmmState, gprsReadyState, readyTimerValueInSecs, NumActivePDPContext, ULThroughput, DLThroughput,
+ // serviceStatus, pmmState, LAU_status, LAU_count, RAU_status, RAU_count
+ // endif
+ //
+ +EEMUMTSSVC: 3, 1, 1, 1,
+ -80, 27, -6, -18, -115, -32768,
+ 1, 1, 1120, 2, 1, 61697, 168432821,
+ 15, 24, 10763, 0, 0, 0, 0,
+ 128, 128, 65535, 0, 0,
+ 2, 255, 65535, 4294967295,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 1,
+ 28672, 28672, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0
+ */
+ else if(strStartsWith(s, "+EEMUMTSSVC:")) // WCDMA Server Cell
+ {
+ // lac, ci, arfcn
+ if(cell_info.running) {
+ int tmp_int;
+ int i = 0;
+ char* tmp_s = memdup(s,strlen(s));
+ char* free_ptr = tmp_s;
+ char *line = tmp_s;
+ if (at_tok_start(&line) < 0)
+ {
+ goto EEMUMTSSVC_EXIT;
+ }
+ // Jump 12 integer.
+ i = 0;
+ while(i < 12) {
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ goto EEMUMTSSVC_EXIT;
+ }
+ i++;
+ }
+ // mcc
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ goto EEMUMTSSVC_EXIT;
+ }
+ cell_info.cell[cell_info.cell_num].value4= (uint32)tmp_int;
+ // mnc
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ goto EEMUMTSSVC_EXIT;
+ }
+ cell_info.cell[cell_info.cell_num].value5= (uint32)tmp_int;
+ // lac
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ goto EEMUMTSSVC_EXIT;
+ }
+ cell_info.cell[cell_info.cell_num].value1 = (uint32)tmp_int;
+ // ci
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ goto EEMUMTSSVC_EXIT;
+ }
+ cell_info.cell[cell_info.cell_num].value2 = (uint32)tmp_int;
+
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ goto EEMUMTSSVC_EXIT;
+ }
+ // cpi
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ goto EEMUMTSSVC_EXIT;
+ }
+ cell_info.cell[cell_info.cell_num].value6= (uint32)tmp_int;
+ /*
+ // Jump 2 integer.
+ i = 0;
+ while(i < 2) {
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ goto EEMUMTSSVC_EXIT;
+ }
+ i++;
+ }
+ */
+ // arfcn
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ goto EEMUMTSSVC_EXIT;
+ }
+ cell_info.cell[cell_info.cell_num].value3 = (uint32)tmp_int;
+
+ cell_info.cell_num++;
+EEMUMTSSVC_EXIT:
+ free(free_ptr);
+ }
+ }
+ /*
+ // index, cpichRSCP, utraRssi, cpichEcN0, sQual, sRxLev ,mcc, mnc, lac, ci, arfcn, psc
+ +EEMUMTSINTRA: 0, -32768, -1, -32768, -18, -115, 0, 0, 65534, 1, 10763, 32
+ */
+ else if(strStartsWith(s, "+EEMUMTSINTRA:")) // WCDMAÁÙ½üÐ¡Çø
+ {
+ // lac, ci, arfcn
+ if(cell_info.running) {
+ int tmp_int;
+ int i = 0;
+ char* tmp_s = memdup(s,strlen(s));
+ char* free_ptr = tmp_s;
+ char *line = tmp_s;
+ if (at_tok_start(&line) < 0)
+ {
+ goto EEMUMTSINTRA_EXIT;
+ }
+ // Jump 8 integer.
+ i = 0;
+ while(i < 8) {
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ goto EEMUMTSINTRA_EXIT;
+ }
+ i++;
+ }
+
+ // lac
+ if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int <= 0 || tmp_int >= 65536)
+ {
+ goto EEMUMTSINTRA_EXIT;
+ }
+ cell_info.cell[cell_info.cell_num].value1 = (uint32)tmp_int;
+
+ // ci
+ if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int <= 0 || tmp_int >= 65536)
+ {
+ goto EEMUMTSINTRA_EXIT;
+ }
+ cell_info.cell[cell_info.cell_num].value2 = (uint32)tmp_int;
+
+ // arfcn
+ if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int <= 0 || tmp_int >= 65536)
+ {
+ goto EEMUMTSINTRA_EXIT;
+ }
+ cell_info.cell[cell_info.cell_num].value3 = (uint32)tmp_int;
+
+ cell_info.cell_num++;
+EEMUMTSINTRA_EXIT:
+ free(free_ptr);
+ }
+ }
+ /*
+ // index,gsmRssi,rxLev,C1,C2,mcc,mnc,lac,ci,arfcn,bsic
+ +EEMUMTSINTERRAT: 0, -32768, -107, -1, -1, 0, 0, 65534, 0, 117, 36
+ */
+ else if(strStartsWith(s, "+EEMUMTSINTERRAT:")) // WCDMA RATÐ¡ÇøÐÅÏ¢
+ {
+ // lac, ci, arfcn
+ if(cell_info.running) {
+ int tmp_int;
+ int i = 0;
+ char* tmp_s = memdup(s,strlen(s));
+ char* free_ptr = tmp_s;
+ char *line = tmp_s;
+ if (at_tok_start(&line) < 0)
+ {
+ goto EEMUMTSINTERRAT_EXIT;
+ }
+ // Jump 7 integer.
+ i = 0;
+ while(i < 7) {
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ goto EEMUMTSINTERRAT_EXIT;
+ }
+ i++;
+ }
+
+ // lac
+ if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int <= 0 || tmp_int >= 65536)
+ {
+ goto EEMUMTSINTERRAT_EXIT;
+ }
+ cell_info.cell[cell_info.cell_num].value1 = (uint32)tmp_int;
+
+ // ci
+ if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int <= 0 || tmp_int >= 65536)
+ {
+ goto EEMUMTSINTERRAT_EXIT;
+ }
+ cell_info.cell[cell_info.cell_num].value2 = (uint32)tmp_int;
+
+ // arfcn
+ if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int <= 0 || tmp_int >= 65536)
+ {
+ goto EEMUMTSINTERRAT_EXIT;
+ }
+ cell_info.cell[cell_info.cell_num].value3 = (uint32)tmp_int;
+
+ cell_info.cell_num++;
+EEMUMTSINTERRAT_EXIT:
+ free(free_ptr);
+ }
+ }
+ // GSM
+ // +EEMGINFOBASIC: 2
+ // Do nothing.
+ else if(strStartsWith(s, "+EEMGINFOBASIC:")) // Basic information in GSM
+ // 0: ME in Idle mode 1: ME in Dedicated mode 2: ME in PS PTM mode
+ {
+ if(cell_info.running) {
+
+ }
+ }
+ /*
+ // mcc, mnc_len, mnc, lac, ci, nom, nco,
+ // bsic, C1, C2, TA, TxPwr,
+ // RxSig, RxSigFull, RxSigSub, RxQualFull, RxQualSub,
+ // ARFCB_tch, hopping_chnl, chnl_type, TS, PacketIdle, rac, arfcn,
+ // bs_pa_mfrms, C31, C32, t3212, t3312, pbcch_support, EDGE_support,
+ // ncc_permitted, rl_timeout, ho_count, ho_succ, chnl_access_count, chnl_access_succ_count,
+ // gsmBand,channelMode
+ +EEMGINFOSVC: 1120, 2, 0, 32784, 24741, 2, 0,
+ 63, 36, 146, 1, 7,
+ 46, 42, 42, 7, 0,
+ 53, 0, 8, 0, 1, 6, 53,
+ 2, 0, 146, 42, 54, 0, 1,
+ 1, 32, 0, 0, 0, 0,
+ 0, 0
+ */
+ else if(strStartsWith(s, "+EEMGINFOSVC:")) // GSM Server Cell
+ {
+ // lac, ci, arfcn, bsic
+ LOG("+EEMGINFOSVC: 1= %d\n.",cell_info.running);
+ if(cell_info.running) {
+ int tmp_int;
+ int i = 0;
+ char* tmp_s = memdup(s,strlen(s));
+ char* free_ptr = tmp_s;
+ char *line = tmp_s;
+ if (at_tok_start(&line) < 0)
+ {
+ goto EEMGINFOSVC_EXIT;
+ }
+
+ // mcc
+ if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int <= 0 || tmp_int >= 65536)
+ {
+ goto EEMGINFOSVC_EXIT;
+ }
+ cell_info.cell[cell_info.cell_num].value5 = (uint32)tmp_int;
+
+ //mnc_len
+ if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int <= 0 || tmp_int >= 65536)
+ {
+ goto EEMGINFOSVC_EXIT;
+ }
+ // mnc
+ if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int <= 0 || tmp_int >= 65536)
+ {
+ goto EEMGINFOSVC_EXIT;
+ }
+ cell_info.cell[cell_info.cell_num].value6 = (uint32)tmp_int;
+
+ /*
+ // Jump 3 integer.
+ i = 0;
+ while(i < 3) {
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ goto EEMGINFOSVC_EXIT;
+ }
+ i++;
+ }
+ */
+ // lac
+ if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int < 0 || tmp_int >= 65536)
+ {
+ goto EEMGINFOSVC_EXIT;
+ }
+ cell_info.cell[cell_info.cell_num].value1 = (uint32)tmp_int;
+
+ // ci
+ if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int < 0 || tmp_int >= 65536)
+ {
+ goto EEMGINFOSVC_EXIT;
+ }
+ cell_info.cell[cell_info.cell_num].value2 = (uint32)tmp_int;
+
+ // Jump 2 integer.
+ i = 0;
+ while(i < 2) {
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ goto EEMGINFOSVC_EXIT;
+ }
+ i++;
+ }
+
+ // bsic
+ if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int < 0 || tmp_int >= 65536)
+ {
+ goto EEMGINFOSVC_EXIT;
+ }
+ cell_info.cell[cell_info.cell_num].value4 = (uint32)tmp_int;
+
+ // Jump 15 integer.
+ i = 0;
+ while(i < 15) {
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ goto EEMGINFOSVC_EXIT;
+ }
+ i++;
+ }
+
+ // arfcn
+ if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int < 0 || tmp_int >= 65536)
+ {
+ goto EEMGINFOSVC_EXIT;
+ }
+ cell_info.cell[cell_info.cell_num].value3 = (uint32)tmp_int;
+
+ cell_info.cell_num++;
+EEMGINFOSVC_EXIT:
+ free(free_ptr);
+ }
+ }
+ /*
+ // PS_attached, attach_type, service_type, tx_power, c_value,
+ // ul_ts, dl_ts, ul_cs, dl_cs, ul_modulation, dl_modulation,
+ // gmsk_cv_bep, 8psk_cv_bep, gmsk_mean_bep, 8psk_mean_bep, EDGE_bep_period, single_gmm_rej_cause
+ // pdp_active_num, mac_mode, network_control, network_mode, EDGE_slq_measurement_mode, edge_status
+ +EEMGINFOPS: 1, 255, 0, 0, 0,
+ 0, 0, 268435501, 1, 0, 0,
+ 4, 0, 96, 0, 0, 0,
+ 0, 0, 0, 65535, 0, 13350
+ */
+ // Do nothing.
+ else if(strStartsWith(s, "+EEMGINFOPS:")) // PSÐÅÏ¢
+ {
+ if(cell_info.running) {
+
+ }
+ }
+ else if(strStartsWith(s, "+EEMGINFONC:")) // cell
+ {
+ if(cell_info.running) {
+ int tmp_int;
+ int i = 0;
+ char* tmp_s = memdup(s,strlen(s));
+ char* free_ptr = tmp_s;
+ char *line = tmp_s;
+ if (at_tok_start(&line) < 0)
+ {
+ goto EEMGINFOPS_EXIT;
+ }
+
+ // nc_num
+ if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int < 0 || tmp_int >= 65536)
+ {
+ LOG("cell_info.running 1= %d\n.",cell_info.running);
+ goto EEMGINFOPS_EXIT;
+ }
+ // mcc
+ if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int < 0 || tmp_int >= 65536)
+ {
+ LOG("cell_info.running 2= %d\n.",cell_info.running);
+ goto EEMGINFOPS_EXIT;
+ }
+ cell_info.cell[cell_info.cell_num].value5 = (uint32)tmp_int;
+
+ // mnc
+ if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int < 0 || tmp_int >= 65536)
+ {
+ LOG("cell_info.running 3= %d\n.",cell_info.running);
+ goto EEMGINFOPS_EXIT;
+ }
+ cell_info.cell[cell_info.cell_num].value6 = (uint32)tmp_int;
+
+ // lac
+ if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int < 0 || tmp_int >= 65536)
+ {
+ LOG("cell_info.running 4= %d\n.",cell_info.running);
+ goto EEMGINFOPS_EXIT;
+ }
+ cell_info.cell[cell_info.cell_num].value1 = (uint32)tmp_int;
+
+ // rac
+ if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int < 0 || tmp_int >= 65536)
+ {
+ LOG("cell_info.running 5= %d\n.",cell_info.running);
+ goto EEMGINFOPS_EXIT;
+ }
+
+ // ci
+ if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int < 0 || tmp_int >= 65536)
+ {
+ LOG("cell_info.running 6= %d\n.",cell_info.running);
+ goto EEMGINFOPS_EXIT;
+ }
+ cell_info.cell[cell_info.cell_num].value2 = (uint32)tmp_int;
+
+ // rx_lv
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ LOG("cell_info.running 7= %d\n.",cell_info.running);
+ goto EEMGINFOPS_EXIT;
+ }
+
+ // bsic
+ if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int < 0 || tmp_int >= 65536)
+ {
+ LOG("cell_info.running 8= %d\n.",cell_info.running);
+ goto EEMGINFOPS_EXIT;
+ }
+ cell_info.cell[cell_info.cell_num].value4 = (uint32)tmp_int;
+
+ // Jump 2 integer.
+ i = 0;
+ while(i < 2) {
+ if (at_tok_nextint(&line, &tmp_int) < 0)
+ {
+ LOG("cell_info.running 9= %d\n.",cell_info.running);
+ goto EEMGINFOPS_EXIT;
+ }
+ i++;
+ }
+
+ // arfcn
+ if (at_tok_nextint(&line, &tmp_int) < 0 || tmp_int < 0 || tmp_int >= 65536)
+ {
+ LOG("cell_info.running 10 = %d\n.",cell_info.running);
+ goto EEMGINFOPS_EXIT;
+ }
+ cell_info.cell[cell_info.cell_num].value3 = (uint32)tmp_int;
+
+ cell_info.cell_num++;
+EEMGINFOPS_EXIT:
+ free(free_ptr);
+ }
+ }
+ else if(strStartsWith(s, "+ZGIPDNS:")) // +ZGIPDNS: 1,"IPV4V6","10.156.239.245","10.156.239.246","223.87.253.100","223.87.253.253","fe80:0000:0000:0000:0001:0001:9b8c:7c0c","fe80::1:1:9b8c:7c0d","2409:8062:2000:2::1","2409:8062:2000:2::2"
+ {
+
+ }
+ else
+ {
+ LOGV("Unknown URC : %s", s);
+ }
+#endif
+}
+
+static int openSocket(const char* sockname)
+{
+ int sock = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (sock < 0)
+ {
+ LOGE("Error create socket: %s\n", strerror(errno));
+ return -1;
+ }
+ struct sockaddr_un addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ strncpy(addr.sun_path, sockname, sizeof(addr.sun_path));
+ while (TEMP_FAILURE_RETRY(connect(sock,(const struct sockaddr*)&addr, sizeof(addr))) != 0)
+ {
+ LOGE("Error connect to socket %s: %s, try again", sockname, strerror(errno));
+ sleep(1);
+ }
+
+#if 0
+ int sk_flags = fcntl(sock, F_GETFL, 0);
+ fcntl(sock, F_SETFL, sk_flags | O_NONBLOCK);
+#endif
+
+ return sock;
+}
+
+static void ril_at_ready_process()
+{
+ ril_info.radio_state = ril_radio_state_get();
+ if (ril_info.radio_state != MBTK_RADIO_STATE_FULL_FUNC)
+ {
+ ril_radio_state_set(MBTK_RADIO_STATE_FULL_FUNC, FALSE);
+ }
+
+ if(ril_info.radio_state == MBTK_RADIO_STATE_FULL_FUNC)
+ {
+ at_send_command("AT+CEREG=2", NULL);
+ }
+
+ ril_info.sim_state = ril_sim_state_get();
+ if(ril_info.sim_state == MBTK_SIM_STATE_READY)
+ {
+ LOGD("SIM READY!");
+ at_send_command("AT+COPS=3", NULL);
+
+ // Set APN from prop.
+ apn_auto_conf_from_prop();
+ }
+ else
+ {
+ LOGE("SIM NOT READY!");
+ }
+}
+
+static void ind_regisger(sock_cli_info_t* cli_info, uint16 ind)
+{
+ uint32 i = 0;
+ while(i < cli_info->ind_num)
+ {
+ if(cli_info->ind_register[i] == ind)
+ break;
+ i++;
+ }
+
+ if(i == cli_info->ind_num) // No found IND
+ {
+ cli_info->ind_register[i] = ind;
+ cli_info->ind_num++;
+ LOGD("Register IND : %s", id2str(ind));
+ }
+ else
+ {
+ LOGW("IND had exist.");
+ }
+}
+
+// Process AT URC data
+static int send_pack_to_queue(sock_cli_info_t* cli_info, void* pack)
+{
+ if(ril_info.msg_queue.count >= PACK_PROCESS_QUEUE_MAX)
+ {
+ LOGE("Packet process queue is full");
+ return -1;
+ }
+
+ ril_msg_queue_info_t *item = (ril_msg_queue_info_t*)malloc(sizeof(ril_msg_queue_info_t));
+ if(!item)
+ {
+ LOGE("malloc() fail[%d].", errno);
+ return -1;
+ }
+ item->cli_info = cli_info;
+ item->pack = pack;
+ mbtk_queue_put(&ril_info.msg_queue, item);
+
+ // If thread is waitting,continue it.
+ pthread_mutex_lock(&ril_info.msg_mutex);
+ pthread_cond_signal(&ril_info.msg_cond);
+ pthread_mutex_unlock(&ril_info.msg_mutex);
+
+ return 0;
+}
+
+
+static void pack_distribute(sock_cli_info_t* cli_info, ril_msg_pack_info_t* pack)
+{
+ // Register IND Message.
+ if(pack->msg_type == RIL_MSG_TYPE_IND)
+ {
+ mbtk_ril_err_enum err = MBTK_RIL_ERR_SUCCESS;
+ if(cli_info->ind_num >= IND_REGISTER_MAX)
+ {
+ LOGE("IND if full.");
+ err = MBTK_RIL_ERR_IND_FULL;
+ }
+ else
+ {
+ ind_regisger(cli_info, pack->msg_id);
+ }
+
+ ril_error_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, err);
+
+ ril_msg_pack_free(pack);
+ }
+ else // Request Information.
+ {
+ LOGD("Start process REQ(%s), Length : %d", id2str(pack->msg_id), pack->data_len);
+ if(0 && pack->data_len > 0)
+ {
+ log_hex("DATA", pack->data, pack->data_len);
+ }
+
+ // Send to REQ_process_thread process.
+ send_pack_to_queue(cli_info, pack);
+
+ // For test.
+ // pack_error_send(cli_info->fd, pack->info_id + 1, MBTK_INFO_ERR_SUCCESS);
+ }
+}
+
+// Return MBTK_INFO_ERR_SUCCESS,will call pack_error_send() to send RSP.
+// Otherwise, do not call pack_error_send().
+static mbtk_ril_err_enum pack_req_process(sock_cli_info_t* cli_info, ril_msg_pack_info_t* pack)
+{
+ if(pack->msg_id > RIL_MSG_ID_DEV_BEGIN && pack->msg_id < RIL_MSG_ID_DEV_END) {
+ return dev_pack_req_process(cli_info, pack);
+ } else if(pack->msg_id > RIL_MSG_ID_SIM_BEGIN && pack->msg_id < RIL_MSG_ID_SIM_END) {
+ return sim_pack_req_process(cli_info, pack);
+ } else if(pack->msg_id > RIL_MSG_ID_NET_BEGIN && pack->msg_id < RIL_MSG_ID_NET_END) {
+ return net_pack_req_process(cli_info, pack);
+ } else if(pack->msg_id > RIL_MSG_ID_CALL_BEGIN && pack->msg_id < RIL_MSG_ID_CALL_END) {
+ return call_pack_req_process(cli_info, pack);
+ } else if(pack->msg_id > RIL_MSG_ID_SMS_BEGIN && pack->msg_id < RIL_MSG_ID_SMS_END) {
+ return sms_pack_req_process(cli_info, pack);
+ } else if(pack->msg_id > RIL_MSG_ID_PB_BEGIN && pack->msg_id < RIL_MSG_ID_PB_END) {
+ return pb_pack_req_process(cli_info, pack);
+ } else {
+ LOGW("Unknown msg id : %d", pack->msg_id);
+ return MBTK_RIL_ERR_FORMAT;
+ }
+}
+
+static void urc_msg_process(ril_urc_msg_info_t *msg)
+{
+ uint8 *data = NULL;
+ if(msg->data) {
+ data = (uint8*)msg->data;
+ }
+ switch(msg->msg) {
+ case RIL_URC_MSG_RADIO_STATE:
+ {
+ break;
+ }
+ default:
+ {
+ LOGE("Unknown URC : %d", msg->msg);
+ break;
+ }
+ }
+}
+
+// Read client conn/msg and push into ril_info.msg_queue.
+static void* ril_read_pthread(void* arg)
+{
+ UNUSED(arg);
+ ril_info.epoll_fd = epoll_create(SOCK_CLIENT_MAX + 1);
+ if(ril_info.epoll_fd < 0)
+ {
+ LOGE("epoll_create() fail[%d].", errno);
+ return NULL;
+ }
+
+ uint32 event = EPOLLIN | EPOLLET;
+ struct epoll_event ev;
+ ev.data.fd = ril_info.sock_listen_fd;
+ ev.events = event; //EPOLLIN | EPOLLERR | EPOLLET;
+ epoll_ctl(ril_info.epoll_fd, EPOLL_CTL_ADD, ril_info.sock_listen_fd, &ev);
+
+ int nready = -1;
+ struct epoll_event epoll_events[EPOLL_LISTEN_MAX];
+ while(1)
+ {
+ nready = epoll_wait(ril_info.epoll_fd, epoll_events, EPOLL_LISTEN_MAX, -1);
+ if(nready > 0)
+ {
+ sock_cli_info_t *cli_info = NULL;
+ int i;
+ for(i = 0; i < nready; i++)
+ {
+ LOG("fd[%d] event = %x",epoll_events[i].data.fd, epoll_events[i].events);
+ if(epoll_events[i].events & EPOLLHUP) // Client Close.
+ {
+ if((cli_info = cli_find(epoll_events[i].data.fd)) != NULL)
+ {
+ cli_close(cli_info);
+ }
+ else
+ {
+ LOG("Unknown client[fd = %d].", epoll_events[i].data.fd);
+ }
+ }
+ else if(epoll_events[i].events & EPOLLIN)
+ {
+ if(epoll_events[i].data.fd == ril_info.sock_listen_fd) // New clients connected.
+ {
+ int client_fd = -1;
+ while(1)
+ {
+ struct sockaddr_in cliaddr;
+ socklen_t clilen = sizeof(cliaddr);
+ client_fd = accept(epoll_events[i].data.fd, (struct sockaddr *) &cliaddr, &clilen);
+ if(client_fd < 0)
+ {
+ if(errno == EAGAIN)
+ {
+ LOG("All client connect get.");
+ }
+ else
+ {
+ LOG("accept() error[%d].", errno);
+ }
+ break;
+ }
+ // Set O_NONBLOCK
+ int flags = fcntl(client_fd, F_GETFL, 0);
+ if (flags > 0)
+ {
+ flags |= O_NONBLOCK;
+ if (fcntl(client_fd, F_SETFL, flags) < 0)
+ {
+ LOG("Set flags error:%d", errno);
+ }
+ }
+
+ memset(&ev,0,sizeof(struct epoll_event));
+ ev.data.fd = client_fd;
+ ev.events = event;//EPOLLIN | EPOLLERR | EPOLLET;
+ epoll_ctl(ril_info.epoll_fd, EPOLL_CTL_ADD, client_fd, &ev);
+
+ sock_cli_info_t *info = (sock_cli_info_t*)malloc(sizeof(sock_cli_info_t));
+ if(info)
+ {
+ memset(info, 0, sizeof(sock_cli_info_t));
+ info->fd = client_fd;
+ list_add(ril_info.sock_client_list, info);
+ LOG("Add New Client FD Into List.");
+
+ // Send msg RIL_MSG_ID_IND_SER_READY to client.
+ ril_ind_pack_send(client_fd, RIL_MSG_ID_IND_SER_READY, NULL, 0);
+ }
+ else
+ {
+ LOG("malloc() fail.");
+ }
+ }
+ }
+ else if((cli_info = cli_find(epoll_events[i].data.fd)) != NULL) // Client data arrive.
+ {
+ // Read and process every message.
+ mbtk_ril_err_enum err = MBTK_RIL_ERR_SUCCESS;
+ ril_msg_pack_info_t** pack = ril_pack_recv(cli_info->fd, true, &err);
+
+ // Parse packet error,send error response to client.
+ if(pack == NULL)
+ {
+ ril_error_pack_send(cli_info->fd, RIL_MSG_ID_UNKNOWN, RIL_MSG_INDEX_INVALID, err);
+ }
+ else
+ {
+ ril_msg_pack_info_t** pack_ptr = pack;
+ while(*pack_ptr)
+ {
+ pack_distribute(cli_info, *pack_ptr);
+ // Not free,will free in pack_process() or packet process thread.
+ //mbtk_info_pack_free(pack_ptr);
+ pack_ptr++;
+ }
+
+ free(pack);
+ }
+ }
+ else
+ {
+ LOG("Unknown socket : %d", epoll_events[i].data.fd);
+ }
+ }
+ else
+ {
+ LOG("Unknown event : %x", epoll_events[i].events);
+ }
+ }
+ }
+ else
+ {
+ LOG("epoll_wait() fail[%d].", errno);
+ }
+ }
+
+ return NULL;
+}
+
+static void* ril_process_thread(void* arg)
+{
+ UNUSED(arg);
+ ril_msg_queue_info_t* item = NULL;
+
+ pthread_mutex_lock(&ril_info.msg_mutex);
+ while(TRUE)
+ {
+ if(mbtk_queue_empty(&ril_info.msg_queue))
+ {
+ LOG("Packet process wait...");
+ pthread_cond_wait(&ril_info.msg_cond, &ril_info.msg_mutex);
+ LOG("Packet process continue...");
+ }
+ else
+ {
+ LOG("Packet process queue not empty,continue...");
+ }
+
+ // Process all information request.
+ mbtk_ril_err_enum err;
+ while((item = (ril_msg_queue_info_t*)mbtk_queue_get(&ril_info.msg_queue)) != NULL)
+ {
+ if(item->cli_info) { // REQ form client.
+ ril_msg_pack_info_t *pack = (ril_msg_pack_info_t*)item->pack;
+ LOGD("Process REQ %s.", id2str(pack->msg_id));
+ ril_info.at_process = true;
+ err = pack_req_process(item->cli_info, pack);
+ if(err != MBTK_RIL_ERR_SUCCESS)
+ {
+ ril_error_pack_send(item->cli_info->fd, pack->msg_id, pack->msg_index, err);
+ }
+ ril_info.at_process = false;
+ ril_msg_pack_free(pack);
+ free(item);
+ } else { // REQ from myself.
+ ril_urc_msg_info_t *urc = (ril_urc_msg_info_t*)item->pack;
+ LOGD("Process URC %d.", urc->msg);
+ urc_msg_process(urc);
+ if(urc->data)
+ free(urc->data);
+ free(urc);
+ }
+ }
+ }
+ pthread_mutex_unlock(&ril_info.msg_mutex);
+ return NULL;
+}
+
+/*
+AT*BAND=15,78,147,482,134742231
+
+OK
+*/
+static void* band_config_thread()
+{
+ mbtk_device_info_modem_t info_modem;
+ memset(&band_info.band_support, 0, sizeof(mbtk_band_info_t));
+ memset(&info_modem, 0, sizeof(mbtk_device_info_modem_t));
+ band_info.band_set_success = FALSE;
+ if(mbtk_dev_info_read(MBTK_DEVICE_INFO_ITEM_MODEM, &(info_modem), sizeof(mbtk_device_info_modem_t))) {
+ LOGD("mbtk_dev_info_read(MODEM) fail, use default band.");
+ band_info.band_area = MBTK_MODEM_BAND_AREA_ALL;
+ band_info.band_support.net_pref = MBTK_NET_PREF_UNUSE;
+ band_info.band_support.gsm_band = MBTK_BAND_ALL_GSM_DEFAULT;
+ band_info.band_support.umts_band = MBTK_BAND_ALL_WCDMA_DEFAULT;
+ band_info.band_support.tdlte_band = MBTK_BAND_ALL_TDLTE_DEFAULT;
+ band_info.band_support.fddlte_band = MBTK_BAND_ALL_FDDLTE_DEFAULT;
+ band_info.band_support.lte_ext_band = MBTK_BAND_ALL_EXT_LTE_DEFAULT;
+ } else {
+ band_info.band_area = info_modem.band_area;
+ band_info.band_support.net_pref = MBTK_NET_PREF_UNUSE;
+ band_info.band_support.gsm_band = info_modem.band_gsm;
+ band_info.band_support.umts_band = info_modem.band_wcdma;
+ band_info.band_support.tdlte_band = info_modem.band_tdlte;
+ band_info.band_support.fddlte_band = info_modem.band_fddlte;
+ band_info.band_support.lte_ext_band = info_modem.band_lte_ext;
+ }
+
+ bool is_first = TRUE;
+ while(!band_info.band_set_success) {
+ // Set band.
+#if 0
+ info_urc_msg_t *urc = (info_urc_msg_t*)malloc(sizeof(info_urc_msg_t));
+ if(!urc)
+ {
+ LOG("malloc() fail[%d].", errno);
+ break;
+ } else {
+ urc->msg = INFO_URC_MSG_SET_BAND;
+ urc->data = NULL;
+ urc->data_len = 0;
+ send_pack_to_queue(NULL, urc);
+
+ if(is_first) {
+ is_first = FALSE;
+ } else {
+ LOGE("*BAND exec error, will retry in 5s.");
+ }
+ sleep(5);
+ }
+#else
+ sleep(5);
+#endif
+ }
+
+ LOGD("Set Band thread exit.");
+ return NULL;
+}
+
+
+int ril_server_start()
+{
+ signal(SIGPIPE, SIG_IGN);
+
+ memset(&ril_info, 0, sizeof(ril_info_t));
+ memset(&band_info, 0, sizeof(ril_band_info_t));
+ memset(&band_info.band_support, 0xFF, sizeof(mbtk_band_info_t));
+
+ //check cfun and sim card status
+ ril_at_ready_process();
+
+ //any AT instruction that is not sent through pack_process_thread needs to precede the thread
+ //thread create
+ if(ril_info.sock_listen_fd > 0)
+ {
+ LOGE("Information Server Has Started.");
+ return -1;
+ }
+
+ struct sockaddr_un server_addr;
+ ril_info.sock_listen_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
+ if(ril_info.sock_listen_fd < 0)
+ {
+ LOGE("socket() fail[%d].", errno);
+ return -1;
+ }
+
+ // Set O_NONBLOCK
+ int flags = fcntl(ril_info.sock_listen_fd, F_GETFL, 0);
+ if (flags < 0)
+ {
+ LOGE("Get flags error:%d", errno);
+ goto error;
+ }
+ flags |= O_NONBLOCK;
+ if (fcntl(ril_info.sock_listen_fd, F_SETFL, flags) < 0)
+ {
+ LOGE("Set flags error:%d", errno);
+ goto error;
+ }
+
+ unlink(RIL_SOCK_NAME);
+ memset(&server_addr, 0, sizeof(struct sockaddr_un));
+ server_addr.sun_family = AF_LOCAL;
+ strcpy(server_addr.sun_path, RIL_SOCK_NAME);
+ if(bind(ril_info.sock_listen_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)))
+ {
+ LOGE("bind() fail[%d].", errno);
+ goto error;
+ }
+
+ if(listen(ril_info.sock_listen_fd, SOCK_CLIENT_MAX))
+ {
+ LOGE("listen() fail[%d].", errno);
+ goto error;
+ }
+
+ ril_info.sock_client_list = list_create(sock_cli_free_func);
+ if(ril_info.sock_client_list == NULL)
+ {
+ LOGE("list_create() fail.");
+ goto error;
+ }
+
+ mbtk_queue_init(&ril_info.msg_queue);
+ pthread_mutex_init(&ril_info.msg_mutex, NULL);
+ pthread_cond_init(&ril_info.msg_cond, NULL);
+
+ pthread_t info_pid, pack_pid, monitor_pid, urc_pid, bootconn_pid;
+ pthread_attr_t thread_attr;
+ pthread_attr_init(&thread_attr);
+ if(pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED))
+ {
+ LOGE("pthread_attr_setdetachstate() fail.");
+ goto error;
+ }
+
+ if(pthread_create(&info_pid, &thread_attr, ril_read_pthread, NULL))
+ {
+ LOGE("pthread_create() fail.");
+ goto error;
+ }
+
+ if(pthread_create(&pack_pid, &thread_attr, ril_process_thread, NULL))
+ {
+ LOGE("pthread_create() fail.");
+ goto error;
+ }
+
+ // Set Band
+ // AT*BAND=15,78,147,482,134742231
+ char buff[10];
+ memset(buff, 0, 10);
+ property_get("persist.mbtk.band_config", buff, "");
+ if(strlen(buff) == 0) {
+ pthread_t band_pid;
+ if(pthread_create(&band_pid, &thread_attr, band_config_thread, NULL))
+ {
+ LOGE("pthread_create() fail.");
+ }
+ }
+
+ pthread_attr_destroy(&thread_attr);
+
+ LOGD("MBTK Ril Server Start...");
+
+ return 0;
+error:
+ if(ril_info.sock_client_list) {
+ list_free(ril_info.sock_client_list);
+ ril_info.sock_client_list = NULL;
+ }
+
+ if(ril_info.sock_listen_fd > 0) {
+ close(ril_info.sock_listen_fd);
+ ril_info.sock_listen_fd = -1;
+ }
+ return -1;
+}
+
+
+int main(int argc, char *argv[])
+{
+ mbtk_log_init("radio", "MBTK_RIL");
+
+#ifdef MBTK_DUMP_SUPPORT
+ mbtk_debug_open(NULL, TRUE);
+#endif
+
+// Using Killall,the file lock may be not release.
+#if 0
+ if(app_already_running(MBTK_RILD_PID_FILE)) {
+ LOGW("daemon already running.");
+ exit(1);
+ }
+#endif
+
+ LOGI("mbtk_rild start.");
+
+ if(InProduction_Mode()) {
+ LOGI("Is Production Mode, will exit...");
+ exit(0);
+ }
+
+ ready_state_update();
+
+ int at_sock = openSocket("/tmp/atcmd_at");
+ if(at_sock < 0)
+ {
+ LOGE("Open AT Socket Fail[%d].", errno);
+ return -1;
+ }
+ int uart_sock = openSocket("/tmp/atcmd_urc");
+ if(uart_sock < 0)
+ {
+ LOGE("Open Uart Socket Fail[%d].", errno);
+ return -1;
+ }
+
+ at_set_on_reader_closed(onATReaderClosed);
+ at_set_on_timeout(onATTimeout);
+
+ if(at_open(at_sock, uart_sock, onUnsolicited))
+ {
+ LOGE("Start AT thread fail.");
+ return -1;
+ }
+
+ if(at_handshake())
+ {
+ LOGE("AT handshake fail.");
+ return -1;
+ }
+
+ LOGD("AT OK.");
+
+ if(ril_server_start())
+ {
+ LOGE("ril_server_start() fail.");
+ return -1;
+ }
+
+ mbtk_ril_ready();
+
+ while(1)
+ {
+ sleep(24 * 60 * 60);
+ }
+
+ LOGD("!!!mbtk_ril exit!!!");
+ return 0;
+}
diff --git a/mbtk/mbtk_rild_v2/src/ril_call.c b/mbtk/mbtk_rild_v2/src/ril_call.c
new file mode 100755
index 0000000..6264972
--- /dev/null
+++ b/mbtk/mbtk_rild_v2/src/ril_call.c
@@ -0,0 +1,570 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <pthread.h>
+#include <sys/epoll.h>
+#include <fcntl.h>
+#include <signal.h>
+
+#include "mbtk_type.h"
+#include "mbtk_ril.h"
+#include "atchannel.h"
+#include "at_tok.h"
+#include "mbtk_utils.h"
+#include "ril_info.h"
+
+void ril_rsp_pack_send(int fd, int ril_id, int msg_index, const void* data, int data_len);
+
+/*
+ATDXXXXXXX;
+OK
+
+*/
+static int req_call_start(char *phont_number, int *cme_err)
+{
+ ATResponse *response = NULL;
+ int tmp_int;
+ char *tmp_str = NULL;
+ char cmd[100] = {0};
+ sprintf(cmd, "ATD%s;", phont_number);
+ int err = at_send_command(cmd, &response);
+ if (err < 0 || response->success == 0){
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+
+exit:
+ at_response_free(response);
+ return err;
+}
+
+/*
+
+AT+CHLD=2
+OK
+
+*/
+static int req_answer_call(int *cme_err)
+{
+ ATResponse *response = NULL;
+ int err = at_send_command("AT+CHLD=2", &response);
+ if (err < 0 || response->success == 0){
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+
+exit:
+ at_response_free(response);
+ return err;
+}
+
+/*
+ATH
+OK
+
+*/
+static int req_hangup_call(int *cme_err)
+{
+ ATResponse *response = NULL;
+ int err = at_send_command("ATH", &response);
+ if (err < 0 || response->success == 0){
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+
+exit:
+ at_response_free(response);
+ return err;
+}
+
+/*
+AT+CHLD=1x
+OK
+
+*/
+static int req_hangup_a_call(int phone_id, int *cme_err)
+{
+ ATResponse *response = NULL;
+ char cmd[100] = {0};
+ sprintf(cmd, "AT+CHLD=1%d", phone_id);
+ int err = at_send_command(cmd, &response);
+ if (err < 0 || response->success == 0){
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+
+exit:
+ at_response_free(response);
+ return err;
+}
+
+/*
+AT+CHLD=0
+OK
+
+*/
+static int req_hangup_waiting_or_background_call(int *cme_err)
+{
+ ATResponse *response = NULL;
+ int err = at_send_command("AT+CHLD=0", &response);
+ if (err < 0 || response->success == 0){
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+
+exit:
+ at_response_free(response);
+ return err;
+}
+
+/*
+AT+CHLD=1
+OK
+
+*/
+static int req_hangup_foreground_resume_background_call(int *cme_err)
+{
+ ATResponse *response = NULL;
+ int err = at_send_command("AT+CHLD=1", &response);
+ if (err < 0 || response->success == 0){
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+
+exit:
+ at_response_free(response);
+ return err;
+}
+
+/*
+AT+CLCC
+OK
+
+*/
+static int req_waitin_call(mbtk_call_info_t *reg, int *cme_err)
+{
+ ATResponse *response = NULL;
+ int tmp_int;
+ char *tmp_str = NULL;
+
+ int err = at_send_command_multiline("AT+CLCC", "+CLCC:", &response);
+ if (err < 0 || response->success == 0){
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+
+ if(response->success == 1 && !response->p_intermediates)
+ {
+ reg->call_wait = 0;
+ goto exit;
+ }
+
+ reg->call_wait = 1;
+ char *line = response->p_intermediates->line;
+ err = at_tok_start(&line);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ err = at_tok_nextint(&line, &tmp_int); // dir1
+ if (err < 0)
+ {
+ goto exit;
+ }
+ reg->dir1 = (uint8)tmp_int;
+ err = at_tok_nextint(&line, &tmp_int);// dir
+ if (err < 0)
+ {
+ goto exit;
+ }
+ reg->dir = (uint8)tmp_int;
+ err = at_tok_nextint(&line, &tmp_int);// state
+ if (err < 0)
+ {
+ goto exit;
+ }
+ reg->state = (uint8)tmp_int;
+ err = at_tok_nextint(&line, &tmp_int);// mode
+ if (err < 0)
+ {
+ goto exit;
+ }
+ reg->mode = (uint8)tmp_int;
+ err = at_tok_nextint(&line, &tmp_int);// mpty
+ if (err < 0)
+ {
+ goto exit;
+ }
+ reg->mpty = (uint8)tmp_int;
+ err = at_tok_nextstr(&line, &tmp_str); // phone_number
+ if (err < 0)
+ {
+ goto exit;
+ }
+ memcpy(reg->phone_number, tmp_str, strlen(tmp_str));
+ err = at_tok_nextint(&line, &tmp_int);// tpye
+ if (err < 0)
+ {
+ goto exit;
+ }
+ reg->type = (uint8)tmp_int;
+
+exit:
+ at_response_free(response);
+ return err;
+}
+
+/*
+AT+CMUT?
++CMUT: 0
+
+OK
+*/
+static int req_mute_get(int *state, int *cme_err)
+{
+ ATResponse *response = NULL;
+ int tmp_int;
+ int err = at_send_command_singleline("AT+CMUT?", "+CMUT:", &response);
+
+ if (err < 0 || response->success == 0 || !response->p_intermediates){
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+
+ char *line = response->p_intermediates->line;
+ err = at_tok_start(&line);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ err = at_tok_nextint(&line, &tmp_int);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ *state = tmp_int;
+
+exit:
+ at_response_free(response);
+ return err;
+}
+
+/*
+AT+CMUT=0;
+OK
+
+*/
+static int req_mute_set(int state, int *cme_err)
+{
+ ATResponse *response = NULL;
+ char cmd[100] = {0};
+ sprintf(cmd, "AT+CMUT=%d", state);
+ LOG("Set the mute command is = %s.\n", cmd);
+ int err = at_send_command(cmd, &response);
+ if (err < 0 || response->success == 0){
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+
+exit:
+ at_response_free(response);
+ return err;
+}
+
+/*
+AT+VTS=0; //0, 1, ..., 9, A, B, C, D, *, #
+OK
+
+*/
+static int req_dtmf_set(mbtk_call_dtmf_info_t *state, int *cme_err)
+{
+ ATResponse *response = NULL;
+ char cmd[100] = {0};
+ sprintf(cmd, "AT+VTS=%c,%d", state->character, state->duration);
+ LOG("Set the DTMF command is = %s.\n", cmd);
+ int err = at_send_command(cmd, &response);
+ if (err < 0 || response->success == 0){
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+
+exit:
+ at_response_free(response);
+ return err;
+}
+
+//void net_list_free(void *data);
+// Return MBTK_INFO_ERR_SUCCESS,will call pack_error_send() to send RSP.
+// Otherwise, do not call pack_error_send().
+mbtk_ril_err_enum call_pack_req_process(sock_cli_info_t* cli_info, ril_msg_pack_info_t* pack)
+{
+ mbtk_ril_err_enum err = MBTK_RIL_ERR_SUCCESS;
+ int cme_err = MBTK_RIL_ERR_CME_NON;
+ switch(pack->msg_id)
+ {
+ case RIL_MSG_ID_CALL_START: // <string> phone number
+ {
+ if(pack->data_len == 0 || pack->data == NULL)
+ {
+ err = MBTK_RIL_ERR_UNSUPPORTED;
+ }
+ else // Set
+ {
+ char *pn = (char*)(pack->data);
+ if(req_call_start(pn, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("ATD fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+ }
+ }
+ break;
+ }
+ case RIL_MSG_ID_CALL_ANSWER:
+ {
+ if(pack->data_len == 0 || pack->data == NULL)
+ {
+ if(req_answer_call(&cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Answer call fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+ }
+ }
+ else // Set
+ {
+ err = MBTK_RIL_ERR_UNSUPPORTED;
+ LOG("Answer call fail. NO DATA\n");
+ }
+ break;
+ }
+ case RIL_MSG_ID_CALL_HANGUP:
+ {
+ if(pack->data_len == 0 || pack->data == NULL)
+ {
+ if(req_hangup_call(&cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Hang up call fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+ }
+ }
+ else // Set
+ {
+ err = MBTK_RIL_ERR_UNSUPPORTED;
+ LOG("Hang up call fail.");
+ }
+ break;
+ }
+ case RIL_MSG_ID_CALL_HANGUP_A:
+ {
+ if(pack->data_len == 0 || pack->data == NULL)
+ {
+ err = MBTK_RIL_ERR_UNSUPPORTED;
+ LOG("Hang up a call fail.");
+ }
+ else
+ {
+ uint8 phone_id = *(pack->data);
+ if(req_hangup_a_call(phone_id, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Hang up a call fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+ }
+ }
+ break;
+ }
+ case RIL_MSG_ID_CALL_HANGUP_B:
+ {
+ if(pack->data_len == 0 || pack->data == NULL)
+ {
+ if(req_hangup_waiting_or_background_call(&cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Hang up waiting_or_background call fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+ }
+ }
+ else
+ {
+ err = MBTK_RIL_ERR_UNSUPPORTED;
+ LOG("Hang up waiting_or_background call fail.");
+ }
+ break;
+ }
+ case RIL_MSG_ID_CALL_HANGUP_C:
+ {
+ if(pack->data_len == 0 || pack->data == NULL)
+ {
+ if(req_hangup_foreground_resume_background_call(&cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Hang up waiting_or_background call fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+ }
+ }
+ else
+ {
+ err = MBTK_RIL_ERR_UNSUPPORTED;
+ LOG("Hang up waiting_or_background call fail.");
+ }
+ break;
+ }
+ case RIL_MSG_ID_CALL_WAITIN:
+ {
+ if(pack->data_len == 0 || pack->data == NULL)
+ {
+ mbtk_call_info_t reg;
+ memset(®, 0, sizeof(mbtk_call_info_t));
+ if(req_waitin_call(®, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Wait incoing call fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, ®, sizeof(mbtk_call_info_t));
+ }
+ }
+ else // Set
+ {
+ err = MBTK_RIL_ERR_UNSUPPORTED;
+ LOG("Wait incoing call fail.");
+ }
+ break;
+ }
+ case RIL_MSG_ID_CALL_MUTE:
+ {
+ if(pack->data_len == 0 || pack->data == NULL) // Get VoLTE state.
+ {
+ int state;
+ if(req_mute_get(&state, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Get mute state fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &state, sizeof(uint8));
+ }
+ }
+ else // Set mute state.
+ {
+ uint8 on = *(pack->data);
+ if(pack->data_len != sizeof(uint8) || (on != 0 && on != 1))
+ {
+ err = MBTK_RIL_ERR_REQ_PARAMETER;
+ LOG("Set mute parameter error.");
+ break;
+ }
+
+ if(req_mute_set(on, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Set mute state fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+ }
+ }
+ break;
+ }
+ case RIL_MSG_ID_CALL_DTMF:
+ {
+ if(pack->data_len == 0 || pack->data == NULL)
+ {
+ err = MBTK_RIL_ERR_UNSUPPORTED;
+ LOG("Wait incoing call fail.");
+ }
+ else // Set
+ {
+ mbtk_call_dtmf_info_t *reg = (mbtk_call_dtmf_info_t *)pack->data;
+ if(req_dtmf_set(reg, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Wait incoing call fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+ }
+ }
+ break;
+ }
+ default:
+ {
+ err = MBTK_RIL_ERR_REQ_UNKNOWN;
+ LOG("Unknown request : %s", id2str(pack->msg_id));
+ break;
+ }
+ }
+
+ return err;
+}
+
+
+
diff --git a/mbtk/mbtk_rild_v2/src/ril_data_call.c b/mbtk/mbtk_rild_v2/src/ril_data_call.c
new file mode 100755
index 0000000..a0f3eeb
--- /dev/null
+++ b/mbtk/mbtk_rild_v2/src/ril_data_call.c
@@ -0,0 +1,41 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <pthread.h>
+#include <sys/epoll.h>
+#include <fcntl.h>
+#include <signal.h>
+
+#include "mbtk_type.h"
+#include "mbtk_ril.h"
+#include "atchannel.h"
+#include "at_tok.h"
+#include "mbtk_utils.h"
+#include "ril_info.h"
+
+/*
+IPv4 : 10.255.74.26
+IPv6 : 254.128.0.0.0.0.0.0.0.1.0.2.144.5.212.239
+*/
+bool is_ipv4(const char *ip)
+{
+ const char *ptr = ip;
+ int count = 0;
+ while(*ptr) {
+ if(*ptr == '.')
+ count++;
+ ptr++;
+ }
+
+ if(count == 3) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+
diff --git a/mbtk/mbtk_rild_v2/src/ril_dev.c b/mbtk/mbtk_rild_v2/src/ril_dev.c
new file mode 100755
index 0000000..0fe2d2f
--- /dev/null
+++ b/mbtk/mbtk_rild_v2/src/ril_dev.c
@@ -0,0 +1,705 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <pthread.h>
+#include <sys/epoll.h>
+#include <fcntl.h>
+#include <signal.h>
+
+#include "mbtk_type.h"
+#include "mbtk_ril.h"
+#include "atchannel.h"
+#include "at_tok.h"
+#include "mbtk_utils.h"
+#include "ril_info.h"
+
+void ril_rsp_pack_send(int fd, int ril_id, int msg_index, const void* data, int data_len);
+
+/*
+AT+CGSN
+864788050901201
+
+OK
+*/
+static int req_imei_get(void *data, int *cme_err)
+{
+ ATResponse *response = NULL;
+ int err = at_send_command_numeric("AT+CGSN", &response);
+
+ if (err < 0 || response->success == 0 || !response->p_intermediates) {
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+
+ memcpy(data, response->p_intermediates->line, strlen(response->p_intermediates->line));
+exit:
+ at_response_free(response);
+ return err;
+}
+
+/*
+AT+MRD_SN=R
++MRD_SN:0101,Thu Nov 12 00:00:00 2020,G4M32301020006
+
+OK
+
+*/
+static int req_sn_get(void *data, int *cme_err)
+{
+ ATResponse *response = NULL;
+ char *tmp_ptr = NULL;
+ int err = at_send_command_singleline("AT+MRD_SN=R", "+MRD_SN:", &response);
+
+ if (err < 0 || response->success == 0 || !response->p_intermediates){
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+
+ char *line = response->p_intermediates->line;
+ err = at_tok_start(&line);
+ if (err < 0)
+ {
+ goto exit;
+ }
+
+ err = at_tok_nextstr(&line, &tmp_ptr);
+ if (err < 0)
+ {
+ goto exit;
+ }
+
+ err = at_tok_nextstr(&line, &tmp_ptr);
+ if (err < 0)
+ {
+ goto exit;
+ }
+
+ err = at_tok_nextstr(&line, &tmp_ptr);
+ if (err < 0)
+ {
+ goto exit;
+ }
+
+ memcpy(data, tmp_ptr, strlen(tmp_ptr));
+
+ goto exit;
+exit:
+ at_response_free(response);
+ return err;
+}
+
+/*
+ATI
+Manufacturer:"LYNQ"
+Model:"LYNQ_L508TLC"
+Revision:L508TLCv02.01b01.00
+IMEI:864788050901201
+
+OK
+
+*/
+static int req_version_get(void *data, int *cme_err)
+{
+ ATResponse *response = NULL;
+ int err = at_send_command_multiline("ATI", "", &response);
+
+ if (err < 0 || response->success == 0 || !response->p_intermediates){
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+
+ ATLine* lines_ptr = response->p_intermediates;
+ char *line = NULL;
+ while(lines_ptr)
+ {
+ line = lines_ptr->line;
+ if(strStartsWith(line, "Revision"))
+ {
+ err = at_tok_start(&line);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ memcpy(data, line, strlen(line));
+ break;
+ }
+ lines_ptr = lines_ptr->p_next;
+ }
+
+ goto exit;
+exit:
+ at_response_free(response);
+ return err;
+}
+
+/*
+ATI
+Manufacturer:"LYNQ"
+Model:"LYNQ_L508TLC"
+Revision:L508TLCv02.01b01.00
+IMEI:864788050901201
+
+OK
+
+*/
+static int req_model_get(void *data, int *cme_err)
+{
+ ATResponse *response = NULL;
+ int err = at_send_command_multiline("ATI", "", &response);
+
+ if (err < 0 || response->success == 0 || !response->p_intermediates){
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+
+ ATLine* lines_ptr = response->p_intermediates;
+ char *line = NULL;
+ while(lines_ptr)
+ {
+ line = lines_ptr->line;
+ if(strStartsWith(line, "Model"))
+ {
+ err = at_tok_start(&line);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ memcpy(data, line, strlen(line));
+ break;
+ }
+ lines_ptr = lines_ptr->p_next;
+ }
+
+ goto exit;
+exit:
+ at_response_free(response);
+ return err;
+}
+
+/*
+AT+ACONFIG="IMSD=1"
+or
+AT+ACONFIG="IMSD=0"
+
+OK
+*/
+static int req_volte_set(int state, int *cme_err)
+{
+ ATResponse *response = NULL;
+ char cmd[30] = {0};
+ if(state)
+ {
+ strcpy(cmd, "AT+ACONFIG=\"IMSD=1\"");
+ }
+ else
+ {
+ strcpy(cmd, "AT+ACONFIG=\"IMSD=0\"");
+ }
+ int err = at_send_command(cmd, &response);
+
+ if (err < 0 || response->success == 0) {
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+
+ err = 0;
+exit:
+ at_response_free(response);
+ return err;
+}
+
+/*
+AT+ACONFIG?
+PID=0,VID=0,IMSD=1,PIPE=0,FAST=0,RDUP=1,NOCP=0,GEFL=-1237040617
+
+OK
+*/
+static int req_volte_get(int *state, int *cme_err)
+{
+ ATResponse *response = NULL;
+ char *tmp_ptr = NULL;
+ int err = at_send_command_singleline("AT+ACONFIG?", "", &response);
+
+ if (err < 0 || response->success == 0 || !response->p_intermediates){
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+
+ char *line = response->p_intermediates->line;
+ char* ptr = strstr(line, "IMSD=");
+ if(ptr)
+ {
+ *state = atoi(ptr + strlen("IMSD="));
+ }
+ else
+ {
+ err = -1;
+ }
+exit:
+ at_response_free(response);
+ return err;
+}
+
+
+/*
+* Get system temperature.
+*
+* type[IN]:
+* 0: Soc temperature.
+* 1: RF temperature.
+* temp[OUT]:
+* temperature in celsius.
+*
+
+AT*RFTEMP
+*RFTEMP:0,28
+OK
+
+AT*SOCTEMP
+*SOCTEMP:24000
+OK
+
+*/
+static int req_temp_get(mbtk_temp_type_enum type, int16 *temp, int *cme_err)
+{
+ ATResponse *response = NULL;
+ int err = -1;
+ int tmp_int;
+ if(type == MBTK_TEMP_TYPE_SOC) { // Soc
+ err = at_send_command_singleline("AT*SOCTEMP", "*SOCTEMP:", &response);
+ } else { // RF
+ err = at_send_command_singleline("AT*RFTEMP", "*RFTEMP:", &response);
+ }
+
+ if (err < 0 || response->success == 0 || !response->p_intermediates){
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+
+ char *line = response->p_intermediates->line;
+ err = at_tok_start(&line);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ err = at_tok_nextint(&line, &tmp_int);
+ if (err < 0)
+ {
+ goto exit;
+ }
+
+ if(type == MBTK_TEMP_TYPE_RF) { // RF
+ err = at_tok_nextint(&line, &tmp_int);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ *temp = (int16)tmp_int;
+ } else {
+ tmp_int = tmp_int / 1000;
+ *temp = (int16)tmp_int;
+ }
+
+exit:
+ at_response_free(response);
+ return err;
+}
+
+/*
+AT+CCLK?
++CCLK: "23/03/20,01:58:00+32"
+
+OK
+
+*/
+static int req_cell_time_get(char *data, int *cme_err)
+{
+ ATResponse *response = NULL;
+ char *tmp_ptr = NULL;
+ int err = at_send_command_singleline("AT+CCLK?", "+CCLK:", &response);
+
+ if (err < 0 || response->success == 0 || !response->p_intermediates){
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+
+ char *line = response->p_intermediates->line;
+ err = at_tok_start(&line);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ err = at_tok_nextstr(&line, &tmp_ptr);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ memcpy(data, tmp_ptr, strlen(tmp_ptr));
+
+exit:
+ at_response_free(response);
+ return err;
+}
+
+/*
+0: minimum functionality
+1: full functionality
+3: disable phone receive RF circuits.
+4: disable phone both transmit and receive RF circuits
+5: disable SIM
+6: turn off full secondary receive.
+-1: fail
+*/
+mbtk_radio_state_enum ril_radio_state_get()
+{
+ ATResponse *p_response = NULL;
+ int err;
+ char *line;
+ int ret;
+
+ err = at_send_command_singleline("AT+CFUN?", "+CFUN:", &p_response);
+
+ if (err < 0 || p_response->success == 0 || !p_response->p_intermediates)
+ {
+ // assume radio is off
+ goto done;
+ }
+
+ line = p_response->p_intermediates->line;
+
+ err = at_tok_start(&line);
+ if (err < 0) goto done;
+
+ err = at_tok_nextint(&line, &ret);
+ if (err < 0) goto done;
+
+ at_response_free(p_response);
+
+ ril_info.radio_state = (mbtk_radio_state_enum)ret;
+
+ return ril_info.radio_state;
+done:
+ at_response_free(p_response);
+ return MBTK_RADIO_STATE_UNKNOWN;
+}
+
+mbtk_ril_err_enum ril_radio_state_set(mbtk_radio_state_enum state, bool reset)
+{
+ int err;
+ ATResponse *p_response = NULL;
+ mbtk_ril_err_enum ret = MBTK_RIL_ERR_UNKNOWN;
+
+ if(state == ril_info.radio_state) {
+ LOGE("Radio state is same.");
+ //return MBTK_RIL_ERR_PARAMETER;
+ return MBTK_RIL_ERR_SUCCESS;
+ }
+
+ LOGI("Set radio state - %d", state);
+
+ char cmd[64] = {0};
+ if(reset) {
+ snprintf(cmd, sizeof(cmd), "AT+CFUN=%d,1", state);
+ } else {
+ snprintf(cmd, sizeof(cmd), "AT+CFUN=%d", state);
+ }
+ err = at_send_command(cmd, &p_response);
+ if (err || !p_response->success) {
+ goto done;
+ }
+
+ if(state == MBTK_RADIO_STATE_FULL_FUNC) { // +CFUN=1
+ if(ril_radio_state_get() == MBTK_RADIO_STATE_FULL_FUNC) { // success
+ ril_info.radio_state = MBTK_RADIO_STATE_FULL_FUNC;
+ ret = MBTK_RIL_ERR_SUCCESS;
+ LOGD("Radio open success.");
+ } else {
+ LOGW("Radio open fail.");
+ }
+ } else {
+ ril_info.radio_state = state;
+ ret = MBTK_RIL_ERR_SUCCESS;
+ LOGD("Set radio state to %d success.", state);
+ }
+
+done:
+ at_response_free(p_response);
+ return ret;
+}
+
+
+//void net_list_free(void *data);
+// Return MBTK_INFO_ERR_SUCCESS,will call pack_error_send() to send RSP.
+// Otherwise, do not call pack_error_send().
+mbtk_ril_err_enum dev_pack_req_process(sock_cli_info_t* cli_info, ril_msg_pack_info_t* pack)
+{
+ mbtk_ril_err_enum err = MBTK_RIL_ERR_SUCCESS;
+ int cme_err = MBTK_RIL_ERR_CME_NON;
+ switch(pack->msg_id)
+ {
+ case RIL_MSG_ID_DEV_IMEI:
+ {
+ if(pack->data_len == 0 || pack->data == NULL) // Get IMEI
+ {
+ char imei[20] = {0};
+ if(req_imei_get(imei, &cme_err) || strlen(imei) == 0 || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Get IMEI fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, imei, strlen(imei));
+ }
+ }
+ else // Set IMEI(Unsupport).
+ {
+ err = MBTK_RIL_ERR_UNSUPPORTED;
+ LOG("Unsupport set IMEI.");
+ }
+ break;
+ }
+ case RIL_MSG_ID_DEV_SN:
+ {
+ if(pack->data_len == 0 || pack->data == NULL)
+ {
+ char sn[20] = {0};
+ if(req_sn_get(sn, &cme_err) || strlen(sn) == 0 || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Get SN fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, sn, strlen(sn));
+ }
+ }
+ else // Set
+ {
+ err = MBTK_RIL_ERR_UNSUPPORTED;
+ LOG("Unsupport set SN.");
+ }
+ break;
+ }
+ case RIL_MSG_ID_DEV_MEID:
+ {
+ if(pack->data_len == 0 || pack->data == NULL)
+ {
+ err = MBTK_RIL_ERR_UNSUPPORTED;
+ LOG("Support only for CDMA.");
+ }
+ else // Set
+ {
+ err = MBTK_RIL_ERR_UNSUPPORTED;
+ LOG("Unsupport set MEID.");
+ }
+ break;
+ }
+ case RIL_MSG_ID_DEV_VERSION:
+ {
+ if(pack->data_len == 0 || pack->data == NULL)
+ {
+ char version[50] = {0};
+ if(req_version_get(version, &cme_err) || strlen(version) == 0 || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Get Version fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, version, strlen(version));
+ }
+ }
+ else // Set
+ {
+ err = MBTK_RIL_ERR_UNSUPPORTED;
+ LOG("Unsupport set Version.");
+ }
+ break;
+ }
+ case RIL_MSG_ID_DEV_MODEL:
+ {
+ if(pack->data_len == 0 || pack->data == NULL)
+ {
+ char model[50] = {0};
+ if(req_model_get(model, &cme_err) || strlen(model) == 0 || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Get Version fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, model, strlen(model));
+ }
+ }
+ else // Set
+ {
+ err = MBTK_RIL_ERR_UNSUPPORTED;
+ LOG("Unsupport set Model.");
+ }
+ break;
+ }
+ case RIL_MSG_ID_DEV_VOLTE: // <uint8> 0:Close 1:Open
+ {
+ if(pack->data_len == 0 || pack->data == NULL) // Get VoLTE state.
+ {
+ int state;
+ if(req_volte_get(&state, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Get VoLTE state fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &state, sizeof(uint8));
+ }
+ }
+ else // Set VoLTE state.
+ {
+ if(pack->data == NULL || pack->data_len != sizeof(uint8)
+ || (*(pack->data) != 0 && *(pack->data) != 1))
+ {
+ err = MBTK_RIL_ERR_REQ_PARAMETER;
+ LOG("Set VOLTE parameter error.");
+ break;
+ }
+
+ uint8 on = *(pack->data);
+ if(req_volte_set(on, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Set VoLTE state fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+
+ // Restart is required to take effect.
+ // LOG("Will reboot system...");
+ }
+ }
+ break;
+ }
+ case RIL_MSG_ID_DEV_TEMP:
+ {
+ if(pack->data && pack->data_len == sizeof(uint8)) {
+ int16 temp;
+ mbtk_temp_type_enum type = (mbtk_temp_type_enum)(*(pack->data));
+ if(req_temp_get(type, &temp, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Get temperature fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &temp, sizeof(int16));
+ }
+ } else {
+ err = MBTK_RIL_ERR_UNSUPPORTED;
+ LOG("Unsupport set Temperature.");
+ }
+ break;
+ }
+ case RIL_MSG_ID_DEV_CELL_TIME:
+ {
+ if(pack->data_len == 0 || pack->data == NULL) // Get Time
+ {
+ char time[100] = {0};
+ if(req_cell_time_get(time, &cme_err) || strlen(time) == 0 || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Get cell time fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, time, strlen(time));
+ }
+ }
+ else // Set Time
+ {
+ err = MBTK_RIL_ERR_UNSUPPORTED;
+ LOG("Unsupport set cell time.");
+ }
+ break;
+ }
+ case RIL_MSG_ID_DEV_MODEM:
+ {
+ if(pack->data_len == 0 || pack->data == NULL)
+ {
+ mbtk_radio_state_enum radio_state = ril_radio_state_get();
+ if(radio_state == MBTK_RADIO_STATE_UNKNOWN)
+ {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ LOG("Get Version fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &radio_state, sizeof(uint8));
+ }
+ }
+ else // Set
+ {
+ // <func><reset>
+ if(pack->data && pack->data_len == 2) {
+ mbtk_radio_state_enum radio_state = (mbtk_radio_state_enum)(*(pack->data));
+ bool reset = *(pack->data + 1);
+ err = ril_radio_state_set(radio_state, reset);
+ if(MBTK_RIL_ERR_SUCCESS == err) {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+ }
+ } else {
+ err = MBTK_RIL_ERR_FORMAT;
+ }
+ }
+ break;
+ }
+ default:
+ {
+ err = MBTK_RIL_ERR_REQ_UNKNOWN;
+ LOG("Unknown request : %s", id2str(pack->msg_id));
+ break;
+ }
+ }
+
+ return err;
+}
+
+
+
+
diff --git a/mbtk/mbtk_rild_v2/src/ril_net.c b/mbtk/mbtk_rild_v2/src/ril_net.c
new file mode 100755
index 0000000..3f02965
--- /dev/null
+++ b/mbtk/mbtk_rild_v2/src/ril_net.c
@@ -0,0 +1,1856 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <pthread.h>
+#include <sys/epoll.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <cutils/properties.h>
+#include <arpa/inet.h>
+
+#include "mbtk_type.h"
+#include "mbtk_ril.h"
+#include "atchannel.h"
+#include "at_tok.h"
+#include "mbtk_utils.h"
+#include "ril_info.h"
+#include "mbtk_str.h"
+
+extern ril_band_info_t band_info;
+void ril_rsp_pack_send(int fd, int ril_id, int msg_index, const void* data, int data_len);
+static int req_apn_get(mbtk_apn_info_array_t *apns, int *cme_err);
+static int req_apn_set(mbtk_apn_info_t *apn, int *cme_err);
+static void apn_prop_get(ril_apn_info_array_t *apns);
+
+void apn_auto_conf_from_prop()
+{
+ ril_apn_info_array_t apns;
+ int i = 0;
+ memset(&apns, 0, sizeof(ril_apn_info_array_t));
+ apn_prop_get(&apns);
+ while(i < apns.num) {
+ int cme_err = MBTK_RIL_ERR_CME_NON;
+ if(req_apn_set(&(apns.apns[i]), &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ LOGD("Set APN fail.");
+ }
+ else
+ {
+ LOGD("Set APN - %d success.", apns.apns[i].cid);
+ }
+ i++;
+ }
+}
+
+static bool apn_conf_support(mbtk_ril_cid_enum cid)
+{
+ if(cid == MBTK_RIL_CID_DEF) {
+ /*
+ uci show wan_default.default.enable
+ wan_default.default.enable='1'
+
+ uci get wan_default.default.enable
+ 1
+ */
+ char buff[128] = {0};
+ if(mbtk_cmd_line("uci get wan_default.default.enable", buff, sizeof(buff)) && strlen(buff) > 0) {
+ return buff[0] == '1' ? FALSE : TRUE;
+ }
+ }
+ return TRUE;
+}
+
+static int apn_cid_reset(mbtk_apn_info_t *apn)
+{
+ // Delete apn
+ if(str_empty(apn->apn)) {
+ if(apn->cid == MBTK_RIL_CID_NUL)
+ return -1;
+
+ if(!apn_conf_support(MBTK_RIL_CID_DEF) && apn->cid == MBTK_RIL_CID_DEF)
+ return -1;
+
+ mbtk_apn_info_array_t apns;
+ int cme_err = MBTK_RIL_ERR_CME_NON;
+ memset(&apns, 0, sizeof(mbtk_apn_info_array_t));
+ if(req_apn_get(&apns, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ LOGW("Get APN fail.");
+ return 0;
+ }
+ else
+ {
+ int index = 0;
+ while(index < apns.num) {
+ if(apns.apns[index].cid == apn->cid)
+ return 0;
+ index++;
+ }
+ return -1;
+ }
+ } else {
+ if(apn->cid == MBTK_RIL_CID_NUL) {
+ int start_cid;
+ bool asr_auto_call_open = !apn_conf_support(MBTK_RIL_CID_DEF);
+ mbtk_apn_info_array_t apns;
+ int cme_err = MBTK_RIL_ERR_CME_NON;
+ if(asr_auto_call_open) {
+ start_cid = MBTK_RIL_CID_2;
+ } else {
+ start_cid = MBTK_APN_CID_MIN;
+ }
+ memset(&apns, 0, sizeof(mbtk_apn_info_array_t));
+ if(req_apn_get(&apns, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ LOGW("Get APN fail.");
+ apn->cid = start_cid;
+ }
+ else
+ {
+ for(; start_cid <= MBTK_APN_CID_MAX; start_cid++) {
+ int index = 0;
+ while(index < apns.num) {
+ if(apns.apns[index].cid == start_cid)
+ break;
+ index++;
+ }
+
+ if(index == apns.num) { // Found not used cid : start_cid.
+ LOGD("Change CID : %d -> %d", apn->cid, start_cid);
+ apn->cid = start_cid;
+ return 0;
+ }
+ }
+
+ if(start_cid > MBTK_APN_CID_MAX) {
+ LOGE("APN full.");
+ return -1;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+static void apn_prop_get(ril_apn_info_array_t *apns)
+{
+ char prop_name[20] = {0};
+ char prop_data[300] = {0};
+ int cid;
+ memset(apns, 0, sizeof(ril_apn_info_array_t));
+ bool asr_auto_call_open = !apn_conf_support(MBTK_RIL_CID_DEF);
+
+ // If auto data call is open,the default route is CID 1.
+ if(asr_auto_call_open) {
+ apns->cid_for_def_route = MBTK_RIL_CID_DEF;
+ cid = MBTK_RIL_CID_2;
+ } else {
+ if(property_get(MBTK_DEF_ROUTE_CID, prop_data, "") > 0 && !str_empty(prop_data)) {
+ apns->cid_for_def_route = (mbtk_ril_cid_enum)atoi(prop_data);
+ }
+ cid = MBTK_APN_CID_MIN;
+ }
+ for(; cid <= MBTK_APN_CID_MAX; cid++) {
+ memset(prop_name, 0, 20);
+ memset(prop_data, 0, 300);
+
+ sprintf(prop_name, "%s_%d",MBTK_APN_PROP,cid);
+ // ip_type,auth,auto_data_call,apn,user,pass
+ if(property_get(prop_name, prop_data, "") > 0 && !str_empty(prop_data)) {
+ apns->apns[apns->num].cid = (mbtk_ril_cid_enum)cid;
+ char *ptr_1 = prop_data;
+ apns->apns[apns->num].ip_type = (mbtk_ip_type_enum)atoi(ptr_1);
+ ptr_1 = strstr(ptr_1, ",");
+ if(!ptr_1) {
+ continue;
+ }
+ ptr_1++; // Jump ',' to auth
+
+ apns->apns[apns->num].auth = (mbtk_apn_auth_type_enum)atoi(ptr_1);
+ ptr_1 = strstr(ptr_1, ",");
+ if(!ptr_1) {
+ continue;
+ }
+ ptr_1++; // Jump ',' to auto_data_call
+
+ apns->apns[apns->num].auto_boot_call = (uint8)atoi(ptr_1);
+ ptr_1 = strstr(ptr_1, ",");
+ if(!ptr_1) {
+ continue;
+ }
+ ptr_1++; // Jump ',' to apn
+
+ char *ptr_2 = strstr(ptr_1, ",");
+ if(!ptr_2) {
+ continue;
+ }
+ if(memcmp(ptr_1, "NULL", 4)) { // Not "NULL"
+ memcpy(apns->apns[apns->num].apn, ptr_1, ptr_2 - ptr_1); // apn
+ }
+
+ ptr_2++; // Jump ',' to user
+ ptr_1 = strstr(ptr_2, ",");
+ if(!ptr_1) {
+ continue;
+ }
+ if(memcmp(ptr_2, "NULL", 4)) { // Not "NULL"
+ memcpy(apns->apns[apns->num].user, ptr_2, ptr_1 - ptr_2); // user
+ }
+
+ ptr_1++; // Jump ',' to pass
+ if(memcmp(ptr_1, "NULL", 4)) { // Not "NULL"
+ memcpy(apns->apns[apns->num].pass, ptr_1, strlen(ptr_1)); // pass
+ }
+
+ apns->num++;
+ }
+ }
+}
+
+static int apn_prop_get_by_cid(mbtk_ril_cid_enum cid, mbtk_apn_info_t *apn)
+{
+ char prop_name[20] = {0};
+ char prop_data[300] = {0};
+ memset(apn, 0, sizeof(mbtk_apn_info_t));
+
+ sprintf(prop_name, "%s_%d",MBTK_APN_PROP,cid);
+ // ip_type,auth,auto_data_call,apn,user,pass
+ if(property_get(prop_name, prop_data, "") > 0 && !str_empty(prop_data)) {
+ apn->cid = cid;
+ apn->auto_save = (uint8)1;
+ char *ptr_1 = prop_data;
+ apn->ip_type = (mbtk_ip_type_enum)atoi(ptr_1);
+ ptr_1 = strstr(ptr_1, ",");
+ if(!ptr_1) {
+ return -1;
+ }
+ ptr_1++; // Jump ',' to auth
+
+ apn->auth = (mbtk_apn_auth_type_enum)atoi(ptr_1);
+ ptr_1 = strstr(ptr_1, ",");
+ if(!ptr_1) {
+ return -1;
+ }
+ ptr_1++; // Jump ',' to auto_data_call
+
+ apn->auto_boot_call = (uint8)atoi(ptr_1);
+ ptr_1 = strstr(ptr_1, ",");
+ if(!ptr_1) {
+ return -1;
+ }
+ ptr_1++; // Jump ',' to apn
+
+ char *ptr_2 = strstr(ptr_1, ",");
+ if(!ptr_2) {
+ return -1;
+ }
+ if(memcmp(ptr_1, "NULL", 4)) { // Not "NULL"
+ memcpy(apn->apn, ptr_1, ptr_2 - ptr_1); // apn
+ }
+
+ ptr_2++; // Jump ',' to user
+ ptr_1 = strstr(ptr_2, ",");
+ if(!ptr_1) {
+ return -1;
+ }
+ if(memcmp(ptr_2, "NULL", 4)) { // Not "NULL"
+ memcpy(apn->user, ptr_2, ptr_1 - ptr_2); // user
+ }
+
+ ptr_1++; // Jump ',' to pass
+ if(memcmp(ptr_1, "NULL", 4)) { // Not "NULL"
+ memcpy(apn->pass, ptr_1, strlen(ptr_1)); // pass
+ }
+ return 0;
+ }
+ return -1;
+}
+
+static int apn_prop_set(mbtk_apn_info_t *apn)
+{
+ char prop_name[20] = {0};
+ char prop_data[300] = {0};
+ int ret = -1;
+ if(apn->auto_save) {
+ sprintf(prop_name, "%s_%d", MBTK_APN_PROP, apn->cid);
+ // Delete apn
+ if(!str_empty(apn->apn)) {
+ snprintf(prop_data, 300, "%d,%d,%d,%s,%s,%s", apn->ip_type, apn->auth, apn->auto_boot_call,
+ apn->apn,
+ str_empty(apn->user) ? "NULL" : apn->user,
+ str_empty(apn->pass) ? "NULL" : apn->pass);
+ }
+
+ ret = property_set(prop_name, prop_data);
+ }
+
+ if(apn->def_route) {
+ memset(prop_data, 0, sizeof(prop_data));
+ prop_data[0] = '0' + apn->cid;
+ ret = property_set(MBTK_DEF_ROUTE_CID, prop_data);
+ }
+ return ret;
+}
+
+static int apn_prop_reset(mbtk_data_call_info_t *data_info)
+{
+ mbtk_apn_info_t apn;
+ if(apn_prop_get_by_cid(data_info->cid, &apn)) {
+ return -1;
+ } else {
+ apn.auto_boot_call = data_info->auto_boot_call;
+ apn.def_route = data_info->def_route;
+ return apn_prop_set(&apn);
+ }
+}
+
+
+/*
+AT+COPS=?
+
++COPS: (2, "CHN-CT", "CT", "46011", 7),(3, "CHN-UNICOM", "UNICOM", "46001", 7),(3, "CHINA MOBILE", "CMCC", "46000", 0),(3, "CHINA MOBILE", "CMCC", "46000", 7),(3, "China Broadnet", "CBN", "46015", 7),,(0,1,2,3,4),(0,1,2)
+
+OK
+*/
+static int req_available_net_get(mbtk_net_info_array_t* nets, int *cme_err)
+{
+ ATResponse *response = NULL;
+ int err = at_send_command_singleline("AT+COPS=?", "+COPS:", &response);
+
+ if (err < 0 || response->success == 0 || !response->p_intermediates){
+ if(cme_err) {
+ *cme_err = at_get_cme_error(response);
+ }
+ goto exit;
+ }
+ char *line_ptr = response->p_intermediates->line;
+ if(line_ptr == NULL) {
+ LOG("line is NULL");
+ err = -1;
+ goto exit;
+ }
+ //LOG("Line:%s",line_ptr);
+ line_ptr = strstr(line_ptr, "(");
+ while(line_ptr) {
+ line_ptr++;
+ // Only for available/current net.
+ if(*line_ptr == '1' || *line_ptr == '2' || *line_ptr == '3') {
+ nets->net_info[nets->num].net_state = (uint8)atoi(line_ptr); // net_state
+
+ line_ptr = strstr(line_ptr, ",");
+ if(line_ptr == NULL) {
+ err = -1;
+ goto exit;
+ }
+ line_ptr++;
+
+ line_ptr = strstr(line_ptr, ",");
+ if(line_ptr == NULL) {
+ err = -1;
+ goto exit;
+ }
+ line_ptr++;
+
+ line_ptr = strstr(line_ptr, ",");
+ if(line_ptr == NULL) {
+ err = -1;
+ goto exit;
+ }
+
+ while(*line_ptr != '\0' && (*line_ptr == ',' || *line_ptr == ' ' || *line_ptr == '"'))
+ line_ptr++;
+
+ // set sel_mode to 0
+ nets->net_info[nets->num].net_sel_mode = (uint8)0;
+ // Point to "46000"
+ //LOG("PLMN:%s",line_ptr);
+ //sleep(1);
+ //uint32_2_byte((uint32)atoi(line_ptr), buff_ptr + 3, false); // plmn
+ nets->net_info[nets->num].plmn = (uint32)atoi(line_ptr);
+
+ line_ptr = strstr(line_ptr, ",");
+ if(line_ptr == NULL) {
+ err = -1;
+ goto exit;
+ }
+
+ while(*line_ptr != '\0' && (*line_ptr == ',' || *line_ptr == ' '))
+ line_ptr++;
+
+ // Point to "7"
+ if(*line_ptr == '\0') {
+ err = -1;
+ goto exit;
+ }
+ //LOG("Type:%s",line_ptr);
+ //sleep(1);
+ nets->net_info[nets->num].net_type = (uint8)atoi(line_ptr); // net_type
+
+ nets->num++;
+ }
+
+ line_ptr = strstr(line_ptr, "(");
+ }
+exit:
+ at_response_free(response);
+ return err;
+}
+
+/*
+AT+COPS?
++COPS: 1
+
+OK
+
+or
+
+AT+COPS?
++COPS: 0,2,"46001",7
+
+OK
+
+*/
+static int req_net_sel_mode_get(mbtk_net_info_t *net, int *cme_err)
+{
+ //LOG("req_net_sel_mode_get() 0");
+ //sleep(1);
+ ATResponse *response = NULL;
+ int tmp_int;
+ char *tmp_ptr = NULL;
+ int err = at_send_command_singleline("AT+COPS?", "+COPS:", &response);
+ //LOG("req_net_sel_mode_get() 00");
+ //sleep(1);
+ if (err < 0 || response->success == 0 || !response->p_intermediates){
+ if(cme_err != NULL)
+ *cme_err = at_get_cme_error(response);
+ err = -1;
+ goto exit;
+ }
+ //LOG("req_net_sel_mode_get() 1");
+ //sleep(1);
+ char *line = response->p_intermediates->line;
+ if(line == NULL) {
+ LOG("line is NULL");
+ goto exit;
+ }
+ //LOG("req_net_sel_mode_get() 2");
+ //sleep(1);
+ err = at_tok_start(&line);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ //LOG("req_net_sel_mode_get() 3");
+ //sleep(1);
+ err = at_tok_nextint(&line, &tmp_int);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ net->net_sel_mode = (uint8)tmp_int;
+ //LOG("req_net_sel_mode_get() 4");
+ //sleep(1);
+ // +COPS: 1
+ if(!at_tok_hasmore(&line)) {
+ goto exit;
+ }
+ //LOG("req_net_sel_mode_get() 5");
+ //sleep(1);
+ err = at_tok_nextint(&line, &tmp_int);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ //LOG("req_net_sel_mode_get() 6");
+ //sleep(1);
+ err = at_tok_nextstr(&line, &tmp_ptr);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ // memcpy(net->plmn, tmp_ptr, strlen(tmp_ptr));
+ net->plmn = (uint32)atoi(tmp_ptr);
+ //LOG("req_net_sel_mode_get() 7");
+ //sleep(1);
+ err = at_tok_nextint(&line, &tmp_int);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ net->net_type = (uint8)tmp_int;
+
+ net->net_state = (uint8)MBTK_NET_AVIL_STATE_CURRENT;
+
+exit:
+ //LOG("req_net_sel_mode_get() 8");
+ //sleep(1);
+ at_response_free(response);
+ return err;
+}
+
+/*
+AT+COPS=0
+or
+AT+COPS=1,2,"46000",7
+
+OK
+
+*/
+static int req_net_sel_mode_set(mbtk_net_info_t* net, int *cme_err)
+{
+ ATResponse *response = NULL;
+ char cmd[50] = {0};
+ char* cmp_ptr = cmd;
+ if(net == NULL) {
+ cmp_ptr += sprintf(cmp_ptr, "AT+COPS=0");
+ } else {
+ if(net->net_sel_mode == 0) {
+ cmp_ptr += sprintf(cmp_ptr, "AT+COPS=0");
+ } else if(net->net_type == 0xFF) {
+ cmp_ptr += sprintf(cmp_ptr, "AT+COPS=1,2,\"%d\"",net->plmn);
+ } else {
+ cmp_ptr += sprintf(cmp_ptr, "AT+COPS=1,2,\"%d\",%d",net->plmn, net->net_type);
+ }
+ }
+
+ int err = at_send_command(cmd, &response);
+
+ if (err < 0 || response->success == 0) {
+ if(cme_err) {
+ *cme_err = at_get_cme_error(response);
+ }
+ goto exit;
+ }
+
+exit:
+ at_response_free(response);
+ return err;
+}
+
+/*
+AT*BAND=15
+OK
+
+*/
+static int req_band_set(mbtk_band_info_t* band, int *cme_err)
+{
+ ATResponse *response = NULL;
+ char cmd[100] = {0};
+ int err = -1;
+
+ if(band->gsm_band == 0 && band->umts_band == 0
+ && band->tdlte_band == 0 && band->fddlte_band == 0) {
+ sprintf(cmd, "AT*BAND=%d", band->net_pref);
+ } else {
+ log_hex("BAND_SUPPORT", &band_info.band_support, sizeof(mbtk_band_info_t));
+ log_hex("BAND", band, sizeof(mbtk_band_info_t));
+
+ if(band->gsm_band == 0) {
+ band->gsm_band = band_info.band_support.gsm_band;
+ }
+ if(band->umts_band == 0) {
+ band->umts_band = band_info.band_support.umts_band;
+ }
+ if(band->tdlte_band == 0) {
+ band->tdlte_band = band_info.band_support.tdlte_band;
+ }
+ if(band->fddlte_band == 0) {
+ band->fddlte_band = band_info.band_support.fddlte_band;
+ }
+
+ if((band->gsm_band & band_info.band_support.gsm_band) != band->gsm_band) {
+ LOG("GSM band error.");
+ goto exit;
+ }
+
+ if((band->umts_band & band_info.band_support.umts_band) != band->umts_band) {
+ LOG("UMTS band error.");
+ goto exit;
+ }
+
+ if((band->tdlte_band & band_info.band_support.tdlte_band) != band->tdlte_band) {
+ LOG("TDLTE band error.");
+ goto exit;
+ }
+
+ if((band->fddlte_band & band_info.band_support.fddlte_band) != band->fddlte_band) {
+ LOG("FDDLTE band error.");
+ goto exit;
+ }
+
+ if((band->lte_ext_band & band_info.band_support.lte_ext_band) != band->lte_ext_band) {
+ LOG("EXT_LTE band error.");
+ goto exit;
+ }
+
+ if(band->net_pref == 0xFF) { // No change net_pref.
+ int tmp_int;
+ err = at_send_command_singleline("AT*BAND?", "*BAND:", &response);
+ if (err < 0 || response->success == 0 || !response->p_intermediates){
+ if(cme_err) {
+ *cme_err = at_get_cme_error(response);
+ }
+ goto exit;
+ }
+
+ char *line = response->p_intermediates->line;
+ err = at_tok_start(&line);
+ if (err < 0)
+ {
+ goto exit;
+ }
+
+ err = at_tok_nextint(&line, &tmp_int);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ band->net_pref = (uint8)tmp_int; // Set to current net_pref.
+
+ at_response_free(response);
+ }
+
+ if(band->lte_ext_band > 0) {
+ sprintf(cmd, "AT*BAND=%d,%d,%d,%d,%d,,,,%d", band->net_pref, band->gsm_band, band->umts_band, band->tdlte_band, band->fddlte_band, band->lte_ext_band);
+ } else {
+ sprintf(cmd, "AT*BAND=%d,%d,%d,%d,%d", band->net_pref, band->gsm_band, band->umts_band, band->tdlte_band, band->fddlte_band);
+ }
+ }
+ err = at_send_command(cmd, &response);
+
+ if (err < 0 || response->success == 0){
+ if(cme_err) {
+ *cme_err = at_get_cme_error(response);
+ }
+ goto exit;
+ }
+
+ err = 0;
+exit:
+ at_response_free(response);
+ return err;
+}
+
+/*
+// ???????
+AT*BAND=?
+*BAND:(0-18),79,147,482,524503
+
+OK
+
+// ???????????
+AT*BAND?
+*BAND: 15, 78, 147, 482, 524503, 0, 2, 2, 0, 0
+
+OK
+
+// ?????????
+AT*BAND=5,79,147,128,1
+OK
+
+net_prefferred??
+ 0 : GSM only
+ 1 : UMTS only
+ 2 : GSM/UMTS(auto)
+ 3 : GSM/UMTS(GSM preferred)
+ 4 : GSM/UMTS(UMTS preferred)
+ 5 : LTE only
+ 6 : GSM/LTE(auto)
+ 7 : GSM/LTE(GSM preferred)
+ 8 : GSM/LTE(LTE preferred)
+ 9 : UMTS/LTE(auto)
+ 10 : UMTS/LTE(UMTS preferred)
+ 11 : UMTS/LTE(LTE preferred)
+ 12 : GSM/UMTS/LTE(auto)
+ 13 : GSM/UMTS/LTE(GSM preferred)
+ 14 : GSM/UMTS/LTE(UMTS preferred)
+ 15 : GSM/UMTS/LTE(LTE preferred)
+GSM band??
+ 1 ?C PGSM 900 (standard or primary)
+ 2 ?C DCS GSM 1800
+ 4 ?C PCS GSM 1900
+ 8 ?C EGSM 900 (extended)
+ 16 ?C GSM 450
+ 32 ?C GSM 480
+ 64 ?C GSM 850
+ 512 - BAND_LOCK_BIT // used for GSM band setting
+UMTS band??
+ 1 ?C UMTS_BAND_1
+ 2 ?C UMTS_BAND_2
+ 4 ?C UMTS_BAND_3
+ 8 ?C UMTS_BAND_4
+ 16 ?C UMTS_BAND_5
+ 32 ?C UMTS_BAND_6
+ 64 ?C UMTS_BAND_7
+ 128 ?C UMTS_BAND_8
+ 256 ?C UMTS_BAND_9
+LTEbandH(TDD-LTE band)
+ 32 ?C TDLTE_BAND_38
+ 64 ?C TDLTE_BAND_39
+ 128 ?C TDLTE_BAND_40
+ 256 ?C TDLTE_BAND_41
+LTEbandL(FDD-LTE band)
+ 1 ?C FDDLTE_BAND_1
+ 4 ?C FDDLTE _BAND_3
+ 8 ?C FDDLTE _BAND_4
+ 64 ?C FDDLTE _BAND_7
+ 65536 ?C FDDLTE _BAND_17
+ 524288 ?C FDDLTE _BAND_20
+*/
+static int req_band_get(mbtk_band_info_t *band, int *cme_err)
+{
+ ATResponse *response = NULL;
+ int tmp_int;
+
+ log_hex("BAND_SUPPORT", &band_info.band_support, sizeof(mbtk_band_info_t));
+ int err = at_send_command_singleline("AT*BAND?", "*BAND:", &response);
+ if (err < 0 || response->success == 0 || !response->p_intermediates){
+ if(cme_err) {
+ *cme_err = at_get_cme_error(response);
+ }
+ goto exit;
+ }
+
+ char *line = response->p_intermediates->line;
+ err = at_tok_start(&line);
+ if (err < 0)
+ {
+ goto exit;
+ }
+
+ err = at_tok_nextint(&line, &tmp_int);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ band->net_pref = (uint8)tmp_int;
+
+ err = at_tok_nextint(&line, &tmp_int);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ band->gsm_band = (uint16)tmp_int;
+
+ err = at_tok_nextint(&line, &tmp_int);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ band->umts_band = (uint16)tmp_int;
+
+ err = at_tok_nextint(&line, &tmp_int);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ band->tdlte_band = (uint32)tmp_int;
+
+ err = at_tok_nextint(&line, &tmp_int);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ band->fddlte_band = (uint32)tmp_int;
+
+ // roamingConfig
+ err = at_tok_nextint(&line, &tmp_int);
+ if (err < 0)
+ {
+ goto exit;
+ }
+
+ // srvDomain
+ err = at_tok_nextint(&line, &tmp_int);
+ if (err < 0)
+ {
+ goto exit;
+ }
+
+ // bandPriorityFlag
+ err = at_tok_nextint(&line, &tmp_int);
+ if (err < 0)
+ {
+ goto exit;
+ }
+
+ //
+ err = at_tok_nextint(&line, &tmp_int);
+ if (err < 0)
+ {
+ goto exit;
+ }
+
+ // ltebandExt
+ err = at_tok_nextint(&line, &tmp_int);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ band->lte_ext_band = (uint32)tmp_int;
+
+ log_hex("BAND", band, sizeof(mbtk_band_info_t));
+
+exit:
+ at_response_free(response);
+ return err;
+}
+
+/*
+AT+CSQ
++CSQ: 31,99
+
+OK
+
+AT+CESQ
++CESQ: 60,99,255,255,20,61
+
+OK
+
+AT+COPS?
++COPS: 0,2,"46001",7
+
+OK
+
+*/
+static int req_net_signal_get(mbtk_signal_info_t *signal, int *cme_err)
+{
+ ATResponse *response = NULL;
+ int tmp_int;
+ char *tmp_ptr = NULL;
+ // AT+EEMOPT=1 in the first.
+ int err = at_send_command_singleline("AT+CSQ", "+CSQ:", &response);
+ if (err < 0 || response->success == 0 || !response->p_intermediates){
+ if(cme_err != NULL)
+ *cme_err = at_get_cme_error(response);
+ err = -1;
+ goto exit;
+ }
+
+ char *line = response->p_intermediates->line;
+ err = at_tok_start(&line);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ err = at_tok_nextint(&line, &tmp_int);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ signal->rssi = (uint8)tmp_int;
+ at_response_free(response);
+
+ err = at_send_command_singleline("AT+CESQ", "+CESQ:", &response);
+ if (err < 0 || response->success == 0 || !response->p_intermediates){
+ if(cme_err != NULL)
+ *cme_err = at_get_cme_error(response);
+ err = -1;
+ goto exit;
+ }
+
+ line = response->p_intermediates->line;
+ err = at_tok_start(&line);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ err = at_tok_nextint(&line, &tmp_int);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ signal->rxlev = (uint8)tmp_int;
+
+ err = at_tok_nextint(&line, &tmp_int);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ signal->ber = (uint8)tmp_int;
+
+ err = at_tok_nextint(&line, &tmp_int);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ signal->rscp = (uint8)tmp_int;
+
+ err = at_tok_nextint(&line, &tmp_int);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ signal->ecno = (uint8)tmp_int;
+
+ err = at_tok_nextint(&line, &tmp_int);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ signal->rsrq = (uint8)tmp_int;
+
+ err = at_tok_nextint(&line, &tmp_int);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ signal->rsrp = (uint8)tmp_int;
+
+ at_response_free(response);
+ err = at_send_command_singleline("AT+COPS?", "+COPS:", &response);
+ if (err < 0 || response->success == 0 || !response->p_intermediates){
+ if(cme_err != NULL)
+ *cme_err = at_get_cme_error(response);
+ err = -1;
+ goto exit;
+ }
+ line = response->p_intermediates->line;
+ err = at_tok_start(&line);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ err = at_tok_nextint(&line, &tmp_int);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ if(!at_tok_hasmore(&line)) {
+ goto exit;
+ }
+ err = at_tok_nextint(&line, &tmp_int);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ err = at_tok_nextstr(&line, &tmp_ptr);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ err = at_tok_nextint(&line, &tmp_int);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ signal->type = (uint8)tmp_int;
+
+exit:
+ at_response_free(response);
+ return err;
+}
+
+/*
+AT+CREG=3
+OK
+
+AT+CREG?
++CREG: 3,1,"8330","06447340",7
+
+OK
+
+AT+CREG?
++CREG: 3,0
+
+OK
+
+AT+CEREG?
++CEREG: 3,1,"8330","06447340",7
+
+OK
+
+
+AT+CIREG?
++CIREG: 2,1,15
+
+OK
+
+AT+CIREG?
++CIREG: 0
+
+OK
+
+
+*/
+static int req_net_reg_get(mbtk_net_reg_info_t *reg, int *cme_err)
+{
+ ATResponse *response = NULL;
+ int tmp_int;
+ char *tmp_str = NULL;
+ int err = at_send_command("AT+CREG=3", &response);
+ if (err < 0 || response->success == 0){
+ if(cme_err) {
+ *cme_err = at_get_cme_error(response);
+ }
+ goto exit;
+ }
+ at_response_free(response);
+
+ err = at_send_command_multiline("AT+CREG?", "+CREG:", &response);
+ if (err < 0 || response->success == 0 || !response->p_intermediates){
+ if(cme_err) {
+ *cme_err = at_get_cme_error(response);
+ }
+ goto exit;
+ }
+
+ char *line = response->p_intermediates->line;
+ err = at_tok_start(&line);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ err = at_tok_nextint(&line, &tmp_int); // n
+ if (err < 0)
+ {
+ goto exit;
+ }
+ err = at_tok_nextint(&line, &tmp_int);// stat
+ if (err < 0)
+ {
+ goto exit;
+ }
+ reg->call_state = (uint8)tmp_int;
+
+ if(at_tok_hasmore(&line)) {
+ err = at_tok_nextstr(&line, &tmp_str); // lac
+ if (err < 0)
+ {
+ goto exit;
+ }
+ reg->lac = strtol(tmp_str, NULL, 16);
+
+ err = at_tok_nextstr(&line, &tmp_str); // ci
+ if (err < 0)
+ {
+ goto exit;
+ }
+ reg->ci = strtol(tmp_str, NULL, 16);
+
+ err = at_tok_nextint(&line, &tmp_int);// AcT
+ if (err < 0)
+ {
+ goto exit;
+ }
+ reg->type = (uint8)tmp_int;
+ }
+ at_response_free(response);
+
+ err = at_send_command_multiline("AT+CEREG?", "+CEREG:", &response);
+ if (err < 0 || response->success == 0 || !response->p_intermediates){
+ if(cme_err) {
+ *cme_err = at_get_cme_error(response);
+ }
+ goto exit;
+ }
+
+ line = response->p_intermediates->line;
+ err = at_tok_start(&line);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ err = at_tok_nextint(&line, &tmp_int); // n
+ if (err < 0)
+ {
+ goto exit;
+ }
+ err = at_tok_nextint(&line, &tmp_int);// stat
+ if (err < 0)
+ {
+ goto exit;
+ }
+ reg->data_state = (uint8)tmp_int;
+
+ if(reg->lac == 0 && at_tok_hasmore(&line)) {
+ err = at_tok_nextstr(&line, &tmp_str); // lac
+ if (err < 0)
+ {
+ goto exit;
+ }
+ reg->lac = strtol(tmp_str, NULL, 16);
+
+ err = at_tok_nextstr(&line, &tmp_str); // ci
+ if (err < 0)
+ {
+ goto exit;
+ }
+ reg->ci = strtol(tmp_str, NULL, 16);
+
+ err = at_tok_nextint(&line, &tmp_int);// AcT
+ if (err < 0)
+ {
+ goto exit;
+ }
+ reg->type = (uint8)tmp_int;
+ }
+ at_response_free(response);
+
+ err = at_send_command_multiline("AT+CIREG?", "+CIREG:", &response);
+ if (err < 0 || response->success == 0 || !response->p_intermediates){
+ reg->ims_state = (uint8)0;
+ err = 0;
+ goto exit;
+ }
+ line = response->p_intermediates->line;
+ err = at_tok_start(&line);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ err = at_tok_nextint(&line, &tmp_int); // n/stat
+ if (err < 0)
+ {
+ goto exit;
+ }
+ if(at_tok_hasmore(&line)) {
+ err = at_tok_nextint(&line, &tmp_int);// stat
+ if (err < 0)
+ {
+ goto exit;
+ }
+ reg->ims_state = (uint8)tmp_int;
+ } else {
+ reg->ims_state = (uint8)tmp_int;
+ }
+
+exit:
+ at_response_free(response);
+ return err;
+}
+
+/*
+AT+CGDCONT?
+
++CGDCONT: 1,"IPV4V6","ctnet","10.142.64.116 254.128.0.0.0.0.0.0.0.0.0.0.0.0.0.1",0,0,0,2,0,0
+
++CGDCONT: 8,"IPV4V6","IMS","254.128.0.0.0.0.0.0.0.0.0.0.0.0.0.1",0,0,0,2,1,1
+
+OK
+
+*/
+static int req_apn_get(mbtk_apn_info_array_t *apns, int *cme_err)
+{
+ ATResponse *response = NULL;
+ int err = at_send_command_multiline("AT+CGDCONT?", "+CGDCONT:", &response);
+
+ if (err < 0 || response->success == 0 || !response->p_intermediates){
+ if(cme_err) {
+ *cme_err = at_get_cme_error(response);
+ }
+ goto exit;
+ }
+
+ ATLine* lines_ptr = response->p_intermediates;
+ char *line = NULL;
+ int tmp_int;
+ char *tmp_str = NULL;
+ /*
+ <apn_num[1]><cid[1]><ip_type[1]><apn_len[2]><apn><user_len[2]><user><pass_len[2]><pass><auth_len[2]><auth>...
+ <cid[1]><ip_type[1]><apn_len[2]><apn><user_len[2]><user><pass_len[2]><pass><auth_len[2]><auth>
+ */
+ while(lines_ptr)
+ {
+ line = lines_ptr->line;
+ err = at_tok_start(&line);
+ if (err < 0)
+ {
+ goto exit;
+ }
+
+ err = at_tok_nextint(&line, &tmp_int); // cid
+ if (err < 0)
+ {
+ goto exit;
+ }
+ // Only get CID 1-7
+ if(tmp_int >= MBTK_APN_CID_MIN && tmp_int <= MBTK_APN_CID_MAX) {
+ apns->apns[apns->num].cid = (mbtk_ril_cid_enum)tmp_int;
+
+ err = at_tok_nextstr(&line, &tmp_str);// ip type
+ if (err < 0)
+ {
+ goto exit;
+ }
+ if(!strcasecmp(tmp_str, "IP")) {
+ apns->apns[apns->num].ip_type = MBTK_IP_TYPE_IP;
+ } else if(!strcasecmp(tmp_str, "IPV6")) {
+ apns->apns[apns->num].ip_type = MBTK_IP_TYPE_IPV6;
+ } else if(!strcasecmp(tmp_str, "IPV4V6")) {
+ apns->apns[apns->num].ip_type = MBTK_IP_TYPE_IPV4V6;
+ } else {
+ apns->apns[apns->num].ip_type = MBTK_IP_TYPE_PPP;
+ }
+
+ err = at_tok_nextstr(&line, &tmp_str); // apn
+ if (err < 0)
+ {
+ goto exit;
+ }
+ if(!str_empty(tmp_str)) {
+ memcpy(apns->apns[apns->num].apn, tmp_str, strlen(tmp_str));
+ }
+
+ apns->num++;
+ }
+
+ lines_ptr = lines_ptr->p_next;
+ }
+
+ goto exit;
+exit:
+ at_response_free(response);
+ return err;
+}
+
+/*
+AT+CGDCONT=1,"IPV4V6","cmnet"
+OK
+
+AT*AUTHReq=1,1,marvell,123456
+OK
+
+*/
+static int req_apn_set(mbtk_apn_info_t *apn, int *cme_err)
+{
+ ATResponse *response = NULL;
+ char cmd[400] = {0};
+ int index = 0;
+ int err = 0;
+
+ // Delete apn
+ if(str_empty(apn->apn)) {
+ sprintf(cmd, "AT+CGDCONT=%d", apn->cid);
+ err = at_send_command(cmd, &response);
+ if (err < 0 || response->success == 0){
+ if(cme_err) {
+ *cme_err = at_get_cme_error(response);
+ }
+ goto exit;
+ }
+ } else {
+ index += sprintf(cmd, "AT+CGDCONT=%d,", apn->cid);
+ switch(apn->ip_type) {
+ case MBTK_IP_TYPE_IP: {
+ index += sprintf(cmd + index,"\"IP\",");
+ break;
+ }
+ case MBTK_IP_TYPE_IPV6: {
+ index += sprintf(cmd + index,"\"IPV6\",");
+ break;
+ }
+ case MBTK_IP_TYPE_IPV4V6: {
+ index += sprintf(cmd + index,"\"IPV4V6\",");
+ break;
+ }
+ default: {
+ index += sprintf(cmd + index,"\"PPP\",");
+ break;
+ }
+ }
+ if(strlen(apn->apn) > 0) {
+ index += sprintf(cmd + index,"\"%s\"", apn->apn);
+ }
+
+ err = at_send_command(cmd, &response);
+ if (err < 0 || response->success == 0){
+ if(cme_err) {
+ *cme_err = at_get_cme_error(response);
+ }
+ goto exit;
+ }
+
+ if(!str_empty(apn->user) || !str_empty(apn->pass)) {
+ at_response_free(response);
+
+ memset(cmd,0,400);
+ int cmd_auth=0;
+ if(apn->auth == MBTK_APN_AUTH_PROTO_NONE)
+ cmd_auth = 0;
+ else if(apn->auth == MBTK_APN_AUTH_PROTO_PAP)
+ cmd_auth = 1;
+ else if(apn->auth == MBTK_APN_AUTH_PROTO_CHAP)
+ cmd_auth = 2;
+ else
+ goto exit;
+
+ sprintf(cmd, "AT*AUTHREQ=%d,%d,%s,%s",apn->cid,cmd_auth,apn->user,apn->pass);
+ err = at_send_command(cmd, &response);
+ if (err < 0 || response->success == 0){
+ if(cme_err) {
+ *cme_err = at_get_cme_error(response);
+ }
+ goto exit;
+ }
+ }
+ }
+
+exit:
+ at_response_free(response);
+ return err;
+}
+
+/*
+AT+CGACT?
++CGACT: 1,1
++CGACT: 8,1
+OK
+
+AT+CGACT=1,<cid>
+OK
+
+*/
+static int req_data_call_start(mbtk_ril_cid_enum cid, bool def_route,
+ int retry_interval, int timeout, mbtk_ip_info_t *ip_info, int *cme_err)
+{
+ ATResponse *response = NULL;
+ char cmd[400] = {0};
+ int err = 0;
+
+ sprintf(cmd, "AT+CGACT=1,%d", cid);
+ err = at_send_command(cmd, &response);
+ if (err < 0 || response->success == 0){
+ if(cme_err) {
+ *cme_err = at_get_cme_error(response);
+ }
+ goto exit;
+ }
+
+exit:
+ at_response_free(response);
+ return err;
+}
+
+/*
+AT+CGACT=0,<cid>
+OK
+
+*/
+static int req_data_call_stop(mbtk_ril_cid_enum cid, int timeout, int *cme_err)
+{
+ ATResponse *response = NULL;
+ char cmd[400] = {0};
+ int err = 0;
+
+ sprintf(cmd, "AT+CGACT=0,%d", cid);
+ err = at_send_command(cmd, &response);
+ if (err < 0 || response->success == 0){
+ if(cme_err) {
+ *cme_err = at_get_cme_error(response);
+ }
+ goto exit;
+ }
+
+exit:
+ at_response_free(response);
+ return err;
+}
+
+/*
+AT+CGCONTRDP=1
++CGCONTRDP: 1,7,"cmnet-2.MNC000.MCC460.GPRS","10.255.74.26","","223.87.253.100","223.87.253.253","","",0,0
++CGCONTRDP: 1,7,"cmnet-2.MNC000.MCC460.GPRS","254.128.0.0.0.0.0.0.0.1.0.2.144.5.212.239","","36.9.128.98.32.0.0.2.0.0.0.0.0.0.0.1","36.9.128.98.32.0.0.2.0.0.0.0.0.0.0.2","","",0,0
+
+OK
+
+*/
+static int req_data_call_state_get(mbtk_ril_cid_enum cid, mbtk_ip_info_t *ip_info, int *cme_err)
+{
+ ATResponse *response = NULL;
+ char cmd[50] = {0};
+ int err = 0;
+
+ sprintf(cmd, "AT+CGCONTRDP=%d", cid);
+
+ err = at_send_command_multiline(cmd, "+CGCONTRDP:", &response);
+ if (err < 0 || response->success == 0 || !response->p_intermediates){
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+ ATLine* lines_ptr = response->p_intermediates;
+ char *line = NULL;
+ int tmp_int;
+ char *tmp_ptr = NULL;
+ while(lines_ptr)
+ {
+ line = lines_ptr->line;
+ err = at_tok_start(&line);
+ if (err < 0)
+ {
+ goto exit;
+ }
+
+ err = at_tok_nextint(&line, &tmp_int); // cid
+ if (err < 0)
+ {
+ goto exit;
+ }
+ err = at_tok_nextint(&line, &tmp_int); // bearer_id
+ if (err < 0)
+ {
+ goto exit;
+ }
+ err = at_tok_nextstr(&line, &tmp_ptr); // APN
+ if (err < 0)
+ {
+ goto exit;
+ }
+
+ err = at_tok_nextstr(&line, &tmp_ptr); // IP
+ if (err < 0 || str_empty(tmp_ptr))
+ {
+ goto exit;
+ }
+ if(is_ipv4(tmp_ptr)) {
+ if(inet_pton(AF_INET, tmp_ptr, &(ip_info->ipv4.IPAddr)) < 0) {
+ LOGE("inet_pton() fail.");
+ err = -1;
+ goto exit;
+ }
+
+ ip_info->ipv4.valid = true;
+ //log_hex("IPv4", &(ipv4->IPAddr), sizeof(struct in_addr));
+ } else {
+ if(str_2_ipv6(tmp_ptr, &(ip_info->ipv6.IPV6Addr))) {
+ LOGE("str_2_ipv6() fail.");
+ err = -1;
+ goto exit;
+ }
+
+ ip_info->ipv6.valid = true;
+ //log_hex("IPv6", &(ipv6->IPV6Addr), 16);
+ }
+
+ err = at_tok_nextstr(&line, &tmp_ptr); // Gateway
+ if (err < 0)
+ {
+ goto exit;
+ }
+ if(!str_empty(tmp_ptr)) { // No found gateway
+ if(is_ipv4(tmp_ptr)) {
+ if(inet_pton(AF_INET, tmp_ptr, &(ip_info->ipv4.GateWay)) < 0) {
+ LOGE("inet_pton() fail.");
+ err = -1;
+ goto exit;
+ }
+
+ //log_hex("IPv4", &(ipv4->GateWay), sizeof(struct in_addr));
+ } else {
+ if(str_2_ipv6(tmp_ptr, &(ip_info->ipv6.GateWay))) {
+ LOGE("str_2_ipv6() fail.");
+ err = -1;
+ goto exit;
+ }
+
+ //log_hex("IPv6", &(ipv6->GateWay), 16);
+ }
+ }
+
+ err = at_tok_nextstr(&line, &tmp_ptr); // prim_DNS
+ if (err < 0)
+ {
+ goto exit;
+ }
+ if(!str_empty(tmp_ptr)) { // No found Primary DNS
+ if(is_ipv4(tmp_ptr)) {
+ if(inet_pton(AF_INET, tmp_ptr, &(ip_info->ipv4.PrimaryDNS)) < 0) {
+ LOGE("inet_pton() fail.");
+ err = -1;
+ goto exit;
+ }
+
+ //log_hex("IPv4", &(ipv4->PrimaryDNS), sizeof(struct in_addr));
+ } else {
+ if(str_2_ipv6(tmp_ptr, &(ip_info->ipv6.PrimaryDNS))) {
+ LOGE("str_2_ipv6() fail.");
+ err = -1;
+ goto exit;
+ }
+
+ //log_hex("IPv6", &(ipv6->PrimaryDNS), 16);
+ }
+ }
+
+ err = at_tok_nextstr(&line, &tmp_ptr); // sec_DNS
+ if (err < 0)
+ {
+ goto exit;
+ }
+ if(!str_empty(tmp_ptr)) { // No found Secondary DNS
+ if(is_ipv4(tmp_ptr)) {
+ if(inet_pton(AF_INET, tmp_ptr, &(ip_info->ipv4.SecondaryDNS)) < 0) {
+ LOGE("inet_pton() fail.");
+ err = -1;
+ goto exit;
+ }
+
+ //log_hex("IPv4", &(ipv4->SecondaryDNS), sizeof(struct in_addr));
+ } else {
+ if(str_2_ipv6(tmp_ptr, &(ip_info->ipv6.SecondaryDNS))) {
+ LOGE("str_2_ipv6() fail.");
+ err = -1;
+ goto exit;
+ }
+
+ //log_hex("IPv6", &(ipv6->SecondaryDNS), 16);
+ }
+ }
+
+ lines_ptr = lines_ptr->p_next;
+ }
+
+exit:
+ at_response_free(response);
+ return err;
+}
+
+
+//void net_list_free(void *data);
+// Return MBTK_INFO_ERR_SUCCESS,will call pack_error_send() to send RSP.
+// Otherwise, do not call pack_error_send().
+mbtk_ril_err_enum net_pack_req_process(sock_cli_info_t* cli_info, ril_msg_pack_info_t* pack)
+{
+ mbtk_ril_err_enum err = MBTK_RIL_ERR_SUCCESS;
+ int cme_err = MBTK_RIL_ERR_CME_NON;
+ switch(pack->msg_id)
+ {
+ case RIL_MSG_ID_NET_AVAILABLE:
+ {
+ if(pack->data_len == 0 || pack->data == NULL)
+ {
+ mbtk_net_info_array_t net_array;
+ memset(&net_array, 0, sizeof(mbtk_net_info_array_t));
+ if(req_available_net_get(&net_array, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOGD("Get Available Net fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &net_array, sizeof(mbtk_net_info_array_t));
+ }
+ }
+ else // Set
+ {
+ err = MBTK_RIL_ERR_UNSUPPORTED;
+ LOGW("Unsupport set available net.");
+ }
+ break;
+ }
+ case RIL_MSG_ID_NET_SEL_MODE:
+ {
+ if(pack->data_len == 0 || pack->data == NULL)
+ {
+ mbtk_net_info_t info;
+ memset(&info, 0, sizeof(mbtk_net_info_t));
+ if(req_net_sel_mode_get(&info, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOGD("Get Net sel mode fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &info, sizeof(mbtk_net_info_t));
+ }
+ }
+ else // Set
+ {
+ mbtk_net_info_t *info = (mbtk_net_info_t*)pack->data;
+ if(req_net_sel_mode_set(info, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOGD("Set Net sel mode fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+ }
+ }
+ break;
+ }
+ case RIL_MSG_ID_NET_BAND:
+ {
+ if(pack->data_len == 0 || pack->data == NULL)
+ {
+ err = MBTK_RIL_ERR_REQ_PARAMETER;
+ LOG("No data found.");
+ }
+ else // Set
+ {
+ if(pack->data_len == sizeof(uint8)) {
+ if(*(pack->data)) { // Get current bands.
+ mbtk_band_info_t band;
+ memset(&band, 0x0, sizeof(mbtk_band_info_t));
+ if(req_band_get(&band, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Get net band fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &band, sizeof(mbtk_band_info_t));
+ }
+ } else { // Get support bands.
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &band_info.band_support , sizeof(mbtk_band_info_t));
+ }
+ } else { // Set current bands.
+ mbtk_band_info_t* band = (mbtk_band_info_t*)pack->data;
+ if(pack->data_len != sizeof(mbtk_band_info_t))
+ {
+ err = MBTK_RIL_ERR_REQ_PARAMETER;
+ LOG("Set net band error.");
+ break;
+ }
+
+ if(req_band_set(band, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Set net band fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+ }
+ }
+ }
+ break;
+ }
+ case RIL_MSG_ID_NET_SIGNAL:
+ {
+ if(pack->data_len == 0 || pack->data == NULL)
+ {
+ mbtk_signal_info_t signal;
+ memset(&signal, 0, sizeof(mbtk_signal_info_t));
+ if(req_net_signal_get(&signal, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOGD("Get net signal fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &signal, sizeof(mbtk_signal_info_t));
+ }
+ }
+ else // Set
+ {
+ err = MBTK_RIL_ERR_UNSUPPORTED;
+ LOGW("Unsupport set net signal.");
+ }
+ break;
+ }
+ case RIL_MSG_ID_NET_REG:
+ {
+ if(pack->data_len == 0 || pack->data == NULL)
+ {
+ mbtk_net_reg_info_t net_reg;
+ memset(&net_reg, 0, sizeof(mbtk_net_reg_info_t));
+ if(req_net_reg_get(&net_reg, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOGD("Get Net reg info fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &net_reg, sizeof(mbtk_net_reg_info_t));
+ }
+ }
+ else // Set
+ {
+ err = MBTK_RIL_ERR_UNSUPPORTED;
+ LOGW("Unsupport set net reg info.");
+ }
+ break;
+ }
+ case RIL_MSG_ID_NET_CELL:
+ {
+ if(pack->data_len == 0 || pack->data == NULL)
+ {
+ mbtk_net_info_array_t net_array;
+ memset(&net_array, 0, sizeof(mbtk_net_info_array_t));
+ if(req_available_net_get(&net_array, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOGD("Get Available Net fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &net_array, sizeof(mbtk_net_info_array_t));
+ }
+ }
+ else // Set
+ {
+ err = MBTK_RIL_ERR_UNSUPPORTED;
+ LOGW("Unsupport set available net.");
+ }
+ break;
+ }
+ case RIL_MSG_ID_NET_APN:
+ {
+ if(pack->data_len == 0 || pack->data == NULL)
+ {
+ mbtk_apn_info_array_t apns;
+ memset(&apns, 0, sizeof(mbtk_apn_info_array_t));
+ if(req_apn_get(&apns, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOGD("Get APN fail.");
+ }
+ else
+ {
+ LOGD("size - %d", sizeof(mbtk_apn_info_array_t));
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &apns, sizeof(mbtk_apn_info_array_t));
+ }
+ }
+ else // Set
+ {
+ mbtk_apn_info_t *apn = (mbtk_apn_info_t*)pack->data;
+ if(apn_cid_reset(apn)) {
+ err = MBTK_RIL_ERR_CID;
+ } else {
+ if(apn_conf_support(apn->cid)) {
+ if(req_apn_set(apn, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOGD("Set APN fail.");
+ }
+ else
+ {
+ if(apn_prop_set(apn)) {
+ LOGE("Save APN fail.");
+ }
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+ }
+ } else {
+ err = MBTK_RIL_ERR_UNSUPPORTED;
+ LOGD("Can not set APN for CID : %d", apn->cid);
+ }
+ }
+ }
+ break;
+ }
+ case RIL_MSG_ID_NET_DATA_CALL:
+ {
+ if(pack->data_len == 0 || pack->data == NULL)
+ {
+ err = MBTK_RIL_ERR_UNSUPPORTED;
+ }
+ else // Set
+ {
+ mbtk_data_call_info_t *call_info = (mbtk_data_call_info_t*)pack->data;
+ if(call_info->type == MBTK_DATA_CALL_START) {
+ mbtk_ip_info_t ip_info;
+ memset(&ip_info, 0, sizeof(ip_info));
+ if(apn_prop_reset(call_info)) {
+ err = MBTK_RIL_ERR_REQ_UNKNOWN;
+ LOG("apn_prop_reset() fail.");
+ } else {
+ if(req_data_call_start(call_info->cid, call_info->def_route,
+ call_info->retry_interval, call_info->timeout, &ip_info, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOGD("Start data call fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &ip_info, sizeof(mbtk_ip_info_t));
+ }
+ }
+ } else if(call_info->type == MBTK_DATA_CALL_STOP) {
+ if(req_data_call_stop(call_info->cid, call_info->timeout, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOGD("Stop data call fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+ }
+ } else {
+ mbtk_ip_info_t ip_info;
+ memset(&ip_info, 0, sizeof(ip_info));
+ if(req_data_call_state_get(call_info->cid ,&ip_info, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOGD("Get data call state fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &ip_info, sizeof(mbtk_ip_info_t));
+ }
+ }
+ }
+ break;
+ }
+ default:
+ {
+ err = MBTK_RIL_ERR_REQ_UNKNOWN;
+ LOG("Unknown request : %s", id2str(pack->msg_id));
+ break;
+ }
+ }
+
+ return err;
+}
+
+
+
+
+
+
diff --git a/mbtk/mbtk_rild_v2/src/ril_pb.c b/mbtk/mbtk_rild_v2/src/ril_pb.c
new file mode 100755
index 0000000..088aa46
--- /dev/null
+++ b/mbtk/mbtk_rild_v2/src/ril_pb.c
@@ -0,0 +1,57 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <pthread.h>
+#include <sys/epoll.h>
+#include <fcntl.h>
+#include <signal.h>
+
+#include "mbtk_type.h"
+#include "mbtk_ril.h"
+#include "atchannel.h"
+#include "at_tok.h"
+#include "mbtk_utils.h"
+#include "ril_info.h"
+
+void ril_rsp_pack_send(int fd, int ril_id, int msg_index, const void* data, int data_len);
+
+//void net_list_free(void *data);
+// Return MBTK_INFO_ERR_SUCCESS,will call pack_error_send() to send RSP.
+// Otherwise, do not call pack_error_send().
+mbtk_ril_err_enum pb_pack_req_process(sock_cli_info_t* cli_info, ril_msg_pack_info_t* pack)
+{
+ mbtk_ril_err_enum err = MBTK_RIL_ERR_SUCCESS;
+ int cme_err = MBTK_RIL_ERR_CME_NON;
+ switch(pack->msg_id)
+ {
+ case RIL_MSG_ID_PB_STATE:
+ {
+ if(pack->data_len == 0 || pack->data == NULL)
+ {
+ err = MBTK_RIL_ERR_UNSUPPORTED;
+ }
+ else // Set
+ {
+
+ }
+ break;
+ }
+ default:
+ {
+ err = MBTK_RIL_ERR_REQ_UNKNOWN;
+ LOG("Unknown request : %s", id2str(pack->msg_id));
+ break;
+ }
+ }
+
+ return err;
+}
+
+
+
+
+
diff --git a/mbtk/mbtk_rild_v2/src/ril_sim.c b/mbtk/mbtk_rild_v2/src/ril_sim.c
new file mode 100755
index 0000000..ebc09f2
--- /dev/null
+++ b/mbtk/mbtk_rild_v2/src/ril_sim.c
@@ -0,0 +1,847 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <pthread.h>
+#include <sys/epoll.h>
+#include <fcntl.h>
+#include <signal.h>
+
+#include "mbtk_type.h"
+#include "mbtk_ril.h"
+#include "atchannel.h"
+#include "at_tok.h"
+#include "mbtk_utils.h"
+#include "ril_info.h"
+
+void ril_rsp_pack_send(int fd, int ril_id, int msg_index, const void* data, int data_len);
+
+/** Returns SIM_NOT_READY on error */
+mbtk_sim_state_enum ril_sim_state_get()
+{
+ ATResponse *p_response = NULL;
+ int err;
+ mbtk_sim_state_enum ret = MBTK_SIM_STATE_UNKNOWN;
+ char *cpinLine;
+ char *cpinResult;
+
+ err = at_send_command_singleline("AT+CPIN?", "+CPIN:", &p_response);
+
+ if (err < 0 || p_response->success == 0 || !p_response->p_intermediates)
+ {
+ ret = MBTK_SIM_STATE_NOT_READY;
+ goto done;
+ }
+
+ switch (at_get_cme_error(p_response))
+ {
+ case CME_SUCCESS:
+ break;
+
+ case CME_SIM_NOT_INSERTED:
+ ret = MBTK_SIM_STATE_ABSENT;
+ goto done;
+
+ default:
+ ret = MBTK_SIM_STATE_NOT_READY;
+ goto done;
+ }
+
+ /* CPIN? has succeeded, now look at the result */
+
+ cpinLine = p_response->p_intermediates->line;
+ err = at_tok_start (&cpinLine);
+
+ if (err < 0)
+ {
+ ret = MBTK_SIM_STATE_NOT_READY;
+ goto done;
+ }
+
+ err = at_tok_nextstr(&cpinLine, &cpinResult);
+
+ if (err < 0)
+ {
+ ret = MBTK_SIM_STATE_NOT_READY;
+ goto done;
+ }
+
+ if (0 == strcmp (cpinResult, "SIM PIN"))
+ {
+ ret = MBTK_SIM_STATE_SIM_PIN;
+ }
+ else if (0 == strcmp (cpinResult, "SIM PUK"))
+ {
+ ret = MBTK_SIM_STATE_SIM_PUK;
+ }
+ else if (0 == strcmp (cpinResult, "PH-SIMLOCK PIN"))
+ {
+ ret = MBTK_SIM_STATE_PH_SIMLOCK_PIN;
+ }
+ else if (0 == strcmp (cpinResult, "PH-SIMLOCK PIN"))
+ {
+ ret = MBTK_SIM_STATE_PH_SIMLOCK_PUK;
+ }
+ else if (0 == strcmp (cpinResult, "PH-FSIM PIN"))
+ {
+ ret = MBTK_SIM_STATE_PH_FSIM_PIN;
+ }
+ else if (0 == strcmp (cpinResult, "PH-FSIM PUK"))
+ {
+ ret = MBTK_SIM_STATE_PH_FSIM_PUK;
+ }
+ else if (0 == strcmp (cpinResult, "SIM PIN2"))
+ {
+ ret = MBTK_SIM_STATE_SIM_PIN2;
+ }
+ else if (0 == strcmp (cpinResult, "SIM PUK2"))
+ {
+ ret = MBTK_SIM_STATE_SIM_PUK2;
+ }
+ else if (0 == strcmp (cpinResult, "PH-NET PIN"))
+ {
+ ret = MBTK_SIM_STATE_PH_NET_PIN;
+ }
+ else if (0 == strcmp (cpinResult, "PH-NET PUK"))
+ {
+ ret = MBTK_SIM_STATE_PH_NET_PUK;
+ }
+ else if (0 == strcmp (cpinResult, "PH-NETSUB PIN"))
+ {
+ ret = MBTK_SIM_STATE_PH_NETSUB_PIN;
+ }
+ else if (0 == strcmp (cpinResult, "PH-NETSUB PUK"))
+ {
+ ret = MBTK_SIM_STATE_PH_NETSUB_PUK;
+ }
+ else if (0 == strcmp (cpinResult, "PH-SP PIN"))
+ {
+ ret = MBTK_SIM_STATE_PH_SP_PIN;
+ }
+ else if (0 == strcmp (cpinResult, "PH-SP PUK"))
+ {
+ ret = MBTK_SIM_STATE_PH_SP_PUK;
+ }
+ else if (0 == strcmp (cpinResult, "PH-CORP PIN"))
+ {
+ ret = MBTK_SIM_STATE_PH_CORP_PIN;
+ }
+ else if (0 == strcmp (cpinResult, "PH-CORP PUK"))
+ {
+ ret = MBTK_SIM_STATE_PH_CORP_PUK;
+ }
+ else if (0 == strcmp (cpinResult, "READY"))
+ {
+ ret = MBTK_SIM_STATE_READY;
+ } else {
+ ret = MBTK_SIM_STATE_ABSENT;
+ }
+
+done:
+ at_response_free(p_response);
+ p_response = NULL;
+ cpinResult = NULL;
+ ril_info.sim_state = ret;
+ return ret;
+}
+
+/*
+AT*EUICC?
+*EUICC: 1
+
+OK
+*/
+static int req_sim_type_get(uint8 *type, int *cme_err)
+{
+ ATResponse *response = NULL;
+ char *tmp_ptr = NULL;
+ int err = at_send_command_singleline("AT*EUICC?", "*EUICC:", &response);
+
+ if (err < 0 || response->success == 0 || !response->p_intermediates){
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+
+ char *line = response->p_intermediates->line;
+ err = at_tok_start(&line);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ int sim_card_type = -1;
+ err = at_tok_nextint(&line, &sim_card_type);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ if(sim_card_type != -1)
+ *type = sim_card_type;
+ goto exit;
+exit:
+ at_response_free(response);
+ return err;
+}
+
+/*
+AT+ICCID
++ICCID: 89860621330065648041
+
+OK
+*/
+static int req_iccid_get(void *data, int *cme_err)
+{
+ ATResponse *response = NULL;
+ char *tmp_ptr = NULL;
+ int err = at_send_command_singleline("AT+ICCID", "+ICCID:", &response);
+
+ if (err < 0 || response->success == 0 || !response->p_intermediates){
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+
+ char *line = response->p_intermediates->line;
+ err = at_tok_start(&line);
+ if (err < 0)
+ {
+ goto exit;
+ }
+
+ err = at_tok_nextstr(&line, &tmp_ptr);
+ if (err < 0)
+ {
+ goto exit;
+ }
+
+ memcpy(data, tmp_ptr, strlen(tmp_ptr));
+exit:
+ at_response_free(response);
+ return err;
+}
+
+/*
+AT+CNUM?
++CNUM: "","13980414101",129
+
+OK
+
+*/
+static int req_phone_number_get(void *data, int *cme_err)
+{
+ ATResponse *response = NULL;
+ char *tmp_ptr = NULL;
+ int err = at_send_command_singleline("AT+CNUM?", "+CNUM:", &response);
+ if (err < 0 || response == NULL || response->success == 0 || !response->p_intermediates){
+ if(response) {
+ *cme_err = at_get_cme_error(response);
+ }
+ LOGD("AT+CNUM? fail.");
+ goto exit;
+ }
+
+ char *line = response->p_intermediates->line;
+ if(line == NULL) {
+ LOGD("line is NULL");
+ goto exit;
+ }
+ err = at_tok_start(&line);
+ if (err < 0)
+ {
+ goto exit;
+ }
+
+ err = at_tok_nextstr(&line, &tmp_ptr);
+ if (err < 0)
+ {
+ goto exit;
+ }
+
+ err = at_tok_nextstr(&line, &tmp_ptr);
+ if (err < 0)
+ {
+ goto exit;
+ }
+
+ memcpy(data, tmp_ptr, strlen(tmp_ptr));
+exit:
+ at_response_free(response);
+ return err;
+}
+
+
+/*
+AT+CIMI
+460068103383304
+
+OK
+
+*/
+static int req_imsi_get(void *data, int *cme_err)
+{
+ ATResponse *response = NULL;
+ int err = at_send_command_numeric("AT+CIMI", &response);
+
+ if (err < 0 || response->success == 0 || !response->p_intermediates){
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+
+ memcpy(data, response->p_intermediates->line, strlen(response->p_intermediates->line));
+exit:
+ at_response_free(response);
+ return err;
+}
+
+static int req_sim_lock_state_get(int *state, int *cme_err)
+{
+ ATResponse *response = NULL;
+ char cmd[64]={0};
+
+ int err = at_send_command_singleline("AT+CLCK=SC,2", "+CLCK:", &response);
+ if (err < 0 || response == NULL || response->success == 0 || !response->p_intermediates){
+ if(response) {
+ *cme_err = at_get_cme_error(response);
+ }
+ LOGD("AT+CLCK fail.");
+ goto exit;
+ }
+
+ char *line = response->p_intermediates->line;
+ if(line == NULL) {
+ LOGD("line is NULL");
+ goto exit;
+ }
+ err = at_tok_start(&line);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ err = at_tok_nextint(&line, state);
+ if (err < 0)
+ {
+ goto exit;
+ }
+
+exit:
+ at_response_free(response);
+ return err;
+}
+
+/*
+*
+AT+CLCK=SC,0,1234
++CLCK: 0
+
+OK
+
+AT+CLCK=SC,1,1234
++CLCK: 1
+
+OK
+
+*
+*/
+static int req_sim_lock_switch(bool enable, uint8* pin, int *cme_err)
+{
+ ATResponse *response = NULL;
+ char cmd[64]={0};
+ snprintf(cmd, sizeof(cmd), "AT+CLCK=SC,%d,%s", enable ? 1 : 0, pin);
+ int err = at_send_command_singleline(cmd, "+CLCK:", &response);
+ if (err < 0 || response == NULL || response->success == 0 || !response->p_intermediates){
+ if(response) {
+ *cme_err = at_get_cme_error(response);
+ }
+ LOGD("AT+CLCK fail.");
+ goto exit;
+ }
+
+ int ret;
+ char *line = response->p_intermediates->line;
+ if(line == NULL) {
+ LOGD("line is NULL");
+ goto exit;
+ }
+ err = at_tok_start(&line);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ err = at_tok_nextint(&line, &ret);
+ if (err < 0)
+ {
+ goto exit;
+ }
+
+ if(enable) {
+ if(ret != 1) {
+ LOGW("+CLCK not 1.");
+ err = -1;
+ goto exit;
+ }
+ } else {
+ if(ret != 0) {
+ LOGW("+CLCK not 0.");
+ err = -1;
+ goto exit;
+ }
+ }
+
+exit:
+ at_response_free(response);
+ return err;
+}
+
+static int req_sim_pin_change(uint8* old_pin, uint8 *new_pin, int *cme_err)
+{
+ ATResponse *response = NULL;
+ char cmd[128]={0};
+ int err = 0;
+ int state;
+ if(req_sim_lock_state_get(&state, cme_err) || *cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ return -1;
+ }
+
+ if(state == 0) { // Sim lock not open.
+ return req_sim_lock_switch(TRUE, new_pin, cme_err);
+ } else {// Change password.
+ snprintf(cmd, sizeof(cmd), "AT+CPWD=SC,%s,%s", old_pin, new_pin);
+ err = at_send_command(cmd, &response);
+ if (err < 0 || response->success == 0){
+ if(cme_err) {
+ *cme_err = at_get_cme_error(response);
+ }
+ goto exit;
+ }
+ }
+
+exit:
+ at_response_free(response);
+ return err;
+}
+
+static int req_sim_pin_verify(uint8* pin, int *cme_err)
+{
+ ATResponse *response = NULL;
+ char cmd[64]={0};
+ sprintf(cmd, "AT+CPIN=%s", pin);
+ int err = at_send_command(cmd, &response);
+ if (err < 0 || response->success == 0){
+ if(cme_err) {
+ *cme_err = at_get_cme_error(response);
+ }
+ goto exit;
+ }
+
+exit:
+ at_response_free(response);
+ return err;
+}
+
+static int req_sim_puk_verify(uint8* puk, uint8* pin, int *cme_err)
+{
+ ATResponse *response = NULL;
+ char cmd[64]={0};
+ sprintf(cmd, "AT+CPIN=%s,%s", puk, pin);
+ int err = at_send_command(cmd, &response);
+ if (err < 0 || response->success == 0){
+ if(cme_err) {
+ *cme_err = at_get_cme_error(response);
+ }
+ goto exit;
+ }
+
+exit:
+ at_response_free(response);
+ return err;
+}
+
+static int req_sim_lock_set(mbtk_sim_lock_info_t *lock_info, int *cme_err)
+{
+ switch(lock_info->type)
+ {
+ case MBTK_SIM_LOCK_TYPE_DISABLE:
+ {
+ return req_sim_lock_switch(FALSE, lock_info->pin1, cme_err);
+ }
+ case MBTK_SIM_LOCK_TYPE_ENABLE:
+ {
+ return req_sim_lock_switch(TRUE, lock_info->pin1, cme_err);
+ }
+ case MBTK_SIM_LOCK_TYPE_CHANGE:
+ {
+ return req_sim_pin_change(lock_info->pin1, lock_info->pin2, cme_err);
+ }
+ case MBTK_SIM_LOCK_TYPE_VERIFY_PIN:
+ {
+ return req_sim_pin_verify(lock_info->pin1, cme_err);
+ }
+ case MBTK_SIM_LOCK_TYPE_VERIFY_PUK:
+ {
+ return req_sim_puk_verify(lock_info->puk, lock_info->pin1, cme_err);
+ }
+ default:
+ {
+ LOGE("Unknown type : %d", lock_info->type);
+ break;
+ }
+ }
+
+ return -1;
+}
+
+/*
+AT+EPIN?
++EPIN: 3,0,10,0
+
+OK
+*/
+static int req_pin_puk_last_times_get(mbtk_pin_puk_last_times_t *times, int *cme_err)
+{
+ ATResponse *response = NULL;
+ char *tmp_ptr = NULL;
+ int err = at_send_command_singleline("AT+EPIN?", "+EPIN:", &response);
+
+ if (err < 0 || response->success == 0 || !response->p_intermediates){
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+
+ char *line = response->p_intermediates->line;
+ err = at_tok_start(&line);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ mbtk_pin_puk_last_times_t last_times={0};
+ err = at_tok_nextint(&line, &(last_times.p1_retry));
+ if (err < 0)
+ {
+ goto exit;
+ }
+ times->p1_retry = last_times.p1_retry;
+ err = at_tok_nextint(&line, &(last_times.p2_retry));
+ if (err < 0)
+ {
+ goto exit;
+ }
+ times->p2_retry = last_times.p2_retry;
+ err = at_tok_nextint(&line, &(last_times.puk1_retry));
+ if (err < 0)
+ {
+ goto exit;
+ }
+ times->puk1_retry = last_times.puk1_retry;
+ err = at_tok_nextint(&line, &(last_times.puk2_retry));
+ if (err < 0)
+ {
+ goto exit;
+ }
+ times->puk2_retry = last_times.puk2_retry;
+
+exit:
+ at_response_free(response);
+ return err;
+}
+
+/*
+AT+CPOL?
+*EUICC: 1
+
+OK
+*/
+static int req_plmn_get(mbtk_plmn_info *info, int *cme_err)
+{
+ ATResponse *response = NULL;
+ char *tmp_ptr = NULL;
+ int err = at_send_command_multiline("AT+CPOL?", "+CPOL:", &response);
+
+ if (err < 0 || response->success == 0 || !response->p_intermediates){
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+
+ int mccmnc_type = -1;
+ int count = -1;
+ char *mccmnc_name = NULL;
+ ATLine* lines_ptr = response->p_intermediates;
+ char *line = NULL;
+ while(lines_ptr)
+ {
+ line = lines_ptr->line;
+ //if(strStartsWith(line, "+CPOL:"))
+ {
+ err = at_tok_start(&line);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ err = at_tok_nextint(&line, &count);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ info->count = count;
+
+ err = at_tok_nextint(&line, &mccmnc_type);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ info->plmn[count-1].format = mccmnc_type;
+
+ err = at_tok_nextstr(&line, &mccmnc_name);
+ if (err < 0)
+ {
+ goto exit;
+ }
+ memcpy(info->plmn[count-1].name, mccmnc_name, strlen(mccmnc_name));
+ mccmnc_name = NULL;
+ }
+ lines_ptr = lines_ptr->p_next;
+ }
+
+exit:
+ at_response_free(response);
+ return err;
+}
+
+//void net_list_free(void *data);
+// Return MBTK_INFO_ERR_SUCCESS,will call pack_error_send() to send RSP.
+// Otherwise, do not call pack_error_send().
+mbtk_ril_err_enum sim_pack_req_process(sock_cli_info_t* cli_info, ril_msg_pack_info_t* pack)
+{
+ mbtk_ril_err_enum err = MBTK_RIL_ERR_SUCCESS;
+ int cme_err = MBTK_RIL_ERR_CME_NON;
+ switch(pack->msg_id)
+ {
+ case RIL_MSG_ID_SIM_STATE:
+ {
+ if(pack->data_len == 0 || pack->data == NULL)
+ {
+ mbtk_sim_state_enum state = ril_sim_state_get();
+ if(state == MBTK_SIM_STATE_UNKNOWN)
+ {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ LOG("Get sim state fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &state, sizeof(uint8));
+ }
+ }
+ else // Set
+ {
+ err = MBTK_RIL_ERR_UNSUPPORTED;
+ LOG("Unsupport set sim state.");
+ }
+ break;
+ }
+ case RIL_MSG_ID_SIM_TYPE:
+ {
+ if(pack->data_len == 0 || pack->data == NULL)
+ {
+ uint8 sim_card_type;
+ if(req_sim_type_get(&sim_card_type, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Get IMSI fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &sim_card_type, sizeof(uint8));
+ }
+ }
+ else // Set
+ {
+ err = MBTK_RIL_ERR_UNSUPPORTED;
+ LOG("Unsupport set sim type.");
+ }
+ break;
+ }
+ case RIL_MSG_ID_SIM_IMSI:
+ {
+ if(pack->data_len == 0 || pack->data == NULL)
+ {
+ char imsi[20] = {0};
+ if(req_imsi_get(imsi, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Get IMSI fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, imsi, strlen(imsi));
+ }
+ }
+ else // Set
+ {
+ err = MBTK_RIL_ERR_UNSUPPORTED;
+ LOG("Unsupport set IMSI.");
+ }
+ break;
+ }
+ case RIL_MSG_ID_SIM_PN:
+ {
+ if(pack->data_len == 0 || pack->data == NULL)
+ {
+ char pn[50] = {0};
+ if(req_phone_number_get(pn, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Get PN fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, pn, strlen(pn));
+ }
+ }
+ else // Set
+ {
+ err = MBTK_RIL_ERR_UNSUPPORTED;
+ LOG("Unsupport set PN.");
+ }
+ break;
+ }
+ case RIL_MSG_ID_SIM_ICCID:
+ {
+ if(pack->data_len == 0 || pack->data == NULL)
+ {
+ char iccid[50] = {0};
+ if(req_iccid_get(iccid, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Get ICCID fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, iccid, strlen(iccid));
+ }
+ }
+ else // Set
+ {
+ err = MBTK_RIL_ERR_UNSUPPORTED;
+ LOG("Unsupport set ICCID.");
+ }
+ break;
+ }
+ case RIL_MSG_ID_SIM_LOCK:
+ {
+ if(pack->data_len == 0 || pack->data == NULL)
+ {
+ int state;
+ if(req_sim_lock_state_get(&state, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Get sim lock state fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &state, sizeof(uint8));
+ }
+ }
+ else // Set
+ {
+ mbtk_sim_lock_info_t *lock_info = (mbtk_sim_lock_info_t*)pack->data;
+ if(req_sim_lock_set(lock_info, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Set sim lock fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+ }
+ }
+ break;
+ }
+ case RIL_MSG_ID_SIM_PINPUK_TIMES:
+ {
+ if(pack->data_len == 0 || pack->data == NULL)
+ {
+ mbtk_pin_puk_last_times_t last_times;
+ if(req_pin_puk_last_times_get(&last_times, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Get PIN/PUK Last times fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &last_times, sizeof(mbtk_pin_puk_last_times_t));
+ }
+ }
+ else // Set
+ {
+ err = MBTK_RIL_ERR_UNSUPPORTED;
+ LOG("Unsupport set PIN/PUK Last times.");
+ }
+ break;
+ }
+ case RIL_MSG_ID_SIM_PLMN:
+ {
+ if(pack->data_len == 0 || pack->data == NULL)
+ {
+ mbtk_plmn_info info;
+ memset(&info, 0, sizeof(mbtk_plmn_info));
+ if(req_plmn_get(&info, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Get PLMN list fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &info, sizeof(mbtk_plmn_info));
+ }
+ }
+ else // Set
+ {
+ err = MBTK_RIL_ERR_UNSUPPORTED;
+ LOG("Unsupport set PLMN list.");
+ }
+ break;
+ }
+ default:
+ {
+ err = MBTK_RIL_ERR_REQ_UNKNOWN;
+ LOG("Unknown request : %s", id2str(pack->msg_id));
+ break;
+ }
+ }
+
+ return err;
+}
+
diff --git a/mbtk/mbtk_rild_v2/src/ril_sms.c b/mbtk/mbtk_rild_v2/src/ril_sms.c
new file mode 100755
index 0000000..081ad01
--- /dev/null
+++ b/mbtk/mbtk_rild_v2/src/ril_sms.c
@@ -0,0 +1,1203 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <pthread.h>
+#include <sys/epoll.h>
+#include <fcntl.h>
+#include <signal.h>
+
+#include "mbtk_type.h"
+#include "mbtk_ril.h"
+#include "atchannel.h"
+#include "at_tok.h"
+#include "mbtk_utils.h"
+#include "ril_info.h"
+
+void ril_rsp_pack_send(int fd, int ril_id, int msg_index, const void* data, int data_len);
+
+/*
+AT+CMGF?
++CMGF: 0
+
+OK
+
+*/
+static int req_cmgf_get(int *state, int *cme_err)
+{
+ ATResponse *response = NULL;
+ char *tmp_ptr = NULL;
+ int err = at_send_command_singleline("AT+CMGF?", "", &response);
+
+ if (err < 0 || response->success == 0 || !response->p_intermediates){
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+
+ char *line = response->p_intermediates->line;
+ printf("req_cmgf_get() ---line:%s\n", line);
+ char* ptr = strstr(line, "+CMGF: ");
+ printf("req_cmgf_get() ---ptr:%s\n",ptr);
+ if(ptr)
+ {
+ *state = atoi(ptr + strlen("+CMGF: "));
+ }
+ else
+ {
+ err = -1;
+ }
+exit:
+ at_response_free(response);
+ return err;
+}
+
+/*
+AT+CMGF=0"
+or
+AT+CMGF=1"
+
+OK
+*/
+static int req_cmgf_set(int state, int *cme_err)
+{
+ printf("req_cmgf_set()-------------start\n");
+ printf("state:%d\n",state);
+ ATResponse *response = NULL;
+ char cmd[30] = {0};
+ if(state)
+ {
+ strcpy(cmd, "AT+CMGF=1");
+ }
+ else
+ {
+ strcpy(cmd, "AT+CMGF=0");
+ }
+
+ printf("req_cmgf_set()----cmd:%s\n", cmd);
+ int err = at_send_command(cmd, &response);
+
+ if (err < 0 || response->success == 0) {
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+
+ err = 0;
+exit:
+ at_response_free(response);
+ return err;
+}
+
+/*set AT+CNMI=1,2*/
+static int req_cnmi_set(int *cme_err)
+{
+ printf("req_cnmi_set()-------------start3\n");
+ ATResponse *response = NULL;
+ char cmd[30] = {0};
+
+ strcpy(cmd, "AT+CNMI=1,2");
+
+ printf("req_cnmi_set()----cmd:%s\n", cmd);
+ int err = at_send_command(cmd, &response);
+
+ if (err < 0 || response->success == 0) {
+ printf("err:%d, response->success:%d \n", err, response->success);
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+
+ err = 0;
+exit:
+ at_response_free(response);
+ printf("exit,err:%d\n", err);
+ return err;
+}
+
+/*
+AT+CPMS?
+
++CPMS: "SM",15,50,"SM",15,50,"SM",15,50
+
+OK
+
+*/
+static int req_cpms_get(char *reg, int *cme_err)
+{
+ printf("req_cpms_get------------start(3)\n");
+ ATResponse *response = NULL;
+ char *tmp_ptr = NULL;
+ int err = at_send_command_singleline("AT+CPMS?", "", &response);
+
+ if (err < 0 || response->success == 0 || !response->p_intermediates){
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+
+ ATLine* lines_ptr = response->p_intermediates;
+ char *line = NULL;
+ int len = 0;
+ while(lines_ptr)
+ {
+ line = lines_ptr->line;
+ if(line ==NULL)
+ {
+ printf("line is null----------------------\n");
+ }
+
+ printf("-----------line:%s, strlen:%d, len:%d----------\n", line, strlen(line), len);
+ memcpy(reg+len, line, strlen(line));
+ len += strlen(line);
+ lines_ptr = lines_ptr->p_next;
+ }
+
+ printf("cpms_get()------reg:%s\n", reg);
+
+exit:
+ at_response_free(response);
+ return err;
+}
+
+
+
+/*
+AT+CPMS=<mem1>[,<mem2>[,<mem3>]]
+AT+CPMS="ME","ME","ME"
+
++CPMS: 14,50,14,50,14,50
+
+OK
+
+*/
+static int req_cpms_set(const char *mem, char *reg, int len, int *cme_err)
+{
+ printf("req_cpms_set(2)----------------start\n");
+ printf("mem:%s\n", mem);
+ ATResponse *response = NULL;
+ char cmd[30] = {0};
+ int err = 0;
+ char data[20] = {0};
+
+ if(mem != NULL)
+ {
+ memcpy(data, mem, len);
+ sprintf(cmd, "AT+CPMS=%s", data);
+ }
+ else{
+ printf("mem is null\n");
+ }
+
+ printf("cmd:%s,data:%s---------\n", cmd,data);
+
+ if(strlen(cmd) > 8)
+ {
+ err = at_send_command_multiline(cmd, "+CPMS:", &response);
+ if (err < 0 || response->success == 0){
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+
+ char *line = response->p_intermediates->line;
+ printf("line:%s, len:%d\n", line, strlen(line));
+
+ memcpy(reg, line, strlen(line));
+
+ printf("cpms_reg:%s\n", reg);
+ }
+ err = 0;
+exit:
+ printf("goto exit do");
+ at_response_free(response);
+ return err;
+}
+
+/*
+if PDU mode (+CMGF=0):
+ AT+CMGS=<length><CR>
+PDU is given<ctrl-Z/ESC>
+if text mode (+CMGF=1):
+ AT+CMGS=<da>[,<toda>]<CR>
+text is entered<ctrl-Z/ESC>
+
+ AT+CMGS=15775690697,hello world
+
+
+*/
+static int req_cmgs_set(char *cmgs, char *reg, int len, int *cme_err)
+{
+ printf("req_cmgs_set()----------------start\n");
+ printf("cmgs:%s\n", cmgs);
+ ATResponse *response = NULL;
+ char cmd[30] = {0};
+ char data[218] = {0};
+ char pnum[20] = {0};
+ char *ptr = cmgs;
+ int err = 0;
+ int data_len = 0;
+
+ char *src = strstr(cmgs, ",");
+ if(src != NULL)
+ {
+ //LOG("[XIAORUI]req_cmgs_set()----------------src=%s",src);
+ //LOG("[XIAORUI]req_cmgs_set()----------------ptr=%s",ptr);
+ memcpy(pnum, ptr, src - ptr);
+ //LOG("[XIAORUI]req_cmgs_set()----------------pnum=%s",pnum);
+ src++;
+ int data_len = 0;
+ data_len = len - (src - ptr);
+ memcpy(data, src, data_len);
+ //LOG("[XIAORUI]req_cmgs_set()----------------data %s",data);
+ }
+
+ sprintf(cmd, "AT+CMGS=%s", pnum);
+ LOG("cmd:%s,data:%s---------", cmd,data);
+
+ if(strlen(cmd) > 0)
+ {
+ int err = at_send_command_sms(cmd, data, "+CMGS: ", &response);
+ printf("err:%d, response:%d\n", err, response->success);
+
+ if (err < 0 || response->success == 0) {
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+ char *line;
+ line = response->p_intermediates->line;
+ memcpy(reg, line, strlen(line));
+ printf("line:%s\n", line);
+
+ }
+ err = 0;
+exit:
+ at_response_free(response);
+ return err;
+}
+
+static int req_cmgw_set(char *cmgw,int len, int *cme_err)
+{
+ printf("req_cmgw_set()----------------start\n");
+ printf("cmgw:%s\n", cmgw);
+ ATResponse *response = NULL;
+ char cmd[30] = {0};
+ char data[218] = {0};
+ char pnum[13] = {0};
+ char *ptr = cmgw;
+ int err = 0;
+
+ char *src = strstr(cmgw, ",");
+ if(src != NULL)
+ {
+ memcpy(pnum, ptr, src - ptr);
+ src++;
+ int data_len = 0;
+ data_len = len - (src - ptr);
+ memcpy(data, src, data_len);
+ }
+
+ sprintf(cmd, "AT+CMGW=%s", pnum);
+ printf("cmd:%s,data:%s---------\n", cmd,data);
+
+ if(strlen(cmd) > 0)
+ {
+ int err = at_send_command_sms(cmd, data, "+CMGW: ", &response);
+ printf("err:%d, response:%d\n", err, response->success);
+
+ if (err < 0 || response->success == 0) {
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+ char *line;
+ line = response->p_intermediates->line;
+ printf("line:%s\n", line);
+ }
+ err = 0;
+exit:
+ at_response_free(response);
+ return err;
+}
+
+/*
+AT+CMGD=25
+OK
+
++MMSG: 1, 0
+*/
+static int req_cmgd_set(char *cmgd, int len, int *cme_err)
+{
+ printf("0req_cmgd_set()--------------start\n");
+ printf("cmgd:%s\n", cmgd);
+ ATResponse *response = NULL;
+ char cmd[30] = {0};
+ char data[218] = {0};
+ char pnum[13] = {0};
+ char *ptr = cmgd;
+ int err = 0;
+
+ memcpy(data, cmgd, len );
+ sprintf(cmd, "AT+CMGD=%s", data);
+ printf("cmd:%s,data:%s---------\n", cmd,data);
+
+ if(strlen(cmd) > 0)
+ {
+ int err = at_send_command(cmd, &response);
+ if (err < 0 || response->success == 0) {
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+
+// Format problem caused the crash
+// char *line;
+// line = response->p_intermediates->line;
+// printf("line:%s\n", line);
+ }
+ err = 0;
+exit:
+ at_response_free(response);
+ return err;
+}
+
+/*
+AT+CMGD=?
+
++CMGD: (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37),(0-4)
+
+OK
+
+*/
+static int req_cmgd_get(char *reg, int *cme_err)
+{
+ ATResponse *response = NULL;
+ char *tmp_ptr = NULL;
+ int err = at_send_command_singleline("AT+CMGD=?", "+CMGD:", &response);
+
+ if (err < 0 || response->success == 0 || !response->p_intermediates){
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+
+ char *line = response->p_intermediates->line;
+
+ const char* start = strchr(line, '(');
+ const char* end = strchr(line, ')');
+
+ if (start && end && end > start)
+ {
+ int len_t = end - start - 1;
+ char substr_t[len_t + 1];
+
+ strncpy(substr_t, start + 1, len_t);
+ substr_t[len_t] = '\0';
+ strncpy(reg, substr_t, len_t);
+ }
+ else
+ {
+ strcpy(reg, "");
+ }
+
+exit:
+ at_response_free(response);
+ return err;
+}
+
+
+/*
+AT+CMGL="ALL"
+
++CMGL: 1,"REC READ","10658678",,"22.11.14 10:41:44 GMT+8"
+
+56DB5DDD62
+
++CMGL: 2,"STO UNSENT","18927467953"
+hello world
+
+*/
+
+static int req_cmgl_set(const char *cmgl, char *reg, int len, int *cme_err)
+{
+ printf("req_cmgl_set(2)-----------------start\n");
+ printf("cmgl:%s\n", cmgl);
+ ATResponse *response = NULL;
+ char cmd[30] = {0};
+ char data[218] = {0};
+ char index_data[256] = {0};
+ int s_index = 0, g_index = 0;
+ bool index_flag = false;
+ char *ptr_index = index_data;
+ char phone[50];
+ char number[5] = {0};
+ int err = 0;
+
+ memcpy(data, cmgl, len);
+
+ char *ptr1 = data;
+ char *ptr2 = strstr(data, ",");
+ if(ptr2 != NULL)
+ {
+ memcpy(number,ptr1, ptr2-ptr1 );
+ s_index = atoi(number);
+ if(s_index == 0)
+ {
+ index_flag = TRUE;
+ memcpy(ptr_index, "+CMGL:", strlen("+CMGL:"));
+ }
+ memset(number, 0, sizeof(number));
+ ptr2++;
+ }else{
+ printf("cmgl set data is error\n eg:index,data\n");
+ return -1;
+ }
+
+ sprintf(cmd, "AT+CMGL=%s", ptr2);
+ printf("cmd:%s\n", cmd);
+
+ ptr1 = NULL;
+ ptr2 = NULL;
+
+ if(strlen(cmd) > 0)
+ {
+ err = at_send_command_multiline(cmd, "", &response);
+ if (err < 0 || response->success == 0 || !response->p_intermediates){
+ *cme_err = at_get_cme_error(response);
+ printf("at_send_command_multiline() is err-----------------\n");
+ goto exit;
+ }
+
+ ATLine* lines_ptr = response->p_intermediates;
+ char *line = NULL;
+ int reg_len = 0;
+ bool flag = false;
+ while(lines_ptr)
+ {
+ line = lines_ptr->line;
+ if(line ==NULL)
+ {
+ printf("line is null----------------------\n");
+ }
+
+ printf("-----line:%s\n", line);
+ if(!flag)
+ {
+ ptr1 = strstr(line, "+CMGL: ");
+ if(ptr1 != NULL)
+ {
+ ptr1 += 7;
+ ptr2 = strstr(line, ",");
+ memcpy(number,ptr1, ptr2-ptr1 );
+ printf("number:%s, ptr1:%s, ptr2:%s\n", number, ptr1, ptr2);
+ g_index = atoi(number);
+ if(index_flag)
+ {
+ sprintf(ptr_index+strlen(ptr_index), "%d,", g_index);
+ }
+ }
+ //if( g_index == s_index)
+ if( g_index == s_index && !index_flag)
+ {
+ printf("g_index == s_index, g_index:%d,s_index:%d\n", g_index, s_index);
+ flag = true;
+ }
+ }
+ if(flag && reg_len <=1024)
+ {
+ memcpy(reg+reg_len, line, strlen(line));
+ printf("-----memcpy------reg:%s----------\n", reg);
+ printf("len:%d\n", reg_len);
+ reg_len += strlen(line);
+ }
+
+ lines_ptr = lines_ptr->p_next;
+ }
+ }
+
+ if(index_flag)
+ {
+ memset(reg, 0, sizeof(reg));
+ memcpy(reg, ptr_index, strlen(ptr_index) );
+ }
+ err = 0;
+exit:
+ at_response_free(response);
+ printf("req_cmgl_set()-----------------end\n");
+ return err;
+}
+
+/*
+at+csca?
++CSCA: "+8613800280500",145
+OK
+*/
+static int req_csca_get(char *req, int *cme_err)
+{
+ ATResponse *response = NULL;
+ char *tmp_ptr = NULL;
+ int err = at_send_command_singleline("AT+CSCA?", "", &response);
+
+ if (err < 0 || response->success == 0 || !response->p_intermediates){
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+
+ char *line = response->p_intermediates->line;
+ printf("req_csca_get() ---line:%s\n", line);
+ char* ptr = strstr(line, "+CSCA: ");
+ printf("req_csca_get() ---ptr:%s\n",ptr);
+ if(ptr)
+ {
+ memcpy(req, line, strlen(line));
+ printf("err:%d, req:%s\n", err, req);
+ err = 0;
+ }
+ else
+ {
+ err = -1;
+ }
+
+exit:
+ at_response_free(response);
+ return err;
+}
+
+static int req_csca_set(char *csca, int len, int *cme_err)
+{
+ printf("req_csca_set()--------------start\n");
+ printf("csca:%s\n", csca);
+ ATResponse *response = NULL;
+ char cmd[30] = {0};
+ char data[218] = {0};
+ char pnum[13] = {0};
+ char *ptr = csca;
+ int err = 0;
+
+ memcpy(data, csca, len);
+ sprintf(cmd, "AT+CSCA=%s", data);
+ printf("cmd:%s,data:%s---------\n", cmd,data);
+
+ if(strlen(cmd) > 0)
+ {
+ int err = at_send_command(cmd, &response);
+ if (err < 0 || response->success == 0) {
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+
+ // char *line;
+ // line = response->p_intermediates->line;
+ // printf("line:%s\n", line);
+ }
+ err = 0;
+exit:
+ at_response_free(response);
+ return err;
+}
+
+static int req_csmp_set(char *csmp, int len, int *cme_err)
+{
+ printf("req_csmp_set()-------------------start\n");
+ printf("csmp:%s\n", csmp);
+ ATResponse *response = NULL;
+ char cmd[30] = {0};
+ char data[218] = {0};
+ char pnum[13] = {0};
+ char *ptr = csmp;
+ int err = 0;
+
+ memcpy(data, csmp, len);
+ sprintf(cmd, "AT+CSMP=%s", data);
+ printf("cmd:%s,data:%s---------\n", cmd,data);
+
+ if(strlen(cmd) > 0)
+ {
+ int err = at_send_command(cmd, &response);
+ if (err < 0 || response->success == 0) {
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+
+ char *line;
+ line = response->p_intermediates->line;
+ printf("line:%s\n", line);
+ }
+ err = 0;
+exit:
+ at_response_free(response);
+ return err;
+}
+
+static int req_cscb_set(char *cscb,int len, int *cme_err)
+{
+ printf("req_cscb_set()----------------start\n");
+ printf("cscb:%s\n", cscb);
+ ATResponse *response = NULL;
+ char cmd[30] = {0};
+ char data[218] = {0};
+ char pnum[13] = {0};
+ char *ptr = cscb;
+ int err = 0;
+
+ memcpy(data, cscb, len);
+ sprintf(cmd, "AT+CSCB=%s", cscb);
+ printf("cmd:%s,data:%s---------\n", cmd,data);
+
+ if(strlen(cmd) > 0)
+ {
+ int err = at_send_command(cmd, &response);
+ if (err < 0 || response->success == 0) {
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+
+ char *line;
+ line = response->p_intermediates->line;
+ printf("line:%s\n", line);
+ }
+ err = 0;
+exit:
+ at_response_free(response);
+ return err;
+}
+
+/*
+AT+CMSS=13
++CMSS: 81
+OK
+*/
+static int req_cmss_set(const char *cmss, char *reg, int len, int *cme_err)
+{
+ printf("req_cmss_set()----------------start\n");
+ printf("cmss:%s\n", cmss);
+ ATResponse *response = NULL;
+ char cmd[30] = {0};
+ char data[20] = {0};
+ int err = 0;
+
+ if(cmss != NULL)
+ {
+ memcpy(data, cmss, len);
+ sprintf(cmd, "AT+CMSS=%s", data);
+ // sprintf(cmd, "AT+CMSS=%d", 8);
+ }
+ else{
+ printf("mem is null\n");
+ }
+
+ printf("cmss. cmd:%s\n", cmd);
+
+ if(strlen(cmd) > 8)
+ {
+ err = at_send_command_multiline(cmd, "+CMSS:", &response);
+ if (err < 0 || response->success == 0){
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+
+ char *line = response->p_intermediates->line;
+ printf("line:%s\n", line);
+
+ char *tmp_str = NULL;
+ err = at_tok_nextstr(&line, &tmp_str); // phone_number
+ if (err < 0)
+ {
+ goto exit;
+ }
+ memcpy(reg, tmp_str, strlen(tmp_str));
+ printf("cmss_reg:%s\n", reg);
+ /*
+ int err = at_send_command(cmd, &response);
+
+ if (err < 0 || response->success == 0) {
+ *cme_err = at_get_cme_error(response);
+ goto exit;
+ }
+
+ char *line;
+ line = response->p_intermediates->line;
+ printf("line:%s\n", line);
+ */
+ }
+ err = 0;
+exit:
+ at_response_free(response);
+ return err;
+}
+
+
+/*
+AT+CMGR=1
++CMGR: "REC READ","10658678",,"22.11.14 10:41:44 GMT+8"
+
+56DB5DDD624B673A62A5FF039003003400310034003500340035003F0073003D0037003800680061006C00450066
+
+OK
+*/
+static int req_cmgr_set(int index, char *reg, int *cme_err)
+{
+ printf("0req_cmgr_set()-------------------start\n");
+ printf("index:%d\n", index);
+ ATResponse *response = NULL;
+ char cmd[30] = {0};
+ int err = 0;
+ sprintf(cmd, "AT+CMGR=%d", index);
+
+ printf("req_cmgr_set()----cmd:%s\n", cmd);
+
+ if(strlen(cmd) > 0)
+ {
+ err = at_send_command_multiline(cmd, "", &response);
+ if (err < 0 || response->success == 0 || !response->p_intermediates){
+ *cme_err = at_get_cme_error(response);
+ printf("at_send_command_multiline() is err-----------------\n");
+ goto exit;
+ }
+
+ ATLine* lines_ptr = response->p_intermediates;
+ char *line = NULL;
+ int reg_len = 0;
+ while(lines_ptr)
+ {
+ line = lines_ptr->line;
+ if(line ==NULL)
+ {
+ printf("line is null----------------------\n");
+ }
+
+ if(reg_len > 0)
+ {
+ memcpy(reg+reg_len, "\r\n", strlen("\r\n"));
+ reg_len += strlen("\r\n");
+ }
+ memcpy(reg+reg_len, line, strlen(line));
+ printf("-----memcpy------reg:%s----------\n", reg);
+ printf("len:%d\n", reg_len);
+ reg_len += strlen(line);
+ lines_ptr = lines_ptr->p_next;
+ }
+ }
+
+ err = 0;
+exit:
+ at_response_free(response);
+ return err;
+}
+
+
+//void net_list_free(void *data);
+// Return MBTK_INFO_ERR_SUCCESS,will call pack_error_send() to send RSP.
+// Otherwise, do not call pack_error_send().
+mbtk_ril_err_enum sms_pack_req_process(sock_cli_info_t* cli_info, ril_msg_pack_info_t* pack)
+{
+ mbtk_ril_err_enum err = MBTK_RIL_ERR_SUCCESS;
+ int cme_err = MBTK_RIL_ERR_CME_NON;
+ switch(pack->msg_id)
+ {
+ case RIL_MSG_ID_SMS_CMGF:
+ {
+ if(pack->data_len == 0 || pack->data == NULL) // Get VoLTE state.
+ {
+ int state;
+ if(req_cmgf_get(&state, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Get SMS CMGF fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &state, sizeof(uint8));
+ }
+ }
+ else // Set VoLTE state.
+ {
+ uint8 mode = *(pack->data);
+ if(pack->data_len != sizeof(uint8) || (mode != 0 && mode != 1))
+ {
+ err = MBTK_RIL_ERR_REQ_PARAMETER;
+ LOG("Set SMS CMGF parameter error.");
+ break;
+ }
+
+ if(req_cmgf_set(mode, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Set SMS CMGF fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+ }
+ }
+ break;
+ }
+ case RIL_MSG_ID_SMS_CNMI:
+ {
+ if(pack->data_len == 0 || pack->data == NULL) // SET at+cnmi=1,2.
+ {
+ int state;
+ if(req_cnmi_set(&cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("set sms cnmi fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+ }
+ }
+ break;
+ }
+ case RIL_MSG_ID_SMS_CPMS:
+ {
+ if(pack->data_len == 0 || pack->data == NULL) // Get VoLTE state.
+ {
+ char reg[100] = {0};
+ if(req_cpms_get(reg, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Get SMS CMGF fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, reg, strlen(reg));
+ }
+ }
+ else // Set VoLTE state.
+ {
+ char *mem = (char*)(pack->data);
+ int len = pack->data_len;
+ char reg[100] = {0};
+ LOGD("mem:%s, len:%d", pack->data, pack->data_len);
+
+ if(req_cpms_set(mem, reg, len, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Set SMS CMGF fail.");
+ }
+ else
+ {
+ LOGD("cpms_set success, reg:%s", reg);
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, reg, strlen(reg));
+ }
+ }
+ break;
+ }
+ case RIL_MSG_ID_SMS_CMGS:
+ {
+ if(pack->data_len == 0 || pack->data == NULL) // Get VoLTE state.
+ {
+ err = MBTK_RIL_ERR_UNSUPPORTED;
+ }
+ else // Set VoLTE state.
+ {
+ char *cmgs = (char*)pack->data;
+ int len = pack->data_len;
+ char reg[50] ={0};
+ LOGD("mbtk_sms,cmgs:%s,len:%d", cmgs, len);
+
+ if(req_cmgs_set(cmgs,reg,len, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Set SMS CMGF fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, reg, strlen(reg));
+ }
+ }
+ break;
+ }
+ case RIL_MSG_ID_SMS_CMSS:
+ {
+ if(pack->data_len == 0 || pack->data == NULL) // Get VoLTE state.
+ {
+ err = MBTK_RIL_ERR_UNSUPPORTED;
+ }
+ else // Set VoLTE state.
+ {
+ char *cmss = (char*)pack->data;
+ int len = pack->data_len;
+ char reg[128] = {0};
+ LOGD("mbtk_sms,cmgs:%s, len:%d", cmss, len);
+
+ if(req_cmss_set(cmss,reg, len, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Set SMS CMGF fail.");
+ }
+ else
+ {
+ LOGD("req_cmss_set success, reg:%s", reg);
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+ }
+ }
+ break;
+ }
+ case RIL_MSG_ID_SMS_CMGR:
+ {
+ if(pack->data_len == 0 || pack->data == NULL) // Get VoLTE state.
+ {
+ err = MBTK_RIL_ERR_UNSUPPORTED;
+ }
+ else // Set VoLTE state.
+ {
+ uint8 index = *(pack->data);
+ char reg[1024] = {0};
+ if(pack->data_len != sizeof(uint8) )
+ {
+ err = MBTK_RIL_ERR_REQ_PARAMETER;
+ LOG("Set SMS CMGF parameter error.");
+ break;
+ }
+
+ if(req_cmgr_set(index, reg, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Set SMS CMGF fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, reg, strlen(reg));
+ }
+ }
+ break;
+ }
+ case RIL_MSG_ID_SMS_CMGW:
+ {
+ if(pack->data_len == 0 || pack->data == NULL) // +CMGW=<oa/da>[,<tooa/toda>[,<stat>]]<CR>
+ {
+ err = MBTK_RIL_ERR_UNSUPPORTED;
+ }
+ else // Set cmgw data.
+ {
+ char *cmgw = (char*)pack->data;
+ int len = pack->data_len;
+ LOGD("mbtk_sms,cmgw:%s,len:%d", cmgw, len);
+
+ if(req_cmgw_set(cmgw, len, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Set SMS CMGF fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+ }
+ }
+ break;
+ }
+ case RIL_MSG_ID_SMS_CMGD:
+ {
+ if(pack->data_len == 0 || pack->data == NULL) // Get VoLTE state.
+ {
+ char reg[1024] = {0};
+ if(req_cmgd_get(reg, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Get SMS CMGD fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, reg, strlen(reg));
+ }
+ }
+ else // Set VoLTE state.
+ {
+ char *cmgd = (char*)pack->data;
+ int len = pack->data_len;
+ LOGD("mbtk_sms,cmgs:%s,len:%d", cmgd, len);
+
+ if(req_cmgd_set(cmgd,len, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Set SMS CMGF fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+ }
+
+ }
+ break;
+ }
+ case RIL_MSG_ID_SMS_CMGL:
+ {
+ if(pack->data_len == 0 || pack->data == NULL) // Get VoLTE state.
+ {
+ err = MBTK_RIL_ERR_UNSUPPORTED;
+ }
+ else // Set VoLTE state.
+ {
+ char *cmgl = (char*)pack->data;
+ int len = pack->data_len;
+ char reg[5*1024] = {0};
+ char reg1[1024+1] = {0};
+
+ if(req_cmgl_set(cmgl, reg, len, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Set SMS CMGF fail.");
+ }
+ else
+ {
+ memcpy(reg1, reg, 1024);
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, reg1, strlen(reg1));
+ }
+ }
+ break;
+ }
+ case RIL_MSG_ID_SMS_CSCA:
+ {
+ if(pack->data_len == 0 || pack->data == NULL) // Get VoLTE state.
+ {
+ char csca[50]={0};
+ if(req_csca_get(csca, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Get SMS CSCA fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, csca, strlen(csca));
+ }
+ err = MBTK_RIL_ERR_UNSUPPORTED;
+ }
+ else // Set VoLTE state.
+ {
+ char *csca = (char*)pack->data;
+ int len = pack->data_len;
+
+ if(req_csca_set(csca, len, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Set SMS CMGF fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+ }
+ }
+ break;
+ }
+ case RIL_MSG_ID_SMS_CSMP:
+ {
+ if(pack->data_len == 0 || pack->data == NULL) // Get VoLTE state.
+ {
+ err = MBTK_RIL_ERR_UNSUPPORTED;
+ }
+ else // Set VoLTE state.
+ {
+ char *csmp = (char*)pack->data;
+ int len = pack->data_len;
+
+ if(req_csmp_set(csmp,len, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Set SMS CMGF fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+ }
+ }
+ break;
+ }
+ case RIL_MSG_ID_SMS_CSCB:
+ {
+ if(pack->data_len == 0 || pack->data == NULL) // Get VoLTE state.
+ {
+ err = MBTK_RIL_ERR_UNSUPPORTED;
+ }
+ else // Set VoLTE state.
+ {
+ char *cscb = (char*)pack->data;
+ int len = pack->data_len;
+
+ if(req_cscb_set(cscb,len, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+ {
+ if(cme_err != MBTK_RIL_ERR_CME_NON) {
+ err = MBTK_RIL_ERR_CME + cme_err;
+ } else {
+ err = MBTK_RIL_ERR_UNKNOWN;
+ }
+ LOG("Set SMS CMGF fail.");
+ }
+ else
+ {
+ ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+ }
+ }
+ break;
+ }
+ default:
+ {
+ err = MBTK_RIL_ERR_REQ_UNKNOWN;
+ LOG("Unknown request : %s", id2str(pack->msg_id));
+ break;
+ }
+ }
+
+ return err;
+}
+
+
+
+
+