From 933081e72f724afb223cfd63ef239c43e237bbe2 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 7 Feb 2018 17:50:37 +0100 Subject: [PATCH 01/17] Started to remove old LinphoneContent and use a C wrapper above C++ Content --- coreapi/CMakeLists.txt | 1 - coreapi/Makefile.am | 1 - coreapi/private_structs.h | 11 -- include/CMakeLists.txt | 2 +- include/linphone/Makefile.am | 1 - .../linphone/{content.h => api/c-content.h} | 54 +++--- include/linphone/api/c-types.h | 6 + include/linphone/types.h | 6 - src/CMakeLists.txt | 1 + src/c-wrapper/api/c-content.cpp | 177 ++++++++++++++++++ src/c-wrapper/c-wrapper.h | 2 +- 11 files changed, 212 insertions(+), 50 deletions(-) rename include/linphone/{content.h => api/c-content.h} (87%) create mode 100644 src/c-wrapper/api/c-content.cpp diff --git a/coreapi/CMakeLists.txt b/coreapi/CMakeLists.txt index 03600de80..76a35259c 100644 --- a/coreapi/CMakeLists.txt +++ b/coreapi/CMakeLists.txt @@ -64,7 +64,6 @@ set(LINPHONE_SOURCE_FILES_C carddav.c chat.c contactprovider.c - content.c dial_plan.c dict.c ec-calibrator.c diff --git a/coreapi/Makefile.am b/coreapi/Makefile.am index 4e63d8879..c2b2ee53b 100644 --- a/coreapi/Makefile.am +++ b/coreapi/Makefile.am @@ -39,7 +39,6 @@ liblinphone_la_SOURCES=\ chat_file_transfer.c \ conference.cc conference_private.h \ contactprovider.c contact_providers_priv.h \ - content.c \ dial_plan.c \ dict.c \ ec-calibrator.c \ diff --git a/coreapi/private_structs.h b/coreapi/private_structs.h index 449609ba9..f7c6faba0 100644 --- a/coreapi/private_structs.h +++ b/coreapi/private_structs.h @@ -444,17 +444,6 @@ struct _EchoTester { unsigned int rate; }; -struct _LinphoneContent { - belle_sip_object_t base; - void *user_data; - SalBodyHandler *body_handler; - char *name; /**< used by RCS File transfer messages to store the original filename of the file to be downloaded from server */ - char *key; /**< used by RCS File transfer messages to store the key to encrypt file if needed */ - size_t keyLength; /**< Length of key in bytes */ - void *cryptoContext; /**< crypto context used to encrypt file for RCS file transfer */ - bool_t owned_fields; -}; - BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneContent); struct _LinphoneBuffer { diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 055f1840d..90cba8715 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -33,7 +33,6 @@ set(ROOT_HEADER_FILES chat.h conference.h contactprovider.h - content.h core_utils.h core.h defs.h @@ -84,6 +83,7 @@ set(C_API_HEADER_FILES c-chat-message.h c-chat-room-cbs.h c-chat-room.h + c-content.h c-dial-plan.h c-event-log.h c-participant.h diff --git a/include/linphone/Makefile.am b/include/linphone/Makefile.am index dc9488e0b..56c2c3dda 100644 --- a/include/linphone/Makefile.am +++ b/include/linphone/Makefile.am @@ -14,7 +14,6 @@ linphone_include_HEADERS=\ chat.h \ conference.h \ contactprovider.h \ - content.h \ core.h \ core_utils.h \ defs.h \ diff --git a/include/linphone/content.h b/include/linphone/api/c-content.h similarity index 87% rename from include/linphone/content.h rename to include/linphone/api/c-content.h index 78ebc3114..fa030a309 100644 --- a/include/linphone/content.h +++ b/include/linphone/api/c-content.h @@ -1,33 +1,32 @@ /* -content.h -Copyright (C) 2010-2014 Belledonne Communications SARL + * c-content.h + * Copyright (C) 2010-2018 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. + */ -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. +#ifndef _L_C_CONTENT_H_ +#define _L_C_CONTENT_H_ -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_CONTENT_H_ -#define LINPHONE_CONTENT_H_ - - -#include "linphone/types.h" +#include "linphone/api/c-types.h" +// ============================================================================= #ifdef __cplusplus -extern "C" { -#endif - + extern "C" { +#endif // ifdef __cplusplus /** * @addtogroup misc @@ -218,9 +217,8 @@ LINPHONE_PUBLIC void linphone_content_set_key(LinphoneContent *content, const ch * @} */ - #ifdef __cplusplus -} -#endif + } +#endif // ifdef __cplusplus -#endif /* LINPHONE_CONTENT_H_ */ +#endif // ifndef _L_C_CONTENT_H_ \ No newline at end of file diff --git a/include/linphone/api/c-types.h b/include/linphone/api/c-types.h index 6c109375f..30594f8ab 100644 --- a/include/linphone/api/c-types.h +++ b/include/linphone/api/c-types.h @@ -156,6 +156,12 @@ typedef struct _LinphoneDialPlan LinphoneDialPlan; **/ typedef struct _LinphoneParticipant LinphoneParticipant; +/** + * The LinphoneContent object holds data that can be embedded in a signaling message. + * @ingroup misc +**/ +typedef struct _LinphoneContent LinphoneContent; + // ============================================================================= // C Enums. // ============================================================================= diff --git a/include/linphone/types.h b/include/linphone/types.h index d3b03ce25..90a48c1ca 100644 --- a/include/linphone/types.h +++ b/include/linphone/types.h @@ -367,12 +367,6 @@ typedef unsigned int LinphoneContactSearchID; */ LINPHONE_DEPRECATED typedef LinphoneContactSearchID ContactSearchID; -/** - * The LinphoneContent object holds data that can be embedded in a signaling message. - * @ingroup misc -**/ -typedef struct _LinphoneContent LinphoneContent; - /** * Linphone core main object created by function linphone_core_new() . * @ingroup initializing diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 59ddaffc1..35634fd09 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -164,6 +164,7 @@ set(LINPHONE_CXX_OBJECTS_SOURCE_FILES c-wrapper/api/c-chat-room-cbs.cpp c-wrapper/api/c-chat-room.cpp c-wrapper/api/c-core.cpp + c-wrapper/api/c-content.cpp c-wrapper/api/c-dial-plan.cpp c-wrapper/api/c-event-log.cpp c-wrapper/api/c-participant.cpp diff --git a/src/c-wrapper/api/c-content.cpp b/src/c-wrapper/api/c-content.cpp new file mode 100644 index 000000000..cfb569732 --- /dev/null +++ b/src/c-wrapper/api/c-content.cpp @@ -0,0 +1,177 @@ +/* + * c-content.cpp + * Copyright (C) 2010-2018 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/api/c-content.h" +#include "linphone/wrapper_utils.h" + +#include "c-wrapper/c-wrapper.h" + +#include "content/content.h" + +// ============================================================================= + +using namespace std; + +L_DECLARE_C_CLONABLE_OBJECT_IMPL(Content, + SalBodyHandler *body_handler; + void *cryptoContext; /**< crypto context used to encrypt file for RCS file transfer */ +) + +// ============================================================================= +// Reference and user data handling functions. +// ============================================================================= + +LinphoneContent * linphone_content_ref(LinphoneContent *content) { + belle_sip_object_ref(content); + return content; +} + +void linphone_content_unref(LinphoneContent *content) { + belle_sip_object_unref(content); +} + +void *linphone_content_get_user_data(const LinphoneContent *content) { + return L_GET_USER_DATA_FROM_C_OBJECT(content); +} + +void linphone_content_set_user_data(LinphoneContent *content, void *ud) { + return L_SET_USER_DATA_FROM_C_OBJECT(content, ud); +} + +// ============================================================================= + +const char * linphone_content_get_type(const LinphoneContent *content) { + return NULL; +} + +void linphone_content_set_type(LinphoneContent *content, const char *type) { + +} + +const char * linphone_content_get_subtype(const LinphoneContent *content) { + return NULL; +} + +void linphone_content_set_subtype(LinphoneContent *content, const char *subtype) { + +} + +uint8_t * linphone_content_get_buffer(const LinphoneContent *content) { + return NULL; +} + +void linphone_content_set_buffer(LinphoneContent *content, const uint8_t *buffer, size_t size) { + +} + +const char * linphone_content_get_string_buffer(const LinphoneContent *content) { + return NULL; +} + +void linphone_content_set_string_buffer(LinphoneContent *content, const char *buffer) { + +} + +size_t linphone_content_get_size(const LinphoneContent *content) { + return 0; +} + +void linphone_content_set_size(LinphoneContent *content, size_t size) { + +} + +const char * linphone_content_get_encoding(const LinphoneContent *content) { + return NULL; +} + +void linphone_content_set_encoding(LinphoneContent *content, const char *encoding) { + +} + +const char * linphone_content_get_name(const LinphoneContent *content) { + return NULL; +} + +void linphone_content_set_name(LinphoneContent *content, const char *name) { + +} + +bool_t linphone_content_is_multipart(const LinphoneContent *content) { + return FALSE; +} + +LinphoneContent * linphone_content_get_part(const LinphoneContent *content, int idx) { + return NULL; +} + +LinphoneContent * linphone_content_find_part_by_header(const LinphoneContent *content, const char *header_name, const char *header_value) { + return NULL; +} + +const char * linphone_content_get_custom_header(const LinphoneContent *content, const char *header_name) { + return NULL; +} + +const char *linphone_content_get_key(const LinphoneContent *content) { + return NULL; +} + +size_t linphone_content_get_key_size(const LinphoneContent *content) { + return 0; +} + +void linphone_content_set_key(LinphoneContent *content, const char *key, const size_t keyLength) { + +} + +// ============================================================================= +// Private functions. +// ============================================================================= + +LinphoneContent * linphone_content_new(void) { + return NULL; +} + +LinphoneContent * linphone_content_copy(const LinphoneContent *ref) { + return NULL; +} + +static LinphoneContent * linphone_content_new_with_body_handler(SalBodyHandler *body_handler) { + return NULL; +} + +LinphoneContent * linphone_core_create_content(LinphoneCore *lc) { + return NULL; +} + +/* crypto context is managed(allocated/freed) by the encryption function, so provide the address of field in the private structure */ +void ** linphone_content_get_cryptoContext_address(LinphoneContent *content) { + return &(content->cryptoContext);; +} + +LinphoneContent * linphone_content_from_sal_body_handler(SalBodyHandler *body_handler) { + if (body_handler) { + return linphone_content_new_with_body_handler(body_handler); + } + return NULL; +} + +SalBodyHandler * sal_body_handler_from_content(const LinphoneContent *content) { + return NULL; +} \ No newline at end of file diff --git a/src/c-wrapper/c-wrapper.h b/src/c-wrapper/c-wrapper.h index 2e1260e5e..b3bf0c8e0 100644 --- a/src/c-wrapper/c-wrapper.h +++ b/src/c-wrapper/c-wrapper.h @@ -37,6 +37,7 @@ F(ChatMessage, ChatMessage) \ F(AbstractChatRoom, ChatRoom) \ F(Core, Core) \ + F(Content, Content) \ F(DialPlan, DialPlan) \ F(EventLog, EventLog) \ F(MediaSessionParams, CallParams) \ @@ -83,7 +84,6 @@ BELLE_SIP_TYPE_ID(LinphoneConferenceParams), BELLE_SIP_TYPE_ID(LinphoneConfig), BELLE_SIP_TYPE_ID(LinphoneContactProvider), BELLE_SIP_TYPE_ID(LinphoneContactSearch), -BELLE_SIP_TYPE_ID(LinphoneContent), BELLE_SIP_TYPE_ID(LinphoneCoreCbs), BELLE_SIP_TYPE_ID(LinphoneErrorInfo), BELLE_SIP_TYPE_ID(LinphoneEvent), From 122098ac04ffb0549fd6c6ab18c1035d4f5e6276 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 8 Feb 2018 11:24:30 +0100 Subject: [PATCH 02/17] More work on C/C++ Contents --- include/linphone/api/c-chat-room.h | 2 +- src/c-wrapper/api/c-chat-message.cpp | 4 +- src/c-wrapper/api/c-chat-room.cpp | 4 +- src/c-wrapper/api/c-content.cpp | 127 ++++++++++++++---- src/chat/chat-message/chat-message-p.h | 4 +- src/chat/chat-message/chat-message.cpp | 31 +++-- src/chat/chat-room/abstract-chat-room.h | 3 +- src/chat/chat-room/chat-room.cpp | 2 +- src/chat/chat-room/chat-room.h | 3 +- src/chat/chat-room/proxy-chat-room.cpp | 2 +- src/chat/chat-room/proxy-chat-room.h | 3 +- .../file-transfer-chat-message-modifier.cpp | 8 +- src/content/content.cpp | 7 - src/content/content.h | 3 - src/content/file-content.cpp | 10 -- src/content/file-content.h | 3 - src/content/file-transfer-content.cpp | 9 -- src/content/file-transfer-content.h | 3 - 18 files changed, 132 insertions(+), 96 deletions(-) diff --git a/include/linphone/api/c-chat-room.h b/include/linphone/api/c-chat-room.h index 392bce10f..aea3a7f61 100644 --- a/include/linphone/api/c-chat-room.h +++ b/include/linphone/api/c-chat-room.h @@ -90,7 +90,7 @@ LINPHONE_PUBLIC LinphoneChatMessage* linphone_chat_room_create_message_2(Linphon * @param initial_content #LinphoneContent initial content. #LinphoneCoreVTable.file_transfer_send is invoked later to notify file transfer progress and collect next chunk of the message if LinphoneContent.data is NULL. * @return a new #LinphoneChatMessage */ -LINPHONE_PUBLIC LinphoneChatMessage* linphone_chat_room_create_file_transfer_message(LinphoneChatRoom *cr, const LinphoneContent* initial_content); +LINPHONE_PUBLIC LinphoneChatMessage* linphone_chat_room_create_file_transfer_message(LinphoneChatRoom *cr, LinphoneContent* initial_content); /** * get peer address \link linphone_core_get_chat_room() associated to \endlink this #LinphoneChatRoom diff --git a/src/c-wrapper/api/c-chat-message.cpp b/src/c-wrapper/api/c-chat-message.cpp index da453b39c..59bffa2d9 100644 --- a/src/c-wrapper/api/c-chat-message.cpp +++ b/src/c-wrapper/api/c-chat-message.cpp @@ -283,7 +283,9 @@ int linphone_chat_message_set_text(LinphoneChatMessage *msg, const char* text) { } LinphoneContent *linphone_chat_message_get_file_transfer_information(LinphoneChatMessage *msg) { - return L_GET_PRIVATE_FROM_C_OBJECT(msg)->getFileTransferInformation(); + const LinphonePrivate::Content *content = L_GET_PRIVATE_FROM_C_OBJECT(msg)->getFileTransferInformation(); + if (content) return L_GET_C_BACK_PTR(content); + return NULL; } // ============================================================================= diff --git a/src/c-wrapper/api/c-chat-room.cpp b/src/c-wrapper/api/c-chat-room.cpp index 3288f1073..11f89e053 100644 --- a/src/c-wrapper/api/c-chat-room.cpp +++ b/src/c-wrapper/api/c-chat-room.cpp @@ -350,8 +350,8 @@ const bctbx_list_t *linphone_chat_room_get_composing_addresses (LinphoneChatRoom return cr->composingAddresses; } -LinphoneChatMessage *linphone_chat_room_create_file_transfer_message(LinphoneChatRoom *cr, const LinphoneContent *initial_content) { - shared_ptr cppPtr = L_GET_CPP_PTR_FROM_C_OBJECT(cr)->createFileTransferMessage(initial_content); +LinphoneChatMessage *linphone_chat_room_create_file_transfer_message(LinphoneChatRoom *cr, LinphoneContent *initial_content) { + shared_ptr cppPtr = L_GET_CPP_PTR_FROM_C_OBJECT(cr)->createFileTransferMessage(L_GET_CPP_PTR_FROM_C_OBJECT(initial_content)); LinphoneChatMessage *object = L_INIT(ChatMessage); L_SET_CPP_PTR_FROM_C_OBJECT(object, cppPtr); return object; diff --git a/src/c-wrapper/api/c-content.cpp b/src/c-wrapper/api/c-content.cpp index cfb569732..7af4b4073 100644 --- a/src/c-wrapper/api/c-content.cpp +++ b/src/c-wrapper/api/c-content.cpp @@ -23,6 +23,9 @@ #include "c-wrapper/c-wrapper.h" #include "content/content.h" +#include "content/content-type.h" +#include "content/file-content.h" +#include "content/file-transfer-content.h" // ============================================================================= @@ -31,6 +34,7 @@ using namespace std; L_DECLARE_C_CLONABLE_OBJECT_IMPL(Content, SalBodyHandler *body_handler; void *cryptoContext; /**< crypto context used to encrypt file for RCS file transfer */ + mutable char *name; ) // ============================================================================= @@ -57,112 +61,176 @@ void linphone_content_set_user_data(LinphoneContent *content, void *ud) { // ============================================================================= const char * linphone_content_get_type(const LinphoneContent *content) { - return NULL; + return L_STRING_TO_C(L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType().getType()); } void linphone_content_set_type(LinphoneContent *content, const char *type) { - + LinphonePrivate::ContentType ct = L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType(); + ct.setType(L_C_TO_STRING(type)); + L_GET_CPP_PTR_FROM_C_OBJECT(content)->setContentType(ct); } const char * linphone_content_get_subtype(const LinphoneContent *content) { - return NULL; + return L_STRING_TO_C(L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType().getSubType()); } void linphone_content_set_subtype(LinphoneContent *content, const char *subtype) { - + LinphonePrivate::ContentType ct = L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType(); + ct.setSubType(L_C_TO_STRING(subtype)); + L_GET_CPP_PTR_FROM_C_OBJECT(content)->setContentType(ct); } uint8_t * linphone_content_get_buffer(const LinphoneContent *content) { - return NULL; + return (uint8_t *)L_STRING_TO_C(L_GET_CPP_PTR_FROM_C_OBJECT(content)->getBodyAsString()); } void linphone_content_set_buffer(LinphoneContent *content, const uint8_t *buffer, size_t size) { - + L_GET_CPP_PTR_FROM_C_OBJECT(content)->setBody(buffer, size); } const char * linphone_content_get_string_buffer(const LinphoneContent *content) { - return NULL; + return L_STRING_TO_C(L_GET_CPP_PTR_FROM_C_OBJECT(content)->getBodyAsString()); } void linphone_content_set_string_buffer(LinphoneContent *content, const char *buffer) { - + L_GET_CPP_PTR_FROM_C_OBJECT(content)->setBody(L_C_TO_STRING(buffer)); } size_t linphone_content_get_size(const LinphoneContent *content) { - return 0; + size_t size = L_GET_CPP_PTR_FROM_C_OBJECT(content)->getSize(); + if (size == 0) { + size = sal_body_handler_get_size(content->body_handler); + } + return size; } void linphone_content_set_size(LinphoneContent *content, size_t size) { - + sal_body_handler_set_size(content->body_handler, size); } const char * linphone_content_get_encoding(const LinphoneContent *content) { - return NULL; + return sal_body_handler_get_encoding(content->body_handler); } void linphone_content_set_encoding(LinphoneContent *content, const char *encoding) { - + sal_body_handler_set_encoding(content->body_handler, encoding); } const char * linphone_content_get_name(const LinphoneContent *content) { - return NULL; + const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); + if (c->isFile()) { + const LinphonePrivate::FileContent *fc = static_cast(c); + if (content->name) ms_free(content->name); + content->name = ms_strdup(L_STRING_TO_C(fc->getFileName())); + } else if (c->getContentType() == LinphonePrivate::ContentType::FileTransfer) { + const LinphonePrivate::FileTransferContent *ftc = static_cast(c); + if (content->name) ms_free(content->name); + content->name = ms_strdup(L_STRING_TO_C(ftc->getFileName())); + } + return content->name; } void linphone_content_set_name(LinphoneContent *content, const char *name) { - + LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); + if (c->isFile()) { + LinphonePrivate::FileContent *fc = static_cast(c); + fc->setFileName(L_C_TO_STRING(name)); + } else if (c->getContentType() == LinphonePrivate::ContentType::FileTransfer) { + LinphonePrivate::FileTransferContent *ftc = static_cast(c); + ftc->setFileName(L_C_TO_STRING(name)); + } + content->name = ms_strdup(name); } bool_t linphone_content_is_multipart(const LinphoneContent *content) { - return FALSE; + return sal_body_handler_is_multipart(content->body_handler); } LinphoneContent * linphone_content_get_part(const LinphoneContent *content, int idx) { - return NULL; + SalBodyHandler *part_body_handler; + if (!linphone_content_is_multipart(content)) return NULL; + part_body_handler = sal_body_handler_get_part(content->body_handler, idx); + return linphone_content_from_sal_body_handler(part_body_handler); } LinphoneContent * linphone_content_find_part_by_header(const LinphoneContent *content, const char *header_name, const char *header_value) { - return NULL; + SalBodyHandler *part_body_handler; + if (!linphone_content_is_multipart(content)) return NULL; + part_body_handler = sal_body_handler_find_part_by_header(content->body_handler, header_name, header_value); + return linphone_content_from_sal_body_handler(part_body_handler); } const char * linphone_content_get_custom_header(const LinphoneContent *content, const char *header_name) { - return NULL; + return sal_body_handler_get_header(content->body_handler, header_name); } const char *linphone_content_get_key(const LinphoneContent *content) { + const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); + if (c->isFile()) { + const LinphonePrivate::FileContent *fc = static_cast(c); + return L_STRING_TO_C(fc->getFileKey()); + } return NULL; } size_t linphone_content_get_key_size(const LinphoneContent *content) { + const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); + if (c->isFile()) { + const LinphonePrivate::FileContent *fc = static_cast(c); + return fc->getFileKey().length(); + } return 0; } void linphone_content_set_key(LinphoneContent *content, const char *key, const size_t keyLength) { - + LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); + if (c->isFile()) { + LinphonePrivate::FileContent *fc = static_cast(c); + fc->setFileKey(L_C_TO_STRING(key)); + } } // ============================================================================= // Private functions. // ============================================================================= -LinphoneContent * linphone_content_new(void) { - return NULL; -} - -LinphoneContent * linphone_content_copy(const LinphoneContent *ref) { - return NULL; +static void linphone_content_set_sal_body_handler(LinphoneContent *content, SalBodyHandler *body_handler) { + if (content->body_handler != NULL) { + sal_body_handler_unref(content->body_handler); + content->body_handler = NULL; + } + content->body_handler = sal_body_handler_ref(body_handler); } static LinphoneContent * linphone_content_new_with_body_handler(SalBodyHandler *body_handler) { - return NULL; + LinphoneContent *content = L_INIT(Content); + content->cryptoContext = NULL; + if (body_handler == NULL) { + linphone_content_set_sal_body_handler(content, sal_body_handler_new()); + } else { + linphone_content_set_sal_body_handler(content, body_handler); + } + LinphonePrivate::Content *c = new LinphonePrivate::Content(); + L_SET_CPP_PTR_FROM_C_OBJECT(content, c); + return content; +} + +LinphoneContent * linphone_content_new(void) { + return linphone_content_new_with_body_handler(NULL); +} + +LinphoneContent * linphone_content_copy(const LinphoneContent *ref) { + //TODO + return (LinphoneContent *)belle_sip_object_ref(belle_sip_object_clone(BELLE_SIP_OBJECT(ref))); } LinphoneContent * linphone_core_create_content(LinphoneCore *lc) { - return NULL; + return linphone_content_new(); } /* crypto context is managed(allocated/freed) by the encryption function, so provide the address of field in the private structure */ void ** linphone_content_get_cryptoContext_address(LinphoneContent *content) { - return &(content->cryptoContext);; + return &(content->cryptoContext); } LinphoneContent * linphone_content_from_sal_body_handler(SalBodyHandler *body_handler) { @@ -173,5 +241,6 @@ LinphoneContent * linphone_content_from_sal_body_handler(SalBodyHandler *body_ha } SalBodyHandler * sal_body_handler_from_content(const LinphoneContent *content) { - return NULL; + if (content == NULL) return NULL; + return content->body_handler; } \ No newline at end of file diff --git a/src/chat/chat-message/chat-message-p.h b/src/chat/chat-message/chat-message-p.h index 0eae6c24e..b47355e3b 100644 --- a/src/chat/chat-message/chat-message-p.h +++ b/src/chat/chat-message/chat-message-p.h @@ -119,8 +119,8 @@ public: bool hasFileTransferContent () const; const Content* getFileTransferContent () const; - LinphoneContent *getFileTransferInformation () const; - void setFileTransferInformation (const LinphoneContent *content); + const Content* getFileTransferInformation () const; + void setFileTransferInformation (Content *content); bool downloadFile (); diff --git a/src/chat/chat-message/chat-message.cpp b/src/chat/chat-message/chat-message.cpp index d6f7d3f95..855dbd902 100644 --- a/src/chat/chat-message/chat-message.cpp +++ b/src/chat/chat-message/chat-message.cpp @@ -284,33 +284,36 @@ void ChatMessagePrivate::setText (const string &text) { } } -LinphoneContent *ChatMessagePrivate::getFileTransferInformation () const { +const Content *ChatMessagePrivate::getFileTransferInformation () const { if (hasFileTransferContent()) { - return getFileTransferContent()->toLinphoneContent(); + return getFileTransferContent(); } for (const Content *c : contents) { if (c->isFile()) { FileContent *fileContent = (FileContent *)c; - return fileContent->toLinphoneContent(); + return fileContent; } } return NULL; } -void ChatMessagePrivate::setFileTransferInformation (const LinphoneContent *c_content) { +void ChatMessagePrivate::setFileTransferInformation (Content *content) { L_Q(); - // Create a FileContent, it will create the FileTransferContent at upload time - FileContent *fileContent = new FileContent(); - ContentType contentType(linphone_content_get_type(c_content), linphone_content_get_subtype(c_content)); - fileContent->setContentType(contentType); - fileContent->setFileSize(linphone_content_get_size(c_content)); - fileContent->setFileName(linphone_content_get_name(c_content)); - if (linphone_content_get_string_buffer(c_content) != NULL) { - fileContent->setBody(linphone_content_get_string_buffer(c_content)); + if (content->isFile()) { + q->addContent(*content); + } else { + // This scenario is more likely to happen because the caller is using the C API + LinphoneContent *c_content = L_GET_C_BACK_PTR(content); + FileContent *fileContent = new FileContent(); + fileContent->setContentType(content->getContentType()); + fileContent->setFileSize(linphone_content_get_size(c_content)); // This information is only available from C Content if it was created from C API + fileContent->setFileName(linphone_content_get_name(c_content)); // This information is only available from C Content if it was created from C API + if (!content->isEmpty()) { + fileContent->setBody(content->getBody()); + } + q->addContent(*fileContent); } - - q->addContent(*fileContent); } bool ChatMessagePrivate::downloadFile () { diff --git a/src/chat/chat-room/abstract-chat-room.h b/src/chat/chat-room/abstract-chat-room.h index 46f5aec29..6cd260a82 100644 --- a/src/chat/chat-room/abstract-chat-room.h +++ b/src/chat/chat-room/abstract-chat-room.h @@ -87,8 +87,7 @@ public: virtual std::shared_ptr createChatMessage () = 0; virtual std::shared_ptr createChatMessage (const std::string &text) = 0; - // TODO: Remove LinphoneContent by LinphonePrivate::Content. - virtual std::shared_ptr createFileTransferMessage (const LinphoneContent *initialContent) = 0; + virtual std::shared_ptr createFileTransferMessage (Content *initialContent) = 0; virtual std::shared_ptr findChatMessage (const std::string &messageId) const = 0; virtual std::shared_ptr findChatMessage ( diff --git a/src/chat/chat-room/chat-room.cpp b/src/chat/chat-room/chat-room.cpp index 14e92cf85..03b8cd079 100644 --- a/src/chat/chat-room/chat-room.cpp +++ b/src/chat/chat-room/chat-room.cpp @@ -393,7 +393,7 @@ shared_ptr ChatRoom::createChatMessage (const string &text) { return chatMessage; } -shared_ptr ChatRoom::createFileTransferMessage (const LinphoneContent *initialContent) { +shared_ptr ChatRoom::createFileTransferMessage (Content *initialContent) { shared_ptr chatMessage = createChatMessage(); chatMessage->getPrivate()->setFileTransferInformation(initialContent); return chatMessage; diff --git a/src/chat/chat-room/chat-room.h b/src/chat/chat-room/chat-room.h index 35d887e59..9c6dbb999 100644 --- a/src/chat/chat-room/chat-room.h +++ b/src/chat/chat-room/chat-room.h @@ -61,8 +61,7 @@ public: std::shared_ptr createChatMessage () override; std::shared_ptr createChatMessage (const std::string &text) override; - // TODO: Remove LinphoneContent by LinphonePrivate::Content. - std::shared_ptr createFileTransferMessage (const LinphoneContent *initialContent) override; + std::shared_ptr createFileTransferMessage (Content *initialContent) override; std::shared_ptr findChatMessage (const std::string &messageId) const override; std::shared_ptr findChatMessage ( diff --git a/src/chat/chat-room/proxy-chat-room.cpp b/src/chat/chat-room/proxy-chat-room.cpp index bf984d2a1..29a9ddb80 100644 --- a/src/chat/chat-room/proxy-chat-room.cpp +++ b/src/chat/chat-room/proxy-chat-room.cpp @@ -264,7 +264,7 @@ shared_ptr ProxyChatRoom::createChatMessage (const string &text) { return d->chatRoom->createChatMessage(text); } -shared_ptr ProxyChatRoom::createFileTransferMessage (const LinphoneContent *initialContent) { +shared_ptr ProxyChatRoom::createFileTransferMessage (Content *initialContent) { L_D(); return d->chatRoom->createFileTransferMessage(initialContent); } diff --git a/src/chat/chat-room/proxy-chat-room.h b/src/chat/chat-room/proxy-chat-room.h index 16a5c49aa..6b9a75428 100644 --- a/src/chat/chat-room/proxy-chat-room.h +++ b/src/chat/chat-room/proxy-chat-room.h @@ -62,8 +62,7 @@ public: std::shared_ptr createChatMessage () override; std::shared_ptr createChatMessage (const std::string &text) override; - // TODO: Remove LinphoneContent by LinphonePrivate::Content. - std::shared_ptr createFileTransferMessage (const LinphoneContent *initialContent) override; + std::shared_ptr createFileTransferMessage (Content *initialContent) override; std::shared_ptr findChatMessage (const std::string &messageId) const override; std::shared_ptr findChatMessage ( diff --git a/src/chat/modifier/file-transfer-chat-message-modifier.cpp b/src/chat/modifier/file-transfer-chat-message-modifier.cpp index 30d088d2c..ac99d2201 100644 --- a/src/chat/modifier/file-transfer-chat-message-modifier.cpp +++ b/src/chat/modifier/file-transfer-chat-message-modifier.cpp @@ -100,7 +100,7 @@ void FileTransferChatMessageModifier::fileTransferOnProgress ( LinphoneChatMessage *msg = L_GET_C_BACK_PTR(message); LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg); - LinphoneContent *content = currentFileContentToTransfer->toLinphoneContent(); + LinphoneContent *content = L_GET_C_BACK_PTR((Content *)currentFileContentToTransfer); if (linphone_chat_message_cbs_get_file_transfer_progress_indication(cbs)) { linphone_chat_message_cbs_get_file_transfer_progress_indication(cbs)(msg, content, offset, total); } else { @@ -150,7 +150,7 @@ int FileTransferChatMessageModifier::onSendBody ( LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg); LinphoneChatMessageCbsFileTransferSendCb file_transfer_send_cb = linphone_chat_message_cbs_get_file_transfer_send(cbs); - LinphoneContent *content = currentFileContentToTransfer->toLinphoneContent(); + LinphoneContent *content = L_GET_C_BACK_PTR((Content *)currentFileContentToTransfer); if (file_transfer_send_cb) { LinphoneBuffer *lb = file_transfer_send_cb(msg, content, offset, *size); if (lb) { @@ -706,7 +706,7 @@ void FileTransferChatMessageModifier::onRecvBody (belle_sip_user_body_handler_t if (currentFileContentToTransfer->getFilePath().empty()) { LinphoneChatMessage *msg = L_GET_C_BACK_PTR(message); LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg); - LinphoneContent *content = currentFileContentToTransfer->toLinphoneContent(); + LinphoneContent *content = L_GET_C_BACK_PTR((Content *)currentFileContentToTransfer); if (linphone_chat_message_cbs_get_file_transfer_recv(cbs)) { LinphoneBuffer *lb = linphone_buffer_new_from_data(buffer, size); linphone_chat_message_cbs_get_file_transfer_recv(cbs)(msg, content, lb); @@ -747,7 +747,7 @@ void FileTransferChatMessageModifier::onRecvEnd (belle_sip_user_body_handler_t * if (currentFileContentToTransfer->getFilePath().empty()) { LinphoneChatMessage *msg = L_GET_C_BACK_PTR(message); LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg); - LinphoneContent *content = currentFileContentToTransfer->toLinphoneContent(); + LinphoneContent *content = L_GET_C_BACK_PTR((Content *)currentFileContentToTransfer); if (linphone_chat_message_cbs_get_file_transfer_recv(cbs)) { LinphoneBuffer *lb = linphone_buffer_new(); linphone_chat_message_cbs_get_file_transfer_recv(cbs)(msg, content, lb); diff --git a/src/content/content.cpp b/src/content/content.cpp index 732996494..93fd2f6e4 100644 --- a/src/content/content.cpp +++ b/src/content/content.cpp @@ -172,11 +172,4 @@ bool Content::isFile () const { return false; } -LinphoneContent *Content::toLinphoneContent () const { - LinphoneContent *content = linphone_core_create_content(nullptr); - linphone_content_set_type(content, getContentType().getType().c_str()); - linphone_content_set_subtype(content, getContentType().getSubType().c_str()); - return content; -} - LINPHONE_END_NAMESPACE diff --git a/src/content/content.h b/src/content/content.h index 4885feadf..da3c9e055 100644 --- a/src/content/content.h +++ b/src/content/content.h @@ -71,9 +71,6 @@ public: virtual bool isFile () const; - // TODO: Remove me later. - virtual LinphoneContent *toLinphoneContent () const; - protected: explicit Content (ContentPrivate &p); diff --git a/src/content/file-content.cpp b/src/content/file-content.cpp index 09de486b6..a2d1df851 100644 --- a/src/content/file-content.cpp +++ b/src/content/file-content.cpp @@ -135,14 +135,4 @@ bool FileContent::isFile () const { return true; } -LinphoneContent *FileContent::toLinphoneContent () const { - LinphoneContent *content = linphone_core_create_content(nullptr); - linphone_content_set_type(content, getContentType().getType().c_str()); - linphone_content_set_subtype(content, getContentType().getSubType().c_str()); - linphone_content_set_name(content, getFileName().c_str()); - linphone_content_set_size(content, getFileSize()); - linphone_content_set_key(content, getFileKey().c_str(), getFileKey().size()); - return content; -} - LINPHONE_END_NAMESPACE diff --git a/src/content/file-content.h b/src/content/file-content.h index 4876370fb..79dfe5629 100644 --- a/src/content/file-content.h +++ b/src/content/file-content.h @@ -53,9 +53,6 @@ public: bool isFile () const override; - // TODO: Remove me later. - LinphoneContent *toLinphoneContent () const override; - private: L_DECLARE_PRIVATE(FileContent); }; diff --git a/src/content/file-transfer-content.cpp b/src/content/file-transfer-content.cpp index 4ce62bc19..628080c7c 100644 --- a/src/content/file-transfer-content.cpp +++ b/src/content/file-transfer-content.cpp @@ -146,15 +146,6 @@ size_t FileTransferContent::getFileSize () const { return d->fileSize; } -LinphoneContent *FileTransferContent::toLinphoneContent () const { - LinphoneContent *content = linphone_core_create_content(nullptr); - linphone_content_set_type(content, getContentType().getType().c_str()); - linphone_content_set_subtype(content, getContentType().getSubType().c_str()); - linphone_content_set_name(content, getFileName().c_str()); - linphone_content_set_size(content, getFileSize()); - return content; -} - bool FileTransferContent::isFile () const { return false; } diff --git a/src/content/file-transfer-content.h b/src/content/file-transfer-content.h index 4b668a0ac..4abc4369f 100644 --- a/src/content/file-transfer-content.h +++ b/src/content/file-transfer-content.h @@ -57,9 +57,6 @@ public: bool isFile () const override; - // TODO: Remove me later. - LinphoneContent *toLinphoneContent () const override; - private: L_DECLARE_PRIVATE(FileTransferContent); }; From 96c01f70525159610edd4f7ee9fb1d8233c4fc35 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 8 Feb 2018 13:06:39 +0100 Subject: [PATCH 03/17] More work --- src/c-wrapper/api/c-chat-message.cpp | 4 +- src/c-wrapper/api/c-content.cpp | 18 +++---- src/chat/chat-message/chat-message.cpp | 16 +++--- src/chat/chat-message/chat-message.h | 4 +- src/chat/chat-room/chat-room.cpp | 4 +- .../file-transfer-chat-message-modifier.cpp | 54 +++++++++++-------- .../multipart-chat-message-modifier.cpp | 2 +- src/content/file-content.cpp | 18 +------ src/content/file-content.h | 3 -- src/content/file-transfer-content.cpp | 20 +++++++ src/content/file-transfer-content.h | 6 +++ src/db/main-db.cpp | 2 +- tester/cpim-tester.cpp | 2 +- tester/multipart-tester.cpp | 8 +-- 14 files changed, 90 insertions(+), 71 deletions(-) diff --git a/src/c-wrapper/api/c-chat-message.cpp b/src/c-wrapper/api/c-chat-message.cpp index 59bffa2d9..1bf1faee5 100644 --- a/src/c-wrapper/api/c-chat-message.cpp +++ b/src/c-wrapper/api/c-chat-message.cpp @@ -222,7 +222,7 @@ void linphone_chat_message_add_text_content(LinphoneChatMessage *msg, const char LinphonePrivate::ContentType contentType = LinphonePrivate::ContentType::PlainText; content->setContentType(contentType); content->setBody(L_C_TO_STRING(c_content)); - L_GET_CPP_PTR_FROM_C_OBJECT(msg)->addContent(*content); + L_GET_CPP_PTR_FROM_C_OBJECT(msg)->addContent(content); } bool_t linphone_chat_message_has_text_content(const LinphoneChatMessage *msg) { @@ -284,7 +284,7 @@ int linphone_chat_message_set_text(LinphoneChatMessage *msg, const char* text) { LinphoneContent *linphone_chat_message_get_file_transfer_information(LinphoneChatMessage *msg) { const LinphonePrivate::Content *content = L_GET_PRIVATE_FROM_C_OBJECT(msg)->getFileTransferInformation(); - if (content) return L_GET_C_BACK_PTR(content); + if (content) return linphone_content_ref(L_GET_C_BACK_PTR(content)); return NULL; } diff --git a/src/c-wrapper/api/c-content.cpp b/src/c-wrapper/api/c-content.cpp index 7af4b4073..6691ec9da 100644 --- a/src/c-wrapper/api/c-content.cpp +++ b/src/c-wrapper/api/c-content.cpp @@ -166,27 +166,27 @@ const char * linphone_content_get_custom_header(const LinphoneContent *content, const char *linphone_content_get_key(const LinphoneContent *content) { const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); - if (c->isFile()) { - const LinphonePrivate::FileContent *fc = static_cast(c); - return L_STRING_TO_C(fc->getFileKey()); + if (c->getContentType() == LinphonePrivate::ContentType::FileTransfer) { + const LinphonePrivate::FileTransferContent *ftc = static_cast(c); + return ftc->getFileKeyAsString(); } return NULL; } size_t linphone_content_get_key_size(const LinphoneContent *content) { const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); - if (c->isFile()) { - const LinphonePrivate::FileContent *fc = static_cast(c); - return fc->getFileKey().length(); + if (c->getContentType() == LinphonePrivate::ContentType::FileTransfer) { + const LinphonePrivate::FileTransferContent *ftc = static_cast(c); + return ftc->getFileKey().size(); } return 0; } void linphone_content_set_key(LinphoneContent *content, const char *key, const size_t keyLength) { LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); - if (c->isFile()) { - LinphonePrivate::FileContent *fc = static_cast(c); - fc->setFileKey(L_C_TO_STRING(key)); + if (c->getContentType() == LinphonePrivate::ContentType::FileTransfer) { + LinphonePrivate::FileTransferContent *ftc = static_cast(c); + ftc->setFileKey(key, keyLength); } } diff --git a/src/chat/chat-message/chat-message.cpp b/src/chat/chat-message/chat-message.cpp index 855dbd902..2c5130802 100644 --- a/src/chat/chat-message/chat-message.cpp +++ b/src/chat/chat-message/chat-message.cpp @@ -301,7 +301,7 @@ void ChatMessagePrivate::setFileTransferInformation (Content *content) { L_Q(); if (content->isFile()) { - q->addContent(*content); + q->addContent(content); } else { // This scenario is more likely to happen because the caller is using the C API LinphoneContent *c_content = L_GET_C_BACK_PTR(content); @@ -312,7 +312,7 @@ void ChatMessagePrivate::setFileTransferInformation (Content *content) { if (!content->isEmpty()) { fileContent->setBody(content->getBody()); } - q->addContent(*fileContent); + q->addContent(fileContent); } } @@ -354,7 +354,7 @@ void ChatMessagePrivate::sendImdn (Imdn::Type imdnType, LinphoneReason reason) { Content *content = new Content(); content->setContentType("message/imdn+xml"); content->setBody(Imdn::createXml(imdnId, time, imdnType, reason)); - msg->addContent(*content); + msg->addContent(content); if (reason != LinphoneReasonNone) msg->getPrivate()->setEncryptionPrevented(true); @@ -676,7 +676,7 @@ void ChatMessagePrivate::send () { if (content->getContentType() == ContentType::FileTransfer) { FileTransferContent *fileTransferContent = (FileTransferContent *)content; it = contents.erase(it); - q->addContent(*fileTransferContent->getFileContent()); + q->addContent(fileTransferContent->getFileContent()); delete fileTransferContent; } else { it++; @@ -881,18 +881,18 @@ const list &ChatMessage::getContents () const { return d->contents; } -void ChatMessage::addContent (Content &content) { +void ChatMessage::addContent (Content *content) { L_D(); if (d->isReadOnly) return; - d->contents.push_back(&content); + d->contents.push_back(content); } -void ChatMessage::removeContent (const Content &content) { +void ChatMessage::removeContent (const Content *content) { L_D(); if (d->isReadOnly) return; - d->contents.remove(&const_cast(content)); + d->contents.remove(const_cast(content)); } const Content &ChatMessage::getInternalContent () const { diff --git a/src/chat/chat-message/chat-message.h b/src/chat/chat-message/chat-message.h index af7623b77..3b0b26417 100644 --- a/src/chat/chat-message/chat-message.h +++ b/src/chat/chat-message/chat-message.h @@ -94,8 +94,8 @@ public: void setToBeStored (bool value); const std::list &getContents () const; - void addContent (Content &content); - void removeContent (const Content &content); + void addContent (Content *content); + void removeContent (const Content *content); const Content &getInternalContent () const; void setInternalContent (const Content &content); diff --git a/src/chat/chat-room/chat-room.cpp b/src/chat/chat-room/chat-room.cpp index 03b8cd079..2c1e0054a 100644 --- a/src/chat/chat-room/chat-room.cpp +++ b/src/chat/chat-room/chat-room.cpp @@ -82,7 +82,7 @@ void ChatRoomPrivate::sendIsComposingNotification () { Content *content = new Content(); content->setContentType(ContentType::ImIsComposing); content->setBody(payload); - chatMessage->addContent(*content); + chatMessage->addContent(content); chatMessage->getPrivate()->send(); } } @@ -389,7 +389,7 @@ shared_ptr ChatRoom::createChatMessage (const string &text) { Content *content = new Content(); content->setContentType(ContentType::PlainText); content->setBody(text); - chatMessage->addContent(*content); + chatMessage->addContent(content); return chatMessage; } diff --git a/src/chat/modifier/file-transfer-chat-message-modifier.cpp b/src/chat/modifier/file-transfer-chat-message-modifier.cpp index ac99d2201..674ddb308 100644 --- a/src/chat/modifier/file-transfer-chat-message-modifier.cpp +++ b/src/chat/modifier/file-transfer-chat-message-modifier.cpp @@ -246,12 +246,6 @@ void FileTransferChatMessageModifier::processResponseFromPostFile (const belle_h } // shall we encrypt the file if (is_file_encryption_enabled && message->getChatRoom()) { - LinphoneImEncryptionEngineCbs *imee_cbs = linphone_im_encryption_engine_get_callbacks(imee); - LinphoneImEncryptionEngineCbsGenerateFileTransferKeyCb generate_file_transfer_key_cb = - linphone_im_encryption_engine_cbs_get_generate_file_transfer_key(imee_cbs); - if (generate_file_transfer_key_cb) { - generate_file_transfer_key_cb(imee, L_GET_C_BACK_PTR(message->getChatRoom()), L_GET_C_BACK_PTR(message)); - } // temporary storage for the Content-disposition header value : use a generic filename to not leak it // Actual filename stored in msg->file_transfer_information->name will be set in encrypted msg // sended to the @@ -294,9 +288,32 @@ void FileTransferChatMessageModifier::processResponseFromPostFile (const belle_h const char *body = belle_sip_message_get_body((belle_sip_message_t *)event->response); if (body && strlen(body) > 0) { FileTransferContent *fileTransferContent = new FileTransferContent(); + fileTransferContent->setContentType(ContentType::FileTransfer); + message->addContent(fileTransferContent); + + LinphoneImEncryptionEngine *imee = linphone_core_get_im_encryption_engine(message->getCore()->getCCore()); + bool_t is_file_encryption_enabled = FALSE; + if (imee && message->getChatRoom()) { + LinphoneImEncryptionEngineCbs *imee_cbs = linphone_im_encryption_engine_get_callbacks(imee); + LinphoneImEncryptionEngineCbsIsEncryptionEnabledForFileTransferCb is_encryption_enabled_for_file_transfer_cb = + linphone_im_encryption_engine_cbs_get_is_encryption_enabled_for_file_transfer(imee_cbs); + if (is_encryption_enabled_for_file_transfer_cb) { + is_file_encryption_enabled = is_encryption_enabled_for_file_transfer_cb(imee, L_GET_C_BACK_PTR(message->getChatRoom())); + } + } + if (is_file_encryption_enabled && message->getChatRoom()) { + LinphoneImEncryptionEngineCbs *imee_cbs = linphone_im_encryption_engine_get_callbacks(imee); + LinphoneImEncryptionEngineCbsGenerateFileTransferKeyCb generate_file_transfer_key_cb = + linphone_im_encryption_engine_cbs_get_generate_file_transfer_key(imee_cbs); + if (generate_file_transfer_key_cb) { + generate_file_transfer_key_cb(imee, L_GET_C_BACK_PTR(message->getChatRoom()), L_GET_C_BACK_PTR(message)); + } + } + // if we have an encryption key for the file, we must insert it into the msg and restore the correct filename - string content_key = currentFileContentToTransfer->getFileKey(); - if (!content_key.empty()) { + const char *content_key = fileTransferContent->getFileKeyAsString(); + size_t content_key_size = fileTransferContent->getFileKey().size(); + if (content_key_size > 0) { // parse the msg body xmlDocPtr xmlMessageBody = xmlParseDoc((const xmlChar *)body); @@ -309,16 +326,15 @@ void FileTransferChatMessageModifier::processResponseFromPostFile (const belle_h xmlChar *typeAttribute = xmlGetProp(cur, (const xmlChar *)"type"); // this is the node we are looking for : add a file-key children node if (!xmlStrcmp(typeAttribute, (const xmlChar *)"file")) { - size_t content_key_size = content_key.length(); // need to parse the children node to update the file-name one xmlNodePtr fileInfoNodeChildren = cur->xmlChildrenNode; // convert key to base64 size_t b64Size; - bctbx_base64_encode(nullptr, &b64Size, (unsigned char *)content_key.c_str(), content_key_size); + bctbx_base64_encode(nullptr, &b64Size, (unsigned char *)content_key, content_key_size); unsigned char *keyb64 = (unsigned char *)ms_malloc0(b64Size + 1); int xmlStringLength; - bctbx_base64_encode(keyb64, &b64Size, (unsigned char *)content_key.c_str(), content_key_size); + bctbx_base64_encode(keyb64, &b64Size, (unsigned char *)content_key, content_key_size); keyb64[b64Size] = '\0'; // libxml need a null terminated string // add the node containing the key to the file-info node @@ -354,11 +370,9 @@ void FileTransferChatMessageModifier::processResponseFromPostFile (const belle_h } FileContent *fileContent = currentFileContentToTransfer; - fileTransferContent->setContentType(ContentType::FileTransfer); fileTransferContent->setFileContent(fileContent); - message->removeContent(*fileContent); - message->addContent(*fileTransferContent); + message->removeContent(fileContent); message->updateState(ChatMessage::State::FileTransferDone); releaseHttpRequest(); @@ -566,7 +580,7 @@ ChatMessageModifier::Result FileTransferChatMessageModifier::decode (const share fileTransferContent->setContentType(internalContent.getContentType()); fileTransferContent->setBody(internalContent.getBody()); fillFileTransferContentInformationsFromVndGsmaRcsFtHttpXml(fileTransferContent); - message->addContent(*fileTransferContent); + message->addContent(fileTransferContent); return ChatMessageModifier::Result::Done; } @@ -641,8 +655,7 @@ static void createFileTransferInformationsFromVndGsmaRcsFtHttpXml (FileTransferC uint8_t *keyBuffer = (uint8_t *)malloc(keyLength); // decode the key into local key buffer bctbx_base64_decode(keyBuffer, &keyLength, (unsigned char *)keyb64, strlen((const char *)keyb64)); - string key = string((const char *)keyBuffer); - fileContent->setFileKey(key); + fileTransferContent->setFileKey((const char *)keyBuffer, keyLength); // duplicate key value into the linphone content private structure xmlFree(keyb64); free(keyBuffer); @@ -715,7 +728,6 @@ void FileTransferChatMessageModifier::onRecvBody (belle_sip_user_body_handler_t // Legacy: call back given by application level linphone_core_notify_file_transfer_recv(message->getCore()->getCCore(), msg, content, (const char *)buffer, size); } - linphone_content_unref(content); } } else { lWarning() << "File transfer decrypt failed with code " << (int)retval; @@ -763,12 +775,12 @@ void FileTransferChatMessageModifier::onRecvEnd (belle_sip_user_body_handler_t * if (retval <= 0 && message->getState() != ChatMessage::State::FileTransferError) { // Remove the FileTransferContent from the message and store the FileContent FileContent *fileContent = currentFileContentToTransfer; - message->addContent(*fileContent); + message->addContent(fileContent); for (Content *content : message->getContents()) { if (content->getContentType() == ContentType::FileTransfer) { FileTransferContent *fileTransferContent = (FileTransferContent*)content; if (fileTransferContent->getFileContent() == fileContent) { - message->removeContent(*content); + message->removeContent(content); delete fileTransferContent; break; } @@ -821,7 +833,7 @@ void FileTransferChatMessageModifier::processResponseHeadersFromGetFile (const b } else { lWarning() << "No file transfer information for msg [" << this << "]: creating..."; FileContent *content = createFileTransferInformationFromHeaders(response); - message->addContent(*content); + message->addContent(content); } size_t body_size = 0; diff --git a/src/chat/modifier/multipart-chat-message-modifier.cpp b/src/chat/modifier/multipart-chat-message-modifier.cpp index 4abf91210..97081a4d0 100644 --- a/src/chat/modifier/multipart-chat-message-modifier.cpp +++ b/src/chat/modifier/multipart-chat-message-modifier.cpp @@ -120,7 +120,7 @@ ChatMessageModifier::Result MultipartChatMessageModifier::decode (const shared_p } content->setContentType(contentType); content->setBody(contentBody); - message->addContent(*content); + message->addContent(content); lInfo() << "Parsed and added content with type " << contentType.asString(); } diff --git a/src/content/file-content.cpp b/src/content/file-content.cpp index a2d1df851..8f6425474 100644 --- a/src/content/file-content.cpp +++ b/src/content/file-content.cpp @@ -36,7 +36,6 @@ public: string fileName; string filePath; size_t fileSize = 0; - string fileKey; }; // ----------------------------------------------------------------------------- @@ -48,7 +47,6 @@ FileContent::FileContent (const FileContent &src) : Content(*new FileContentPriv d->fileName = src.getFileName(); d->filePath = src.getFilePath(); d->fileSize = src.getFileSize(); - d->fileKey = src.getFileKey(); } FileContent::FileContent (FileContent &&src) : Content(*new FileContentPrivate) { @@ -56,7 +54,6 @@ FileContent::FileContent (FileContent &&src) : Content(*new FileContentPrivate) d->fileName = move(src.getPrivate()->fileName); d->filePath = move(src.getPrivate()->filePath); d->fileSize = move(src.getPrivate()->fileSize); - d->fileKey = move(src.getPrivate()->fileKey); } FileContent &FileContent::operator= (const FileContent &src) { @@ -66,7 +63,6 @@ FileContent &FileContent::operator= (const FileContent &src) { d->fileName = src.getFileName(); d->filePath = src.getFilePath(); d->fileSize = src.getFileSize(); - d->fileKey = src.getFileKey(); } return *this; @@ -78,7 +74,6 @@ FileContent &FileContent::operator= (FileContent &&src) { d->fileName = move(src.getPrivate()->fileName); d->filePath = move(src.getPrivate()->filePath); d->fileSize = move(src.getPrivate()->fileSize); - d->fileKey = move(src.getPrivate()->fileKey); return *this; } @@ -87,8 +82,7 @@ bool FileContent::operator== (const FileContent &content) const { return Content::operator==(content) && d->fileName == content.getFileName() && d->filePath == content.getFilePath() && - d->fileSize == content.getFileSize() && - d->fileKey == content.getFileKey(); + d->fileSize == content.getFileSize(); } void FileContent::setFileSize (size_t size) { @@ -121,16 +115,6 @@ const string &FileContent::getFilePath () const { return d->filePath; } -void FileContent::setFileKey (const string &key) { - L_D(); - d->fileKey = key; -} - -const string &FileContent::getFileKey () const { - L_D(); - return d->fileKey; -} - bool FileContent::isFile () const { return true; } diff --git a/src/content/file-content.h b/src/content/file-content.h index 79dfe5629..c46786dd5 100644 --- a/src/content/file-content.h +++ b/src/content/file-content.h @@ -48,9 +48,6 @@ public: void setFilePath (const std::string &path); const std::string &getFilePath () const; - void setFileKey (const std::string &key); - const std::string &getFileKey () const; - bool isFile () const override; private: diff --git a/src/content/file-transfer-content.cpp b/src/content/file-transfer-content.cpp index 628080c7c..d1d67c00d 100644 --- a/src/content/file-transfer-content.cpp +++ b/src/content/file-transfer-content.cpp @@ -38,6 +38,7 @@ public: string filePath; FileContent *fileContent = nullptr; size_t fileSize = 0; + std::vector fileKey; }; // ----------------------------------------------------------------------------- @@ -51,6 +52,7 @@ FileTransferContent::FileTransferContent (const FileTransferContent &src) : Cont d->filePath = src.getFilePath(); d->fileContent = src.getFileContent(); d->fileSize = src.getFileSize(); + d->fileKey = src.getFileKey(); } FileTransferContent::FileTransferContent (FileTransferContent &&src) : Content(*new FileTransferContentPrivate) { @@ -60,6 +62,7 @@ FileTransferContent::FileTransferContent (FileTransferContent &&src) : Content(* d->filePath = move(src.getPrivate()->filePath); d->fileContent = move(src.getPrivate()->fileContent); d->fileSize = move(src.getPrivate()->fileSize); + d->fileKey = move(src.getPrivate()->fileKey); } FileTransferContent &FileTransferContent::operator= (const FileTransferContent &src) { @@ -71,6 +74,7 @@ FileTransferContent &FileTransferContent::operator= (const FileTransferContent & d->filePath = src.getFilePath(); d->fileContent = src.getFileContent(); d->fileSize = src.getFileSize(); + d->fileKey = src.getFileKey(); } return *this; @@ -84,6 +88,7 @@ FileTransferContent &FileTransferContent::operator= (FileTransferContent &&src) d->filePath = move(src.getPrivate()->filePath); d->fileContent = move(src.getPrivate()->fileContent); d->fileSize = move(src.getPrivate()->fileSize); + d->fileKey = move(src.getPrivate()->fileKey); return *this; } @@ -146,6 +151,21 @@ size_t FileTransferContent::getFileSize () const { return d->fileSize; } +void FileTransferContent::setFileKey (const char *key, size_t size) { + L_D(); + d->fileKey = vector(key, key + size); +} + +const vector &FileTransferContent::getFileKey () const { + L_D(); + return d->fileKey; +} + +const char *FileTransferContent::getFileKeyAsString() const { + L_D(); + return d->fileKey.data(); +} + bool FileTransferContent::isFile () const { return false; } diff --git a/src/content/file-transfer-content.h b/src/content/file-transfer-content.h index 4abc4369f..da23053cb 100644 --- a/src/content/file-transfer-content.h +++ b/src/content/file-transfer-content.h @@ -20,6 +20,8 @@ #ifndef _L_FILE_TRANSFER_CONTENT_H_ #define _L_FILE_TRANSFER_CONTENT_H_ +#include + #include "content.h" // ============================================================================= @@ -55,6 +57,10 @@ public: void setFileSize (size_t size); size_t getFileSize () const; + void setFileKey (const char *key, size_t size); + const std::vector &getFileKey () const; + const char *getFileKeyAsString () const; + bool isFile () const override; private: diff --git a/src/db/main-db.cpp b/src/db/main-db.cpp index 1e76e96ae..943426029 100644 --- a/src/db/main-db.cpp +++ b/src/db/main-db.cpp @@ -708,7 +708,7 @@ shared_ptr MainDbPrivate::selectConferenceChatMessageEvent ( string data; fetchContentAppData(session, *content, contentId, data); } - chatMessage->addContent(*content); + chatMessage->addContent(content); } } diff --git a/tester/cpim-tester.cpp b/tester/cpim-tester.cpp index a98ca133d..54a36b568 100644 --- a/tester/cpim-tester.cpp +++ b/tester/cpim-tester.cpp @@ -426,7 +426,7 @@ static void cpim_chat_message_modifier_base(bool_t use_multipart) { Content *content = new Content(); content->setContentType(ContentType::PlainText); content->setBody("Hello Part 2"); - marieMessage->addContent(*content); + marieMessage->addContent(content); } marieMessage->send(); diff --git a/tester/multipart-tester.cpp b/tester/multipart-tester.cpp index ad5d731f3..0472df0eb 100644 --- a/tester/multipart-tester.cpp +++ b/tester/multipart-tester.cpp @@ -53,13 +53,13 @@ static void chat_message_multipart_modifier_base(bool first_file_transfer, bool content->setContentType("video/mkv"); content->setFilePath(send_filepath); content->setFileName("sintel_trailer_opus_h264.mkv"); - marieMessage->addContent(*content); + marieMessage->addContent(content); bc_free(send_filepath); } else { Content *content = new Content(); content->setContentType(ContentType::PlainText); content->setBody("Hello Part 1"); - marieMessage->addContent(*content); + marieMessage->addContent(content); } if (second_file_transfer) { @@ -68,13 +68,13 @@ static void chat_message_multipart_modifier_base(bool first_file_transfer, bool content->setContentType("file/vcf"); content->setFilePath(send_filepath); content->setFileName("vcards.vcf"); - marieMessage->addContent(*content); + marieMessage->addContent(content); bc_free(send_filepath); } else { Content *content = new Content(); content->setContentType(ContentType::PlainText); content->setBody("Hello Part 2"); - marieMessage->addContent(*content); + marieMessage->addContent(content); } linphone_core_set_file_transfer_server(marie->lc,"https://www.linphone.org:444/lft.php"); From 450548f612d3d547c3eb3ad8d65502f0659674ed Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Thu, 8 Feb 2018 16:28:48 +0100 Subject: [PATCH 04/17] fix(core): add missing content.h include --- coreapi/callbacks.c | 3 ++- coreapi/friendlist.c | 1 + coreapi/info.c | 1 + coreapi/lime.c | 6 ++++-- coreapi/linphonecore.c | 6 ++++-- coreapi/proxy.c | 2 ++ coreapi/quality_reporting.c | 2 ++ include/linphone/core.h | 1 - src/c-wrapper/api/c-chat-message.cpp | 1 + src/c-wrapper/api/c-content.cpp | 2 +- src/chat/chat-message/chat-message.cpp | 3 ++- src/chat/modifier/file-transfer-chat-message-modifier.cpp | 8 +++++--- .../handlers/local-conference-event-handler.cpp | 1 + src/conference/session/call-session.cpp | 7 +++---- 14 files changed, 29 insertions(+), 15 deletions(-) diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index 25967bcb8..e99f02e17 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -17,14 +17,15 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - #include "c-wrapper/internal/c-sal.h" #include "sal/call-op.h" #include "sal/message-op.h" #include "sal/refer-op.h" +#include "linphone/api/c-content.h" #include "linphone/core.h" #include "linphone/utils/utils.h" + #include "private.h" #include "mediastreamer2/mediastream.h" #include "linphone/lpconfig.h" diff --git a/coreapi/friendlist.c b/coreapi/friendlist.c index 159409449..9475b877c 100644 --- a/coreapi/friendlist.c +++ b/coreapi/friendlist.c @@ -19,6 +19,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include +#include "linphone/api/c-content.h" #include "linphone/core.h" #include "c-wrapper/c-wrapper.h" diff --git a/coreapi/info.c b/coreapi/info.c index 5b12089bb..f68bb4522 100644 --- a/coreapi/info.c +++ b/coreapi/info.c @@ -23,6 +23,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include "linphone/api/c-content.h" #include "linphone/core.h" #include "linphone/lpconfig.h" diff --git a/coreapi/lime.c b/coreapi/lime.c index 4270f9d2a..965ccd10c 100644 --- a/coreapi/lime.c +++ b/coreapi/lime.c @@ -17,6 +17,8 @@ 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/api/c-content.h" + #include "lime.h" #ifdef HAVE_CONFIG_H #include "config.h" @@ -787,8 +789,8 @@ int lime_im_encryption_engine_process_incoming_message_cb(LinphoneImEncryptionEn LinphoneCore *lc = linphone_im_encryption_engine_get_core(engine); int errcode = -1; /* check if we have a xml/cipher message to be decrypted */ - if (linphone_chat_message_get_content_type(msg) && - (strcmp("xml/cipher", linphone_chat_message_get_content_type(msg)) == 0 || + if (linphone_chat_message_get_content_type(msg) && + (strcmp("xml/cipher", linphone_chat_message_get_content_type(msg)) == 0 || strcmp("application/cipher.vnd.gsma.rcs-ft-http+xml", linphone_chat_message_get_content_type(msg)) == 0)) { errcode = 0; int retval; diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 114749d3a..9e01822e1 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -18,9 +18,11 @@ 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/api/c-content.h" #include "linphone/core.h" -#include "linphone/sipsetup.h" #include "linphone/lpconfig.h" +#include "linphone/sipsetup.h" + #include "private.h" #include "quality_reporting.h" #include "lime.h" @@ -2320,7 +2322,7 @@ void linphone_core_start (LinphoneCore *lc) { lp_config_set_string(lc->config,"misc","uuid",tmp); }else if (strcmp(uuid,"0")!=0) /*to allow to disable sip.instance*/ lc->sal->set_uuid(uuid); - + if (lc->sal->get_root_ca()) { belle_tls_crypto_config_set_root_ca(lc->http_crypto_config, lc->sal->get_root_ca()); belle_http_provider_set_tls_crypto_config(lc->http_provider, lc->http_crypto_config); diff --git a/coreapi/proxy.c b/coreapi/proxy.c index d5f3ea5ad..1f7d88519 100644 --- a/coreapi/proxy.c +++ b/coreapi/proxy.c @@ -20,10 +20,12 @@ Copyright (C) 2000 Simon MORLAT (simon.morlat@linphone.org) #include +#include "linphone/api/c-content.h" #include "linphone/core_utils.h" #include "linphone/core.h" #include "linphone/lpconfig.h" #include "linphone/sipsetup.h" + #include "mediastreamer2/mediastream.h" #include "enum.h" diff --git a/coreapi/quality_reporting.c b/coreapi/quality_reporting.c index 571a8faa0..a20b03b8e 100644 --- a/coreapi/quality_reporting.c +++ b/coreapi/quality_reporting.c @@ -21,7 +21,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "config.h" #endif +#include "linphone/api/c-content.h" #include "linphone/core.h" + #include "private.h" #include "c-wrapper/internal/c-sal.h" #include "sal/sal.h" diff --git a/include/linphone/core.h b/include/linphone/core.h index d2efdce47..d1ebbeb53 100644 --- a/include/linphone/core.h +++ b/include/linphone/core.h @@ -42,7 +42,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "linphone/call_stats.h" #include "linphone/chat.h" #include "linphone/conference.h" -#include "linphone/content.h" #include "linphone/dictionary.h" #include "linphone/error_info.h" #include "linphone/event.h" diff --git a/src/c-wrapper/api/c-chat-message.cpp b/src/c-wrapper/api/c-chat-message.cpp index 1bf1faee5..7f8e1b8c6 100644 --- a/src/c-wrapper/api/c-chat-message.cpp +++ b/src/c-wrapper/api/c-chat-message.cpp @@ -18,6 +18,7 @@ */ #include "linphone/api/c-chat-message.h" +#include "linphone/api/c-content.h" #include "linphone/utils/utils.h" #include "linphone/wrapper_utils.h" diff --git a/src/c-wrapper/api/c-content.cpp b/src/c-wrapper/api/c-content.cpp index 6691ec9da..b4f77a316 100644 --- a/src/c-wrapper/api/c-content.cpp +++ b/src/c-wrapper/api/c-content.cpp @@ -243,4 +243,4 @@ LinphoneContent * linphone_content_from_sal_body_handler(SalBodyHandler *body_ha SalBodyHandler * sal_body_handler_from_content(const LinphoneContent *content) { if (content == NULL) return NULL; return content->body_handler; -} \ No newline at end of file +} diff --git a/src/chat/chat-message/chat-message.cpp b/src/chat/chat-message/chat-message.cpp index 2c5130802..fd3157614 100644 --- a/src/chat/chat-message/chat-message.cpp +++ b/src/chat/chat-message/chat-message.cpp @@ -19,6 +19,7 @@ #include "object/object-p.h" +#include "linphone/api/c-content.h" #include "linphone/core.h" #include "linphone/lpconfig.h" #include "linphone/utils/utils.h" @@ -668,7 +669,7 @@ void ChatMessagePrivate::send () { } else { msgOp->send_message(ContentType::PlainText.asString().c_str(), internalContent.getBodyAsUtf8String().c_str()); } - + // Restore FileContents and remove FileTransferContents list::iterator it = contents.begin(); while (it != contents.end()) { diff --git a/src/chat/modifier/file-transfer-chat-message-modifier.cpp b/src/chat/modifier/file-transfer-chat-message-modifier.cpp index 674ddb308..ec04c61f0 100644 --- a/src/chat/modifier/file-transfer-chat-message-modifier.cpp +++ b/src/chat/modifier/file-transfer-chat-message-modifier.cpp @@ -17,15 +17,17 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include "c-wrapper/c-wrapper.h" +#include "linphone/api/c-content.h" + #include "address/address.h" +#include "bctoolbox/crypto.h" +#include "c-wrapper/c-wrapper.h" #include "chat/chat-message/chat-message-p.h" +#include "chat/chat-room/chat-room-p.h" #include "content/content-type.h" #include "content/content.h" -#include "chat/chat-room/chat-room-p.h" #include "core/core.h" #include "logger/logger.h" -#include "bctoolbox/crypto.h" #include "file-transfer-chat-message-modifier.h" diff --git a/src/conference/handlers/local-conference-event-handler.cpp b/src/conference/handlers/local-conference-event-handler.cpp index 7b3989b72..96da99d07 100644 --- a/src/conference/handlers/local-conference-event-handler.cpp +++ b/src/conference/handlers/local-conference-event-handler.cpp @@ -19,6 +19,7 @@ #include +#include "linphone/api/c-content.h" #include "linphone/utils/utils.h" #include "conference/local-conference.h" diff --git a/src/conference/session/call-session.cpp b/src/conference/session/call-session.cpp index 97aa06f6f..bb3ac773e 100644 --- a/src/conference/session/call-session.cpp +++ b/src/conference/session/call-session.cpp @@ -19,19 +19,18 @@ #include -#include "c-wrapper/c-wrapper.h" +#include "linphone/api/c-content.h" +#include "linphone/core.h" #include "address/address-p.h" +#include "c-wrapper/c-wrapper.h" #include "call/call-p.h" #include "conference/params/call-session-params-p.h" #include "conference/session/call-session-p.h" #include "conference/session/call-session.h" #include "core/core-p.h" - #include "logger/logger.h" -#include "linphone/core.h" - #include "private.h" using namespace std; From bfe175f85310148804d1682252b0141b838f05f6 Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Thu, 8 Feb 2018 16:30:28 +0100 Subject: [PATCH 05/17] fix(c-api): add missing content include --- include/linphone/api/c-api.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/include/linphone/api/c-api.h b/include/linphone/api/c-api.h index 0b671d6ee..c37f7549a 100644 --- a/include/linphone/api/c-api.h +++ b/include/linphone/api/c-api.h @@ -23,14 +23,15 @@ #include "linphone/utils/general.h" #include "linphone/api/c-address.h" -#include "linphone/api/c-call.h" #include "linphone/api/c-call-cbs.h" #include "linphone/api/c-call-stats.h" +#include "linphone/api/c-call.h" #include "linphone/api/c-callbacks.h" -#include "linphone/api/c-chat-message.h" #include "linphone/api/c-chat-message-cbs.h" -#include "linphone/api/c-chat-room.h" +#include "linphone/api/c-chat-message.h" #include "linphone/api/c-chat-room-cbs.h" +#include "linphone/api/c-chat-room.h" +#include "linphone/api/c-content.h" #include "linphone/api/c-dial-plan.h" #include "linphone/api/c-event-log.h" #include "linphone/api/c-participant.h" From 1b74fdadefef9c721b35687b7528473b3c92a358 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 8 Feb 2018 17:25:35 +0100 Subject: [PATCH 06/17] Do not crash if key is NULL --- coreapi/lime.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/coreapi/lime.c b/coreapi/lime.c index 965ccd10c..cdf697b95 100644 --- a/coreapi/lime.c +++ b/coreapi/lime.c @@ -421,6 +421,8 @@ int lime_encryptFile(void **cryptoContext, unsigned char *key, size_t length, ch int lime_decryptFile(void **cryptoContext, unsigned char *key, size_t length, char *plain, char *cipher) { bctbx_aes_gcm_context_t *gcmContext; + if (key == NULL) return -1; + if (*cryptoContext == NULL) { /* first call to the function, allocate a crypto context and initialise it */ /* key contains 192bits of key || 64 bits of Initialisation Vector, no additional data */ gcmContext = bctbx_aes_gcm_context_new(key, 24, NULL, 0, key+24, 8, BCTBX_GCM_DECRYPT); @@ -895,6 +897,7 @@ int lime_im_encryption_engine_process_downloading_file_cb(LinphoneImEncryptionEn LinphoneContent *content = linphone_chat_message_get_file_transfer_information(msg); if (!content) return -1; + if (!linphone_content_get_key(content)) { linphone_content_unref(content); return -1; From dbdbeaa46f426b6efdabc24ffdbb5c2f20adaa66 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 8 Feb 2018 17:38:16 +0100 Subject: [PATCH 07/17] Added and using isFileTransfer --- src/chat/chat-message/chat-message.cpp | 16 ++++++++-------- src/chat/chat-message/chat-message.h | 2 +- .../file-transfer-chat-message-modifier.cpp | 8 ++++---- src/content/content.cpp | 4 ++++ src/content/content.h | 1 + src/content/file-content.cpp | 4 ++++ src/content/file-content.h | 1 + src/content/file-transfer-content.cpp | 4 ++++ src/content/file-transfer-content.h | 1 + 9 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/chat/chat-message/chat-message.cpp b/src/chat/chat-message/chat-message.cpp index fd3157614..df72a1b46 100644 --- a/src/chat/chat-message/chat-message.cpp +++ b/src/chat/chat-message/chat-message.cpp @@ -162,7 +162,7 @@ const Content* ChatMessagePrivate::getTextContent() const { bool ChatMessagePrivate::hasFileTransferContent() const { for (const Content *c : contents) { - if (c->getContentType() == ContentType::FileTransfer) { + if (c->isFileTransfer()) { return true; } } @@ -171,7 +171,7 @@ bool ChatMessagePrivate::hasFileTransferContent() const { const Content* ChatMessagePrivate::getFileTransferContent() const { for (const Content *c : contents) { - if (c->getContentType() == ContentType::FileTransfer) { + if (c->isFileTransfer()) { return c; } } @@ -321,8 +321,8 @@ bool ChatMessagePrivate::downloadFile () { L_Q(); for (auto &content : contents) - if (content->getContentType() == ContentType::FileTransfer) - return q->downloadFile(*static_cast(content)); + if (content->isFileTransfer()) + return q->downloadFile(static_cast(content)); return false; } @@ -674,8 +674,8 @@ void ChatMessagePrivate::send () { list::iterator it = contents.begin(); while (it != contents.end()) { Content *content = *it; - if (content->getContentType() == ContentType::FileTransfer) { - FileTransferContent *fileTransferContent = (FileTransferContent *)content; + if (content->isFileTransfer()) { + FileTransferContent *fileTransferContent = static_cast(content); it = contents.erase(it); q->addContent(fileTransferContent->getFileContent()); delete fileTransferContent; @@ -965,9 +965,9 @@ void ChatMessage::sendDisplayNotification () { d->sendImdn(Imdn::Type::Display, LinphoneReasonNone); } -bool ChatMessage::downloadFile(FileTransferContent &fileTransferContent) { +bool ChatMessage::downloadFile(FileTransferContent *fileTransferContent) { L_D(); - return d->fileTransferChatMessageModifier.downloadFile(getSharedFromThis(), &fileTransferContent); + return d->fileTransferChatMessageModifier.downloadFile(getSharedFromThis(), fileTransferContent); } void ChatMessage::cancelFileTransfer () { diff --git a/src/chat/chat-message/chat-message.h b/src/chat/chat-message/chat-message.h index 3b0b26417..47d8c365a 100644 --- a/src/chat/chat-message/chat-message.h +++ b/src/chat/chat-message/chat-message.h @@ -104,7 +104,7 @@ public: void addCustomHeader (const std::string &headerName, const std::string &headerValue); void removeCustomHeader (const std::string &headerName); - bool downloadFile (FileTransferContent &content); + bool downloadFile (FileTransferContent *content); private: ChatMessage (const std::shared_ptr &chatRoom, ChatMessage::Direction direction); diff --git a/src/chat/modifier/file-transfer-chat-message-modifier.cpp b/src/chat/modifier/file-transfer-chat-message-modifier.cpp index ec04c61f0..1032c5af8 100644 --- a/src/chat/modifier/file-transfer-chat-message-modifier.cpp +++ b/src/chat/modifier/file-transfer-chat-message-modifier.cpp @@ -587,8 +587,8 @@ ChatMessageModifier::Result FileTransferChatMessageModifier::decode (const share } for (Content *content : message->getContents()) { - if (content->getContentType() == ContentType::FileTransfer) { - FileTransferContent *fileTransferContent = (FileTransferContent *)content; + if (content->isFileTransfer()) { + FileTransferContent *fileTransferContent = static_cast(content); fillFileTransferContentInformationsFromVndGsmaRcsFtHttpXml(fileTransferContent); } } @@ -779,8 +779,8 @@ void FileTransferChatMessageModifier::onRecvEnd (belle_sip_user_body_handler_t * FileContent *fileContent = currentFileContentToTransfer; message->addContent(fileContent); for (Content *content : message->getContents()) { - if (content->getContentType() == ContentType::FileTransfer) { - FileTransferContent *fileTransferContent = (FileTransferContent*)content; + if (content->isFileTransfer()) { + FileTransferContent *fileTransferContent = static_cast(content); if (fileTransferContent->getFileContent() == fileContent) { message->removeContent(content); delete fileTransferContent; diff --git a/src/content/content.cpp b/src/content/content.cpp index 93fd2f6e4..786c9be8d 100644 --- a/src/content/content.cpp +++ b/src/content/content.cpp @@ -172,4 +172,8 @@ bool Content::isFile () const { return false; } +bool Content::isFileTransfer () const { + return false; +} + LINPHONE_END_NAMESPACE diff --git a/src/content/content.h b/src/content/content.h index da3c9e055..281ad78d2 100644 --- a/src/content/content.h +++ b/src/content/content.h @@ -70,6 +70,7 @@ public: bool isEmpty () const; virtual bool isFile () const; + virtual bool isFileTransfer () const; protected: explicit Content (ContentPrivate &p); diff --git a/src/content/file-content.cpp b/src/content/file-content.cpp index 8f6425474..63c727dc6 100644 --- a/src/content/file-content.cpp +++ b/src/content/file-content.cpp @@ -119,4 +119,8 @@ bool FileContent::isFile () const { return true; } +bool FileContent::isFileTransfer () const { + return false; +} + LINPHONE_END_NAMESPACE diff --git a/src/content/file-content.h b/src/content/file-content.h index c46786dd5..82bc1bcff 100644 --- a/src/content/file-content.h +++ b/src/content/file-content.h @@ -49,6 +49,7 @@ public: const std::string &getFilePath () const; bool isFile () const override; + bool isFileTransfer () const override; private: L_DECLARE_PRIVATE(FileContent); diff --git a/src/content/file-transfer-content.cpp b/src/content/file-transfer-content.cpp index d1d67c00d..57ecff245 100644 --- a/src/content/file-transfer-content.cpp +++ b/src/content/file-transfer-content.cpp @@ -170,4 +170,8 @@ bool FileTransferContent::isFile () const { return false; } +bool FileTransferContent::isFileTransfer () const { + return true; +} + LINPHONE_END_NAMESPACE diff --git a/src/content/file-transfer-content.h b/src/content/file-transfer-content.h index da23053cb..d107fcd52 100644 --- a/src/content/file-transfer-content.h +++ b/src/content/file-transfer-content.h @@ -62,6 +62,7 @@ public: const char *getFileKeyAsString () const; bool isFile () const override; + bool isFileTransfer () const override; private: L_DECLARE_PRIVATE(FileTransferContent); From 1024c1942bddfc584c59811839b12035433d86ce Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 8 Feb 2018 17:50:25 +0100 Subject: [PATCH 08/17] Some invalid read fixes --- src/c-wrapper/api/c-content.cpp | 12 ++++++------ src/content/file-transfer-content.cpp | 5 +++++ src/content/file-transfer-content.h | 1 + 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/c-wrapper/api/c-content.cpp b/src/c-wrapper/api/c-content.cpp index b4f77a316..3b7e009bd 100644 --- a/src/c-wrapper/api/c-content.cpp +++ b/src/c-wrapper/api/c-content.cpp @@ -122,7 +122,7 @@ const char * linphone_content_get_name(const LinphoneContent *content) { const LinphonePrivate::FileContent *fc = static_cast(c); if (content->name) ms_free(content->name); content->name = ms_strdup(L_STRING_TO_C(fc->getFileName())); - } else if (c->getContentType() == LinphonePrivate::ContentType::FileTransfer) { + } else if (c->isFileTransfer()) { const LinphonePrivate::FileTransferContent *ftc = static_cast(c); if (content->name) ms_free(content->name); content->name = ms_strdup(L_STRING_TO_C(ftc->getFileName())); @@ -135,7 +135,7 @@ void linphone_content_set_name(LinphoneContent *content, const char *name) { if (c->isFile()) { LinphonePrivate::FileContent *fc = static_cast(c); fc->setFileName(L_C_TO_STRING(name)); - } else if (c->getContentType() == LinphonePrivate::ContentType::FileTransfer) { + } else if (c->isFileTransfer()) { LinphonePrivate::FileTransferContent *ftc = static_cast(c); ftc->setFileName(L_C_TO_STRING(name)); } @@ -166,7 +166,7 @@ const char * linphone_content_get_custom_header(const LinphoneContent *content, const char *linphone_content_get_key(const LinphoneContent *content) { const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); - if (c->getContentType() == LinphonePrivate::ContentType::FileTransfer) { + if (c->isFileTransfer()) { const LinphonePrivate::FileTransferContent *ftc = static_cast(c); return ftc->getFileKeyAsString(); } @@ -175,16 +175,16 @@ const char *linphone_content_get_key(const LinphoneContent *content) { size_t linphone_content_get_key_size(const LinphoneContent *content) { const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); - if (c->getContentType() == LinphonePrivate::ContentType::FileTransfer) { + if (c->isFileTransfer()) { const LinphonePrivate::FileTransferContent *ftc = static_cast(c); - return ftc->getFileKey().size(); + return ftc->getFileKeySize(); } return 0; } void linphone_content_set_key(LinphoneContent *content, const char *key, const size_t keyLength) { LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); - if (c->getContentType() == LinphonePrivate::ContentType::FileTransfer) { + if (c->isFileTransfer()) { LinphonePrivate::FileTransferContent *ftc = static_cast(c); ftc->setFileKey(key, keyLength); } diff --git a/src/content/file-transfer-content.cpp b/src/content/file-transfer-content.cpp index 57ecff245..6dffb441d 100644 --- a/src/content/file-transfer-content.cpp +++ b/src/content/file-transfer-content.cpp @@ -166,6 +166,11 @@ const char *FileTransferContent::getFileKeyAsString() const { return d->fileKey.data(); } +size_t FileTransferContent::getFileKeySize() const { + L_D(); + return d->fileKey.size(); +} + bool FileTransferContent::isFile () const { return false; } diff --git a/src/content/file-transfer-content.h b/src/content/file-transfer-content.h index d107fcd52..0f29dc489 100644 --- a/src/content/file-transfer-content.h +++ b/src/content/file-transfer-content.h @@ -60,6 +60,7 @@ public: void setFileKey (const char *key, size_t size); const std::vector &getFileKey () const; const char *getFileKeyAsString () const; + size_t getFileKeySize() const; bool isFile () const override; bool isFileTransfer () const override; From b9b2ca63119127b2d59be2b2110d83e8bba85f50 Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Fri, 9 Feb 2018 10:57:25 +0100 Subject: [PATCH 09/17] feat(MainDb): add a security to delete basic chat room on migration when peer sip address is a server sip address chat room --- src/db/main-db.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/db/main-db.cpp b/src/db/main-db.cpp index 943426029..4b507cb6e 100644 --- a/src/db/main-db.cpp +++ b/src/db/main-db.cpp @@ -89,8 +89,10 @@ public: } catch (const soci::soci_error &e) { lWarning() << "Catched exception in MainDb::" << info.name << "."; soci::soci_error::error_category category = e.get_error_category(); - if ((category == soci::soci_error::connection_error - || category == soci::soci_error::unknown) && info.mainDb->forceReconnect()) { + if ( + (category == soci::soci_error::connection_error || category == soci::soci_error::unknown) && + info.mainDb->forceReconnect() + ) { mResult = mFunction(); return; } @@ -2528,6 +2530,19 @@ void MainDb::migrateBasicToClientGroupChatRoom ( const long long &localSipAddressId = d->insertSipAddress(newChatRoomId.getLocalAddress().asString()); const int &capabilities = clientGroupChatRoom->getCapabilities(); + { + shared_ptr buggyChatRoom = getCore()->findChatRoom(newChatRoomId); + if (buggyChatRoom) { + lError() << "Chat room was found with the same chat room id of a new migrated ClientGroupChatRoom!!!"; + AbstractChatRoom::CapabilitiesMask capabilities = buggyChatRoom->getCapabilities(); + if (capabilities & AbstractChatRoom::Capabilities::Basic) { + lError() << "Delete invalid basic chat room..."; + Core::deleteChatRoom(buggyChatRoom); + } else + lError() << "Unable to delete invalid chat room with capabilities: " << capabilities << "."; + } + } + *session << "UPDATE chat_room" " SET capabilities = :capabilities," " peer_sip_address_id = :peerSipAddressId," From 575370919d140cc2041ad50da21afd84a3608c07 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 9 Feb 2018 13:41:27 +0100 Subject: [PATCH 10/17] More work on c-content.cpp --- src/c-wrapper/api/c-content.cpp | 94 ++++++++++++++++++++++----------- 1 file changed, 63 insertions(+), 31 deletions(-) diff --git a/src/c-wrapper/api/c-content.cpp b/src/c-wrapper/api/c-content.cpp index 3b7e009bd..99318aa23 100644 --- a/src/c-wrapper/api/c-content.cpp +++ b/src/c-wrapper/api/c-content.cpp @@ -32,9 +32,14 @@ using namespace std; L_DECLARE_C_CLONABLE_OBJECT_IMPL(Content, - SalBodyHandler *body_handler; void *cryptoContext; /**< crypto context used to encrypt file for RCS file transfer */ mutable char *name; + mutable char *type; + mutable char *subtype; + mutable char *body; + mutable size_t size; + mutable char *encoding; + mutable char *key; ) // ============================================================================= @@ -61,7 +66,9 @@ void linphone_content_set_user_data(LinphoneContent *content, void *ud) { // ============================================================================= const char * linphone_content_get_type(const LinphoneContent *content) { - return L_STRING_TO_C(L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType().getType()); + if (content->type) ms_free(content->type); + content->type = ms_strdup(L_STRING_TO_C(L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType().getType())); + return content->type; } void linphone_content_set_type(LinphoneContent *content, const char *type) { @@ -71,7 +78,9 @@ void linphone_content_set_type(LinphoneContent *content, const char *type) { } const char * linphone_content_get_subtype(const LinphoneContent *content) { - return L_STRING_TO_C(L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType().getSubType()); + if (content->subtype) ms_free(content->subtype); + content->subtype = ms_strdup(L_STRING_TO_C(L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType().getSubType())); + return content->subtype; } void linphone_content_set_subtype(LinphoneContent *content, const char *subtype) { @@ -89,7 +98,9 @@ void linphone_content_set_buffer(LinphoneContent *content, const uint8_t *buffer } const char * linphone_content_get_string_buffer(const LinphoneContent *content) { - return L_STRING_TO_C(L_GET_CPP_PTR_FROM_C_OBJECT(content)->getBodyAsString()); + if (content->body) ms_free(content->body); + content->body = ms_strdup(L_STRING_TO_C(L_GET_CPP_PTR_FROM_C_OBJECT(content)->getBodyAsString())); + return content->body; } void linphone_content_set_string_buffer(LinphoneContent *content, const char *buffer) { @@ -99,21 +110,22 @@ void linphone_content_set_string_buffer(LinphoneContent *content, const char *bu size_t linphone_content_get_size(const LinphoneContent *content) { size_t size = L_GET_CPP_PTR_FROM_C_OBJECT(content)->getSize(); if (size == 0) { - size = sal_body_handler_get_size(content->body_handler); + size = content->size; } return size; } void linphone_content_set_size(LinphoneContent *content, size_t size) { - sal_body_handler_set_size(content->body_handler, size); + content->size = size; } const char * linphone_content_get_encoding(const LinphoneContent *content) { - return sal_body_handler_get_encoding(content->body_handler); + return content->encoding; } void linphone_content_set_encoding(LinphoneContent *content, const char *encoding) { - sal_body_handler_set_encoding(content->body_handler, encoding); + if (content->encoding) ms_free(content->encoding); + content->encoding = ms_strdup(encoding); } const char * linphone_content_get_name(const LinphoneContent *content) { @@ -131,6 +143,8 @@ const char * linphone_content_get_name(const LinphoneContent *content) { } void linphone_content_set_name(LinphoneContent *content, const char *name) { + if (content->name) ms_free(content->name); + LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); if (c->isFile()) { LinphonePrivate::FileContent *fc = static_cast(c); @@ -139,38 +153,58 @@ void linphone_content_set_name(LinphoneContent *content, const char *name) { LinphonePrivate::FileTransferContent *ftc = static_cast(c); ftc->setFileName(L_C_TO_STRING(name)); } + content->name = ms_strdup(name); } bool_t linphone_content_is_multipart(const LinphoneContent *content) { - return sal_body_handler_is_multipart(content->body_handler); + SalBodyHandler *body_handler = sal_body_handler_from_content(content); + bool_t multipart = sal_body_handler_is_multipart(body_handler); + sal_body_handler_unref(body_handler); + return multipart; } LinphoneContent * linphone_content_get_part(const LinphoneContent *content, int idx) { SalBodyHandler *part_body_handler; - if (!linphone_content_is_multipart(content)) return NULL; - part_body_handler = sal_body_handler_get_part(content->body_handler, idx); + SalBodyHandler *body_handler = sal_body_handler_from_content(content); + if (!sal_body_handler_is_multipart(body_handler)) { + sal_body_handler_unref(body_handler); + return NULL; + } + part_body_handler = sal_body_handler_get_part(body_handler, idx); + sal_body_handler_unref(body_handler); return linphone_content_from_sal_body_handler(part_body_handler); } LinphoneContent * linphone_content_find_part_by_header(const LinphoneContent *content, const char *header_name, const char *header_value) { SalBodyHandler *part_body_handler; - if (!linphone_content_is_multipart(content)) return NULL; - part_body_handler = sal_body_handler_find_part_by_header(content->body_handler, header_name, header_value); + SalBodyHandler *body_handler = sal_body_handler_from_content(content); + if (!sal_body_handler_is_multipart(body_handler)) { + sal_body_handler_unref(body_handler); + return NULL; + } + part_body_handler = sal_body_handler_find_part_by_header(body_handler, header_name, header_value); + sal_body_handler_unref(body_handler); return linphone_content_from_sal_body_handler(part_body_handler); } const char * linphone_content_get_custom_header(const LinphoneContent *content, const char *header_name) { - return sal_body_handler_get_header(content->body_handler, header_name); + SalBodyHandler *body_handler = sal_body_handler_from_content(content); + const char *header = sal_body_handler_get_header(body_handler, header_name); + sal_body_handler_unref(body_handler); + return header; } const char *linphone_content_get_key(const LinphoneContent *content) { + if (content->key) ms_free(content->key); + const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); if (c->isFileTransfer()) { const LinphonePrivate::FileTransferContent *ftc = static_cast(c); - return ftc->getFileKeyAsString(); + content->key = ms_strdup(ftc->getFileKeyAsString()); } - return NULL; + + return content->key; } size_t linphone_content_get_key_size(const LinphoneContent *content) { @@ -194,24 +228,17 @@ void linphone_content_set_key(LinphoneContent *content, const char *key, const s // Private functions. // ============================================================================= -static void linphone_content_set_sal_body_handler(LinphoneContent *content, SalBodyHandler *body_handler) { - if (content->body_handler != NULL) { - sal_body_handler_unref(content->body_handler); - content->body_handler = NULL; - } - content->body_handler = sal_body_handler_ref(body_handler); -} - static LinphoneContent * linphone_content_new_with_body_handler(SalBodyHandler *body_handler) { LinphoneContent *content = L_INIT(Content); content->cryptoContext = NULL; - if (body_handler == NULL) { - linphone_content_set_sal_body_handler(content, sal_body_handler_new()); - } else { - linphone_content_set_sal_body_handler(content, body_handler); - } LinphonePrivate::Content *c = new LinphonePrivate::Content(); L_SET_CPP_PTR_FROM_C_OBJECT(content, c); + if (body_handler != NULL) { + linphone_content_set_type(content, sal_body_handler_get_type(body_handler)); + linphone_content_set_subtype(content, sal_body_handler_get_subtype(body_handler)); + linphone_content_set_string_buffer(content, (char *)sal_body_handler_get_data(body_handler)); + linphone_content_set_encoding(content, sal_body_handler_get_encoding(body_handler)); + } return content; } @@ -220,7 +247,6 @@ LinphoneContent * linphone_content_new(void) { } LinphoneContent * linphone_content_copy(const LinphoneContent *ref) { - //TODO return (LinphoneContent *)belle_sip_object_ref(belle_sip_object_clone(BELLE_SIP_OBJECT(ref))); } @@ -242,5 +268,11 @@ LinphoneContent * linphone_content_from_sal_body_handler(SalBodyHandler *body_ha SalBodyHandler * sal_body_handler_from_content(const LinphoneContent *content) { if (content == NULL) return NULL; - return content->body_handler; + SalBodyHandler *body_handler = sal_body_handler_new(); + sal_body_handler_set_type(body_handler, belle_sip_strdup(linphone_content_get_type(content))); + sal_body_handler_set_subtype(body_handler, belle_sip_strdup(linphone_content_get_subtype(content))); + sal_body_handler_set_size(body_handler, linphone_content_get_size(content)); + sal_body_handler_set_data(body_handler, belle_sip_strdup(linphone_content_get_string_buffer(content))); + sal_body_handler_set_encoding(body_handler, belle_sip_strdup(linphone_content_get_encoding(content))); + return body_handler; } From 7e92d238a17d9718644ba0803887724737e6777f Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 9 Feb 2018 14:33:39 +0100 Subject: [PATCH 11/17] Fixed for c-content.cpp --- src/c-wrapper/api/c-content.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/c-wrapper/api/c-content.cpp b/src/c-wrapper/api/c-content.cpp index 99318aa23..2cf40c119 100644 --- a/src/c-wrapper/api/c-content.cpp +++ b/src/c-wrapper/api/c-content.cpp @@ -90,7 +90,7 @@ void linphone_content_set_subtype(LinphoneContent *content, const char *subtype) } uint8_t * linphone_content_get_buffer(const LinphoneContent *content) { - return (uint8_t *)L_STRING_TO_C(L_GET_CPP_PTR_FROM_C_OBJECT(content)->getBodyAsString()); + return (uint8_t *)L_GET_CPP_PTR_FROM_C_OBJECT(content)->getBody().data(); } void linphone_content_set_buffer(LinphoneContent *content, const uint8_t *buffer, size_t size) { @@ -99,12 +99,12 @@ void linphone_content_set_buffer(LinphoneContent *content, const uint8_t *buffer const char * linphone_content_get_string_buffer(const LinphoneContent *content) { if (content->body) ms_free(content->body); - content->body = ms_strdup(L_STRING_TO_C(L_GET_CPP_PTR_FROM_C_OBJECT(content)->getBodyAsString())); + content->body = ms_strdup(L_GET_CPP_PTR_FROM_C_OBJECT(content)->getBodyAsUtf8String().c_str()); return content->body; } void linphone_content_set_string_buffer(LinphoneContent *content, const char *buffer) { - L_GET_CPP_PTR_FROM_C_OBJECT(content)->setBody(L_C_TO_STRING(buffer)); + L_GET_CPP_PTR_FROM_C_OBJECT(content)->setBodyFromUtf8(L_C_TO_STRING(buffer)); } size_t linphone_content_get_size(const LinphoneContent *content) { @@ -269,10 +269,10 @@ LinphoneContent * linphone_content_from_sal_body_handler(SalBodyHandler *body_ha SalBodyHandler * sal_body_handler_from_content(const LinphoneContent *content) { if (content == NULL) return NULL; SalBodyHandler *body_handler = sal_body_handler_new(); - sal_body_handler_set_type(body_handler, belle_sip_strdup(linphone_content_get_type(content))); - sal_body_handler_set_subtype(body_handler, belle_sip_strdup(linphone_content_get_subtype(content))); + sal_body_handler_set_type(body_handler, linphone_content_get_type(content)); + sal_body_handler_set_subtype(body_handler, linphone_content_get_subtype(content)); sal_body_handler_set_size(body_handler, linphone_content_get_size(content)); sal_body_handler_set_data(body_handler, belle_sip_strdup(linphone_content_get_string_buffer(content))); - sal_body_handler_set_encoding(body_handler, belle_sip_strdup(linphone_content_get_encoding(content))); + if (content->encoding) sal_body_handler_set_encoding(body_handler, linphone_content_get_encoding(content)); return body_handler; } From ee87c0dcc1d3b02dc1ded5ef646967c75b9743fd Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 9 Feb 2018 16:22:41 +0100 Subject: [PATCH 12/17] Yet another c-content fix --- src/c-wrapper/api/c-content.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/c-wrapper/api/c-content.cpp b/src/c-wrapper/api/c-content.cpp index 2cf40c119..b38f55c12 100644 --- a/src/c-wrapper/api/c-content.cpp +++ b/src/c-wrapper/api/c-content.cpp @@ -172,8 +172,9 @@ LinphoneContent * linphone_content_get_part(const LinphoneContent *content, int return NULL; } part_body_handler = sal_body_handler_get_part(body_handler, idx); + LinphoneContent *result = linphone_content_from_sal_body_handler(part_body_handler); sal_body_handler_unref(body_handler); - return linphone_content_from_sal_body_handler(part_body_handler); + return result; } LinphoneContent * linphone_content_find_part_by_header(const LinphoneContent *content, const char *header_name, const char *header_value) { @@ -184,8 +185,9 @@ LinphoneContent * linphone_content_find_part_by_header(const LinphoneContent *co return NULL; } part_body_handler = sal_body_handler_find_part_by_header(body_handler, header_name, header_value); + LinphoneContent *result = linphone_content_from_sal_body_handler(part_body_handler); sal_body_handler_unref(body_handler); - return linphone_content_from_sal_body_handler(part_body_handler); + return result; } const char * linphone_content_get_custom_header(const LinphoneContent *content, const char *header_name) { @@ -236,8 +238,18 @@ static LinphoneContent * linphone_content_new_with_body_handler(SalBodyHandler * if (body_handler != NULL) { linphone_content_set_type(content, sal_body_handler_get_type(body_handler)); linphone_content_set_subtype(content, sal_body_handler_get_subtype(body_handler)); - linphone_content_set_string_buffer(content, (char *)sal_body_handler_get_data(body_handler)); - linphone_content_set_encoding(content, sal_body_handler_get_encoding(body_handler)); + if (!sal_body_handler_is_multipart(body_handler)) { + linphone_content_set_string_buffer(content, (char *)sal_body_handler_get_data(body_handler)); + } else { + string body; + belle_sip_multipart_body_handler_t *mpbh = BELLE_SIP_MULTIPART_BODY_HANDLER(body_handler); + for (const belle_sip_list_t *parts = belle_sip_multipart_body_handler_get_parts(mpbh); parts; parts = parts->next) { + belle_sip_body_handler_t *part = BELLE_SIP_BODY_HANDLER(parts->data); + body += (const char *)belle_sip_memory_body_handler_get_buffer(BELLE_SIP_MEMORY_BODY_HANDLER(part)); + } + linphone_content_set_string_buffer(content, body.c_str()); + } + if (sal_body_handler_get_encoding(body_handler)) linphone_content_set_encoding(content, sal_body_handler_get_encoding(body_handler)); } return content; } From 9a45223db4493b62b2cf5657b01b344caf9e6e35 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 9 Feb 2018 17:12:28 +0100 Subject: [PATCH 13/17] Use ContentManager in c-content --- src/c-wrapper/api/c-content.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/c-wrapper/api/c-content.cpp b/src/c-wrapper/api/c-content.cpp index b38f55c12..5006d23d9 100644 --- a/src/c-wrapper/api/c-content.cpp +++ b/src/c-wrapper/api/c-content.cpp @@ -24,6 +24,7 @@ #include "content/content.h" #include "content/content-type.h" +#include "content/content-manager.h" #include "content/file-content.h" #include "content/file-transfer-content.h" @@ -158,10 +159,7 @@ void linphone_content_set_name(LinphoneContent *content, const char *name) { } bool_t linphone_content_is_multipart(const LinphoneContent *content) { - SalBodyHandler *body_handler = sal_body_handler_from_content(content); - bool_t multipart = sal_body_handler_is_multipart(body_handler); - sal_body_handler_unref(body_handler); - return multipart; + return L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType() == LinphonePrivate::ContentType::Multipart; } LinphoneContent * linphone_content_get_part(const LinphoneContent *content, int idx) { @@ -241,13 +239,15 @@ static LinphoneContent * linphone_content_new_with_body_handler(SalBodyHandler * if (!sal_body_handler_is_multipart(body_handler)) { linphone_content_set_string_buffer(content, (char *)sal_body_handler_get_data(body_handler)); } else { - string body; belle_sip_multipart_body_handler_t *mpbh = BELLE_SIP_MULTIPART_BODY_HANDLER(body_handler); + list contents; for (const belle_sip_list_t *parts = belle_sip_multipart_body_handler_get_parts(mpbh); parts; parts = parts->next) { belle_sip_body_handler_t *part = BELLE_SIP_BODY_HANDLER(parts->data); - body += (const char *)belle_sip_memory_body_handler_get_buffer(BELLE_SIP_MEMORY_BODY_HANDLER(part)); + LinphoneContent *part_content = linphone_content_new_with_body_handler((SalBodyHandler *)part); + contents.push_back(*L_GET_CPP_PTR_FROM_C_OBJECT(part_content)); } - linphone_content_set_string_buffer(content, body.c_str()); + LinphonePrivate::Content multipartContent = LinphonePrivate::ContentManager::contentListToMultipart(contents); + linphone_content_set_string_buffer(content, multipartContent.getBodyAsUtf8String().c_str()); } if (sal_body_handler_get_encoding(body_handler)) linphone_content_set_encoding(content, sal_body_handler_get_encoding(body_handler)); } From 7a5a78c9b89123c20cefc982a2da0871a33d7d69 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 12 Feb 2018 10:18:45 +0100 Subject: [PATCH 14/17] Fixes for multipart content --- src/c-wrapper/api/c-content.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/c-wrapper/api/c-content.cpp b/src/c-wrapper/api/c-content.cpp index 5006d23d9..8e135ecfa 100644 --- a/src/c-wrapper/api/c-content.cpp +++ b/src/c-wrapper/api/c-content.cpp @@ -280,11 +280,20 @@ LinphoneContent * linphone_content_from_sal_body_handler(SalBodyHandler *body_ha SalBodyHandler * sal_body_handler_from_content(const LinphoneContent *content) { if (content == NULL) return NULL; - SalBodyHandler *body_handler = sal_body_handler_new(); + SalBodyHandler *body_handler; + if (L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType() == LinphonePrivate::ContentType::Multipart) { + size_t size = linphone_content_get_size(content); + char *buffer = ms_strdup(L_GET_CPP_PTR_FROM_C_OBJECT(content)->getBodyAsUtf8String().c_str()); + const char *boundary = L_STRING_TO_C(L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType().getParameter()); + belle_sip_multipart_body_handler_t *bh = belle_sip_multipart_body_handler_new_from_buffer(buffer, size, boundary); + body_handler = (SalBodyHandler *)BELLE_SIP_BODY_HANDLER(bh); + } else { + body_handler = sal_body_handler_new(); + sal_body_handler_set_data(body_handler, belle_sip_strdup(linphone_content_get_string_buffer(content))); + } sal_body_handler_set_type(body_handler, linphone_content_get_type(content)); sal_body_handler_set_subtype(body_handler, linphone_content_get_subtype(content)); sal_body_handler_set_size(body_handler, linphone_content_get_size(content)); - sal_body_handler_set_data(body_handler, belle_sip_strdup(linphone_content_get_string_buffer(content))); if (content->encoding) sal_body_handler_set_encoding(body_handler, linphone_content_get_encoding(content)); return body_handler; } From f58dff4a2fefac0847b613891a32210d4c9d9ca5 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 12 Feb 2018 11:14:41 +0100 Subject: [PATCH 15/17] Fixed linphone_content_get_buffer --- src/c-wrapper/api/c-content.cpp | 2 +- tester/eventapi_tester.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/c-wrapper/api/c-content.cpp b/src/c-wrapper/api/c-content.cpp index 8e135ecfa..211985bbb 100644 --- a/src/c-wrapper/api/c-content.cpp +++ b/src/c-wrapper/api/c-content.cpp @@ -91,7 +91,7 @@ void linphone_content_set_subtype(LinphoneContent *content, const char *subtype) } uint8_t * linphone_content_get_buffer(const LinphoneContent *content) { - return (uint8_t *)L_GET_CPP_PTR_FROM_C_OBJECT(content)->getBody().data(); + return (uint8_t *)linphone_content_get_string_buffer(content); } void linphone_content_set_buffer(LinphoneContent *content, const uint8_t *buffer, size_t size) { diff --git a/tester/eventapi_tester.c b/tester/eventapi_tester.c index 2119f3500..66ae0f165 100644 --- a/tester/eventapi_tester.c +++ b/tester/eventapi_tester.c @@ -41,7 +41,7 @@ void linphone_notify_received(LinphoneCore *lc, LinphoneEvent *lev, const char * if (!BC_ASSERT_PTR_NOT_NULL(content)) return; if (!linphone_content_is_multipart(content) && (!ua || !strstr(ua, "flexisip"))) { /*disable check for full presence server support*/ /*hack to disable content checking for list notify */ - BC_ASSERT_STRING_EQUAL(notify_content,(const char*)linphone_content_get_buffer(content)); + BC_ASSERT_STRING_EQUAL((const char*)linphone_content_get_buffer(content),notify_content); } mgr=get_manager(lc); mgr->stat.number_of_NotifyReceived++; From de6283928d2acea29f5922b9e87c5c6f1d51d815 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 19 Mar 2018 17:26:35 +0100 Subject: [PATCH 16/17] Fixed issue with merge --- src/chat/modifier/file-transfer-chat-message-modifier.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/chat/modifier/file-transfer-chat-message-modifier.cpp b/src/chat/modifier/file-transfer-chat-message-modifier.cpp index fcdf15842..14733e4c8 100644 --- a/src/chat/modifier/file-transfer-chat-message-modifier.cpp +++ b/src/chat/modifier/file-transfer-chat-message-modifier.cpp @@ -298,7 +298,6 @@ void FileTransferChatMessageModifier::processResponseFromPostFile (const belle_h if (body && strlen(body) > 0) { FileTransferContent *fileTransferContent = new FileTransferContent(); fileTransferContent->setContentType(ContentType::FileTransfer); - message->addContent(fileTransferContent); LinphoneImEncryptionEngine *imee = linphone_core_get_im_encryption_engine(message->getCore()->getCCore()); bool_t is_file_encryption_enabled = FALSE; From b248771be135e8cb97431192ae205d2f168517c5 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 19 Mar 2018 17:34:14 +0100 Subject: [PATCH 17/17] Removed content.c as it is not compiled anymore --- coreapi/content.c | 243 ---------------------------------------------- 1 file changed, 243 deletions(-) delete mode 100644 coreapi/content.c diff --git a/coreapi/content.c b/coreapi/content.c deleted file mode 100644 index 8d20964bd..000000000 --- a/coreapi/content.c +++ /dev/null @@ -1,243 +0,0 @@ -/* -linphone -Copyright (C) 2010-2014 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/core.h" - -#include "c-wrapper/c-wrapper.h" - -// TODO: From coreapi. Remove me later. -#include "private.h" - -static void linphone_content_set_sal_body_handler(LinphoneContent *content, SalBodyHandler *body_handler) { - if (content->body_handler != NULL) { - sal_body_handler_unref(content->body_handler); - content->body_handler = NULL; - } - content->body_handler = sal_body_handler_ref(body_handler); -} - -static LinphoneContent * linphone_content_new_with_body_handler(SalBodyHandler *body_handler) { - LinphoneContent *content = belle_sip_object_new(LinphoneContent); - belle_sip_object_ref(content); - content->owned_fields = TRUE; - content->cryptoContext = NULL; /* this field is managed externally by encryption/decryption functions so be careful to initialise it to NULL */ - if (body_handler == NULL) { - linphone_content_set_sal_body_handler(content, sal_body_handler_new()); - } else { - linphone_content_set_sal_body_handler(content, body_handler); - } - return content; -} - -static void linphone_content_destroy(LinphoneContent *content) { - if (content->owned_fields == TRUE) { - if (content->body_handler) sal_body_handler_unref(content->body_handler); - if (content->name) belle_sip_free(content->name); - if (content->key) belle_sip_free(content->key); - /* note : crypto context is allocated/destroyed by the encryption function */ - } -} - -static void linphone_content_clone(LinphoneContent *obj, const LinphoneContent *ref) { - obj->owned_fields = TRUE; - linphone_content_set_sal_body_handler(obj, sal_body_handler_new()); - if ((linphone_content_get_type(ref) != NULL) || (linphone_content_get_subtype(ref) != NULL)) { - linphone_content_set_type(obj, linphone_content_get_type(ref)); - linphone_content_set_subtype(obj, linphone_content_get_subtype(ref)); - } - if (linphone_content_get_encoding(ref) != NULL) { - linphone_content_set_encoding(obj, linphone_content_get_encoding(ref)); - } - linphone_content_set_name(obj, linphone_content_get_name(ref)); - linphone_content_set_key(obj, linphone_content_get_key(ref), linphone_content_get_key_size(ref)); - if (linphone_content_get_buffer(ref) != NULL) { - linphone_content_set_buffer(obj, linphone_content_get_buffer(ref), linphone_content_get_size(ref)); - } else { - linphone_content_set_size(obj, linphone_content_get_size(ref)); - } -} - - -BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneContent); - -BELLE_SIP_INSTANCIATE_VPTR(LinphoneContent, belle_sip_object_t, - (belle_sip_object_destroy_t)linphone_content_destroy, - (belle_sip_object_clone_t)linphone_content_clone, - NULL, // marshal - TRUE -); - - -LinphoneContent * linphone_core_create_content(LinphoneCore *lc) { - return linphone_content_new(); -} - -LinphoneContent * linphone_content_ref(LinphoneContent *content) { - belle_sip_object_ref(content); - return content; -} - -void linphone_content_unref(LinphoneContent *content) { - belle_sip_object_unref(content); -} - -void *linphone_content_get_user_data(const LinphoneContent *content) { - return content->user_data; -} - -void linphone_content_set_user_data(LinphoneContent *content, void *ud) { - content->user_data = ud; -} - -const char * linphone_content_get_type(const LinphoneContent *content) { - return sal_body_handler_get_type(content->body_handler); -} - -void linphone_content_set_type(LinphoneContent *content, const char *type) { - sal_body_handler_set_type(content->body_handler, type); -} - -const char * linphone_content_get_subtype(const LinphoneContent *content) { - return sal_body_handler_get_subtype(content->body_handler); -} - -void linphone_content_set_subtype(LinphoneContent *content, const char *subtype) { - sal_body_handler_set_subtype(content->body_handler, subtype); -} - -uint8_t * linphone_content_get_buffer(const LinphoneContent *content) { - return (uint8_t *)sal_body_handler_get_data(content->body_handler); -} - -void linphone_content_set_buffer(LinphoneContent *content, const uint8_t *buffer, size_t size) { - void *data; - sal_body_handler_set_size(content->body_handler, size); - data = belle_sip_malloc(size + 1); - memcpy(data, buffer, size); - ((char *)data)[size] = '\0'; - sal_body_handler_set_data(content->body_handler, data); -} - -const char * linphone_content_get_string_buffer(const LinphoneContent *content) { - return (const char *)linphone_content_get_buffer(content); -} - -void linphone_content_set_string_buffer(LinphoneContent *content, const char *buffer) { - sal_body_handler_set_size(content->body_handler, strlen(buffer)); - sal_body_handler_set_data(content->body_handler, belle_sip_strdup(buffer)); -} - -size_t linphone_content_get_size(const LinphoneContent *content) { - return sal_body_handler_get_size(content->body_handler); -} - -void linphone_content_set_size(LinphoneContent *content, size_t size) { - sal_body_handler_set_size(content->body_handler, size); -} - -const char * linphone_content_get_encoding(const LinphoneContent *content) { - return sal_body_handler_get_encoding(content->body_handler); -} - -void linphone_content_set_encoding(LinphoneContent *content, const char *encoding) { - sal_body_handler_set_encoding(content->body_handler, encoding); -} - -const char * linphone_content_get_name(const LinphoneContent *content) { - return content->name; -} - -void linphone_content_set_name(LinphoneContent *content, const char *name) { - if (content->name != NULL) { - belle_sip_free(content->name); - content->name = NULL; - } - if (name != NULL) { - content->name = belle_sip_strdup(name); - } -} - -size_t linphone_content_get_key_size(const LinphoneContent *content) { - return content->keyLength; -} - -const char * linphone_content_get_key(const LinphoneContent *content) { - return content->key; -} - -void linphone_content_set_key(LinphoneContent *content, const char *key, const size_t keyLength) { - if (content->key != NULL) { - belle_sip_free(content->key); - content->key = NULL; - } - if (key != NULL) { - content->key = reinterpret_cast(belle_sip_malloc(keyLength + 1)); - memcpy(content->key, key, keyLength); - content->key[keyLength] = '\0'; - content->keyLength = keyLength; - } -} - -/* crypto context is managed(allocated/freed) by the encryption function, so provide the address of field in the private structure */ -void ** linphone_content_get_cryptoContext_address(LinphoneContent *content) { - return &(content->cryptoContext); -} - -bool_t linphone_content_is_multipart(const LinphoneContent *content) { - return sal_body_handler_is_multipart(content->body_handler); -} - -LinphoneContent * linphone_content_get_part(const LinphoneContent *content, int idx) { - SalBodyHandler *part_body_handler; - if (!linphone_content_is_multipart(content)) return NULL; - part_body_handler = sal_body_handler_get_part(content->body_handler, idx); - return linphone_content_from_sal_body_handler(part_body_handler); -} - -LinphoneContent * linphone_content_find_part_by_header(const LinphoneContent *content, const char *header_name, const char *header_value) { - SalBodyHandler *part_body_handler; - if (!linphone_content_is_multipart(content)) return NULL; - part_body_handler = sal_body_handler_find_part_by_header(content->body_handler, header_name, header_value); - return linphone_content_from_sal_body_handler(part_body_handler); -} - -const char * linphone_content_get_custom_header(const LinphoneContent *content, const char *header_name) { - return sal_body_handler_get_header(content->body_handler, header_name); -} - - -LinphoneContent * linphone_content_new(void) { - return linphone_content_new_with_body_handler(NULL); -} - -LinphoneContent * linphone_content_copy(const LinphoneContent *ref) { - return (LinphoneContent *)belle_sip_object_ref(belle_sip_object_clone(BELLE_SIP_OBJECT(ref))); -} - -LinphoneContent * linphone_content_from_sal_body_handler(SalBodyHandler *body_handler) { - if (body_handler) { - return linphone_content_new_with_body_handler(body_handler); - } - return NULL; -} - -SalBodyHandler * sal_body_handler_from_content(const LinphoneContent *content) { - if (content == NULL) return NULL; - return content->body_handler; -}