blob: 97376a7bcd4dbe25621bad59c321ee7012dd4eaa [file] [log] [blame]
/* Copyright Statement:
*
* This software/firmware and related documentation ("MediaTek Software") are
* protected under relevant copyright laws. The information contained herein
* is confidential and proprietary to MediaTek Inc. and/or its licensors.
* Without the prior written permission of MediaTek inc. and/or its licensors,
* any reproduction, modification, use or disclosure of MediaTek Software,
* and information contained herein, in whole or in part, shall be strictly prohibited.
*/
/* MediaTek Inc. (C) 2010. All rights reserved.
*
* BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
* THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
* CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
* SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
* STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
* CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
*
* The following software/firmware and/or related documentation ("MediaTek Software")
* have been modified by MediaTek Inc. All revisions are subject to any receiver's
* applicable license agreements with MediaTek Inc.
*/
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <signal.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <vendor-ril/telephony/ril.h>
#include "common.h"
#include "util/utils.h"
#include "atci/ATCI.h"
#include "atci_util.h"
#include "atci_at_util.h"
#include "Radio_capability_switch_util.h"
#ifdef ATCI_PARSE
#include "atci_sys_cmd.h"
#include "atci_ss_cmd.h"
#include "atci_cc_cmd.h"
#endif
struct sockaddr_un atci_server_addr;
//struct sockaddr_in atci_server_addr;
//struct sockaddr_un atci_client_addr;
#undef LOG_TAG
#define LOG_TAG "DEMO_ATCI"
#if ATCI_ENABLE_RESPONSE
char Respose_buf[RESPONSE_BUF_SIZE];
#endif
#ifdef ATCI_PARSE
int atci_dispatch_cmd(char *line);
#endif
int atci_server_socket_fd, atci_client_connect;
namespace android {
extern int s_registerCalled;
}
#define SOCKET_ZERO 0
#define SOCKET_SUCC 1
#define SOCKET_FAIL -1
static int ATCI_Token = 0;
int ATCISupport(int request) {
switch (request) {
case TELEPHONY_REQUEST_SET_CALL_FORWARD:
return 1;
case TELEPHONY_REQUEST_SET_CALL_WAITING:
return 1;
case TELEPHONY_REQUEST_SET_CALL_BARRING:
return 1;
case TELEPHONY_REQUEST_DIAL:
return 1;
case TELEPHONY_REQUEST_DROP_CONF_CALL_MEMBER:
return 1;
case TELEPHONY_REQUEST_FLIGHT:
return 1;
case TELEPHONY_REQUEST_SET_MUTE:
return 1;
case TELEPHONY_REQUEST_MERGE_CONF_CALLS:
return 1;
case TELEPHONY_REQUEST_CREATE_IMS_CONF_CALL:
return 1;
case TELEPHONY_REQUEST_DIAL_WITH_SIP_URI:
return 1;
default:
return 0;
}
}
const char * ATCIReqRspToString(int request) {
switch (request) {
case TELEPHONY_REQUEST_SET_CALL_FORWARD:
return "SET_CALL_FORWARD";
case TELEPHONY_REQUEST_SET_CALL_WAITING:
return "SET_CALL_WAITING";
case TELEPHONY_REQUEST_SET_CALL_BARRING:
return "SET_CALL_BARRING";
case TELEPHONY_REQUEST_DIAL:
return "DIAL";
case TELEPHONY_REQUEST_DROP_CONF_CALL_MEMBER:
return "DROP_CONF_CALL_MEMBER";
case TELEPHONY_REQUEST_FLIGHT:
return "FLIGHT";
case TELEPHONY_RESPONSE_FLIGHT:
return "RSP_FLIGHT";
case TELEPHONY_REQUEST_SET_MUTE:
return "SET_MUTE";
case TELEPHONY_REQUEST_MERGE_CONF_CALLS:
return "MERGE_CONF_CALLS";
case TELEPHONY_REQUEST_CREATE_IMS_CONF_CALL:
return "CREATE_IMS_CONF_CALL";
case TELEPHONY_REQUEST_DIAL_WITH_SIP_URI:
return "DIAL_WITH_SIP_URI";
default:
return "<unknown request>";
}
}
//return requestNumber
int ATCIParserRequest(int request) {
//char* cPoint = buf;
//int reqNum = 0;
RLOGD("ATCI Parser request number start!");
//memcpy(&reqNum,cPoint,sizeof(int));
RLOGD("Request is %d,%s", request, ATCIReqRspToString(request));
if (ATCISupport(request) != 1)
return -1;
return request;
}
int MappingATCI2RIL(int reqNum) {
int request = 0;
switch (reqNum) {
case TELEPHONY_REQUEST_SET_CALL_FORWARD:
request = RIL_REQUEST_SET_CALL_FORWARD;
break;
case TELEPHONY_REQUEST_SET_CALL_WAITING:
request = RIL_REQUEST_SET_CALL_WAITING;
break;
case TELEPHONY_REQUEST_SET_CALL_BARRING:
request = RIL_REQUEST_SET_FACILITY_LOCK;
break;
case TELEPHONY_REQUEST_DIAL:
request = RIL_REQUEST_DIAL;
break;
case TELEPHONY_REQUEST_DROP_CONF_CALL_MEMBER:
request = RIL_REQUEST_REMOVE_IMS_CONFERENCE_CALL_MEMBER;
break;
case TELEPHONY_REQUEST_FLIGHT:
request = RIL_REQUEST_RADIO_POWER;
break;
case TELEPHONY_REQUEST_SET_MUTE:
request = RIL_REQUEST_SET_MUTE;
break;
case TELEPHONY_REQUEST_MERGE_CONF_CALLS:
request = RIL_REQUEST_CONFERENCE;
break;
case TELEPHONY_REQUEST_CREATE_IMS_CONF_CALL:
request = RIL_REQUEST_CONFERENCE_DIAL;
break;
case TELEPHONY_REQUEST_DIAL_WITH_SIP_URI:
request = RIL_REQUEST_DIAL_WITH_SIP_URI;
break;
default:
request = -1;
}
return request;
}
int MappingParameter(int reqNum, int length, char* data, char* buf,
char** argv) {
int argc = 1;
char* cPoint;
cPoint = buf;
switch (reqNum) {
case TELEPHONY_REQUEST_SET_CALL_FORWARD: {
if (length != sizeof(telephonyRequestSetCallForward)) {
RLOGD("Set_Call_Forward data error!");
return -1;
}
telephonyRequestSetCallForward tempSCF;
memset(&tempSCF, 0, sizeof(tempSCF));
memcpy(&tempSCF, data, length);
//cmd parameter sequence: status, reason, number, time_seconds, service_class; other not need.
argv[1] = cPoint; //status
cPoint += sizeof(tempSCF.status);
sprintf(argv[1], "%d", tempSCF.status);
argv[2] = cPoint; //reason
cPoint += sizeof(tempSCF.reason);
sprintf(argv[2], "%d", tempSCF.reason);
argv[5] = cPoint; //service_class
cPoint += sizeof(tempSCF.service_class);
sprintf(argv[5], "%d", tempSCF.service_class);
argv[6] = cPoint; //toa
cPoint += sizeof(tempSCF.toa);
sprintf(argv[6], "%d", tempSCF.toa);
argv[3] = cPoint; //number
cPoint += sizeof(tempSCF.number);
sprintf(argv[3], "%s", tempSCF.number);
argv[4] = cPoint; //time_seconds
sprintf(argv[4], "%d", tempSCF.time_seconds);
argc += 5;
RLOGD(
"TELEPHONY_REQUEST_SET_CALL_FORWARD status(%s) reason(%s) number(%s) time_seconds(%s) service_class(%s) --toa(%s)",
argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]);
}
break;
case TELEPHONY_REQUEST_SET_CALL_WAITING: {
if (length != sizeof(telephonyRequestSetCallWaiting)) {
RLOGD("Set_Call_Waiting data error!");
return -1;
}
telephonyRequestSetCallWaiting tempSCW;
memset(&tempSCW, 0, sizeof(tempSCW));
memcpy(&tempSCW, data, length);
//cmd parameter sequence: statue, service_code
argv[1] = cPoint; //status
cPoint += sizeof(tempSCW.status);
sprintf(argv[1], "%d", tempSCW.status);
argv[2] = cPoint; //service_class
sprintf(argv[2], "%d", tempSCW.service_class);
argc += 2;
RLOGD("TELEPHONY_REQUEST_SET_CALL_WAITING status(%s) service_class(%s)",
argv[1], argv[2]);
}
break;
case TELEPHONY_REQUEST_SET_CALL_BARRING: {
if (length != sizeof(telephonyRequestSetCallBarring)) {
RLOGD("Set_Call_Barring data error!");
return -1;
}
telephonyRequestSetCallBarring tempSCB;
memset(&tempSCB, 0, sizeof(tempSCB));
memcpy(&tempSCB, data, length);
//cmd parameter sequence: facility, password, serviceclass,enable; other not need.
argv[4] = cPoint; //status
cPoint += sizeof(tempSCB.status);
sprintf(argv[4], "%d", tempSCB.status);
argv[1] = cPoint; //facility
cPoint += sizeof(tempSCB.facility);
sprintf(argv[1], "%s", tempSCB.facility);
argv[2] = cPoint; //password
cPoint += sizeof(tempSCB.password);
sprintf(argv[2], "%s", tempSCB.password);
argv[3] = cPoint; //serviceclass
cPoint += sizeof(tempSCB.serviceClass);
sprintf(argv[3], "%d", tempSCB.serviceClass);
argc += 4;
RLOGD(
"TELEPHONY_REQUEST_SET_CALL_Barring facility(%s) password(%s) service_class(%s) status(enable)(%s)",
argv[1], argv[2], argv[3], argv[4]);
}
break;
case TELEPHONY_REQUEST_DIAL: {
if (length != sizeof(telephonyRequestDial)) {
RLOGD("Request dail data error!");
return -1;
}
telephonyRequestDial tempDIAL;
memset(&tempDIAL, 0, sizeof(tempDIAL));
memcpy(&tempDIAL, data, length);
//cmd parameter sequence: callnumber, clir;
argv[2] = cPoint; //clir
cPoint += sizeof(tempDIAL.clir);
sprintf(argv[2], "%d", tempDIAL.clir);
argv[1] = cPoint; //phonyNumber
sprintf(argv[1], "%s", tempDIAL.phonyNumber);
argc += 2;
RLOGD("TELEPHONY_REQUEST_DIAL CLIR(%s) PhoneNumber(%s)", argv[2], argv[1]);
}
break;
case TELEPHONY_REQUEST_DROP_CONF_CALL_MEMBER: {
if (length != sizeof(telephonyRequestDropConfCallMember)) {
RLOGD("DropConfCallMember data error!");
return -1;
}
telephonyRequestDropConfCallMember tempDCCM;
memset(&tempDCCM, 0, sizeof(tempDCCM));
memcpy(&tempDCCM, data, length);
//cmd parameter sequence: callId, addr, ToAdd; other not need.
argv[1] = cPoint; //ConfCallID
cPoint += sizeof(tempDCCM.confCallID);
sprintf(argv[1], "%d", tempDCCM.confCallID);
argv[2] = cPoint; //phonyNumber
cPoint += sizeof(tempDCCM.phonyNumber);
sprintf(argv[2], "%d", tempDCCM.phonyNumber);
argv[3] = cPoint; //callIDToAdd
sprintf(argv[3], "%d", tempDCCM.callIDToAdd);
argc += 3;
RLOGD(
"TELEPHONY_REQUEST_DROP_CONF_CALL_MEMBER ConfCallID(%s) phonyNumber(%s) callIDToAdd(%s)",
argv[1], argv[2], argv[3]);
}
break;
case TELEPHONY_REQUEST_FLIGHT: {
if (length != sizeof(telephonyRequestFlight)) {
RLOGD("Request flight data error!");
return -1;
}
telephonyRequestFlight tempFT;
memset(&tempFT, 0, sizeof(tempFT));
memcpy(&tempFT, data, length);
//cmd parameter sequence: mode.
argv[1] = cPoint; //flightModeOn
sprintf(argv[1], "%d", (tempFT.flightModeOn == 1 ? 0 : 1));
argc += 1;
RLOGD("TELEPHONY_REQUEST_FLIGHT flight Mode is %s-->(%s)",
(tempFT.flightModeOn == 1 ? "On" : "Off"), argv[1]);
}
break;
case TELEPHONY_REQUEST_SET_MUTE: {
if (length != sizeof(telephonyRequestSetMute)) {
RLOGD("Request flight data error!");
return -1;
}
telephonyRequestSetMute tempSM;
memset(&tempSM, 0, sizeof(tempSM));
memcpy(&tempSM, data, length);
//cmd parameter sequence: mode.
argv[1] = cPoint; //isMute
sprintf(argv[1], "%d", tempSM.isMute);
argc += 1;
RLOGD("TELEPHONY_REQUERT_SET_MUTE isMute(%s)", argv[1]);
}
break;
case TELEPHONY_REQUEST_MERGE_CONF_CALLS: {
RLOGD("TELEPHONY_REQUERT_MERGE_CONF_CALLS (No Parm.)");
}
break;
case TELEPHONY_REQUEST_CREATE_IMS_CONF_CALL: {
//cmd parameter sequence: DialMethod, ParticipantsNumber, addresses, clir;
argv[1] = cPoint; //DialMethod
sprintf(argv[1], "%d", 0);
cPoint += sizeof(int);
argv[2] = cPoint; //ParticipantsNumber
sprintf(argv[2], "%d", 0);
cPoint += sizeof(int);
//no address
argv[3] = cPoint; //CLIR
sprintf(argv[2], "%s", "0");
argc += 3;
RLOGD(
"TELEPHONY_REQUEST_CREATE_IMS_CONF_CALL dialMethod(%d) PhoneNumber(%d),clir(%s)",
argv[1], argv[2], argv[3]);
}
break;
case TELEPHONY_REQUEST_DIAL_WITH_SIP_URI: {
if (length != sizeof(telephonyRequestDial)) //struct with the same as DIAL
{
RLOGD("Request DialWithSipUri data error!");
return -1;
}
telephonyRequestDial tempDWSU;
memset(&tempDWSU, 0, sizeof(tempDWSU));
memcpy(&tempDWSU, data, length);
//cmd parameter sequence: address, clir;
argv[2] = cPoint; //clir
cPoint += sizeof(tempDWSU.clir);
sprintf(argv[2], "%d", tempDWSU.clir);
argv[1] = cPoint; //address
sprintf(argv[1], "%s", tempDWSU.phonyNumber);
argc += 2;
RLOGD("TELEPHONY_REQUEST_DIAL_WITH_SIP_URI CLIR(%d) PhoneNumber(%s)",
argv[2], argv[1]);
}
break;
default:
break;
}
return argc;
}
void ATCIResponse(int token, int error, char* data, int reqNum)
{
//int reqNum;
char buf[64];
if(token&ATCI_TOKEN_MARK != ATCI_TOKEN_MARK) {
if(token == 0 && data == NULL && reqNum == 0) {
RLOGD("AT%RESTART: %d", error);
} else {
RLOGE("ATCIRespnse Error, Token not ATCI\n");
}
} else {
RLOGD("token is %d,%s",reqNum,android::requestToString(reqNum));
}
memset(buf, 0, sizeof(buf));
if(error == 1){
sprintf(buf,"%s","ERROR");
} else {
sprintf(buf,"%s","OK");
}
int len_s = send(atci_client_connect, buf, strlen(buf), 0);
RLOGD("Response Buf is %s, send length is %d",buf,len_s);
}
#ifdef ATCI_PARSE
int acti_cmd_recv(int fd, char *buf, int len) {
int ret = 0;
fd_set rfds;
//FD_CLR(fd, &rfds);
FD_SET(fd, &rfds);
ret = select(fd + 1, &rfds, NULL, NULL, NULL);
if (ret <= 0) {
RLOGE("acti_cmd_recv select error, ret=%d, error=%s(%d),fd=%d", ret,
strerror(errno), errno, fd);
return SOCKET_FAIL;
}
if (FD_ISSET(fd, &rfds)) {
ret = recv(fd, buf, len, 0);
if (ret < 0) {
RLOGE("acti_cmd_recv select error, ret=%d, error=%s(%d),fd=%d", ret,
strerror(errno), errno, fd);
return SOCKET_FAIL;
} else if (ret == 0) {
RLOGE("acti_cmd_recv recv error, ret=%d, error=%s(%d),fd=%d", ret,
strerror(errno), errno, fd);
return SOCKET_ZERO;
} else {
//buf[ret] = '\0';
}
}
return SOCKET_SUCC;
}
#endif
int atci_sock_recv(int fd, char *buf, int len) {
int ret = 0;
int offset = 0;
while (offset < len) {
fd_set rfds;
FD_SET(fd, &rfds);
ret = select(fd + 1, &rfds, NULL, NULL, NULL);
if (ret < 0) {
if (errno == EINTR || errno == EAGAIN) {
continue;
}
RLOGE("atci_sock_recv select error, ret=%d, error=%s(%d),fd=%d", ret,
strerror(errno), errno, fd);
return SOCKET_FAIL;
} else if (ret == 0) {
continue;
}
if (FD_ISSET(fd, &rfds)) {
ret = recv(fd, buf + offset, len - offset, 0);
if (ret < 0) {
RLOGE("atci_sock_recv recv error, ret=%d, error=%s(%d),fd=%d", ret,
strerror(errno), errno, fd);
return SOCKET_FAIL;
} else if (ret == 0) {
RLOGE("atci_sock_recv recv error, ret=%d, error=%s(%d),fd=%d", ret,
strerror(errno), errno, fd);
return SOCKET_ZERO;
}
offset += ret;
}
}
return SOCKET_SUCC;
}
void sendAtciRequest(int request, char* reqStr, int argc, char** argv) {
//for dsds, should close two slot radio.
if(utils::is_support_dsds() && (request == RIL_REQUEST_RADIO_POWER)){
int enable = atoi(argv[1])? 1 : 0;
for(int i = 0; i < 2; i++) {
//For GCF, enhance AT%Flight=0. only SIM is inserted, radio can open.
if(enable){
if (Radio_capability_switch_util::is_sim_inserted(i)) {
RequestInfo* pRI = (RequestInfo*) (calloc(1, sizeof(RequestInfo)));
pRI->socket_id = (RIL_SOCKET_ID)i;
android::ATCIRequest(request, reqStr, (void*) (pRI), argc, argv);
} {
RLOGD("ignore radio power on command because of absent SIM Card");
}
} else {
RequestInfo* pRI = (RequestInfo*) (calloc(1, sizeof(RequestInfo)));
pRI->socket_id = (RIL_SOCKET_ID)i;
android::ATCIRequest(request, reqStr, (void*) (pRI), argc, argv);
}
}
} else {
RequestInfo* pRI = (RequestInfo*) (calloc(1, sizeof(RequestInfo)));
android::ATCIRequest(request, reqStr, (void*) (pRI), argc, argv);
}
return;
}
void * StartATCISocket(void *param) {
RLOGD("StartATCISocket start\n");
socklen_t server_len, client_len;
struct sockaddr_un atci_client_addr;
//struct sockaddr_in atci_client_addr;
char parser_buf[SOCKET_BUF_SIZE];
char *argv[ATCI_MAX_ARGS];
int argc = 0;
prctl(PR_SET_NAME, (unsigned long) "ATCI_Thr");
/* create socket */
unlink(ATCI_SERVER_SOCKET);
atci_server_socket_fd = socket(AF_UNIX, SOCK_STREAM, 0);
//atci_server_socket_fd = socket(AF_INET, SOCK_STREAM, 0);
if (atci_server_socket_fd == -1) {
RLOGE("Create ATCI Socket Failed:");
exit(1);
}
memset(&atci_server_addr, 0, sizeof(atci_server_addr));
atci_server_addr.sun_family = AF_UNIX;
//atci_server_addr.sin_family = AF_INET;
//atci_server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
//atci_server_addr.sin_port = htons(10004);
strcpy(atci_server_addr.sun_path, ATCI_SERVER_SOCKET);
server_len = sizeof(atci_server_addr);
/* bind socket port*/
if (-1
== bind(atci_server_socket_fd, (struct sockaddr *) &atci_server_addr,
server_len)) {
RLOGE("Server Bind Failed:");
exit(1);
}
if (listen(atci_server_socket_fd, 1) == -1) {
RLOGE("listen fail!");
close(atci_server_socket_fd);
exit(1);
}
#ifdef ATCI_PARSE
DbgMsg("init cmd handle");
if(/*atci_generic_init(NULL)||*/atci_cc_init(NULL)||atci_ss_init(NULL)||atci_sys_init(NULL)) {
ErrMsg("module init function error,exit");
exit(-1);
}
#endif
TryNewLink:
client_len = sizeof(atci_client_addr);
int conn = accept(atci_server_socket_fd,
(struct sockaddr *) &atci_client_addr, &client_len);
if (conn <= 0) {
RLOGE("accept error!");
close(conn);
exit(1);
}
RLOGD("Accept a client , fd is %d", conn);
atci_client_connect = conn;
socketData recv_data;
int ret;
/* tranlate data */
while (true) {
if (!android::s_registerCalled) {
sleep(1);
continue;
}
#ifdef ATCI_PARSE
memset(parser_buf, 0, sizeof(parser_buf));
ret = acti_cmd_recv(conn, parser_buf, SOCKET_BUF_SIZE);
if (ret < 0) {
RLOGE("receive CMD error");
continue;
} else if (ret == SOCKET_ZERO) {
RLOGE("maybe client socket closed 1. retry new link!");
goto TryNewLink;
}
atci_dispatch_cmd(parser_buf);
#else
memset(parser_buf, 0, sizeof(parser_buf));
memset(&recv_data, 0, sizeof(socketData));
//receive_ID
ret = atci_sock_recv(conn, (char*) &recv_data.requestId,
sizeof(recv_data.requestId));
if (ret < 0) {
RLOGE("reveive request id is error");
continue;
} else if (ret == SOCKET_ZERO) {
RLOGE("maybe client socket closed 1. retry new link!");
goto TryNewLink;
}
RLOGE("reveive request id is %d", recv_data.requestId);
//receive_length
ret = atci_sock_recv(conn, (char*) &recv_data.datalen,
sizeof(recv_data.datalen));
if (ret < 0) {
RLOGE("reveive request lenth is error");
continue;
} else if (ret == SOCKET_ZERO) {
RLOGE("maybe client socket closed 2. retry new link!");
goto TryNewLink;
}
RLOGE("reveive request lenth is %d", recv_data.datalen);
//receive_data
recv_data.data = (char*) calloc(recv_data.datalen, 1);
if (NULL == recv_data.data) {
RLOGE("alloc mem error");
continue;
}
ret = atci_sock_recv(conn, recv_data.data, recv_data.datalen);
if (ret < 0) {
RLOGE("reveive request data is error");
free(recv_data.data);
recv_data.data = NULL;
continue;
} else if (ret == SOCKET_ZERO) {
RLOGE("maybe client socket closed 3. retry new link!");
free(recv_data.data);
recv_data.data = NULL;
goto TryNewLink;
}
int reqNum = ATCIParserRequest(recv_data.requestId);
if (reqNum <= 0) {
RLOGE("ATCI command is error!");
continue;
}
int request = MappingATCI2RIL(reqNum);
char reqStr[RIL_REQUEST_STRING_LENGTH];
memcpy(reqStr, request2RILStr(request),
strlen(request2RILStr(request)) + 1);
RLOGD("request is %s", reqStr);
argc = MappingParameter(reqNum, recv_data.datalen, recv_data.data,
parser_buf, argv);
if (argc <= 0) {
RLOGE("ATCI command is error!");
continue;
}
free(recv_data.data);
recv_data.data = NULL;
sendAtciRequest(request, reqStr, argc, argv);
#endif
};
RLOGD("close socket fd!");
close(atci_server_socket_fd);
RLOGD("exist start ATCI socket thread, errno:%d", errno);
// kill self to restart on error
kill(0, SIGKILL);
return NULL;
}
#ifdef ATCI_PARSE
char* atci_get_cmd_prefix(char *line) {
int buf_len;
char *prefix;
char *end_ptr;
if (NULL == line) {
RLOGD("input is null");
return NULL;
}
end_ptr = line;
while (!ATCI_IS_CAHR(*end_ptr, ATCI_EQUAL)
&& !ATCI_IS_CAHR(*end_ptr, ATCI_QUESTION_MARK)
&& !ATCI_IS_CAHR(*end_ptr, ATCI_END_CHAR)
&& !ATCI_IS_CAHR(*end_ptr, ATCI_CR) && !ATCI_IS_CAHR(*end_ptr, ATCI_LF)) {
end_ptr++;
}
buf_len = end_ptr - line + 1;
prefix = (char *) calloc(buf_len, 1);
if (prefix) {
int i;
char *in_ptr = line;
char *out_ptr = prefix;
for (i = 0; i < buf_len - 1; i++) {
if (!ATCI_IS_CAHR(*in_ptr, ATCI_SPACE)) {
*out_ptr = ATCI_UPPER_TO_LOWER(*in_ptr);
out_ptr++;
}
in_ptr++;
}
*out_ptr = ATCI_END_CHAR;
}
RLOGD("get cmd prefix [%d][%s]", buf_len, prefix);
return prefix;
}
int atci_get_cmd_mode(char *line) {
int reasult = AT_WRONG_MODE;
char *p_cur = NULL;
if (NULL == line) {
reasult = AT_WRONG_MODE;
RLOGD("atci_get_cmd_mode error, input is NULL");
return reasult;
}
p_cur = strchr(line, ATCI_EQUAL);
if (NULL == p_cur) {
p_cur = strchr(line, ATCI_QUESTION_MARK);
if (NULL == p_cur) {
reasult = AT_ACTIVE_MODE;
} else {
reasult = AT_READ_MODE;
}
} else {
p_cur++;
atci_at_skip_space(&p_cur);
if (ATCI_QUESTION_MARK == *p_cur) {
reasult = AT_TEST_MODE;
} else {
reasult = AT_SET_MODE;
}
}
RLOGD("atci_get_cmd_mode success[%d]", reasult);
return reasult;
}
int atci_dispatch_cmd(char *line) {
int ret = SYS_FAIL;
char *prefix = NULL;
//atci_Info_t* atci_ptr = atci_info_get();
atci_cmd_type_t* cmd_handle = NULL;
if (NULL == line) {
RLOGD("CMD is null");
return SYS_FAIL;
}
RLOGD("enter: %s", line);
prefix = atci_get_cmd_prefix(line);
if (NULL == prefix) {
RLOGD("atci_cut_cmd_prefix error");
return SYS_FAIL;
}
RLOGD("find prefix [%s]", prefix);
cmd_handle = atci_find_cmd_handler(prefix);
free(prefix);
if (NULL == cmd_handle) {
RLOGD("not find handler");
} else {
RLOGD("find handler");
int cmd_mode = atci_get_cmd_mode(line);
char response[MAX_RESP_BUF_LENGTH];
memset(response, 0, sizeof(response));
RLOGD("write to handler");
ret = cmd_handle->cmd_handle_func(line, cmd_mode, cmd_handle->target,
response);
if (SYS_FAIL == ret) {
RLOGD("cmd_handle_func error");
} else {
RLOGD("cmd_handle_func success");
}
}
return ret;
}
#endif