From 90678a34b1be20dccc5b3c2de9b2632a51b2012a Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Mon, 16 Jan 2017 12:21:51 +0100 Subject: [PATCH 01/13] Reflect real media directions in the current call params. --- coreapi/linphonecall.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 21e53e43b..2e274e1b9 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -688,24 +688,30 @@ void linphone_call_update_biggest_desc(LinphoneCall *call, SalMediaDescription * static void force_streams_dir_according_to_state(LinphoneCall *call, SalMediaDescription *md){ int i; - switch (call->state){ - case LinphoneCallPausing: - case LinphoneCallPaused: - break; - default: - return; - break; - } - for (i=0; istreams[i]; - if (sd->dir != SalStreamInactive) { - sd->dir = SalStreamSendOnly; - if (sd->type == SalVideo){ - if (lp_config_get_int(call->core->config, "sip", "inactive_video_on_pause", 0)) { - sd->dir = SalStreamInactive; + + switch (call->state){ + case LinphoneCallPausing: + case LinphoneCallPaused: + if (sd->dir != SalStreamInactive) { + sd->dir = SalStreamSendOnly; + if (sd->type == SalVideo){ + if (lp_config_get_int(call->core->config, "sip", "inactive_video_on_pause", 0)) { + sd->dir = SalStreamInactive; + } + } } - } + break; + default: + break; + } + + /* Reflect the stream directions in the call params */ + if (i == call->main_audio_stream_index) { + linphone_call_params_set_audio_direction(call->current_params, media_direction_from_sal_stream_dir(sd->dir)); + } else if (i == call->main_video_stream_index) { + linphone_call_params_set_video_direction(call->current_params, media_direction_from_sal_stream_dir(sd->dir)); } } } From ce9dc60f9704e79d4a77a4a18877d97cd2e4f4e3 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Mon, 16 Jan 2017 12:22:29 +0100 Subject: [PATCH 02/13] Fix some paused resumed video tests. --- tester/call_video_tester.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/tester/call_video_tester.c b/tester/call_video_tester.c index a4d415024..7cd5179b7 100644 --- a/tester/call_video_tester.c +++ b/tester/call_video_tester.c @@ -69,11 +69,24 @@ static void call_paused_resumed_with_video_base(bool_t sdp_200_ack wait_for_until(pauline->lc, marie->lc, NULL, 5, 2000); - linphone_core_pause_call(pauline->lc,call_pauline); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallPausing,1)); + if (resume_in_audio_send_only_video_inactive_first) { + LinphoneCallParams *params = linphone_core_create_call_params(pauline->lc, call_pauline); + linphone_call_params_set_audio_direction(params,LinphoneMediaDirectionSendOnly); + linphone_call_params_set_video_direction(params,LinphoneMediaDirectionInactive); + linphone_core_update_call(pauline->lc, call_pauline, params); + linphone_call_params_unref(params); + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallUpdating,1)); + } else { + 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_FALSE(linphone_call_params_video_enabled(linphone_call_get_remote_params(call_marie))); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallPaused,1)); + if (resume_in_audio_send_only_video_inactive_first) { + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,2)); + } else { + 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); @@ -93,19 +106,19 @@ static void call_paused_resumed_with_video_base(bool_t sdp_200_ack /*now pauline wants to resume*/ if (resume_in_audio_send_only_video_inactive_first) { LinphoneCallParams *params = linphone_core_create_call_params(pauline->lc, call_pauline); - linphone_call_params_set_video_direction(params,LinphoneMediaDirectionInactive); linphone_call_params_set_audio_direction(params,LinphoneMediaDirectionSendOnly); + linphone_call_params_set_video_direction(params,LinphoneMediaDirectionInactive); linphone_core_update_call(pauline->lc,call_pauline,params); BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallPausedByRemote,2)); BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallUpdating,1)); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,2)); - linphone_call_params_set_video_direction(params,LinphoneMediaDirectionSendRecv); + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,3)); linphone_call_params_set_audio_direction(params,LinphoneMediaDirectionSendRecv); + linphone_call_params_set_video_direction(params,LinphoneMediaDirectionSendRecv); if (with_call_accept) { linphone_core_add_listener(marie->lc, vtable); } linphone_core_update_call(pauline->lc,call_pauline,params); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,3)); + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,4)); linphone_call_params_unref(params); } else { linphone_core_resume_call(pauline->lc, call_pauline); From 562bf46ffca42c5fb0554d9b819244f454e4298a Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Mon, 16 Jan 2017 12:23:19 +0100 Subject: [PATCH 03/13] Improve documentation of linphone_core_pause_call(), linphone_core_resume_call() and linphone_core_update_call(). --- include/linphone/core.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/linphone/core.h b/include/linphone/core.h index 6f4714d25..28a9781bf 100644 --- a/include/linphone/core.h +++ b/include/linphone/core.h @@ -1820,10 +1820,12 @@ LINPHONE_PUBLIC int linphone_core_terminate_all_calls(LinphoneCore *lc); /** * Pauses the call. If a music file has been setup using linphone_core_set_play_file(), * this file will be played to the remote user. + * The only way to resume a paused call is to call linphone_core_resume_call(). * @param[in] lc LinphoneCore object * @param[in] call The call to pause * @return 0 on success, -1 on failure * @ingroup call_control + * @see linphone_core_resume_call() **/ LINPHONE_PUBLIC int linphone_core_pause_call(LinphoneCore *lc, LinphoneCall *call); @@ -1837,10 +1839,12 @@ LINPHONE_PUBLIC int linphone_core_pause_all_calls(LinphoneCore *lc); /** * Resumes a call. + * The call needs to have been paused previously with linphone_core_pause_call(). * @param[in] lc LinphoneCore object * @param[in] call The call to resume * @return 0 on success, -1 on failure * @ingroup call_control + * @see linphone_core_pause_call() **/ LINPHONE_PUBLIC int linphone_core_resume_call(LinphoneCore *lc, LinphoneCall *call); @@ -1850,6 +1854,8 @@ LINPHONE_PUBLIC int linphone_core_resume_call(LinphoneCore *lc, LinphoneCall *ca * - setting up/down the video stream according to the video parameter of the LinphoneCallParams (see linphone_call_params_enable_video() ). * - changing the size of the transmitted video after calling linphone_core_set_preferred_video_size() * In case no changes are requested through the LinphoneCallParams argument, then this argument can be omitted and set to NULL. + * WARNING: Updating a call in the LinphoneCallPaused state will still result in a paused call even if the media directions set in the + * params are sendrecv. To resume a paused call, you need to call linphone_core_resume_call(). * @param[in] lc LinphoneCore object * @param[in] call The call to be updated * @param[in] params The new call parameters to use (may be NULL) From 09627fe9562b9e0420e7d27e06bb4619d3ad7f4e Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Mon, 16 Jan 2017 15:04:37 +0100 Subject: [PATCH 04/13] Print a warning when updating a call using the current call params. --- coreapi/linphonecore.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 76b3072cc..4fd54e556 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -3471,6 +3471,7 @@ int linphone_core_start_update_call(LinphoneCore *lc, LinphoneCall *call){ int linphone_core_update_call(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params){ int err=0; LinphoneCallState nextstate, initial_state; + const LinphoneCallParams *current_params; #if defined(VIDEO_ENABLED) && defined(BUILD_UPNP) bool_t has_video = FALSE; @@ -3501,7 +3502,12 @@ int linphone_core_update_call(LinphoneCore *lc, LinphoneCall *call, const Linpho ms_error("linphone_core_update_call() is not allowed in [%s] state",linphone_call_state_to_string(call->state)); return -1; } - + + current_params = linphone_call_get_current_params(call); + if ((current_params != NULL) && (current_params == params)) { + ms_warning("linphone_core_update_call() is given the current params of the call, this probably not what you intend to do!"); + } + linphone_call_check_ice_session(call, IR_Controlling, TRUE); if (params!=NULL){ From ed17954707dfb7697bb7a2d7cde8d0c58dab366c Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Mon, 16 Jan 2017 16:07:08 +0100 Subject: [PATCH 05/13] fix memory leak --- mediastreamer2 | 2 +- oRTP | 2 +- tester/call_single_tester.c | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/mediastreamer2 b/mediastreamer2 index dcfd617bf..07d69113f 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit dcfd617bf70a131d9090d1d410f909a7a9cfadb0 +Subproject commit 07d69113f6e19a2f72ebfe99f5c2af3e7b7e5f2a diff --git a/oRTP b/oRTP index 155f0c85c..d98a04c13 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit 155f0c85cd659222e97b59b4bb7e0b036370f081 +Subproject commit d98a04c13d0a670f77daeb9f7cc97d5d30cc713d diff --git a/tester/call_single_tester.c b/tester/call_single_tester.c index d0dbd4c0b..394b4e727 100644 --- a/tester/call_single_tester.c +++ b/tester/call_single_tester.c @@ -2899,6 +2899,7 @@ static void call_rejected_because_wrong_credentials_with_params(const char* user ((VTableReference*)(marie->lc->vtable_refs->data))->cbs->vtable->auth_info_requested=NULL; linphone_core_add_auth_info(marie->lc,wrong_auth_info); } + BC_ASSERT_PTR_NOT_NULL(linphone_core_invite_address(marie->lc,marie->identity)); @@ -2918,6 +2919,7 @@ static void call_rejected_because_wrong_credentials_with_params(const char* user linphone_core_clear_all_auth_info(marie->lc); linphone_core_add_auth_info(marie->lc,good_auth_info); linphone_auth_info_destroy(good_auth_info); + linphone_auth_info_destroy(wrong_auth_info); linphone_core_manager_destroy(marie); } From c0048ed884a411dc29f92daf7bf4c6941074675a Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Mon, 16 Jan 2017 16:30:12 +0100 Subject: [PATCH 06/13] add doc on `linphone_core_set_chat_database_path` --- include/linphone/chat.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/linphone/chat.h b/include/linphone/chat.h index 770ae34f4..517834b79 100644 --- a/include/linphone/chat.h +++ b/include/linphone/chat.h @@ -110,7 +110,11 @@ typedef LinphoneBuffer * (*LinphoneChatMessageCbsFileTransferSendCb)(LinphoneCha */ typedef void (*LinphoneChatMessageCbsFileTransferProgressIndicationCb)(LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t total); - +/** + * Set the chat database path. + * @param lc the linphone core + * @param path the database path + */ LINPHONE_PUBLIC void linphone_core_set_chat_database_path(LinphoneCore *lc, const char *path); /** From 3080862c624432e1f56be1514708c5dba16472a2 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Mon, 16 Jan 2017 21:24:34 +0100 Subject: [PATCH 07/13] add test for a rare crash --- mediastreamer2 | 2 +- oRTP | 2 +- tester/call_single_tester.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mediastreamer2 b/mediastreamer2 index 07d69113f..66423e002 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 07d69113f6e19a2f72ebfe99f5c2af3e7b7e5f2a +Subproject commit 66423e00293dc6f840428ad0e5dabd52f1ec0115 diff --git a/oRTP b/oRTP index d98a04c13..4b85949ab 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit d98a04c13d0a670f77daeb9f7cc97d5d30cc713d +Subproject commit 4b85949abbca071b17c65efe48e03d632718fa59 diff --git a/tester/call_single_tester.c b/tester/call_single_tester.c index 394b4e727..d3a036eca 100644 --- a/tester/call_single_tester.c +++ b/tester/call_single_tester.c @@ -5383,7 +5383,7 @@ static void call_with_network_reachable_down_in_callback(void){ linphone_core_cbs_set_call_state_changed(cbs, my_call_state_changed_cb); - marie = linphone_core_manager_new("marie_rc"); + marie = linphone_core_manager_new("laure_rc_udp"); linphone_core_add_callbacks(marie->lc, cbs); From 289d4bb36501671f7cc96cafa134e019faf3d108 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Mon, 16 Jan 2017 21:48:00 +0100 Subject: [PATCH 08/13] update ortp --- oRTP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oRTP b/oRTP index 4b85949ab..dd51efd2c 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit 4b85949abbca071b17c65efe48e03d632718fa59 +Subproject commit dd51efd2cbf010fbf118fbf4ef0a8eb9e4b33f4c From 030b1c05d5d77dac2d34a1be1c98516a8fb9887a Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 17 Jan 2017 11:56:11 +0100 Subject: [PATCH 09/13] Fixed callback issue with file body handler if file is big enough + improved tester --- coreapi/chat_file_transfer.c | 34 +++++++++------- tester/CMakeLists.txt | 4 +- tester/Makefile.am | 2 +- tester/images/nowebcamVGA.jpg | Bin 0 -> 43066 bytes tester/message_tester.c | 74 +++++++++++++++++----------------- 5 files changed, 61 insertions(+), 53 deletions(-) create mode 100644 tester/images/nowebcamVGA.jpg diff --git a/coreapi/chat_file_transfer.c b/coreapi/chat_file_transfer.c index 490bc91cc..b1d066f4b 100644 --- a/coreapi/chat_file_transfer.c +++ b/coreapi/chat_file_transfer.c @@ -109,7 +109,7 @@ static int on_send_body(belle_sip_user_body_handler_t *bh, belle_sip_message_t * lc = msg->chat_room->lc; /* if we've not reach the end of file yet, ask for more data */ /* in case of file body handler, won't be called */ - if (offset < linphone_content_get_size(msg->file_transfer_information)) { + if (msg->file_transfer_filepath == NULL && offset < linphone_content_get_size(msg->file_transfer_information)) { /* get data from call back */ LinphoneChatMessageCbsFileTransferSendCb file_transfer_send_cb = linphone_chat_message_cbs_get_file_transfer_send(msg->callbacks); if (file_transfer_send_cb) { @@ -397,13 +397,15 @@ static void on_recv_body(belle_sip_user_body_handler_t *bh, belle_sip_message_t ms_free(decrypted_buffer); if (retval <= 0) { - if (linphone_chat_message_cbs_get_file_transfer_recv(msg->callbacks)) { - LinphoneBuffer *lb = linphone_buffer_new_from_data(buffer, size); - linphone_chat_message_cbs_get_file_transfer_recv(msg->callbacks)(msg, msg->file_transfer_information, lb); - linphone_buffer_unref(lb); - } else { - /* Legacy: call back given by application level */ - linphone_core_notify_file_transfer_recv(lc, msg, msg->file_transfer_information, (const char *)buffer, size); + if (msg->file_transfer_filepath == NULL) { + if (linphone_chat_message_cbs_get_file_transfer_recv(msg->callbacks)) { + LinphoneBuffer *lb = linphone_buffer_new_from_data(buffer, size); + linphone_chat_message_cbs_get_file_transfer_recv(msg->callbacks)(msg, msg->file_transfer_information, lb); + linphone_buffer_unref(lb); + } else { + /* Legacy: call back given by application level */ + linphone_core_notify_file_transfer_recv(lc, msg, msg->file_transfer_information, (const char *)buffer, size); + } } } else { ms_warning("File transfer decrypt failed with code %d", (int)retval); @@ -428,13 +430,15 @@ static void on_recv_end(belle_sip_user_body_handler_t *bh, void *data) { } if (retval <= 0) { - if (linphone_chat_message_cbs_get_file_transfer_recv(msg->callbacks)) { - LinphoneBuffer *lb = linphone_buffer_new(); - linphone_chat_message_cbs_get_file_transfer_recv(msg->callbacks)(msg, msg->file_transfer_information, lb); - linphone_buffer_unref(lb); - } else { - /* Legacy: call back given by application level */ - linphone_core_notify_file_transfer_recv(lc, msg, msg->file_transfer_information, NULL, 0); + if (msg->file_transfer_filepath == NULL) { + if (linphone_chat_message_cbs_get_file_transfer_recv(msg->callbacks)) { + LinphoneBuffer *lb = linphone_buffer_new(); + linphone_chat_message_cbs_get_file_transfer_recv(msg->callbacks)(msg, msg->file_transfer_information, lb); + linphone_buffer_unref(lb); + } else { + /* Legacy: call back given by application level */ + linphone_core_notify_file_transfer_recv(lc, msg, msg->file_transfer_information, NULL, 0); + } } } diff --git a/tester/CMakeLists.txt b/tester/CMakeLists.txt index b929ceb80..b5c0bc576 100644 --- a/tester/CMakeLists.txt +++ b/tester/CMakeLists.txt @@ -130,7 +130,9 @@ set(RC_FILES rcfiles/zero_length_params_rc ) -set(IMAGE_FILES images/nowebcamCIF.jpg) +set(IMAGE_FILES + images/nowebcamCIF.jpg + images/nowebcamVGA.jpg) set(VCARD_FILES vcards/thousand_vcards.vcf diff --git a/tester/Makefile.am b/tester/Makefile.am index d6969b303..4bc979e1c 100644 --- a/tester/Makefile.am +++ b/tester/Makefile.am @@ -78,7 +78,7 @@ RCFILES = \ rcfiles/friends_rc\ rcfiles/carddav_rc -IMAGE_FILES = images/nowebcamCIF.jpg +IMAGE_FILES = images/nowebcamCIF.jpg images/nowebcamVGA.jpg VCARDS_FILE = vcards/vcards.vcf vcards/thousand_vcards.vcf diff --git a/tester/images/nowebcamVGA.jpg b/tester/images/nowebcamVGA.jpg new file mode 100644 index 0000000000000000000000000000000000000000..968234d320ef74ee843e8d0fb859ecf46e26f1e3 GIT binary patch literal 43066 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 literal 0 HcmV?d00001 diff --git a/tester/message_tester.c b/tester/message_tester.c index 17b0d9634..4ec384cd5 100644 --- a/tester/message_tester.c +++ b/tester/message_tester.c @@ -75,34 +75,25 @@ void message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMess void file_transfer_received(LinphoneChatMessage *msg, const LinphoneContent* content, const LinphoneBuffer *buffer){ FILE* file=NULL; char *receive_file = NULL; - LinphoneChatRoom *cr = linphone_chat_message_get_chat_room(msg); - LinphoneCore *lc = linphone_chat_room_get_core(cr); - if (linphone_chat_message_get_file_transfer_filepath(msg) != NULL) { - if (linphone_buffer_is_empty(buffer)) { - stats* counters = get_stats(lc); - counters->number_of_LinphoneFileTransferDownloadSuccessful++; - return; - } - } else { - receive_file = bc_tester_file("receive_file.dump"); - if (!linphone_chat_message_get_user_data(msg)) { - /*first chunk, creating file*/ - file = fopen(receive_file,"wb"); - linphone_chat_message_set_user_data(msg,(void*)file); /*store fd for next chunks*/ - } - bc_free(receive_file); - file = (FILE*)linphone_chat_message_get_user_data(msg); - BC_ASSERT_PTR_NOT_NULL(file); - if (linphone_buffer_is_empty(buffer)) { /* tranfer complete */ - stats* counters = get_stats(lc); - counters->number_of_LinphoneFileTransferDownloadSuccessful++; - linphone_chat_message_set_user_data(msg, NULL); - fclose(file); - } else { /* store content on a file*/ - if (fwrite(linphone_buffer_get_content(buffer),linphone_buffer_get_size(buffer),1,file)==0){ - ms_error("file_transfer_received(): write() failed: %s",strerror(errno)); - } + // If a file path is set, we should NOT call the on_recv callback ! + BC_ASSERT_PTR_NULL(msg->file_transfer_filepath); + + receive_file = bc_tester_file("receive_file.dump"); + if (!linphone_chat_message_get_user_data(msg)) { + /*first chunk, creating file*/ + file = fopen(receive_file,"wb"); + linphone_chat_message_set_user_data(msg,(void*)file); /*store fd for next chunks*/ + } + bc_free(receive_file); + file = (FILE*)linphone_chat_message_get_user_data(msg); + BC_ASSERT_PTR_NOT_NULL(file); + if (linphone_buffer_is_empty(buffer)) { /* tranfer complete */ + linphone_chat_message_set_user_data(msg, NULL); + fclose(file); + } else { /* store content on a file*/ + if (fwrite(linphone_buffer_get_content(buffer),linphone_buffer_get_size(buffer),1,file)==0){ + ms_error("file_transfer_received(): write() failed: %s",strerror(errno)); } } } @@ -116,6 +107,9 @@ LinphoneBuffer * tester_file_transfer_send(LinphoneChatMessage *msg, const Linph size_t size_to_send; uint8_t *buf; FILE *file_to_send = linphone_chat_message_get_user_data(msg); + + // If a file path is set, we should NOT call the on_send callback ! + BC_ASSERT_PTR_NULL(msg->file_transfer_filepath); BC_ASSERT_PTR_NOT_NULL(file_to_send); if (file_to_send == NULL){ @@ -126,7 +120,7 @@ LinphoneBuffer * tester_file_transfer_send(LinphoneChatMessage *msg, const Linph fseek(file_to_send, (long)offset, SEEK_SET); size_to_send = MIN(size, file_size - offset); buf = ms_malloc(size_to_send); - if (fread(buf, size_to_send, 1, file_to_send)!=size_to_send){ + if (fread(buf, sizeof(uint8_t), size_to_send, file_to_send) != size_to_send){ // reaching end of file, close it fclose(file_to_send); linphone_chat_message_set_user_data(msg, NULL); @@ -154,6 +148,9 @@ void file_transfer_progress_indication(LinphoneChatMessage *msg, const LinphoneC ,(linphone_chat_message_is_outgoing(msg)?"to":"from") , address); counters->progress_of_LinphoneFileTransfer = progress; + if (progress == 100) { + counters->number_of_LinphoneFileTransferDownloadSuccessful++; + } free(address); } @@ -224,7 +221,7 @@ LinphoneChatMessage* create_message_from_nowebcam(LinphoneChatRoom *chat_room) { LinphoneContent* content; LinphoneChatMessage* msg; size_t file_size; - char *send_filepath = bc_tester_res("images/nowebcamCIF.jpg"); + char *send_filepath = bc_tester_res("images/nowebcamVGA.jpg"); file_to_send = fopen(send_filepath, "rb"); fseek(file_to_send, 0, SEEK_END); file_size = ftell(file_to_send); @@ -235,7 +232,7 @@ LinphoneChatMessage* create_message_from_nowebcam(LinphoneChatRoom *chat_room) { linphone_content_set_type(content,"image"); linphone_content_set_subtype(content,"jpeg"); linphone_content_set_size(content,file_size); /*total size to be transfered*/ - linphone_content_set_name(content,"nowebcamCIF.jpg"); + linphone_content_set_name(content,"nowebcamVGA.jpg"); msg = linphone_chat_room_create_file_transfer_message(chat_room, content); cbs = linphone_chat_message_get_callbacks(msg); @@ -243,6 +240,7 @@ LinphoneChatMessage* create_message_from_nowebcam(LinphoneChatRoom *chat_room) { linphone_chat_message_cbs_set_msg_state_changed(cbs,liblinphone_tester_chat_message_msg_state_changed); linphone_chat_message_cbs_set_file_transfer_progress_indication(cbs, file_transfer_progress_indication); linphone_chat_message_set_user_data(msg, file_to_send); + BC_ASSERT_PTR_NOT_NULL(linphone_chat_message_get_user_data(msg)); linphone_content_unref(content); ms_free(send_filepath); @@ -253,17 +251,18 @@ LinphoneChatMessage* create_file_transfer_message_from_nowebcam(LinphoneChatRoom LinphoneChatMessageCbs *cbs; LinphoneContent* content; LinphoneChatMessage* msg; - char *send_filepath = bc_tester_res("images/nowebcamCIF.jpg"); + char *send_filepath = bc_tester_res("images/nowebcamVGA.jpg"); content = linphone_core_create_content(chat_room->lc); belle_sip_object_set_name(&content->base, "nowebcam content"); linphone_content_set_type(content,"image"); linphone_content_set_subtype(content,"jpeg"); - linphone_content_set_name(content,"nowebcamCIF.jpg"); + linphone_content_set_name(content,"nowebcamVGA.jpg"); msg = linphone_chat_room_create_file_transfer_message(chat_room, content); linphone_chat_message_set_file_transfer_filepath(msg, send_filepath); cbs = linphone_chat_message_get_callbacks(msg); + linphone_chat_message_cbs_set_file_transfer_send(cbs, tester_file_transfer_send); linphone_chat_message_cbs_set_msg_state_changed(cbs,liblinphone_tester_chat_message_msg_state_changed); linphone_chat_message_cbs_set_file_transfer_progress_indication(cbs, file_transfer_progress_indication); @@ -451,7 +450,7 @@ static void text_message_with_external_body(void) { void transfer_message_base2(LinphoneCoreManager* marie, LinphoneCoreManager* pauline, bool_t upload_error, bool_t download_error, bool_t use_file_body_handler_in_upload, bool_t use_file_body_handler_in_download, bool_t download_from_history) { - char *send_filepath = bc_tester_res("images/nowebcamCIF.jpg"); + char *send_filepath = bc_tester_res("images/nowebcamVGA.jpg"); char *receive_filepath = bc_tester_file("receive_file.dump"); LinphoneChatRoom* chat_room; LinphoneChatMessage* msg; @@ -681,7 +680,7 @@ static void file_transfer_2_messages_simultaneously(void) { LinphoneChatMessage* msg; LinphoneChatMessage* msg2; LinphoneChatMessageCbs *cbs; - char *send_filepath = bc_tester_res("images/nowebcamCIF.jpg"); + char *send_filepath = bc_tester_res("images/nowebcamVGA.jpg"); char *receive_filepath = bc_tester_file("receive_file.dump"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); @@ -722,11 +721,13 @@ static void file_transfer_2_messages_simultaneously(void) { cbs = linphone_chat_message_get_callbacks(msg); linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed); linphone_chat_message_cbs_set_file_transfer_recv(cbs, file_transfer_received); + linphone_chat_message_cbs_set_file_transfer_progress_indication(cbs, file_transfer_progress_indication); linphone_chat_message_download_file(msg); cbs = linphone_chat_message_get_callbacks(msg2); linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed); linphone_chat_message_cbs_set_file_transfer_recv(cbs, file_transfer_received); + linphone_chat_message_cbs_set_file_transfer_progress_indication(cbs, file_transfer_progress_indication); linphone_chat_message_download_file(msg2); BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,2)); @@ -1217,7 +1218,7 @@ void lime_transfer_message_base(bool_t encrypt_file,bool_t download_file_from_st LinphoneChatMessageCbs *cbs; char *pauline_id, *marie_id; char *filepath; - char *send_filepath = bc_tester_res("images/nowebcamCIF.jpg"); + char *send_filepath = bc_tester_res("images/nowebcamVGA.jpg"); char *receive_filepath = bc_tester_file("receive_file.dump"); MSList * msg_list = NULL; @@ -1286,6 +1287,7 @@ void lime_transfer_message_base(bool_t encrypt_file,bool_t download_file_from_st cbs = linphone_chat_message_get_callbacks(recv_msg); linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed); linphone_chat_message_cbs_set_file_transfer_recv(cbs, file_transfer_received); + linphone_chat_message_cbs_set_file_transfer_progress_indication(cbs, file_transfer_progress_indication); content = linphone_chat_message_get_file_transfer_information(recv_msg); if (!content) goto end; if (encrypt_file) @@ -1564,7 +1566,7 @@ int message_tester_copy_file(const char *from, const char *to) } /* Copy data from "in" to "out" */ - while ( (n=fread(buf, 1, sizeof buf, in)) > 0 ) + while ( (n=fread(buf, sizeof(char), sizeof(buf), in)) > 0 ) { if ( ! fwrite(buf, 1, n, out) ) { From efeab2d4c8b3ae51316009e905055eb41df912ad Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Tue, 17 Jan 2017 15:06:00 +0100 Subject: [PATCH 10/13] fix ortp build on windows --- oRTP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oRTP b/oRTP index dd51efd2c..767cbcd61 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit dd51efd2cbf010fbf118fbf4ef0a8eb9e4b33f4c +Subproject commit 767cbcd61a28fa80e901d3f58ae6a7afc96c2879 From 79684bad94a1331191997070c4fa5eaeafd242c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Grisez?= Date: Mon, 16 Jan 2017 15:30:31 +0100 Subject: [PATCH 11/13] =?UTF-8?q?C++=20wrapper:=C2=A0build=20scripts=20rew?= =?UTF-8?q?orking?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- wrappers/cpp/CMakeLists.txt | 128 +++----------------------- wrappers/cpp/c_make_lists.mustache.in | 40 ++++++++ wrappers/cpp/genheaders.py | 40 ++++---- 3 files changed, 72 insertions(+), 136 deletions(-) create mode 100644 wrappers/cpp/c_make_lists.mustache.in diff --git a/wrappers/cpp/CMakeLists.txt b/wrappers/cpp/CMakeLists.txt index 164870026..a1630a524 100644 --- a/wrappers/cpp/CMakeLists.txt +++ b/wrappers/cpp/CMakeLists.txt @@ -1,119 +1,17 @@ -set(GENERATED_SOURCES - src/account_creator.cc - src/address.cc - src/auth_info.cc - src/buffer.cc - src/call.cc - src/call_log.cc - src/call_params.cc - src/call_stats.cc - src/chat_message.cc - src/chat_room.cc - src/conference.cc - src/conference_params.cc - src/config.cc - src/content.cc - src/core.cc - src/core_v_table.cc - src/error_info.cc - src/event.cc - src/factory.cc - src/friend.cc - src/friend_list.cc - src/nat_policy.cc - src/payload_type.cc - src/player.cc - src/presence_activity.cc - src/presence_model.cc - src/presence_note.cc - src/presence_person.cc - src/presence_service.cc - src/proxy_config.cc - src/sip_transports.cc - src/tunnel.cc - src/tunnel_config.cc - src/vcard.cc - src/video_policy.cc - src/xml_rpc_request.cc - src/xml_rpc_session.cc -) -set(SOURCES - ${GENERATED_SOURCES} - object.cc -) -set(GENERATED_HEADERS - ${CMAKE_CURRENT_BINARY_DIR}/include/account_creator.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/account_creator_listener.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/address.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/auth_info.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/buffer.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/call.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/call_log.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/call_params.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/call_stats.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/chat_message.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/chat_message_listener.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/chat_room.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/conference.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/conference_params.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/config.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/content.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/core.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/core_listener.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/core_v_table.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/enums.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/error_info.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/event.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/factory.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/friend.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/friend_list.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/friend_list_listener.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/linphone.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/nat_policy.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/payload_type.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/player.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/presence_activity.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/presence_model.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/presence_note.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/presence_person.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/presence_service.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/proxy_config.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/sip_transports.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/tunnel_config.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/tunnel.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/vcard.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/video_policy.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/xml_rpc_request.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/xml_rpc_request_listener.hh - ${CMAKE_CURRENT_BINARY_DIR}/include/xml_rpc_session.hh -) -set(HEADERS - ${GENERATED_HEADERS} - object.hh -) +configure_file(c_make_lists.mustache.in c_make_lists.mustache @ONLY) +configure_file(object.cc src/object.cc COPYONLY) +configure_file(object.hh include/object.hh COPYONLY) -add_custom_command(OUTPUT ${GENERATED_SOURCES} ${GENERATED_HEADERS} +add_custom_command(OUTPUT CMakeLists.txt include/linphone.hh COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/genheaders.py" "${PROJECT_BINARY_DIR}/coreapi/help/doc/xml" - DEPENDS *.py *.mustache linphone-doc "${PROJECT_BINARY_DIR}/coreapi/help/doc/xml/index.xml" + DEPENDS *.py *.mustache linphone-doc + "${PROJECT_BINARY_DIR}/coreapi/help/doc/xml/index.xml" + "${CMAKE_CURRENT_BINARY_DIR}/c_make_lists.mustache" ) - -add_compile_options(-Wall -Wextra -Wno-deprecated-declarations -Wno-unused-parameter -Werror --std=c++11) -add_definitions(-DWRAPPER_BUILD) - -add_library(linphone++ SHARED ${SOURCES}) -target_link_libraries(linphone++ PRIVATE linphone) -target_include_directories(linphone++ - PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR} - PRIVATE ${PROJECT_SOURCE_DIR} +add_custom_target(make_cpp_wrapper ALL ${CMAKE_COMMAND} -E make_directory build/ + COMMAND ${CMAKE_COMMAND} -E chdir build/ ${CMAKE_COMMAND} .. -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} -DCMAKE_INSTALL_RPATH=${CMAKE_INSTALL_RPATH} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + COMMAND ${CMAKE_COMMAND} --build build/ + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/CMakeLists.txt + ${CMAKE_CURRENT_BINARY_DIR}/include/linphone.hh ) -set_target_properties(linphone++ - PROPERTIES SOVERSION ${LINPHONE_SO_VERSION} -) - -install(TARGETS linphone++ - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} -) -install(FILES ${HEADERS} - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/linphone++ -) - +install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} --build ${CMAKE_CURRENT_BINARY_DIR}/build --target install)") diff --git a/wrappers/cpp/c_make_lists.mustache.in b/wrappers/cpp/c_make_lists.mustache.in new file mode 100644 index 000000000..9484d28f0 --- /dev/null +++ b/wrappers/cpp/c_make_lists.mustache.in @@ -0,0 +1,40 @@ +cmake_minimum_required(VERSION 3.0) + +include(GNUInstallDirs) + +set(GENERATED_SOURCES + {{#classes}} + src/{{{source}}} + {{/classes}} +) +set(SOURCES + ${GENERATED_SOURCES} + src/object.cc +) +set(GENERATED_HEADERS + {{#classes}} + ${CMAKE_CURRENT_SOURCE_DIR}/include/{{{header}}} + {{/classes}} +) +set(HEADERS + ${GENERATED_HEADERS} + ${CMAKE_CURRENT_SOURCE_DIR}/include/object.hh +) + +add_library(linphone++ SHARED ${SOURCES}) +target_link_libraries(linphone++ PRIVATE @PROJECT_BINARY_DIR@/coreapi/liblinphone.so.@LINPHONE_SO_VERSION@) +target_include_directories(linphone++ + PUBLIC include + PRIVATE @PROJECT_SOURCE_DIR@/include +) +set_target_properties(linphone++ + PROPERTIES SOVERSION @LINPHONE_SO_VERSION@ +) + +install(TARGETS linphone++ + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} +) +install(FILES ${HEADERS} + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/linphone++ +) + diff --git a/wrappers/cpp/genheaders.py b/wrappers/cpp/genheaders.py index d00b3e5f2..57296e40c 100755 --- a/wrappers/cpp/genheaders.py +++ b/wrappers/cpp/genheaders.py @@ -611,6 +611,11 @@ class ClassImpl(object): namespace = parsedClass.find_first_ancestor_by_type(AbsApi.Namespace) self.namespace = namespace.name.concatenate(fullName=True) if namespace is not None else None +class CMakeLists(object): + def __init__(self): + self.classes = [] + self.interfaces = [] + def main(): argparser = argparse.ArgumentParser(description='Generate source files for the C++ wrapper') @@ -631,26 +636,6 @@ def main(): parser = AbsApi.CParser(project) parser.parse_all() translator = CppTranslator() - #translator.ignore += ['linphone_tunnel_get_http_proxy', - #'linphone_core_can_we_add_call', - #'linphone_core_get_default_proxy', - #'linphone_core_add_listener', - #'linphone_core_remove_listener', - #'linphone_core_get_current_callbacks', - #'linphone_proxy_config_normalize_number', - #'linphone_proxy_config_set_file_transfer_server', - #'linphone_proxy_config_get_file_transfer_server', - #'linphone_factory_create_core', - #'linphone_factory_create_core_with_config', - #'linphone_buffer_get_content', - #'linphone_chat_room_send_chat_message', - #'linphone_config_read_relative_file', - #'linphone_core_new_with_config', - #'LinphoneImEncryptionEngine', - #'LinphoneImEncryptionEngineCbs', - #'LinphoneImNotifPolicy', - #'LpConfig'] - renderer = pystache.Renderer() header = EnumsHeader(translator) @@ -664,13 +649,23 @@ def main(): f.write(renderer.render(header)) mainHeader = MainHeader() + cmakelists = CMakeLists() for _class in parser.classesIndex.values() + parser.interfacesIndex.values(): if _class is not None: try: header = ClassHeader(_class, translator, ignore=['LinphoneBuffer']) impl = ClassImpl(_class, header._class) - mainHeader.add_include(_class.name.to_snake_case() + '.hh') + + headerName = _class.name.to_snake_case() + '.hh' + sourceName = _class.name.to_snake_case() + '.cc' + mainHeader.add_include(headerName) + + if type(_class) is AbsApi.Class: + cmakelists.classes.append({'header': headerName, 'source': sourceName}) + else: + cmakelists.interfaces.append({'header': headerName}) + with open(args.outputdir + '/include/' + header.filename, mode='w') as f: f.write(renderer.render(header)) @@ -683,6 +678,9 @@ def main(): with open(args.outputdir + '/include/linphone.hh', mode='w') as f: f.write(renderer.render(mainHeader)) + + with open(args.outputdir + '/CMakeLists.txt', mode='w') as f: + f.write(renderer.render(cmakelists)) if __name__ == '__main__': From f33db333db8d0659d0bf91382a10cc422f200e6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Grisez?= Date: Tue, 17 Jan 2017 15:40:58 +0100 Subject: [PATCH 12/13] Add license texts --- wrappers/cpp/abstractapi.py | 16 ++++++++++++++++ wrappers/cpp/class_header.mustache | 18 ++++++++++++++++++ wrappers/cpp/class_impl.mustache | 18 ++++++++++++++++++ wrappers/cpp/enums_header.mustache | 18 ++++++++++++++++++ wrappers/cpp/genheaders.py | 16 ++++++++++++++++ wrappers/cpp/main_header.mustache | 19 +++++++++++++++++++ wrappers/cpp/object.cc | 19 +++++++++++++++++++ wrappers/cpp/object.hh | 19 +++++++++++++++++++ 8 files changed, 143 insertions(+) diff --git a/wrappers/cpp/abstractapi.py b/wrappers/cpp/abstractapi.py index 5b6a5cd23..790891e2e 100644 --- a/wrappers/cpp/abstractapi.py +++ b/wrappers/cpp/abstractapi.py @@ -1,3 +1,19 @@ +# Copyright (C) 2017 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + import re import genapixml as CApi diff --git a/wrappers/cpp/class_header.mustache b/wrappers/cpp/class_header.mustache index 5f63341f8..61b458ce7 100644 --- a/wrappers/cpp/class_header.mustache +++ b/wrappers/cpp/class_header.mustache @@ -1,3 +1,21 @@ +/* +Copyright (C) 2017 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + #ifndef {{define}} #define {{define}} diff --git a/wrappers/cpp/class_impl.mustache b/wrappers/cpp/class_impl.mustache index b993397c3..19889a091 100644 --- a/wrappers/cpp/class_impl.mustache +++ b/wrappers/cpp/class_impl.mustache @@ -1,3 +1,21 @@ +/* +Copyright (C) 2017 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + #include "linphone.hh" using namespace {{{namespace}}}; diff --git a/wrappers/cpp/enums_header.mustache b/wrappers/cpp/enums_header.mustache index aaf7b9dff..46d9b8220 100644 --- a/wrappers/cpp/enums_header.mustache +++ b/wrappers/cpp/enums_header.mustache @@ -1,3 +1,21 @@ +/* +Copyright (C) 2017 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + #ifndef _ENUMS_HH #define _ENUMS_HH diff --git a/wrappers/cpp/genheaders.py b/wrappers/cpp/genheaders.py index 57296e40c..113f2de63 100755 --- a/wrappers/cpp/genheaders.py +++ b/wrappers/cpp/genheaders.py @@ -1,5 +1,21 @@ #!/usr/bin/python +# Copyright (C) 2017 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + import pystache import re diff --git a/wrappers/cpp/main_header.mustache b/wrappers/cpp/main_header.mustache index 9bc3acf87..e8493c720 100644 --- a/wrappers/cpp/main_header.mustache +++ b/wrappers/cpp/main_header.mustache @@ -1,3 +1,22 @@ +/* +linphone.hh +Copyright (C) 2017 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + #ifndef {{{define}}} #define {{{define}}} diff --git a/wrappers/cpp/object.cc b/wrappers/cpp/object.cc index 9a3e1e356..7afb183cc 100644 --- a/wrappers/cpp/object.cc +++ b/wrappers/cpp/object.cc @@ -1,3 +1,22 @@ +/* +object.cc +Copyright (C) 2017 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + #include "object.hh" #include #include diff --git a/wrappers/cpp/object.hh b/wrappers/cpp/object.hh index 57d93acd4..b827bb631 100644 --- a/wrappers/cpp/object.hh +++ b/wrappers/cpp/object.hh @@ -1,3 +1,22 @@ +/* +object.hh +Copyright (C) 2017 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + #ifndef _LINPHONE_OBJECT_HH #define _LINPHONE_OBJECT_HH From cc7bec3cf57fa18e6d7a6dc760760d85c623a659 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Grisez?= Date: Tue, 17 Jan 2017 15:41:30 +0100 Subject: [PATCH 13/13] Fix memory leak --- coreapi/bellesip_sal/sal_op_message.c | 1 + 1 file changed, 1 insertion(+) diff --git a/coreapi/bellesip_sal/sal_op_message.c b/coreapi/bellesip_sal/sal_op_message.c index a051dc52f..445afd1e2 100644 --- a/coreapi/bellesip_sal/sal_op_message.c +++ b/coreapi/bellesip_sal/sal_op_message.c @@ -149,6 +149,7 @@ void sal_process_incoming_message(SalOp *op,const belle_sip_request_event_t *eve belle_sip_object_unref(address); belle_sip_free(from); if (salmsg.url) ms_free((char*)salmsg.url); + ms_free((char *)salmsg.content_type); } } else { ms_error("Unsupported MESSAGE (no Content-Type)");