blob: e22b01689f8d7f5d972ab68b18afd414512583f6 [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 "lynq_call.h"
#include "lynq_module_common.h"
#include "lynq_call_common.h"
#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 %s auto-multicast=true port=%d"
#define RTP_VLAN_INFO_FORMAT "multicast-iface=\"%s\""
#define USER_LOG_TAG "LYNQ_CALL"
typedef struct
{
char ip[MAX_IP_LENGTH];
int port;
char vlan_info[MAX_VLAN_INFO_LENGTH];
}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];
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;
}
/*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=\"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);
sprintf(cmd, "amixer -D mtk_phonecall cset name=\"Speech_on\" %d", 1);
system(cmd);
}
}
void* lynq_start_rtp_cmd(void *arg)
{
int* rtp_mode= (int*) arg;
char cmd[384];
char vlan_para_string[sizeof(RTP_VLAN_INFO_FORMAT)+MAX_VLAN_INFO_LENGTH-2/*sizeof "%s"*/]={0};
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)
{
if(strlen(g_rtp_server_info.vlan_info)>0)
{
sprintf(vlan_para_string,RTP_VLAN_INFO_FORMAT,g_rtp_server_info.vlan_info);
}
sprintf(cmd,RTP_TO_CMD, \
g_rtp_server_info.ip,vlan_para_string,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 RESULT_OK;
}
/*set*/
int lynq_set_voice_audio_mode(const LYNQ_Audio_Mode audio_mode)
{
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 RESULT_ERROR;
}
LYINFLOG("start rtp whole suc");
return RESULT_OK;
}
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 RESULT_OK;
}
int lynq_set_remote_rtp_ip(const char* ip, const int ip_length)
{
if (NULL == ip)
{
LYERRLOG("ip is NULL!!!");
return LYNQ_E_PARAMETER_ANONALY;
}
if ((ip_length < strlen(ip)+1) || (ip_length > MAX_IP_LENGTH))
{
LYERRLOG("incoming ip length error %d", ip_length);
return LYNQ_E_PARAMETER_ANONALY;
}
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 RESULT_OK;
}
int lynq_set_vlan_info(const char* vlan_info, const int vlan_info_length)
{
if (NULL == vlan_info)
{
LYERRLOG("vlan_info is NULL!!!");
return LYNQ_E_PARAMETER_ANONALY;
}
if ((vlan_info_length < strlen(vlan_info)+1) || (vlan_info_length > MAX_VLAN_INFO_LENGTH))
{
LYERRLOG("incoming vlan_info error, vlan info length %d", vlan_info_length);
return LYNQ_E_PARAMETER_ANONALY;
}
bzero(g_rtp_server_info.vlan_info,MAX_VLAN_INFO_LENGTH);
strcpy(g_rtp_server_info.vlan_info,vlan_info);
LYINFLOG("lynq_set_vlan_info suc: vlan is %s, length is %d", vlan_info,vlan_info_length);
return RESULT_OK;
}
int lynq_set_rtp_port(const LYNQ_Rtp_Mode rtp_mode, const int port)
{
if (port < 0)
{
LYERRLOG("invalid port number %d", port);
return LYNQ_E_PARAMETER_ANONALY;
}
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 RESULT_OK;
}
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 RESULT_OK;
}
/*get*/
LYNQ_Audio_Mode lynq_get_voice_audio_mode()
{
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(ip==NULL)
{
LYERRLOG("ip is NULL");
return LYNQ_E_PARAMETER_ANONALY;
}
if(ip_length < strlen(g_rtp_server_info.ip)+1)
{
LYERRLOG("ip length %d is shorter than saved ip length %d",ip_length,strlen(g_rtp_server_info.ip)+1);
return LYNQ_E_PARAMETER_ANONALY;
}
bzero(ip,ip_length);
strcpy(ip,g_rtp_server_info.ip);
return RESULT_OK;
}
int lynq_get_vlan_info(char* vlan_info, const int vlan_info_length)
{
if(vlan_info==NULL)
{
LYERRLOG("vlan info is NULL");
return LYNQ_E_PARAMETER_ANONALY;
}
if(vlan_info_length < strlen(g_rtp_server_info.vlan_info)+1)
{
LYERRLOG("vlan info length %d is shorter than saved vlan info length %d",vlan_info_length,strlen(g_rtp_server_info.vlan_info)+1);
return LYNQ_E_PARAMETER_ANONALY;
}
bzero(vlan_info,vlan_info_length);
strcpy(vlan_info,g_rtp_server_info.vlan_info);
return RESULT_OK;
}
int lynq_get_rtp_port(const LYNQ_Rtp_Mode rtp_mode, int* port)
{
if(port==NULL)
{
return LYNQ_E_PARAMETER_ANONALY;
}
if (rtp_mode == 0)
{
*port = g_rtp_client_info.port;
}
else if (rtp_mode == 1)
{
*port = g_rtp_server_info.port;
}
return RESULT_OK;
}
int lynq_get_rtp_param(int* clock_rate, int* channels, int* latency)//only for client mode
{
if(clock_rate == NULL || channels ==NULL || latency ==NULL)
{
LYERRLOG("input parameter is NULL");
return LYNQ_E_PARAMETER_ANONALY;
}
*clock_rate = g_rtp_client_info.clockrate;
*channels = g_rtp_client_info.channels ;
*latency = g_rtp_client_info.latency;
return RESULT_OK;
}