From cc640524b498981ee523ebf4e951adfc81c25835 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Mon, 21 May 2012 12:25:01 +0200 Subject: [PATCH 1/2] fix missing handling of paused-by-remote when done twice --- coreapi/callbacks.c | 2 +- coreapi/linphone_tunnel.h | 10 +++++++--- coreapi/linphonecore.c | 4 ++-- coreapi/linphonecore.h | 3 +++ coreapi/proxy.c | 2 +- 5 files changed, 14 insertions(+), 7 deletions(-) diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index 142a7a564..d7bc861ba 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -463,7 +463,7 @@ static void call_updating(SalOp *op){ case LinphoneCallPausedByRemote: if (sal_media_description_has_dir(rmd,SalStreamSendRecv) || sal_media_description_has_dir(rmd,SalStreamRecvOnly)){ call_resumed(lc,call); - } + }else call_paused_by_remote(lc,call); break; case LinphoneCallStreamsRunning: case LinphoneCallConnected: diff --git a/coreapi/linphone_tunnel.h b/coreapi/linphone_tunnel.h index 539668904..ea49ac8b2 100644 --- a/coreapi/linphone_tunnel.h +++ b/coreapi/linphone_tunnel.h @@ -52,7 +52,7 @@ extern "C" * Add a tunnel server. At least one should be provided to be able to connect. * When several addresses are provided, the tunnel client may try each of them until it gets connected. * @param tunnel object - * @param ip server ip address + * @param host server ip address * @param port tunnel server tls port, recommended value is 443 */ void linphone_tunnel_add_server(LinphoneTunnel *tunnel, const char *host, int port); @@ -60,7 +60,7 @@ void linphone_tunnel_add_server(LinphoneTunnel *tunnel, const char *host, int po *Add tunnel server with auto detection capabilities * * @param tunnel object - * @param ip tunnel server ip address + * @param host tunnel server ip address * @param port tunnel server tls port, recommended value is 443 * @param remote_udp_mirror remote port on the tunnel server side used to test udp reachability * @param delay udp packet round trip delay in ms considered as acceptable. recommended value is 1000 ms. @@ -79,7 +79,7 @@ void linphone_tunnel_clean_servers(LinphoneTunnel *tunnel); /** * Sets whether tunneling of SIP and RTP is required. * @param tunnel object - * @param isEnabled If true enter in tunneled mode, if false exits from tunneled mode. + * @param enabled If true enter in tunneled mode, if false exits from tunneled mode. * The TunnelManager takes care of refreshing SIP registration when switching on or off the tunneled mode. * **/ @@ -109,6 +109,10 @@ void linphone_tunnel_set_http_proxy_auth_info(LinphoneTunnel*tunnel, const char* void linphone_tunnel_enable_logs(LinphoneTunnel *tunnel, bool_t enabled); +/** + * @} +**/ + #ifdef __cplusplus } #endif diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 802afe725..0ca5b7b4a 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -2367,7 +2367,7 @@ int linphone_core_update_call(LinphoneCore *lc, LinphoneCall *call, const Linpho * Then, when the user responds to dialog prompt, it becomes possible to call linphone_core_accept_call_update() to answer * the reINVITE, with eventually video enabled in the LinphoneCallParams argument. * - * @Returns 0 if successful, -1 if the linphone_core_defer_call_update() was done outside a #LinphoneCallUpdatedByRemote notification, which is illegal. + * @return 0 if successful, -1 if the linphone_core_defer_call_update() was done outside a #LinphoneCallUpdatedByRemote notification, which is illegal. **/ int linphone_core_defer_call_update(LinphoneCore *lc, LinphoneCall *call){ if (call->state==LinphoneCallUpdatedByRemote){ @@ -2395,7 +2395,7 @@ int linphone_core_defer_call_update(LinphoneCore *lc, LinphoneCall *call){ * @param lc the linphone core object. * @param call the LinphoneCall object * @param params a LinphoneCallParams object describing the call parameters to accept. - * @Returns 0 if sucessful, -1 otherwise (actually when this function call is performed outside ot #LinphoneCallUpdatedByRemote state). + * @return 0 if sucessful, -1 otherwise (actually when this function call is performed outside ot #LinphoneCallUpdatedByRemote state). **/ int linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params){ SalMediaDescription *md; diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index bd10556a0..0eaec1e81 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -227,6 +227,9 @@ typedef struct _LinphoneVideoPolicy LinphoneVideoPolicy; * The LinphoneCall object represents a call issued or received by the LinphoneCore **/ struct _LinphoneCall; +/** + * The LinphoneCall object represents a call issued or received by the LinphoneCore +**/ typedef struct _LinphoneCall LinphoneCall; /** Callback prototype */ diff --git a/coreapi/proxy.c b/coreapi/proxy.c index cf7675807..1676e0918 100644 --- a/coreapi/proxy.c +++ b/coreapi/proxy.c @@ -477,7 +477,7 @@ const char *linphone_proxy_config_get_route(const LinphoneProxyConfig *obj){ /** * Returns the SIP identity that belongs to this proxy configuration. * - * The SIP identity is a SIP address (Display Name ) + * The SIP identity is a SIP address (Display Name ) **/ const char *linphone_proxy_config_get_identity(const LinphoneProxyConfig *obj){ return obj->reg_identity; From d92f7e0b38703626dc96a03a4500d631280e8a9f Mon Sep 17 00:00:00 2001 From: Yann Diorcet Date: Mon, 21 May 2012 15:35:14 +0200 Subject: [PATCH 2/2] Add call audio/video stats --- coreapi/linphonecall.c | 53 +++++++++++++++++++++++++++++++++++++++--- coreapi/linphonecore.h | 23 ++++++++++++++++-- coreapi/private.h | 5 +++- 3 files changed, 75 insertions(+), 6 deletions(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 69f9266a1..8dccf9612 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -68,6 +68,14 @@ LinphoneCore *linphone_call_get_core(const LinphoneCall *call){ return call->core; } +const LinphoneCallStats *linphone_call_get_audio_stats(const LinphoneCall *call) { + return &call->stats[LINPHONE_CALL_STATS_AUDIO]; +} + +const LinphoneCallStats *linphone_call_get_video_stats(const LinphoneCall *call) { + return &call->stats[LINPHONE_CALL_STATS_VIDEO]; +} + const char* linphone_call_get_authentication_token(LinphoneCall *call){ return call->auth_token; } @@ -305,7 +313,14 @@ static void linphone_call_init_common(LinphoneCall *call, LinphoneAddress *from, if (port_offset==-1) return; call->audio_port=linphone_core_get_audio_port(call->core)+port_offset; call->video_port=linphone_core_get_video_port(call->core)+port_offset; + linphone_call_init_stats(&call->stats[LINPHONE_CALL_STATS_AUDIO], LINPHONE_CALL_STATS_AUDIO); + linphone_call_init_stats(&call->stats[LINPHONE_CALL_STATS_VIDEO], LINPHONE_CALL_STATS_VIDEO); +} +void linphone_call_init_stats(LinphoneCallStats *stats, int type) { + stats->type = LINPHONE_CALL_STATS_AUDIO; + stats->received_rtcp = NULL; + stats->sent_rtcp = NULL; } static void discover_mtu(LinphoneCore *lc, const char *remote){ @@ -1594,6 +1609,7 @@ static void linphone_core_disconnected(LinphoneCore *lc, LinphoneCall *call){ } void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapsed){ + LinphoneCore* lc = call->core; int disconnect_timeout = linphone_core_get_nortp_timeout(call->core); bool_t disconnected=FALSE; @@ -1623,9 +1639,25 @@ void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapse OrtpEvent *ev; while (NULL != (ev=ortp_ev_queue_get(call->videostream_app_evq))){ OrtpEventType evt=ortp_event_get_type(ev); + OrtpEventData *evd=ortp_event_get_data(ev); if (evt == ORTP_EVENT_ZRTP_ENCRYPTION_CHANGED){ - OrtpEventData *evd=ortp_event_get_data(ev); linphone_call_videostream_encryption_changed(call, evd->info.zrtp_stream_encrypted); + } else if (evt == ORTP_EVENT_RTCP_PACKET_RECEIVED) { + call->stats[LINPHONE_CALL_STATS_VIDEO].round_trip_delay = rtp_session_get_round_trip_propagation(call->videostream->session); + if(call->stats[LINPHONE_CALL_STATS_VIDEO].received_rtcp != NULL) + freemsg(call->stats[LINPHONE_CALL_STATS_VIDEO].received_rtcp); + call->stats[LINPHONE_CALL_STATS_VIDEO].received_rtcp = evd->packet; + evd->packet = NULL; + if (lc->vtable.call_stats_updated) + lc->vtable.call_stats_updated(lc, call, &call->stats[LINPHONE_CALL_STATS_VIDEO]); + } else if (evt == ORTP_EVENT_RTCP_PACKET_EMITTED) { + memcpy(&call->stats[LINPHONE_CALL_STATS_VIDEO].jitter_stats, rtp_session_get_jitter_stats(call->videostream->session), sizeof(jitter_stats_t)); + if(call->stats[LINPHONE_CALL_STATS_VIDEO].sent_rtcp != NULL) + freemsg(call->stats[LINPHONE_CALL_STATS_VIDEO].sent_rtcp); + call->stats[LINPHONE_CALL_STATS_VIDEO].sent_rtcp = evd->packet; + evd->packet = NULL; + if (lc->vtable.call_stats_updated) + lc->vtable.call_stats_updated(lc, call, &call->stats[LINPHONE_CALL_STATS_VIDEO]); } ortp_event_destroy(ev); } @@ -1641,12 +1673,27 @@ void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapse OrtpEvent *ev; while (NULL != (ev=ortp_ev_queue_get(call->audiostream_app_evq))){ OrtpEventType evt=ortp_event_get_type(ev); + OrtpEventData *evd=ortp_event_get_data(ev); if (evt == ORTP_EVENT_ZRTP_ENCRYPTION_CHANGED){ - OrtpEventData *evd=ortp_event_get_data(ev); linphone_call_audiostream_encryption_changed(call, evd->info.zrtp_stream_encrypted); } else if (evt == ORTP_EVENT_ZRTP_SAS_READY) { - OrtpEventData *evd=ortp_event_get_data(ev); linphone_call_audiostream_auth_token_ready(call, evd->info.zrtp_sas.sas, evd->info.zrtp_sas.verified); + } else if (evt == ORTP_EVENT_RTCP_PACKET_RECEIVED) { + call->stats[LINPHONE_CALL_STATS_AUDIO].round_trip_delay = rtp_session_get_round_trip_propagation(call->audiostream->session); + if(call->stats[LINPHONE_CALL_STATS_AUDIO].received_rtcp != NULL) + freemsg(call->stats[LINPHONE_CALL_STATS_AUDIO].received_rtcp); + call->stats[LINPHONE_CALL_STATS_AUDIO].received_rtcp = evd->packet; + evd->packet = NULL; + if (lc->vtable.call_stats_updated) + lc->vtable.call_stats_updated(lc, call, &call->stats[LINPHONE_CALL_STATS_AUDIO]); + } else if (evt == ORTP_EVENT_RTCP_PACKET_EMITTED) { + memcpy(&call->stats[LINPHONE_CALL_STATS_AUDIO].jitter_stats, rtp_session_get_jitter_stats(call->audiostream->session), sizeof(jitter_stats_t)); + if(call->stats[LINPHONE_CALL_STATS_AUDIO].sent_rtcp != NULL) + freemsg(call->stats[LINPHONE_CALL_STATS_AUDIO].sent_rtcp); + call->stats[LINPHONE_CALL_STATS_AUDIO].sent_rtcp = evd->packet; + evd->packet = NULL; + if (lc->vtable.call_stats_updated) + lc->vtable.call_stats_updated(lc, call, &call->stats[LINPHONE_CALL_STATS_AUDIO]); } ortp_event_destroy(ev); } diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index bd10556a0..9b0de2e71 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -228,7 +228,23 @@ typedef struct _LinphoneVideoPolicy LinphoneVideoPolicy; **/ struct _LinphoneCall; typedef struct _LinphoneCall LinphoneCall; - + + +#define LINPHONE_CALL_STATS_AUDIO 0 +#define LINPHONE_CALL_STATS_VIDEO 1 + +typedef struct _LinphoneCallStats { + int type; + jitter_stats_t jitter_stats; + mblk_t* received_rtcp; + mblk_t* sent_rtcp; + float round_trip_delay; +} LinphoneCallStats; + +const LinphoneCallStats *linphone_call_get_audio_stats(const LinphoneCall *call); +const LinphoneCallStats *linphone_call_get_video_stats(const LinphoneCall *call); + + /** Callback prototype */ typedef void (*LinphoneCallCbFunc)(struct _LinphoneCall *call,void * user_data); @@ -624,6 +640,8 @@ typedef void (*ReferReceived)(struct _LinphoneCore *lc, const char *refer_to); typedef void (*BuddyInfoUpdated)(struct _LinphoneCore *lc, LinphoneFriend *lf); /** Callback prototype for in progress transfers. The new_call_state is the state of the call resulting of the transfer, at the other party. */ typedef void (*LinphoneTransferStateChanged)(struct _LinphoneCore *lc, LinphoneCall *transfered, LinphoneCallState new_call_state); +/** Callback prototype */ +typedef void (*CallStatsUpdated)(struct _LinphoneCore *lc, LinphoneCall *call, LinphoneCallStats *stats); /** * This structure holds all callbacks that the application should implement. @@ -641,9 +659,10 @@ typedef struct _LinphoneVTable{ DtmfReceived dtmf_received; /**< A dtmf has been received received */ ReferReceived refer_received; /**< An out of call refer was received */ CallEncryptionChangedCb call_encryption_changed; /**