blob: fe9d3745072edd99e5cc4fe21886e6b4b7a28479 [file] [log] [blame]
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <pthread.h>
#include <sys/epoll.h>
#include <fcntl.h>
#include <signal.h>
#include "mbtk_type.h"
#include "mbtk_ril.h"
#include "atchannel.h"
#include "at_tok.h"
#include "mbtk_utils.h"
#include "ril_info.h"
void ril_rsp_pack_send(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);
/*
ATDXXXXXXX;
OK
*/
static int req_call_start(mbtk_sim_type_enum sim_id, ATPortType_enum port, char *phont_number, int *cme_err)
{
ATResponse *response = NULL;
// int tmp_int;
// char *tmp_str = NULL;
char cmd[100] = {0};
sprintf(cmd, "ATD%s;", phont_number);
int err = at_send_command(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+CHLD=2
OK
*/
static int req_answer_call(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+CHLD=2", &response);
if (err < 0 || response->success == 0){
*cme_err = at_get_cme_error(response);
goto exit;
}
exit:
at_response_free(response);
return err;
}
/*
ATH
OK
*/
static int req_hangup_call(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), "ATH", &response);
if (err < 0 || response->success == 0){
*cme_err = at_get_cme_error(response);
goto exit;
}
exit:
at_response_free(response);
return err;
}
/*
AT+CHLD=1x
OK
*/
static int req_hangup_a_call(mbtk_sim_type_enum sim_id, ATPortType_enum port, int phone_id, int *cme_err)
{
ATResponse *response = NULL;
char cmd[100] = {0};
sprintf(cmd, "AT+CHLD=1%d", phone_id);
int err = at_send_command(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+CHLD=0
OK
*/
static int req_hangup_waiting_or_background_call(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+CHLD=0", &response);
if (err < 0 || response->success == 0){
*cme_err = at_get_cme_error(response);
goto exit;
}
exit:
at_response_free(response);
return err;
}
/*
AT+CHLD=1
OK
*/
static int req_hangup_foreground_resume_background_call(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+CHLD=1", &response);
if (err < 0 || response->success == 0){
*cme_err = at_get_cme_error(response);
goto exit;
}
exit:
at_response_free(response);
return err;
}
/*
AT+CLCC
OK
*/
static int req_waitin_call(mbtk_sim_type_enum sim_id, ATPortType_enum port, mbtk_call_info_t *reg, int *cme_err)
{
ATResponse *response = NULL;
int tmp_int;
char *tmp_str = NULL;
int err = at_send_command_multiline(portType_2_portId(sim_id, port), "AT+CLCC", "+CLCC:", &response);
if (err < 0 || response->success == 0){
*cme_err = at_get_cme_error(response);
goto exit;
}
if(response->success == 1 && !response->p_intermediates)
{
reg->call_wait = 0;
goto exit;
}
reg->call_wait = 1;
char *line = response->p_intermediates->line;
err = at_tok_start(&line);
if (err < 0)
{
goto exit;
}
err = at_tok_nextint(&line, &tmp_int); // dir1
if (err < 0)
{
goto exit;
}
reg->dir1 = (uint8)tmp_int;
err = at_tok_nextint(&line, &tmp_int);// dir
if (err < 0)
{
goto exit;
}
reg->dir = (uint8)tmp_int;
err = at_tok_nextint(&line, &tmp_int);// state
if (err < 0)
{
goto exit;
}
reg->state = (uint8)tmp_int;
err = at_tok_nextint(&line, &tmp_int);// mode
if (err < 0)
{
goto exit;
}
reg->mode = (uint8)tmp_int;
err = at_tok_nextint(&line, &tmp_int);// mpty
if (err < 0)
{
goto exit;
}
reg->mpty = (uint8)tmp_int;
err = at_tok_nextstr(&line, &tmp_str); // phone_number
if (err < 0)
{
goto exit;
}
memcpy(reg->phone_number, tmp_str, strlen(tmp_str));
err = at_tok_nextint(&line, &tmp_int);// tpye
if (err < 0)
{
goto exit;
}
reg->type = (uint8)tmp_int;
exit:
at_response_free(response);
return err;
}
/*
AT+CMUT?
+CMUT: 0
OK
*/
static int req_mute_get(mbtk_sim_type_enum sim_id, ATPortType_enum port, int *state, int *cme_err)
{
ATResponse *response = NULL;
int tmp_int;
int err = at_send_command_singleline(portType_2_portId(sim_id, port), "AT+CMUT?", "+CMUT:", &response);
if (err < 0 || response->success == 0 || !response->p_intermediates){
*cme_err = at_get_cme_error(response);
goto exit;
}
char *line = response->p_intermediates->line;
err = at_tok_start(&line);
if (err < 0)
{
goto exit;
}
err = at_tok_nextint(&line, &tmp_int);
if (err < 0)
{
goto exit;
}
*state = tmp_int;
exit:
at_response_free(response);
return err;
}
/*
AT+CMUT=0;
OK
*/
static int req_mute_set(mbtk_sim_type_enum sim_id, ATPortType_enum port, int state, int *cme_err)
{
ATResponse *response = NULL;
char cmd[100] = {0};
sprintf(cmd, "AT+CMUT=%d", state);
LOG("Set the mute command is = %s.\n", cmd);
int err = at_send_command(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+VTS=0; //0, 1, ..., 9, A, B, C, D, *, #
OK
*/
static int req_dtmf_set(mbtk_sim_type_enum sim_id, ATPortType_enum port, mbtk_call_dtmf_info_t *state, int *cme_err)
{
ATResponse *response = NULL;
char cmd[100] = {0};
sprintf(cmd, "AT+VTS=%c,%d", state->character, state->duration);
LOG("Set the DTMF command is = %s.\n", cmd);
int err = at_send_command(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_centric_get(mbtk_sim_type_enum sim_id, ATPortType_enum port, int *state, int *cme_err)
{
ATResponse *response = NULL;
int tmp_int = 0;
int err = at_send_command_singleline(portType_2_portId(sim_id, port), "AT+CEUS?", "+CEUS:", &response);
if (err < 0 || response->success == 0 || !response->p_intermediates){
*cme_err = at_get_cme_error(response);
goto exit;
}
char *line = response->p_intermediates->line;
err = at_tok_start(&line);
if (err < 0)
{
goto exit;
}
err = at_tok_nextint(&line, &tmp_int);
if (err < 0)
{
goto exit;
}
*state = tmp_int;
exit:
at_response_free(response);
return err;
}
/*
AT+CMUT=0;
OK
*/
static int req_centric_set(mbtk_sim_type_enum sim_id, ATPortType_enum port, int state, int *cme_err)
{
ATResponse *response = NULL;
char cmd[100] = {0};
sprintf(cmd, "AT+CEUS=%d", state);
LOG("Set the centric command is = %s.\n", cmd);
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 call_pack_req_process(sock_cli_info_t* cli_info, ril_msg_pack_info_t* pack)
{
mbtk_ril_err_enum err = MBTK_RIL_ERR_SUCCESS;
int cme_err = MBTK_RIL_ERR_CME_NON;
switch(pack->msg_id)
{
case RIL_MSG_ID_CALL_START: // <string> phone number
{
if(pack->data_len == 0 || pack->data == NULL)
{
err = MBTK_RIL_ERR_UNSUPPORTED;
}
else // Set
{
char *pn = (char*)(pack->data);
if(req_call_start(cli_info->sim_id, cli_info->port, pn, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
{
if(cme_err != MBTK_RIL_ERR_CME_NON) {
err = MBTK_RIL_ERR_CME + cme_err;
} else {
err = MBTK_RIL_ERR_UNKNOWN;
}
LOG("ATD fail.");
}
else
{
ril_rsp_pack_send(cli_info->sim_id, cli_info->port, cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
}
}
break;
}
case RIL_MSG_ID_CALL_ANSWER:
{
if(pack->data_len == 0 || pack->data == NULL)
{
if(req_answer_call(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("Answer call 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;
LOG("Answer call fail. NO DATA\n");
}
break;
}
case RIL_MSG_ID_CALL_HANGUP:
{
if(pack->data_len == 0 || pack->data == NULL)
{
if(req_hangup_call(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("Hang up call 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;
LOG("Hang up call fail.");
}
break;
}
case RIL_MSG_ID_CALL_HANGUP_A:
{
if(pack->data_len == 0 || pack->data == NULL)
{
err = MBTK_RIL_ERR_UNSUPPORTED;
LOG("Hang up a call fail.");
}
else
{
uint8 phone_id = *(pack->data);
if(req_hangup_a_call(cli_info->sim_id, cli_info->port, phone_id, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
{
if(cme_err != MBTK_RIL_ERR_CME_NON) {
err = MBTK_RIL_ERR_CME + cme_err;
} else {
err = MBTK_RIL_ERR_UNKNOWN;
}
LOG("Hang up a call fail.");
}
else
{
ril_rsp_pack_send(cli_info->sim_id, cli_info->port, cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
}
}
break;
}
case RIL_MSG_ID_CALL_HANGUP_B:
{
if(pack->data_len == 0 || pack->data == NULL)
{
if(req_hangup_waiting_or_background_call(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("Hang up waiting_or_background call 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
{
err = MBTK_RIL_ERR_UNSUPPORTED;
LOG("Hang up waiting_or_background call fail.");
}
break;
}
case RIL_MSG_ID_CALL_HANGUP_C:
{
if(pack->data_len == 0 || pack->data == NULL)
{
if(req_hangup_foreground_resume_background_call(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("Hang up waiting_or_background call 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
{
err = MBTK_RIL_ERR_UNSUPPORTED;
LOG("Hang up waiting_or_background call fail.");
}
break;
}
case RIL_MSG_ID_CALL_WAITIN:
{
if(pack->data_len == 0 || pack->data == NULL)
{
mbtk_call_info_t reg;
memset(&reg, 0, sizeof(mbtk_call_info_t));
if(req_waitin_call(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("Wait incoing call fail.");
}
else
{
ril_rsp_pack_send(cli_info->sim_id, cli_info->port, cli_info->fd, pack->msg_id, pack->msg_index, &reg, sizeof(mbtk_call_info_t));
}
}
else // Set
{
err = MBTK_RIL_ERR_UNSUPPORTED;
LOG("Wait incoing call fail.");
}
break;
}
case RIL_MSG_ID_CALL_MUTE:
{
if(pack->data_len == 0 || pack->data == NULL) // Get VoLTE state.
{
int state;
if(req_mute_get(cli_info->sim_id, cli_info->port, &state, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
{
if(cme_err != MBTK_RIL_ERR_CME_NON) {
err = MBTK_RIL_ERR_CME + cme_err;
} else {
err = MBTK_RIL_ERR_UNKNOWN;
}
LOG("Get mute state fail.");
}
else
{
ril_rsp_pack_send(cli_info->sim_id, cli_info->port, cli_info->fd, pack->msg_id, pack->msg_index, &state, sizeof(uint8));
}
}
else // Set mute state.
{
uint8 on = *(pack->data);
if(pack->data_len != sizeof(uint8) || (on != 0 && on != 1))
{
err = MBTK_RIL_ERR_REQ_PARAMETER;
LOG("Set mute parameter error.");
break;
}
if(req_mute_set(cli_info->sim_id, cli_info->port, on, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
{
if(cme_err != MBTK_RIL_ERR_CME_NON) {
err = MBTK_RIL_ERR_CME + cme_err;
} else {
err = MBTK_RIL_ERR_UNKNOWN;
}
LOG("Set mute state fail.");
}
else
{
ril_rsp_pack_send(cli_info->sim_id, cli_info->port, cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
}
}
break;
}
case RIL_MSG_ID_CALL_DTMF:
{
if(pack->data_len == 0 || pack->data == NULL)
{
err = MBTK_RIL_ERR_UNSUPPORTED;
LOG("Wait incoing call fail.");
}
else // Set
{
mbtk_call_dtmf_info_t *reg = (mbtk_call_dtmf_info_t *)pack->data;
if(req_dtmf_set(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("Wait incoing call 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_CALL_CENTRIC:
{
if(pack->data_len == 0 || pack->data == NULL) // Get VoLTE state.
{
int state;
if(req_centric_get(cli_info->sim_id, cli_info->port, &state, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
{
if(cme_err != MBTK_RIL_ERR_CME_NON) {
err = MBTK_RIL_ERR_CME + cme_err;
} else {
err = MBTK_RIL_ERR_UNKNOWN;
}
LOG("Get mute state fail.");
}
else
{
ril_rsp_pack_send(cli_info->sim_id, cli_info->port, cli_info->fd, pack->msg_id, pack->msg_index, &state, sizeof(int));
}
}
else // Set mute state.
{
uint8 on = *(pack->data);
if(pack->data_len != sizeof(uint8) || (on != 0 && on != 1))
{
err = MBTK_RIL_ERR_REQ_PARAMETER;
LOG("Set mute parameter error.");
break;
}
if(req_centric_set(cli_info->sim_id, cli_info->port, on, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
{
if(cme_err != MBTK_RIL_ERR_CME_NON) {
err = MBTK_RIL_ERR_CME + cme_err;
} else {
err = MBTK_RIL_ERR_UNKNOWN;
}
LOG("Set mute state fail.");
}
else
{
ril_rsp_pack_send(cli_info->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;
}