mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-21 13:08:08 +00:00
Merge branch 'dev_rtt'
This commit is contained in:
commit
b5d0667594
38 changed files with 2046 additions and 229 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -50,6 +50,10 @@ coreapi/help/chatroom
|
|||
coreapi/help/doc/
|
||||
coreapi/help/helloworld
|
||||
coreapi/help/registration
|
||||
coreapi/help/realtimetext_receiver
|
||||
coreapi/help/realtimetext_sender
|
||||
coreapi/test_ecc
|
||||
coreapi/test_lsd
|
||||
gtk/version_date.h
|
||||
specs.c
|
||||
*.orig
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ static void sdp_process(SalOp *h){
|
|||
/*for backward compatibility purpose*/
|
||||
if(h->cnx_ip_to_0000_if_sendonly_enabled && sal_media_description_has_dir(h->result,SalStreamSendOnly)) {
|
||||
set_addr_to_0000(h->result->addr);
|
||||
for(i=0;i<h->result->nb_streams;++i){
|
||||
for(i=0;i<SAL_MEDIA_DESCRIPTION_MAX_STREAMS;++i){
|
||||
if (h->result->streams[i].dir == SalStreamSendOnly)
|
||||
set_addr_to_0000(h->result->streams[i].rtp_addr);
|
||||
set_addr_to_0000(h->result->streams[i].rtcp_addr);
|
||||
|
|
@ -78,7 +78,7 @@ static void sdp_process(SalOp *h){
|
|||
strcpy(h->result->addr,h->base.remote_media->addr);
|
||||
h->result->bandwidth=h->base.remote_media->bandwidth;
|
||||
|
||||
for(i=0;i<h->result->nb_streams;++i){
|
||||
for(i=0;i<SAL_MEDIA_DESCRIPTION_MAX_STREAMS;++i){
|
||||
/*copy back parameters from remote description that we need in our result description*/
|
||||
if (h->result->streams[i].rtp_port!=0){ /*if stream was accepted*/
|
||||
strcpy(h->result->streams[i].rtp_addr,h->base.remote_media->streams[i].rtp_addr);
|
||||
|
|
|
|||
|
|
@ -416,7 +416,8 @@ belle_sdp_session_description_t * media_description_to_sdp ( const SalMediaDescr
|
|||
belle_sdp_session_description_add_attribute(session_desc, create_rtcp_xr_attribute(&desc->rtcp_xr));
|
||||
}
|
||||
|
||||
for ( i=0; i<desc->nb_streams; i++ ) {
|
||||
for ( i=0; i<SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++ ) {
|
||||
if (!sal_stream_description_active(&desc->streams[i])) continue;
|
||||
stream_description_to_sdp(session_desc, desc, &desc->streams[i]);
|
||||
}
|
||||
return session_desc;
|
||||
|
|
@ -739,6 +740,8 @@ static SalStreamDescription * sdp_to_stream_description(SalMediaDescription *md,
|
|||
stream->type=SalAudio;
|
||||
} else if ( strcasecmp ( "video", mtype ) == 0 ) {
|
||||
stream->type=SalVideo;
|
||||
} else if ( strcasecmp ( "text", mtype ) == 0 ) {
|
||||
stream->type=SalText;
|
||||
} else {
|
||||
stream->type=SalOther;
|
||||
strncpy ( stream->typeother,mtype,sizeof ( stream->typeother )-1 );
|
||||
|
|
|
|||
|
|
@ -266,6 +266,7 @@ LinphoneCallParams * linphone_call_params_new(void) {
|
|||
LinphoneCallParams *cp=belle_sip_object_new(LinphoneCallParams);
|
||||
cp->audio_dir=LinphoneMediaDirectionSendRecv;
|
||||
cp->video_dir=LinphoneMediaDirectionSendRecv;
|
||||
cp->realtimetext_enabled = FALSE;
|
||||
return cp;
|
||||
}
|
||||
|
||||
|
|
@ -282,3 +283,12 @@ BELLE_SIP_INSTANCIATE_VPTR(LinphoneCallParams, belle_sip_object_t,
|
|||
NULL, // marshal
|
||||
FALSE
|
||||
);
|
||||
|
||||
int linphone_call_params_enable_realtime_text(LinphoneCallParams *params, bool_t yesno) {
|
||||
params->realtimetext_enabled=yesno;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool_t linphone_call_params_realtime_text_enabled(const LinphoneCallParams *params) {
|
||||
return params->realtimetext_enabled;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -348,14 +348,31 @@ LINPHONE_PUBLIC bool_t linphone_call_params_audio_multicast_enabled(const Linpho
|
|||
* @param yesno if yes, subsequent outgoing calls will propose multicast ip set by #linphone_core_set_video_multicast_addr
|
||||
* @ingroup media_parameters
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_call_params_enable_video_multicast(LinphoneCallParams *param, bool_t yesno);
|
||||
LINPHONE_PUBLIC void linphone_call_params_enable_video_multicast(LinphoneCallParams *params, bool_t yesno);
|
||||
/**
|
||||
* Use to get multicast state of video stream.
|
||||
* @param core #LinphoneCallParams
|
||||
* @param params #LinphoneCallParams
|
||||
* @return true if subsequent calls will propose multicast ip set by #linphone_core_set_video_multicast_addr
|
||||
* @ingroup media_parameters
|
||||
**/
|
||||
LINPHONE_PUBLIC bool_t linphone_call_params_video_multicast_enabled(const LinphoneCallParams *param);
|
||||
LINPHONE_PUBLIC bool_t linphone_call_params_video_multicast_enabled(const LinphoneCallParams *params);
|
||||
|
||||
/**
|
||||
* Use to enable real time text following rfc4103.
|
||||
* If enabled, outgoing calls put a m=text line in SDP offer .
|
||||
* @param params #LinphoneCallParams
|
||||
* @param yesno if yes, subsequent outgoing calls will propose rtt
|
||||
* @ingroup media_parameters
|
||||
**/
|
||||
LINPHONE_PUBLIC int linphone_call_params_enable_realtime_text(LinphoneCallParams *params, bool_t yesno);
|
||||
|
||||
/**
|
||||
* Use to get real time text following rfc4103.
|
||||
* @param params #LinphoneCallParams
|
||||
* @returns returns true if call rtt is activated.
|
||||
* @ingroup media_parameters
|
||||
**/
|
||||
LINPHONE_PUBLIC bool_t linphone_call_params_realtime_text_enabled(const LinphoneCallParams *params);
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ void linphone_core_update_streams_destinations(LinphoneCore *lc, LinphoneCall *c
|
|||
char *rtp_addr, *rtcp_addr;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < new_md->nb_streams; i++) {
|
||||
for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) {
|
||||
if (!sal_stream_description_active(&new_md->streams[i])) continue;
|
||||
if (new_md->streams[i].type == SalAudio) {
|
||||
new_audiodesc = &new_md->streams[i];
|
||||
|
|
@ -188,8 +188,9 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia
|
|||
linphone_call_stop_media_streams (call);
|
||||
if (md_changed & SAL_MEDIA_DESCRIPTION_NETWORK_XXXCAST_CHANGED){
|
||||
ms_message("Media ip type has changed, destroying sessions context on call [%p]",call);
|
||||
ms_media_stream_sessions_uninit(&call->sessions[0]);
|
||||
ms_media_stream_sessions_uninit(&call->sessions[1]);
|
||||
ms_media_stream_sessions_uninit(&call->sessions[call->main_audio_stream_index]);
|
||||
ms_media_stream_sessions_uninit(&call->sessions[call->main_video_stream_index]);
|
||||
if (call->params->realtimetext_enabled) ms_media_stream_sessions_uninit(&call->sessions[call->main_text_stream_index]);
|
||||
}
|
||||
linphone_call_init_media_streams (call);
|
||||
}
|
||||
|
|
@ -368,7 +369,7 @@ static void try_early_media_forking(LinphoneCall *call, SalMediaDescription *md)
|
|||
SalStreamDescription *ref_stream,*new_stream;
|
||||
ms_message("Early media response received from another branch, checking if media can be forked to this new destination.");
|
||||
|
||||
for (i=0;i<cur_md->nb_streams;++i){
|
||||
for (i=0;i<SAL_MEDIA_DESCRIPTION_MAX_STREAMS;++i){
|
||||
if (!sal_stream_description_active(&cur_md->streams[i])) continue;
|
||||
ref_stream=&cur_md->streams[i];
|
||||
new_stream=&md->streams[i];
|
||||
|
|
|
|||
103
coreapi/chat.c
103
coreapi/chat.c
|
|
@ -540,6 +540,11 @@ static void _linphone_chat_room_destroy(LinphoneChatRoom *cr) {
|
|||
}
|
||||
}
|
||||
linphone_address_destroy(cr->peer_url);
|
||||
if (cr->pending_message)
|
||||
linphone_chat_message_destroy(cr->pending_message);
|
||||
if (cr->call)
|
||||
linphone_call_unref(cr->call);
|
||||
|
||||
ms_free(cr->peer);
|
||||
}
|
||||
|
||||
|
|
@ -572,10 +577,18 @@ void linphone_chat_room_set_user_data(LinphoneChatRoom *cr, void *ud) {
|
|||
static void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatMessage *msg) {
|
||||
SalOp *op = NULL;
|
||||
LinphoneCall *call;
|
||||
char *content_type;
|
||||
const char *identity = NULL;
|
||||
time_t t = time(NULL);
|
||||
char* content_type;
|
||||
const char *identity=NULL;
|
||||
time_t t=time(NULL);
|
||||
/*stubed rtt text*/
|
||||
if (cr->call && linphone_call_params_realtime_text_enabled(linphone_call_get_current_params(cr->call))) {
|
||||
char crlf[4]="CRLF";
|
||||
linphone_chat_message_put_char(msg,*(uint32_t*)crlf); /*CRLF*/
|
||||
msg->state = LinphoneChatMessageStateDelivered;
|
||||
return ;
|
||||
}
|
||||
linphone_chat_message_ref(msg);
|
||||
|
||||
/* Check if we shall upload a file to a server */
|
||||
if (msg->file_transfer_information != NULL && msg->content_type == NULL) {
|
||||
/* open a transaction with the server and send an empty request(RCS5.1 section 3.5.4.8.3.1) */
|
||||
|
|
@ -938,6 +951,51 @@ void linphone_core_is_composing_received(LinphoneCore *lc, SalOp *op, const SalI
|
|||
LinphoneAddress *addr = linphone_address_new(is_composing->from);
|
||||
LinphoneChatRoom *cr = _linphone_core_get_chat_room(lc, addr);
|
||||
if (cr != NULL) {
|
||||
/*rtt stub*/
|
||||
LinphoneCall *call = linphone_core_find_call_from_uri(lc,cr->peer);
|
||||
if (call && linphone_call_params_realtime_text_enabled(linphone_call_get_current_params(call))) {
|
||||
const char * rtt;
|
||||
if (cr->call == NULL) {
|
||||
/*attach cr to call*/
|
||||
cr->call = call;
|
||||
linphone_call_ref(cr->call);
|
||||
}
|
||||
if (cr->pending_message == NULL) {
|
||||
cr->pending_message = linphone_chat_room_create_message(cr,"");
|
||||
}
|
||||
|
||||
rtt = sal_custom_header_find(sal_op_get_recv_custom_header(op),"X-RTT");
|
||||
if (rtt) {
|
||||
if (strcmp(rtt,"CRLF")==0) {
|
||||
LinphoneChatMessage *msg = cr->pending_message;
|
||||
/*forge a message*/
|
||||
linphone_chat_message_set_from(msg, cr->peer_url);
|
||||
|
||||
{
|
||||
LinphoneAddress *to;
|
||||
to=sal_op_get_to(op) ? linphone_address_new(sal_op_get_to(op)) : linphone_address_new(linphone_core_get_identity(lc));
|
||||
msg->to=to;
|
||||
}
|
||||
|
||||
msg->time=ms_time(0);
|
||||
msg->state=LinphoneChatMessageStateDelivered;
|
||||
msg->is_read=FALSE;
|
||||
msg->dir=LinphoneChatMessageIncoming;
|
||||
msg->storage_id=linphone_chat_message_store(msg);
|
||||
|
||||
if(cr->unread_count < 0) cr->unread_count = 1;
|
||||
else cr->unread_count++;
|
||||
|
||||
linphone_chat_room_message_received(cr,lc,msg);
|
||||
linphone_chat_message_unref(msg);
|
||||
cr->pending_message=NULL;
|
||||
} else if (strcmp(rtt,"S P")==0) {
|
||||
cr->pending_message->message=ms_strcat_printf(cr->pending_message->message," ");
|
||||
} else {
|
||||
cr->pending_message->message=ms_strcat_printf(cr->pending_message->message,rtt);
|
||||
}
|
||||
}
|
||||
}
|
||||
linphone_chat_room_notify_is_composing(cr, is_composing->text);
|
||||
}
|
||||
linphone_address_destroy(addr);
|
||||
|
|
@ -1091,6 +1149,42 @@ static void linphone_chat_room_send_is_composing_notification(LinphoneChatRoom *
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t linphone_chat_room_get_char(const LinphoneChatRoom *cr) {
|
||||
if (cr->pending_message && strlen(cr->pending_message->message) > 0 ) {
|
||||
return cr->pending_message->message[strlen(cr->pending_message->message)-1];
|
||||
} else return 0;
|
||||
}
|
||||
int linphone_chat_message_put_char(LinphoneChatMessage *msg,uint32_t charater) {
|
||||
/*stubbed implementation using im-iscomposing+xml*/
|
||||
LinphoneChatRoom *cr=linphone_chat_message_get_chat_room(msg);
|
||||
char *content;
|
||||
SalOp *op = sal_op_new(cr->lc->sal);
|
||||
char* value;
|
||||
const char* from;
|
||||
LinphoneCall *call = cr->call;
|
||||
cr->is_composing = LinphoneIsComposingActive;
|
||||
content = linphone_chat_room_create_is_composing_xml(cr);
|
||||
linphone_configure_op(cr->lc, op, cr->peer_url, NULL, lp_config_get_int(cr->lc->config, "sip", "chat_msg_with_contact", 0));
|
||||
if (charater==' ')
|
||||
value=ms_strdup("S P");
|
||||
else
|
||||
value=ms_strdup_printf("%c%c%c%c",((char*)&charater)[0],((char*)&charater)[1],((char*)&charater)[2],((char*)&charater)[3]);
|
||||
sal_op_set_sent_custom_header(op,sal_custom_header_append(NULL,"X-RTT",value));
|
||||
ms_free(value);
|
||||
if (call->dir==LinphoneCallOutgoing) {
|
||||
from = sal_op_get_from(call->op);
|
||||
} else {
|
||||
from = sal_op_get_to(call->op);
|
||||
}
|
||||
sal_message_send(op
|
||||
, from
|
||||
, cr->peer
|
||||
, "application/im-iscomposing+xml"
|
||||
, content
|
||||
, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int linphone_chat_room_stop_composing(void *data, unsigned int revents) {
|
||||
LinphoneChatRoom *cr = (LinphoneChatRoom *)data;
|
||||
cr->is_composing = LinphoneIsComposingIdle;
|
||||
|
|
@ -1559,3 +1653,6 @@ LinphoneChatMessage *linphone_chat_room_create_file_transfer_message(LinphoneCha
|
|||
msg->http_request = NULL; /* this will store the http request during file upload to the server */
|
||||
return msg;
|
||||
}
|
||||
LinphoneCall *linphone_chat_room_get_call(const LinphoneChatRoom *room) {
|
||||
return room->call;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ clean-local:
|
|||
|
||||
if ENABLE_TUTORIALS
|
||||
|
||||
noinst_PROGRAMS=helloworld registration buddy_status chatroom notify filetransfer
|
||||
noinst_PROGRAMS=helloworld registration buddy_status chatroom notify filetransfer realtimetext_sender realtimetext_receiver
|
||||
|
||||
helloworld_SOURCES=helloworld.c
|
||||
LINPHONE_TUTOS=$(helloworld_SOURCES)
|
||||
|
|
@ -81,6 +81,16 @@ LINPHONE_TUTOS+=$(filetransfer_SOURCES)
|
|||
|
||||
filetransfer_LDADD=$(helloworld_LDADD)
|
||||
|
||||
realtimetext_sender_SOURCES=realtimetext_sender.c
|
||||
LINPHONE_TUTOS+=$(realtimetext_sender_SOURCES)
|
||||
|
||||
realtimetext_sender_LDADD=$(helloworld_LDADD)
|
||||
|
||||
realtimetext_receiver_SOURCES=realtimetext_receiver.c
|
||||
LINPHONE_TUTOS+=$(realtimetext_receiver_SOURCES)
|
||||
|
||||
realtimetext_receiver_LDADD=$(helloworld_LDADD)
|
||||
|
||||
AM_CFLAGS=\
|
||||
-I$(top_srcdir)/coreapi \
|
||||
$(STRICT_OPTIONS) \
|
||||
|
|
|
|||
115
coreapi/help/realtimetext_receiver.c
Normal file
115
coreapi/help/realtimetext_receiver.c
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
|
||||
/*
|
||||
linphone
|
||||
Copyright (C) 2015 Belledonne Communications SARL
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup real_time_text Real Time Text Receiver
|
||||
* @ingroup tutorials
|
||||
This program is able to receive chat message in real time on port 5060. Use realtimetext_sender to generate chat message
|
||||
usage: ./realtimetext_receiver
|
||||
|
||||
@include realtimetext_sender.c
|
||||
*/
|
||||
#ifdef IN_LINPHONE
|
||||
#include "linphonecore.h"
|
||||
#else
|
||||
#include "linphone/linphonecore.h"
|
||||
#endif
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
static bool_t running=TRUE;
|
||||
|
||||
static void stop(int signum){
|
||||
running=FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Call state notification callback
|
||||
*/
|
||||
static void call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *msg){
|
||||
switch(cstate){
|
||||
case LinphoneCallIncomingReceived:
|
||||
printf("It is now ringing remotely !\n");
|
||||
linphone_core_accept_call(lc,call);
|
||||
break;
|
||||
case LinphoneCallReleased:
|
||||
printf("call terminated, exit...\n");
|
||||
running=FALSE;
|
||||
break;
|
||||
default:
|
||||
printf("Unhandled notification %i\n",cstate);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Completed message received
|
||||
*/
|
||||
static void message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *message) {
|
||||
char *from=linphone_address_as_string(linphone_chat_room_get_peer_address(room));
|
||||
printf(" Message [%s] received from [%s] \n",linphone_chat_message_get_text(message),from);
|
||||
ms_free(from);
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* Remote is typing
|
||||
*/
|
||||
static void is_composing_received(LinphoneCore *lc, LinphoneChatRoom *room) {
|
||||
LinphoneCall *call = linphone_chat_room_get_call(room); /*get corresponding call*/
|
||||
if (call && linphone_call_params_realtime_text_enabled(linphone_call_get_current_params(call))) /*check if realtime text enabled for this call*/
|
||||
printf("%c",linphone_chat_room_get_char(room));
|
||||
/*else ignored*/
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]){
|
||||
LinphoneCoreVTable vtable={0};
|
||||
LinphoneCore *lc;
|
||||
|
||||
|
||||
signal(SIGINT,stop);
|
||||
|
||||
#ifdef DEBUG
|
||||
linphone_core_enable_logs(NULL); /*enable liblinphone logs.*/
|
||||
#endif
|
||||
/*
|
||||
Fill the LinphoneCoreVTable with application callbacks.
|
||||
All are optional. Here we only use the call_state_changed callbacks
|
||||
in order to get notifications about the progress of the call.
|
||||
*/
|
||||
vtable.call_state_changed=call_state_changed; /*to receive incoming call*/
|
||||
vtable.message_received=message_received; /*to receive committed messages*/
|
||||
vtable.is_composing_received=is_composing_received; /*to receive char in real time*/
|
||||
/*
|
||||
Instanciate a LinphoneCore object given the LinphoneCoreVTable
|
||||
*/
|
||||
lc=linphone_core_new(&vtable,NULL,NULL,NULL);
|
||||
|
||||
/* main loop for receiving notifications and doing background linphonecore work: */
|
||||
while(running){
|
||||
linphone_core_iterate(lc);
|
||||
ms_usleep(50000);
|
||||
}
|
||||
|
||||
printf("Shutting down...\n");
|
||||
linphone_core_destroy(lc);
|
||||
printf("Exited\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
153
coreapi/help/realtimetext_sender.c
Normal file
153
coreapi/help/realtimetext_sender.c
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
|
||||
/*
|
||||
linphone
|
||||
Copyright (C) 2015 Belledonne Communications SARL
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup real_time_text Real Time Text Sender
|
||||
* @ingroup tutorials
|
||||
This program just send chat message in real time to dest uri. Use realtimetext_receiver to receive message.
|
||||
usage: ./realtimetext_sender sip:localhost:5060
|
||||
|
||||
|
||||
@include realtimetext_sender.c
|
||||
*/
|
||||
#ifdef IN_LINPHONE
|
||||
#include "linphonecore.h"
|
||||
#else
|
||||
#include "linphone/linphonecore.h"
|
||||
#endif
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
static bool_t running=TRUE;
|
||||
|
||||
static void stop(int signum){
|
||||
running=FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(int argc, char *argv[]){
|
||||
LinphoneCoreVTable vtable={0};
|
||||
LinphoneCore *lc;
|
||||
LinphoneCall *call=NULL;
|
||||
LinphoneChatRoom *chat_room;
|
||||
LinphoneChatMessage *chat_message=NULL;
|
||||
const char *dest=NULL;
|
||||
LCSipTransports tp;
|
||||
tp.udp_port=LC_SIP_TRANSPORT_RANDOM;
|
||||
tp.tcp_port=LC_SIP_TRANSPORT_RANDOM;
|
||||
tp.tls_port=LC_SIP_TRANSPORT_RANDOM;
|
||||
|
||||
/* take the destination sip uri from the command line arguments */
|
||||
if (argc>1){
|
||||
dest=argv[1];
|
||||
}
|
||||
|
||||
signal(SIGINT,stop);
|
||||
|
||||
#ifdef DEBUG
|
||||
linphone_core_enable_logs(NULL); /*enable liblinphone logs.*/
|
||||
#endif
|
||||
|
||||
/*
|
||||
Instanciate a LinphoneCore object given the LinphoneCoreVTable
|
||||
*/
|
||||
lc=linphone_core_new(&vtable,NULL,NULL,NULL);
|
||||
|
||||
|
||||
linphone_core_set_sip_transports(lc,&tp); /*to avoid port colliding with receiver*/
|
||||
if (dest){
|
||||
/*
|
||||
Place an outgoing call with rtt enabled
|
||||
*/
|
||||
LinphoneCallParams *cp = linphone_core_create_default_call_parameters(lc);
|
||||
linphone_call_params_enable_realtime_text(cp,TRUE); /*enable real time text*/
|
||||
call=linphone_core_invite_with_params(lc,dest,cp);
|
||||
linphone_call_params_destroy(cp);
|
||||
if (call==NULL){
|
||||
printf("Could not place call to %s\n",dest);
|
||||
goto end;
|
||||
}else printf("Call to %s is in progress...",dest);
|
||||
linphone_call_ref(call);
|
||||
|
||||
}
|
||||
/*wait for call to be established*/
|
||||
while (running && (linphone_call_get_state(call) == LinphoneCallOutgoingProgress
|
||||
|| linphone_call_get_state(call) == LinphoneCallOutgoingInit)) {
|
||||
linphone_core_iterate(lc);
|
||||
ms_usleep(50000);
|
||||
}
|
||||
/*check if call is established*/
|
||||
switch (linphone_call_get_state(call)) {
|
||||
case LinphoneCallError:
|
||||
case LinphoneCallReleased:
|
||||
case LinphoneCallEnd:
|
||||
printf("Could not place call to %s\n",dest);
|
||||
goto end;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
/*continue*/
|
||||
}
|
||||
|
||||
chat_room=linphone_call_get_chat_room(call); /*create a chat room associated to this call*/
|
||||
|
||||
/* main loop for sending message and doing background linphonecore work: */
|
||||
while(running){
|
||||
char character;
|
||||
system ("/bin/stty raw"); /*to disable terminal buffering*/
|
||||
character = getchar();
|
||||
system ("/bin/stty cooked");
|
||||
if (character==0x03) {/*CTRL C*/
|
||||
running=0;
|
||||
break;
|
||||
}
|
||||
if (character != EOF) {
|
||||
/* user has typed something*/
|
||||
if (chat_message == NULL) {
|
||||
/*create a new message*/
|
||||
chat_message = linphone_chat_room_create_message(chat_room,""); /*create an empty message*/
|
||||
}
|
||||
if (character == '\r') {
|
||||
/*new line, committing message*/
|
||||
linphone_chat_room_send_chat_message(chat_room,chat_message);
|
||||
chat_message = NULL; /*reset message*/
|
||||
} else {
|
||||
linphone_chat_message_put_char(chat_message,character); /*send char in realtime*/
|
||||
}
|
||||
}
|
||||
linphone_core_iterate(lc);
|
||||
ms_usleep(50000);
|
||||
}
|
||||
if (call && linphone_call_get_state(call)!=LinphoneCallEnd){
|
||||
/* terminate the call */
|
||||
printf("Terminating the call...\n");
|
||||
linphone_core_terminate_call(lc,call);
|
||||
/*at this stage we don't need the call object */
|
||||
linphone_call_unref(call);
|
||||
}
|
||||
|
||||
end:
|
||||
printf("Shutting down...\n");
|
||||
linphone_core_destroy(lc);
|
||||
printf("Exited\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1027,6 +1027,15 @@ static void rtp_config_read(LinphoneCore *lc)
|
|||
linphone_core_set_video_port(lc, min_port);
|
||||
}
|
||||
|
||||
if (lp_config_get_range(lc->config, "rtp", "text_rtp_port", &min_port, &max_port, 11078, 11078) == TRUE) {
|
||||
if (min_port <= 0) min_port = 1;
|
||||
if (max_port > 65535) max_port = 65535;
|
||||
linphone_core_set_text_port_range(lc, min_port, max_port);
|
||||
} else {
|
||||
min_port = lp_config_get_int(lc->config, "rtp", "text_rtp_port", 11078);
|
||||
linphone_core_set_text_port(lc, min_port);
|
||||
}
|
||||
|
||||
jitt_comp=lp_config_get_int(lc->config,"rtp","audio_jitt_comp",60);
|
||||
linphone_core_set_audio_jittcomp(lc,jitt_comp);
|
||||
jitt_comp=lp_config_get_int(lc->config,"rtp","video_jitt_comp",60);
|
||||
|
|
@ -1121,7 +1130,7 @@ static bool_t get_codec(LinphoneCore *lc, SalStreamType type, int index, Payload
|
|||
LpConfig *config=lc->config;
|
||||
|
||||
*ret=NULL;
|
||||
snprintf(codeckey,50,"%s_codec_%i",type==SalAudio ? "audio" : "video", index);
|
||||
snprintf(codeckey,50,"%s_codec_%i",type == SalAudio ? "audio" : type == SalVideo ? "video" : "text", index);
|
||||
mime=lp_config_get_string(config,codeckey,"mime",NULL);
|
||||
if (mime==NULL || strlen(mime)==0 ) return FALSE;
|
||||
|
||||
|
|
@ -1133,15 +1142,17 @@ static bool_t get_codec(LinphoneCore *lc, SalStreamType type, int index, Payload
|
|||
ms_warning("Codec %s/%i read from conf is not supported by mediastreamer2, ignored.",mime,rate);
|
||||
return TRUE;
|
||||
}
|
||||
pt=find_payload(type==SalAudio ? lc->default_audio_codecs : lc->default_video_codecs,mime,rate,channels,fmtp);
|
||||
pt = find_payload(type == SalAudio ? lc->default_audio_codecs : type == SalVideo ? lc->default_video_codecs : lc->default_text_codecs ,mime,rate,channels,fmtp);
|
||||
if (!pt){
|
||||
MSList **default_list=(type==SalAudio) ? &lc->default_audio_codecs : &lc->default_video_codecs;
|
||||
if (type==SalAudio)
|
||||
MSList **default_list = (type==SalAudio) ? &lc->default_audio_codecs : type == SalVideo ? &lc->default_video_codecs : &lc->default_text_codecs;
|
||||
if (type == SalAudio)
|
||||
ms_warning("Codec %s/%i/%i read from conf is not in the default list.",mime,rate,channels);
|
||||
else
|
||||
else if (type == SalVideo)
|
||||
ms_warning("Codec %s/%i read from conf is not in the default list.",mime,rate);
|
||||
else
|
||||
ms_warning("Codec %s read from conf is not in the default list.",mime);
|
||||
pt=payload_type_new();
|
||||
pt->type=(type==SalAudio) ? PAYLOAD_AUDIO_PACKETIZED : PAYLOAD_VIDEO;
|
||||
pt->type=(type==SalAudio) ? PAYLOAD_AUDIO_PACKETIZED : type == SalVideo ? PAYLOAD_VIDEO : PAYLOAD_TEXT;
|
||||
pt->mime_type=ortp_strdup(mime);
|
||||
pt->clock_rate=rate;
|
||||
pt->channels=channels;
|
||||
|
|
@ -1199,6 +1210,7 @@ static void codecs_config_read(LinphoneCore *lc)
|
|||
PayloadType *pt;
|
||||
MSList *audio_codecs=NULL;
|
||||
MSList *video_codecs=NULL;
|
||||
MSList *text_codecs=NULL;
|
||||
|
||||
lc->codecs_conf.dyn_pt=96;
|
||||
lc->codecs_conf.telephone_event_pt=lp_config_get_int(lc->config,"misc","telephone_event_pt",101);
|
||||
|
|
@ -1220,8 +1232,17 @@ static void codecs_config_read(LinphoneCore *lc)
|
|||
if( lp_config_get_int(lc->config, "misc", "add_missing_video_codecs", 1) == 1 ){
|
||||
video_codecs=add_missing_codecs(lc->default_video_codecs,video_codecs);
|
||||
}
|
||||
|
||||
for (i=0;get_codec(lc,SalText,i,&pt);i++){
|
||||
if (pt){
|
||||
text_codecs=codec_append_if_new(text_codecs, pt);
|
||||
}
|
||||
}
|
||||
text_codecs = add_missing_codecs(lc->default_text_codecs, text_codecs);
|
||||
|
||||
linphone_core_set_audio_codecs(lc,audio_codecs);
|
||||
linphone_core_set_video_codecs(lc,video_codecs);
|
||||
linphone_core_set_text_codecs(lc, text_codecs);
|
||||
linphone_core_update_allocated_audio_bandwidth(lc);
|
||||
}
|
||||
|
||||
|
|
@ -1400,7 +1421,7 @@ const char * linphone_core_get_version(void){
|
|||
|
||||
static void linphone_core_register_payload_type(LinphoneCore *lc, const PayloadType *const_pt, const char *recv_fmtp, bool_t enabled){
|
||||
MSList **codec_list=const_pt->type==PAYLOAD_VIDEO ? &lc->default_video_codecs : &lc->default_audio_codecs;
|
||||
if (linphone_core_codec_supported(lc, (const_pt->type == PAYLOAD_VIDEO) ? SalVideo : SalAudio, const_pt->mime_type)){
|
||||
if (linphone_core_codec_supported(lc, (const_pt->type == PAYLOAD_VIDEO) ? SalVideo : const_pt->type == PAYLOAD_TEXT ? SalText : SalAudio, const_pt->mime_type)){
|
||||
PayloadType *pt=payload_type_clone(const_pt);
|
||||
int number=-1;
|
||||
payload_type_set_enable(pt,enabled);
|
||||
|
|
@ -1426,8 +1447,8 @@ static void linphone_core_register_static_payloads(LinphoneCore *lc){
|
|||
if (pt->type==PAYLOAD_VIDEO) continue;
|
||||
#endif
|
||||
if (find_payload_type_from_list(
|
||||
pt->mime_type, pt->clock_rate, pt->type!=PAYLOAD_VIDEO ? pt->channels : LINPHONE_FIND_PAYLOAD_IGNORE_CHANNELS,
|
||||
pt->type==PAYLOAD_VIDEO ? lc->default_video_codecs : lc->default_audio_codecs)==NULL){
|
||||
pt->mime_type, pt->clock_rate, pt->type == PAYLOAD_VIDEO || pt->type == PAYLOAD_TEXT ? LINPHONE_FIND_PAYLOAD_IGNORE_CHANNELS : pt->channels,
|
||||
pt->type == PAYLOAD_VIDEO ? lc->default_video_codecs : pt->type == PAYLOAD_TEXT ? lc->default_text_codecs : lc->default_audio_codecs)==NULL){
|
||||
linphone_core_register_payload_type(lc,pt,NULL,FALSE);
|
||||
}
|
||||
}
|
||||
|
|
@ -1567,7 +1588,8 @@ static void linphone_core_register_default_codecs(LinphoneCore *lc){
|
|||
linphone_core_register_payload_type(lc,&payload_type_aal2_g726_40,NULL,FALSE);
|
||||
linphone_core_register_payload_type(lc,&payload_type_codec2,NULL,FALSE);
|
||||
|
||||
|
||||
linphone_core_register_payload_type(lc,&payload_type_t140,NULL,TRUE);
|
||||
linphone_core_register_payload_type(lc,&payload_type_t140_red,NULL,TRUE);
|
||||
|
||||
|
||||
#ifdef VIDEO_ENABLED
|
||||
|
|
@ -1657,6 +1679,11 @@ const MSList *linphone_core_get_video_codecs(const LinphoneCore *lc)
|
|||
return lc->codecs_conf.video_codecs;
|
||||
}
|
||||
|
||||
const MSList *linphone_core_get_text_codecs(const LinphoneCore *lc)
|
||||
{
|
||||
return lc->codecs_conf.text_codecs;
|
||||
}
|
||||
|
||||
int linphone_core_set_primary_contact(LinphoneCore *lc, const char *contact)
|
||||
{
|
||||
LinphoneAddress *ctt;
|
||||
|
|
@ -1786,6 +1813,15 @@ int linphone_core_set_video_codecs(LinphoneCore *lc, MSList *codecs){
|
|||
return 0;
|
||||
}
|
||||
|
||||
int linphone_core_set_text_codecs(LinphoneCore *lc, MSList *codecs) {
|
||||
if (lc->codecs_conf.text_codecs != NULL)
|
||||
ms_list_free(lc->codecs_conf.text_codecs);
|
||||
|
||||
lc->codecs_conf.text_codecs = codecs;
|
||||
_linphone_core_codec_config_write(lc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable RFC3389 generic confort noise algorithm (CN payload type).
|
||||
* It is disabled by default, because this algorithm is only relevant for legacy codecs (PCMU, PCMA, G722).
|
||||
|
|
@ -1891,6 +1927,24 @@ void linphone_core_get_video_port_range(const LinphoneCore *lc, int *min_port, i
|
|||
*max_port = lc->rtp_conf.video_rtp_max_port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the UDP port used for text streaming.
|
||||
*
|
||||
* @ingroup network_parameters
|
||||
**/
|
||||
int linphone_core_get_text_port(const LinphoneCore *lc) {
|
||||
return lc->rtp_conf.text_rtp_min_port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the video port range from which is randomly chosen the UDP port used for text streaming.
|
||||
*
|
||||
* @ingroup network_parameters
|
||||
*/
|
||||
void linphone_core_get_text_port_range(const LinphoneCore *lc, int *min_port, int *max_port) {
|
||||
*min_port = lc->rtp_conf.text_rtp_min_port;
|
||||
*max_port = lc->rtp_conf.text_rtp_max_port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value in seconds of the no-rtp timeout.
|
||||
|
|
@ -1990,6 +2044,26 @@ void linphone_core_set_video_port_range(LinphoneCore *lc, int min_port, int max_
|
|||
lc->rtp_conf.video_rtp_min_port=min_port;
|
||||
lc->rtp_conf.video_rtp_max_port=max_port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the UDP port used for text streaming.
|
||||
* A value if -1 will request the system to allocate the local port randomly.
|
||||
* This is recommended in order to avoid firewall warnings.
|
||||
*
|
||||
* @ingroup network_parameters
|
||||
**/
|
||||
void linphone_core_set_text_port(LinphoneCore *lc, int port) {
|
||||
lc->rtp_conf.text_rtp_min_port = lc->rtp_conf.text_rtp_max_port = port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the UDP port range from which to randomly select the port used for text streaming.
|
||||
* @ingroup media_parameters
|
||||
*/
|
||||
void linphone_core_set_text_port_range(LinphoneCore *lc, int min_port, int max_port) {
|
||||
lc->rtp_conf.text_rtp_min_port = min_port;
|
||||
lc->rtp_conf.text_rtp_max_port = max_port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the no-rtp timeout value in seconds.
|
||||
|
|
@ -2759,8 +2833,9 @@ int linphone_core_proceed_with_invite_if_ready(LinphoneCore *lc, LinphoneCall *c
|
|||
int linphone_core_restart_invite(LinphoneCore *lc, LinphoneCall *call){
|
||||
linphone_call_create_op(call);
|
||||
linphone_call_stop_media_streams(call);
|
||||
ms_media_stream_sessions_uninit(&call->sessions[0]);
|
||||
ms_media_stream_sessions_uninit(&call->sessions[1]);
|
||||
ms_media_stream_sessions_uninit(&call->sessions[call->main_audio_stream_index]);
|
||||
ms_media_stream_sessions_uninit(&call->sessions[call->main_video_stream_index]);
|
||||
if (call->params->realtimetext_enabled) ms_media_stream_sessions_uninit(&call->sessions[call->main_text_stream_index]);
|
||||
linphone_call_init_media_streams(call);
|
||||
return linphone_core_start_invite(lc,call, NULL);
|
||||
}
|
||||
|
|
@ -2963,6 +3038,11 @@ LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const
|
|||
|
||||
parsed_url2=linphone_address_new(from);
|
||||
|
||||
/*rtt text stub*/
|
||||
if (cp->realtimetext_enabled) {
|
||||
linphone_call_params_add_custom_header(cp,"X-RTT","on");
|
||||
}
|
||||
|
||||
call=linphone_call_new_outgoing(lc,parsed_url2,linphone_address_clone(addr),cp,proxy);
|
||||
|
||||
if(linphone_core_add_call(lc,call)!= 0)
|
||||
|
|
@ -3840,7 +3920,7 @@ int _linphone_core_pause_call(LinphoneCore *lc, LinphoneCall *call){
|
|||
}
|
||||
lc->current_call=NULL;
|
||||
linphone_core_notify_display_status(lc,_("Pausing the current call..."));
|
||||
if (call->audiostream || call->videostream)
|
||||
if (call->audiostream || call->videostream || call->textstream)
|
||||
linphone_call_stop_media_streams (call);
|
||||
call->paused_by_app=FALSE;
|
||||
return 0;
|
||||
|
|
@ -6092,6 +6172,11 @@ void rtp_config_uninit(LinphoneCore *lc)
|
|||
} else {
|
||||
lp_config_set_range(lc->config, "rtp", "video_rtp_port", config->video_rtp_min_port, config->video_rtp_max_port);
|
||||
}
|
||||
if (config->text_rtp_min_port == config->text_rtp_max_port) {
|
||||
lp_config_set_int(lc->config, "rtp", "text_rtp_port", config->text_rtp_min_port);
|
||||
} else {
|
||||
lp_config_set_range(lc->config, "rtp", "text_rtp_port", config->text_rtp_min_port, config->text_rtp_max_port);
|
||||
}
|
||||
lp_config_set_int(lc->config,"rtp","audio_jitt_comp",config->audio_jitt_comp);
|
||||
lp_config_set_int(lc->config,"rtp","video_jitt_comp",config->video_jitt_comp);
|
||||
lp_config_set_int(lc->config,"rtp","nortp_timeout",config->nortp_timeout);
|
||||
|
|
@ -6859,6 +6944,7 @@ void linphone_core_init_default_params(LinphoneCore*lc, LinphoneCallParams *para
|
|||
params->has_video=linphone_core_video_enabled(lc) && lc->video_policy.automatically_initiate;
|
||||
params->media_encryption=linphone_core_get_media_encryption(lc);
|
||||
params->in_conference=FALSE;
|
||||
params->realtimetext_enabled = linphone_core_realtime_text_enabled(lc);
|
||||
params->privacy=LinphonePrivacyDefault;
|
||||
params->avpf_enabled=FALSE;
|
||||
params->audio_dir=LinphoneMediaDirectionSendRecv;
|
||||
|
|
@ -7193,3 +7279,7 @@ LINPHONE_PUBLIC const char *linphone_core_log_collection_upload_state_to_string(
|
|||
}
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
bool_t linphone_core_realtime_text_enabled(LinphoneCore *lc) {
|
||||
return lc->text_conf.enabled;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -469,6 +469,7 @@ typedef struct _LinphoneVideoPolicy LinphoneVideoPolicy;
|
|||
|
||||
#define LINPHONE_CALL_STATS_AUDIO 0
|
||||
#define LINPHONE_CALL_STATS_VIDEO 1
|
||||
#define LINPHONE_CALL_STATS_TEXT 2
|
||||
|
||||
/**
|
||||
* Enum describing ICE states.
|
||||
|
|
@ -737,6 +738,15 @@ LINPHONE_PUBLIC float linphone_call_get_play_volume(LinphoneCall *call);
|
|||
*/
|
||||
LINPHONE_PUBLIC float linphone_call_get_record_volume(LinphoneCall *call);
|
||||
|
||||
struct _LinphoneChatRoom;
|
||||
/**
|
||||
* Create a new chat room for messaging from a call if not already existing, else return existing one
|
||||
* @param call #LinphoneCall object
|
||||
* @return #LinphoneChatRoom where messaging can take place.
|
||||
*/
|
||||
LINPHONE_PUBLIC struct _LinphoneChatRoom * linphone_call_get_chat_room(LinphoneCall *call);
|
||||
|
||||
|
||||
/**
|
||||
* Get speaker volume gain.
|
||||
* If the sound backend supports it, the returned gain is equal to the gain set
|
||||
|
|
@ -1435,6 +1445,14 @@ LINPHONE_PUBLIC LinphoneCore* linphone_chat_room_get_lc(LinphoneChatRoom *cr);
|
|||
**/
|
||||
LINPHONE_PUBLIC LinphoneCore* linphone_chat_room_get_core(LinphoneChatRoom *cr);
|
||||
|
||||
/**
|
||||
* When realtime text is enabled #linphone_call_params_realtime_text_enabled, #LinphoneCoreIsComposingReceivedCb is call everytime a char is received from peer.
|
||||
* At the end of remote typing a regular #LinphoneChatMessage is received with committed data from #LinphoneCoreMessageReceivedCb.
|
||||
* @param[in] msg LinphoneChatMessage
|
||||
* @returns RFC 4103/T.140 char
|
||||
*/
|
||||
LINPHONE_PUBLIC uint32_t linphone_chat_room_get_char(const LinphoneChatRoom *cr);
|
||||
|
||||
/**
|
||||
* Returns an list of chat rooms
|
||||
* @param[in] lc #LinphoneCore object
|
||||
|
|
@ -1640,6 +1658,27 @@ LINPHONE_PUBLIC void linphone_chat_message_set_file_transfer_filepath(LinphoneCh
|
|||
* @return The path to the file to use for the file transfer.
|
||||
*/
|
||||
LINPHONE_PUBLIC const char * linphone_chat_message_get_file_transfer_filepath(LinphoneChatMessage *msg);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Fulfill a chat message char by char. Message linked to a Real Time Text Call send char in realtime following RFC 4103/T.140
|
||||
* To commit a message, use #linphone_chat_room_send_message
|
||||
* @param[in] msg LinphoneChatMessage
|
||||
* @param[in] character T.140 char
|
||||
* @returns 0 if succeed.
|
||||
*/
|
||||
LINPHONE_PUBLIC int linphone_chat_message_put_char(LinphoneChatMessage *msg,uint32_t charater);
|
||||
|
||||
/**
|
||||
* get Curent Call associated to this chatroom if any
|
||||
* To commit a message, use #linphone_chat_room_send_message
|
||||
* @param[in] room LinphoneChatRomm
|
||||
* @returns LinphoneCall or NULL.
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneCall *linphone_chat_room_get_call(const LinphoneChatRoom *room);
|
||||
|
||||
|
||||
/**
|
||||
* Get the LinphoneChatMessageCbs object associated with the LinphoneChatMessage.
|
||||
* @param[in] msg LinphoneChatMessage object
|
||||
|
|
@ -2645,6 +2684,22 @@ LINPHONE_PUBLIC const MSList *linphone_core_get_video_codecs(const LinphoneCore
|
|||
|
||||
LINPHONE_PUBLIC int linphone_core_set_video_codecs(LinphoneCore *lc, MSList *codecs);
|
||||
|
||||
/**
|
||||
* Returns the list of available text codecs.
|
||||
* @param[in] lc The LinphoneCore object
|
||||
* @return \mslist{PayloadType}
|
||||
*
|
||||
* This list is unmodifiable. The ->data field of the MSList points a PayloadType
|
||||
* structure holding the codec information.
|
||||
* It is possible to make copy of the list with ms_list_copy() in order to modify it
|
||||
* (such as the order of codecs).
|
||||
* @ingroup media_parameters
|
||||
**/
|
||||
LINPHONE_PUBLIC const MSList *linphone_core_get_text_codecs(const LinphoneCore *lc);
|
||||
|
||||
|
||||
LINPHONE_PUBLIC int linphone_core_set_text_codecs(LinphoneCore *lc, MSList *codecs);
|
||||
|
||||
LINPHONE_PUBLIC void linphone_core_enable_generic_confort_noise(LinphoneCore *lc, bool_t enabled);
|
||||
|
||||
LINPHONE_PUBLIC bool_t linphone_core_generic_confort_noise_enabled(const LinphoneCore *lc);
|
||||
|
|
@ -2893,6 +2948,10 @@ LINPHONE_PUBLIC int linphone_core_get_video_port(const LinphoneCore *lc);
|
|||
|
||||
LINPHONE_PUBLIC void linphone_core_get_video_port_range(const LinphoneCore *lc, int *min_port, int *max_port);
|
||||
|
||||
LINPHONE_PUBLIC int linphone_core_get_text_port(const LinphoneCore *lc);
|
||||
|
||||
LINPHONE_PUBLIC void linphone_core_get_text_port_range(const LinphoneCore *lc, int *min_port, int *max_port);
|
||||
|
||||
LINPHONE_PUBLIC int linphone_core_get_nortp_timeout(const LinphoneCore *lc);
|
||||
|
||||
LINPHONE_PUBLIC void linphone_core_set_audio_port(LinphoneCore *lc, int port);
|
||||
|
|
@ -2903,6 +2962,10 @@ LINPHONE_PUBLIC void linphone_core_set_video_port(LinphoneCore *lc, int port);
|
|||
|
||||
LINPHONE_PUBLIC void linphone_core_set_video_port_range(LinphoneCore *lc, int min_port, int max_port);
|
||||
|
||||
LINPHONE_PUBLIC void linphone_core_set_text_port(LinphoneCore *lc, int port);
|
||||
|
||||
LINPHONE_PUBLIC void linphone_core_set_text_port_range(LinphoneCore *lc, int min_port, int max_port);
|
||||
|
||||
LINPHONE_PUBLIC void linphone_core_set_nortp_timeout(LinphoneCore *lc, int port);
|
||||
|
||||
LINPHONE_PUBLIC void linphone_core_set_use_info_for_dtmf(LinphoneCore *lc, bool_t use_info);
|
||||
|
|
@ -4054,6 +4117,13 @@ LINPHONE_PUBLIC void linphone_core_set_video_preset(LinphoneCore *lc, const char
|
|||
*/
|
||||
LINPHONE_PUBLIC const char * linphone_core_get_video_preset(const LinphoneCore *lc);
|
||||
|
||||
/**
|
||||
* Gets if realtime text is enabled or not
|
||||
* @param[in] lc LinphoneCore object
|
||||
* @return true if realtime text is enabled, false otherwise
|
||||
*/
|
||||
LINPHONE_PUBLIC bool_t linphone_core_realtime_text_enabled(LinphoneCore *lc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -6180,3 +6180,27 @@ JNIEXPORT jstring JNICALL Java_org_linphone_core_LinphoneCoreImpl_getVideoPreset
|
|||
const char *tmp = linphone_core_get_video_preset((LinphoneCore *)lc);
|
||||
return tmp ? env->NewStringUTF(tmp) : NULL;
|
||||
}
|
||||
|
||||
extern "C" jlong Java_org_linphone_core_LinphoneCallImpl_getChatRoom(JNIEnv* env ,jobject thiz, jlong ptr) {
|
||||
return (jlong) linphone_call_get_chat_room((LinphoneCall *) ptr);
|
||||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneCallParamsImpl_enableRealTimeText(JNIEnv* env ,jobject thiz, jlong ptr, jboolean yesno) {
|
||||
linphone_call_params_enable_realtime_text((LinphoneCallParams *)ptr, yesno);
|
||||
}
|
||||
|
||||
extern "C" jboolean Java_org_linphone_core_LinphoneCallParamsImpl_realTimeTextEnabled(JNIEnv* env ,jobject thiz, jlong ptr) {
|
||||
return linphone_call_params_realtime_text_enabled((LinphoneCallParams *)ptr);
|
||||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneChatMessageImpl_putChar(JNIEnv* env ,jobject thiz, jlong ptr, jlong character) {
|
||||
linphone_chat_message_put_char((LinphoneChatMessage *)ptr, character);
|
||||
}
|
||||
|
||||
extern "C" jobject Java_org_linphone_core_LinphoneChatRoomImpl_getCall(JNIEnv* env ,jobject thiz, jlong ptr) {
|
||||
return getCall(env, linphone_chat_room_get_call((LinphoneChatRoom *)ptr));
|
||||
}
|
||||
|
||||
extern "C" jlong Java_org_linphone_core_LinphoneChatRoomImpl_getChar(JNIEnv* env ,jobject thiz, jlong ptr) {
|
||||
return linphone_chat_room_get_char((LinphoneChatRoom *)ptr);
|
||||
}
|
||||
|
|
@ -62,7 +62,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
static void clear_ice_check_list(LinphoneCall *call, IceCheckList *removed);
|
||||
|
||||
bool_t linphone_core_payload_type_enabled(LinphoneCore *lc, const LinphonePayloadType *pt){
|
||||
if (ms_list_find(lc->codecs_conf.audio_codecs, (PayloadType*) pt) || ms_list_find(lc->codecs_conf.video_codecs, (PayloadType*)pt)){
|
||||
if (ms_list_find(lc->codecs_conf.audio_codecs, (PayloadType*) pt) || ms_list_find(lc->codecs_conf.video_codecs, (PayloadType*)pt) || ms_list_find(lc->codecs_conf.text_codecs, (PayloadType*)pt)){
|
||||
return payload_type_enabled(pt);
|
||||
}
|
||||
ms_error("Getting enablement status of codec not in audio or video list of PayloadType !");
|
||||
|
|
@ -75,7 +75,7 @@ bool_t linphone_core_payload_type_is_vbr(LinphoneCore *lc, const LinphonePayload
|
|||
}
|
||||
|
||||
int linphone_core_enable_payload_type(LinphoneCore *lc, LinphonePayloadType *pt, bool_t enabled){
|
||||
if (ms_list_find(lc->codecs_conf.audio_codecs,pt) || ms_list_find(lc->codecs_conf.video_codecs,pt)){
|
||||
if (ms_list_find(lc->codecs_conf.audio_codecs,pt) || ms_list_find(lc->codecs_conf.video_codecs,pt) || ms_list_find(lc->codecs_conf.text_codecs,pt)){
|
||||
payload_type_set_enable(pt,enabled);
|
||||
_linphone_core_codec_config_write(lc);
|
||||
linphone_core_update_allocated_audio_bandwidth(lc);
|
||||
|
|
@ -106,7 +106,7 @@ const char *linphone_core_get_payload_type_description(LinphoneCore *lc, Payload
|
|||
}
|
||||
|
||||
void linphone_core_set_payload_type_bitrate(LinphoneCore *lc, LinphonePayloadType *pt, int bitrate){
|
||||
if (ms_list_find(lc->codecs_conf.audio_codecs, (PayloadType*) pt) || ms_list_find(lc->codecs_conf.video_codecs, (PayloadType*)pt)){
|
||||
if (ms_list_find(lc->codecs_conf.audio_codecs, (PayloadType*) pt) || ms_list_find(lc->codecs_conf.video_codecs, (PayloadType*)pt) || ms_list_find(lc->codecs_conf.text_codecs, (PayloadType*)pt)){
|
||||
if (pt->type==PAYLOAD_VIDEO || pt->flags & PAYLOAD_TYPE_IS_VBR){
|
||||
pt->normal_bitrate=bitrate*1000;
|
||||
pt->flags|=PAYLOAD_TYPE_BITRATE_OVERRIDE;
|
||||
|
|
@ -409,22 +409,23 @@ int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){
|
|||
const char *server=linphone_core_get_stun_server(lc);
|
||||
StunCandidate *ac=&call->ac;
|
||||
StunCandidate *vc=&call->vc;
|
||||
StunCandidate *tc=&call->tc;
|
||||
|
||||
if (lc->sip_conf.ipv6_enabled){
|
||||
ms_warning("stun support is not implemented for ipv6");
|
||||
return -1;
|
||||
}
|
||||
if (call->media_ports[0].rtp_port==-1){
|
||||
if (call->media_ports[call->main_audio_stream_index].rtp_port==-1){
|
||||
ms_warning("Stun-only support not available for system random port");
|
||||
return -1;
|
||||
}
|
||||
if (server!=NULL){
|
||||
const struct addrinfo *ai=linphone_core_get_stun_server_addrinfo(lc);
|
||||
ortp_socket_t sock1=-1, sock2=-1;
|
||||
ortp_socket_t sock1=-1, sock2=-1, sock3=-1;
|
||||
int loops=0;
|
||||
bool_t video_enabled=linphone_core_video_enabled(lc);
|
||||
bool_t got_audio,got_video;
|
||||
bool_t cone_audio=FALSE,cone_video=FALSE;
|
||||
bool_t got_audio,got_video,got_text;
|
||||
bool_t cone_audio=FALSE,cone_video=FALSE,cone_text=FALSE;
|
||||
struct timeval init,cur;
|
||||
double elapsed;
|
||||
int ret=0;
|
||||
|
|
@ -436,14 +437,18 @@ int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){
|
|||
linphone_core_notify_display_status(lc,_("Stun lookup in progress..."));
|
||||
|
||||
/*create the two audio and video RTP sockets, and send STUN message to our stun server */
|
||||
sock1=create_socket(call->media_ports[0].rtp_port);
|
||||
sock1=create_socket(call->media_ports[call->main_audio_stream_index].rtp_port);
|
||||
if (sock1==-1) return -1;
|
||||
if (video_enabled){
|
||||
sock2=create_socket(call->media_ports[1].rtp_port);
|
||||
sock2=create_socket(call->media_ports[call->main_video_stream_index].rtp_port);
|
||||
if (sock2==-1) return -1;
|
||||
}
|
||||
sock3=create_socket(call->media_ports[call->main_text_stream_index].rtp_port);
|
||||
if (sock3==-1) return -1;
|
||||
|
||||
got_audio=FALSE;
|
||||
got_video=FALSE;
|
||||
got_text=FALSE;
|
||||
ortp_gettimeofday(&init,NULL);
|
||||
do{
|
||||
|
||||
|
|
@ -456,6 +461,10 @@ int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){
|
|||
sendStunRequest(sock2,ai->ai_addr,ai->ai_addrlen,22,TRUE);
|
||||
sendStunRequest(sock2,ai->ai_addr,ai->ai_addrlen,2,FALSE);
|
||||
}
|
||||
if (sock3!=-1){
|
||||
sendStunRequest(sock3,ai->ai_addr,ai->ai_addrlen,33,TRUE);
|
||||
sendStunRequest(sock3,ai->ai_addr,ai->ai_addrlen,3,FALSE);
|
||||
}
|
||||
}
|
||||
ms_usleep(10000);
|
||||
|
||||
|
|
@ -477,6 +486,15 @@ int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){
|
|||
cone_video=TRUE;
|
||||
got_video=TRUE;
|
||||
}
|
||||
if (recvStunResponse(sock3,tc->addr,
|
||||
&tc->port,&id)>0){
|
||||
ms_message("STUN test result: local text port maps to %s:%i",
|
||||
tc->addr,
|
||||
tc->port);
|
||||
if (id==33)
|
||||
cone_text=TRUE;
|
||||
got_text=TRUE;
|
||||
}
|
||||
ortp_gettimeofday(&cur,NULL);
|
||||
elapsed=((cur.tv_sec-init.tv_sec)*1000.0) + ((cur.tv_usec-init.tv_usec)/1000.0);
|
||||
if (elapsed>2000) {
|
||||
|
|
@ -485,7 +503,7 @@ int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){
|
|||
break;
|
||||
}
|
||||
loops++;
|
||||
}while(!(got_audio && (got_video||sock2==-1) ) );
|
||||
}while(!(got_audio && (got_video||sock2==-1) && (got_text||sock3==-1) ) );
|
||||
if (ret==0) ret=(int)elapsed;
|
||||
if (!got_audio){
|
||||
ms_error("No stun server response for audio port.");
|
||||
|
|
@ -503,8 +521,18 @@ int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){
|
|||
}
|
||||
}
|
||||
}
|
||||
if (sock3!=-1){
|
||||
if (!got_text){
|
||||
ms_error("No stun server response for text port.");
|
||||
}else{
|
||||
if (!cone_text) {
|
||||
ms_message("NAT is symmetric for text port.");
|
||||
}
|
||||
}
|
||||
}
|
||||
close_socket(sock1);
|
||||
if (sock2!=-1) close_socket(sock2);
|
||||
if (sock3!=-1) close_socket(sock3);
|
||||
return ret;
|
||||
}
|
||||
return -1;
|
||||
|
|
@ -598,11 +626,13 @@ int linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call)
|
|||
const struct addrinfo *ai;
|
||||
IceCheckList *audio_check_list;
|
||||
IceCheckList *video_check_list;
|
||||
IceCheckList *text_check_list;
|
||||
const char *server = linphone_core_get_stun_server(lc);
|
||||
|
||||
if ((server == NULL) || (call->ice_session == NULL)) return -1;
|
||||
audio_check_list = ice_session_check_list(call->ice_session, 0);
|
||||
video_check_list = ice_session_check_list(call->ice_session, 1);
|
||||
text_check_list = ice_session_check_list(call->ice_session, 2);
|
||||
if (audio_check_list == NULL) return -1;
|
||||
|
||||
if (call->af==AF_INET6){
|
||||
|
|
@ -622,16 +652,22 @@ int linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call)
|
|||
return -1;
|
||||
}
|
||||
if ((ice_check_list_state(audio_check_list) != ICL_Completed) && (ice_check_list_candidates_gathered(audio_check_list) == FALSE)) {
|
||||
ice_add_local_candidate(audio_check_list, "host", local_addr, call->media_ports[0].rtp_port, 1, NULL);
|
||||
ice_add_local_candidate(audio_check_list, "host", local_addr, call->media_ports[0].rtcp_port, 2, NULL);
|
||||
ice_add_local_candidate(audio_check_list, "host", local_addr, call->media_ports[call->main_audio_stream_index].rtp_port, 1, NULL);
|
||||
ice_add_local_candidate(audio_check_list, "host", local_addr, call->media_ports[call->main_audio_stream_index].rtcp_port, 2, NULL);
|
||||
call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateInProgress;
|
||||
}
|
||||
if (linphone_core_video_enabled(lc) && (video_check_list != NULL)
|
||||
&& (ice_check_list_state(video_check_list) != ICL_Completed) && (ice_check_list_candidates_gathered(video_check_list) == FALSE)) {
|
||||
ice_add_local_candidate(video_check_list, "host", local_addr, call->media_ports[1].rtp_port, 1, NULL);
|
||||
ice_add_local_candidate(video_check_list, "host", local_addr, call->media_ports[1].rtcp_port, 2, NULL);
|
||||
ice_add_local_candidate(video_check_list, "host", local_addr, call->media_ports[call->main_video_stream_index].rtp_port, 1, NULL);
|
||||
ice_add_local_candidate(video_check_list, "host", local_addr, call->media_ports[call->main_video_stream_index].rtcp_port, 2, NULL);
|
||||
call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateInProgress;
|
||||
}
|
||||
if (call->params->realtimetext_enabled && (text_check_list != NULL)
|
||||
&& (ice_check_list_state(text_check_list) != ICL_Completed) && (ice_check_list_candidates_gathered(text_check_list) == FALSE)) {
|
||||
ice_add_local_candidate(text_check_list, "host", local_addr, call->media_ports[call->main_text_stream_index].rtp_port, 1, NULL);
|
||||
ice_add_local_candidate(text_check_list, "host", local_addr, call->media_ports[call->main_text_stream_index].rtcp_port, 2, NULL);
|
||||
call->stats[LINPHONE_CALL_STATS_TEXT].ice_state = LinphoneIceStateInProgress;
|
||||
}
|
||||
|
||||
ms_message("ICE: gathering candidate from [%s]",server);
|
||||
/* Gather local srflx candidates. */
|
||||
|
|
@ -759,7 +795,7 @@ void _update_local_media_description_from_ice(SalMediaDescription *desc, IceSess
|
|||
}
|
||||
strncpy(desc->ice_pwd, ice_session_local_pwd(session), sizeof(desc->ice_pwd));
|
||||
strncpy(desc->ice_ufrag, ice_session_local_ufrag(session), sizeof(desc->ice_ufrag));
|
||||
for (i = 0; i < desc->nb_streams; i++) {
|
||||
for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) {
|
||||
SalStreamDescription *stream = &desc->streams[i];
|
||||
IceCheckList *cl = ice_session_check_list(session, i);
|
||||
nb_candidates = 0;
|
||||
|
|
@ -866,9 +902,10 @@ void linphone_call_update_ice_from_remote_media_description(LinphoneCall *call,
|
|||
ice_params_found=TRUE;
|
||||
} else {
|
||||
int i;
|
||||
for (i = 0; i < md->nb_streams; i++) {
|
||||
for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) {
|
||||
const SalStreamDescription *stream = &md->streams[i];
|
||||
IceCheckList *cl = ice_session_check_list(call->ice_session, i);
|
||||
if (!sal_stream_description_active(stream)) continue;
|
||||
if (cl) {
|
||||
if ((stream->ice_pwd[0] != '\0') && (stream->ice_ufrag[0] != '\0')) {
|
||||
ice_params_found=TRUE;
|
||||
|
|
@ -887,9 +924,10 @@ void linphone_call_update_ice_from_remote_media_description(LinphoneCall *call,
|
|||
ice_session_restart(call->ice_session);
|
||||
ice_restarted = TRUE;
|
||||
} else {
|
||||
for (i = 0; i < md->nb_streams; i++) {
|
||||
for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) {
|
||||
const SalStreamDescription *stream = &md->streams[i];
|
||||
IceCheckList *cl = ice_session_check_list(call->ice_session, i);
|
||||
if (!sal_stream_description_active(stream)) continue;
|
||||
if (cl && (strcmp(stream->rtp_addr, "0.0.0.0") == 0)) {
|
||||
ice_session_restart(call->ice_session);
|
||||
ice_restarted = TRUE;
|
||||
|
|
@ -906,9 +944,10 @@ void linphone_call_update_ice_from_remote_media_description(LinphoneCall *call,
|
|||
}
|
||||
ice_session_set_remote_credentials(call->ice_session, md->ice_ufrag, md->ice_pwd);
|
||||
}
|
||||
for (i = 0; i < md->nb_streams; i++) {
|
||||
for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) {
|
||||
const SalStreamDescription *stream = &md->streams[i];
|
||||
IceCheckList *cl = ice_session_check_list(call->ice_session, i);
|
||||
if (!sal_stream_description_active(stream)) continue;
|
||||
if (cl && (stream->ice_pwd[0] != '\0') && (stream->ice_ufrag[0] != '\0')) {
|
||||
if (ice_check_list_remote_credentials_changed(cl, stream->ice_ufrag, stream->ice_pwd)) {
|
||||
if (ice_restarted == FALSE
|
||||
|
|
@ -925,9 +964,10 @@ void linphone_call_update_ice_from_remote_media_description(LinphoneCall *call,
|
|||
}
|
||||
|
||||
/* Create ICE check lists if needed and parse ICE attributes. */
|
||||
for (i = 0; i < md->nb_streams; i++) {
|
||||
for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) {
|
||||
const SalStreamDescription *stream = &md->streams[i];
|
||||
IceCheckList *cl = ice_session_check_list(call->ice_session, i);
|
||||
if (!sal_stream_description_active(stream)) continue;
|
||||
/*
|
||||
if ((cl == NULL) && (i < md->n_active_streams)) {
|
||||
cl = ice_check_list_new();
|
||||
|
|
@ -986,7 +1026,7 @@ void linphone_call_update_ice_from_remote_media_description(LinphoneCall *call,
|
|||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < md->nb_streams; i++) {
|
||||
for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) {
|
||||
IceCheckList * cl = ice_session_check_list(call->ice_session, i);
|
||||
if (!sal_stream_description_active(&md->streams[i]) && (cl != NULL)) {
|
||||
ice_session_remove_check_list_from_idx(call->ice_session, i);
|
||||
|
|
@ -1007,7 +1047,7 @@ void linphone_call_update_ice_from_remote_media_description(LinphoneCall *call,
|
|||
bool_t linphone_core_media_description_contains_video_stream(const SalMediaDescription *md){
|
||||
int i;
|
||||
|
||||
for (i = 0; md && i < md->nb_streams; i++) {
|
||||
for (i = 0; md && i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) {
|
||||
if (md->streams[i].type == SalVideo && md->streams[i].rtp_port!=0)
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -493,9 +493,10 @@ int offer_answer_initiate_outgoing(const SalMediaDescription *local_offer,
|
|||
int i,j;
|
||||
const SalStreamDescription *ls,*rs;
|
||||
|
||||
for(i=0,j=0;i<local_offer->nb_streams;++i){
|
||||
ms_message("Processing for stream %i",i);
|
||||
for(i=0,j=0;i<SAL_MEDIA_DESCRIPTION_MAX_STREAMS;++i){
|
||||
ls=&local_offer->streams[i];
|
||||
if (!sal_stream_description_active(ls)) continue;
|
||||
ms_message("Processing for stream %i",i);
|
||||
rs=sal_media_description_find_stream((SalMediaDescription*)remote_answer,ls->proto,ls->type);
|
||||
if (rs) {
|
||||
initiate_outgoing(ls,rs,&result->streams[j]);
|
||||
|
|
@ -522,7 +523,7 @@ int offer_answer_initiate_outgoing(const SalMediaDescription *local_offer,
|
|||
|
||||
static bool_t local_stream_not_already_used(const SalMediaDescription *result, const SalStreamDescription *stream){
|
||||
int i;
|
||||
for(i=0;i<result->nb_streams;++i){
|
||||
for(i=0;i<SAL_MEDIA_DESCRIPTION_MAX_STREAMS;++i){
|
||||
const SalStreamDescription *ss=&result->streams[i];
|
||||
if (strcmp(ss->name,stream->name)==0){
|
||||
ms_message("video stream already used in answer");
|
||||
|
|
@ -543,8 +544,8 @@ static bool_t proto_compatible(SalMediaProto local, SalMediaProto remote) {
|
|||
}
|
||||
|
||||
static const SalStreamDescription *find_local_matching_stream(const SalMediaDescription *result, const SalMediaDescription *local_capabilities, const SalStreamDescription *remote_stream){
|
||||
int i;
|
||||
for(i=0;i<local_capabilities->nb_streams;++i){
|
||||
int i;
|
||||
for(i=0;i<SAL_MEDIA_DESCRIPTION_MAX_STREAMS;++i){
|
||||
const SalStreamDescription *ss=&local_capabilities->streams[i];
|
||||
if (!sal_stream_description_active(ss)) continue;
|
||||
if (ss->type==remote_stream->type && proto_compatible(ss->proto,remote_stream->proto)
|
||||
|
|
@ -563,9 +564,11 @@ int offer_answer_initiate_incoming(const SalMediaDescription *local_capabilities
|
|||
SalMediaDescription *result, bool_t one_matching_codec){
|
||||
int i;
|
||||
const SalStreamDescription *ls=NULL,*rs;
|
||||
result->nb_streams = 0;
|
||||
|
||||
for(i=0;i<remote_offer->nb_streams;++i){
|
||||
for(i=0;i<SAL_MEDIA_DESCRIPTION_MAX_STREAMS;++i){
|
||||
rs=&remote_offer->streams[i];
|
||||
if (!sal_stream_description_active(rs)) continue;
|
||||
if (rs->proto!=SalProtoOther){
|
||||
ls=find_local_matching_stream(result,local_capabilities,rs);
|
||||
}else ms_warning("Unknown protocol for mline %i, declining",i);
|
||||
|
|
@ -586,6 +589,7 @@ int offer_answer_initiate_incoming(const SalMediaDescription *local_capabilities
|
|||
result->streams[i].rtcp_xr.enabled = TRUE;
|
||||
}
|
||||
}
|
||||
result->nb_streams++;
|
||||
}else {
|
||||
ms_message("Declining mline %i, no corresponding stream in local capabilities description.",i);
|
||||
/* create an inactive stream for the answer, as there where no matching stream in local capabilities */
|
||||
|
|
@ -601,7 +605,7 @@ int offer_answer_initiate_incoming(const SalMediaDescription *local_capabilities
|
|||
}
|
||||
}
|
||||
}
|
||||
result->nb_streams=i;
|
||||
|
||||
strcpy(result->username, local_capabilities->username);
|
||||
strcpy(result->addr,local_capabilities->addr);
|
||||
result->bandwidth=local_capabilities->bandwidth;
|
||||
|
|
|
|||
|
|
@ -117,6 +117,7 @@ struct _LinphoneCallParams{
|
|||
LinphoneMediaEncryption media_encryption;
|
||||
PayloadType *audio_codec; /*audio codec currently in use */
|
||||
PayloadType *video_codec; /*video codec currently in use */
|
||||
PayloadType *text_codec; /*text codec currently in use */
|
||||
MSVideoSize sent_vsize; /* Size of the video currently being sent */
|
||||
MSVideoSize recv_vsize; /* Size of the video currently being received */
|
||||
float received_fps,sent_fps;
|
||||
|
|
@ -141,6 +142,7 @@ struct _LinphoneCallParams{
|
|||
bool_t internal_call_update; /*use mark that call update was requested internally (might be by ice)*/
|
||||
bool_t video_multicast_enabled;
|
||||
bool_t audio_multicast_enabled;
|
||||
bool_t realtimetext_enabled;
|
||||
};
|
||||
|
||||
BELLE_SIP_DECLARE_VPTR(LinphoneCallParams);
|
||||
|
|
@ -250,6 +252,7 @@ struct _LinphoneCall{
|
|||
SalMediaDescription *resultdesc;
|
||||
struct _RtpProfile *audio_profile;
|
||||
struct _RtpProfile *video_profile;
|
||||
struct _RtpProfile *text_profile;
|
||||
struct _RtpProfile *rtp_io_audio_profile;
|
||||
struct _RtpProfile *rtp_io_video_profile;
|
||||
struct _LinphoneCallLog *log;
|
||||
|
|
@ -261,11 +264,13 @@ struct _LinphoneCall{
|
|||
LinphoneCallState prevstate;
|
||||
LinphoneCallState transfer_state; /*idle if no transfer*/
|
||||
LinphoneProxyConfig *dest_proxy;
|
||||
PortConfig media_ports[2];
|
||||
MSMediaStreamSessions sessions[2]; /*the rtp, srtp, zrtp contexts for each stream*/
|
||||
StunCandidate ac,vc; /*audio video ip/port discovered by STUN*/
|
||||
int main_audio_stream_index, main_video_stream_index, main_text_stream_index;
|
||||
PortConfig media_ports[SAL_MEDIA_DESCRIPTION_MAX_STREAMS];
|
||||
MSMediaStreamSessions sessions[SAL_MEDIA_DESCRIPTION_MAX_STREAMS]; /*the rtp, srtp, zrtp contexts for each stream*/
|
||||
StunCandidate ac, vc, tc; /*audio video text ip/port discovered by STUN*/
|
||||
struct _AudioStream *audiostream; /**/
|
||||
struct _VideoStream *videostream;
|
||||
struct _TextStream *textstream;
|
||||
void *video_window_id;
|
||||
MSAudioEndpoint *endpoint; /*used for conferencing*/
|
||||
char *refer_to;
|
||||
|
|
@ -277,8 +282,9 @@ struct _LinphoneCall{
|
|||
OrtpEvQueue *audiostream_app_evq;
|
||||
char *auth_token;
|
||||
OrtpEvQueue *videostream_app_evq;
|
||||
OrtpEvQueue *textstream_app_evq;
|
||||
CallCallbackObj nextVideoFrameDecoded;
|
||||
LinphoneCallStats stats[2];
|
||||
LinphoneCallStats stats[3]; /* audio, video, text */
|
||||
#ifdef BUILD_UPNP
|
||||
UpnpSession *upnp_session;
|
||||
#endif //BUILD_UPNP
|
||||
|
|
@ -454,6 +460,7 @@ void linphone_call_init_stats(LinphoneCallStats *stats, int type);
|
|||
void linphone_call_fix_call_parameters(LinphoneCall *call);
|
||||
void linphone_call_init_audio_stream(LinphoneCall *call);
|
||||
void linphone_call_init_video_stream(LinphoneCall *call);
|
||||
void linphone_call_init_text_stream(LinphoneCall *call);
|
||||
void linphone_call_init_media_streams(LinphoneCall *call);
|
||||
void linphone_call_start_media_streams(LinphoneCall *call, LinphoneCallState target_state);
|
||||
void linphone_call_start_media_streams_for_ice_gathering(LinphoneCall *call);
|
||||
|
|
@ -582,6 +589,8 @@ struct _LinphoneChatRoom{
|
|||
belle_sip_source_t *remote_composing_refresh_timer;
|
||||
belle_sip_source_t *composing_idle_timer;
|
||||
belle_sip_source_t *composing_refresh_timer;
|
||||
LinphoneCall *call;
|
||||
LinphoneChatMessage *pending_message;
|
||||
};
|
||||
|
||||
BELLE_SIP_DECLARE_VPTR(LinphoneChatRoom);
|
||||
|
|
@ -655,6 +664,8 @@ typedef struct rtp_config
|
|||
char* video_multicast_addr;
|
||||
int video_multicast_ttl;
|
||||
bool_t video_multicast_enabled;
|
||||
int text_rtp_min_port;
|
||||
int text_rtp_max_port;
|
||||
}rtp_config_t;
|
||||
|
||||
|
||||
|
|
@ -700,6 +711,7 @@ typedef struct codecs_config
|
|||
{
|
||||
MSList *audio_codecs; /* list of audio codecs in order of preference*/
|
||||
MSList *video_codecs;
|
||||
MSList *text_codecs;
|
||||
int dyn_pt;
|
||||
int telephone_event_pt;
|
||||
}codecs_config_t;
|
||||
|
|
@ -717,6 +729,10 @@ typedef struct video_config{
|
|||
bool_t reuse_preview_source;
|
||||
}video_config_t;
|
||||
|
||||
typedef struct text_config{
|
||||
bool_t enabled;
|
||||
}text_config_t;
|
||||
|
||||
typedef struct ui_config
|
||||
{
|
||||
int is_daemon;
|
||||
|
|
@ -780,11 +796,13 @@ struct _LinphoneCore
|
|||
struct _LpConfig *config;
|
||||
MSList *default_audio_codecs;
|
||||
MSList *default_video_codecs;
|
||||
MSList *default_text_codecs;
|
||||
net_config_t net_conf;
|
||||
sip_config_t sip_conf;
|
||||
rtp_config_t rtp_conf;
|
||||
sound_config_t sound_conf;
|
||||
video_config_t video_conf;
|
||||
text_config_t text_conf;
|
||||
codecs_config_t codecs_conf;
|
||||
ui_config_t ui_conf;
|
||||
autoreplier_config_t autoreplier_conf;
|
||||
|
|
|
|||
|
|
@ -390,8 +390,8 @@ static int send_report(LinphoneCall* call, reporting_session_report_t * report,
|
|||
static const SalStreamDescription * get_media_stream_for_desc(const SalMediaDescription * smd, SalStreamType sal_stream_type) {
|
||||
int count;
|
||||
if (smd != NULL) {
|
||||
for (count = 0; count < smd->nb_streams; ++count) {
|
||||
if (smd->streams[count].type == sal_stream_type) {
|
||||
for (count = 0; count < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; ++count) {
|
||||
if (sal_stream_description_active(&smd->streams[count]) && smd->streams[count].type == sal_stream_type) {
|
||||
return &smd->streams[count];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,7 +55,13 @@ SalTransport sal_transport_parse(const char* param) {
|
|||
|
||||
SalMediaDescription *sal_media_description_new(){
|
||||
SalMediaDescription *md=ms_new0(SalMediaDescription,1);
|
||||
int i;
|
||||
md->refcount=1;
|
||||
for(i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) {
|
||||
md->streams[i].dir=SalStreamInactive;
|
||||
md->streams[i].rtp_port = 0;
|
||||
md->streams[i].rtcp_port = 0;
|
||||
}
|
||||
return md;
|
||||
}
|
||||
|
||||
|
|
@ -82,10 +88,9 @@ void sal_media_description_unref(SalMediaDescription *md){
|
|||
}
|
||||
}
|
||||
|
||||
SalStreamDescription *sal_media_description_find_stream(SalMediaDescription *md,
|
||||
SalMediaProto proto, SalStreamType type){
|
||||
SalStreamDescription *sal_media_description_find_stream(SalMediaDescription *md, SalMediaProto proto, SalStreamType type){
|
||||
int i;
|
||||
for(i=0;i<md->nb_streams;++i){
|
||||
for(i=0;i<SAL_MEDIA_DESCRIPTION_MAX_STREAMS;++i){
|
||||
SalStreamDescription *ss=&md->streams[i];
|
||||
if (!sal_stream_description_active(ss)) continue;
|
||||
if (ss->proto==proto && ss->type==type) return ss;
|
||||
|
|
@ -96,7 +101,7 @@ SalStreamDescription *sal_media_description_find_stream(SalMediaDescription *md,
|
|||
unsigned int sal_media_description_nb_active_streams_of_type(SalMediaDescription *md, SalStreamType type) {
|
||||
unsigned int i;
|
||||
unsigned int nb = 0;
|
||||
for (i = 0; i < md->nb_streams; ++i) {
|
||||
for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; ++i) {
|
||||
if (!sal_stream_description_active(&md->streams[i])) continue;
|
||||
if (md->streams[i].type == type) nb++;
|
||||
}
|
||||
|
|
@ -105,7 +110,7 @@ unsigned int sal_media_description_nb_active_streams_of_type(SalMediaDescription
|
|||
|
||||
SalStreamDescription * sal_media_description_get_active_stream_of_type(SalMediaDescription *md, SalStreamType type, unsigned int idx) {
|
||||
unsigned int i;
|
||||
for (i = 0; i < md->nb_streams; ++i) {
|
||||
for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; ++i) {
|
||||
if (!sal_stream_description_active(&md->streams[i])) continue;
|
||||
if (md->streams[i].type == type) {
|
||||
if (idx-- == 0) return &md->streams[i];
|
||||
|
|
@ -137,7 +142,7 @@ bool_t sal_media_description_empty(const SalMediaDescription *md){
|
|||
|
||||
void sal_media_description_set_dir(SalMediaDescription *md, SalStreamDir stream_dir){
|
||||
int i;
|
||||
for(i=0;i<md->nb_streams;++i){
|
||||
for(i=0;i<SAL_MEDIA_DESCRIPTION_MAX_STREAMS;++i){
|
||||
SalStreamDescription *ss=&md->streams[i];
|
||||
if (!sal_stream_description_active(ss)) continue;
|
||||
ss->dir=stream_dir;
|
||||
|
|
@ -147,7 +152,7 @@ void sal_media_description_set_dir(SalMediaDescription *md, SalStreamDir stream_
|
|||
int sal_media_description_get_nb_active_streams(const SalMediaDescription *md) {
|
||||
int i;
|
||||
int nb = 0;
|
||||
for (i = 0; i < md->nb_streams; i++) {
|
||||
for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) {
|
||||
if (sal_stream_description_active(&md->streams[i])) nb++;
|
||||
}
|
||||
return nb;
|
||||
|
|
@ -162,7 +167,7 @@ static bool_t has_dir(const SalMediaDescription *md, SalStreamDir stream_dir){
|
|||
int i;
|
||||
|
||||
/* we are looking for at least one stream with requested direction, inactive streams are ignored*/
|
||||
for(i=0;i<md->nb_streams;++i){
|
||||
for(i=0;i<SAL_MEDIA_DESCRIPTION_MAX_STREAMS;++i){
|
||||
const SalStreamDescription *ss=&md->streams[i];
|
||||
if (!sal_stream_description_active(ss)) continue;
|
||||
if (ss->dir==stream_dir) {
|
||||
|
|
@ -211,7 +216,7 @@ bool_t sal_stream_description_has_dtls(const SalStreamDescription *sd) {
|
|||
bool_t sal_media_description_has_avpf(const SalMediaDescription *md) {
|
||||
int i;
|
||||
if (md->nb_streams == 0) return FALSE;
|
||||
for (i = 0; i < md->nb_streams; i++) {
|
||||
for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) {
|
||||
if (!sal_stream_description_active(&md->streams[i])) continue;
|
||||
if (sal_stream_description_has_avpf(&md->streams[i]) != TRUE) return FALSE;
|
||||
}
|
||||
|
|
@ -221,7 +226,7 @@ bool_t sal_media_description_has_avpf(const SalMediaDescription *md) {
|
|||
bool_t sal_media_description_has_srtp(const SalMediaDescription *md) {
|
||||
int i;
|
||||
if (md->nb_streams == 0) return FALSE;
|
||||
for (i = 0; i < md->nb_streams; i++) {
|
||||
for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) {
|
||||
if (!sal_stream_description_active(&md->streams[i])) continue;
|
||||
if (sal_stream_description_has_srtp(&md->streams[i]) != TRUE) return FALSE;
|
||||
}
|
||||
|
|
@ -231,7 +236,7 @@ bool_t sal_media_description_has_srtp(const SalMediaDescription *md) {
|
|||
bool_t sal_media_description_has_dtls(const SalMediaDescription *md) {
|
||||
int i;
|
||||
if (md->nb_streams == 0) return FALSE;
|
||||
for (i = 0; i < md->nb_streams; i++) {
|
||||
for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) {
|
||||
if (!sal_stream_description_active(&md->streams[i])) continue;
|
||||
if (sal_stream_description_has_dtls(&md->streams[i]) != TRUE) return FALSE;
|
||||
}
|
||||
|
|
@ -336,7 +341,8 @@ int sal_media_description_equals(const SalMediaDescription *md1, const SalMediaD
|
|||
result |= SAL_MEDIA_DESCRIPTION_NETWORK_XXXCAST_CHANGED;
|
||||
if (md1->nb_streams != md2->nb_streams) result |= SAL_MEDIA_DESCRIPTION_STREAMS_CHANGED;
|
||||
if (md1->bandwidth != md2->bandwidth) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED;
|
||||
for(i = 0; i < md1->nb_streams; ++i){
|
||||
for(i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; ++i){
|
||||
if (!sal_stream_description_active(&md1->streams[i]) && !sal_stream_description_active(&md2->streams[i])) continue;
|
||||
result |= sal_stream_description_equals(&md1->streams[i], &md2->streams[i]);
|
||||
}
|
||||
return result;
|
||||
|
|
@ -617,8 +623,9 @@ void sal_auth_info_delete(SalAuthInfo* auth_info) {
|
|||
|
||||
const char* sal_stream_type_to_string(SalStreamType type) {
|
||||
switch (type) {
|
||||
case SalAudio:return "audio";
|
||||
case SalVideo:return "video";
|
||||
case SalAudio: return "audio";
|
||||
case SalVideo: return "video";
|
||||
case SalText: return "text";
|
||||
default: return "other";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -698,19 +698,19 @@ int linphone_core_update_upnp_audio_video(LinphoneCall *call, bool_t audio, bool
|
|||
* Audio part
|
||||
*/
|
||||
linphone_upnp_update_port_binding(lupnp, &call->upnp_session->audio->rtp,
|
||||
UPNP_IGD_IP_PROTOCOL_UDP, (audio)? call->media_ports[0].rtp_port:0, UPNP_CALL_RETRY_DELAY);
|
||||
UPNP_IGD_IP_PROTOCOL_UDP, (audio)? call->media_ports[call->main_audio_stream_index].rtp_port:0, UPNP_CALL_RETRY_DELAY);
|
||||
|
||||
linphone_upnp_update_port_binding(lupnp, &call->upnp_session->audio->rtcp,
|
||||
UPNP_IGD_IP_PROTOCOL_UDP, (audio)? call->media_ports[0].rtcp_port:0, UPNP_CALL_RETRY_DELAY);
|
||||
UPNP_IGD_IP_PROTOCOL_UDP, (audio)? call->media_ports[call->main_audio_stream_index].rtcp_port:0, UPNP_CALL_RETRY_DELAY);
|
||||
|
||||
/*
|
||||
* Video part
|
||||
*/
|
||||
linphone_upnp_update_port_binding(lupnp, &call->upnp_session->video->rtp,
|
||||
UPNP_IGD_IP_PROTOCOL_UDP, (video)? call->media_ports[1].rtp_port:0, UPNP_CALL_RETRY_DELAY);
|
||||
UPNP_IGD_IP_PROTOCOL_UDP, (video)? call->media_ports[call->main_video_stream_index].rtp_port:0, UPNP_CALL_RETRY_DELAY);
|
||||
|
||||
linphone_upnp_update_port_binding(lupnp, &call->upnp_session->video->rtcp,
|
||||
UPNP_IGD_IP_PROTOCOL_UDP, (video)? call->media_ports[1].rtcp_port:0, UPNP_CALL_RETRY_DELAY);
|
||||
UPNP_IGD_IP_PROTOCOL_UDP, (video)? call->media_ports[call->main_video_stream_index].rtcp_port:0, UPNP_CALL_RETRY_DELAY);
|
||||
}
|
||||
|
||||
ms_mutex_unlock(&lupnp->mutex);
|
||||
|
|
@ -731,8 +731,9 @@ int linphone_core_update_upnp_from_remote_media_description(LinphoneCall *call,
|
|||
int i;
|
||||
const SalStreamDescription *stream;
|
||||
|
||||
for (i = 0; i < md->nb_streams; i++) {
|
||||
for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) {
|
||||
stream = &md->streams[i];
|
||||
if (!sal_stream_description_active(stream)) continue;
|
||||
if(stream->type == SalAudio) {
|
||||
audio = TRUE;
|
||||
} else if(stream->type == SalVideo) {
|
||||
|
|
@ -1060,7 +1061,7 @@ int linphone_core_update_local_media_description_from_upnp(SalMediaDescription *
|
|||
SalStreamDescription *stream;
|
||||
UpnpStream *upnpStream;
|
||||
|
||||
for (i = 0; i < desc->nb_streams; i++) {
|
||||
for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) {
|
||||
stream = &desc->streams[i];
|
||||
if (!sal_stream_description_active(stream)) continue;
|
||||
upnpStream = NULL;
|
||||
|
|
|
|||
|
|
@ -126,6 +126,7 @@ void *sal_get_user_pointer(const Sal *sal);
|
|||
typedef enum {
|
||||
SalAudio,
|
||||
SalVideo,
|
||||
SalText,
|
||||
SalOther
|
||||
} SalStreamType;
|
||||
const char* sal_stream_type_to_string(SalStreamType type);
|
||||
|
|
|
|||
|
|
@ -359,5 +359,12 @@ public interface LinphoneCall {
|
|||
* @return A player
|
||||
*/
|
||||
public LinphonePlayer getPlayer();
|
||||
|
||||
/**
|
||||
* Create a new chat room for messaging from a call if not already existing, else return existing one
|
||||
* @return LinphoneChatRoom where messaging can take place.
|
||||
*/
|
||||
public LinphoneChatRoom getChatRoom() ;
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -158,4 +158,18 @@ public interface LinphoneCallParams {
|
|||
**/
|
||||
boolean videoMulticastEnabled();
|
||||
|
||||
/**
|
||||
* Use to enable real time text following rfc4103.
|
||||
* If enabled, outgoing calls put a m=text line in SDP offer .
|
||||
* @param yesno if yes, subsequent outgoing calls will propose rtt
|
||||
*
|
||||
**/
|
||||
void enableRealTimeText(boolean yesno);
|
||||
/**
|
||||
* Use to get real time text following rfc4103.
|
||||
* @returns returns true if call rtt is activated.
|
||||
**/
|
||||
boolean realTimeTextEnabled();
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -227,4 +227,12 @@ public interface LinphoneChatMessage {
|
|||
* Set the callbacks associated with the LinphoneChatMessage.
|
||||
*/
|
||||
void setListener(LinphoneChatMessage.LinphoneChatMessageListener listener);
|
||||
/**
|
||||
* Fulfill a chat message char by char. Message linked to a Real Time Text Call send char in realtime following RFC 4103/T.140
|
||||
* To commit a message, use #linphone_chat_room_send_message
|
||||
* @param[in] character T.140 char
|
||||
* @throw LinphoneCoreExeption .
|
||||
*/
|
||||
void putChar(long character) throws LinphoneCoreException;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -139,4 +139,19 @@ public interface LinphoneChatRoom {
|
|||
* @param message
|
||||
*/
|
||||
void sendChatMessage(LinphoneChatMessage message);
|
||||
|
||||
/**
|
||||
* get Curent Call associated to this chatroom if any
|
||||
* To commit a message, use #linphone_chat_room_send_message
|
||||
* @returns LinphoneCall or NULL.
|
||||
*/
|
||||
public LinphoneCall getCall();
|
||||
/**
|
||||
* When realtime text is enabled LinphoneCallParams.realTimeTextEnabled, LinphoneCoreListener.isComposingReceived is call every time a char is received from peer.
|
||||
* At the end of remote typing a regular LinphoneChatMessage is received with committed data from LinphoneCoreListener.messageReceived .
|
||||
* @returns RFC 4103/T.140 char
|
||||
*/
|
||||
long getChar();
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -254,5 +254,11 @@ class LinphoneCallImpl implements LinphoneCall {
|
|||
public LinphonePlayer getPlayer() {
|
||||
return new LinphonePlayerImpl(getPlayer(nativePtr));
|
||||
}
|
||||
|
||||
private native long getChatRoom(long nativePtr);
|
||||
@Override
|
||||
public LinphoneChatRoom getChatRoom() {
|
||||
return new LinphoneChatRoomImpl(getChatRoom(nativePtr));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -171,4 +171,16 @@ public class LinphoneCallParamsImpl implements LinphoneCallParams {
|
|||
public boolean videoMulticastEnabled() {
|
||||
return videoMulticastEnabled(nativePtr);
|
||||
}
|
||||
|
||||
private native void enableRealTimeText(long nativePtr, boolean yesno);
|
||||
@Override
|
||||
public void enableRealTimeText(boolean yesno) {
|
||||
enableRealTimeText(nativePtr, yesno);
|
||||
}
|
||||
|
||||
private native boolean realTimeTextEnabled(long nativePtr);
|
||||
@Override
|
||||
public boolean realTimeTextEnabled() {
|
||||
return realTimeTextEnabled(nativePtr);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -154,4 +154,10 @@ public class LinphoneChatMessageImpl implements LinphoneChatMessage {
|
|||
public void setListener(LinphoneChatMessageListener listener) {
|
||||
setListener(nativePtr, listener);
|
||||
}
|
||||
|
||||
private native void putChar(long nativePtr, long character);
|
||||
@Override
|
||||
public void putChar(long character) throws LinphoneCoreException {
|
||||
putChar(nativePtr, character);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ package org.linphone.core;
|
|||
|
||||
import org.linphone.core.LinphoneChatMessage.State;
|
||||
import org.linphone.core.LinphoneChatMessage.StateListener;
|
||||
import org.linphone.core.LinphoneCall;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
class LinphoneChatRoomImpl implements LinphoneChatRoom {
|
||||
|
|
@ -170,4 +171,16 @@ class LinphoneChatRoomImpl implements LinphoneChatRoom {
|
|||
public void sendChatMessage(LinphoneChatMessage message) {
|
||||
sendChatMessage(nativePtr, message, ((LinphoneChatMessageImpl)message).getNativePtr());
|
||||
}
|
||||
|
||||
private native Object getCall(long nativePtr);
|
||||
@Override
|
||||
public LinphoneCall getCall() {
|
||||
return (LinphoneCall) getCall(nativePtr);
|
||||
}
|
||||
|
||||
private native long getChar(long nativePtr);
|
||||
@Override
|
||||
public long getChar() {
|
||||
return getChar(nativePtr);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 4bce1692e7d60dce23f99cf3507fd9ae364674d5
|
||||
Subproject commit 16b17b19d7fbb6644954edef25e7080addbe8cb4
|
||||
2
oRTP
2
oRTP
|
|
@ -1 +1 @@
|
|||
Subproject commit 9477ed6ef1b3bffb6eb1e9e64787b2a3ccd9059e
|
||||
Subproject commit a72acabc9fc5347287bb166b8b2f5bf92f4924f1
|
||||
|
|
@ -27,6 +27,26 @@
|
|||
#define pclose _pclose
|
||||
#endif
|
||||
|
||||
void check_rtcp(LinphoneCall *call) {
|
||||
MSTimeSpec ts;
|
||||
|
||||
linphone_call_ref(call);
|
||||
liblinphone_tester_clock_start(&ts);
|
||||
|
||||
do {
|
||||
if (linphone_call_get_audio_stats(call)->round_trip_delay > 0.0 && (!linphone_call_log_video_enabled(linphone_call_get_call_log(call)) || linphone_call_get_video_stats(call)->round_trip_delay > 0.0)) {
|
||||
break;
|
||||
}
|
||||
wait_for_until(call->core, NULL, NULL, 0, 20); /*just to sleep while iterating*/
|
||||
} while (!liblinphone_tester_clock_elapsed(&ts, 15000));
|
||||
|
||||
BC_ASSERT_GREATER(linphone_call_get_audio_stats(call)->round_trip_delay, 0.0, float, "%f");
|
||||
if (linphone_call_log_video_enabled(linphone_call_get_call_log(call))) {
|
||||
BC_ASSERT_GREATER(linphone_call_get_video_stats(call)->round_trip_delay, 0.0, float, "%f");
|
||||
}
|
||||
|
||||
linphone_call_unref(call);
|
||||
}
|
||||
|
||||
static FILE *sip_start(const char *senario, const char* dest_username, LinphoneAddress* dest_addres) {
|
||||
char *dest;
|
||||
|
|
@ -37,9 +57,9 @@ static FILE *sip_start(const char *senario, const char* dest_username, LinphoneA
|
|||
dest = ms_strdup_printf("%s:%i",linphone_address_get_domain(dest_addres),linphone_address_get_port(dest_addres));
|
||||
else
|
||||
dest = ms_strdup_printf("%s",linphone_address_get_domain(dest_addres));
|
||||
|
||||
command = ms_strdup_printf("sipp -sf %s -s %s %s -trace_err -trace_msg -m 1 -d 1000 ",senario,dest_username,dest);
|
||||
|
||||
|
||||
command = ms_strdup_printf("sipp -sf %s -s %s %s -trace_err -trace_msg -rtp_echo -m 1 -d 1000",senario,dest_username,dest);
|
||||
|
||||
ms_message("Starting sipp commad [%s]",command);
|
||||
file = popen(command, "r");
|
||||
ms_free(command);
|
||||
|
|
@ -86,10 +106,7 @@ static void sip_update_within_icoming_reinvite_with_no_sdp(void) {
|
|||
linphone_address_set_port(dest, port);
|
||||
*/
|
||||
scen = bc_tester_res("sipp/sip_update_within_icoming_reinvite_with_no_sdp.xml");
|
||||
|
||||
sipp_out = sip_start(scen
|
||||
, linphone_address_get_username(mgr->identity)
|
||||
, mgr->identity);
|
||||
sipp_out = sip_start(scen, linphone_address_get_username(mgr->identity), mgr->identity);
|
||||
|
||||
if (sipp_out) {
|
||||
BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallIncomingReceived, 1));
|
||||
|
|
@ -101,9 +118,172 @@ static void sip_update_within_icoming_reinvite_with_no_sdp(void) {
|
|||
linphone_core_manager_destroy(mgr);
|
||||
}
|
||||
|
||||
static void call_with_audio_mline_before_video_in_sdp() {
|
||||
LinphoneCoreManager *mgr;
|
||||
char *identity_char;
|
||||
char *scen;
|
||||
FILE * sipp_out;
|
||||
LinphoneCall *call = NULL;
|
||||
|
||||
/*currently we use direct connection because sipp do not properly set ACK request uri*/
|
||||
mgr= linphone_core_manager_new2( "empty_rc", FALSE);
|
||||
mgr->identity = linphone_core_get_primary_contact_parsed(mgr->lc);
|
||||
linphone_address_set_username(mgr->identity,"marie");
|
||||
identity_char = linphone_address_as_string(mgr->identity);
|
||||
linphone_core_set_primary_contact(mgr->lc,identity_char);
|
||||
|
||||
linphone_core_iterate(mgr->lc);
|
||||
|
||||
scen = bc_tester_res("sipp/call_with_audio_mline_before_video_in_sdp.xml");
|
||||
|
||||
sipp_out = sip_start(scen, linphone_address_get_username(mgr->identity), mgr->identity);
|
||||
|
||||
if (sipp_out) {
|
||||
BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallIncomingReceived, 1));
|
||||
call = linphone_core_get_current_call(mgr->lc);
|
||||
linphone_core_accept_call(mgr->lc, call);
|
||||
BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallStreamsRunning, 1));
|
||||
BC_ASSERT_EQUAL(call->main_audio_stream_index, 0, int, "%d");
|
||||
BC_ASSERT_EQUAL(call->main_video_stream_index, 1, int, "%d");
|
||||
BC_ASSERT_TRUE(call->main_text_stream_index > 1);
|
||||
BC_ASSERT_TRUE(linphone_call_log_video_enabled(linphone_call_get_call_log(call)));
|
||||
|
||||
check_rtcp(call);
|
||||
|
||||
BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallEnd, 1));
|
||||
pclose(sipp_out);
|
||||
}
|
||||
linphone_core_manager_destroy(mgr);
|
||||
}
|
||||
|
||||
static void call_with_video_mline_before_audio_in_sdp() {
|
||||
LinphoneCoreManager *mgr;
|
||||
char *identity_char;
|
||||
char *scen;
|
||||
FILE * sipp_out;
|
||||
LinphoneCall *call = NULL;
|
||||
|
||||
/*currently we use direct connection because sipp do not properly set ACK request uri*/
|
||||
mgr= linphone_core_manager_new2( "empty_rc", FALSE);
|
||||
mgr->identity = linphone_core_get_primary_contact_parsed(mgr->lc);
|
||||
linphone_address_set_username(mgr->identity,"marie");
|
||||
identity_char = linphone_address_as_string(mgr->identity);
|
||||
linphone_core_set_primary_contact(mgr->lc,identity_char);
|
||||
|
||||
linphone_core_iterate(mgr->lc);
|
||||
|
||||
scen = bc_tester_res("sipp/call_with_video_mline_before_audio_in_sdp.xml");
|
||||
|
||||
sipp_out = sip_start(scen, linphone_address_get_username(mgr->identity), mgr->identity);
|
||||
|
||||
if (sipp_out) {
|
||||
BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallIncomingReceived, 1));
|
||||
call = linphone_core_get_current_call(mgr->lc);
|
||||
linphone_core_accept_call(mgr->lc, call);
|
||||
BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallStreamsRunning, 1));
|
||||
BC_ASSERT_EQUAL(call->main_audio_stream_index, 1, int, "%d");
|
||||
BC_ASSERT_EQUAL(call->main_video_stream_index, 0, int, "%d");
|
||||
BC_ASSERT_TRUE(call->main_text_stream_index > 1);
|
||||
BC_ASSERT_TRUE(linphone_call_log_video_enabled(linphone_call_get_call_log(call)));
|
||||
|
||||
check_rtcp(call);
|
||||
|
||||
BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallEnd, 1));
|
||||
pclose(sipp_out);
|
||||
}
|
||||
linphone_core_manager_destroy(mgr);
|
||||
}
|
||||
|
||||
static void call_with_multiple_audio_mline_in_sdp() {
|
||||
LinphoneCoreManager *mgr;
|
||||
char *identity_char;
|
||||
char *scen;
|
||||
FILE * sipp_out;
|
||||
LinphoneCall *call = NULL;
|
||||
|
||||
/*currently we use direct connection because sipp do not properly set ACK request uri*/
|
||||
mgr= linphone_core_manager_new2( "empty_rc", FALSE);
|
||||
mgr->identity = linphone_core_get_primary_contact_parsed(mgr->lc);
|
||||
linphone_address_set_username(mgr->identity,"marie");
|
||||
identity_char = linphone_address_as_string(mgr->identity);
|
||||
linphone_core_set_primary_contact(mgr->lc,identity_char);
|
||||
|
||||
linphone_core_iterate(mgr->lc);
|
||||
|
||||
scen = bc_tester_res("sipp/call_with_multiple_audio_mline_in_sdp.xml");
|
||||
|
||||
sipp_out = sip_start(scen, linphone_address_get_username(mgr->identity), mgr->identity);
|
||||
|
||||
if (sipp_out) {
|
||||
BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallIncomingReceived, 1));
|
||||
call = linphone_core_get_current_call(mgr->lc);
|
||||
linphone_core_accept_call(mgr->lc, call);
|
||||
BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallStreamsRunning, 1));
|
||||
BC_ASSERT_EQUAL(call->main_audio_stream_index, 0, int, "%d");
|
||||
BC_ASSERT_EQUAL(call->main_video_stream_index, 2, int, "%d");
|
||||
BC_ASSERT_TRUE(call->main_text_stream_index > 2);
|
||||
BC_ASSERT_TRUE(linphone_call_log_video_enabled(linphone_call_get_call_log(call)));
|
||||
|
||||
check_rtcp(call);
|
||||
|
||||
BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallEnd, 1));
|
||||
pclose(sipp_out);
|
||||
}
|
||||
linphone_core_manager_destroy(mgr);
|
||||
}
|
||||
|
||||
static void call_with_multiple_video_mline_in_sdp() {
|
||||
LinphoneCoreManager *mgr;
|
||||
char *identity_char;
|
||||
char *scen;
|
||||
FILE * sipp_out;
|
||||
LinphoneCall *call = NULL;
|
||||
|
||||
/*currently we use direct connection because sipp do not properly set ACK request uri*/
|
||||
mgr= linphone_core_manager_new2( "empty_rc", FALSE);
|
||||
mgr->identity = linphone_core_get_primary_contact_parsed(mgr->lc);
|
||||
linphone_address_set_username(mgr->identity,"marie");
|
||||
identity_char = linphone_address_as_string(mgr->identity);
|
||||
linphone_core_set_primary_contact(mgr->lc,identity_char);
|
||||
|
||||
linphone_core_iterate(mgr->lc);
|
||||
|
||||
scen = bc_tester_res("sipp/call_with_multiple_video_mline_in_sdp.xml");
|
||||
|
||||
sipp_out = sip_start(scen, linphone_address_get_username(mgr->identity), mgr->identity);
|
||||
|
||||
if (sipp_out) {
|
||||
BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallIncomingReceived, 1));
|
||||
call = linphone_core_get_current_call(mgr->lc);
|
||||
linphone_core_accept_call(mgr->lc, call);
|
||||
BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallStreamsRunning, 1));
|
||||
BC_ASSERT_EQUAL(call->main_audio_stream_index, 0, int, "%d");
|
||||
BC_ASSERT_EQUAL(call->main_video_stream_index, 1, int, "%d");
|
||||
BC_ASSERT_TRUE(call->main_text_stream_index > 3);
|
||||
BC_ASSERT_TRUE(linphone_call_log_video_enabled(linphone_call_get_call_log(call)));
|
||||
|
||||
check_rtcp(call);
|
||||
|
||||
BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallEnd, 1));
|
||||
pclose(sipp_out);
|
||||
}
|
||||
linphone_core_manager_destroy(mgr);
|
||||
}
|
||||
|
||||
static test_t tests[] = {
|
||||
{ "SIP UPDATE within incoming reinvite witjout sdp", sip_update_within_icoming_reinvite_with_no_sdp},
|
||||
{ "SIP UPDATE within incoming reinvite without sdp", sip_update_within_icoming_reinvite_with_no_sdp },
|
||||
{ "Call with audio mline before video in sdp", call_with_audio_mline_before_video_in_sdp },
|
||||
{ "Call with video mline before audio in sdp", call_with_video_mline_before_audio_in_sdp },
|
||||
{ "Call with multiple audio mline in sdp", call_with_multiple_audio_mline_in_sdp },
|
||||
{ "Call with multiple video mline in sdp", call_with_multiple_video_mline_in_sdp },
|
||||
};
|
||||
|
||||
test_suite_t complex_sip_call_test_suite = {"Complex SIP Call", NULL, NULL, liblinphone_tester_before_each, NULL,
|
||||
sizeof(tests) / sizeof(tests[0]), tests};
|
||||
test_suite_t complex_sip_call_test_suite = {
|
||||
"Complex SIP Call",
|
||||
NULL,
|
||||
NULL,
|
||||
liblinphone_tester_before_each,
|
||||
NULL,
|
||||
sizeof(tests) / sizeof(tests[0]),
|
||||
tests
|
||||
};
|
||||
|
|
|
|||
|
|
@ -224,6 +224,71 @@ static void text_message_within_dialog(void) {
|
|||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
|
||||
static void rtt_text_message(void) {
|
||||
LinphoneChatRoom *pauline_chat_room, *marie_chat_room;
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
|
||||
|
||||
LinphoneCallParams *marie_params = linphone_core_create_default_call_parameters(marie->lc);
|
||||
LinphoneCall *pauline_call, *marie_call;
|
||||
linphone_call_params_enable_realtime_text(marie_params,TRUE);
|
||||
|
||||
BC_ASSERT_TRUE(call_with_caller_params(marie,pauline,marie_params));
|
||||
pauline_call=linphone_core_get_current_call(pauline->lc);
|
||||
marie_call=linphone_core_get_current_call(marie->lc);
|
||||
BC_ASSERT_TRUE(linphone_call_params_realtime_text_enabled(linphone_call_get_current_params(pauline_call)));
|
||||
|
||||
pauline_chat_room = linphone_call_get_chat_room(pauline_call);
|
||||
BC_ASSERT_PTR_NOT_NULL(pauline_chat_room);
|
||||
if (pauline_chat_room) {
|
||||
LinphoneChatMessage* rtt_message = linphone_chat_room_create_message(pauline_chat_room,NULL);
|
||||
|
||||
linphone_chat_message_put_char(rtt_message,'B');
|
||||
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneIsComposingActiveReceived,1));
|
||||
marie_chat_room = linphone_call_get_chat_room(marie_call);
|
||||
BC_ASSERT_PTR_NOT_NULL(marie_chat_room);
|
||||
BC_ASSERT_EQUAL(linphone_chat_room_get_char(marie_chat_room),'B',int,"%c");
|
||||
|
||||
linphone_chat_message_put_char(rtt_message,'L');
|
||||
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneIsComposingActiveReceived,2));
|
||||
BC_ASSERT_EQUAL(linphone_chat_room_get_char(marie_chat_room),'L',int,"%c");
|
||||
|
||||
linphone_chat_message_put_char(rtt_message,'A');
|
||||
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneIsComposingActiveReceived,3));
|
||||
BC_ASSERT_EQUAL(linphone_chat_room_get_char(marie_chat_room),'A',int,"%c");
|
||||
|
||||
linphone_chat_message_put_char(rtt_message,' ');
|
||||
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneIsComposingActiveReceived,4));
|
||||
BC_ASSERT_EQUAL(linphone_chat_room_get_char(marie_chat_room),' ',int,"%c");
|
||||
|
||||
linphone_chat_message_put_char(rtt_message,'B');
|
||||
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneIsComposingActiveReceived,5));
|
||||
BC_ASSERT_EQUAL(linphone_chat_room_get_char(marie_chat_room),'B',int,"%c");
|
||||
|
||||
linphone_chat_message_put_char(rtt_message,'L');
|
||||
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneIsComposingActiveReceived,6));
|
||||
BC_ASSERT_EQUAL(linphone_chat_room_get_char(marie_chat_room),'L',int,"%c");
|
||||
|
||||
linphone_chat_message_put_char(rtt_message,'A');
|
||||
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneIsComposingActiveReceived,7));
|
||||
BC_ASSERT_EQUAL(linphone_chat_room_get_char(marie_chat_room),'A',int,"%c");
|
||||
|
||||
/*Commit the message, triggers a NEW LINE in T.140 */
|
||||
linphone_chat_room_send_chat_message(pauline_chat_room, rtt_message);
|
||||
|
||||
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived,1));
|
||||
{
|
||||
LinphoneChatMessage * msg = marie->stat.last_received_chat_message;
|
||||
BC_ASSERT_PTR_NOT_NULL(linphone_core_get_chat_room(marie->lc,pauline->identity));
|
||||
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(msg),"BLA BLA");
|
||||
}
|
||||
}
|
||||
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
|
||||
|
||||
static LinphoneAuthInfo* text_message_with_credential_from_auth_cb_auth_info;
|
||||
static void text_message_with_credential_from_auth_cb_auth_info_requested(LinphoneCore *lc, const char *realm, const char *username, const char *domain) {
|
||||
ms_message("text_message_with_credential_from_auth_cb:Auth info requested for user id [%s] at realm [%s]\n"
|
||||
|
|
@ -1665,7 +1730,15 @@ test_t message_tests[] = {
|
|||
,{"Transfer not sent if host not found", file_transfer_not_sent_if_host_not_found}
|
||||
,{"Transfer not sent if url moved permanently", file_transfer_not_sent_if_url_moved_permanently}
|
||||
,{"Transfer io error after destroying chatroom", file_transfer_io_error_after_destroying_chatroom}
|
||||
,{ "Real Time Text base", rtt_text_message}
|
||||
,{ "Text status after destroying chat room", text_status_after_destroying_chat_room }
|
||||
};
|
||||
|
||||
test_suite_t message_test_suite = {"Message", NULL, NULL, liblinphone_tester_before_each, NULL,
|
||||
sizeof(message_tests) / sizeof(message_tests[0]), message_tests};
|
||||
test_suite_t message_test_suite = {
|
||||
"Message",
|
||||
NULL,
|
||||
NULL,
|
||||
liblinphone_tester_before_each,
|
||||
NULL,
|
||||
sizeof(message_tests) / sizeof(message_tests[0]), message_tests
|
||||
};
|
||||
|
|
|
|||
125
tester/sipp/call_with_audio_mline_before_video_in_sdp.xml
Normal file
125
tester/sipp/call_with_audio_mline_before_video_in_sdp.xml
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||
<!DOCTYPE scenario SYSTEM "sipp.dtd">
|
||||
|
||||
<!-- This program is free software; you can redistribute it and/or -->
|
||||
<!-- modify it under the terms of the GNU General Public License as -->
|
||||
<!-- published by the Free Software Foundation; either version 2 of the -->
|
||||
<!-- License, or (at your option) any later version. -->
|
||||
<!-- -->
|
||||
<!-- This program is distributed in the hope that it will be useful, -->
|
||||
<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->
|
||||
<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->
|
||||
<!-- GNU General Public License for more details. -->
|
||||
<!-- -->
|
||||
<!-- You should have received a copy of the GNU General Public License -->
|
||||
<!-- along with this program; if not, write to the -->
|
||||
<!-- Free Software Foundation, Inc., -->
|
||||
<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->
|
||||
<!-- -->
|
||||
<!-- Sipp default 'uac' scenario. -->
|
||||
<!-- -->
|
||||
|
||||
<scenario name="Basic Sipstone UAC">
|
||||
<!-- In client mode (sipp placing calls), the Call-ID MUST be -->
|
||||
<!-- generated by sipp. To do so, use [call_id] keyword. -->
|
||||
<send retrans="500">
|
||||
<![CDATA[
|
||||
|
||||
INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
|
||||
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
|
||||
From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
|
||||
To: sut <sip:[service]@[remote_ip]:[remote_port]>
|
||||
Call-ID: [call_id]
|
||||
CSeq: 1 INVITE
|
||||
Contact: sip:sipp@[local_ip]:[local_port]
|
||||
Max-Forwards: 70
|
||||
Subject: Performance Test
|
||||
Content-Type: application/sdp
|
||||
Content-Length: [len]
|
||||
|
||||
v=0
|
||||
o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]
|
||||
s=-
|
||||
c=IN IP[media_ip_type] [media_ip]
|
||||
t=0 0
|
||||
m=audio [media_port] RTP/AVP 96 97 0 8 101 98
|
||||
a=rtpmap:96 speex/16000
|
||||
a=fmtp:96 vbr=on
|
||||
a=rtpmap:97 speex/8000
|
||||
a=fmtp:97 vbr=on
|
||||
a=rtpmap:101 telephone-event/16000
|
||||
a=rtpmap:98 telephone-event/8000
|
||||
m=video [media_port+2] RTP/AVP 96
|
||||
a=rtpmap:96 VP8/90000
|
||||
|
||||
]]>
|
||||
</send>
|
||||
|
||||
<recv response="100"
|
||||
optional="true">
|
||||
</recv>
|
||||
|
||||
<recv response="180" optional="true">
|
||||
</recv>
|
||||
|
||||
<recv response="183" optional="true">
|
||||
</recv>
|
||||
|
||||
<!-- By adding rrs="true" (Record Route Sets), the route sets -->
|
||||
<!-- are saved and used for following messages sent. Useful to test -->
|
||||
<!-- against stateful SIP proxies/B2BUAs. -->
|
||||
<recv response="200" rtd="true">
|
||||
</recv>
|
||||
|
||||
<!-- Packet lost can be simulated in any send/recv message by -->
|
||||
<!-- by adding the 'lost = "10"'. Value can be [1-100] percent. -->
|
||||
<send>
|
||||
<![CDATA[
|
||||
|
||||
ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0
|
||||
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
|
||||
From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
|
||||
To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
|
||||
Call-ID: [call_id]
|
||||
CSeq: 1 ACK
|
||||
Contact: sip:sipp@[local_ip]:[local_port]
|
||||
Max-Forwards: 70
|
||||
Subject: Performance Test
|
||||
Content-Length: 0
|
||||
|
||||
]]>
|
||||
</send>
|
||||
|
||||
<!-- This delay can be customized by the -d command-line option -->
|
||||
<!-- or by adding a 'milliseconds = "value"' option here. -->
|
||||
<pause/>
|
||||
|
||||
<!-- The 'crlf' option inserts a blank line in the statistics report. -->
|
||||
<send retrans="500">
|
||||
<![CDATA[
|
||||
|
||||
BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
|
||||
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
|
||||
From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
|
||||
To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
|
||||
Call-ID: [call_id]
|
||||
CSeq: 2 BYE
|
||||
Contact: sip:sipp@[local_ip]:[local_port]
|
||||
Max-Forwards: 70
|
||||
Subject: Performance Test
|
||||
Content-Length: 0
|
||||
|
||||
]]>
|
||||
</send>
|
||||
|
||||
<recv response="200" crlf="true">
|
||||
</recv>
|
||||
|
||||
<!-- definition of the response time repartition table (unit is ms) -->
|
||||
<ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
|
||||
|
||||
<!-- definition of the call length repartition table (unit is ms) -->
|
||||
<CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
|
||||
|
||||
</scenario>
|
||||
|
||||
132
tester/sipp/call_with_multiple_audio_mline_in_sdp.xml
Normal file
132
tester/sipp/call_with_multiple_audio_mline_in_sdp.xml
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||
<!DOCTYPE scenario SYSTEM "sipp.dtd">
|
||||
|
||||
<!-- This program is free software; you can redistribute it and/or -->
|
||||
<!-- modify it under the terms of the GNU General Public License as -->
|
||||
<!-- published by the Free Software Foundation; either version 2 of the -->
|
||||
<!-- License, or (at your option) any later version. -->
|
||||
<!-- -->
|
||||
<!-- This program is distributed in the hope that it will be useful, -->
|
||||
<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->
|
||||
<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->
|
||||
<!-- GNU General Public License for more details. -->
|
||||
<!-- -->
|
||||
<!-- You should have received a copy of the GNU General Public License -->
|
||||
<!-- along with this program; if not, write to the -->
|
||||
<!-- Free Software Foundation, Inc., -->
|
||||
<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->
|
||||
<!-- -->
|
||||
<!-- Sipp default 'uac' scenario. -->
|
||||
<!-- -->
|
||||
|
||||
<scenario name="Basic Sipstone UAC">
|
||||
<!-- In client mode (sipp placing calls), the Call-ID MUST be -->
|
||||
<!-- generated by sipp. To do so, use [call_id] keyword. -->
|
||||
<send retrans="500">
|
||||
<![CDATA[
|
||||
|
||||
INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
|
||||
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
|
||||
From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
|
||||
To: sut <sip:[service]@[remote_ip]:[remote_port]>
|
||||
Call-ID: [call_id]
|
||||
CSeq: 1 INVITE
|
||||
Contact: sip:sipp@[local_ip]:[local_port]
|
||||
Max-Forwards: 70
|
||||
Subject: Performance Test
|
||||
Content-Type: application/sdp
|
||||
Content-Length: [len]
|
||||
|
||||
v=0
|
||||
o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]
|
||||
s=-
|
||||
c=IN IP[media_ip_type] [media_ip]
|
||||
t=0 0
|
||||
m=audio [media_port] RTP/AVP 96 97 0 8 101 98
|
||||
a=rtpmap:96 speex/16000
|
||||
a=fmtp:96 vbr=on
|
||||
a=rtpmap:97 speex/8000
|
||||
a=fmtp:97 vbr=on
|
||||
a=rtpmap:101 telephone-event/16000
|
||||
a=rtpmap:98 telephone-event/8000
|
||||
m=audio [media_port+1] RTP/AVP 96 97 0 8 101 98
|
||||
a=rtpmap:96 speex/16000
|
||||
a=fmtp:96 vbr=on
|
||||
a=rtpmap:97 speex/8000
|
||||
a=fmtp:97 vbr=on
|
||||
a=rtpmap:101 telephone-event/16000
|
||||
a=rtpmap:98 telephone-event/8000
|
||||
m=video [media_port+2] RTP/AVP 96
|
||||
a=rtpmap:96 VP8/90000
|
||||
|
||||
]]>
|
||||
</send>
|
||||
|
||||
<recv response="100"
|
||||
optional="true">
|
||||
</recv>
|
||||
|
||||
<recv response="180" optional="true">
|
||||
</recv>
|
||||
|
||||
<recv response="183" optional="true">
|
||||
</recv>
|
||||
|
||||
<!-- By adding rrs="true" (Record Route Sets), the route sets -->
|
||||
<!-- are saved and used for following messages sent. Useful to test -->
|
||||
<!-- against stateful SIP proxies/B2BUAs. -->
|
||||
<recv response="200" rtd="true">
|
||||
</recv>
|
||||
|
||||
<!-- Packet lost can be simulated in any send/recv message by -->
|
||||
<!-- by adding the 'lost = "10"'. Value can be [1-100] percent. -->
|
||||
<send>
|
||||
<![CDATA[
|
||||
|
||||
ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0
|
||||
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
|
||||
From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
|
||||
To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
|
||||
Call-ID: [call_id]
|
||||
CSeq: 1 ACK
|
||||
Contact: sip:sipp@[local_ip]:[local_port]
|
||||
Max-Forwards: 70
|
||||
Subject: Performance Test
|
||||
Content-Length: 0
|
||||
|
||||
]]>
|
||||
</send>
|
||||
|
||||
<!-- This delay can be customized by the -d command-line option -->
|
||||
<!-- or by adding a 'milliseconds = "value"' option here. -->
|
||||
<pause/>
|
||||
|
||||
<!-- The 'crlf' option inserts a blank line in the statistics report. -->
|
||||
<send retrans="500">
|
||||
<![CDATA[
|
||||
|
||||
BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
|
||||
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
|
||||
From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
|
||||
To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
|
||||
Call-ID: [call_id]
|
||||
CSeq: 2 BYE
|
||||
Contact: sip:sipp@[local_ip]:[local_port]
|
||||
Max-Forwards: 70
|
||||
Subject: Performance Test
|
||||
Content-Length: 0
|
||||
|
||||
]]>
|
||||
</send>
|
||||
|
||||
<recv response="200" crlf="true">
|
||||
</recv>
|
||||
|
||||
<!-- definition of the response time repartition table (unit is ms) -->
|
||||
<ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
|
||||
|
||||
<!-- definition of the call length repartition table (unit is ms) -->
|
||||
<CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
|
||||
|
||||
</scenario>
|
||||
|
||||
129
tester/sipp/call_with_multiple_video_mline_in_sdp.xml
Normal file
129
tester/sipp/call_with_multiple_video_mline_in_sdp.xml
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||
<!DOCTYPE scenario SYSTEM "sipp.dtd">
|
||||
|
||||
<!-- This program is free software; you can redistribute it and/or -->
|
||||
<!-- modify it under the terms of the GNU General Public License as -->
|
||||
<!-- published by the Free Software Foundation; either version 2 of the -->
|
||||
<!-- License, or (at your option) any later version. -->
|
||||
<!-- -->
|
||||
<!-- This program is distributed in the hope that it will be useful, -->
|
||||
<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->
|
||||
<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->
|
||||
<!-- GNU General Public License for more details. -->
|
||||
<!-- -->
|
||||
<!-- You should have received a copy of the GNU General Public License -->
|
||||
<!-- along with this program; if not, write to the -->
|
||||
<!-- Free Software Foundation, Inc., -->
|
||||
<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->
|
||||
<!-- -->
|
||||
<!-- Sipp default 'uac' scenario. -->
|
||||
<!-- -->
|
||||
|
||||
<scenario name="Basic Sipstone UAC">
|
||||
<!-- In client mode (sipp placing calls), the Call-ID MUST be -->
|
||||
<!-- generated by sipp. To do so, use [call_id] keyword. -->
|
||||
<send retrans="500">
|
||||
<![CDATA[
|
||||
|
||||
INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
|
||||
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
|
||||
From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
|
||||
To: sut <sip:[service]@[remote_ip]:[remote_port]>
|
||||
Call-ID: [call_id]
|
||||
CSeq: 1 INVITE
|
||||
Contact: sip:sipp@[local_ip]:[local_port]
|
||||
Max-Forwards: 70
|
||||
Subject: Performance Test
|
||||
Content-Type: application/sdp
|
||||
Content-Length: [len]
|
||||
|
||||
v=0
|
||||
o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]
|
||||
s=-
|
||||
c=IN IP[media_ip_type] [media_ip]
|
||||
t=0 0
|
||||
m=audio [media_port] RTP/AVP 96 97 0 8 101 98
|
||||
a=rtpmap:96 speex/16000
|
||||
a=fmtp:96 vbr=on
|
||||
a=rtpmap:97 speex/8000
|
||||
a=fmtp:97 vbr=on
|
||||
a=rtpmap:101 telephone-event/16000
|
||||
a=rtpmap:98 telephone-event/8000
|
||||
m=video [media_port+2] RTP/AVP 96
|
||||
a=rtpmap:96 VP8/90000
|
||||
m=video [media_port+3] RTP/AVP 96
|
||||
a=rtpmap:96 VP8/90000
|
||||
m=video [media_port+4] RTP/AVP 96
|
||||
a=rtpmap:96 VP8/90000
|
||||
|
||||
]]>
|
||||
</send>
|
||||
|
||||
<recv response="100"
|
||||
optional="true">
|
||||
</recv>
|
||||
|
||||
<recv response="180" optional="true">
|
||||
</recv>
|
||||
|
||||
<recv response="183" optional="true">
|
||||
</recv>
|
||||
|
||||
<!-- By adding rrs="true" (Record Route Sets), the route sets -->
|
||||
<!-- are saved and used for following messages sent. Useful to test -->
|
||||
<!-- against stateful SIP proxies/B2BUAs. -->
|
||||
<recv response="200" rtd="true">
|
||||
</recv>
|
||||
|
||||
<!-- Packet lost can be simulated in any send/recv message by -->
|
||||
<!-- by adding the 'lost = "10"'. Value can be [1-100] percent. -->
|
||||
<send>
|
||||
<![CDATA[
|
||||
|
||||
ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0
|
||||
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
|
||||
From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
|
||||
To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
|
||||
Call-ID: [call_id]
|
||||
CSeq: 1 ACK
|
||||
Contact: sip:sipp@[local_ip]:[local_port]
|
||||
Max-Forwards: 70
|
||||
Subject: Performance Test
|
||||
Content-Length: 0
|
||||
|
||||
]]>
|
||||
</send>
|
||||
|
||||
<!-- This delay can be customized by the -d command-line option -->
|
||||
<!-- or by adding a 'milliseconds = "value"' option here. -->
|
||||
<pause/>
|
||||
|
||||
<!-- The 'crlf' option inserts a blank line in the statistics report. -->
|
||||
<send retrans="500">
|
||||
<![CDATA[
|
||||
|
||||
BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
|
||||
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
|
||||
From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
|
||||
To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
|
||||
Call-ID: [call_id]
|
||||
CSeq: 2 BYE
|
||||
Contact: sip:sipp@[local_ip]:[local_port]
|
||||
Max-Forwards: 70
|
||||
Subject: Performance Test
|
||||
Content-Length: 0
|
||||
|
||||
]]>
|
||||
</send>
|
||||
|
||||
<recv response="200" crlf="true">
|
||||
</recv>
|
||||
|
||||
<!-- definition of the response time repartition table (unit is ms) -->
|
||||
<ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
|
||||
|
||||
<!-- definition of the call length repartition table (unit is ms) -->
|
||||
<CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
|
||||
|
||||
</scenario>
|
||||
|
||||
125
tester/sipp/call_with_video_mline_before_audio_in_sdp.xml
Normal file
125
tester/sipp/call_with_video_mline_before_audio_in_sdp.xml
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||
<!DOCTYPE scenario SYSTEM "sipp.dtd">
|
||||
|
||||
<!-- This program is free software; you can redistribute it and/or -->
|
||||
<!-- modify it under the terms of the GNU General Public License as -->
|
||||
<!-- published by the Free Software Foundation; either version 2 of the -->
|
||||
<!-- License, or (at your option) any later version. -->
|
||||
<!-- -->
|
||||
<!-- This program is distributed in the hope that it will be useful, -->
|
||||
<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->
|
||||
<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->
|
||||
<!-- GNU General Public License for more details. -->
|
||||
<!-- -->
|
||||
<!-- You should have received a copy of the GNU General Public License -->
|
||||
<!-- along with this program; if not, write to the -->
|
||||
<!-- Free Software Foundation, Inc., -->
|
||||
<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->
|
||||
<!-- -->
|
||||
<!-- Sipp default 'uac' scenario. -->
|
||||
<!-- -->
|
||||
|
||||
<scenario name="Basic Sipstone UAC">
|
||||
<!-- In client mode (sipp placing calls), the Call-ID MUST be -->
|
||||
<!-- generated by sipp. To do so, use [call_id] keyword. -->
|
||||
<send retrans="500">
|
||||
<![CDATA[
|
||||
|
||||
INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
|
||||
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
|
||||
From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
|
||||
To: sut <sip:[service]@[remote_ip]:[remote_port]>
|
||||
Call-ID: [call_id]
|
||||
CSeq: 1 INVITE
|
||||
Contact: sip:sipp@[local_ip]:[local_port]
|
||||
Max-Forwards: 70
|
||||
Subject: Performance Test
|
||||
Content-Type: application/sdp
|
||||
Content-Length: [len]
|
||||
|
||||
v=0
|
||||
o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]
|
||||
s=-
|
||||
c=IN IP[media_ip_type] [media_ip]
|
||||
t=0 0
|
||||
m=video [media_port+2] RTP/AVP 96
|
||||
a=rtpmap:96 VP8/90000
|
||||
m=audio [media_port] RTP/AVP 96 97 0 8 101 98
|
||||
a=rtpmap:96 speex/16000
|
||||
a=fmtp:96 vbr=on
|
||||
a=rtpmap:97 speex/8000
|
||||
a=fmtp:97 vbr=on
|
||||
a=rtpmap:101 telephone-event/16000
|
||||
a=rtpmap:98 telephone-event/8000
|
||||
|
||||
]]>
|
||||
</send>
|
||||
|
||||
<recv response="100"
|
||||
optional="true">
|
||||
</recv>
|
||||
|
||||
<recv response="180" optional="true">
|
||||
</recv>
|
||||
|
||||
<recv response="183" optional="true">
|
||||
</recv>
|
||||
|
||||
<!-- By adding rrs="true" (Record Route Sets), the route sets -->
|
||||
<!-- are saved and used for following messages sent. Useful to test -->
|
||||
<!-- against stateful SIP proxies/B2BUAs. -->
|
||||
<recv response="200" rtd="true">
|
||||
</recv>
|
||||
|
||||
<!-- Packet lost can be simulated in any send/recv message by -->
|
||||
<!-- by adding the 'lost = "10"'. Value can be [1-100] percent. -->
|
||||
<send>
|
||||
<![CDATA[
|
||||
|
||||
ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0
|
||||
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
|
||||
From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
|
||||
To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
|
||||
Call-ID: [call_id]
|
||||
CSeq: 1 ACK
|
||||
Contact: sip:sipp@[local_ip]:[local_port]
|
||||
Max-Forwards: 70
|
||||
Subject: Performance Test
|
||||
Content-Length: 0
|
||||
|
||||
]]>
|
||||
</send>
|
||||
|
||||
<!-- This delay can be customized by the -d command-line option -->
|
||||
<!-- or by adding a 'milliseconds = "value"' option here. -->
|
||||
<pause/>
|
||||
|
||||
<!-- The 'crlf' option inserts a blank line in the statistics report. -->
|
||||
<send retrans="500">
|
||||
<![CDATA[
|
||||
|
||||
BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
|
||||
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
|
||||
From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
|
||||
To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
|
||||
Call-ID: [call_id]
|
||||
CSeq: 2 BYE
|
||||
Contact: sip:sipp@[local_ip]:[local_port]
|
||||
Max-Forwards: 70
|
||||
Subject: Performance Test
|
||||
Content-Length: 0
|
||||
|
||||
]]>
|
||||
</send>
|
||||
|
||||
<recv response="200" crlf="true">
|
||||
</recv>
|
||||
|
||||
<!-- definition of the response time repartition table (unit is ms) -->
|
||||
<ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
|
||||
|
||||
<!-- definition of the call length repartition table (unit is ms) -->
|
||||
<CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
|
||||
|
||||
</scenario>
|
||||
|
||||
|
|
@ -72,8 +72,12 @@ static void linphone_stun_test_grab_ip()
|
|||
int tmp=0;
|
||||
|
||||
memset(&dummy_call, 0, sizeof(LinphoneCall));
|
||||
dummy_call.media_ports[0].rtp_port = 7078;
|
||||
dummy_call.media_ports[1].rtp_port = 9078;
|
||||
dummy_call.main_audio_stream_index = 0;
|
||||
dummy_call.main_video_stream_index = 1;
|
||||
dummy_call.main_text_stream_index = 2;
|
||||
dummy_call.media_ports[dummy_call.main_audio_stream_index].rtp_port = 7078;
|
||||
dummy_call.media_ports[dummy_call.main_video_stream_index].rtp_port = 9078;
|
||||
dummy_call.media_ports[dummy_call.main_text_stream_index].rtp_port = 11078;
|
||||
|
||||
linphone_core_set_stun_server(lc_stun->lc, stun_address);
|
||||
BC_ASSERT_STRING_EQUAL(stun_address, linphone_core_get_stun_server(lc_stun->lc));
|
||||
|
|
@ -91,6 +95,8 @@ static void linphone_stun_test_grab_ip()
|
|||
BC_ASSERT( dummy_call.vc.addr[0] != '\0');
|
||||
BC_ASSERT( dummy_call.vc.port != 0);
|
||||
#endif
|
||||
BC_ASSERT( dummy_call.tc.addr[0] != '\0');
|
||||
BC_ASSERT( dummy_call.tc.port != 0);
|
||||
|
||||
ms_message("STUN test result: local audio port maps to %s:%i",
|
||||
dummy_call.ac.addr,
|
||||
|
|
@ -100,6 +106,9 @@ static void linphone_stun_test_grab_ip()
|
|||
dummy_call.vc.addr,
|
||||
dummy_call.vc.port);
|
||||
#endif
|
||||
ms_message("STUN test result: local text port maps to %s:%i",
|
||||
dummy_call.tc.addr,
|
||||
dummy_call.tc.port);
|
||||
|
||||
linphone_core_manager_destroy(lc_stun);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue