Merge remote-tracking branch 'origin/dev_content_cpp' into dev_chatroom_list_subscription

This commit is contained in:
Benjamin Reis 2018-03-20 15:02:18 +01:00
commit 177dd8778c
46 changed files with 516 additions and 459 deletions

View file

@ -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

View file

@ -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 \

View file

@ -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"

View file

@ -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<char *>(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;
}

View file

@ -19,6 +19,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <bctoolbox/crypto.h>
#include "linphone/api/c-content.h"
#include "linphone/core.h"
#include "c-wrapper/c-wrapper.h"

View file

@ -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"

View file

@ -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"
@ -419,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);
@ -787,8 +791,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;
@ -893,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;

View file

@ -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"

View file

@ -449,17 +449,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 {

View file

@ -25,6 +25,7 @@ Copyright (C) 2000 Simon MORLAT (simon.morlat@linphone.org)
#include "linphone/core.h"
#include "linphone/lpconfig.h"
#include "linphone/sipsetup.h"
#include "mediastreamer2/mediastream.h"
#include "enum.h"

View file

@ -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"

View file

@ -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-magic-search.h

View file

@ -14,7 +14,6 @@ linphone_include_HEADERS=\
chat.h \
conference.h \
contactprovider.h \
content.h \
core.h \
core_utils.h \
defs.h \

View file

@ -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"

View file

@ -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

View file

@ -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_

View file

@ -162,6 +162,12 @@ typedef struct _LinphoneMagicSearch LinphoneMagicSearch;
**/
typedef struct _LinphoneParticipant LinphoneParticipant;
/**
* The LinphoneContent object holds data that can be embedded in a signaling message.
* @ingroup misc
**/
typedef struct _LinphoneContent LinphoneContent;
/**
* The LinphoneSearchResult object represents a result of a search
* @ingroup misc

View file

@ -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"

View file

@ -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

View file

@ -176,6 +176,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-magic-search.cpp

View file

@ -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"
@ -227,7 +228,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) {
@ -289,7 +290,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 linphone_content_ref(L_GET_C_BACK_PTR(content));
return NULL;
}
// =============================================================================

View file

@ -355,8 +355,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<LinphonePrivate::ChatMessage> 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<LinphonePrivate::ChatMessage> 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;

View file

@ -0,0 +1,299 @@
/*
* 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"
#include "content/content-type.h"
#include "content/content-manager.h"
#include "content/file-content.h"
#include "content/file-transfer-content.h"
// =============================================================================
using namespace std;
L_DECLARE_C_CLONABLE_OBJECT_IMPL(Content,
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;
)
// =============================================================================
// 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) {
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) {
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) {
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) {
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 (uint8_t *)linphone_content_get_string_buffer(content);
}
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) {
if (content->body) ms_free(content->body);
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)->setBodyFromUtf8(L_C_TO_STRING(buffer));
}
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 = content->size;
}
return size;
}
void linphone_content_set_size(LinphoneContent *content, size_t size) {
content->size = size;
}
const char * linphone_content_get_encoding(const LinphoneContent *content) {
return content->encoding;
}
void linphone_content_set_encoding(LinphoneContent *content, const char *encoding) {
if (content->encoding) ms_free(content->encoding);
content->encoding = ms_strdup(encoding);
}
const char * linphone_content_get_name(const LinphoneContent *content) {
const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content);
if (c->isFile()) {
const LinphonePrivate::FileContent *fc = static_cast<const LinphonePrivate::FileContent *>(c);
if (content->name) ms_free(content->name);
content->name = ms_strdup(L_STRING_TO_C(fc->getFileName()));
} else if (c->isFileTransfer()) {
const LinphonePrivate::FileTransferContent *ftc = static_cast<const LinphonePrivate::FileTransferContent *>(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) {
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<LinphonePrivate::FileContent *>(c);
fc->setFileName(L_C_TO_STRING(name));
} else if (c->isFileTransfer()) {
LinphonePrivate::FileTransferContent *ftc = static_cast<LinphonePrivate::FileTransferContent *>(c);
ftc->setFileName(L_C_TO_STRING(name));
}
content->name = ms_strdup(name);
}
bool_t linphone_content_is_multipart(const LinphoneContent *content) {
return L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType() == LinphonePrivate::ContentType::Multipart;
}
LinphoneContent * linphone_content_get_part(const LinphoneContent *content, int idx) {
SalBodyHandler *part_body_handler;
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);
LinphoneContent *result = linphone_content_from_sal_body_handler(part_body_handler);
sal_body_handler_unref(body_handler);
return result;
}
LinphoneContent * linphone_content_find_part_by_header(const LinphoneContent *content, const char *header_name, const char *header_value) {
SalBodyHandler *part_body_handler;
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);
LinphoneContent *result = linphone_content_from_sal_body_handler(part_body_handler);
sal_body_handler_unref(body_handler);
return result;
}
const char * linphone_content_get_custom_header(const LinphoneContent *content, const char *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<const LinphonePrivate::FileTransferContent *>(c);
content->key = ms_strdup(ftc->getFileKeyAsString());
}
return content->key;
}
size_t linphone_content_get_key_size(const LinphoneContent *content) {
const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content);
if (c->isFileTransfer()) {
const LinphonePrivate::FileTransferContent *ftc = static_cast<const LinphonePrivate::FileTransferContent *>(c);
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->isFileTransfer()) {
LinphonePrivate::FileTransferContent *ftc = static_cast<LinphonePrivate::FileTransferContent *>(c);
ftc->setFileKey(key, keyLength);
}
}
// =============================================================================
// Private functions.
// =============================================================================
static LinphoneContent * linphone_content_new_with_body_handler(SalBodyHandler *body_handler) {
LinphoneContent *content = L_INIT(Content);
content->cryptoContext = NULL;
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));
if (!sal_body_handler_is_multipart(body_handler)) {
linphone_content_set_string_buffer(content, (char *)sal_body_handler_get_data(body_handler));
} else {
belle_sip_multipart_body_handler_t *mpbh = BELLE_SIP_MULTIPART_BODY_HANDLER(body_handler);
list<LinphonePrivate::Content> 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);
LinphoneContent *part_content = linphone_content_new_with_body_handler((SalBodyHandler *)part);
contents.push_back(*L_GET_CPP_PTR_FROM_C_OBJECT(part_content));
}
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));
}
return content;
}
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_core_create_content(LinphoneCore *lc) {
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);
}
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;
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));
if (content->encoding) sal_body_handler_set_encoding(body_handler, linphone_content_get_encoding(content));
return body_handler;
}

View file

@ -37,6 +37,7 @@
F(ChatMessage, ChatMessage) \
F(AbstractChatRoom, ChatRoom) \
F(Core, Core) \
F(Content, Content) \
F(DialPlan, DialPlan) \
F(EventLog, EventLog) \
F(MagicSearch, MagicSearch) \
@ -85,7 +86,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),

View file

@ -136,11 +136,11 @@ public:
bool hasFileTransferContent () const;
const Content* getFileTransferContent () const;
LinphoneContent *getFileTransferInformation () const;
void setFileTransferInformation (const LinphoneContent *content);
const Content* getFileTransferInformation () const;
void setFileTransferInformation (Content *content);
void addContent (Content &content);
void removeContent (const Content &content);
void addContent (Content *content);
void removeContent (Content *content);
bool downloadFile ();

View file

@ -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"
@ -215,8 +216,8 @@ const Content* ChatMessagePrivate::getTextContent() const {
}
bool ChatMessagePrivate::hasFileTransferContent() const {
for (const Content *c : getContents()) {
if (c->getContentType() == ContentType::FileTransfer) {
for (const Content *c : contents) {
if (c->isFileTransfer()) {
return true;
}
}
@ -224,8 +225,8 @@ bool ChatMessagePrivate::hasFileTransferContent() const {
}
const Content* ChatMessagePrivate::getFileTransferContent() const {
for (const Content *c : getContents()) {
if (c->getContentType() == ContentType::FileTransfer) {
for (const Content *c : contents) {
if (c->isFileTransfer()) {
return c;
}
}
@ -350,51 +351,54 @@ 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 : getContents()) {
if (c->isFile()) {
FileContent *fileContent = (FileContent *)c;
return fileContent->toLinphoneContent();
return fileContent;
}
}
return nullptr;
}
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)) {
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 () {
L_Q();
for (auto &content : getContents())
if (content->getContentType() == ContentType::FileTransfer)
return q->downloadFile(*static_cast<FileTransferContent *>(content));
if (content->isFileTransfer())
return q->downloadFile(static_cast<FileTransferContent *>(content));
return false;
}
void ChatMessagePrivate::addContent (Content &content) {
getContents().push_back(&content);
void ChatMessagePrivate::addContent (Content *content) {
getContents().push_back(content);
}
void ChatMessagePrivate::removeContent (const Content &content) {
getContents().remove(&const_cast<Content &>(content));
void ChatMessagePrivate::removeContent (Content *content) {
getContents().remove(content);
}
void ChatMessagePrivate::loadFileTransferUrlFromBodyToContent() {
@ -429,7 +433,7 @@ void ChatMessagePrivate::sendImdn (Imdn::Type imdnType, LinphoneReason reason) {
Content *content = new Content();
content->setContentType(ContentType::Imdn);
content->setBody(Imdn::createXml(imdnId, time, imdnType, reason));
msg->addContent(*content);
msg->addContent(content);
if (reason != LinphoneReasonNone)
msg->getPrivate()->setEncryptionPrevented(true);
@ -749,10 +753,10 @@ void ChatMessagePrivate::send () {
list<Content*>::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<FileTransferContent *>(content);
it = contents.erase(it);
addContent(*fileTransferContent->getFileContent());
addContent(fileTransferContent->getFileContent());
delete fileTransferContent;
} else {
it++;
@ -990,13 +994,13 @@ const list<Content *> &ChatMessage::getContents () const {
return d->getContents();
}
void ChatMessage::addContent (Content &content) {
void ChatMessage::addContent (Content *content) {
L_D();
if (!d->isReadOnly)
d->addContent(content);
}
void ChatMessage::removeContent (const Content &content) {
void ChatMessage::removeContent (Content *content) {
L_D();
if (!d->isReadOnly)
d->removeContent(content);
@ -1066,9 +1070,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);
}
bool ChatMessage::isFileTransferInProgress() {

View file

@ -94,8 +94,8 @@ public:
void setToBeStored (bool value);
const std::list<Content *> &getContents () const;
void addContent (Content &content);
void removeContent (const Content &content);
void addContent (Content *content);
void removeContent (Content *content);
const Content &getInternalContent () const;
void setInternalContent (const Content &content);
@ -105,7 +105,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);
bool isFileTransferInProgress();
private:

View file

@ -89,8 +89,7 @@ public:
virtual std::shared_ptr<ChatMessage> createChatMessage () = 0;
virtual std::shared_ptr<ChatMessage> createChatMessage (const std::string &text) = 0;
// TODO: Remove LinphoneContent by LinphonePrivate::Content.
virtual std::shared_ptr<ChatMessage> createFileTransferMessage (const LinphoneContent *initialContent) = 0;
virtual std::shared_ptr<ChatMessage> createFileTransferMessage (Content *initialContent) = 0;
virtual std::shared_ptr<ChatMessage> findChatMessage (const std::string &messageId) const = 0;
virtual std::shared_ptr<ChatMessage> findChatMessage (

View file

@ -86,7 +86,7 @@ void ChatRoomPrivate::sendIsComposingNotification () {
shared_ptr<ChatMessage> chatMessage = createChatMessage(ChatMessage::Direction::Outgoing);
chatMessage->setToBeStored(false);
chatMessage->addContent(*content);
chatMessage->addContent(content);
chatMessage->getPrivate()->addSalCustomHeader(PriorityHeader::HeaderName, PriorityHeader::NonUrgent);
chatMessage->getPrivate()->addSalCustomHeader("Expires", "0");
@ -414,11 +414,11 @@ shared_ptr<ChatMessage> ChatRoom::createChatMessage (const string &text) {
Content *content = new Content();
content->setContentType(ContentType::PlainText);
content->setBody(text);
chatMessage->addContent(*content);
chatMessage->addContent(content);
return chatMessage;
}
shared_ptr<ChatMessage> ChatRoom::createFileTransferMessage (const LinphoneContent *initialContent) {
shared_ptr<ChatMessage> ChatRoom::createFileTransferMessage (Content *initialContent) {
shared_ptr<ChatMessage> chatMessage = createChatMessage();
chatMessage->getPrivate()->setFileTransferInformation(initialContent);
return chatMessage;

View file

@ -65,8 +65,7 @@ public:
std::shared_ptr<ChatMessage> createChatMessage () override;
std::shared_ptr<ChatMessage> createChatMessage (const std::string &text) override;
// TODO: Remove LinphoneContent by LinphonePrivate::Content.
std::shared_ptr<ChatMessage> createFileTransferMessage (const LinphoneContent *initialContent) override;
std::shared_ptr<ChatMessage> createFileTransferMessage (Content *initialContent) override;
std::shared_ptr<ChatMessage> findChatMessage (const std::string &messageId) const override;
std::shared_ptr<ChatMessage> findChatMessage (

View file

@ -173,7 +173,7 @@ shared_ptr<ChatMessage> ProxyChatRoom::createChatMessage (const string &text) {
return d->chatRoom->createChatMessage(text);
}
shared_ptr<ChatMessage> ProxyChatRoom::createFileTransferMessage (const LinphoneContent *initialContent) {
shared_ptr<ChatMessage> ProxyChatRoom::createFileTransferMessage (Content *initialContent) {
L_D();
return d->chatRoom->createFileTransferMessage(initialContent);
}

View file

@ -66,8 +66,7 @@ public:
std::shared_ptr<ChatMessage> createChatMessage () override;
std::shared_ptr<ChatMessage> createChatMessage (const std::string &text) override;
// TODO: Remove LinphoneContent by LinphonePrivate::Content.
std::shared_ptr<ChatMessage> createFileTransferMessage (const LinphoneContent *initialContent) override;
std::shared_ptr<ChatMessage> createFileTransferMessage (Content *initialContent) override;
std::shared_ptr<ChatMessage> findChatMessage (const std::string &messageId) const override;
std::shared_ptr<ChatMessage> findChatMessage (

View file

@ -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"
@ -107,7 +109,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 {
@ -157,7 +159,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) {
@ -253,12 +255,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
@ -301,9 +297,31 @@ 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);
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);
@ -316,16 +334,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
@ -361,11 +378,10 @@ void FileTransferChatMessageModifier::processResponseFromPostFile (const belle_h
}
FileContent *fileContent = currentFileContentToTransfer;
fileTransferContent->setContentType(ContentType::FileTransfer);
fileTransferContent->setFileContent(fileContent);
message->getPrivate()->removeContent(*fileContent);
message->getPrivate()->addContent(*fileTransferContent);
message->getPrivate()->removeContent(fileContent);
message->getPrivate()->addContent(fileTransferContent);
message->getPrivate()->setState(ChatMessage::State::FileTransferDone);
releaseHttpRequest();
@ -559,13 +575,13 @@ 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;
}
for (Content *content : message->getContents()) {
if (content->getContentType() == ContentType::FileTransfer) {
FileTransferContent *fileTransferContent = (FileTransferContent *)content;
if (content->isFileTransfer()) {
FileTransferContent *fileTransferContent = static_cast<FileTransferContent *>(content);
fillFileTransferContentInformationsFromVndGsmaRcsFtHttpXml(fileTransferContent);
}
}
@ -634,8 +650,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);
@ -699,7 +714,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);
@ -708,7 +723,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;
@ -740,7 +754,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);
@ -756,12 +770,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->getPrivate()->addContent(*fileContent);
message->getPrivate()->addContent(fileContent);
for (Content *content : message->getContents()) {
if (content->getContentType() == ContentType::FileTransfer) {
FileTransferContent *fileTransferContent = (FileTransferContent*)content;
if (content->isFileTransfer()) {
FileTransferContent *fileTransferContent = static_cast<FileTransferContent *>(content);
if (fileTransferContent->getFileContent() == fileContent) {
message->getPrivate()->removeContent(*content);
message->getPrivate()->removeContent(content);
delete fileTransferContent;
break;
}
@ -814,7 +828,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;

View file

@ -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();
}

View file

@ -19,6 +19,7 @@
#include <ctime>
#include "linphone/api/c-content.h"
#include "linphone/utils/utils.h"
#include "conference/local-conference.h"

View file

@ -19,19 +19,18 @@
#include <bctoolbox/defs.h>
#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;

View file

@ -198,6 +198,10 @@ bool Content::isFile () const {
return false;
}
bool Content::isFileTransfer () const {
return false;
}
void Content::addHeader (const string &headerName, const string &headerValue) {
L_D();
removeHeader(headerName);
@ -225,18 +229,4 @@ const string &Content::getHeaderValue (const string &headerName) const {
return Utils::getEmptyConstRefObject<string>();
}
LinphoneContent *Content::toLinphoneContent () const {
LinphoneContent *content = linphone_core_create_content(nullptr);
linphone_content_set_type(content, getContentType().getType().c_str());
string subtype;
string parameter = getContentType().getParameter();
subtype = (parameter.empty())
? getContentType().getSubType()
: getContentType().getSubType() + ";" + parameter;
linphone_content_set_subtype(content, subtype.c_str());
linphone_content_set_buffer(content, (const uint8_t *)getBodyAsUtf8String().c_str(), getBodyAsUtf8String().size());
return content;
}
LINPHONE_END_NAMESPACE

View file

@ -74,15 +74,13 @@ public:
bool isEmpty () const;
virtual bool isFile () const;
virtual bool isFileTransfer () const;
const std::list<std::pair<std::string, std::string>> &getHeaders () const;
void addHeader (const std::string &headerName, const std::string &headerValue);
void removeHeader (const std::string &headerName);
const std::string &getHeaderValue (const std::string &headerName) const;
// TODO: Remove me later.
virtual LinphoneContent *toLinphoneContent () const;
protected:
explicit Content (ContentPrivate &p);

View file

@ -36,7 +36,6 @@ public:
string fileName;
string filePath;
size_t fileSize = 0;
string fileKey;
};
// -----------------------------------------------------------------------------
@ -48,7 +47,6 @@ FileContent::FileContent (const FileContent &other) : Content(*new FileContentPr
d->fileName = other.getFileName();
d->filePath = other.getFilePath();
d->fileSize = other.getFileSize();
d->fileKey = other.getFileKey();
}
FileContent::FileContent (FileContent &&other) : Content(*new FileContentPrivate) {
@ -56,18 +54,14 @@ FileContent::FileContent (FileContent &&other) : Content(*new FileContentPrivate
d->fileName = move(other.getPrivate()->fileName);
d->filePath = move(other.getPrivate()->filePath);
d->fileSize = move(other.getPrivate()->fileSize);
d->fileKey = move(other.getPrivate()->fileKey);
}
FileContent &FileContent::operator= (const FileContent &other) {
L_D();
if (this != &other) {
Content::operator=(other);
d->fileName = other.getFileName();
d->filePath = other.getFilePath();
d->fileSize = other.getFileSize();
d->fileKey = other.getFileKey();
}
return *this;
}
@ -78,7 +72,6 @@ FileContent &FileContent::operator= (FileContent &&other) {
d->fileName = move(other.getPrivate()->fileName);
d->filePath = move(other.getPrivate()->filePath);
d->fileSize = move(other.getPrivate()->fileSize);
d->fileKey = move(other.getPrivate()->fileKey);
return *this;
}
@ -87,8 +80,7 @@ bool FileContent::operator== (const FileContent &other) const {
return Content::operator==(other) &&
d->fileName == other.getFileName() &&
d->filePath == other.getFilePath() &&
d->fileSize == other.getFileSize() &&
d->fileKey == other.getFileKey();
d->fileSize == other.getFileSize();
}
void FileContent::setFileSize (size_t size) {
@ -121,28 +113,12 @@ 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;
}
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;
bool FileContent::isFileTransfer () const {
return false;
}
LINPHONE_END_NAMESPACE

View file

@ -48,13 +48,8 @@ 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;
// TODO: Remove me later.
LinphoneContent *toLinphoneContent () const override;
bool isFileTransfer () const override;
private:
L_DECLARE_PRIVATE(FileContent);

View file

@ -38,6 +38,7 @@ public:
string filePath;
FileContent *fileContent = nullptr;
size_t fileSize = 0;
std::vector<char> fileKey;
};
// -----------------------------------------------------------------------------
@ -51,6 +52,7 @@ FileTransferContent::FileTransferContent (const FileTransferContent &other) : Co
d->filePath = other.getFilePath();
d->fileContent = other.getFileContent();
d->fileSize = other.getFileSize();
d->fileKey = other.getFileKey();
}
FileTransferContent::FileTransferContent (FileTransferContent &&other) : Content(*new FileTransferContentPrivate) {
@ -60,6 +62,7 @@ FileTransferContent::FileTransferContent (FileTransferContent &&other) : Content
d->filePath = move(other.getPrivate()->filePath);
d->fileContent = move(other.getPrivate()->fileContent);
d->fileSize = move(other.getPrivate()->fileSize);
d->fileKey = move(other.getPrivate()->fileKey);
}
FileTransferContent &FileTransferContent::operator= (const FileTransferContent &other) {
@ -71,6 +74,7 @@ FileTransferContent &FileTransferContent::operator= (const FileTransferContent &
d->filePath = other.getFilePath();
d->fileContent = other.getFileContent();
d->fileSize = other.getFileSize();
d->fileKey = other.getFileKey();
}
return *this;
@ -84,6 +88,8 @@ FileTransferContent &FileTransferContent::operator= (FileTransferContent &&other
d->filePath = move(other.getPrivate()->filePath);
d->fileContent = move(other.getPrivate()->fileContent);
d->fileSize = move(other.getPrivate()->fileSize);
d->fileKey = move(other.getPrivate()->fileKey);
return *this;
}
@ -146,17 +152,32 @@ 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;
void FileTransferContent::setFileKey (const char *key, size_t size) {
L_D();
d->fileKey = vector<char>(key, key + size);
}
const vector<char> &FileTransferContent::getFileKey () const {
L_D();
return d->fileKey;
}
const char *FileTransferContent::getFileKeyAsString() const {
L_D();
return d->fileKey.data();
}
size_t FileTransferContent::getFileKeySize() const {
L_D();
return d->fileKey.size();
}
bool FileTransferContent::isFile () const {
return false;
}
bool FileTransferContent::isFileTransfer () const {
return true;
}
LINPHONE_END_NAMESPACE

View file

@ -20,6 +20,8 @@
#ifndef _L_FILE_TRANSFER_CONTENT_H_
#define _L_FILE_TRANSFER_CONTENT_H_
#include <vector>
#include "content.h"
// =============================================================================
@ -55,10 +57,13 @@ public:
void setFileSize (size_t size);
size_t getFileSize () const;
bool isFile () const override;
void setFileKey (const char *key, size_t size);
const std::vector<char> &getFileKey () const;
const char *getFileKeyAsString () const;
size_t getFileKeySize() const;
// TODO: Remove me later.
LinphoneContent *toLinphoneContent () const override;
bool isFile () const override;
bool isFileTransfer () const override;
private:
L_DECLARE_PRIVATE(FileTransferContent);

View file

@ -2203,7 +2203,7 @@ void MainDb::loadChatMessageContents (const shared_ptr<ChatMessage> &chatMessage
string data;
fetchContentAppData(session, *content, contentId, data);
}
chatMessage->addContent(*content);
chatMessage->addContent(content);
}
// 2 - Load external body url from body into FileTransferContent if needed.

View file

@ -423,7 +423,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();

View file

@ -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++;

View file

@ -53,13 +53,13 @@ static void chat_message_multipart_modifier_base(bool first_file_transfer, bool
content->setContentType(ContentType("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(ContentType("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");