blob: b90b44b41886daf97555060401732c5198248eff [file] [log] [blame]
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <binder/Parcel.h>
#include <log/log.h>
#include <cutils/jstring.h>
#include <pthread.h>
#include "liblog/lynq_deflog.h"
#include <sys/time.h>
#include <string.h>
#include <vendor-ril/telephony/ril.h>
#include <vendor-ril/telephony/mtk_ril_sp.h>
#include <vendor-ril/telephony/mtk_ril_ivt.h>
#include "lynq_call.h"
#define LYNQ_SERVICE_PORT 8088
#define DSET_IP_ADDRESS "127.0.0.1"
#define LYNQ_URC_SERVICE_PORT 8086
#define LYNQ_REC_BUF 8192
#define LYNQ_REQUEST_PARAM_BUF 8192
#define LYQN_SEDN_BUF 1024*8+sizeof(int)*3
#define INVALID_ID (-1)
#define RTP_FROM_CMD "gst-launch-1.0 -v udpsrc port=%d caps=\'application/x-rtp, media=(string)audio, clock-rate=(int)%d, channels=(int)%d\' ! rtpjitterbuffer latency=%d ! rtppcmadepay ! alawdec ! audioresample ! audioconvert ! alsasink device=\'hw:0,2\'"
#define RTP_TO_CMD "gst-launch-1.0 -v alsasrc device=\'hw:0,6\' ! audioconvert ! audioresample ! alawenc ! rtppcmapay ! udpsink host=%s auto-multicast=true port=%d"
#define MAX_IP_LENGTH 128
#define USER_LOG_TAG "LYNQ_CALL"
using ::android::Parcel;
typedef enum {
LYNQ_CALL_ACTIVE = 0,
LYNQ_CALL_HOLDING = 1,
LYNQ_CALL_DIALING = 2, /* MO call only */
LYNQ_CALL_ALERTING = 3, /* MO call only */
LYNQ_CALL_INCOMING = 4, /* MT call only */
LYNQ_CALL_WAITING = 5, /* MT call only */
/*warren add for T800 platform 2022/04/26 start*/
LYNQ_CALL_END = 6, /*CALL END*/
/*warren add for T800 platform 2022/04/26 end*/
}lynq_call_state_t;
typedef struct{
int uToken;
int request;
int paramLen;
char param[LYNQ_REQUEST_PARAM_BUF];
}lynq_client_t;
typedef struct
{
int used;
int call_id;
int call_state;
int toa;
int direction;/*0: MO call,1:MT call*/
char addr[LYNQ_PHONE_NUMBER_MAX];
}lynq_call_list_e_t;
typedef struct
{
int call_id;
int call_state;
int toa;
int direction;/*0: MO call,1:MT call*/
char addr[LYNQ_PHONE_NUMBER_MAX];
}lynq_call_list_t;
lynq_call_list_e_t lynq_call_lists[LYNQ_CALL_MAX]={};
static pthread_mutex_t call_state_change_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t call_state_change_cond = PTHREAD_COND_INITIALIZER;
static pthread_mutex_t *s_urc_call_state_change_mutex = NULL;
static pthread_cond_t *s_urc_call_state_change_cond = NULL;
static pthread_mutex_t s_incoming_call_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t s_incoming_call_cond = PTHREAD_COND_INITIALIZER;
static pthread_mutex_t g_lynq_call_sendto_mutex;
pthread_t lynq_call_urc_tid = -1;
pthread_t lynq_call_list_loop_tid = -1;
/*lei add*/
/* socket文件描述符 */
int len_addr_serv;
struct sockaddr_in addr_serv;
lynq_client_t client_t;
int client_size = 0;
/*lei add*/
int s_call_urc_event_complete = 0;
enum{
CALL_OFF=0,
CALL_ON=1
}call_state;
typedef enum{
LYNQ_E_CARDSTATE_ERROR=8000,
/* The voice service state is out of service*/
LYNQ_E_STATE_OUT_OF_SERVICE=8001,
/* The voice service state is EMERGENCY_ONLY*/
LYNQ_E_STATE_EMERGENCY_ONLY=8002,
/* The radio power is power off*/
LYNQ_E_STATE_POWER_OFF=8003,
LYNQ_E_TIME_OUT=8004,
/*create or open sms DB fail */
LYNQ_E_SMS_DB_FAIL=8005,
/*Failed to execute sql statement*/
LYNQ_E_SMS_SQL_FAIL = 8006,
LYNQ_E_SMS_NOT_FIND = 8007,
/* The logic conflict*/
LYNQ_E_CONFLICT=9000,
/*Null anomaly*/
LYNQ_E_NULL_ANONALY=9001,
/*Invalid id anomaly*/
LYNQ_E_INVALID_ID_ANONALY=9002,
#ifdef ECALL_SUPPORT
LYNQ_E_ECALL_BEING_RUNNING =9003,
LYNQ_E_ECALL_MSD_LENGTH_ERROR =9004,
LYNQ_E_ECALL_DAILING_NO_ANSWER =9005,
#endif
}LYNQ_E;
typedef enum{
LYNQ_E_VOLUMN_SET_DTMF,
LYNQ_E_VOLUMN_SET_SPEECH
}LYNQ_E_VOLUMN_SET;
int lynq_call_state =CALL_OFF;
int lynq_call_client_sockfd = 0;
int Global_uToken_call = 0;
int global_call_count =0;
int global_call_auto_answer = 0;
bool urc_call_recive_status = 1;
bool call_list_loop = 0;
int isDial = 0;
int lynqIncomingCallId = 0;
/*rtp begin*/
typedef struct
{
char ip[MAX_IP_LENGTH];
int port;
}lynq_rtp_server_info;
typedef struct
{
int port;
int clockrate;
int latency;
int channels;
}lynq_rtp_client_info;
static lynq_rtp_client_info g_rtp_client_info;
static lynq_rtp_server_info g_rtp_server_info;
static pthread_t g_rtp_thread[RTP_MODE_MAX];
static bool g_rtp_thread_valid[RTP_MODE_MAX];
/*rtp end*/
#ifdef ECALL_SUPPORT
int lynq_set_common_request(int request_id, int argc, const char* format,...);
int g_ecallId = INVALID_ID;
typedef enum{
LYNQ_ECALL_TYPE_TEST = 0, /* Test eCall */
LYNQ_ECALL_TYPE_RECONFIG = 1, /* Reconfiguration eCall */
LYNQ_ECALL_MANUAL_EMERGENCY = 2, /*Manual Emergency eCall */
LYNQ_ECALL_TYPE_AUTO_EMERGENCY = 3, /* Automatic Emergency eCall */
}LYNQ_ECall_Type;
typedef enum{
LYNQ_ECALL_DAILING_STATE_NONE =0,
LYNQ_ECALL_DAILING_STATE_STARTED = 1,
LYNQ_ECALL_DAILING_STATE_ANSWERED = 2,
}LYNQ_ECall_Dailing_State;
LYNQ_ECall_Dailing_State is_ecall_dial = LYNQ_ECALL_DAILING_STATE_NONE;
char e_call_addr[LYNQ_ECALL_VAR_MAX][LYNQ_PHONE_NUMBER_MAX]={"test_ecall","emergency_ecall","reconf_ecall"};
static pthread_mutex_t s_incoming_e_call_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t s_incoming_e_call_cond = PTHREAD_COND_INITIALIZER;
LYNQ_ECall_Indication g_lynqIncomingEcallIndication;
int g_lynqIncomingEcallId;
void sendSignalIncomingECallEvent()
{
LYINFLOG("send incoming ecall event signal");
pthread_mutex_lock(&s_incoming_e_call_mutex);
pthread_cond_signal(&s_incoming_e_call_cond);
pthread_mutex_unlock(&s_incoming_e_call_mutex);
}
int lynq_is_msd_suc(LYNQ_ECall_Indication lynqIncomingEcallIndication)
{
if(LYNQ_ECALL_LLACK_RECEIVED == lynqIncomingEcallIndication ||
LYNQ_ECALL_ALACK_POSITIVE_RECEIVED == lynqIncomingEcallIndication ||
LYNQ_ECALL_ALACK_CLEARDOWN_RECEIVED == lynqIncomingEcallIndication ||
LYNQ_ECALL_T5_TIMER_OUT == lynqIncomingEcallIndication ||
LYNQ_ECALL_T6_TIMER_OUT == lynqIncomingEcallIndication ||
LYNQ_ECALL_T7_TIMER_OUT == lynqIncomingEcallIndication)
{
return 1;
}
return 0;
}
int lynq_ecall_is_running()
{
return (is_ecall_dial!=LYNQ_ECALL_DAILING_STATE_NONE) || (g_ecallId !=INVALID_ID);
}
#endif
/**
* @brief mark call initialization state
* 0: deinit state
* 1: init state
*/
int g_lynq_call_init_flag = 0;
int JumpHeader(Parcel &p,int *resp_type,int *request,int *slot_id,int *error)
{
if(p.dataAvail() > 0)
{
p.readInt32(resp_type);
p.readInt32(request);
p.readInt32(slot_id);
p.readInt32(error);
return 0;
}
else
{
return -1;
}
}
int send_request(int sockfd,lynq_client_t *client_tmp)
{
int ret=0;
ret = sendto(sockfd, client_tmp, client_size, 0, (struct sockaddr *)&addr_serv, len_addr_serv);
if(ret==-1)
{
LYERRLOG("sendto error");
return -1;
}
return 0;
}
int get_response(int sockfd,Parcel &p)
{
int len = 0;
char recvline[LYNQ_REC_BUF];
bzero(recvline,LYNQ_REC_BUF);
/* receive data from server */
len = recvfrom(sockfd,recvline,LYNQ_REC_BUF, 0, (struct sockaddr *)&addr_serv,(socklen_t*)&len_addr_serv);
if(len == -1)
{
LYERRLOG("recvfrom error");
return -1;
}
if (recvline != NULL) {
p.setData((uint8_t *)recvline,len); // p.setData((uint8_t *) buffer, buflen);
p.setDataPosition(0);
}
return 0;
}
static char *strdupReadString(Parcel &p) {
size_t stringlen;
const char16_t *s16;
s16 = p.readString16Inplace(&stringlen);
return strndup16to8(s16, stringlen);
}
int lynq_get_current_call_list(lynq_call_list_t call_list[LYNQ_CALL_MAX])
{
Parcel p;
lynq_client_t client;
int resp_type = -1;
int request = -1;
int slot_id = -1;
int error = -1;
int call_num = 0;
int temp = 0;
char *remote_phoneNum = NULL;
char *remote_name= NULL;
char *uusData = NULL;
client.uToken = Global_uToken_call;
client.request = 9;//RIL_REQUEST_GET_CURRENT_CALLS
client.paramLen = 0;
bzero(client.param,LYNQ_REQUEST_PARAM_BUF);
LYINFLOG("uToken=%d,request=%d,paralen=%d,param=%s",client.uToken,client.request,client.paramLen,client.param);
if(send_request(lynq_call_client_sockfd,&client)==-1)
{
LYERRLOG("send request fail");
return -1;
}
get_response(lynq_call_client_sockfd,p);
JumpHeader(p,&resp_type,&request,&slot_id,&error);
LYINFLOG("resp_type=%d,request=%d,slot_id=%d,error_code=%d",resp_type,request,slot_id,error);
if(error == 0)
{
p.readInt32(&call_num);
global_call_count = call_num;
if(call_num<=0)
{
lynq_call_state = CALL_OFF;
LYINFLOG("lynq_call_state:%d",lynq_call_state);
return 0;
}
lynq_call_state = CALL_ON;
LYINFLOG("lynq_call_state:%d, call num is %d ",lynq_call_state,call_num);
for(int i = 0;i < call_num;i++)
{
p.readInt32(&temp);
call_list[i].call_state = temp;
p.readInt32(&call_list[i].call_id);
p.readInt32(&call_list[i].toa);
p.readInt32(&temp);
p.readInt32(&temp);
call_list[i].direction = temp;
p.readInt32(&temp);
p.readInt32(&temp);
p.readInt32(&temp);
remote_phoneNum = strdupReadString(p);
memcpy(call_list[i].addr,remote_phoneNum,strlen(remote_phoneNum));
LYINFLOG("call_id=%d,call_state=%d,direction=%d,addr=%s,toa=%d",call_list[i].call_id,call_list[i].call_state,
call_list[i].direction,call_list[i].addr,call_list[i].toa);
p.readInt32(&temp);
remote_name = strdupReadString(p);
p.readInt32(&temp);
p.readInt32(&temp);
if(temp==0)
{
continue;
}
p.readInt32(&temp); /* UUS Information is present */
p.readInt32(&temp);
p.readInt32(&temp);
p.read(uusData,temp);
}
}
return 0;
}
void cleanCallList(int lynq_call_id)
{
LYINFLOG("cleanCall local idx is %d, id is %d",lynq_call_id,lynq_call_lists[lynq_call_id].call_id);
lynq_call_lists[lynq_call_id].call_id = 0;
lynq_call_lists[lynq_call_id].call_state = (int)LYNQ_CALL_END;
lynq_call_lists[lynq_call_id].toa = 0;
lynq_call_lists[lynq_call_id].direction = 0;
lynq_call_lists[lynq_call_id].used = 0;
memset(lynq_call_lists[lynq_call_id].addr,0,sizeof(lynq_call_lists[lynq_call_id].addr));
}
int getUnusedElement()
{
for(int i=0;i < LYNQ_CALL_MAX; i++)
{
if(lynq_call_lists[i].used!=1)
{
return i;
}
}
return -1;
}
int addAddr(char addr[])
{
int ret = 0;
ret = getUnusedElement();
memcpy(lynq_call_lists[ret].addr,addr,strlen(addr)+1);
lynq_call_lists[ret].used = 1;
LYINFLOG("add local idx is %d addr is %s",ret,addr);
return ret;
}
void updateCallList(lynq_call_list_e_t *callList, int call_id,int call_state,int toa,int direction)
{
LYINFLOG("Update original local id is %d, new local id is %d",callList->call_id,call_id);
callList->call_id = call_id;
callList->call_state = call_state;
callList->toa = toa;
callList->direction = direction;
return;
}
int waitCallstateChange(int mtime)
{
LYINFLOG("wait Call state Change");
int ret = 0;
int sec = 0;
int usec = 0;
struct timeval now;
struct timespec timeout;
gettimeofday(&now,NULL);
sec = mtime/1000;
usec = mtime%1000;
timeout.tv_sec = now.tv_sec+sec;
timeout.tv_nsec = now.tv_usec*1000+usec*1000000;
pthread_mutex_lock(&call_state_change_mutex);
ret = pthread_cond_timedwait(&call_state_change_cond,&call_state_change_mutex,&timeout);
pthread_mutex_unlock(&call_state_change_mutex);
return ret;
}
int waitIncomingCall()
{
LYINFLOG("wait incming call");
int ret = 0;
pthread_mutex_lock(&s_incoming_call_mutex);
ret = pthread_cond_wait(&s_incoming_call_cond,&s_incoming_call_mutex);
pthread_mutex_unlock(&s_incoming_call_mutex);
return ret;
}
int checkHasCall(char addr[])
{
for(int i = 0;i<LYNQ_CALL_MAX;i++)
{
if(strcmp(lynq_call_lists[i].addr,addr)==0)
{
LYINFLOG("checkHasCall addr is %s idx is %d id is %d",addr,i,lynq_call_lists[i].call_id);
return 1;
}
}
LYINFLOG("checkHasCall addr is %s , no idx is found",addr);
return 0;
}
int find_call_id_with_addr(char *addr)
{
for(int id = 0; id < LYNQ_CALL_MAX; id++)
{
if(lynq_call_lists[id].used && (strcmp(lynq_call_lists[id].addr,addr) == 0))
{
LYINFLOG("find addr %s in local list, local idx is %d id is %d",addr,id,lynq_call_lists[id].call_id);
return id;
}
}
LYINFLOG("find addr %s in local list , not found",addr);
return -1;
}
int find_call_id_with_call_id(int call_id)
{
for(int id = 0; id < LYNQ_CALL_MAX; id++)
{
if(lynq_call_lists[id].used && (lynq_call_lists[id].call_id == call_id))
{
LYINFLOG("find id %d in local list, local idx is %d, addr is %s",call_id,id,lynq_call_lists[id].addr);
return id;
}
}
LYINFLOG("find id %d in local list , not found",call_id);
return INVALID_ID;
}
void sendSignalToWaitCallStateChange()
{
LYINFLOG("send Signal To Wait Call State Change");
pthread_mutex_lock(&call_state_change_mutex);
pthread_cond_signal(&call_state_change_cond);
pthread_mutex_unlock(&call_state_change_mutex);
}
void sendSignalIncomingCall()
{
LYINFLOG("send incoming call signal");
pthread_mutex_lock(&s_incoming_call_mutex);
pthread_cond_signal(&s_incoming_call_cond);
pthread_mutex_unlock(&s_incoming_call_mutex);
}
void addCallListToLynqCallList(lynq_call_list_e_t *callList, int call_id,int call_state,int toa,int direction,char addr[LYNQ_PHONE_NUMBER_MAX])
{
callList->call_id = call_id;
callList->call_state = call_state;
callList->toa = toa;
callList->direction = direction;
memcpy(callList->addr,addr,strlen(addr)+1);
callList->used = 1;
return;
}
void *triggerGetCallList(void *parg)
{
int ret=0;
bool call_end;
lynq_call_list_t call_list[LYNQ_CALL_MAX];
int update=0;
int cnt;
int i,n;
while(call_list_loop)
{
update=0;
pthread_mutex_lock(s_urc_call_state_change_mutex);
pthread_cond_wait(s_urc_call_state_change_cond, s_urc_call_state_change_mutex);
LYDBGLOG("triggerGetCallList event!!!");
memset(call_list,0,sizeof(call_list));
ret = lynq_get_current_call_list(call_list);
if(ret != 0)
{
LYDBGLOG("get current call list failure!!!");
continue;
}
LYINFLOG("++++++++++++++triggerGetCallList++++++++++++++");
LYINFLOG("clear local index begin");
cnt=0;
for(i = 0;i < LYNQ_CALL_MAX;i++)
{
if(lynq_call_lists[i].used ==0)
{
continue;
}
cnt++;
LYINFLOG("local idx is %d id is %d addr is %s state is %d direction is %d",i,lynq_call_lists[i].call_id,lynq_call_lists[i].addr,lynq_call_lists[i].call_state,lynq_call_lists[i].direction);
if(lynq_call_lists[i].call_id > 0)
{
call_end = 0;
for(n = 0; n < LYNQ_CALL_MAX; n++)
{
if(call_list[n].call_id == lynq_call_lists[i].call_id)
{
call_end = 1;
LYINFLOG("find lynq call local idx %d, service idx %d id is %d!!!",i,n,lynq_call_lists[i].call_id);
break;
}
}
if(call_end == 0)
{
LYINFLOG("MT hungup,then clean call info local idx is %d id is %d",i, lynq_call_lists[i].call_id);
cleanCallList(i);
}
} //fix bug API-54
else
{
LYINFLOG("local id is 0");
}
}
LYINFLOG("clear local index end, local used cnt is %d", cnt);
LYINFLOG("add or update local index begin ");
for (i = 0;i < LYNQ_CALL_MAX;i++)
{
if(call_list[i].call_id==0)
{
break;
}
LYINFLOG("servie idx %d begin: call_id=%d, call_state=%d, direction=%d, addr=%s, toa=%d",i,call_list[i].call_id, call_list[i].call_state,
call_list[i].direction,call_list[i].addr,call_list[i].toa);
if(call_list[i].direction == 1)//MT call
{
LYINFLOG("This is a MT CALL");
/*MT CALL state code
**LYNQ_CALL_INCOMING = 4,
**LYNQ_CALL_WAITING = 5,
*/
if((call_list[i].call_state ==4) || (call_list[i].call_state ==5))
{
#ifdef ECALL_SUPPORT
if(lynq_ecall_is_running())
{
lynq_call_hungup(&(call_list[i].call_id));
continue;
}
#endif
}
/*you call me, and i call you,One party failed to dial*/
n = find_call_id_with_addr(call_list[i].addr);
if(n ==INVALID_ID)
{
n = addAddr(call_list[i].addr);
updateCallList(&lynq_call_lists[n],call_list[i].call_id,call_list[i].call_state,call_list[i].toa,call_list[i].direction);
lynqIncomingCallId = call_list[i].call_id;
sendSignalIncomingCall();
}
else if(lynq_call_lists[n].call_state == call_list[i].call_state)
{
LYINFLOG("state not changed, state is %d ",call_list[i].call_state);
if(call_list[i].call_state ==4 || call_list[i].call_state ==5)
{
/*if call state not change,Maybe this call was ignored, so we need to continue to inform the user of
**an incoming call until the status changes.
**fix bug API-54
*/
LYINFLOG("resend incoming call signal");
sendSignalIncomingCall();
}
}
else
{
LYINFLOG("state changed from %d to %d",lynq_call_lists[n].call_state,call_list[i].call_state);
updateCallList(&lynq_call_lists[n],call_list[i].call_id,call_list[i].call_state,call_list[i].toa,call_list[i].direction);
}
}
else
{
LYINFLOG("This is a MO CALL");
call_end = 0;
for(n = 0 ; n < LYNQ_CALL_MAX; n++)
{
if(lynq_call_lists[n].used && ((strcmp(call_list[i].addr,lynq_call_lists[n].addr)==0)||(call_list[i].call_id==lynq_call_lists[n].call_id)))
{
if(lynq_call_lists[n].call_id==0)
{
LYINFLOG("add a call id");
update=1;
}
LYINFLOG("local idx %d updated, original call id is %d origial addr is %s original state is %d",n,lynq_call_lists[n].call_id,lynq_call_lists[n].addr,lynq_call_lists[n].call_state);
updateCallList(&lynq_call_lists[n],call_list[i].call_id,call_list[i].call_state,call_list[i].toa,call_list[i].direction);
call_end = 1;
break;
}
}
if(call_end == 0)
{
LYINFLOG("need to hangup id %d", call_list[i].call_id);
#ifdef ECALL_SUPPORT
if(is_ecall_dial != LYNQ_ECALL_DAILING_STATE_NONE)
{
LYINFLOG("ecall is dialing, for the timebeing, don't huangup");
continue;
}
#endif
LYINFLOG("hang up service call id %d",call_list[i].call_id);
lynq_call_hungup(&(call_list[i].call_id));
}
}
LYDBGLOG("servie idx %d end",i);
}
LYINFLOG("add or update local index end ");
s_call_urc_event_complete = 1;
if(isDial==1)
{
LYINFLOG("now is dialing");
if(update==1)
{
LYINFLOG("find added call");
sendSignalToWaitCallStateChange();
isDial = 0;
}
else
{
LYINFLOG("not find added call");
}
}
else
{
LYINFLOG("now is not dialing");
}
pthread_mutex_unlock(s_urc_call_state_change_mutex);
}
return NULL;
}
void lynqRespWatingEvent()
{
if(s_call_urc_event_complete==1)
{
pthread_mutex_lock(s_urc_call_state_change_mutex);
pthread_cond_signal(s_urc_call_state_change_cond);
s_call_urc_event_complete = 0;
pthread_mutex_unlock(s_urc_call_state_change_mutex);
}
return;
}
/*Warren add for T800 platform 2021/11/19 start*/
int lynq_socket_client_start()
{
#if 0
struct sockaddr_in lynq_socket_server_addr;
/* init lynq_socket_server_addr */
bzero(&lynq_socket_server_addr, sizeof(lynq_socket_server_addr));
lynq_socket_server_addr.sin_family = AF_INET;
lynq_socket_server_addr.sin_port = htons(LYNQ_SERVICE_PORT);
lynq_socket_server_addr.sin_addr.s_addr = htons(INADDR_ANY);
/*
if(inet_pton(AF_INET,"127.0.0.1", &lynq_socket_server_addr.sin_addr) <= 0)
{
LYDBGLOG("[%s] is not a valid IPaddress", argv[1]);
exit(1);
}
*/
lynq_call_client_sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if(connect(lynq_call_client_sockfd, (struct sockaddr *)&lynq_socket_server_addr, sizeof(lynq_socket_server_addr)) == -1)
{
LYERRLOG("connect error");
return -1;
}
#endif
lynq_call_client_sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (-1 == lynq_call_client_sockfd)
{
return lynq_call_client_sockfd;
}
struct timeval timeOut;
timeOut.tv_sec = 60;
timeOut.tv_usec = 0;
if (setsockopt(lynq_call_client_sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeOut, sizeof(timeOut)) < 0)
{
RLOGD("time out setting failed\n");
return -1;
}
/* 设置address */
memset(&addr_serv, 0, sizeof(addr_serv));
addr_serv.sin_family = AF_INET;
addr_serv.sin_addr.s_addr = inet_addr(DSET_IP_ADDRESS);
addr_serv.sin_port = htons(LYNQ_SERVICE_PORT);
len_addr_serv = sizeof(addr_serv);
return 0;
}
int lynq_update_call_list_loop()
{
int ret = 0;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
ret = pthread_create(&lynq_call_list_loop_tid,&attr,triggerGetCallList,NULL);
if(ret < 0)
{
LYERRLOG("lynq_update_call_list_loop fail!!!");
return -1;
}
LYDBGLOG("lynq_update_call_list_loop success!!!");
return 0;
}
void *thread_urc_recv(void *parg)
{
int socket_fd = (int64_t)parg;
int len=0;
socklen_t addr_len=0;
uint8_t *dataLength = NULL;
char urc_data[LYNQ_REC_BUF];
int slot_id = -1;
int resp_type = -1;
int urcid = -1;
Parcel *p = NULL;
struct sockaddr_in dest_addr;
#ifdef ECALL_SUPPORT
int ecall_ind;
int ecallId;
int unused_callid;
#endif
LYINFLOG("thread_urc_recv in running....");
while(urc_call_recive_status)
{
bzero(urc_data,LYNQ_REC_BUF);
//get data msg
len = recvfrom(socket_fd,urc_data,LYNQ_REC_BUF,0,(struct sockaddr *)&dest_addr,&addr_len);
if(len <= 0)
{
LYERRLOG("thread_urc_recv step2 fail");
break;
}
LYDBGLOG("=====>urc data len<=====:%d",len);
p = new Parcel();
if(p==NULL)
{
LYERRLOG("new parcel failure!!!");
break;
}
p->setData((uint8_t *)urc_data,len); // p.setData((uint8_t *) buffer, buflen);
p->setDataPosition(0);
if(p->dataAvail() > 0)
{
p->readInt32(&resp_type);
p->readInt32(&urcid);
p->readInt32(&slot_id);
//LYDBGLOG("*******Warren test*******:resp_type=%d,urcid=%d,slot_id=%d",resp_type,urcid,slot_id);
switch (urcid)
{
case 1001://RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED
{
LYINFLOG("**************:resp_type=%d,urcid=%d,slot_id=%d",resp_type,urcid,slot_id);
lynqRespWatingEvent();
break;
}
case 1018://RIL_UNSOL_CALL_RING
{
if(global_call_auto_answer==1)
{
lynq_call_answer();
}
break;
}
case 1029://RIL_UNSOL_RINGBACK_TONE
case 3049://RIL_UNSOL_CALL_INFO_INDICATION
{
LYINFLOG("**************:resp_type=%d,urcid=%d,slot_id=%d",resp_type,urcid,slot_id);
break;
}
#ifdef ECALL_SUPPORT
case RIL_UNSOL_ECALL_INDICATIONS:
{
p->readInt32(&ecall_ind);
g_lynqIncomingEcallIndication = ecall_ind;
p->readInt32(&ecallId);
g_lynqIncomingEcallId = ecallId;
LYINFLOG("**************:RIL_UNSOL_ECALL_INDICATIONS ,Id %d, ind %d, ecall dialing is %d, normal dialing is %d, local ecall id is %d",ecallId,ecall_ind,is_ecall_dial,isDial,g_ecallId);
switch (g_lynqIncomingEcallIndication)
{
case LYNQ_ECALL_ACTIVE:
if(is_ecall_dial)
{
is_ecall_dial = LYNQ_ECALL_DAILING_STATE_ANSWERED;
}
break;
case LYNQ_ECALL_LLACK_RECEIVED:
case LYNQ_ECALL_ALACK_POSITIVE_RECEIVED:
case LYNQ_ECALL_ALACK_CLEARDOWN_RECEIVED:
case LYNQ_ECALL_T5_TIMER_OUT:
case LYNQ_ECALL_T6_TIMER_OUT:
case LYNQ_ECALL_T7_TIMER_OUT:
if(is_ecall_dial)
{
LYINFLOG("ecall is dialing, recv suc indication");
is_ecall_dial = LYNQ_ECALL_DAILING_STATE_NONE;
if(ecallId >0 && find_call_id_with_call_id(ecallId)==INVALID_ID)
{
LYINFLOG("add ecall in loacl list");
g_ecallId = ecallId;
unused_callid=addAddr("ecall");
lynq_call_lists[unused_callid].call_id=g_ecallId;
}
sendSignalToWaitCallStateChange();
}
else if(ecallId >0 && (find_call_id_with_call_id(ecallId)==INVALID_ID))
{
LYERRLOG("ecall is not in dialing and first recv suc indication, hangup");
lynq_call_hungup(&ecallId);
}
else
{
LYERRLOG("ecall is not in dialing and not first recv suc indication");
}
break;
case LYNQ_ECALL_PSAP_CALLBACK_START:
if(lynq_ecall_is_running()==0)
{
LYINFLOG("ecall is not running, recv psap call back msd start, set ecall in dialing");
if(find_call_id_with_call_id(ecallId)!=INVALID_ID)
{
g_ecallId = ecallId;
if(isDial)
{
LYINFLOG("stop normal dial");
sendSignalToWaitCallStateChange();
}
else
{
LYINFLOG("no normal dial");
}
}
else
{
LYERRLOG("can't find ecall id in local list");
}
}
else
{
LYERRLOG("ecall is running, recv psap call back msd start");
}
break;
case LYNQ_ECALL_ABNORMAL_HANGUP:
if(is_ecall_dial == LYNQ_ECALL_DAILING_STATE_NONE)
{
LYERRLOG("ecall is not in dialing , recv abnormal hangup");
g_ecallId = INVALID_ID;
}
else if (is_ecall_dial == LYNQ_ECALL_DAILING_STATE_STARTED)
{
LYERRLOG("ecall is in dialing state, recv no answer, recv abnormal hangup, dont' redial");
g_ecallId = INVALID_ID;
sendSignalToWaitCallStateChange();
}
else {
LYINFLOG("ecall is in dialing and recv answer, recv abnormal hangup");
}
break;
case LYNQ_ECALL_DISCONNECTED:
case LYNQ_ECALL_REDIAL_TIMER_OUT:
case LYNQ_ECALL_T2_TIMER_OUT :
case LYNQ_ECALL_IMS_DISCONNECTED:
g_ecallId = INVALID_ID;
if(is_ecall_dial != LYNQ_ECALL_DAILING_STATE_NONE)
{
LYERRLOG("ecall is in dialing, recv like disconnect indication");
is_ecall_dial = LYNQ_ECALL_DAILING_STATE_NONE;
sendSignalToWaitCallStateChange();
}
else
{
LYINFLOG("ecall is not in dialing, recv like disconnect indication");
}
break;
default:
LYINFLOG("not special indication");
}
sendSignalIncomingECallEvent();
LYINFLOG("**************:RIL_UNSOL_ECALL_INDICATIONS, local ecall id is %d", g_ecallId);
break;
}
#endif
default:
break;
}
}
delete p;
p = NULL;
}
close(socket_fd);
}
int lynq_socket_urc_start()
{
int socket_fd=0;
int rt=0;
int len=0;
int on=1;
struct sockaddr_in urc_local_addr;
pthread_attr_t attr;
socket_fd = socket(AF_INET,SOCK_DGRAM,0);
if(socket_fd < 0)
{
LYERRLOG("creaet socket for udp fail");
return -1;
}
urc_local_addr.sin_family = AF_INET;
urc_local_addr.sin_port = htons(LYNQ_URC_SERVICE_PORT);
urc_local_addr.sin_addr.s_addr = htons(INADDR_ANY);
/* Set socket to allow reuse of address and port, SO_REUSEADDR value is 2*/
rt = setsockopt(socket_fd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof on);
if(rt<0)
{
LYERRLOG("SO_REUSEADDR fail");
return -1;
}
rt = bind(socket_fd ,(struct sockaddr*)&urc_local_addr, sizeof(urc_local_addr));
if (rt == -1)
{
LYERRLOG("bind failed");
return -1;
}
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
rt = pthread_create(&lynq_call_urc_tid,&attr,thread_urc_recv,(void *)socket_fd);
if(rt < 0)
{
LYERRLOG("urc loop failure!!!");
return -1;
}
LYDBGLOG("urc loop success!!!");
return 0;
}
int getSelfElement(char addr[])
{
for(int i=0;i < LYNQ_CALL_MAX; i++)
{
if(lynq_call_lists[i].used==1)
{
if(strcmp(lynq_call_lists[i].addr,addr)==0)
{
return i;
}
}
}
return -1;
}
void lynq_call_state_change_test(int soc_id)
{
LYDBGLOG("call state change,sim:%d",soc_id);
}
void lynq_init_rtp()
{
memset(&g_rtp_client_info,0,sizeof(g_rtp_client_info));
memset(&g_rtp_server_info,0,sizeof(g_rtp_server_info));
lynq_set_rtp_param(8000,1,400);
for(int i=0;i<RTP_MODE_MAX;i++)
{
lynq_set_rtp_port(i,6666);
g_rtp_thread_valid[i] = 0;
}
LYDBGLOG("lynq init rtp success!!!");
return;
}
int lynq_init_call(int uToken)
{
if(g_lynq_call_init_flag == 1){
LYDBGLOG("lynq init call failed!!!");
return -1;
}
g_lynq_call_init_flag = 1;
s_call_urc_event_complete = 1;
call_list_loop = 1;
LYINFLOG("liulei call_list_loop %d\n", call_list_loop);
s_urc_call_state_change_mutex = new pthread_mutex_t;
pthread_mutex_init(s_urc_call_state_change_mutex, NULL);
s_urc_call_state_change_cond = new pthread_cond_t;
LYINFLOG("liulei s_urc_call_state_change_mutex\n");
pthread_cond_init(s_urc_call_state_change_cond, NULL);
LYINFLOG("liulei s_urc_call_state_change_cond\n");
int result = 0;
Global_uToken_call = uToken;
urc_call_recive_status = 1;
client_size = sizeof(client_t);
LYLOGSET(LOG_INFO);
LYLOGEINIT(USER_LOG_TAG);
result = lynq_socket_client_start();
if(result!=0)
{
return -1;
}
result = lynq_socket_urc_start();
if(result!=0)
{
return -1;
}
result = lynq_update_call_list_loop();
if(result!=0)
{
return -1;
}
memset(lynq_call_lists,0,sizeof(lynq_call_lists));
lynq_init_rtp();
LYDBGLOG("lynq init call success!!!");
return 0;
}
int lynq_deinit_call()
{
int ret;
if(g_lynq_call_init_flag == 0)
{
LYDBGLOG("lynq_deinit_call failed!!!");
return -1;
}
else
{
g_lynq_call_init_flag = 0;
lynq_call_hungup_all();
if(lynq_call_client_sockfd>0)
{
close(lynq_call_client_sockfd);
}
urc_call_recive_status = 0;
call_list_loop = 0;
lynq_set_voice_audio_mode(AUDIO_MODE_CODEC);
if(lynq_call_urc_tid == -1 || lynq_call_list_loop_tid == -1)
{
return -1;
}
ret = pthread_cancel(lynq_call_urc_tid);
LYDBGLOG("pthread cancel ret = %d",ret);
ret = pthread_cancel(lynq_call_list_loop_tid);
LYDBGLOG("pthread cancel ret = %d",ret);
ret = pthread_join(lynq_call_urc_tid,NULL);
LYDBGLOG("pthread join ret = %d",ret);
ret = pthread_join(lynq_call_list_loop_tid,NULL);
LYDBGLOG("pthread join ret = %d",ret);
pthread_mutex_destroy(s_urc_call_state_change_mutex);
pthread_cond_destroy(s_urc_call_state_change_cond);
delete s_urc_call_state_change_mutex;
//s_urc_call_state_change_mutex = NULL;
delete s_urc_call_state_change_cond;
//s_urc_call_state_change_cond = NULL;
return 0;
}
}
int lynq_set_common_request(int request_id, int argc, const char* format,...)
{
Parcel p;
lynq_client_t client;
int resp_type = -1;
int request = -1;
int slot_id = -1;
int error = -1;
client.uToken = Global_uToken_call;
client.request = request_id;
client.paramLen = argc;
bzero(client.param,LYNQ_REQUEST_PARAM_BUF);
if(argc!=0)
{
va_list args;
va_start(args, format);
vsnprintf(client.param, LYNQ_REQUEST_PARAM_BUF, format, args);
va_end(args);
}
LYINFLOG("uToken=%d,request=%d,paralen=%d,param=%s",client.uToken,client.request,client.paramLen,client.param);
if(send_request(lynq_call_client_sockfd,&client)==-1)
{
LYERRLOG("send request fail");
return -1;
}
if(get_response(lynq_call_client_sockfd,p)==0)
{
JumpHeader(p,&resp_type,&request,&slot_id,&error);
LYINFLOG("resp_type=%d,request=%d,slot_id=%d,error_code=%d",resp_type,request,slot_id,error);
}
return error;
}
int lynq_get_common_request(int request_id, int* status)
{
Parcel p;
lynq_client_t client;
int resp_type = -1;
int request = -1;
int slot_id = -1;
int error = -1;
if(status==NULL)
{
LYERRLOG("status is null");
return -1;
}
client.uToken = Global_uToken_call;
client.request = request_id;
client.paramLen = 0;
bzero(client.param,LYNQ_REQUEST_PARAM_BUF);
LYINFLOG("uToken=%d,request=%d,paralen=%d,param=%s",client.uToken,client.request,client.paramLen,client.param);
if(send_request(lynq_call_client_sockfd,&client)==-1)
{
LYERRLOG("send request fail");
return -1;
}
if(get_response(lynq_call_client_sockfd,p)==0)
{
JumpHeader(p,&resp_type,&request,&slot_id,&error);
p.readInt32(status);
LYINFLOG("resp_type=%d,request=%d,slot_id=%d,error_code=%d",resp_type,request,slot_id,error);
}
return error;
}
int lynq_call(int* handle,char addr[])
{
if(g_lynq_call_init_flag == 0)
{
return -1;
}
Parcel p;
lynq_client_t client;
int resp_type = -1;
int request = -1;
int slot_id = -1;
int error = -1;
int lynq_call_id = -1;
LYINFLOG("lynq_call begin addr %s",addr);
if(addr==NULL)
{
LYERRLOG("Phone num is null!!!");
return -1;
}
if(find_call_id_with_addr(addr)!=INVALID_ID)
{
LYERRLOG("addr %s exists",addr);
return LYNQ_E_CONFLICT;
}
#ifdef ECALL_SUPPORT
if(lynq_ecall_is_running())
{
LYERRLOG("lynq_fast_ecall ecall is running");
return LYNQ_E_ECALL_BEING_RUNNING;
}
#endif
client.uToken = Global_uToken_call;
client.request = 10;//RIL_REQUEST_DIAL
client.paramLen = 2;
bzero(client.param,LYNQ_REQUEST_PARAM_BUF);
memcpy(client.param,addr,strlen(addr)+1);
strcat(client.param," 0");
lynq_call_id = addAddr(addr);
LYINFLOG("uToken=%d,request=%d,paralen=%d,param=%s",client.uToken,client.request,client.paramLen,client.param);
pthread_mutex_lock(&g_lynq_call_sendto_mutex);
if(send_request(lynq_call_client_sockfd,&client)==-1)
{
LYERRLOG("send request fail");
cleanCallList(lynq_call_id);
return -1;
}
get_response(lynq_call_client_sockfd,p);
pthread_mutex_unlock(&g_lynq_call_sendto_mutex);
JumpHeader(p,&resp_type,&request,&slot_id,&error);
LYINFLOG("resp_type=%d,request=%d,slot_id=%d,error_code=%d",resp_type,request,slot_id,error);
if(error==0)
{
isDial = 1;
if(waitCallstateChange(6000)==ETIMEDOUT)//6000ms
{
//if timeout,this call need destroy.
isDial = 0;
error = LYNQ_E_TIME_OUT;
LYERRLOG("lynq_call timeout:wait Call state fail!!! clear local idx %d",lynq_call_id);
cleanCallList(lynq_call_id);
return error;
}
isDial = 0;
*handle = lynq_call_lists[lynq_call_id].call_id;
if(*handle > 0)
{
LYINFLOG("lynq_call dial addr %s suc, id is %d",addr,*handle);
return 0;
}
else
{
LYERRLOG("lynq_call dial addr %s fail, invalid id",addr);
cleanCallList(lynq_call_id);
return LYNQ_E_INVALID_ID_ANONALY;
}
}
LYERRLOG("lynq_call dial addr %s fail, service error %d",addr, error);
cleanCallList(lynq_call_id);
return error;
}
int lynq_call_answer()
{
if(g_lynq_call_init_flag == 0)
{
return -1;
}
Parcel p;
lynq_client_t client;
int resp_type = -1;
int request = -1;
int slot_id = -1;
int error = -1;
client.uToken = Global_uToken_call;
client.request = 40;//RIL_REQUEST_DIAL
client.paramLen = 0;
bzero(client.param,LYNQ_REQUEST_PARAM_BUF);
LYINFLOG("uToken=%d,request=%d,paralen=%d,param=%s",client.uToken,client.request,client.paramLen,client.param);
pthread_mutex_lock(&g_lynq_call_sendto_mutex);
if(send_request(lynq_call_client_sockfd,&client)==-1)
{
LYERRLOG("send request fail");
return -1;
}
get_response(lynq_call_client_sockfd,p);
pthread_mutex_unlock(&g_lynq_call_sendto_mutex);
JumpHeader(p,&resp_type,&request,&slot_id,&error);
LYINFLOG("resp_type=%d,request=%d,slot_id=%d,error_code=%d",resp_type,request,slot_id,error);
return error;
}
int lynq_call_hungup(int* handle)
{
if(g_lynq_call_init_flag == 0)
{
return -1;
}
Parcel p;
lynq_client_t client;
int resp_type = -1;
int request = -1;
int slot_id = -1;
int error = -1;
int call_id = 0;
int lynq_call_id;
if(handle==NULL||!((*handle>=0)&&(*handle<10)))
{
LYERRLOG("[%s] illegal input!!!!",__FUNCTION__);
return LYNQ_E_CONFLICT;
}
client.uToken = Global_uToken_call;
client.request = 12;//RIL_REQUEST_HUNGUP
client.paramLen = 1;
bzero(client.param,LYNQ_REQUEST_PARAM_BUF);
call_id = *handle;
sprintf(client.param,"%d",call_id);
LYINFLOG("uToken=%d,request=%d,paralen=%d,param=%s",client.uToken,client.request,client.paramLen,client.param);
pthread_mutex_lock(&g_lynq_call_sendto_mutex);
if(send_request(lynq_call_client_sockfd,&client)==-1)
{
LYERRLOG("send request fail");
return -1;
}
get_response(lynq_call_client_sockfd,p);
pthread_mutex_unlock(&g_lynq_call_sendto_mutex);
JumpHeader(p,&resp_type,&request,&slot_id,&error);
LYINFLOG("resp_type=%d,request=%d,slot_id=%d,error_code=%d",resp_type,request,slot_id,error);
if(error==0)
{
lynq_call_id=find_call_id_with_call_id(call_id);
if(lynq_call_id!=INVALID_ID)
{
cleanCallList(lynq_call_id);
}
}
return error;
}
int lynq_call_hungup_all()
{
if(g_lynq_call_init_flag == 0)
{
return -1;
}
Parcel p;
lynq_client_t client;
int resp_type = -1;
int request = -1;
int slot_id = -1;
int error = -1;
client.uToken = Global_uToken_call;
client.request = 17;//RIL_REQUEST_UDUB
client.paramLen = 0;
bzero(client.param,LYNQ_REQUEST_PARAM_BUF);
LYDBGLOG("uToken=%d,request=%d,paralen=%d,param=%s",client.uToken,client.request,client.paramLen,client.param);
pthread_mutex_lock(&g_lynq_call_sendto_mutex);
if(send_request(lynq_call_client_sockfd,&client)==-1)
{
LYERRLOG("send request fail");
return -1;
}
get_response(lynq_call_client_sockfd,p);
pthread_mutex_unlock(&g_lynq_call_sendto_mutex);
JumpHeader(p,&resp_type,&request,&slot_id,&error);
LYINFLOG("resp_type=%d,request=%d,slot_id=%d,error_code=%d",resp_type,request,slot_id,error);
return error;
}
int lynq_wait_incoming_call(int *handle)
{
if(g_lynq_call_init_flag == 0)
{
return -1;
}
waitIncomingCall();
*handle = lynqIncomingCallId;
LYINFLOG("lynq incoming call id:%d",lynqIncomingCallId);
return 0;
}
int lynq_set_auto_answercall(const int mode)
{
if(g_lynq_call_init_flag == 0)
{
return -1;
}
global_call_auto_answer = mode;
LYINFLOG("auto answer call mode =%d",mode);
return 0;
}
int lynq_get_current_call_state(int *handle, int *call_state,int *toa,int *direction,char addr[])
{
if(g_lynq_call_init_flag == 0)
{
return -1;
}
int lynq_call_id = 0;
LYINFLOG("lynq_get_current_call_state begin ");
if(handle==NULL)
{
LYERRLOG("handle is NULL");
return LYNQ_E_NULL_ANONALY;
}
lynq_call_id = find_call_id_with_call_id(*handle);
if(lynq_call_id==INVALID_ID)
{
return LYNQ_E_INVALID_ID_ANONALY;
}
*call_state = lynq_call_lists[lynq_call_id].call_state;
*toa = lynq_call_lists[lynq_call_id].toa;
*direction = lynq_call_lists[lynq_call_id].direction;
memcpy(addr,lynq_call_lists[lynq_call_id].addr,strlen(lynq_call_lists[lynq_call_id].addr)+1);
return 0;
}
/*audio begin*/
static int judge_mic(const int enable){
switch(enable){
case 0:
return 1;
case 1:
return 1;
default:
return 0;
}
}
int lynq_set_mute_mic(const int enable)
{
if(g_lynq_call_init_flag == 0)
{
return -1;
}
if(!judge_mic(enable)){
return LYNQ_E_CONFLICT;
}
return lynq_set_common_request(53,1,"%d",enable); //RIL_REQUEST_SET_MUTE
}
int lynq_get_mute_mic(int *status)
{
if(g_lynq_call_init_flag == 0)
{
return -1;
}
return lynq_get_common_request(54,status);//RIL_REQUEST_GET_MUTE
}
/**
* @brief Check whether DTMF is valid
*
* @param callnum dtmf eg:0-9 * #
* @return int
*/
static int judge_dtmf(const char callnum)
{
if(callnum == '#')
{
return 1;
}
if(callnum == '*')
{
return 1;
}
if(callnum >= '0'&& callnum <= '9')
{
return 1;
}
return 0;
}
int lynq_switch_waiting_or_holding_and_active(void)
{
if(g_lynq_call_init_flag == 0)
{
return -1;
}
Parcel p;
lynq_client_t client;
int resp_type = -1;
int request = -1;
int slot_id = -1;
int error = -1;
client.uToken = Global_uToken_call;
client.request = RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE;
client.paramLen = 0;
bzero(client.param,LYNQ_REQUEST_PARAM_BUF);
LYDBGLOG("uToken=%d,request=%d,paralen=%d,param=%s",client.uToken,client.request,client.paramLen,client.param);
pthread_mutex_lock(&g_lynq_call_sendto_mutex);
if(send_request(lynq_call_client_sockfd,&client)==-1)
{
LYERRLOG("send request fail");
return -1;
}
get_response(lynq_call_client_sockfd,p);
pthread_mutex_unlock(&g_lynq_call_sendto_mutex);
JumpHeader(p,&resp_type,&request,&slot_id,&error);
LYINFLOG("resp_type=%d,request=%d,slot_id=%d,error_code=%d",resp_type,request,slot_id,error);
return error;
}
int lynq_hangup_waiting_or_background(void)
{
if(g_lynq_call_init_flag == 0)
{
return -1;
}
Parcel p;
lynq_client_t client;
int resp_type = -1;
int request = -1;
int slot_id = -1;
int error = -1;
client.uToken = Global_uToken_call;
client.request = RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND;
client.paramLen = 0;
bzero(client.param,LYNQ_REQUEST_PARAM_BUF);
LYDBGLOG("uToken=%d,request=%d,paralen=%d,param=%s",client.uToken,client.request,client.paramLen,client.param);
pthread_mutex_lock(&g_lynq_call_sendto_mutex);
if(send_request(lynq_call_client_sockfd,&client)==-1)
{
LYERRLOG("send request fail");
return -1;
}
get_response(lynq_call_client_sockfd,p);
pthread_mutex_unlock(&g_lynq_call_sendto_mutex);
JumpHeader(p,&resp_type,&request,&slot_id,&error);
LYINFLOG("resp_type=%d,request=%d,slot_id=%d,error_code=%d",resp_type,request,slot_id,error);
return error;
}
int lynq_hangup_foreground_resume_background(void)
{
if(g_lynq_call_init_flag == 0)
{
return -1;
}
Parcel p;
lynq_client_t client;
int resp_type = -1;
int request = -1;
int slot_id = -1;
int error = -1;
client.uToken = Global_uToken_call;
client.request = RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND;
client.paramLen = 0;
bzero(client.param,LYNQ_REQUEST_PARAM_BUF);
LYDBGLOG("uToken=%d,request=%d,paralen=%d,param=%s",client.uToken,client.request,client.paramLen,client.param);
pthread_mutex_lock(&g_lynq_call_sendto_mutex);
if(send_request(lynq_call_client_sockfd,&client)==-1)
{
LYERRLOG("send request fail");
return -1;
}
get_response(lynq_call_client_sockfd,p);
pthread_mutex_unlock(&g_lynq_call_sendto_mutex);
JumpHeader(p,&resp_type,&request,&slot_id,&error);
LYINFLOG("resp_type=%d,request=%d,slot_id=%d,error_code=%d",resp_type,request,slot_id,error);
return error;
}
int lynq_set_DTMF(const char callnum)
{
if(g_lynq_call_init_flag == 0)
{
return -1;
}
if(!judge_dtmf(callnum))
{
return LYNQ_E_CONFLICT;
}
if(!lynq_call_state)
{
LYERRLOG("LYNQ_E_CONFLICT");
return LYNQ_E_CONFLICT;
}
return lynq_set_common_request(24,1,"%c",callnum); //RIL_REQUEST_DTMF
}
static int judge_volume(LYNQ_E_VOLUMN_SET set,const int volume){
if(set==LYNQ_E_VOLUMN_SET_DTMF){
if(volume < 0 ||volume >36){
return 0;
}
}
else if (set==LYNQ_E_VOLUMN_SET_SPEECH)
{
if(volume < 1 ||volume >7){
return 0;
}
}
return 1;
}
int lynq_set_DTMF_volume(const int volume)
{
if(!judge_volume(LYNQ_E_VOLUMN_SET_DTMF,volume)){
return LYNQ_E_CONFLICT;
}
return lynq_set_common_request(8003,1,"%d",volume);//LYNQ_REQUEST_SET_DTMF_VOLUME
}
int lynq_set_speech_volume(const int volume)//mixer_set_volume
{
if(!judge_volume(LYNQ_E_VOLUMN_SET_SPEECH,volume))
{
return LYNQ_E_CONFLICT;
}
return lynq_set_common_request(8009,1,"%d",volume); //LYNQ_REQUEST_SET_SPEECH_VOLUME
}
int lynq_get_speech_volume(int* volumn)//mixer_get_volume
{
return lynq_get_common_request(8010,volumn);//LYNQ_REQUEST_GET_SPEECH_VOLUME
}
int lynq_incall_record_start(const char* file_path)
{
return lynq_set_common_request(8011,2,"%s %s","1",file_path); //LYNQ_REQUEST_RECORD
}
int lynq_incall_record_stop()
{
const char* unused_file="just_ocuupy_paramter_postion";
return lynq_set_common_request(8011,2,"%s %s","0",unused_file); //LYNQ_REQUEST_RECORD
}
/*audio end*/
#ifdef ECALL_SUPPORT
LYNQ_ECall_Variant lynq_get_lynq_ecall_variant_from_lynq_type(LYNQ_ECall_Type type)
{
switch(type)
{
case LYNQ_ECALL_TYPE_TEST:
return LYNQ_ECALL_TEST;
case LYNQ_ECALL_TYPE_RECONFIG:
return LYNQ_ECALL_RECONFIG;
default:
return LYNQ_ECALL_EMERGENCY;
}
}
RIL_ECall_Variant lynq_get_ril_ecall_variant_from_lynq_variant(LYNQ_ECall_Variant type)
{
switch(type)
{
case LYNQ_ECALL_TEST:
return ECALL_TEST;
case LYNQ_ECALL_RECONFIG:
return ECALL_RECONFIG;
default:
return ECALL_EMERGENCY;
}
}
RIL_ECall_Category lynq_get_ril_ecall_cat_from_lynq_cat(LYNQ_ECall_Category cat)
{
switch(cat)
{
case LYNQ_EMER_CAT_MANUAL_ECALL:
return EMER_CAT_MANUAL_ECALL;
default:
return EMER_CAT_AUTO_ECALL;
}
}
int lynq_set_test_num(LYNQ_ECall_Set_Type type, const char *test_num, int test_num_length)
{
int error;
if(test_num==NULL || test_num_length > LYNQ_PHONE_NUMBER_MAX )
{
LYERRLOG("test_num is null or test_num_length %d s greater than %d ",test_num_length,LYNQ_PHONE_NUMBER_MAX);
return -1;
}
error=lynq_set_common_request(RIL_REQUEST_ECALL_SET_TEST_NUM,2,"%d %s",type,test_num);
if(error==0)
{
snprintf(e_call_addr[LYNQ_ECALL_TEST],LYNQ_PHONE_NUMBER_MAX,"%s",test_num);
}
return error;
}
int lynq_fast_ecall(int* handle, LYNQ_ECall_Category lynq_ecall_cat, LYNQ_ECall_Variant lynq_ecall_variant, const char *addr, int addr_length, const unsigned char *msd_data,int msd_length)
{
int error;
RIL_ECall_Variant ril_ecall_variant = lynq_get_ril_ecall_variant_from_lynq_variant (lynq_ecall_variant);
RIL_ECall_Category ril_ecall_cat = lynq_get_ril_ecall_cat_from_lynq_cat(lynq_ecall_cat);
char lynq_msd_data[MSD_MAX_LENGTH*2+1]={0};
unsigned int i;
if(lynq_ecall_is_running())
{
LYERRLOG("lynq_fast_ecall ecall is running");
return LYNQ_E_ECALL_BEING_RUNNING;
}
if(msd_length > MSD_MAX_LENGTH || msd_length <=0)
{
LYERRLOG("lynq_fast_ecall msd_length %d is greater than %d or <= 0, parameter error",msd_length,MSD_MAX_LENGTH);
return LYNQ_E_ECALL_MSD_LENGTH_ERROR;
}
for(i =0; i<msd_length;i++)
{
sprintf(&(lynq_msd_data[i<<1]),"%02x",msd_data[i]);
}
LYINFLOG("lynq_fast_ecall addr is %s",e_call_addr[lynq_ecall_variant]);
error=lynq_set_common_request(RIL_REQUEST_ECALL_FAST_MAKE_ECALL,4,"%d %d %s %s",ril_ecall_cat, ril_ecall_variant, "null", lynq_msd_data);
if(error==0)
{
is_ecall_dial = LYNQ_ECALL_DAILING_STATE_STARTED;
if(waitCallstateChange(270000)==ETIMEDOUT)//4.5 min, dailing 1 min, alerting 1 min, sending msd 30s, redial 2min
{
LYERRLOG("lynq_fast_ecall timeout:wait Call state time out!!!");
is_ecall_dial = LYNQ_ECALL_DAILING_STATE_NONE;
lynqRespWatingEvent();
return LYNQ_E_TIME_OUT;
}
if(is_ecall_dial == LYNQ_ECALL_DAILING_STATE_STARTED)
{
/*just dail, no recv answer*/
LYERRLOG("lynq_fast_ecall, no answer!");
is_ecall_dial = LYNQ_ECALL_DAILING_STATE_NONE;
lynqRespWatingEvent();
return LYNQ_E_ECALL_DAILING_NO_ANSWER;
}
is_ecall_dial = LYNQ_ECALL_DAILING_STATE_NONE;
lynqRespWatingEvent();
if(g_ecallId != INVALID_ID)
{
*handle=g_ecallId;
LYINFLOG("lynq_fast_ecall id is %d",g_ecallId);
return 0;
}
else
{
LYERRLOG("lynq_fast_ecall service return fail");
return LYNQ_E_INVALID_ID_ANONALY;
}
}
return error;
}
int lynq_set_psap(int enable)
{
return lynq_set_common_request(RIL_REQUEST_ECALL_SET_PSAP,1,"%d",enable);
}
int lynq_psap_pull_msd()
{
return lynq_set_common_request(RIL_REQUEST_ECALL_PSAP_PULL_MSD,0,"");
}
int lynq_make_ecall(int* handle, LYNQ_ECall_Type type)
{
LYNQ_ECall_Variant lynq_ecall_variant;
int error = -1;
int lynq_call_id = -1;
if(handle==NULL)
{
LYERRLOG("handle is NULL, parameter error ");
return -1;
}
error=lynq_set_common_request(RIL_REQUEST_ECALL_MAKE_ECALL,1,"%d",type);
if(error==0)
{
lynq_ecall_variant=lynq_get_lynq_ecall_variant_from_lynq_type(type);
lynq_call_id = addAddr(e_call_addr[lynq_ecall_variant]);
isDial = 1;
if(waitCallstateChange(10000)==ETIMEDOUT)//10000ms
{
error = LYNQ_E_TIME_OUT;
LYERRLOG("timeout:wait Call state fail!!!");
return error;
}
*handle = lynq_call_id;
}
return error;
}
int lynq_set_msd(int* handle, const unsigned char *msd_data, int msd_length)
{
char lynq_msd_data[MSD_MAX_LENGTH*2+1]={0};
unsigned int i;
if(handle==NULL || ((*handle) >= LYNQ_CALL_MAX) || msd_length > MSD_MAX_LENGTH || msd_length == 0 || msd_data ==NULL)
{
LYERRLOG("lynq_set_msd handle is NULL or *handle %d is greater or equeal to %d or msd_length %d is greater than %d or msd_data %s is NULL, parameter error",*handle,LYNQ_CALL_MAX,msd_length,MSD_MAX_LENGTH, msd_data);
return -1;
}
for(i=0; i<msd_length;i++)
{
sprintf(&(lynq_msd_data[i<<1]),"%02x",msd_data[i]);
}
LYINFLOG("lynq_set_msd ");
return lynq_set_common_request(RIL_REQUEST_ECALL_SET_MSD,2,"%d %s",lynq_call_lists[(*handle)].call_id,lynq_msd_data);
}
int lynq_set_ivs(int enable)
{
if(enable<0)
{
lynq_set_common_request(RIL_REQUEST_ECALL_SET_IVS,1,"%d",enable);
return 0;
}
return lynq_set_common_request(RIL_REQUEST_ECALL_SET_IVS,1,"%d",enable);
}
int lynq_reset_ivs()
{
return lynq_set_common_request(RIL_REQUEST_ECALL_RESET_IVS,0,"");
}
int lynq_ivs_push_msd()
{
return lynq_set_common_request(RIL_REQUEST_ECALL_IVS_PUSH_MSD,0,"");
}
int wait_ecall_event()
{
int ret = 0;
pthread_mutex_lock(&s_incoming_e_call_mutex);
ret = pthread_cond_wait(&s_incoming_e_call_cond,&s_incoming_e_call_mutex);
pthread_mutex_unlock(&s_incoming_e_call_mutex);
return ret;
}
int lynq_wait_ecall_indication(int* handle, LYNQ_ECall_Indication *eCall_Indication)
{
wait_ecall_event();
*handle = g_lynqIncomingEcallId;
*eCall_Indication = g_lynqIncomingEcallIndication;
LYINFLOG("lynq_wait_ecall_indication handle %d, Ind id: %d", *handle, *eCall_Indication);
return 0;
}
#endif
/*Audio Path setting begin*/
/*sub function*/
void lynq_set_rtp_mixer_ctrl(int enable_rtp)
{
char cmd[256];
LYINFLOG("set_rtp_mixer_ctrl %d", enable_rtp);
if(enable_rtp)
{
sprintf(cmd, "amixer -D mtk_phonecall cset name=\"Speech_on\" %d", 0);
system(cmd);
sprintf(cmd, "amixer -D mtk_phonecall cset name=\"M2M_Speech_on\" %d", 1);
system(cmd);
sprintf(cmd, "amixer -c0 cset name=\"PCM_2_PB_CH1 DL2_CH1\" %d", 1);
system(cmd);
sprintf(cmd, "amixer -c0 cset name=\"PCM_2_PB_CH2 DL2_CH2\" %d", 1);
system(cmd);
sprintf(cmd, "amixer -c0 cset name=\"UL2_CH1 PCM_2_CAP_CH1\" %d", 1);
system(cmd);
sprintf(cmd, "amixer -c0 cset name=\"UL2_CH2 PCM_2_CAP_CH1\" %d", 1);
system(cmd);
}
else
{
sprintf(cmd, "amixer -D mtk_phonecall cset name=\"Speech_on\" %d", 1);
system(cmd);
sprintf(cmd, "amixer -D mtk_phonecall cset name=\"M2M_Speech_on\" %d", 0);
system(cmd);
sprintf(cmd, "amixer -c0 cset name=\"PCM_2_PB_CH1 DL2_CH1\" %d", 0);
system(cmd);
sprintf(cmd, "amixer -c0 cset name=\"PCM_2_PB_CH2 DL2_CH2\" %d", 0);
system(cmd);
sprintf(cmd, "amixer -c0 cset name=\"UL2_CH1 PCM_2_CAP_CH1\" %d", 0);
system(cmd);
sprintf(cmd, "amixer -c0 cset name=\"UL2_CH2 PCM_2_CAP_CH1\" %d", 0);
system(cmd);
}
}
void* lynq_start_rtp_cmd(void *arg)
{
if(g_lynq_call_init_flag == 0)
{
return -1;
}
int* rtp_mode= (int*) arg;
char cmd[384];
LYINFLOG("lynq_start_rtp_cmd: rtp_mode is %d",(*rtp_mode));
if ((*rtp_mode) == RTP_CLIENT)
{
sprintf(cmd,RTP_FROM_CMD, \
g_rtp_client_info.port,g_rtp_client_info.clockrate,g_rtp_client_info.channels, \
g_rtp_client_info.latency);
LYINFLOG("start from rtp play: cmd is %s",cmd);
system(cmd);
}
else if ((*rtp_mode) == RTP_SERVER)
{
sprintf(cmd,RTP_TO_CMD, \
g_rtp_server_info.ip,g_rtp_server_info.port);
LYINFLOG("start to rtp play: cmd is %s",cmd);
system(cmd);
}
return NULL;
}
int lynq_start_rtp_thread(int rtp_mode)
{
int ret;
pthread_attr_t attr;
static int start_mode[RTP_MODE_MAX]={0,1};
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
ret = pthread_create(&(g_rtp_thread[rtp_mode]),&attr,lynq_start_rtp_cmd,&(start_mode[rtp_mode]));
if(ret != 0)
{
g_rtp_thread_valid[rtp_mode]=0;
LYERRLOG("rtp create %d pthread error, ret is %d",rtp_mode, ret);
return ret;
}
g_rtp_thread_valid[rtp_mode]=1;
return 0;
}
/*set*/
int lynq_set_voice_audio_mode(const LYNQ_Audio_Mode audio_mode)
{
if(g_lynq_call_init_flag == 0)
{
return -1;
}
int ret;
int i;
if(audio_mode==AUDIO_MODE_RTP)
{
lynq_set_rtp_mixer_ctrl(1);
for(i=0;i<RTP_MODE_MAX;i++)
{
if(!g_rtp_thread_valid[i])
{
if(lynq_start_rtp_thread(i)!= 0)
{
LYERRLOG("start rtp %d fail",i);
break;
}
else
{
LYINFLOG("start rtp %d suc",i);
}
}
else
{
LYERRLOG("rtp %d needn't start",i);
}
}
if(i!= RTP_MODE_MAX)
{
LYERRLOG("start rtp whole fail");
lynq_set_voice_audio_mode(AUDIO_MODE_CODEC);
return 1;
}
LYINFLOG("start rtp whole suc");
return 0;
}
else if(audio_mode==AUDIO_MODE_CODEC)
{
for(i=0;i<RTP_MODE_MAX;i++)
{
if(g_rtp_thread_valid[i])
{
ret = pthread_cancel(g_rtp_thread[i]);
LYINFLOG("pthread cancel rtp %d ret = %d",i,ret);
ret = pthread_join(g_rtp_thread[i],NULL);
LYINFLOG("pthread join rtp %d ret = %d",i,ret);
g_rtp_thread_valid[i] = 0;
}
else
{
LYINFLOG("rtp %d needn't stop",i);
}
}
lynq_set_rtp_mixer_ctrl(0);
LYINFLOG("stop rtp suc");
}
return 0;
}
int lynq_set_remote_rtp_ip(const char* ip, const int ip_length)
{
if (NULL == ip)
{
LYERRLOG("ip is NULL!!!");
return -1;
}
if ((ip_length < strlen(ip)+1) || (ip_length > MAX_IP_LENGTH))
{
LYERRLOG("incoming ip length error %d", ip_length);
return -1;
}
bzero(g_rtp_server_info.ip,MAX_IP_LENGTH);
strcpy(g_rtp_server_info.ip,ip);
LYINFLOG("lynq_set_remote_rtp_ip suc: ip is %s, length is %d", ip,ip_length);
return 0;
}
int lynq_set_rtp_port(const LYNQ_Rtp_Mode rtp_mode, const int port)
{
if (port < 0)
{
LYERRLOG("invalid port number %d", port);
return -1;
}
if (rtp_mode == 0)
{
g_rtp_client_info.port = port;
}
else if (rtp_mode == 1)
{
g_rtp_server_info.port = port;
}
LYINFLOG("lynq_set_rtp_port suc: LYNQ_Rtp_Mode is %d, port is %d", rtp_mode, port);
return 0;
}
int lynq_set_rtp_param(const int clock_rate,const int channels,const int latency) //only for client mode
{
g_rtp_client_info.clockrate = clock_rate;
g_rtp_client_info.channels = channels;
g_rtp_client_info.latency = latency;
LYINFLOG("lynq_set_rtp_param suc: clockrate is %d, channels is %d, latency is %d", clock_rate, channels, latency);
return 0;
}
/*get*/
LYNQ_Audio_Mode lynq_get_voice_audio_mode()
{
if(g_lynq_call_init_flag == 0)
{
return -1;
}
if(g_rtp_thread_valid[0])
{
return AUDIO_MODE_RTP;
}
else
{
return AUDIO_MODE_CODEC;
}
}
int lynq_get_remote_rtp_ip(char* ip, const int ip_length)
{
if(g_lynq_call_init_flag == 0)
{
return -1;
}
if(ip==NULL)
{
LYERRLOG("ip is NULL");
return 1;
}
if(ip_length < strlen(g_rtp_server_info.ip)+1)
{
LYERRLOG("ip lenght %d is shorter than saved ip length %d",ip_length,strlen(g_rtp_server_info.ip)+1);
return 1;
}
bzero(ip,ip_length);
strcpy(ip,g_rtp_server_info.ip);
return 0;
}
int lynq_get_rtp_port(const LYNQ_Rtp_Mode rtp_mode, int* port)
{
if(g_lynq_call_init_flag == 0)
{
return -1;
}
if(port==NULL)
{
return 1;
}
if (rtp_mode == 0)
{
*port = g_rtp_client_info.port;
}
else if (rtp_mode == 1)
{
*port = g_rtp_server_info.port;
}
return 0;
}
int lynq_get_rtp_param(int* clock_rate, int* channels, int* latency)//only for client mode
{
if(g_lynq_call_init_flag == 0)
{
return -1;
}
if(clock_rate == NULL || channels ==NULL || latency ==NULL)
{
LYERRLOG("input parameter is NULL");
return 1;
}
*clock_rate = g_rtp_client_info.clockrate;
*channels = g_rtp_client_info.channels ;
*latency = g_rtp_client_info.latency;
return 0;
}
/*Audio Path setting end*/
#if 0
int main(int argc,char **argv)
{
int n = 0;
n = lynq_init_call(lynq_call_state_change_test,2222);
if(n<0)
{
LYDBGLOG("lynq init call fail!!!");
return -1;
}
LYDBGLOG("lynq call init success!!!");
char phoneNum[LYNQ_PHONE_NUMBER_MAX];
sprintf(phoneNum,"18180053406 0",strlen("18180053406 0")+1);
lynq_call(phoneNum);
while(1)
{
sleep(1);
}
return 0;
}
#endif
/*Warren add for T800 platform 2021/11/19 end*/