Commit a81d673f authored by Sylvain Berfini's avatar Sylvain Berfini 🎩
Browse files

Added API to get the meta RTP transports + test to check we can append a RTP...

Added API to get the meta RTP transports + test to check we can append a RTP transport modifier on it
parent ee44a22e
......@@ -90,3 +90,6 @@ tester/record-call_with_file_player.wav
tester/ZIDCache*.xml
tester/stereo-record.wav
coreapi/bellesip_sal/.dirstamp
coreapi/ldap/.dirstamp
......@@ -2009,6 +2009,7 @@ void linphone_call_init_audio_stream(LinphoneCall *call){
ms_free(cname);
rtp_session_set_symmetric_rtp(audiostream->ms.sessions.rtp_session,linphone_core_symmetric_rtp_enabled(lc));
setup_dtls_params(call, &audiostream->ms);
media_stream_reclaim_sessions(&audiostream->ms, &call->sessions[0]);
}else{
call->audiostream=audio_stream_new_with_sessions(&call->sessions[0]);
}
......@@ -2108,8 +2109,8 @@ void linphone_call_init_video_stream(LinphoneCall *call){
video_stream_set_rtcp_information(call->videostream, cname, rtcp_tool);
ms_free(cname);
rtp_session_set_symmetric_rtp(call->videostream->ms.sessions.rtp_session,linphone_core_symmetric_rtp_enabled(lc));
setup_dtls_params(call, &call->videostream->ms);
media_stream_reclaim_sessions(&call->videostream->ms, &call->sessions[1]);
}else{
call->videostream=video_stream_new_with_sessions(&call->sessions[1]);
}
......@@ -4143,3 +4144,40 @@ void linphone_call_set_audio_route(LinphoneCall *call, LinphoneAudioRoute route)
audio_stream_set_audio_route(call->audiostream, (MSAudioRoute) route);
}
}
int linphone_call_get_stream_count(LinphoneCall *call) {
// Revisit when multiple media streams will be implemented
return 2;
}
MSFormatType linphone_call_get_stream_type(LinphoneCall *call, int stream_index) {
// Revisit when multiple media streams will be implemented
if (stream_index == 0) {
return MSAudio;
}
return MSVideo;
}
RtpTransport* linphone_call_get_meta_rtp_transport(LinphoneCall *call, int stream_index) {
RtpTransport *meta_rtp;
RtpTransport *meta_rtcp;
if (!call || stream_index < 0 || stream_index >= linphone_call_get_stream_count(call)) {
return NULL;
}
rtp_session_get_transports(call->sessions[stream_index].rtp_session, &meta_rtp, &meta_rtcp);
return meta_rtp;
}
RtpTransport* linphone_call_get_meta_rtcp_transport(LinphoneCall *call, int stream_index) {
RtpTransport *meta_rtp;
RtpTransport *meta_rtcp;
if (!call || stream_index < 0 || stream_index >= linphone_call_get_stream_count(call)) {
return NULL;
}
rtp_session_get_transports(call->sessions[stream_index].rtp_session, &meta_rtp, &meta_rtcp);
return meta_rtcp;
}
\ No newline at end of file
......@@ -898,7 +898,43 @@ typedef enum _LinphoneAudioRoute LinphoneAudioRoute;
*
* @ingroup call_control
**/
LINPHONE_PUBLIC void linphone_call_set_audio_route(LinphoneCall *call, LinphoneAudioRoute route);
LINPHONE_PUBLIC void linphone_call_set_audio_route(LinphoneCall *call, LinphoneAudioRoute route);
/**
* Returns the number of stream for the given call.
* Currently there is only two (Audio, Video), but later there will be more.
* @param call
*
* @return 2
**/
LINPHONE_PUBLIC int linphone_call_get_stream_count(LinphoneCall *call);
/**
* Returns the type of stream for the given stream index.
* @param call
* @param stream_index
*
* @return MsAudio if stream_index = 0, MsVideo otherwise
**/
LINPHONE_PUBLIC MSFormatType linphone_call_get_stream_type(LinphoneCall *call, int stream_index);
/**
* Returns the meta rtp transport for the given stream index.
* @param call
* @param stream_index
*
* @return a pointer to the meta rtp transport if it exists, NULL otherwise
**/
LINPHONE_PUBLIC RtpTransport* linphone_call_get_meta_rtp_transport(LinphoneCall *call, int stream_index);
/**
* Returns the meta rtcp transport for the given stream index.
* @param call
* @param stream_index
*
* @return a pointer to the meta rtcp transport if it exists, NULL otherwise
**/
LINPHONE_PUBLIC RtpTransport* linphone_call_get_meta_rtcp_transport(LinphoneCall *call, int stream_index);
/*keep this in sync with mediastreamer2/msvolume.h*/
......
......@@ -33,6 +33,16 @@
#endif
#endif
int static min(int a, int b) {
if (a < b) return a;
return b;
}
int static max(int a, int b) {
if (a < b) return b;
return a;
}
static void srtp_call(void);
static char *create_filepath(const char *dir, const char *filename, const char *ext);
......@@ -4430,6 +4440,125 @@ end:
linphone_core_manager_destroy(pauline);
}
typedef struct _RtpTransportModifierData {
int packetSentCount;
int packetReceivedCount;
} RtpTransportModifierData;
static int rtptm_on_send(RtpTransportModifier *rtptm, mblk_t *msg) {
RtpTransportModifierData *data = rtptm->data;
data->packetSentCount += 1;
/* /!\ DO NOT RETURN 0 or the packet will never leave /!\ */
return msgdsize(msg);
}
static int rtptm_on_receive(RtpTransportModifier *rtptm, mblk_t *msg) {
RtpTransportModifierData *data = rtptm->data;
data->packetReceivedCount += 1;
return 0;
}
static void rtptm_destroy(RtpTransportModifier *rtptm) {
// Do nothing, we'll free it later
}
void static call_state_changed_4(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *msg){
if (cstate == LinphoneCallIncomingReceived || cstate == LinphoneCallOutgoingProgress) {
RtpTransport *rtpt = NULL;
RtpTransportModifierData *data = ms_new0(RtpTransportModifierData, 1);
RtpTransportModifier *rtptm = ms_new0(RtpTransportModifier, 1);
rtpt = linphone_call_get_meta_rtp_transport(call, 0);
rtptm->data = data;
rtptm->t_process_on_send = rtptm_on_send;
rtptm->t_process_on_receive = rtptm_on_receive;
rtptm->t_destroy = rtptm_destroy;
meta_rtp_transport_append_modifier(rtpt, rtptm);
call->user_data = rtptm;
}
}
static void call_with_custom_rtp_modifier(void) {
LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
LinphoneCall* call_pauline;
LinphoneCall* call_marie;
const rtp_stats_t * stats;
bool_t call_ok;
LinphoneCoreVTable * v_table;
RtpTransportModifier *rtptm_marie = NULL;
RtpTransportModifier *rtptm_pauline = NULL;
RtpTransportModifierData *data_marie = NULL;
RtpTransportModifierData *data_pauline = NULL;
v_table = linphone_core_v_table_new();
v_table->call_state_changed=call_state_changed_4;
linphone_core_add_listener(pauline->lc,v_table);
v_table = linphone_core_v_table_new();
v_table->call_state_changed=call_state_changed_4;
linphone_core_add_listener(marie->lc,v_table);
BC_ASSERT_TRUE((call_ok=call(pauline,marie)));
if (!call_ok) goto end;
wait_for_until(pauline->lc, marie->lc, NULL, 5, 3000);
call_pauline = linphone_core_get_current_call(pauline->lc);
rtptm_pauline = (RtpTransportModifier *)call_pauline->user_data;
call_marie = linphone_core_get_current_call(marie->lc);
rtptm_marie = (RtpTransportModifier *)call_marie->user_data;
linphone_core_pause_call(pauline->lc,call_pauline);
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallPausing,1));
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallPausedByRemote,1));
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallPaused,1));
/*stay in pause a little while in order to generate traffic*/
wait_for_until(pauline->lc, marie->lc, NULL, 5, 2000);
linphone_core_resume_call(pauline->lc,call_pauline);
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,2));
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,2));
/*same here: wait a while for a bit of a traffic, we need to receive a RTCP packet*/
wait_for_until(pauline->lc, marie->lc, NULL, 5, 5000);
/*since RTCP streams are reset when call is paused/resumed, there should be no loss at all*/
stats = rtp_session_get_stats(call_pauline->sessions->rtp_session);
BC_ASSERT_EQUAL(stats->cum_packet_loss, 0, int, "%d");
linphone_core_terminate_all_calls(pauline->lc);
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1));
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1));
BC_ASSERT_PTR_NOT_NULL(rtptm_marie);
BC_ASSERT_PTR_NOT_NULL(rtptm_pauline);
data_marie = (RtpTransportModifierData *)rtptm_marie->data;
data_pauline = (RtpTransportModifierData *)rtptm_pauline->data;
BC_ASSERT_PTR_NOT_NULL(data_marie);
BC_ASSERT_PTR_NOT_NULL(data_pauline);
ms_message("Marie sent %i RTP packets and received %i", data_marie->packetSentCount, data_marie->packetReceivedCount);
ms_message("Pauline sent %i RTP packets and received %i", data_pauline->packetSentCount, data_pauline->packetReceivedCount);
// There will be a few RTP packets sent on marie's side before the call is ended at pauline's request, so we need the threshold
BC_ASSERT_TRUE(max(data_pauline->packetReceivedCount, data_marie->packetSentCount) - min(data_pauline->packetReceivedCount, data_marie->packetSentCount) < 8);
BC_ASSERT_TRUE(data_marie->packetReceivedCount == data_pauline->packetSentCount);
end:
if (data_pauline) {
ms_free(data_pauline);
}
ms_free(rtptm_pauline);
if (data_marie) {
ms_free(data_marie);
}
ms_free(rtptm_marie);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
}
test_t call_tests[] = {
{ "Early declined call", early_declined_call },
{ "Call declined", call_declined },
......@@ -4557,7 +4686,8 @@ test_t call_tests[] = {
{ "Simple mono call with opus", simple_mono_call_opus },
{ "Call with FQDN in SDP", call_with_fqdn_in_sdp},
{ "Call with RTP IO mode", call_with_rtp_io_mode },
{ "Call with generic NACK RTCP feedback", call_with_generic_nack_rtcp_feedback }
{ "Call with generic NACK RTCP feedback", call_with_generic_nack_rtcp_feedback },
{ "Call with custom RTP Modifier", call_with_custom_rtp_modifier }
};
test_suite_t call_test_suite = {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment