From 8e200bcf98a4d4c6d101d91d37698e24c05eed15 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 25 Sep 2015 17:27:42 +0200 Subject: [PATCH] fix memory leaks in RTT and fix generation of local media description --- coreapi/chat.c | 22 +++++++++------ coreapi/linphonecall.c | 62 ++++++++++++++++++++++++------------------ coreapi/linphonecore.h | 8 ++++-- coreapi/private.h | 2 ++ 4 files changed, 56 insertions(+), 38 deletions(-) diff --git a/coreapi/chat.c b/coreapi/chat.c index ef5f6ed9d..e47b75bf5 100644 --- a/coreapi/chat.c +++ b/coreapi/chat.c @@ -130,9 +130,6 @@ 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); } @@ -185,16 +182,28 @@ BELLE_SIP_INSTANCIATE_VPTR(LinphoneChatRoom, belle_sip_object_t, NULL, // marshal FALSE); -static LinphoneChatRoom *_linphone_core_create_chat_room(LinphoneCore *lc, LinphoneAddress *addr) { +static LinphoneChatRoom *_linphone_core_create_chat_room_base(LinphoneCore *lc, LinphoneAddress *addr){ LinphoneChatRoom *cr = belle_sip_object_new(LinphoneChatRoom); cr->lc = lc; cr->peer = linphone_address_as_string(addr); cr->peer_url = addr; cr->unread_count = -1; + return cr; +} + +static LinphoneChatRoom *_linphone_core_create_chat_room(LinphoneCore *lc, LinphoneAddress *addr) { + LinphoneChatRoom *cr = _linphone_core_create_chat_room_base(lc, addr); lc->chatrooms = ms_list_append(lc->chatrooms, (void *)cr); return cr; } +LinphoneChatRoom *_linphone_core_create_chat_room_from_call(LinphoneCall *call){ + LinphoneChatRoom *cr = _linphone_core_create_chat_room_base(call->core, + linphone_address_clone(linphone_call_get_remote_address(call))); + cr->call = call; + return cr; +} + static LinphoneChatRoom *_linphone_core_create_chat_room_from_url(LinphoneCore *lc, const char *to) { LinphoneAddress *parsed_url = NULL; if ((parsed_url = linphone_core_interpret_url(lc, to)) != NULL) { @@ -799,11 +808,6 @@ void linphone_core_real_time_text_received(LinphoneCore *lc, LinphoneChatRoom *c char crlf[2] = "\r\n"; if (call && linphone_call_params_realtime_text_enabled(linphone_call_get_current_params(call))) { - 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, ""); } diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 03eca35c8..ff25e4413 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -631,7 +631,7 @@ void linphone_call_make_local_media_description(LinphoneCall *call) { MSList *l; SalMediaDescription *old_md=call->localdesc; int i; - int nb_active_streams = 0; + int max_index = 0; SalMediaDescription *md=sal_media_description_new(); LinphoneAddress *addr; const char *subject; @@ -702,17 +702,19 @@ void linphone_call_make_local_media_description(LinphoneCall *call) { } else ms_warning("Cannot get audio local ssrc for call [%p]",call); - nb_active_streams++; + if (call->main_audio_stream_index > max_index) + max_index = call->main_audio_stream_index; + md->streams[call->main_video_stream_index].proto=md->streams[call->main_audio_stream_index].proto; + md->streams[call->main_video_stream_index].dir=get_video_dir_from_call_params(params); + md->streams[call->main_video_stream_index].type=SalVideo; + strncpy(md->streams[call->main_video_stream_index].name,"Video",sizeof(md->streams[call->main_video_stream_index].name)-1); + if (params->has_video){ strncpy(md->streams[call->main_video_stream_index].rtp_addr,linphone_call_get_public_ip_for_stream(call,call->main_video_stream_index),sizeof(md->streams[call->main_video_stream_index].rtp_addr)); strncpy(md->streams[call->main_video_stream_index].rtcp_addr,linphone_call_get_public_ip_for_stream(call,call->main_video_stream_index),sizeof(md->streams[call->main_video_stream_index].rtcp_addr)); - strncpy(md->streams[call->main_video_stream_index].name,"Video",sizeof(md->streams[call->main_video_stream_index].name)-1); md->streams[call->main_video_stream_index].rtp_port=call->media_ports[call->main_video_stream_index].rtp_port; md->streams[call->main_video_stream_index].rtcp_port=call->media_ports[call->main_video_stream_index].rtcp_port; - md->streams[call->main_video_stream_index].proto=md->streams[call->main_audio_stream_index].proto; - md->streams[call->main_video_stream_index].dir=get_video_dir_from_call_params(params); - md->streams[call->main_video_stream_index].type=SalVideo; codec_hints.bandwidth_limit=0; codec_hints.max_codecs=-1; codec_hints.previously_used=old_md ? old_md->streams[call->main_video_stream_index].already_assigned_payloads : NULL; @@ -726,20 +728,24 @@ void linphone_call_make_local_media_description(LinphoneCall *call) { } else ms_warning("Cannot get video local ssrc for call [%p]",call); - nb_active_streams++; + if (call->main_video_stream_index > max_index) + max_index = call->main_video_stream_index; } else { ms_message("Don't put video stream on local offer for call [%p]",call); + md->streams[call->main_video_stream_index].dir = SalStreamInactive; } + md->streams[call->main_text_stream_index].proto=md->streams[call->main_text_stream_index].proto; + md->streams[call->main_text_stream_index].dir=SalStreamSendRecv; + md->streams[call->main_text_stream_index].type=SalText; + strncpy(md->streams[call->main_text_stream_index].name,"Text",sizeof(md->streams[call->main_text_stream_index].name)-1); if (params->realtimetext_enabled) { strncpy(md->streams[call->main_text_stream_index].rtp_addr,linphone_call_get_public_ip_for_stream(call,call->main_text_stream_index),sizeof(md->streams[call->main_text_stream_index].rtp_addr)); strncpy(md->streams[call->main_text_stream_index].rtcp_addr,linphone_call_get_public_ip_for_stream(call,call->main_text_stream_index),sizeof(md->streams[call->main_text_stream_index].rtcp_addr)); - strncpy(md->streams[call->main_text_stream_index].name,"Text",sizeof(md->streams[call->main_text_stream_index].name)-1); + md->streams[call->main_text_stream_index].rtp_port=call->media_ports[call->main_text_stream_index].rtp_port; md->streams[call->main_text_stream_index].rtcp_port=call->media_ports[call->main_text_stream_index].rtcp_port; - md->streams[call->main_text_stream_index].proto=md->streams[call->main_text_stream_index].proto; - md->streams[call->main_text_stream_index].dir=SalStreamSendRecv; - md->streams[call->main_text_stream_index].type=SalText; + codec_hints.bandwidth_limit=0; codec_hints.max_codecs=-1; codec_hints.previously_used=old_md ? old_md->streams[call->main_text_stream_index].already_assigned_payloads : NULL; @@ -753,28 +759,23 @@ void linphone_call_make_local_media_description(LinphoneCall *call) { } else ms_warning("Cannot get text local ssrc for call [%p]",call); - nb_active_streams++; + if (call->main_text_stream_index > max_index) + max_index = call->main_text_stream_index; } else { ms_message("Don't put text stream on local offer for call [%p]",call); + md->streams[call->main_text_stream_index].dir = SalStreamInactive; } - if (md->nb_streams < nb_active_streams) - md->nb_streams = nb_active_streams; + md->nb_streams = max_index+1; - /* Deactivate inactive streams. */ - for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) { + /* Deactivate unused streams. */ + for (i = md->nb_streams; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) { if (md->streams[i].rtp_port == 0) { md->streams[i].dir = SalStreamInactive; - md->streams[i].rtcp_port = 0; if (call->biggestdesc && i < call->biggestdesc->nb_streams) { md->streams[i].proto = call->biggestdesc->streams[i].proto; md->streams[i].type = call->biggestdesc->streams[i].type; } - codec_hints.bandwidth_limit=0; - codec_hints.max_codecs=1; - codec_hints.previously_used=NULL; - l = make_codec_list(lc, &codec_hints, SalVideo, lc->codecs_conf.video_codecs); - md->streams[i].payloads = l; } } setup_encryption_keys(call,md); @@ -1359,6 +1360,10 @@ static void linphone_call_set_released(LinphoneCall *call){ linphone_call_unref(call->transfer_target); call->transfer_target=NULL; } + if (call->chat_room){ + linphone_chat_room_unref(call->chat_room); + call->chat_room = NULL; + } linphone_call_unref(call); } @@ -1387,6 +1392,9 @@ static void linphone_call_set_terminated(LinphoneCall *call){ linphone_core_stop_dtmf(lc); call->ringing_beep=FALSE; } + if (call->chat_room){ + call->chat_room->call = NULL; + } } /*function to be called at each incoming reINVITE, in order to adjust various local parameters to what is being offered by remote: @@ -4566,10 +4574,12 @@ void linphone_call_set_audio_route(LinphoneCall *call, LinphoneAudioRoute route) } LinphoneChatRoom * linphone_call_get_chat_room(LinphoneCall *call) { - /*stubbed implementation*/ - LinphoneChatRoom * chat_room = linphone_core_get_chat_room(call->core,linphone_call_get_remote_address(call)); - chat_room->call=linphone_call_ref(call); - return chat_room; + if (!call->chat_room){ + if (call->state != LinphoneCallReleased && call->state != LinphoneCallEnd){ + call->chat_room = _linphone_core_create_chat_room_from_call(call); + } + } + return call->chat_room; } int linphone_call_get_stream_count(LinphoneCall *call) { diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index af425c55a..2d435223d 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -46,6 +46,8 @@ extern "C" { #endif struct _LinphoneCore; +struct _LinphoneChatRoom; + /** * Linphone core main object created by function linphone_core_new() . * @ingroup initializing @@ -738,15 +740,16 @@ 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 + * Create a new chat room for messaging from a call if not already existing, else return existing one. + * No reference is given to the caller: the chat room will be deleted when the call is ended. * @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 @@ -1163,7 +1166,6 @@ LINPHONE_PUBLIC LinphoneAuthInfo * linphone_auth_info_new_from_config_file(LpCon #endif -struct _LinphoneChatRoom; /** * @addtogroup chatroom * @{ diff --git a/coreapi/private.h b/coreapi/private.h index 51d52f16e..f12a20173 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -304,6 +304,7 @@ struct _LinphoneCall{ belle_sip_source_t *dtmfs_timer; /*DTMF timer needed to send a DTMF sequence*/ char *dtls_certificate_fingerprint; /**> This fingerprint is computed during stream init and is stored in call to be used when making local media description */ + LinphoneChatRoom *chat_room; bool_t refer_pending; bool_t expect_media_in_ack; bool_t audio_muted; @@ -519,6 +520,7 @@ void linphone_chat_message_set_state(LinphoneChatMessage *msg, LinphoneChatMessa void linphone_chat_room_upload_file(LinphoneChatMessage *msg); void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatMessage *msg); LinphoneChatMessageCbs *linphone_chat_message_cbs_new(void); +LinphoneChatRoom *_linphone_core_create_chat_room_from_call(LinphoneCall *call); /**/ struct _LinphoneProxyConfig