blob: 2924ac55ad0330849f0158c46a8c3406afa1830d [file] [log] [blame]
/*
* ril_ecall.c
*
* Implementation of ecall related functions.
*
* The general structure is as follows:
* API --- mbtk_rild --- atcmdsrv --- modem
* |
|
* ecall_daemon
*
*/
/******************************************************************************
EDIT HISTORY FOR FILE
WHEN WHO WHAT,WHERE,WHY
-------- -------- -------------------------------------------------------
2024/11/04 LiuBin Initial version
******************************************************************************/
#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"
static mbtk_ecall_mode_type_enum ecall_mode = MBTK_ECALL_MODE_TYPE_EU;
void ril_rsp_pack_send(mbtk_sim_type_enum sim_id, ATPortType_enum port, int fd, int ril_id, int msg_index, const void* data, int data_len);
ATPortId_enum portType_2_portId(mbtk_sim_type_enum sim_id, ATPortType_enum port);
static int cfg_ecalldata_get(mbtk_sim_type_enum sim_id, ATPortType_enum port, mbtk_ecall_cfg_item_enum type, uint32 *value, int *cme_err)
{
ATResponse *response = NULL;
// char *tmp_ptr = NULL;
int tmp_int;
char cmd[100] = {0};
int err = 0;
snprintf(cmd, sizeof(cmd), "AT*ECALLDATA=5,%d", type);
err = at_send_command_singleline(portType_2_portId(sim_id, port), cmd, "*ECALLDATA:", &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;
}
err = at_tok_nextint(&line, &tmp_int);
if (err < 0)
{
goto exit;
}
err = at_tok_nextint(&line, &tmp_int);
if (err < 0)
{
goto exit;
}
*value = (uint32)(tmp_int * 20); // ms
goto exit;
exit:
at_response_free(response);
return err;
}
static int cfg_ecalldata_set(mbtk_sim_type_enum sim_id, ATPortType_enum port, mbtk_ecall_cfg_item_enum type, uint32 value, int *cme_err)
{
ATResponse *response = NULL;
char cmd[100] = {0};
int err = 0;
snprintf(cmd, sizeof(cmd), "AT*ECALLDATA=5,%d,%d", type, value / 20);
err = at_send_command(portType_2_portId(sim_id, port), cmd, &response);
if (err < 0 || response->success == 0){
*cme_err = at_get_cme_error(response);
goto exit;
}
goto exit;
exit:
at_response_free(response);
return err;
}
static int cfg_ecalltimer_set(mbtk_sim_type_enum sim_id, ATPortType_enum port, const char* type, uint32 value, int *cme_err)
{
ATResponse *response = NULL;
char cmd[100] = {0};
int err = 0;
snprintf(cmd, sizeof(cmd), "AT*ECALLTIMER=%s,%d", type, value);
err = at_send_command(portType_2_portId(sim_id, port), cmd, &response);
if (err < 0 || response->success == 0){
*cme_err = at_get_cme_error(response);
goto exit;
}
goto exit;
exit:
at_response_free(response);
return err;
}
static int req_ecall_msdcfg(mbtk_sim_type_enum sim_id, ATPortType_enum port, mbtk_ecall_msd_cfg_info_t *cfg_info, int *cme_err)
{
ATResponse *response = NULL;
char cmd[1024] = {0};
sprintf(cmd, "AT*ECALLMSDCFG=%d,\"%s\",0", cfg_info->item_type, cfg_info->data);
int err = at_send_command(portType_2_portId(sim_id, port), cmd, &response);
if (err < 0 || response->success == 0){
*cme_err = at_get_cme_error(response);
goto exit;
}
exit:
at_response_free(response);
return err;
}
static int req_ecall_msdgen(mbtk_sim_type_enum sim_id, ATPortType_enum port, int *cme_err)
{
ATResponse *response = NULL;
int err = at_send_command(portType_2_portId(sim_id, port), "AT*ECALLMSDGEN", &response);
if (err < 0 || response->success == 0){
*cme_err = at_get_cme_error(response);
goto exit;
}
exit:
at_response_free(response);
return err;
}
static int req_ecall_msd_set(mbtk_sim_type_enum sim_id, ATPortType_enum port, const uint8 *msd, int *cme_err)
{
ATResponse *response = NULL;
char cmd[1024] = {0};
sprintf(cmd, "AT*ECALLMSD=\"%s\"", msd);
int err = at_send_command(portType_2_portId(sim_id, port), cmd, &response);
if (err < 0 || response->success == 0){
*cme_err = at_get_cme_error(response);
goto exit;
}
exit:
at_response_free(response);
return err;
}
static int req_ecall_msd_get(mbtk_sim_type_enum sim_id, ATPortType_enum port, uint8 *msd, int *cme_err)
{
ATResponse *response = NULL;
char *tmp_ptr = NULL;
int err = at_send_command_singleline(portType_2_portId(sim_id, port), "AT*ECALLMSD?", "*ECALLMSD:", &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;
}
if(tmp_ptr && strlen(tmp_ptr) > 0) {
memcpy(msd, tmp_ptr, strlen(tmp_ptr));
}
goto exit;
exit:
at_response_free(response);
return err;
}
static int req_ecall_push(mbtk_sim_type_enum sim_id, ATPortType_enum port, int *cme_err)
{
ATResponse *response = NULL;
int err = at_send_command(portType_2_portId(sim_id, port), "AT*ECALLPUSH", &response);
if (err < 0 || response->success == 0){
*cme_err = at_get_cme_error(response);
goto exit;
}
exit:
at_response_free(response);
return err;
}
/*
AT*ECALLONLY?
*ECALLONLY: 0,0,18981911691,18981911691
OK
*/
static int req_ecall_only_get(mbtk_sim_type_enum sim_id, ATPortType_enum port, mbtk_ecall_only_info_t *only_info, int *cme_err)
{
ATResponse *response = NULL;
char *tmp_ptr = NULL;
int tmp_int;
int err = at_send_command_singleline(portType_2_portId(sim_id, port), "AT*ECALLONLY?", "*ECALLONLY:", &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;
}
only_info->active = (mbtk_ecall_only_type_enum)tmp_int;
err = at_tok_nextint(&line, &tmp_int);
if (err < 0)
{
goto exit;
}
only_info->sim_type = (mbtk_ecall_sim_type_enum)tmp_int;
err = at_tok_nextstr(&line, &tmp_ptr);
if (err < 0)
{
goto exit;
}
if(tmp_ptr && strlen(tmp_ptr) > 0) {
memcpy(only_info->test_num, tmp_ptr, strlen(tmp_ptr));
}
err = at_tok_nextstr(&line, &tmp_ptr);
if (err < 0)
{
goto exit;
}
if(tmp_ptr && strlen(tmp_ptr) > 0) {
memcpy(only_info->reconfig_num, tmp_ptr, strlen(tmp_ptr));
}
goto exit;
exit:
at_response_free(response);
return err;
}
/*
AT*ECALLONLY?
*ECALLONLY: 0,0,18981911691,18981911691
OK
*/
static int req_ecall_only_set(mbtk_sim_type_enum sim_id, ATPortType_enum port, const mbtk_ecall_only_info_t *only_info, int *cme_err)
{
ATResponse *response = NULL;
char cmd[1024] = {0};
sprintf(cmd, "AT*ECALLONLY=%d,%s,%s", only_info->active,only_info->test_num,only_info->reconfig_num);
int err = at_send_command(portType_2_portId(sim_id, port), 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*ECALLREG=0/1
*/
static int req_ecall_reg_set(mbtk_sim_type_enum sim_id, ATPortType_enum port, uint8 reg, int *cme_err)
{
ATResponse *response = NULL;
char cmd[30] = {0};
sprintf(cmd, "AT*ECALLREG=%d", reg);
int err = at_send_command(portType_2_portId(sim_id, port), 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+CECALL?
+CECALL: 4
OK
*/
static int req_ecall_dial_state_get(mbtk_sim_type_enum sim_id, ATPortType_enum port, mbtk_ecall_dial_type_enum *type, int *cme_err)
{
ATResponse *response = NULL;
int tmp_int;
int err = at_send_command_singleline(portType_2_portId(sim_id, port), "AT+CECALL?", "+CECALL:", &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;
}
*type = (mbtk_ecall_dial_type_enum)tmp_int;
goto exit;
exit:
at_response_free(response);
return err;
}
/*
AT+CECALL=<ecalltype>
OK
*/
static int req_ecall_dial_start(mbtk_sim_type_enum sim_id, ATPortType_enum port, mbtk_ecall_dial_type_enum type, int *cme_err)
{
ATResponse *response = NULL;
char cmd[1024] = {0};
sprintf(cmd, "AT+CECALL=%d", type);
int err = at_send_command(portType_2_portId(sim_id, port), 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*ECALLMODE?
*ECALLMODE: "ERA"
OK
*/
static int req_ecall_mode_get(mbtk_sim_type_enum sim_id, ATPortType_enum port, mbtk_ecall_mode_type_enum *mode, int *cme_err)
{
ATResponse *response = NULL;
char *tmp_ptr = NULL;
int err = at_send_command_singleline(portType_2_portId(sim_id, port), "AT*ECALLMODE?", "*ECALLMODE:", &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;
}
if(tmp_ptr && strlen(tmp_ptr) > 0) {
if(strcmp(tmp_ptr, "ERA") == 0) {
*mode = MBTK_ECALL_MODE_TYPE_ERA;
} else {
*mode = MBTK_ECALL_MODE_TYPE_EU;
}
ecall_mode = *mode;
} else {
err = -1;
}
goto exit;
exit:
at_response_free(response);
return err;
}
/*
AT*ECALLMODE="ERA"
OK
*/
static int req_ecall_mode_set(mbtk_sim_type_enum sim_id, ATPortType_enum port, mbtk_ecall_mode_type_enum mode, int *cme_err)
{
ATResponse *response = NULL;
char cmd[1024] = {0};
if(mode == MBTK_ECALL_MODE_TYPE_EU) {
sprintf(cmd, "AT*ECALLMODE=\"EU\"");
} else {
sprintf(cmd, "AT*ECALLMODE=\"ERA\"");
}
int err = at_send_command(portType_2_portId(sim_id, port), cmd, &response);
if (err < 0 || response->success == 0){
*cme_err = at_get_cme_error(response);
goto exit;
}
ecall_mode = mode;
exit:
at_response_free(response);
return err;
}
/*
AT*ECALLDATA=5,2
*ECALLDATA: 5,2,250
OK
AT*ECALLTIMER?
*ECALLTIMER: ERA mode, callback timer: 1200s, dial setup timer: 30s, NAD deregister timer: 7200s, cleardown timer: 3600s, redial attempts count: 10, redial wait timer: 30s, smsprocess: 1, SMS resend timer: 3600s, sms msd send count: 10.
OK
*/
static int req_ecall_cfg_get(mbtk_sim_type_enum sim_id, ATPortType_enum port, uint32 type, mbtk_ecall_cfg_info_t *cfg, int *cme_err)
{
ATResponse *response = NULL;
char *tmp_ptr = NULL;
// int tmp_int;
int err = 0;
cfg->type = type;
if(type & MBTK_ECALL_CFG_T3) {
if(cfg_ecalldata_get(sim_id, port, MBTK_ECALL_CFG_ITEM_T3, &(cfg->data[MBTK_ECALL_CFG_ITEM_T3]), cme_err)
|| *cme_err != MBTK_RIL_ERR_CME_NON)
{
goto exit;
}
cfg->data_valid[MBTK_ECALL_CFG_ITEM_T3] = (uint8)1;
}
if(type & MBTK_ECALL_CFG_T5) {
if(cfg_ecalldata_get(sim_id, port, MBTK_ECALL_CFG_ITEM_T5, &(cfg->data[MBTK_ECALL_CFG_ITEM_T5]), cme_err)
|| *cme_err != MBTK_RIL_ERR_CME_NON)
{
goto exit;
}
cfg->data_valid[MBTK_ECALL_CFG_ITEM_T5] = (uint8)1;
}
if(type & MBTK_ECALL_CFG_T6) {
if(cfg_ecalldata_get(sim_id, port, MBTK_ECALL_CFG_ITEM_T6, &(cfg->data[MBTK_ECALL_CFG_ITEM_T6]), cme_err)
|| *cme_err != MBTK_RIL_ERR_CME_NON)
{
goto exit;
}
cfg->data_valid[MBTK_ECALL_CFG_ITEM_T6] = (uint8)1;
}
if(type & MBTK_ECALL_CFG_T7) {
if(cfg_ecalldata_get(sim_id, port, MBTK_ECALL_CFG_ITEM_T7, &(cfg->data[MBTK_ECALL_CFG_ITEM_T7]), cme_err)
|| *cme_err != MBTK_RIL_ERR_CME_NON)
{
goto exit;
}
cfg->data_valid[MBTK_ECALL_CFG_ITEM_T7] = (uint8)1;
}
if(type & MBTK_ECALL_CFG_TH) {
if(cfg_ecalldata_get(sim_id, port, MBTK_ECALL_CFG_ITEM_TH, &(cfg->data[MBTK_ECALL_CFG_ITEM_TH]), cme_err)
|| *cme_err != MBTK_RIL_ERR_CME_NON)
{
goto exit;
}
cfg->data_valid[MBTK_ECALL_CFG_ITEM_TH] = (uint8)1;
}
if(type & (MBTK_ECALL_CFG_TIMER_CALLBACK | MBTK_ECALL_CFG_TIMER_CLEARDOWN | MBTK_ECALL_CFG_TIMER_DEREG
| MBTK_ECALL_CFG_TIMER_DIAL | MBTK_ECALL_CFG_TIMER_REDIAL | MBTK_ECALL_CFG_TIMER_SMS
| MBTK_ECALL_CFG_REDIALCNT | MBTK_ECALL_CFG_SMSPROCESS | MBTK_ECALL_CFG_SMSMSDCNT)) {
err = at_send_command_singleline(portType_2_portId(sim_id, port), "AT*ECALLTIMER?", "*ECALLTIMER:", &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;
}
// *ECALLTIMER: ERA mode, callback timer: 1200s,
// dial setup timer: 30s, NAD deregister timer: 7200s,
// cleardown timer: 3600s, redial attempts count: 10,
// redial wait timer: 30s, smsprocess: 1, SMS resend timer: 3600s,
// sms msd send count: 10.
if(strstr(line, "ERA mode") != NULL) {
ecall_mode = MBTK_ECALL_MODE_TYPE_ERA;
} else {
ecall_mode = MBTK_ECALL_MODE_TYPE_EU;
}
if(type & MBTK_ECALL_CFG_TIMER_CALLBACK)
{
if((tmp_ptr = strstr(line, "callback timer: ")) != NULL) {
cfg->data[MBTK_ECALL_CFG_ITEM_TIMER_CALLBACK] = (uint32)atoi(tmp_ptr + 16); // s
cfg->data[MBTK_ECALL_CFG_ITEM_TIMER_CALLBACK] *= 1000; // s -> ms
cfg->data_valid[MBTK_ECALL_CFG_ITEM_TIMER_CALLBACK] = (uint8)1;
}
}
if(type & MBTK_ECALL_CFG_TIMER_CLEARDOWN)
{
if((tmp_ptr = strstr(line, "cleardown timer: ")) != NULL) {
cfg->data[MBTK_ECALL_CFG_ITEM_TIMER_CLEARDOWN] = (uint32)atoi(tmp_ptr + 17); // s
cfg->data[MBTK_ECALL_CFG_ITEM_TIMER_CLEARDOWN] *= 1000; // s -> ms
cfg->data_valid[MBTK_ECALL_CFG_ITEM_TIMER_CLEARDOWN] = (uint8)1;
}
}
if(type & MBTK_ECALL_CFG_TIMER_DEREG)
{
if((tmp_ptr = strstr(line, "deregister timer: ")) != NULL) {
cfg->data[MBTK_ECALL_CFG_ITEM_TIMER_DEREG] = (uint32)atoi(tmp_ptr + 18); // s
cfg->data[MBTK_ECALL_CFG_ITEM_TIMER_DEREG] *= 1000; // s -> ms
cfg->data_valid[MBTK_ECALL_CFG_ITEM_TIMER_DEREG] = (uint8)1;
}
}
if(type & MBTK_ECALL_CFG_TIMER_DIAL)
{
if((tmp_ptr = strstr(line, "dial setup timer: ")) != NULL) {
cfg->data[MBTK_ECALL_CFG_ITEM_TIMER_DIAL] = (uint32)atoi(tmp_ptr + 18); // s
cfg->data[MBTK_ECALL_CFG_ITEM_TIMER_DIAL] *= 1000; // s -> ms
cfg->data_valid[MBTK_ECALL_CFG_ITEM_TIMER_DIAL] = (uint8)1;
}
}
if(type & MBTK_ECALL_CFG_TIMER_REDIAL)
{
if((tmp_ptr = strstr(line, "redial wait timer: ")) != NULL) {
cfg->data[MBTK_ECALL_CFG_ITEM_TIMER_REDIAL] = (uint32)atoi(tmp_ptr + 19); // s
cfg->data[MBTK_ECALL_CFG_ITEM_TIMER_REDIAL] *= 1000; // s -> ms
cfg->data_valid[MBTK_ECALL_CFG_ITEM_TIMER_REDIAL] = (uint8)1;
}
}
if(type & MBTK_ECALL_CFG_TIMER_SMS)
{
if((tmp_ptr = strstr(line, "SMS resend timer: ")) != NULL) {
cfg->data[MBTK_ECALL_CFG_ITEM_TIMER_SMS] = (uint32)atoi(tmp_ptr + 18);
cfg->data[MBTK_ECALL_CFG_ITEM_TIMER_SMS] *= 1000; // s -> ms
cfg->data_valid[MBTK_ECALL_CFG_ITEM_TIMER_SMS] = (uint8)1;
}
}
if(type & MBTK_ECALL_CFG_REDIALCNT)
{
if((tmp_ptr = strstr(line, "redial attempts count: ")) != NULL) {
cfg->data[MBTK_ECALL_CFG_ITEM_REDIALCNT] = (uint32)atoi(tmp_ptr + 23);
cfg->data_valid[MBTK_ECALL_CFG_ITEM_REDIALCNT] = (uint8)1;
}
}
if(type & MBTK_ECALL_CFG_SMSPROCESS)
{
if((tmp_ptr = strstr(line, "smsprocess: ")) != NULL) {
cfg->data[MBTK_ECALL_CFG_ITEM_SMSPROCESS] = (uint32)atoi(tmp_ptr + 12);
cfg->data_valid[MBTK_ECALL_CFG_ITEM_SMSPROCESS] = (uint8)1;
}
}
if(type & MBTK_ECALL_CFG_SMSMSDCNT)
{
if((tmp_ptr = strstr(line, "sms msd send count: ")) != NULL) {
cfg->data[MBTK_ECALL_CFG_ITEM_SMSMSDCNT] = (uint32)atoi(tmp_ptr + 20);
cfg->data_valid[MBTK_ECALL_CFG_ITEM_SMSMSDCNT] = (uint8)1;
}
}
}
goto exit;
exit:
at_response_free(response);
return err;
}
/*
AT*ECALLDATA=5,2,250
OK
AT*ECALLTIMER=dereg,300
OK
*/
static int req_ecall_cfg_set(mbtk_sim_type_enum sim_id, ATPortType_enum port, const mbtk_ecall_cfg_info_t *cfg_info, int *cme_err)
{
int err = 0;
if(ecall_mode == MBTK_ECALL_MODE_TYPE_EU) {
if((cfg_info->type & MBTK_ECALL_CFG_TIMER_REDIAL)
|| (cfg_info->type & MBTK_ECALL_CFG_TIMER_SMS)
|| (cfg_info->type & MBTK_ECALL_CFG_REDIALCNT)
|| (cfg_info->type & MBTK_ECALL_CFG_SMSPROCESS)
|| (cfg_info->type & MBTK_ECALL_CFG_SMSMSDCNT)){
LOGW("No support for EU.");
return -1;
}
}
if(cfg_info->type & MBTK_ECALL_CFG_T3) {
if(cfg_ecalldata_set(sim_id, port, MBTK_ECALL_CFG_ITEM_T3, cfg_info->data[MBTK_ECALL_CFG_ITEM_T3], cme_err)
|| *cme_err != MBTK_RIL_ERR_CME_NON)
{
goto exit;
}
}
if(cfg_info->type & MBTK_ECALL_CFG_T5) {
if(cfg_ecalldata_set(sim_id, port, MBTK_ECALL_CFG_ITEM_T5, cfg_info->data[MBTK_ECALL_CFG_ITEM_T5], cme_err)
|| *cme_err != MBTK_RIL_ERR_CME_NON)
{
goto exit;
}
}
if(cfg_info->type & MBTK_ECALL_CFG_T6) {
if(cfg_ecalldata_set(sim_id, port, MBTK_ECALL_CFG_ITEM_T6, cfg_info->data[MBTK_ECALL_CFG_ITEM_T6], cme_err)
|| *cme_err != MBTK_RIL_ERR_CME_NON)
{
goto exit;
}
}
if(cfg_info->type & MBTK_ECALL_CFG_T7) {
if(cfg_ecalldata_set(sim_id, port, MBTK_ECALL_CFG_ITEM_T7, cfg_info->data[MBTK_ECALL_CFG_ITEM_T7], cme_err)
|| *cme_err != MBTK_RIL_ERR_CME_NON)
{
goto exit;
}
}
if(cfg_info->type & MBTK_ECALL_CFG_TH) {
if(cfg_ecalldata_set(sim_id, port, MBTK_ECALL_CFG_ITEM_TH, cfg_info->data[MBTK_ECALL_CFG_ITEM_TH], cme_err)
|| *cme_err != MBTK_RIL_ERR_CME_NON)
{
goto exit;
}
}
if(cfg_info->type & MBTK_ECALL_CFG_TIMER_CALLBACK)
{
if(cfg_ecalltimer_set(sim_id, port, "callback", cfg_info->data[MBTK_ECALL_CFG_ITEM_TIMER_CALLBACK] / 1000, cme_err)
|| *cme_err != MBTK_RIL_ERR_CME_NON) {
goto exit;
}
}
if(cfg_info->type & MBTK_ECALL_CFG_TIMER_CLEARDOWN)
{
if(cfg_ecalltimer_set(sim_id, port, "cleardown", cfg_info->data[MBTK_ECALL_CFG_ITEM_TIMER_CLEARDOWN] / 1000, cme_err)
|| *cme_err != MBTK_RIL_ERR_CME_NON) {
goto exit;
}
}
if(cfg_info->type & MBTK_ECALL_CFG_TIMER_DEREG)
{
if(cfg_ecalltimer_set(sim_id, port, "dereg", cfg_info->data[MBTK_ECALL_CFG_ITEM_TIMER_DEREG] / 1000, cme_err)
|| *cme_err != MBTK_RIL_ERR_CME_NON) {
goto exit;
}
}
if(cfg_info->type & MBTK_ECALL_CFG_TIMER_DIAL)
{
if(cfg_ecalltimer_set(sim_id, port, "dial", cfg_info->data[MBTK_ECALL_CFG_ITEM_TIMER_DIAL] / 1000, cme_err)
|| *cme_err != MBTK_RIL_ERR_CME_NON) {
goto exit;
}
}
if(cfg_info->type & MBTK_ECALL_CFG_TIMER_REDIAL)
{
if(cfg_ecalltimer_set(sim_id, port, "redialtmr", cfg_info->data[MBTK_ECALL_CFG_ITEM_TIMER_REDIAL] / 1000, cme_err)
|| *cme_err != MBTK_RIL_ERR_CME_NON) {
goto exit;
}
}
if(cfg_info->type & MBTK_ECALL_CFG_TIMER_SMS)
{
if(cfg_ecalltimer_set(sim_id, port, "sms", cfg_info->data[MBTK_ECALL_CFG_ITEM_TIMER_SMS] / 1000, cme_err)
|| *cme_err != MBTK_RIL_ERR_CME_NON) {
goto exit;
}
}
if(cfg_info->type & MBTK_ECALL_CFG_REDIALCNT)
{
if(cfg_ecalltimer_set(sim_id, port, "redialcnt", cfg_info->data[MBTK_ECALL_CFG_ITEM_REDIALCNT], cme_err)
|| *cme_err != MBTK_RIL_ERR_CME_NON) {
goto exit;
}
}
if(cfg_info->type & MBTK_ECALL_CFG_SMSPROCESS)
{
if(cfg_ecalltimer_set(sim_id, port, "smsprocess", cfg_info->data[MBTK_ECALL_CFG_ITEM_SMSPROCESS], cme_err)
|| *cme_err != MBTK_RIL_ERR_CME_NON) {
goto exit;
}
}
if(cfg_info->type & MBTK_ECALL_CFG_SMSMSDCNT)
{
if(cfg_ecalltimer_set(sim_id, port, "smsmsdcnt", cfg_info->data[MBTK_ECALL_CFG_ITEM_SMSMSDCNT], cme_err)
|| *cme_err != MBTK_RIL_ERR_CME_NON) {
goto exit;
}
}
exit:
return err;
}
/*
AT*ECALLMUTESPK=1
OK
*/
static int req_ecall_spkmute_set(mbtk_sim_type_enum sim_id, ATPortType_enum port, int mute, int *cme_err)
{
ATResponse *response = NULL;
char cmd[100] = {0};
sprintf(cmd, "AT*ECALLMUTESPK=%d", mute);
int err = at_send_command(portType_2_portId(sim_id, port), 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*ECALLSMSNUM?
*ECALLSMSNUM: "18981991452"
OK
*/
static int req_ecall_sms_num_get(mbtk_sim_type_enum sim_id, ATPortType_enum port, uint8 *number, int *cme_err)
{
ATResponse *response = NULL;
char *tmp_ptr = NULL;
int err = at_send_command_singleline(portType_2_portId(sim_id, port), "AT*ECALLSMSNUM?", "*ECALLSMSNUM:", &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;
}
if(tmp_ptr && strlen(tmp_ptr) > 0) {
memcpy(number, tmp_ptr, strlen(tmp_ptr));
}
goto exit;
exit:
at_response_free(response);
return err;
}
/*
AT*ECALLSMSNUM=18981991452
OK
*/
static int req_ecall_sms_num_set(mbtk_sim_type_enum sim_id, ATPortType_enum port, const uint8 *number, int *cme_err)
{
ATResponse *response = NULL;
char cmd[100] = {0};
sprintf(cmd, "AT*ECALLSMSNUM=%s", number);
int err = at_send_command(portType_2_portId(sim_id, port), 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*AUDGAIN=8,1 // Set Rx voice gain = 8dB
OK
*/
static int req_ecall_gain_set(mbtk_sim_type_enum sim_id, ATPortType_enum port, mbtk_ecall_gain_info_t *gain, int *cme_err)
{
ATResponse *response = NULL;
char cmd[100] = {0};
sprintf(cmd, "AT*AUDGAIN=%d,%d", gain->gain, gain->mode);
int err = at_send_command(portType_2_portId(sim_id, port), 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 ecall_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_ECALL_MSDCFG: // mbtk_ecall_msd_cfg_info_t
{
if(pack->data_len == 0 || pack->data == NULL)
{
err = MBTK_RIL_ERR_UNSUPPORTED;
}
else // Set
{
mbtk_ecall_msd_cfg_info_t *cfg_info = (mbtk_ecall_msd_cfg_info_t*)(pack->data);
if(req_ecall_msdcfg(cli_info->sim_id, cli_info->port, cfg_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("AT*ECALLMSDCFG fail.");
}
else
{
ril_rsp_pack_send(cli_info->sim_id, cli_info->port, cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
}
}
break;
}
case RIL_MSG_ID_ECALL_MSDGEN:
{
if(pack->data_len == 0 || pack->data == NULL)
{
if(req_ecall_msdgen(cli_info->sim_id, cli_info->port, &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("AT*ECALLMSDGEN fail.");
}
else
{
ril_rsp_pack_send(cli_info->sim_id, cli_info->port, cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
}
}
else // Set
{
err = MBTK_RIL_ERR_UNSUPPORTED;
}
break;
}
case RIL_MSG_ID_ECALL_MSD: // uint8[]
{
uint8 msd[MBTK_ECALL_MSD_LEN_MAX];
memset(msd, 0, sizeof(msd));
if(pack->data_len == 1 || pack->data == NULL) // data_len == 1 is wrote by hq at 2025/08/26 for bug 2187
{
if(req_ecall_msd_get(cli_info->sim_id, cli_info->port, msd, &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 MSD fail.");
}
else
{
ril_rsp_pack_send(cli_info->sim_id, cli_info->port, cli_info->fd, pack->msg_id, pack->msg_index, msd, strlen((char*)msd));
}
}
else // Set
{
memcpy(msd, pack->data, pack->data_len);
if(req_ecall_msd_set(cli_info->sim_id, cli_info->port, msd, &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("AT*ECALLMSD fail.");
}
else
{
ril_rsp_pack_send(cli_info->sim_id, cli_info->port, cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
}
}
break;
}
case RIL_MSG_ID_ECALL_PUSH:
{
if(pack->data_len == 0 || pack->data == NULL)
{
if(req_ecall_push(cli_info->sim_id, cli_info->port, &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("AT*ECALLPUSH fail.");
}
else
{
ril_rsp_pack_send(cli_info->sim_id, cli_info->port, cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
}
}
else // Set
{
err = MBTK_RIL_ERR_UNSUPPORTED;
}
break;
}
case RIL_MSG_ID_ECALL_ONLY: // mbtk_ecall_only_info_t
{
if(pack->data_len == 0 || pack->data == NULL)
{
mbtk_ecall_only_info_t only_info;
memset(&only_info, 0, sizeof(mbtk_ecall_only_info_t));
if(req_ecall_only_get(cli_info->sim_id, cli_info->port, &only_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 ecall only mode fail.");
}
else
{
ril_rsp_pack_send(cli_info->sim_id, cli_info->port, cli_info->fd, pack->msg_id, pack->msg_index, &only_info, sizeof(mbtk_ecall_only_info_t));
}
}
else // Set
{
mbtk_ecall_only_info_t *only_info = (mbtk_ecall_only_info_t*)(pack->data);
if(req_ecall_only_set(cli_info->sim_id, cli_info->port, only_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("AT*ECALLONLY fail.");
}
else
{
ril_rsp_pack_send(cli_info->sim_id, cli_info->port, cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
}
}
break;
}
case RIL_MSG_ID_ECALL_REG: // reg <uint8>
{
if(pack->data_len == 0 || pack->data == NULL)
{
err = MBTK_RIL_ERR_UNSUPPORTED;
}
else
{
uint8 reg = pack->data[0];
if(req_ecall_reg_set(cli_info->sim_id, cli_info->port, 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("ecall reg(%d) fail.", reg);
}
else
{
ril_rsp_pack_send(cli_info->sim_id, cli_info->port, cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
}
}
break;
}
case RIL_MSG_ID_ECALL_DIAL: // mbtk_ecall_dial_type_enum
{
if(pack->data_len == 0 || pack->data == NULL)
{
mbtk_ecall_dial_type_enum type;
if(req_ecall_dial_state_get(cli_info->sim_id, cli_info->port, &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 ecall type fail.");
}
else
{
ril_rsp_pack_send(cli_info->sim_id, cli_info->port, cli_info->fd, pack->msg_id, pack->msg_index, &type, sizeof(uint8));
}
}
else
{
mbtk_ecall_dial_type_enum type = (mbtk_ecall_dial_type_enum)pack->data[0];
if(req_ecall_dial_start(cli_info->sim_id, cli_info->port, 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("Start ecall %d fail.", type);
}
else
{
ril_rsp_pack_send(cli_info->sim_id, cli_info->port, cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
}
}
break;
}
case RIL_MSG_ID_ECALL_MODE: // mbtk_ecall_cfg_item_enum / mbtk_ecall_cfg_info_t
{
if(pack->data_len == 0 || pack->data == NULL)
{
mbtk_ecall_mode_type_enum mode;
if(req_ecall_mode_get(cli_info->sim_id, cli_info->port, &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("Get ecall mode fail.");
}
else
{
ril_rsp_pack_send(cli_info->sim_id, cli_info->port, cli_info->fd, pack->msg_id, pack->msg_index, &mode, sizeof(uint8));
}
}
else
{
mbtk_ecall_mode_type_enum mode = (mbtk_ecall_mode_type_enum)pack->data[0];
if(req_ecall_mode_set(cli_info->sim_id, cli_info->port, 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 ecall mode %d fail.", mode);
}
else
{
ril_rsp_pack_send(cli_info->sim_id, cli_info->port, cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
}
}
break;
}
case RIL_MSG_ID_ECALL_CFG: // mbtk_ecall_cfg_item_enum / mbtk_ecall_cfg_info_t
{
if(pack->data_len == 0 || pack->data == NULL)
{
err = MBTK_RIL_ERR_UNSUPPORTED;
}
else
{
if(pack->data_len == sizeof(mbtk_ecall_cfg_info_t)) { // Set
mbtk_ecall_cfg_info_t *cfg_info = (mbtk_ecall_cfg_info_t*)pack->data;
if(req_ecall_cfg_set(cli_info->sim_id, cli_info->port, cfg_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 ecall config[%x] fail.", cfg_info->type);
}
else
{
ril_rsp_pack_send(cli_info->sim_id, cli_info->port, cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
}
} else { // Get
mbtk_ecall_cfg_info_t cfg_info;
memset(&cfg_info, 0, sizeof(mbtk_ecall_cfg_info_t));
uint32 *type = (uint32*)(pack->data);
if(req_ecall_cfg_get(cli_info->sim_id, cli_info->port, *type, &cfg_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 ecall config[%x] fail.", *type);
}
else
{
ril_rsp_pack_send(cli_info->sim_id, cli_info->port, cli_info->fd, pack->msg_id, pack->msg_index, &cfg_info, sizeof(mbtk_ecall_cfg_info_t));
}
}
}
break;
}
case RIL_MSG_ID_ECALL_SMS_NUM: // uint8[]
{
uint8 number[RIL_MAX_NUMBER_LEN];
memset(number, 0, sizeof(number));
if(pack->data_len == 1 || pack->data == NULL) // data_len == 1 is wrote by hq at 2025/08/26 for bug 2187
{
if(req_ecall_sms_num_get(cli_info->sim_id, cli_info->port, number, &cme_err) || strlen((char*)number) == 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 ecall sms number fail.");
}
else
{
ril_rsp_pack_send(cli_info->sim_id, cli_info->port, cli_info->fd, pack->msg_id, pack->msg_index, number, strlen((char*)number));
}
}
else // Set
{
memcpy(number, pack->data, pack->data_len);
if(req_ecall_sms_num_set(cli_info->sim_id, cli_info->port, number, &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 ecall sms number fail.");
}
else
{
ril_rsp_pack_send(cli_info->sim_id, cli_info->port, cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
}
}
break;
}
case RIL_MSG_ID_ECALL_MUTESPK:
{
if(pack->data_len == 0 || pack->data == NULL)
{
err = MBTK_RIL_ERR_UNSUPPORTED;
}
else // Set mute state.
{
uint8 mute = pack->data[0];
if(pack->data_len != sizeof(uint8) || (mute != 0 && mute != 1))
{
err = MBTK_RIL_ERR_REQ_PARAMETER;
LOG("Set spk mute parameter error.");
break;
}
if(req_ecall_spkmute_set(cli_info->sim_id, cli_info->port, mute, &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 spk mute state fail.");
}
else
{
ril_rsp_pack_send(cli_info->sim_id, cli_info->port, cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
}
}
break;
}
case RIL_MSG_ID_ECALL_DSP_GAIN: // mbtk_ecall_gain_info_t
{
if(pack->data_len == 0 || pack->data == NULL)
{
err = MBTK_RIL_ERR_UNSUPPORTED;
}
else // Set
{
mbtk_ecall_gain_info_t *gain_info = (mbtk_ecall_gain_info_t *)pack->data;
if(req_ecall_gain_set(cli_info->sim_id, cli_info->port, gain_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;
}
LOGE("Set ecall gain fail.");
}
else
{
ril_rsp_pack_send(cli_info->sim_id, cli_info->port, 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;
}