blob: c1a20c88a1812445e0420de13ca3c553514f3cdf [file] [log] [blame]
#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"
#define RIL_CALL_NUM_MAX 10
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;
static mbtk_ril_call_state_info_t call_list[RIL_CALL_NUM_MAX];
extern mbtk_cell_pack_info_t cell_info;
extern ril_cgact_wait_t cgact_wait;
// 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 data_call_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);
mbtk_ril_err_enum ecall_pack_req_process(sock_cli_info_t* cli_info, ril_msg_pack_info_t* pack);
void data_call_state_change_cb(int cid, bool action, bool auto_change, int reason);
static int send_pack_to_queue(sock_cli_info_t* cli_info, void* 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 ril_state_change(ril_msg_id_enum msg_id, void *data, int data_len)
{
sock_cli_info_t *cli = NULL;
list_first(ril_info.sock_client_list);
while ((cli = (sock_cli_info_t*) list_next(ril_info.sock_client_list)))
{
if(cli->ind_num > 0) {
int i;
for(i = 0; i < IND_REGISTER_MAX; i++) {
if(cli->ind_register[i] == msg_id) {
ril_ind_pack_send(cli->fd, msg_id, data, data_len);
break;
}
}
}
}
}
static int urc_msg_distribute(bool async_process, ril_msg_id_enum msg_id, const void *data, int data_len)
{
// Send urc msg to client.
if(msg_id > RIL_MSG_ID_IND_BEGIN && msg_id < RIL_MSG_ID_IND_END) {
ril_state_change(msg_id, data, data_len);
}
// Async process urc msg.
if(async_process) {
ril_urc_msg_info_t *msg = (ril_urc_msg_info_t*)malloc(sizeof(ril_urc_msg_info_t));
if(msg) {
msg->msg = msg_id;
msg->data = mbtk_memcpy(data, data_len);
msg->data_len = data_len;
if(msg->data == NULL) {
LOGE("mbtk_memcpy() fail.");
return -1;
}
return send_pack_to_queue(NULL, msg);
} else {
LOGE("malloc() fail.");
return -1;
}
}
return 0;
}
// *SIMDETEC:1,SIM
// *EUICC:1
// +CPIN: SIM PIN
static void urc_sim_state_change_process(const char *s, const char *sms_pdu)
{
mbtk_ril_sim_state_info_t state;
memset(&state, 0, sizeof(mbtk_ril_sim_state_info_t));
state.sim_type = MBTK_UNKNOWN;
char* tmp_s = memdup(s,strlen(s));
char *line = tmp_s;
int tmp_int;
char *tmp_str;
if(strStartsWith(s, "*SIMDETEC:")) {
if (at_tok_start(&line) < 0)
{
goto SIM_STATE_EXIT;
}
if (at_tok_nextint(&line, &tmp_int) < 0)
{
goto SIM_STATE_EXIT;
}
if (at_tok_nextstr(&line, &tmp_str) < 0)
{
goto SIM_STATE_EXIT;
}
if(tmp_str) {
if(strcmp(tmp_str, "NOS") == 0) {
state.sim_type = ril_info.sim_type;
state.sim_state = MBTK_SIM_STATE_ABSENT;
ril_info.sim_state = MBTK_SIM_STATE_ABSENT;
urc_msg_distribute(false, RIL_MSG_ID_IND_SIM_STATE_CHANGE, &state, sizeof(mbtk_ril_sim_state_info_t));
} else if(strcmp(tmp_str, "SIM") == 0) {
state.sim_type = ril_info.sim_type;
state.sim_state = MBTK_SIM_STATE_NOT_READY;
ril_info.sim_state = MBTK_SIM_STATE_NOT_READY;
urc_msg_distribute(false, RIL_MSG_ID_IND_SIM_STATE_CHANGE, &state, sizeof(mbtk_ril_sim_state_info_t));
}
}
} else if(strStartsWith(s, "+CPIN:")){
if(strStartsWith(s, "+CPIN: READY"))
{
state.sim_state = MBTK_SIM_STATE_READY;
}
else if(strStartsWith(s, "+CPIN: SIM PIN"))
{
state.sim_state = MBTK_SIM_STATE_SIM_PIN;
}
else if(strStartsWith(s, "+CPIN: SIM PUK"))
{
state.sim_state = MBTK_SIM_STATE_SIM_PUK;
}
else if(strStartsWith(s, "+CPIN: PH-SIMLOCK PIN"))
{
state.sim_state = MBTK_SIM_STATE_PH_SIMLOCK_PIN;
}
else if(strStartsWith(s, "+CPIN: PH-SIMLOCK PUK"))
{
state.sim_state = MBTK_SIM_STATE_PH_SIMLOCK_PUK;
}
else if(strStartsWith(s, "+CPIN: PH-FSIM PIN"))
{
state.sim_state = MBTK_SIM_STATE_PH_FSIM_PIN;
}
else if(strStartsWith(s, "+CPIN: PH-FSIM PUK"))
{
state.sim_state = MBTK_SIM_STATE_PH_FSIM_PUK;
}
else if(strStartsWith(s, "+CPIN: SIM PIN2"))
{
state.sim_state = MBTK_SIM_STATE_SIM_PIN2;
}
else if(strStartsWith(s, "+CPIN: SIM PUK2"))
{
state.sim_state = MBTK_SIM_STATE_SIM_PUK2;
}
else if(strStartsWith(s, "+CPIN: PH-NET PIN"))
{
state.sim_state = MBTK_SIM_STATE_PH_NET_PIN;
}
else if(strStartsWith(s, "+CPIN: PH-NET PUK"))
{
state.sim_state = MBTK_SIM_STATE_PH_NET_PUK;
}
else if(strStartsWith(s, "+CPIN: PH-NETSUB PIN"))
{
state.sim_state = MBTK_SIM_STATE_PH_NETSUB_PIN;
}
else if(strStartsWith(s, "+CPIN: PH-NETSUB PUK"))
{
state.sim_state = MBTK_SIM_STATE_PH_NETSUB_PUK;
}
else if(strStartsWith(s, "+CPIN: PH-SP PIN"))
{
state.sim_state = MBTK_SIM_STATE_PH_SP_PIN;
}
else if(strStartsWith(s, "+CPIN: PH-SP PUK"))
{
state.sim_state = MBTK_SIM_STATE_PH_SP_PUK;
}
else if(strStartsWith(s, "+CPIN: PH-CORP PIN"))
{
state.sim_state = MBTK_SIM_STATE_PH_CORP_PIN;
}
else if(strStartsWith(s, "+CPIN: PH-CORP PUK"))
{
state.sim_state = MBTK_SIM_STATE_PH_CORP_PUK;
}
else if(strStartsWith(s, "+CPIN: SIM REMOVED"))
{
state.sim_state = MBTK_SIM_STATE_ABSENT;
}
state.sim_type = ril_info.sim_type;
ril_info.sim_state = state.sim_state;
urc_msg_distribute(false, RIL_MSG_ID_IND_SIM_STATE_CHANGE, &state, sizeof(mbtk_ril_sim_state_info_t));
} else if(strStartsWith(s, "*EUICC:")){
if (at_tok_start(&line) < 0)
{
goto SIM_STATE_EXIT;
}
if (at_tok_nextint(&line, &tmp_int) < 0)
{
goto SIM_STATE_EXIT;
}
ril_info.sim_type = (mbtk_sim_card_type_enum)tmp_int;
} else {
LOGW("Unknown URC.");
}
SIM_STATE_EXIT:
free(tmp_s);
}
// +CLCC: 1, 1, 6, 0, 0, "18981911691", 129, "",, 0
// +CALLDISCONNECT: 1
// +CPAS: 4
static void urc_call_state_change_process(const char *s, const char *sms_pdu)
{
char* tmp_s = memdup(s,strlen(s));
char *line = tmp_s;
int tmp_int;
char *tmp_str;
if(strStartsWith(s, "+CLCC:")) {
if (at_tok_start(&line) < 0)
{
goto CALL_STATE_EXIT;
}
if (at_tok_nextint(&line, &tmp_int) < 0) // call id
{
goto CALL_STATE_EXIT;
}
int i = 0;
while(i < RIL_CALL_NUM_MAX) {
if(call_list[i].call_id == tmp_int)
break;
i++;
}
if(i == RIL_CALL_NUM_MAX) { // No found this call id.
i = 0;
while(i < RIL_CALL_NUM_MAX) { // Find next empty call item.
if(call_list[i].call_id == 0)
break;
i++;
}
call_list[i].call_id = tmp_int;
}
LOGD("Found call id : %d", call_list[i].call_id);
if (at_tok_nextint(&line, &tmp_int) < 0) // dir
{
goto CALL_STATE_EXIT;
}
call_list[i].dir = (mbtk_ril_call_dir_enum)tmp_int;
if (at_tok_nextint(&line, &tmp_int) < 0) // state
{
goto CALL_STATE_EXIT;
}
call_list[i].state = (mbtk_ril_call_state_enum)tmp_int;
if (at_tok_nextint(&line, &tmp_int) < 0) // mode
{
goto CALL_STATE_EXIT;
}
if (at_tok_nextint(&line, &tmp_int) < 0) // mpty
{
goto CALL_STATE_EXIT;
}
if (at_tok_nextstr(&line, &tmp_str) < 0) // number
{
goto CALL_STATE_EXIT;
}
memset(call_list[i].call_number, 0, sizeof(call_list[i].call_number));
if(tmp_str && strlen(tmp_str) > 0) {
memcpy(call_list[i].call_number, tmp_str, strlen(tmp_str));
}
if (at_tok_nextint(&line, &tmp_int) < 0) // type
{
goto CALL_STATE_EXIT;
}
call_list[i].num_type = (mbtk_ril_call_num_type_enum)tmp_int;
urc_msg_distribute(false, RIL_MSG_ID_IND_CALL_STATE_CHANGE, &(call_list[i]), sizeof(mbtk_ril_call_state_info_t));
} else if(strStartsWith(s, "+CALLDISCONNECT:")){
if (at_tok_start(&line) < 0)
{
goto CALL_STATE_EXIT;
}
if (at_tok_nextint(&line, &tmp_int) < 0) // call id
{
goto CALL_STATE_EXIT;
}
int i = 0;
while(i < RIL_CALL_NUM_MAX) {
if(call_list[i].call_id == tmp_int)
break;
i++;
}
if(i == RIL_CALL_NUM_MAX) { // No found this call id.
LOGE("No found this call id : %d", tmp_int);
goto CALL_STATE_EXIT;
}
call_list[i].state = MBTK_RIL_CALL_STATE_DISCONNECT;
urc_msg_distribute(false, RIL_MSG_ID_IND_CALL_STATE_CHANGE, &(call_list[i]), sizeof(mbtk_ril_call_state_info_t));
// Reset after call disconnect.
memset(&(call_list[i]), 0, sizeof(mbtk_ril_call_state_info_t));
} else if(strStartsWith(s, "+CPAS:")){
} else {
LOGW("Unknown URC.");
}
CALL_STATE_EXIT:
free(tmp_s);
}
// *ECALLDATA: <urc_id>[,<urc_data>]
static void urc_ecall_state_change_process(const char *s, const char *sms_pdu)
{
mbtk_ril_ecall_state_info_t ecall_state;
memset(&ecall_state, 0, sizeof(mbtk_ril_ecall_state_info_t));
char* tmp_s = memdup(s,strlen(s));
char *line = tmp_s;
int tmp_int;
char *tmp_str;
if (at_tok_start(&line) < 0)
{
goto ECALLDATA_EXIT;
}
if (at_tok_nextint(&line, &tmp_int) < 0)
{
goto ECALLDATA_EXIT;
}
ecall_state.urc_id = (uint8)tmp_int; // urc_id
if (at_tok_nextstr(&line, &tmp_str) < 0)
{
goto ECALLDATA_EXIT;
}
if(tmp_str && strlen(tmp_str) > 0) {
memcpy(ecall_state.urc_data, tmp_str, strlen(tmp_str));
}
urc_msg_distribute(false, RIL_MSG_ID_IND_ECALL_STATE_CHANGE, &ecall_state, sizeof(mbtk_ril_ecall_state_info_t));
ECALLDATA_EXIT:
free(tmp_s);
}
// +CMT: ,23
// 0891683108200855F6240D91688189911196F10000221130717445230331D90C
static void urc_sms_state_change_process(const char *s, const char *sms_pdu)
{
}
// +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
static void urc_net_reg_state_change_process(const char *s, const char *sms_pdu)
{
mbtk_ril_net_reg_state_info_t state;
memset(&state, 0, sizeof(mbtk_ril_net_reg_state_info_t));
state.tech = MBTK_RADIO_TECH_UNKNOWN;
if(strStartsWith(s, "+CREG:"))
{
state.type = MBTK_NET_REG_TYPE_CALL;
} else if(strStartsWith(s, "+CGREG:")) {
state.type = MBTK_NET_REG_TYPE_DATA_GSM_WCDMA;
} else {
state.type = MBTK_NET_REG_TYPE_DATA_LTE;
}
char* tmp_s = memdup(s,strlen(s));
char *line = tmp_s;
int tmp_int;
char *tmp_str;
if (at_tok_start(&line) < 0)
{
goto CGREG_EXIT;
}
if (at_tok_nextint(&line, &tmp_int) < 0)
{
goto CGREG_EXIT;
}
state.reg_state = (mbtk_net_reg_state_enum)tmp_int; // Reg State.
if (state.reg_state) // Reg
{
if (at_tok_nextstr(&line, &tmp_str) < 0)
{
goto CGREG_EXIT;
}
if (at_tok_nextstr(&line, &tmp_str) < 0)
{
goto CGREG_EXIT;
}
if (at_tok_nextint(&line, &tmp_int) < 0)
{
goto CGREG_EXIT;
}
state.tech = (mbtk_radio_technology_enum)tmp_int; // AcT
}
urc_msg_distribute(false, RIL_MSG_ID_IND_NET_REG_STATE_CHANGE, &state, sizeof(mbtk_ril_net_reg_state_info_t));
CGREG_EXIT:
free(tmp_s);
}
static void urc_pdp_state_change_process(const char *s, const char *sms_pdu)
{
// "CONNECT"
if(strStartsWith(s, "CONNECT"))
{
#if 1
if(cgact_wait.waitting && cgact_wait.act) {
cgact_wait.waitting = false;
}
#endif
}
// +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
/*
+CGEV: NW DETACH
+CGEV: ME DETACH
+CGEV: NW CLASS <class>
+CGEV: ME CLASS <class>
+CGEV: NW PDN ACT <cid>
+CGEV: ME PDN ACT <cid>[,<reason>[,<cid_other>]]
+CGEV: NW ACT <p_cid>, <cid>, <event_type>
+CGEV: ME ACT <p_cid>, <cid>, <event_type>
+CGEV: NW DEACT <PDP_type>, <PDP_addr>, [<cid>]
+CGEV: ME DEACT <PDP_type>, <PDP_addr>, [<cid>]
+CGEV: NW PDN DEACT <cid>
+CGEV: NW DEACT <PDP_type>, <PDP_addr>, [<cid>]
+CGEV: ME PDN DEACT <cid>
+CGEV: ME DEACT <PDP_type>, <PDP_addr>, [<cid>]
+CGEV: NW DEACT <p_cid>, <cid>, <event_type>
+CGEV: NW DEACT <PDP_type>, <PDP_addr>, [<cid>]
+CGEV: ME DEACT <p_cid>, <cid>, <event_type>
+CGEV: ME DEACT <PDP_type>, <PDP_addr>, [<cid>]
+CGEV: NW MODIFY <cid>, <change_reason>, <event_type>
+CGEV: ME MODIFY <cid>, <change_reason>, <event_type>
+CGEV: REJECT <PDP_type>, <PDP_addr>
+CGEV: NW REACT <PDP_type>, <PDP_addr>, [<cid>]
*/
else if(strStartsWith(s, "+CGEV:"))
{
#if 1
// "+CGEV: ME PDN ACT ")) { // +CGEV: ME PDN ACT <cid>[,<reason>[,<cid_other>]]
// "+CGEV: NW MODIFY ")) { // +CGEV: NW MODIFY <cid>, <change_reason>, <event_type>
// "+CGEV: ME PDN DEACT ")) { // +CGEV: ME PDN DEACT 1
// "+CGEV: NW PDN DEACT ")) { // +CGEV: NW PDN DEACT <cid>
// "+CGEV: EPS PDN ACT ")) { // +CGEV: EPS PDN ACT <cid>
// "+CGEV: ME PDN DEACT ")) { // +CGEV: EPS PDN DEACT <cid>
// "+CGEV: ME PDN ACT ")) { // +CGEV: ME PDN ACT <cid>,1
mbtk_ril_pdp_state_info_t cgev_info;
memset(&cgev_info, 0, sizeof(mbtk_ril_pdp_state_info_t));
if (sscanf(s, "+CGEV: NW PDN DEACT %d", &(cgev_info.cid)) == 1) {
cgev_info.action = FALSE;
} else if (sscanf(s, "+CGEV: ME PDN DEACT %d", &(cgev_info.cid)) == 1) {
cgev_info.action = FALSE;
} else if(sscanf(s, "+CGEV: ME PDN ACT %d,%d", &(cgev_info.cid), &(cgev_info.reason)) == 2
|| sscanf(s, "+CGEV: ME PDN ACT %d", &(cgev_info.cid)) == 1) {
cgev_info.action = TRUE;
} else if (!strcmp(s, "+CGEV: ME DETACH")) {
if(cgact_wait.waitting) {
cgev_info.cid = cgact_wait.cid;
}
cgev_info.action = FALSE;
} else if (sscanf(s, "+CGEV: NW MODIFY %d,%d", &(cgev_info.cid), &(cgev_info.reason)) == 2) {
cgev_info.action = TRUE;
} else if(sscanf(s, "+CGEV: EPS PDN ACT %d", &(cgev_info.cid)) == 1) {
cgev_info.action = TRUE;
} else {
LOGD(">>>>>>>>>No process +CGEV <<<<<<<<<");
return;
}
cgev_info.auto_change = !cgact_wait.waitting;
if(cgact_wait.act) {
if(cgact_wait.waitting && cgev_info.action && cgact_wait.cid == cgev_info.cid) {
cgact_wait.waitting = false;
}
} else {
if(cgact_wait.waitting && !cgev_info.action && cgact_wait.cid == cgev_info.cid) {
cgact_wait.waitting = false;
}
}
LOGD("+CGEV:cid - %d, act - %d, auto_change - %d, reason - %d", cgev_info.cid, cgev_info.action,
cgev_info.auto_change, cgev_info.reason);
if(cgev_info.cid >= MBTK_APN_CID_MIN && cgev_info.cid <= MBTK_APN_CID_MAX) {
urc_msg_distribute(false, RIL_MSG_ID_IND_PDP_STATE_CHANGE, &cgev_info, sizeof(mbtk_ril_pdp_state_info_t));
}
#else
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);
#if (defined(MBTK_AF_SUPPORT) || defined(MBTK_ALL_CID_SUPPORT))
//data[0] = (uint8)1;
//data[1] = (uint8)atoi(s + 19);
#else
data[0] = (uint8)1;
data[1] = (uint8)atoi(s + 19);
#endif
} 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);
}
#endif
} else {
LOGW("Unknown PDP URC : %s", s);
}
}
static void urc_cell_info_process(const char *s, const char *sms_pdu)
{
/*
// <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
*/
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_list.cell[cell_info.cell_list.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_list.cell[cell_info.cell_list.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_list.cell[cell_info.cell_list.num].value1 = (uint32)tmp_int; //tac
if (at_tok_nextint(&line, &tmp_int) < 0)
{
goto EEMLTESVC_EXIT;
}
cell_info.cell_list.cell[cell_info.cell_list.num].value2 = (uint32)tmp_int; //pci
if (at_tok_nextint(&line, &tmp_int) < 0)
{
goto EEMLTESVC_EXIT;
}
cell_info.cell_list.cell[cell_info.cell_list.num].value3 = (uint32)tmp_int; //dl arfcn
if (at_tok_nextint(&line, &tmp_int) < 0)
{
goto EEMLTESVC_EXIT;
}
cell_info.cell_list.cell[cell_info.cell_list.num].value4 = (uint32)tmp_int; //ul arfcn
if (at_tok_nextint(&line, &tmp_int) < 0)
{
goto EEMLTESVC_EXIT;
}
cell_info.cell_list.cell[cell_info.cell_list.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_list.cell[cell_info.cell_list.num].value8 = (uint32)tmp_int; //cid
if (at_tok_nextint(&line, &tmp_int) < 0)
{
goto EEMLTESVC_EXIT;
}
cell_info.cell_list.cell[cell_info.cell_list.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_list.cell[cell_info.cell_list.num].value10 = (uint32)tmp_int; //cell identiy
cell_info.cell_list.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_list.cell[cell_info.cell_list.num].value1 = (uint32)tmp_int;
if (at_tok_nextint(&line, &tmp_int) < 0)
{
goto EEMLTEINTER_EXIT;
}
cell_info.cell_list.cell[cell_info.cell_list.num].value2 = (uint32)tmp_int;
if (at_tok_nextint(&line, &tmp_int) < 0)
{
goto EEMLTEINTER_EXIT;
}
cell_info.cell_list.cell[cell_info.cell_list.num].value3 = (uint32)tmp_int;
LOG("cell line : %s", line);
if (at_tok_nextint(&line, &tmp_int) < 0)
{
goto EEMLTEINTER_EXIT;
}
cell_info.cell_list.cell[cell_info.cell_list.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_list.cell[cell_info.cell_list.num].value5 = (uint32)tmp_int;
LOG("cell value5 : %d", cell_info.cell_list.cell[cell_info.cell_list.num].value5);
cell_info.cell_list.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_list.cell[cell_info.cell_list.num].value4= (uint32)tmp_int;
// mnc
if (at_tok_nextint(&line, &tmp_int) < 0)
{
goto EEMUMTSSVC_EXIT;
}
cell_info.cell_list.cell[cell_info.cell_list.num].value5= (uint32)tmp_int;
// lac
if (at_tok_nextint(&line, &tmp_int) < 0)
{
goto EEMUMTSSVC_EXIT;
}
cell_info.cell_list.cell[cell_info.cell_list.num].value1 = (uint32)tmp_int;
// ci
if (at_tok_nextint(&line, &tmp_int) < 0)
{
goto EEMUMTSSVC_EXIT;
}
cell_info.cell_list.cell[cell_info.cell_list.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_list.cell[cell_info.cell_list.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_list.cell[cell_info.cell_list.num].value3 = (uint32)tmp_int;
cell_info.cell_list.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_list.cell[cell_info.cell_list.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_list.cell[cell_info.cell_list.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_list.cell[cell_info.cell_list.num].value3 = (uint32)tmp_int;
cell_info.cell_list.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_list.cell[cell_info.cell_list.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_list.cell[cell_info.cell_list.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_list.cell[cell_info.cell_list.num].value3 = (uint32)tmp_int;
cell_info.cell_list.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_list.cell[cell_info.cell_list.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_list.cell[cell_info.cell_list.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_list.cell[cell_info.cell_list.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_list.cell[cell_info.cell_list.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_list.cell[cell_info.cell_list.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_list.cell[cell_info.cell_list.num].value3 = (uint32)tmp_int;
cell_info.cell_list.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_list.cell[cell_info.cell_list.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_list.cell[cell_info.cell_list.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_list.cell[cell_info.cell_list.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_list.cell[cell_info.cell_list.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_list.cell[cell_info.cell_list.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_list.cell[cell_info.cell_list.num].value3 = (uint32)tmp_int;
cell_info.cell_list.num++;
EEMGINFOPS_EXIT:
free(free_ptr);
}
} else {
LOGW("Unknown CELL URC : %s", s);
}
}
static void onUnsolicited(const char *s, const char *sms_pdu)
{
LOGD("URC : %s", s);
// MBTK_AT_READY
if (strStartsWith(s, "MBTK_AT_READY")) // AT ready.
{
} else if(strStartsWith(s, "CONNECT") || strStartsWith(s, "+CGEV:")) {
urc_pdp_state_change_process(s, sms_pdu);
} else if(strStartsWith(s, "+EEMLTESVC:") || strStartsWith(s, "+EEMLTEINTER:")
|| strStartsWith(s, "+EEMLTEINTRA:") || strStartsWith(s, "+EEMLTEINTERRAT:")
|| strStartsWith(s, "+EEMUMTSSVC:") || strStartsWith(s, "+EEMUMTSINTRA:")
|| strStartsWith(s, "+EEMUMTSINTERRAT:") || strStartsWith(s, "+EEMGINFOBASIC:")
|| strStartsWith(s, "+EEMGINFOSVC:") || strStartsWith(s, "+EEMGINFOPS:")
|| strStartsWith(s, "+EEMGINFONC:")) {
urc_cell_info_process(s, sms_pdu);
}
else if(strStartsWith(s, "*RADIOPOWER:")) // "*RADIOPOWER: 1"
{
const char* ptr = s + strlen("*RADIOPOWER:");
while(*ptr != '\0' && *ptr == ' ' )
{
ptr++;
}
mbtk_ril_radio_state_info_t state;
memset(&state, 0, sizeof(mbtk_ril_radio_state_info_t));
if(*ptr == '1') {
state.radio_state = MBTK_RADIO_STATE_FULL_FUNC;
} else {
state.radio_state = MBTK_RADIO_STATE_MINI_FUNC;
}
urc_msg_distribute(true, RIL_MSG_ID_IND_RADIO_STATE_CHANGE, &state, sizeof(mbtk_ril_radio_state_info_t));
}
// +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.
|| strStartsWith(s, "+CREG:")) // GMS/WCDMA/LTE CS registed.
{
urc_net_reg_state_change_process(s, sms_pdu);
}
// +CLCC: 1, 1, 6, 0, 0, "18981911691", 129, "",, 0
else if(strStartsWith(s, "+CLCC:")
|| strStartsWith(s, "+CPAS:")
|| strStartsWith(s, "+CALLDISCONNECT:"))
{
urc_call_state_change_process(s, sms_pdu);
}
else if(strStartsWith(s, "*SIMDETEC:")
|| strStartsWith(s, "*EUICC:")
|| strStartsWith(s, "+CPIN:"))
{
urc_sim_state_change_process(s, sms_pdu);
}
else if(strStartsWith(s, "+CMT:"))
{
urc_sms_state_change_process(s, sms_pdu);
}
else if(strStartsWith(s, "*ECALLDATA:"))
{
urc_ecall_state_change_process(s, sms_pdu);
}
#if 0
// +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, &reg, 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(&reg,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, &reg, 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(&reg,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, &reg, 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));
}
#endif
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);
}
}
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_REQ)
{
if(pack->msg_id > RIL_MSG_ID_IND_BEGIN
&& pack->msg_id < RIL_MSG_ID_IND_END) {
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 {
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);
}
} else {
LOGE("Pack type error : %d", pack->msg_type);
}
}
// 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_DATA_CALL_BEGIN && pack->msg_id < RIL_MSG_ID_DATA_CALL_END) {
return data_call_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 if(pack->msg_id > RIL_MSG_ID_ECALL_BEGIN && pack->msg_id < RIL_MSG_ID_ECALL_END) {
return ecall_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)
{
if(!msg->data || msg->data_len <= 0) {
LOGE("URC data is NULL.");
return;
}
switch(msg->msg) {
case RIL_MSG_ID_IND_RADIO_STATE_CHANGE:
{
mbtk_ril_radio_state_info_t *state = (mbtk_ril_radio_state_info_t*)msg->data;
LOGD("Radio state : %d", state->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_STATE_CHANGE to client.
mbtk_ril_ser_state_enum state = MBTK_RIL_SER_STATE_READY;
ril_ind_pack_send(client_fd, RIL_MSG_ID_IND_SER_STATE_CHANGE, &state, 1);
}
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.
if(item->pack) {
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");
MBTK_SOURCE_INFO_PRINT("mbtk_rild");
#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;
}