forked from mirrors/linphone-iphone
Revert "Merge branch 'dev_content_cpp' into dev_refactor_cpp"
This reverts commitd7890dbe74, reversing changes made toe6158d8da5.
This commit is contained in:
parent
3761d1a5d9
commit
2686dca63a
67 changed files with 687 additions and 1411 deletions
|
|
@ -64,6 +64,7 @@ set(LINPHONE_SOURCE_FILES_C
|
|||
carddav.c
|
||||
chat.c
|
||||
contactprovider.c
|
||||
content.c
|
||||
dial_plan.c
|
||||
dict.c
|
||||
ec-calibrator.c
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ 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 \
|
||||
|
|
|
|||
|
|
@ -348,29 +348,6 @@ void sal_body_handler_set_subtype(SalBodyHandler *body_handler, const char *subt
|
|||
belle_sip_header_content_type_set_subtype(content_type, subtype);
|
||||
}
|
||||
|
||||
const belle_sip_list_t * sal_body_handler_get_content_type_parameters_names(const SalBodyHandler *body_handler) {
|
||||
belle_sip_header_content_type_t *content_type = BELLE_SIP_HEADER_CONTENT_TYPE(sal_body_handler_find_header(body_handler, "Content-Type"));
|
||||
if (content_type != NULL) {
|
||||
return belle_sip_parameters_get_parameter_names(BELLE_SIP_PARAMETERS(content_type));
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char * sal_body_handler_get_content_type_parameter(const SalBodyHandler *body_handler, const char *name) {
|
||||
belle_sip_header_content_type_t *content_type = BELLE_SIP_HEADER_CONTENT_TYPE(sal_body_handler_find_header(body_handler, "Content-Type"));
|
||||
if (content_type != NULL) {
|
||||
return belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(content_type), name);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void sal_body_handler_set_content_type_parameter(SalBodyHandler *body_handler, const char *paramName, const char *paramValue) {
|
||||
belle_sip_header_content_type_t *content_type = BELLE_SIP_HEADER_CONTENT_TYPE(sal_body_handler_find_header(body_handler, "Content-Type"));
|
||||
if (content_type != NULL) {
|
||||
belle_sip_parameters_set_parameter(BELLE_SIP_PARAMETERS(content_type), paramName, paramValue);
|
||||
}
|
||||
}
|
||||
|
||||
const char * sal_body_handler_get_encoding(const SalBodyHandler *body_handler) {
|
||||
belle_sip_header_t *content_encoding = sal_body_handler_find_header(body_handler, "Content-Encoding");
|
||||
if (content_encoding != NULL) {
|
||||
|
|
@ -419,11 +396,6 @@ SalBodyHandler * sal_body_handler_get_part(const SalBodyHandler *body_handler, i
|
|||
return (SalBodyHandler *)belle_sip_list_nth_data(l, idx);
|
||||
}
|
||||
|
||||
const belle_sip_list_t * sal_body_handler_get_parts(const SalBodyHandler *body_handler) {
|
||||
if (!sal_body_handler_is_multipart(body_handler)) return NULL;
|
||||
return belle_sip_multipart_body_handler_get_parts(BELLE_SIP_MULTIPART_BODY_HANDLER(body_handler));
|
||||
}
|
||||
|
||||
SalBodyHandler * sal_body_handler_find_part_by_header(const SalBodyHandler *body_handler, const char *header_name, const char *header_value) {
|
||||
const belle_sip_list_t *l = belle_sip_multipart_body_handler_get_parts(BELLE_SIP_MULTIPART_BODY_HANDLER(body_handler));
|
||||
for (; l != NULL; l = l->next) {
|
||||
|
|
@ -446,7 +418,3 @@ const char * sal_body_handler_get_header(const SalBodyHandler *body_handler, con
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const belle_sip_list_t* sal_body_handler_get_headers(const SalBodyHandler *body_handler) {
|
||||
return belle_sip_body_handler_get_headers(BELLE_SIP_BODY_HANDLER(body_handler));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,15 +17,14 @@ 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"
|
||||
|
|
|
|||
243
coreapi/content.c
Normal file
243
coreapi/content.c
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
/*
|
||||
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;
|
||||
}
|
||||
|
|
@ -19,7 +19,6 @@ 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"
|
||||
|
|
@ -962,7 +961,7 @@ void linphone_friend_list_notify_presence_received(LinphoneFriendList *list, Lin
|
|||
const char *subtype = linphone_content_get_subtype(body);
|
||||
|
||||
if ((strcmp(type, "multipart") != 0) || (strcmp(subtype, "related") != 0)) {
|
||||
ms_warning("multipart presence notified but it is not 'multipart/related', instead is '%s/%s'", type, subtype);
|
||||
ms_warning("multipart presence notified but it is not 'multipart/related'");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@
|
|||
* 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"
|
||||
|
||||
|
|
|
|||
|
|
@ -17,8 +17,6 @@ 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"
|
||||
|
|
@ -421,8 +419,6 @@ 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);
|
||||
|
|
@ -791,8 +787,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;
|
||||
|
|
@ -897,7 +893,6 @@ 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;
|
||||
|
|
|
|||
|
|
@ -18,12 +18,10 @@ 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/logging.h"
|
||||
#include "linphone/sipsetup.h"
|
||||
|
||||
#include "private.h"
|
||||
#include "logging-private.h"
|
||||
#include "quality_reporting.h"
|
||||
|
|
|
|||
|
|
@ -449,6 +449,17 @@ 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 {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ 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"
|
||||
|
|
|
|||
|
|
@ -21,9 +21,7 @@ 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"
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ set(ROOT_HEADER_FILES
|
|||
chat.h
|
||||
conference.h
|
||||
contactprovider.h
|
||||
content.h
|
||||
core_utils.h
|
||||
core.h
|
||||
defs.h
|
||||
|
|
@ -84,7 +85,6 @@ 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
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ linphone_include_HEADERS=\
|
|||
chat.h \
|
||||
conference.h \
|
||||
contactprovider.h \
|
||||
content.h \
|
||||
core.h \
|
||||
core_utils.h \
|
||||
defs.h \
|
||||
|
|
|
|||
|
|
@ -23,15 +23,14 @@
|
|||
#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-cbs.h"
|
||||
#include "linphone/api/c-chat-message.h"
|
||||
#include "linphone/api/c-chat-room-cbs.h"
|
||||
#include "linphone/api/c-chat-message-cbs.h"
|
||||
#include "linphone/api/c-chat-room.h"
|
||||
#include "linphone/api/c-content.h"
|
||||
#include "linphone/api/c-chat-room-cbs.h"
|
||||
#include "linphone/api/c-dial-plan.h"
|
||||
#include "linphone/api/c-event-log.h"
|
||||
#include "linphone/api/c-participant.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, LinphoneContent* initial_content);
|
||||
LINPHONE_PUBLIC LinphoneChatMessage* linphone_chat_room_create_file_transfer_message(LinphoneChatRoom *cr, const LinphoneContent* initial_content);
|
||||
|
||||
/**
|
||||
* get peer address \link linphone_core_get_chat_room() associated to \endlink this #LinphoneChatRoom
|
||||
|
|
|
|||
|
|
@ -162,12 +162,6 @@ 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
|
||||
|
|
|
|||
|
|
@ -1,32 +1,33 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
content.h
|
||||
Copyright (C) 2010-2014 Belledonne Communications SARL
|
||||
|
||||
#ifndef _L_C_CONTENT_H_
|
||||
#define _L_C_CONTENT_H_
|
||||
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.
|
||||
|
||||
#include "linphone/api/c-types.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"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @addtogroup misc
|
||||
|
|
@ -88,14 +89,6 @@ LINPHONE_PUBLIC const char * linphone_content_get_subtype(const LinphoneContent
|
|||
*/
|
||||
LINPHONE_PUBLIC void linphone_content_set_subtype(LinphoneContent *content, const char *subtype);
|
||||
|
||||
/**
|
||||
* Adds a parameter to the ContentType header.
|
||||
* @param[in] content LinphoneContent object.
|
||||
* @param[in] name the name of the parameter to add.
|
||||
* @param[in] value the value of the parameter to add.
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_content_add_content_type_parameter(LinphoneContent *content, const char *name, const char *value);
|
||||
|
||||
/**
|
||||
* Get the content data buffer, usually a string.
|
||||
* @param[in] content LinphoneContent object.
|
||||
|
|
@ -225,8 +218,9 @@ LINPHONE_PUBLIC void linphone_content_set_key(LinphoneContent *content, const ch
|
|||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // ifdef __cplusplus
|
||||
|
||||
#endif // ifndef _L_C_CONTENT_H_
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LINPHONE_CONTENT_H_ */
|
||||
|
|
@ -42,6 +42,7 @@ 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"
|
||||
|
|
|
|||
|
|
@ -367,6 +367,12 @@ 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
|
||||
|
|
|
|||
|
|
@ -99,9 +99,6 @@ set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES
|
|||
content/content.h
|
||||
content/file-content.h
|
||||
content/file-transfer-content.h
|
||||
content/header/header.h
|
||||
content/header/header-p.h
|
||||
content/header/header-param.h
|
||||
core/core-accessor.h
|
||||
core/core-listener.h
|
||||
core/core-p.h
|
||||
|
|
@ -176,7 +173,6 @@ 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
|
||||
|
|
@ -226,8 +222,6 @@ set(LINPHONE_CXX_OBJECTS_SOURCE_FILES
|
|||
content/content.cpp
|
||||
content/file-content.cpp
|
||||
content/file-transfer-content.cpp
|
||||
content/header/header.cpp
|
||||
content/header/header-param.cpp
|
||||
core/core-accessor.cpp
|
||||
core/core-call.cpp
|
||||
core/core-chat-room.cpp
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@
|
|||
*/
|
||||
|
||||
#include "linphone/api/c-chat-message.h"
|
||||
#include "linphone/api/c-content.h"
|
||||
#include "linphone/utils/utils.h"
|
||||
#include "linphone/wrapper_utils.h"
|
||||
|
||||
|
|
@ -229,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) {
|
||||
|
|
@ -295,9 +294,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);
|
||||
return NULL;
|
||||
return L_GET_PRIVATE_FROM_C_OBJECT(msg)->getFileTransferInformation();
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
|
|
|||
|
|
@ -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, 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 *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 *object = L_INIT(ChatMessage);
|
||||
L_SET_CPP_PTR_FROM_C_OBJECT(object, cppPtr);
|
||||
return object;
|
||||
|
|
|
|||
|
|
@ -1,331 +0,0 @@
|
|||
/*
|
||||
* 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/header/header-param.h"
|
||||
#include "content/header/header.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);
|
||||
}
|
||||
|
||||
void linphone_content_add_content_type_parameter(LinphoneContent *content, const char *name, const char *value) {
|
||||
LinphonePrivate::ContentType ct = L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType();
|
||||
ct.addParameter(L_C_TO_STRING(name), L_C_TO_STRING(value));
|
||||
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().isMultipart();
|
||||
}
|
||||
|
||||
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));
|
||||
for (const belle_sip_list_t *params = sal_body_handler_get_content_type_parameters_names(body_handler); params; params = params->next) {
|
||||
const char *paramName = (const char *)(params->data);
|
||||
const char *paramValue = sal_body_handler_get_content_type_parameter(body_handler, paramName);
|
||||
linphone_content_add_content_type_parameter(content, paramName, paramValue);
|
||||
}
|
||||
|
||||
if (!linphone_content_is_multipart(content)) {
|
||||
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);
|
||||
char *body = belle_sip_object_to_string(mpbh);
|
||||
linphone_content_set_string_buffer(content, body);
|
||||
belle_sip_free(body);
|
||||
}
|
||||
|
||||
belle_sip_list_t *headers = (belle_sip_list_t *)sal_body_handler_get_headers(body_handler);
|
||||
while (headers) {
|
||||
belle_sip_header_t *cHeader = BELLE_SIP_HEADER(headers->data);
|
||||
LinphonePrivate::Header header = LinphonePrivate::Header(belle_sip_header_get_name(cHeader), belle_sip_header_get_unparsed_value(cHeader));
|
||||
L_GET_CPP_PTR_FROM_C_OBJECT(content)->addHeader(header);
|
||||
headers = headers->next;
|
||||
}
|
||||
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_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;
|
||||
LinphonePrivate::ContentType contentType = L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType();
|
||||
|
||||
if (contentType.isMultipart()) {
|
||||
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(contentType.getParameter("boundary").getValue());
|
||||
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)));
|
||||
}
|
||||
|
||||
for (const auto &header : L_GET_CPP_PTR_FROM_C_OBJECT(content)->getHeaders()) {
|
||||
belle_sip_header_t *additionalHeader = belle_sip_header_parse(header.asString().c_str());
|
||||
belle_sip_body_handler_add_header(BELLE_SIP_BODY_HANDLER(body_handler), additionalHeader);
|
||||
}
|
||||
|
||||
sal_body_handler_set_type(body_handler, contentType.getType().c_str());
|
||||
sal_body_handler_set_subtype(body_handler, contentType.getSubType().c_str());
|
||||
sal_body_handler_set_size(body_handler, linphone_content_get_size(content));
|
||||
for (const auto ¶m : contentType.getParameters()) {
|
||||
sal_body_handler_set_content_type_parameter(body_handler, param.getName().c_str(), param.getValue().c_str());
|
||||
}
|
||||
if (content->encoding) sal_body_handler_set_encoding(body_handler, linphone_content_get_encoding(content));
|
||||
|
||||
return body_handler;
|
||||
}
|
||||
|
|
@ -37,7 +37,6 @@
|
|||
F(ChatMessage, ChatMessage) \
|
||||
F(AbstractChatRoom, ChatRoom) \
|
||||
F(Core, Core) \
|
||||
F(Content, Content) \
|
||||
F(DialPlan, DialPlan) \
|
||||
F(EventLog, EventLog) \
|
||||
F(MagicSearch, MagicSearch) \
|
||||
|
|
@ -86,6 +85,7 @@ 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),
|
||||
|
|
|
|||
|
|
@ -636,9 +636,6 @@ const char * sal_body_handler_get_type(const SalBodyHandler *body_handler);
|
|||
void sal_body_handler_set_type(SalBodyHandler *body_handler, const char *type);
|
||||
const char * sal_body_handler_get_subtype(const SalBodyHandler *body_handler);
|
||||
void sal_body_handler_set_subtype(SalBodyHandler *body_handler, const char *subtype);
|
||||
const belle_sip_list_t * sal_body_handler_get_content_type_parameters_names(const SalBodyHandler *body_handler);
|
||||
const char * sal_body_handler_get_content_type_parameter(const SalBodyHandler *body_handler, const char *name);
|
||||
void sal_body_handler_set_content_type_parameter(SalBodyHandler *body_handler, const char *paramName, const char *paramValue);
|
||||
const char * sal_body_handler_get_encoding(const SalBodyHandler *body_handler);
|
||||
void sal_body_handler_set_encoding(SalBodyHandler *body_handler, const char *encoding);
|
||||
void * sal_body_handler_get_data(const SalBodyHandler *body_handler);
|
||||
|
|
@ -647,10 +644,8 @@ size_t sal_body_handler_get_size(const SalBodyHandler *body_handler);
|
|||
void sal_body_handler_set_size(SalBodyHandler *body_handler, size_t size);
|
||||
bool_t sal_body_handler_is_multipart(const SalBodyHandler *body_handler);
|
||||
SalBodyHandler * sal_body_handler_get_part(const SalBodyHandler *body_handler, int idx);
|
||||
const belle_sip_list_t * sal_body_handler_get_parts(const SalBodyHandler *body_handler);
|
||||
SalBodyHandler * sal_body_handler_find_part_by_header(const SalBodyHandler *body_handler, const char *header_name, const char *header_value);
|
||||
const char * sal_body_handler_get_header(const SalBodyHandler *body_handler, const char *header_name);
|
||||
const belle_sip_list_t* sal_body_handler_get_headers(const SalBodyHandler *body_handler);
|
||||
|
||||
/*this function parses a document with key=value pairs separated by new lines, and extracts the value for a given key*/
|
||||
int sal_lines_get_value(const char *data, const char *key, char *value, size_t value_size);
|
||||
|
|
|
|||
|
|
@ -137,11 +137,11 @@ public:
|
|||
bool hasFileTransferContent () const;
|
||||
const Content* getFileTransferContent () const;
|
||||
|
||||
const Content* getFileTransferInformation () const;
|
||||
void setFileTransferInformation (Content *content);
|
||||
LinphoneContent *getFileTransferInformation () const;
|
||||
void setFileTransferInformation (const LinphoneContent *content);
|
||||
|
||||
void addContent (Content *content);
|
||||
void removeContent (Content *content);
|
||||
void addContent (Content &content);
|
||||
void removeContent (const Content &content);
|
||||
|
||||
bool downloadFile ();
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
#include "object/object-p.h"
|
||||
|
||||
#include "linphone/api/c-content.h"
|
||||
#include "linphone/core.h"
|
||||
#include "linphone/lpconfig.h"
|
||||
#include "linphone/utils/utils.h"
|
||||
|
|
@ -37,7 +36,6 @@
|
|||
#include "chat/modifier/multipart-chat-message-modifier.h"
|
||||
#include "conference/participant.h"
|
||||
#include "content/file-content.h"
|
||||
#include "content/header/header-param.h"
|
||||
#include "content/content.h"
|
||||
#include "core/core.h"
|
||||
#include "core/core-p.h"
|
||||
|
|
@ -241,8 +239,8 @@ const Content* ChatMessagePrivate::getTextContent() const {
|
|||
}
|
||||
|
||||
bool ChatMessagePrivate::hasFileTransferContent() const {
|
||||
for (const Content *c : contents) {
|
||||
if (c->isFileTransfer()) {
|
||||
for (const Content *c : getContents()) {
|
||||
if (c->getContentType() == ContentType::FileTransfer) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -250,8 +248,8 @@ bool ChatMessagePrivate::hasFileTransferContent() const {
|
|||
}
|
||||
|
||||
const Content* ChatMessagePrivate::getFileTransferContent() const {
|
||||
for (const Content *c : contents) {
|
||||
if (c->isFileTransfer()) {
|
||||
for (const Content *c : getContents()) {
|
||||
if (c->getContentType() == ContentType::FileTransfer) {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
|
@ -376,54 +374,51 @@ void ChatMessagePrivate::setText (const string &text) {
|
|||
}
|
||||
}
|
||||
|
||||
const Content *ChatMessagePrivate::getFileTransferInformation () const {
|
||||
LinphoneContent *ChatMessagePrivate::getFileTransferInformation () const {
|
||||
if (hasFileTransferContent()) {
|
||||
return getFileTransferContent();
|
||||
return getFileTransferContent()->toLinphoneContent();
|
||||
}
|
||||
for (const Content *c : getContents()) {
|
||||
if (c->isFile()) {
|
||||
FileContent *fileContent = (FileContent *)c;
|
||||
return fileContent;
|
||||
return fileContent->toLinphoneContent();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ChatMessagePrivate::setFileTransferInformation (Content *content) {
|
||||
void ChatMessagePrivate::setFileTransferInformation (const LinphoneContent *c_content) {
|
||||
L_Q();
|
||||
|
||||
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);
|
||||
// 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));
|
||||
}
|
||||
|
||||
q->addContent(*fileContent);
|
||||
}
|
||||
|
||||
bool ChatMessagePrivate::downloadFile () {
|
||||
L_Q();
|
||||
|
||||
for (auto &content : getContents())
|
||||
if (content->isFileTransfer())
|
||||
return q->downloadFile(static_cast<FileTransferContent *>(content));
|
||||
if (content->getContentType() == ContentType::FileTransfer)
|
||||
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 (Content *content) {
|
||||
getContents().remove(content);
|
||||
void ChatMessagePrivate::removeContent (const Content &content) {
|
||||
getContents().remove(&const_cast<Content &>(content));
|
||||
}
|
||||
|
||||
void ChatMessagePrivate::loadFileTransferUrlFromBodyToContent() {
|
||||
|
|
@ -458,7 +453,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);
|
||||
|
|
@ -475,7 +470,7 @@ static void forceUtf8Content (Content &content) {
|
|||
if (contentType != ContentType::PlainText)
|
||||
return;
|
||||
|
||||
string charset = contentType.getParameter("charset").getValue();
|
||||
string charset = contentType.getParameter();
|
||||
if (charset.empty())
|
||||
return;
|
||||
|
||||
|
|
@ -494,7 +489,7 @@ static void forceUtf8Content (Content &content) {
|
|||
if (!utf8Body.empty()) {
|
||||
// TODO: use move operator if possible in the future!
|
||||
content.setBodyFromUtf8(utf8Body);
|
||||
contentType.addParameter("charset", "UTF-8");
|
||||
contentType.setParameter(string(contentType.getParameter()).replace(begin, end - begin, "UTF-8"));
|
||||
content.setContentType(contentType);
|
||||
}
|
||||
}
|
||||
|
|
@ -606,7 +601,7 @@ LinphoneReason ChatMessagePrivate::receive () {
|
|||
foundSupportContentType = true;
|
||||
break;
|
||||
} else
|
||||
lError() << "Unsupported content-type: " << c->getContentType();
|
||||
lError() << "Unsupported content-type: " << c->getContentType().asString();
|
||||
}
|
||||
|
||||
if (!foundSupportContentType) {
|
||||
|
|
@ -765,7 +760,7 @@ void ChatMessagePrivate::send () {
|
|||
|
||||
auto msgOp = dynamic_cast<SalMessageOpInterface *>(op);
|
||||
if (!externalBodyUrl.empty()) {
|
||||
char *content_type = ms_strdup_printf("message/external-body;access-type=URL;URL=\"%s\"", externalBodyUrl.c_str());
|
||||
char *content_type = ms_strdup_printf("message/external-body; access-type=URL; URL=\"%s\"", externalBodyUrl.c_str());
|
||||
msgOp->send_message(content_type, NULL);
|
||||
ms_free(content_type);
|
||||
} else if (internalContent.getContentType().isValid()) {
|
||||
|
|
@ -778,10 +773,10 @@ void ChatMessagePrivate::send () {
|
|||
list<Content*>::iterator it = contents.begin();
|
||||
while (it != contents.end()) {
|
||||
Content *content = *it;
|
||||
if (content->isFileTransfer()) {
|
||||
FileTransferContent *fileTransferContent = static_cast<FileTransferContent *>(content);
|
||||
if (content->getContentType() == ContentType::FileTransfer) {
|
||||
FileTransferContent *fileTransferContent = (FileTransferContent *)content;
|
||||
it = contents.erase(it);
|
||||
addContent(fileTransferContent->getFileContent());
|
||||
addContent(*fileTransferContent->getFileContent());
|
||||
delete fileTransferContent;
|
||||
} else {
|
||||
it++;
|
||||
|
|
@ -1019,13 +1014,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 (Content *content) {
|
||||
void ChatMessage::removeContent (const Content &content) {
|
||||
L_D();
|
||||
if (!d->isReadOnly)
|
||||
d->removeContent(content);
|
||||
|
|
@ -1095,9 +1090,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() {
|
||||
|
|
|
|||
|
|
@ -95,8 +95,8 @@ public:
|
|||
void setToBeStored (bool value);
|
||||
|
||||
const std::list<Content *> &getContents () const;
|
||||
void addContent (Content *content);
|
||||
void removeContent (Content *content);
|
||||
void addContent (Content &content);
|
||||
void removeContent (const Content &content);
|
||||
|
||||
const Content &getInternalContent () const;
|
||||
void setInternalContent (const Content &content);
|
||||
|
|
@ -106,7 +106,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:
|
||||
|
|
|
|||
|
|
@ -89,7 +89,8 @@ public:
|
|||
virtual std::shared_ptr<ChatMessage> createChatMessage () = 0;
|
||||
virtual std::shared_ptr<ChatMessage> createChatMessage (const std::string &text) = 0;
|
||||
|
||||
virtual std::shared_ptr<ChatMessage> createFileTransferMessage (Content *initialContent) = 0;
|
||||
// TODO: Remove LinphoneContent by LinphonePrivate::Content.
|
||||
virtual std::shared_ptr<ChatMessage> createFileTransferMessage (const LinphoneContent *initialContent) = 0;
|
||||
|
||||
virtual std::shared_ptr<ChatMessage> findChatMessage (const std::string &messageId) const = 0;
|
||||
virtual std::shared_ptr<ChatMessage> findChatMessage (
|
||||
|
|
|
|||
|
|
@ -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 (Content *initialContent) {
|
||||
shared_ptr<ChatMessage> ChatRoom::createFileTransferMessage (const LinphoneContent *initialContent) {
|
||||
shared_ptr<ChatMessage> chatMessage = createChatMessage();
|
||||
chatMessage->getPrivate()->setFileTransferInformation(initialContent);
|
||||
return chatMessage;
|
||||
|
|
|
|||
|
|
@ -65,7 +65,8 @@ public:
|
|||
std::shared_ptr<ChatMessage> createChatMessage () override;
|
||||
std::shared_ptr<ChatMessage> createChatMessage (const std::string &text) override;
|
||||
|
||||
std::shared_ptr<ChatMessage> createFileTransferMessage (Content *initialContent) override;
|
||||
// TODO: Remove LinphoneContent by LinphonePrivate::Content.
|
||||
std::shared_ptr<ChatMessage> createFileTransferMessage (const LinphoneContent *initialContent) override;
|
||||
|
||||
std::shared_ptr<ChatMessage> findChatMessage (const std::string &messageId) const override;
|
||||
std::shared_ptr<ChatMessage> findChatMessage (
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ shared_ptr<ChatMessage> ProxyChatRoom::createChatMessage (const string &text) {
|
|||
return d->chatRoom->createChatMessage(text);
|
||||
}
|
||||
|
||||
shared_ptr<ChatMessage> ProxyChatRoom::createFileTransferMessage (Content *initialContent) {
|
||||
shared_ptr<ChatMessage> ProxyChatRoom::createFileTransferMessage (const LinphoneContent *initialContent) {
|
||||
L_D();
|
||||
return d->chatRoom->createFileTransferMessage(initialContent);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,8 @@ public:
|
|||
std::shared_ptr<ChatMessage> createChatMessage () override;
|
||||
std::shared_ptr<ChatMessage> createChatMessage (const std::string &text) override;
|
||||
|
||||
std::shared_ptr<ChatMessage> createFileTransferMessage (Content *initialContent) override;
|
||||
// TODO: Remove LinphoneContent by LinphonePrivate::Content.
|
||||
std::shared_ptr<ChatMessage> createFileTransferMessage (const LinphoneContent *initialContent) override;
|
||||
|
||||
std::shared_ptr<ChatMessage> findChatMessage (const std::string &messageId) const override;
|
||||
std::shared_ptr<ChatMessage> findChatMessage (
|
||||
|
|
|
|||
|
|
@ -149,11 +149,9 @@ string Cpim::Message::asString () const {
|
|||
|
||||
string output;
|
||||
// TODO: Remove cpimHeaders
|
||||
if (d->cpimHeaders->size() > 0) {
|
||||
for (const auto &cpimHeader : *d->cpimHeaders)
|
||||
output += cpimHeader->asString();
|
||||
output += "\r\n";
|
||||
}
|
||||
for (const auto &cpimHeader : *d->cpimHeaders)
|
||||
output += cpimHeader->asString();
|
||||
output += "\r\n";
|
||||
// TODO Remove cpimHeaders
|
||||
|
||||
if (d->messageHeaders->size() > 0) {
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ ChatMessageModifier::Result CpimChatMessageModifier::decode (const shared_ptr<Ch
|
|||
content = message->getContents().front();
|
||||
|
||||
if (content->getContentType() != ContentType::Cpim) {
|
||||
lError() << "[CPIM] Message is not CPIM but " << content->getContentType();
|
||||
lError() << "[CPIM] Message is not CPIM but " << content->getContentType().asString();
|
||||
return ChatMessageModifier::Result::Skipped;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,17 +17,15 @@
|
|||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "linphone/api/c-content.h"
|
||||
|
||||
#include "address/address.h"
|
||||
#include "bctoolbox/crypto.h"
|
||||
#include "c-wrapper/c-wrapper.h"
|
||||
#include "address/address.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"
|
||||
|
||||
|
|
@ -109,7 +107,7 @@ void FileTransferChatMessageModifier::fileTransferOnProgress (
|
|||
|
||||
LinphoneChatMessage *msg = L_GET_C_BACK_PTR(message);
|
||||
LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg);
|
||||
LinphoneContent *content = L_GET_C_BACK_PTR((Content *)currentFileContentToTransfer);
|
||||
LinphoneContent *content = currentFileContentToTransfer->toLinphoneContent();
|
||||
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 {
|
||||
|
|
@ -159,7 +157,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 = L_GET_C_BACK_PTR((Content *)currentFileContentToTransfer);
|
||||
LinphoneContent *content = currentFileContentToTransfer->toLinphoneContent();
|
||||
if (file_transfer_send_cb) {
|
||||
LinphoneBuffer *lb = file_transfer_send_cb(msg, content, offset, *size);
|
||||
if (lb) {
|
||||
|
|
@ -255,6 +253,12 @@ 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
|
||||
|
|
@ -297,31 +301,9 @@ 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
|
||||
const char *content_key = fileTransferContent->getFileKeyAsString();
|
||||
size_t content_key_size = fileTransferContent->getFileKey().size();
|
||||
if (content_key_size > 0) {
|
||||
string content_key = currentFileContentToTransfer->getFileKey();
|
||||
if (!content_key.empty()) {
|
||||
// parse the msg body
|
||||
xmlDocPtr xmlMessageBody = xmlParseDoc((const xmlChar *)body);
|
||||
|
||||
|
|
@ -334,15 +316,16 @@ 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, content_key_size);
|
||||
bctbx_base64_encode(nullptr, &b64Size, (unsigned char *)content_key.c_str(), content_key_size);
|
||||
unsigned char *keyb64 = (unsigned char *)ms_malloc0(b64Size + 1);
|
||||
int xmlStringLength;
|
||||
|
||||
bctbx_base64_encode(keyb64, &b64Size, (unsigned char *)content_key, content_key_size);
|
||||
bctbx_base64_encode(keyb64, &b64Size, (unsigned char *)content_key.c_str(), content_key_size);
|
||||
keyb64[b64Size] = '\0'; // libxml need a null terminated string
|
||||
|
||||
// add the node containing the key to the file-info node
|
||||
|
|
@ -378,10 +361,11 @@ 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();
|
||||
|
|
@ -575,13 +559,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->isFileTransfer()) {
|
||||
FileTransferContent *fileTransferContent = static_cast<FileTransferContent *>(content);
|
||||
if (content->getContentType() == ContentType::FileTransfer) {
|
||||
FileTransferContent *fileTransferContent = (FileTransferContent *)content;
|
||||
fillFileTransferContentInformationsFromVndGsmaRcsFtHttpXml(fileTransferContent);
|
||||
}
|
||||
}
|
||||
|
|
@ -650,7 +634,8 @@ 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));
|
||||
fileTransferContent->setFileKey((const char *)keyBuffer, keyLength);
|
||||
string key = string((const char *)keyBuffer);
|
||||
fileContent->setFileKey(key);
|
||||
// duplicate key value into the linphone content private structure
|
||||
xmlFree(keyb64);
|
||||
free(keyBuffer);
|
||||
|
|
@ -714,7 +699,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 = L_GET_C_BACK_PTR((Content *)currentFileContentToTransfer);
|
||||
LinphoneContent *content = currentFileContentToTransfer->toLinphoneContent();
|
||||
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);
|
||||
|
|
@ -755,7 +740,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 = L_GET_C_BACK_PTR((Content *)currentFileContentToTransfer);
|
||||
LinphoneContent *content = currentFileContentToTransfer->toLinphoneContent();
|
||||
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);
|
||||
|
|
@ -771,12 +756,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->isFileTransfer()) {
|
||||
FileTransferContent *fileTransferContent = static_cast<FileTransferContent *>(content);
|
||||
if (content->getContentType() == ContentType::FileTransfer) {
|
||||
FileTransferContent *fileTransferContent = (FileTransferContent*)content;
|
||||
if (fileTransferContent->getFileContent() == fileContent) {
|
||||
message->getPrivate()->removeContent(content);
|
||||
message->getPrivate()->removeContent(*content);
|
||||
delete fileTransferContent;
|
||||
break;
|
||||
}
|
||||
|
|
@ -829,7 +814,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;
|
||||
|
|
|
|||
|
|
@ -20,11 +20,13 @@
|
|||
// TODO: Remove me later.
|
||||
#include "private.h"
|
||||
|
||||
#include "address/address.h"
|
||||
#include "chat/chat-message/chat-message.h"
|
||||
#include "chat/chat-room/chat-room.h"
|
||||
#include "content/content-type.h"
|
||||
#include "content/header/header.h"
|
||||
#include "content/content-manager.h"
|
||||
#include "content/file-transfer-content.h"
|
||||
#include "logger/logger.h"
|
||||
#include "core/core.h"
|
||||
|
||||
#include "multipart-chat-message-modifier.h"
|
||||
|
||||
|
|
@ -41,30 +43,90 @@ ChatMessageModifier::Result MultipartChatMessageModifier::encode (
|
|||
if (message->getContents().size() <= 1)
|
||||
return ChatMessageModifier::Result::Skipped;
|
||||
|
||||
Content content = ContentManager::contentListToMultipart(message->getContents());
|
||||
message->setInternalContent(content);
|
||||
LinphoneCore *lc = message->getChatRoom()->getCore()->getCCore();
|
||||
char tmp[64];
|
||||
lc->sal->create_uuid(tmp, sizeof(tmp));
|
||||
string boundary = tmp;
|
||||
stringstream multipartMessage;
|
||||
|
||||
multipartMessage << "--" << boundary;
|
||||
for (Content *content : message->getContents()) {
|
||||
multipartMessage << "\r\n";
|
||||
multipartMessage << "Content-Type: " << content->getContentType().asString() << "\r\n\r\n";
|
||||
multipartMessage << content->getBodyAsString() << "\r\n\r\n";
|
||||
multipartMessage << "--" << boundary;
|
||||
}
|
||||
multipartMessage << "--";
|
||||
|
||||
Content newContent;
|
||||
ContentType newContentType(ContentType::Multipart);
|
||||
newContentType.setParameter("boundary=" + boundary);
|
||||
newContent.setContentType(newContentType);
|
||||
newContent.setBody(multipartMessage.str());
|
||||
message->setInternalContent(newContent);
|
||||
|
||||
return ChatMessageModifier::Result::Done;
|
||||
}
|
||||
|
||||
ChatMessageModifier::Result MultipartChatMessageModifier::decode (const shared_ptr<ChatMessage> &message, int &errorCode) {
|
||||
if (message->getInternalContent().getContentType().isMultipart()) {
|
||||
for (Content &c : ContentManager::multipartToContentList(message->getInternalContent())) {
|
||||
Content *content;
|
||||
if (c.getContentType() == ContentType::FileTransfer) {
|
||||
content = new FileTransferContent();
|
||||
content->setContentType(c.getContentType());
|
||||
content->setContentDisposition(c.getContentDisposition());
|
||||
content->setContentEncoding(c.getContentEncoding());
|
||||
for (const Header &header : c.getHeaders()) {
|
||||
content->addHeader(header);
|
||||
}
|
||||
content->setBodyFromUtf8(c.getBodyAsUtf8String());
|
||||
} else {
|
||||
content = new Content(c);
|
||||
}
|
||||
message->addContent(content);
|
||||
if (message->getInternalContent().getContentType().getType() == "multipart") {
|
||||
string boundary = message->getInternalContent().getContentType().getParameter();
|
||||
if (boundary.empty()) {
|
||||
lError() << "Boundary parameter of content-type not found: " << message->getInternalContent().getContentType().asString();
|
||||
return ChatMessageModifier::Result::Error;
|
||||
}
|
||||
|
||||
size_t pos = boundary.find("=");
|
||||
if (pos == string::npos) {
|
||||
lError() << "Parameter seems invalid: " << boundary;
|
||||
return ChatMessageModifier::Result::Error;
|
||||
}
|
||||
boundary = "--" + boundary.substr(pos + 1);
|
||||
lInfo() << "Multipart boundary is " << boundary;
|
||||
|
||||
const vector<char> body = message->getInternalContent().getBody();
|
||||
string contentsString(body.begin(), body.end());
|
||||
|
||||
pos = contentsString.find(boundary);
|
||||
if (pos == string::npos) {
|
||||
lError() << "Boundary not found in body !";
|
||||
return ChatMessageModifier::Result::Error;
|
||||
}
|
||||
|
||||
size_t start = pos + boundary.length() + 2; // 2 is the size of \r\n
|
||||
size_t end;
|
||||
do {
|
||||
end = contentsString.find(boundary, start);
|
||||
if (end != string::npos) {
|
||||
string contentString = contentsString.substr(start, end - start);
|
||||
|
||||
size_t contentTypePos = contentString.find(": ") + 2; // 2 is the size of :
|
||||
size_t endOfLinePos = contentString.find("\r\n");
|
||||
if (contentTypePos >= endOfLinePos) {
|
||||
lError() << "Content should start by a 'Content-Type: ' line !";
|
||||
continue;
|
||||
}
|
||||
string contentTypeString = contentString.substr(contentTypePos, endOfLinePos - contentTypePos);
|
||||
ContentType contentType(contentTypeString);
|
||||
|
||||
endOfLinePos += 4; // 4 is two time the size of \r\n
|
||||
string contentBody = contentString.substr(endOfLinePos, contentString.length() - (endOfLinePos + 4)); // 4 is two time the size of \r\n
|
||||
|
||||
Content *content;
|
||||
if (contentType == ContentType::FileTransfer) {
|
||||
content = new FileTransferContent();
|
||||
} else {
|
||||
content = new Content();
|
||||
}
|
||||
content->setContentType(contentType);
|
||||
content->setBody(contentBody);
|
||||
message->addContent(*content);
|
||||
|
||||
lInfo() << "Parsed and added content with type " << contentType.asString();
|
||||
}
|
||||
start = end + boundary.length() + 2; // 2 is the size of \r\n
|
||||
} while (end != string::npos);
|
||||
|
||||
return ChatMessageModifier::Result::Done;
|
||||
}
|
||||
return ChatMessageModifier::Result::Skipped;
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
#include <ctime>
|
||||
|
||||
#include "linphone/api/c-content.h"
|
||||
#include "linphone/utils/utils.h"
|
||||
|
||||
#include "conference/local-conference.h"
|
||||
|
|
@ -107,7 +106,7 @@ string LocalConferenceEventHandlerPrivate::createNotifyMultipart (int notifyId)
|
|||
static_cast<unsigned int>(notifyId)
|
||||
);
|
||||
|
||||
list<Content *> contents;
|
||||
list<Content> contents;
|
||||
for (const auto &eventLog : events) {
|
||||
Content content;
|
||||
content.setContentType(ContentType("application","conference-info"));
|
||||
|
|
@ -181,7 +180,7 @@ string LocalConferenceEventHandlerPrivate::createNotifyMultipart (int notifyId)
|
|||
continue;
|
||||
}
|
||||
content.setBody(body);
|
||||
contents.push_back(&content);
|
||||
contents.push_back(content);
|
||||
}
|
||||
|
||||
if (contents.empty())
|
||||
|
|
|
|||
|
|
@ -19,18 +19,19 @@
|
|||
|
||||
#include <bctoolbox/defs.h>
|
||||
|
||||
#include "linphone/api/c-content.h"
|
||||
#include "linphone/core.h"
|
||||
#include "c-wrapper/c-wrapper.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;
|
||||
|
|
|
|||
|
|
@ -19,68 +19,101 @@
|
|||
|
||||
#include <belle-sip/belle-sip.h>
|
||||
|
||||
#include "c-wrapper/c-wrapper.h"
|
||||
|
||||
#include "linphone/api/c-content.h"
|
||||
|
||||
#include "content-manager.h"
|
||||
#include "content-type.h"
|
||||
#include "content/content.h"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
namespace {
|
||||
constexpr const char MultipartBoundary[] = "---------------------------14737809831466499882746641449";
|
||||
}
|
||||
|
||||
using namespace std;
|
||||
|
||||
LINPHONE_BEGIN_NAMESPACE
|
||||
|
||||
namespace {
|
||||
constexpr const char MultipartBoundary[] = "---------------------------14737809831466499882746641449";
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
list<Content> ContentManager::multipartToContentList (const Content &content) {
|
||||
LinphoneContent *cContent = L_GET_C_BACK_PTR(&content);
|
||||
SalBodyHandler *sbh = sal_body_handler_ref(sal_body_handler_from_content(cContent));
|
||||
const string body = content.getBodyAsString();
|
||||
belle_sip_multipart_body_handler_t *mpbh = belle_sip_multipart_body_handler_new_from_buffer(
|
||||
body.c_str(), body.length(), MultipartBoundary
|
||||
);
|
||||
belle_sip_object_ref(mpbh);
|
||||
|
||||
list<Content> contents;
|
||||
for (const belle_sip_list_t *parts = sal_body_handler_get_parts(sbh); parts; parts = parts->next) {
|
||||
SalBodyHandler *part = (SalBodyHandler *)parts->data;
|
||||
LinphoneContent *cContent = linphone_content_from_sal_body_handler(part);
|
||||
Content *cppContent = L_GET_CPP_PTR_FROM_C_OBJECT(cContent);
|
||||
contents.push_back(*cppContent);
|
||||
linphone_content_unref(cContent);
|
||||
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);
|
||||
belle_sip_header_content_type_t *partContentType = nullptr;
|
||||
for (const belle_sip_list_t *it = belle_sip_body_handler_get_headers(part); it; it = it->next) {
|
||||
belle_sip_header_t *header = BELLE_SIP_HEADER(it->data);
|
||||
if (strcasecmp("Content-Type", belle_sip_header_get_name(header)) == 0) {
|
||||
partContentType = BELLE_SIP_HEADER_CONTENT_TYPE(header);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Content content;
|
||||
content.setBody(static_cast<const char *>(
|
||||
belle_sip_memory_body_handler_get_buffer(BELLE_SIP_MEMORY_BODY_HANDLER(part))
|
||||
));
|
||||
content.setContentType(ContentType(
|
||||
belle_sip_header_content_type_get_type(partContentType),
|
||||
belle_sip_header_content_type_get_subtype(partContentType)
|
||||
));
|
||||
contents.push_back(move(content));
|
||||
}
|
||||
|
||||
sal_body_handler_unref(sbh);
|
||||
linphone_content_unref(cContent);
|
||||
belle_sip_object_unref(mpbh);
|
||||
return contents;
|
||||
}
|
||||
|
||||
Content ContentManager::contentListToMultipart (const list<Content *> &contents) {
|
||||
Content ContentManager::contentListToMultipart (const list<Content> &contents) {
|
||||
belle_sip_multipart_body_handler_t *mpbh = belle_sip_multipart_body_handler_new(
|
||||
nullptr, nullptr, nullptr, MultipartBoundary
|
||||
);
|
||||
mpbh = (belle_sip_multipart_body_handler_t *)belle_sip_object_ref(mpbh);
|
||||
belle_sip_object_ref(mpbh);
|
||||
|
||||
for (Content *content : contents) {
|
||||
LinphoneContent *cContent = L_GET_C_BACK_PTR(content);
|
||||
SalBodyHandler *sbh = sal_body_handler_from_content(cContent);
|
||||
belle_sip_multipart_body_handler_add_part(mpbh, BELLE_SIP_BODY_HANDLER(sbh));
|
||||
linphone_content_unref(cContent);
|
||||
for (const auto &content : contents) {
|
||||
const ContentType &contentType = content.getContentType();
|
||||
belle_sip_header_t *cContentType = BELLE_SIP_HEADER(
|
||||
belle_sip_header_content_type_create(
|
||||
contentType.getType().c_str(),
|
||||
string(contentType.getSubType() + "; charset=\"UTF-8\"").c_str()
|
||||
)
|
||||
);
|
||||
|
||||
const string body = content.getBodyAsString();
|
||||
belle_sip_memory_body_handler_t *mbh = belle_sip_memory_body_handler_new_copy_from_buffer(
|
||||
body.c_str(), body.length(), nullptr, nullptr
|
||||
);
|
||||
belle_sip_body_handler_add_header(BELLE_SIP_BODY_HANDLER(mbh), cContentType);
|
||||
|
||||
for (const auto &header : content.getHeaders()) {
|
||||
belle_sip_header_t *additionalHeader = BELLE_SIP_HEADER(
|
||||
belle_sip_header_create(
|
||||
header.first.c_str(),
|
||||
header.second.c_str()
|
||||
)
|
||||
);
|
||||
belle_sip_body_handler_add_header(BELLE_SIP_BODY_HANDLER(mbh), additionalHeader);
|
||||
}
|
||||
|
||||
belle_sip_multipart_body_handler_add_part(mpbh, BELLE_SIP_BODY_HANDLER(mbh));
|
||||
}
|
||||
|
||||
SalBodyHandler *sbh = (SalBodyHandler *)mpbh;
|
||||
sal_body_handler_set_type(sbh, ContentType::Multipart.getType().c_str());
|
||||
sal_body_handler_set_subtype(sbh, ContentType::Multipart.getSubType().c_str());
|
||||
sal_body_handler_set_content_type_parameter(sbh, "boundary", MultipartBoundary);
|
||||
LinphoneContent *cContent = linphone_content_from_sal_body_handler(sbh);
|
||||
Content *content = L_GET_CPP_PTR_FROM_C_OBJECT(cContent);
|
||||
Content returnContent = *content;
|
||||
linphone_content_unref(cContent);
|
||||
char *desc = belle_sip_object_to_string(mpbh);
|
||||
Content content;
|
||||
content.setBody(desc);
|
||||
belle_sip_free(desc);
|
||||
belle_sip_object_unref(mpbh);
|
||||
|
||||
return returnContent;
|
||||
ContentType contentType = ContentType::Multipart;
|
||||
contentType.setParameter("boundary=" + string(MultipartBoundary));
|
||||
content.setContentType(contentType);
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
LINPHONE_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ class Content;
|
|||
|
||||
namespace ContentManager {
|
||||
std::list<Content> multipartToContentList (const Content &content);
|
||||
Content contentListToMultipart (const std::list<Content *> &contents);
|
||||
Content contentListToMultipart (const std::list<Content> &contents);
|
||||
}
|
||||
|
||||
LINPHONE_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -29,15 +29,13 @@
|
|||
|
||||
LINPHONE_BEGIN_NAMESPACE
|
||||
|
||||
class Header;
|
||||
|
||||
class ContentPrivate : public ClonableObjectPrivate {
|
||||
private:
|
||||
std::vector<char> body;
|
||||
ContentType contentType;
|
||||
ContentDisposition contentDisposition;
|
||||
std::string contentEncoding;
|
||||
std::list<Header> headers;
|
||||
std::list<std::pair<std::string, std::string>> headers;
|
||||
|
||||
L_DECLARE_PUBLIC(Content);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -20,8 +20,7 @@
|
|||
#include "linphone/utils/utils.h"
|
||||
|
||||
#include "content-type.h"
|
||||
#include "header/header-p.h"
|
||||
#include "header/header-param.h"
|
||||
#include "object/clonable-object-p.h"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
|
|
@ -31,10 +30,11 @@ LINPHONE_BEGIN_NAMESPACE
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class ContentTypePrivate : public HeaderPrivate {
|
||||
class ContentTypePrivate : public ClonableObjectPrivate {
|
||||
public:
|
||||
string type;
|
||||
string subType;
|
||||
string parameter;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -52,7 +52,7 @@ const ContentType ContentType::Sdp("application/sdp");
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
ContentType::ContentType (const string &contentType) : Header(*new ContentTypePrivate) {
|
||||
ContentType::ContentType (const string &contentType) : ClonableObject(*new ContentTypePrivate) {
|
||||
L_D();
|
||||
|
||||
size_t pos = contentType.find('/');
|
||||
|
|
@ -68,23 +68,11 @@ ContentType::ContentType (const string &contentType) : Header(*new ContentTypePr
|
|||
d->type.clear();
|
||||
}
|
||||
|
||||
if (posParam != string::npos) {
|
||||
string params = contentType.substr(posParam + 1);
|
||||
string token;
|
||||
do {
|
||||
posParam = params.find(";");
|
||||
if (posParam == string::npos) {
|
||||
token = params;
|
||||
} else {
|
||||
token = params.substr(0, posParam);
|
||||
}
|
||||
addParameter(HeaderParam(token));
|
||||
params.erase(0, posParam + 1);
|
||||
} while (posParam != std::string::npos);
|
||||
}
|
||||
if (posParam != string::npos)
|
||||
setParameter(Utils::trim(contentType.substr(posParam + 1)));
|
||||
}
|
||||
|
||||
ContentType::ContentType (const string &type, const string &subType) : Header(*new ContentTypePrivate) {
|
||||
ContentType::ContentType (const string &type, const string &subType) : ClonableObject(*new ContentTypePrivate) {
|
||||
L_D();
|
||||
|
||||
if (setType(type) && !setSubType(subType))
|
||||
|
|
@ -94,35 +82,22 @@ ContentType::ContentType (const string &type, const string &subType) : Header(*n
|
|||
ContentType::ContentType (
|
||||
const string &type,
|
||||
const string &subType,
|
||||
const HeaderParam ¶meter
|
||||
) : Header(*new ContentTypePrivate) {
|
||||
const string ¶meter
|
||||
) : ClonableObject(*new ContentTypePrivate) {
|
||||
L_D();
|
||||
|
||||
if (setType(type) && !setSubType(subType))
|
||||
d->type.clear();
|
||||
addParameter(parameter);
|
||||
setParameter(parameter);
|
||||
}
|
||||
|
||||
ContentType::ContentType (
|
||||
const string &type,
|
||||
const string &subType,
|
||||
const std::list<HeaderParam> ¶meters
|
||||
) : Header(*new ContentTypePrivate) {
|
||||
L_D();
|
||||
|
||||
if (setType(type) && !setSubType(subType))
|
||||
d->type.clear();
|
||||
addParameters(parameters);
|
||||
}
|
||||
|
||||
ContentType::ContentType (const ContentType &other) : ContentType(other.getType(), other.getSubType(), other.getParameters()) {}
|
||||
ContentType::ContentType (const ContentType &other) : ContentType(other.getType(), other.getSubType(), other.getParameter()) {}
|
||||
|
||||
ContentType &ContentType::operator= (const ContentType &other) {
|
||||
if (this != &other) {
|
||||
setType(other.getType());
|
||||
setSubType(other.getSubType());
|
||||
cleanParameters();
|
||||
addParameters(other.getParameters());
|
||||
setParameter(other.getParameter());
|
||||
}
|
||||
|
||||
return *this;
|
||||
|
|
@ -130,7 +105,8 @@ ContentType &ContentType::operator= (const ContentType &other) {
|
|||
|
||||
bool ContentType::operator== (const ContentType &other) const {
|
||||
return getType() == other.getType() &&
|
||||
getSubType() == other.getSubType();
|
||||
getSubType() == other.getSubType() &&
|
||||
getParameter() == other.getParameter();
|
||||
}
|
||||
|
||||
bool ContentType::operator!= (const ContentType &other) const {
|
||||
|
|
@ -146,7 +122,6 @@ bool ContentType::setType (const string &type) {
|
|||
L_D();
|
||||
if (type.find('/') == string::npos) {
|
||||
d->type = Utils::stringToLower(type);
|
||||
setValue(d->type + "/" + d->subType);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -161,12 +136,21 @@ bool ContentType::setSubType (const string &subType) {
|
|||
L_D();
|
||||
if (subType.find('/') == string::npos) {
|
||||
d->subType = Utils::stringToLower(subType);
|
||||
setValue(d->type + "/" + d->subType);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const string &ContentType::getParameter () const {
|
||||
L_D();
|
||||
return d->parameter;
|
||||
}
|
||||
|
||||
void ContentType::setParameter (const string ¶meter) {
|
||||
L_D();
|
||||
d->parameter = parameter;
|
||||
}
|
||||
|
||||
bool ContentType::isEmpty () const {
|
||||
L_D();
|
||||
return d->type.empty() && d->subType.empty();
|
||||
|
|
@ -177,10 +161,18 @@ bool ContentType::isValid () const {
|
|||
return !d->type.empty() && !d->subType.empty();
|
||||
}
|
||||
|
||||
bool ContentType::isMultipart() const {
|
||||
return getType() == "multipart";
|
||||
string ContentType::asString () const {
|
||||
L_D();
|
||||
if (isValid()) {
|
||||
string asString = d->type + "/" + d->subType;
|
||||
if (!d->parameter.empty())
|
||||
asString += "; " + d->parameter;
|
||||
return asString;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
bool ContentType::isFile () const {
|
||||
// TODO Remove when not needed anymore in step 2.1 of maindb
|
||||
return isFile(*this);
|
||||
|
|
|
|||
|
|
@ -21,21 +21,18 @@
|
|||
#define _L_CONTENT_TYPE_H_
|
||||
|
||||
#include "object/clonable-object.h"
|
||||
#include "header/header.h"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
LINPHONE_BEGIN_NAMESPACE
|
||||
|
||||
class ContentTypePrivate;
|
||||
class HeaderParam;
|
||||
|
||||
class LINPHONE_PUBLIC ContentType : public Header {
|
||||
class LINPHONE_PUBLIC ContentType : public ClonableObject {
|
||||
public:
|
||||
explicit ContentType (const std::string &contentType = "");
|
||||
ContentType (const std::string &type, const std::string &subType);
|
||||
ContentType (const std::string &type, const std::string &subType, const HeaderParam ¶meter);
|
||||
ContentType (const std::string &type, const std::string &subType, const std::list<HeaderParam> ¶meters);
|
||||
ContentType (const std::string &type, const std::string &subType, const std::string ¶meter);
|
||||
ContentType (const ContentType &other);
|
||||
|
||||
ContentType &operator= (const ContentType &other);
|
||||
|
|
@ -58,7 +55,10 @@ public:
|
|||
const std::string &getSubType () const;
|
||||
bool setSubType (const std::string &subType);
|
||||
|
||||
bool isMultipart() const;
|
||||
const std::string &getParameter () const;
|
||||
void setParameter (const std::string ¶meter);
|
||||
|
||||
std::string asString () const;
|
||||
|
||||
static bool isFile (const ContentType &contentType);
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
#include "content-p.h"
|
||||
#include "content-type.h"
|
||||
#include "header/header.h"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
|
|
@ -191,37 +190,17 @@ 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);
|
||||
Header header = Header(headerName, headerValue);
|
||||
d->headers.push_back(header);
|
||||
d->headers.push_back(make_pair(headerName, headerValue));
|
||||
}
|
||||
|
||||
void Content::addHeader (const Header &header) {
|
||||
L_D();
|
||||
removeHeader(header.getName());
|
||||
d->headers.push_back(header);
|
||||
}
|
||||
|
||||
const list<Header> &Content::getHeaders () const {
|
||||
const list<pair<string, string>> &Content::getHeaders () const {
|
||||
L_D();
|
||||
return d->headers;
|
||||
}
|
||||
|
||||
const Header &Content::getHeader (const string &headerName) const {
|
||||
L_D();
|
||||
list<Header>::const_iterator it = findHeader(headerName);
|
||||
if (it != d->headers.cend()) {
|
||||
return *it;
|
||||
}
|
||||
return Utils::getEmptyConstRefObject<Header>();
|
||||
}
|
||||
|
||||
void Content::removeHeader (const string &headerName) {
|
||||
L_D();
|
||||
auto it = findHeader(headerName);
|
||||
|
|
@ -229,11 +208,18 @@ void Content::removeHeader (const string &headerName) {
|
|||
d->headers.remove(*it);
|
||||
}
|
||||
|
||||
list<Header>::const_iterator Content::findHeader (const string &headerName) const {
|
||||
list<pair<string, string>>::const_iterator Content::findHeader (const string &headerName) const {
|
||||
L_D();
|
||||
return findIf(d->headers, [&headerName](const Header &header) {
|
||||
return header.getName() == headerName;
|
||||
return findIf(d->headers, [&headerName](const pair<string, string> &pair) {
|
||||
return pair.first == headerName;
|
||||
});
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@ LINPHONE_BEGIN_NAMESPACE
|
|||
class ContentDisposition;
|
||||
class ContentType;
|
||||
class ContentPrivate;
|
||||
class Header;
|
||||
|
||||
class LINPHONE_PUBLIC Content : public ClonableObject, public AppDataContainer {
|
||||
public:
|
||||
|
|
@ -75,14 +74,14 @@ public:
|
|||
bool isEmpty () const;
|
||||
|
||||
virtual bool isFile () const;
|
||||
virtual bool isFileTransfer () const;
|
||||
|
||||
const std::list<Header> &getHeaders () const;
|
||||
const Header &getHeader (const std::string &headerName) const;
|
||||
const std::list<std::pair<std::string, std::string>> &getHeaders () const;
|
||||
void addHeader (const std::string &headerName, const std::string &headerValue);
|
||||
void addHeader (const Header &header);
|
||||
void removeHeader (const std::string &headerName);
|
||||
std::list<Header>::const_iterator findHeader (const std::string &headerName) const;
|
||||
std::list<std::pair<std::string, std::string>>::const_iterator findHeader (const std::string &headerName) const;
|
||||
|
||||
// TODO: Remove me later.
|
||||
virtual LinphoneContent *toLinphoneContent () const;
|
||||
|
||||
protected:
|
||||
explicit Content (ContentPrivate &p);
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ public:
|
|||
string fileName;
|
||||
string filePath;
|
||||
size_t fileSize = 0;
|
||||
string fileKey;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -47,6 +48,7 @@ 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) {
|
||||
|
|
@ -54,14 +56,18 @@ 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;
|
||||
}
|
||||
|
|
@ -72,6 +78,7 @@ 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;
|
||||
}
|
||||
|
||||
|
|
@ -80,7 +87,8 @@ bool FileContent::operator== (const FileContent &other) const {
|
|||
return Content::operator==(other) &&
|
||||
d->fileName == other.getFileName() &&
|
||||
d->filePath == other.getFilePath() &&
|
||||
d->fileSize == other.getFileSize();
|
||||
d->fileSize == other.getFileSize() &&
|
||||
d->fileKey == other.getFileKey();
|
||||
}
|
||||
|
||||
void FileContent::setFileSize (size_t size) {
|
||||
|
|
@ -113,12 +121,28 @@ 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;
|
||||
}
|
||||
|
||||
bool FileContent::isFileTransfer () const {
|
||||
return false;
|
||||
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
|
||||
|
|
|
|||
|
|
@ -48,8 +48,13 @@ 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;
|
||||
bool isFileTransfer () const override;
|
||||
|
||||
// TODO: Remove me later.
|
||||
LinphoneContent *toLinphoneContent () const override;
|
||||
|
||||
private:
|
||||
L_DECLARE_PRIVATE(FileContent);
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ public:
|
|||
string filePath;
|
||||
FileContent *fileContent = nullptr;
|
||||
size_t fileSize = 0;
|
||||
std::vector<char> fileKey;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -52,7 +51,6 @@ 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) {
|
||||
|
|
@ -62,7 +60,6 @@ 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) {
|
||||
|
|
@ -74,7 +71,6 @@ FileTransferContent &FileTransferContent::operator= (const FileTransferContent &
|
|||
d->filePath = other.getFilePath();
|
||||
d->fileContent = other.getFileContent();
|
||||
d->fileSize = other.getFileSize();
|
||||
d->fileKey = other.getFileKey();
|
||||
}
|
||||
|
||||
return *this;
|
||||
|
|
@ -88,8 +84,6 @@ 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;
|
||||
}
|
||||
|
||||
|
|
@ -152,32 +146,17 @@ size_t FileTransferContent::getFileSize () const {
|
|||
return d->fileSize;
|
||||
}
|
||||
|
||||
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();
|
||||
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;
|
||||
}
|
||||
|
||||
bool FileTransferContent::isFileTransfer () const {
|
||||
return true;
|
||||
}
|
||||
|
||||
LINPHONE_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -20,8 +20,6 @@
|
|||
#ifndef _L_FILE_TRANSFER_CONTENT_H_
|
||||
#define _L_FILE_TRANSFER_CONTENT_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "content.h"
|
||||
|
||||
// =============================================================================
|
||||
|
|
@ -57,13 +55,10 @@ public:
|
|||
void setFileSize (size_t size);
|
||||
size_t getFileSize () const;
|
||||
|
||||
void setFileKey (const char *key, size_t size);
|
||||
const std::vector<char> &getFileKey () const;
|
||||
const char *getFileKeyAsString () const;
|
||||
size_t getFileKeySize() const;
|
||||
|
||||
bool isFile () const override;
|
||||
bool isFileTransfer () const override;
|
||||
|
||||
// TODO: Remove me later.
|
||||
LinphoneContent *toLinphoneContent () const override;
|
||||
|
||||
private:
|
||||
L_DECLARE_PRIVATE(FileTransferContent);
|
||||
|
|
|
|||
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
* header-p.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.
|
||||
*/
|
||||
|
||||
#ifndef _L_HEADER_P_H_
|
||||
#define _L_HEADER_P_H_
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "object/clonable-object-p.h"
|
||||
|
||||
#include "header.h"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
LINPHONE_BEGIN_NAMESPACE
|
||||
|
||||
class HeaderPrivate : public ClonableObjectPrivate {
|
||||
private:
|
||||
std::string name;
|
||||
std::string value;
|
||||
std::list<HeaderParam> parameters;
|
||||
L_DECLARE_PUBLIC(Header);
|
||||
};
|
||||
|
||||
LINPHONE_END_NAMESPACE
|
||||
|
||||
#endif // ifndef _L_HEADER_P_H_
|
||||
|
|
@ -1,108 +0,0 @@
|
|||
/*
|
||||
* header-param.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/utils/utils.h"
|
||||
|
||||
#include "header-param.h"
|
||||
#include "object/clonable-object-p.h"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
using namespace std;
|
||||
|
||||
LINPHONE_BEGIN_NAMESPACE
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class HeaderParamPrivate : public ClonableObjectPrivate {
|
||||
public:
|
||||
string name;
|
||||
string value;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
HeaderParam::HeaderParam (const string ¶m) : ClonableObject(*new HeaderParamPrivate) {
|
||||
size_t pos = param.find("=");
|
||||
size_t end = param.length();
|
||||
|
||||
if (pos == string::npos) {
|
||||
setName(param);
|
||||
} else {
|
||||
setName(param.substr(0, pos));
|
||||
setValue(param.substr(pos + 1, end - (pos + 1)));
|
||||
}
|
||||
}
|
||||
|
||||
HeaderParam::HeaderParam (const string &name, const string &value) : ClonableObject(*new HeaderParamPrivate) {
|
||||
setName(name);
|
||||
setValue(value);
|
||||
}
|
||||
|
||||
HeaderParam::HeaderParam (const HeaderParam &other) : HeaderParam(other.getName(), other.getValue()) {}
|
||||
|
||||
HeaderParam &HeaderParam::operator= (const HeaderParam &other) {
|
||||
if (this != &other) {
|
||||
setName(other.getName());
|
||||
setValue(other.getValue());
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool HeaderParam::operator== (const HeaderParam &other) const {
|
||||
return getName() == other.getName() &&
|
||||
getValue() == other.getValue();
|
||||
}
|
||||
|
||||
bool HeaderParam::operator!= (const HeaderParam &other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
const string &HeaderParam::getName () const {
|
||||
L_D();
|
||||
return d->name;
|
||||
}
|
||||
|
||||
bool HeaderParam::setName (const string &name) {
|
||||
L_D();
|
||||
d->name = name;
|
||||
return true;
|
||||
}
|
||||
|
||||
const string &HeaderParam::getValue () const {
|
||||
L_D();
|
||||
return d->value;
|
||||
}
|
||||
|
||||
bool HeaderParam::setValue (const string &value) {
|
||||
L_D();
|
||||
d->value = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
string HeaderParam::asString () const {
|
||||
L_D();
|
||||
string asString = ";" + d->name;
|
||||
if (!d->value.empty())
|
||||
asString += "=" + d->value;
|
||||
return asString;
|
||||
}
|
||||
|
||||
LINPHONE_END_NAMESPACE
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
/*
|
||||
* header-param.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.
|
||||
*/
|
||||
|
||||
#ifndef _L_HEADER_PARAM_H_
|
||||
#define _L_HEADER_PARAM_H_
|
||||
|
||||
#include "object/clonable-object.h"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
LINPHONE_BEGIN_NAMESPACE
|
||||
|
||||
class HeaderParamPrivate;
|
||||
|
||||
class LINPHONE_PUBLIC HeaderParam : public ClonableObject {
|
||||
public:
|
||||
explicit HeaderParam (const std::string &header = "");
|
||||
HeaderParam (const std::string &name, const std::string &value);
|
||||
HeaderParam (const HeaderParam &other);
|
||||
|
||||
HeaderParam &operator= (const HeaderParam &other);
|
||||
|
||||
bool operator== (const HeaderParam &other) const;
|
||||
bool operator!= (const HeaderParam &other) const;
|
||||
|
||||
// Delete these operators to prevent putting complicated content-type strings
|
||||
// in the code. Instead define static const HeaderParam objects below.
|
||||
bool operator== (const std::string &other) const = delete;
|
||||
bool operator!= (const std::string &other) const = delete;
|
||||
|
||||
const std::string &getName () const;
|
||||
bool setName (const std::string &name);
|
||||
|
||||
const std::string &getValue () const;
|
||||
bool setValue (const std::string &value);
|
||||
|
||||
std::string asString () const;
|
||||
|
||||
private:
|
||||
L_DECLARE_PRIVATE(HeaderParam);
|
||||
};
|
||||
|
||||
LINPHONE_END_NAMESPACE
|
||||
|
||||
#endif // ifndef _L_HEADER_PARAM_H_
|
||||
|
|
@ -1,183 +0,0 @@
|
|||
/*
|
||||
* header.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 <sstream>
|
||||
|
||||
#include "linphone/utils/utils.h"
|
||||
#include "linphone/utils/algorithm.h"
|
||||
|
||||
#include "header-p.h"
|
||||
#include "header-param.h"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
using namespace std;
|
||||
|
||||
LINPHONE_BEGIN_NAMESPACE
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
Header::Header(HeaderPrivate &p) : ClonableObject(p) {}
|
||||
|
||||
Header::Header() : ClonableObject(*new HeaderPrivate) {}
|
||||
|
||||
Header::Header (const string &name, const string &value) : ClonableObject(*new HeaderPrivate) {
|
||||
setName(name);
|
||||
|
||||
size_t posParam = value.find(";");
|
||||
if (posParam == string::npos) {
|
||||
setValue(value);
|
||||
return;
|
||||
}
|
||||
|
||||
string parsedValue = value.substr(0, posParam);
|
||||
string params = value.substr(posParam + 1);
|
||||
string token;
|
||||
do {
|
||||
posParam = params.find(";");
|
||||
if (posParam == string::npos) {
|
||||
token = params;
|
||||
} else {
|
||||
token = params.substr(0, posParam);
|
||||
}
|
||||
addParameter(HeaderParam(token));
|
||||
params.erase(0, posParam + 1);
|
||||
} while (posParam != std::string::npos);
|
||||
|
||||
setValue(parsedValue);
|
||||
}
|
||||
|
||||
Header::Header (const string &name, const string &value, const list<HeaderParam> ¶ms) : Header(name, value) {
|
||||
addParameters(params);
|
||||
}
|
||||
|
||||
Header::Header (const Header &other) : Header(other.getName(), other.getValue(), other.getParameters()) {}
|
||||
|
||||
Header &Header::operator= (const Header &other) {
|
||||
if (this != &other) {
|
||||
setName(other.getName());
|
||||
setValue(other.getValue());
|
||||
cleanParameters();
|
||||
addParameters(other.getParameters());
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool Header::operator== (const Header &other) const {
|
||||
return getName() == other.getName() &&
|
||||
getValue() == other.getValue();
|
||||
}
|
||||
|
||||
bool Header::operator!= (const Header &other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
void Header::setName (const string &name) {
|
||||
L_D();
|
||||
d->name = name;
|
||||
}
|
||||
|
||||
string Header::getName () const {
|
||||
L_D();
|
||||
return d->name;
|
||||
}
|
||||
|
||||
void Header::setValue (const string &value) {
|
||||
L_D();
|
||||
d->value = value;
|
||||
}
|
||||
|
||||
string Header::getValue () const {
|
||||
L_D();
|
||||
return d->value;
|
||||
}
|
||||
|
||||
void Header::cleanParameters () {
|
||||
L_D();
|
||||
d->parameters.clear();
|
||||
}
|
||||
|
||||
const list<HeaderParam> &Header::getParameters () const {
|
||||
L_D();
|
||||
return d->parameters;
|
||||
}
|
||||
|
||||
void Header::addParameter (const string ¶mName, const string ¶mValue) {
|
||||
addParameter(HeaderParam(paramName, paramValue));
|
||||
}
|
||||
|
||||
void Header::addParameter (const HeaderParam ¶m) {
|
||||
L_D();
|
||||
removeParameter(param);
|
||||
d->parameters.push_back(param);
|
||||
}
|
||||
|
||||
void Header::addParameters(const list<HeaderParam> ¶ms) {
|
||||
for (auto it = std::begin(params); it!=std::end(params); ++it) {
|
||||
HeaderParam param = *it;
|
||||
addParameter(param.getName(), param.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
void Header::removeParameter (const string ¶mName) {
|
||||
L_D();
|
||||
auto it = findParameter(paramName);
|
||||
if (it != d->parameters.cend())
|
||||
d->parameters.remove(*it);
|
||||
}
|
||||
|
||||
void Header::removeParameter (const HeaderParam ¶m) {
|
||||
removeParameter(param.getName());
|
||||
}
|
||||
|
||||
list<HeaderParam>::const_iterator Header::findParameter (const string ¶mName) const {
|
||||
L_D();
|
||||
return findIf(d->parameters, [¶mName](const HeaderParam ¶m) {
|
||||
return param.getName() == paramName;
|
||||
});
|
||||
}
|
||||
|
||||
const HeaderParam &Header::getParameter (const string ¶mName) const {
|
||||
L_D();
|
||||
list<HeaderParam>::const_iterator it = findParameter(paramName);
|
||||
if (it != d->parameters.cend()) {
|
||||
return *it;
|
||||
}
|
||||
return Utils::getEmptyConstRefObject<HeaderParam>();
|
||||
}
|
||||
|
||||
string Header::asString () const {
|
||||
stringstream asString;
|
||||
if (!getName().empty()) {
|
||||
asString << getName() << ":";
|
||||
}
|
||||
asString << getValue();
|
||||
for (const auto ¶m : getParameters()) {
|
||||
asString << param.asString();
|
||||
}
|
||||
return asString.str();
|
||||
}
|
||||
|
||||
ostream &operator<<(ostream& stream, const Header& header) {
|
||||
stream << header.asString();
|
||||
return stream;
|
||||
}
|
||||
|
||||
LINPHONE_END_NAMESPACE
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
/*
|
||||
* header.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.
|
||||
*/
|
||||
|
||||
#ifndef _L_HEADER_H_
|
||||
#define _L_HEADER_H_
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "object/clonable-object.h"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
LINPHONE_BEGIN_NAMESPACE
|
||||
|
||||
class HeaderPrivate;
|
||||
class HeaderParam;
|
||||
|
||||
class LINPHONE_PUBLIC Header : public ClonableObject {
|
||||
public:
|
||||
Header ();
|
||||
Header (const std::string &name, const std::string &value);
|
||||
Header (const std::string &name, const std::string &value, const std::list<HeaderParam> ¶ms);
|
||||
Header (const Header &other);
|
||||
|
||||
Header &operator= (const Header &other);
|
||||
|
||||
bool operator== (const Header &other) const;
|
||||
bool operator!= (const Header &other) const;
|
||||
|
||||
void setName (const std::string &name);
|
||||
std::string getName () const;
|
||||
|
||||
void setValue (const std::string &value);
|
||||
std::string getValue () const;
|
||||
|
||||
void cleanParameters ();
|
||||
const std::list<HeaderParam> &getParameters () const;
|
||||
void addParameter (const std::string ¶mName, const std::string ¶mValue);
|
||||
void addParameter (const HeaderParam ¶m);
|
||||
void addParameters(const std::list<HeaderParam> ¶ms);
|
||||
void removeParameter (const std::string ¶mName);
|
||||
void removeParameter (const HeaderParam ¶m);
|
||||
std::list<HeaderParam>::const_iterator findParameter (const std::string ¶mName) const;
|
||||
const HeaderParam &getParameter (const std::string ¶mName) const;
|
||||
|
||||
std::string asString () const;
|
||||
friend std::ostream &operator<<(std::ostream&, const Header&);
|
||||
|
||||
protected:
|
||||
explicit Header (HeaderPrivate &p);
|
||||
|
||||
private:
|
||||
L_DECLARE_PRIVATE(Header);
|
||||
};
|
||||
|
||||
LINPHONE_END_NAMESPACE
|
||||
|
||||
#endif // ifndef _L_HEADER_H_
|
||||
|
|
@ -2226,7 +2226,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.
|
||||
|
|
|
|||
|
|
@ -1029,18 +1029,12 @@ void SalOp::process_incoming_message(const belle_sip_request_event_t *event) {
|
|||
/* if we just deciphered a message, use the deciphered part(which can be a rcs xml body pointing to the file to retreive from server)*/
|
||||
salmsg.text=(!external_body)?belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)):NULL;
|
||||
salmsg.url=NULL;
|
||||
|
||||
char buffer[1024];
|
||||
size_t offset = 0;
|
||||
belle_sip_parameters_marshal(BELLE_SIP_PARAMETERS(content_type), buffer, 1024, &offset);
|
||||
buffer[offset] = '\0';
|
||||
salmsg.content_type = ms_strdup_printf("%s/%s%s", belle_sip_header_content_type_get_type(content_type), belle_sip_header_content_type_get_subtype(content_type), buffer);
|
||||
salmsg.content_type = ms_strdup_printf("%s/%s", belle_sip_header_content_type_get_type(content_type), belle_sip_header_content_type_get_subtype(content_type));
|
||||
if (external_body && belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(content_type),"URL")) {
|
||||
size_t url_length=strlen(belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(content_type),"URL"));
|
||||
salmsg.url = ms_strdup(belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(content_type),"URL")+1); /* skip first "*/
|
||||
((char*)salmsg.url)[url_length-2]='\0'; /*remove trailing "*/
|
||||
}
|
||||
|
||||
salmsg.message_id=message_id;
|
||||
salmsg.time=date ? belle_sip_header_date_get_time(date) : time(NULL);
|
||||
this->root->callbacks.message_received(this,&salmsg);
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ set(SOURCE_FILES_C
|
|||
set(SOURCE_FILES_CXX
|
||||
clonable-object-tester.cpp
|
||||
conference-event-tester.cpp
|
||||
contents-tester.cpp
|
||||
content-manager-tester.cpp
|
||||
cpim-tester.cpp
|
||||
main-db-tester.cpp
|
||||
multipart-tester.cpp
|
||||
|
|
|
|||
|
|
@ -21,15 +21,13 @@
|
|||
#include "content/content-manager.h"
|
||||
#include "content/content-type.h"
|
||||
#include "content/content.h"
|
||||
#include "content/header/header-param.h"
|
||||
#include "liblinphone_tester.h"
|
||||
#include "tester_utils.h"
|
||||
#include "logger/logger.h"
|
||||
|
||||
using namespace LinphonePrivate;
|
||||
using namespace std;
|
||||
|
||||
static const char* source_multipart = \
|
||||
static const char* multipart = \
|
||||
"-----------------------------14737809831466499882746641449\r\n" \
|
||||
"Content-Type: application/rlmi+xml;charset=\"UTF-8\"\r\n\r\n" \
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>" \
|
||||
|
|
@ -62,7 +60,6 @@ static const char* source_multipart = \
|
|||
" </p1:person>" \
|
||||
"</presence>" \
|
||||
"-----------------------------14737809831466499882746641449\r\n" \
|
||||
"Content-Encoding: b64\r\n" \
|
||||
"Content-Type: application/pidf+xml;charset=\"UTF-8\"\r\n\r\n" \
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>" \
|
||||
"<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" entity=\"sip:+XXXXXXXXXX@sip.linphone.org;user=phone\" xmlns:p1=\"urn:ietf:params:xml:ns:pidf:data-model\">" \
|
||||
|
|
@ -80,7 +77,6 @@ static const char* source_multipart = \
|
|||
" </p1:person>" \
|
||||
"</presence>" \
|
||||
"-----------------------------14737809831466499882746641449\r\n" \
|
||||
"Content-Id: toto;param1=value1;param2;param3=value3\r\n" \
|
||||
"Content-Type: application/pidf+xml;charset=\"UTF-8\"\r\n\r\n" \
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>" \
|
||||
"<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" entity=\"sip:+ZZZZZZZZZZ@sip.linphone.org;user=phone\" xmlns:p1=\"urn:ietf:params:xml:ns:pidf:data-model\">" \
|
||||
|
|
@ -99,80 +95,6 @@ static const char* source_multipart = \
|
|||
"</presence>" \
|
||||
"-----------------------------14737809831466499882746641449--\r\n";
|
||||
|
||||
static const char* generated_multipart = \
|
||||
"-----------------------------14737809831466499882746641449\r\n" \
|
||||
"Content-Type: application/rlmi+xml;charset=\"UTF-8\"\r\n" \
|
||||
"Content-Length:582\r\n\r\n" \
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>" \
|
||||
"<list xmlns=\"urn:ietf:params:xml:ns:rlmi\" fullState=\"false\" uri=\"sip:rls@sip.linphone.org\" version=\"1\">" \
|
||||
" <resource uri=\"sip:+YYYYYYYYYY@sip.linphone.org;user=phone\">" \
|
||||
" <instance cid=\"LO3VOS4@sip.linphone.org\" id=\"1\" state=\"active\"/>" \
|
||||
" </resource>" \
|
||||
" <resource uri=\"sip:+XXXXXXXXXX@sip.linphone.org;user=phone\">" \
|
||||
" <instance cid=\"5v6tTNM@sip.linphone.org\" id=\"1\" state=\"active\"/>" \
|
||||
" </resource>" \
|
||||
" <resource uri=\"sip:+ZZZZZZZZZZ@sip.linphone.org;user=phone\">" \
|
||||
" <instance cid=\"P2WAj~Y@sip.linphone.org\" id=\"1\" state=\"active\"/>" \
|
||||
" </resource>" \
|
||||
"</list>" \
|
||||
"-----------------------------14737809831466499882746641449\r\n" \
|
||||
"Content-Type: application/pidf+xml;charset=\"UTF-8\"\r\n" \
|
||||
"Content-Length:561\r\n\r\n" \
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>" \
|
||||
"<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" entity=\"sip:+YYYYYYYYYY@sip.linphone.org;user=phone\" xmlns:p1=\"urn:ietf:params:xml:ns:pidf:data-model\">" \
|
||||
" <tuple id=\"qmht-9\">" \
|
||||
" <status>" \
|
||||
" <basic>open</basic>" \
|
||||
" </status>" \
|
||||
" <contact>sip:+YYYYYYYYYY@sip.linphone.org;user=phone</contact>" \
|
||||
" <timestamp>2017-10-25T13:18:26</timestamp>" \
|
||||
" </tuple>" \
|
||||
" <p1:person id=\"sip:+YYYYYYYYYY@sip.linphone.org;user=phone\" xmlns:p2=\"urn:ietf:params:xml:ns:pidf:rpid\">" \
|
||||
" <p2:activities>" \
|
||||
" <p2:away/>" \
|
||||
" </p2:activities>" \
|
||||
" </p1:person>" \
|
||||
"</presence>" \
|
||||
"-----------------------------14737809831466499882746641449\r\n" \
|
||||
"Content-Encoding:b64\r\n" \
|
||||
"Content-Type: application/pidf+xml;charset=\"UTF-8\"\r\n" \
|
||||
"Content-Length:561\r\n\r\n" \
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>" \
|
||||
"<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" entity=\"sip:+XXXXXXXXXX@sip.linphone.org;user=phone\" xmlns:p1=\"urn:ietf:params:xml:ns:pidf:data-model\">" \
|
||||
" <tuple id=\"szohvt\">" \
|
||||
" <status>" \
|
||||
" <basic>open</basic>" \
|
||||
" </status>" \
|
||||
" <contact>sip:+XXXXXXXXXX@sip.linphone.org;user=phone</contact>" \
|
||||
" <timestamp>2017-10-25T13:18:26</timestamp>" \
|
||||
" </tuple>" \
|
||||
" <p1:person id=\"sip:+XXXXXXXXXX@sip.linphone.org;user=phone\" xmlns:p2=\"urn:ietf:params:xml:ns:pidf:rpid\">" \
|
||||
" <p2:activities>" \
|
||||
" <p2:away/>" \
|
||||
" </p2:activities>" \
|
||||
" </p1:person>" \
|
||||
"</presence>" \
|
||||
"-----------------------------14737809831466499882746641449\r\n" \
|
||||
"Content-Id:toto;param1=value1;param2;param3=value3\r\n" \
|
||||
"Content-Type: application/pidf+xml;charset=\"UTF-8\"\r\n" \
|
||||
"Content-Length:546\r\n\r\n" \
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>" \
|
||||
"<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" entity=\"sip:+ZZZZZZZZZZ@sip.linphone.org;user=phone\" xmlns:p1=\"urn:ietf:params:xml:ns:pidf:data-model\">" \
|
||||
" <tuple id=\"oc3e08\">" \
|
||||
" <status>" \
|
||||
" <basic>open</basic>" \
|
||||
" </status>" \
|
||||
" <contact>sip:someone@sip.linphone.org</contact>" \
|
||||
" <timestamp>2017-10-25T13:18:26</timestamp>" \
|
||||
" </tuple>" \
|
||||
" <p1:person id=\"sip:+ZZZZZZZZZZ@sip.linphone.org;user=phone\" xmlns:p2=\"urn:ietf:params:xml:ns:pidf:rpid\">" \
|
||||
" <p2:activities>" \
|
||||
" <p2:away/>" \
|
||||
" </p2:activities>" \
|
||||
" </p1:person>" \
|
||||
"</presence>" \
|
||||
"-----------------------------14737809831466499882746641449--\r\n";
|
||||
|
||||
static const char* part1 = \
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>" \
|
||||
"<list xmlns=\"urn:ietf:params:xml:ns:rlmi\" fullState=\"false\" uri=\"sip:rls@sip.linphone.org\" version=\"1\">" \
|
||||
|
|
@ -240,7 +162,7 @@ static const char* part4 = \
|
|||
|
||||
void multipart_to_list () {
|
||||
Content multipartContent;
|
||||
multipartContent.setBody(source_multipart);
|
||||
multipartContent.setBody(multipart);
|
||||
multipartContent.setContentType(ContentType("multipart", "related"));
|
||||
|
||||
list<Content> contents = ContentManager::multipartToContentList(multipartContent);
|
||||
|
|
@ -298,7 +220,6 @@ void multipart_to_list () {
|
|||
ms_message("\n\n----- Original part 3 -----");
|
||||
ms_message("%s", originalStr3.c_str());
|
||||
BC_ASSERT_TRUE(originalStr3 == generatedStr3);
|
||||
BC_ASSERT_TRUE(content3.getHeader("Content-Encoding").getValue() == "b64");
|
||||
|
||||
Content content4 = contents.front();
|
||||
contents.pop_front();
|
||||
|
|
@ -313,43 +234,29 @@ void multipart_to_list () {
|
|||
generatedStr4.erase(std::remove(generatedStr4.begin(), generatedStr4.end(), '\r'), generatedStr4.end());
|
||||
generatedStr4.erase(std::remove(generatedStr4.begin(), generatedStr4.end(), '\n'), generatedStr4.end());
|
||||
ms_message("\n\n----- Generated part 4 -----");
|
||||
ms_message("%s", generatedStr4.c_str());
|
||||
ms_message("%s", generatedStr3.c_str());
|
||||
ms_message("\n\n----- Original part 4 -----");
|
||||
ms_message("%s", originalStr4.c_str());
|
||||
BC_ASSERT_TRUE(originalStr4 == generatedStr4);
|
||||
BC_ASSERT_TRUE(content4.getHeader("Content-Id").getValue() == "toto");
|
||||
BC_ASSERT_TRUE(content4.getHeader("Content-Id").getParameter("param1").getValue() == "value1");
|
||||
BC_ASSERT_TRUE(content4.getHeader("Content-Id").getParameter("param2").getValue().empty());
|
||||
BC_ASSERT_TRUE(content4.getHeader("Content-Id").getParameter("param3").getValue() == "value3");
|
||||
}
|
||||
|
||||
void list_to_multipart () {
|
||||
ContentType contentType = ContentType("application", "rlmi+xml");
|
||||
contentType.addParameter("charset", "\"UTF-8\"");
|
||||
Content content1;
|
||||
content1.setBody(part1);
|
||||
content1.setContentType(contentType);
|
||||
contentType = ContentType("application", "pidf+xml");
|
||||
contentType.addParameter("charset", "\"UTF-8\"");
|
||||
content1.setContentType(ContentType("application", "rlmi+xml"));
|
||||
Content content2;
|
||||
content2.setBody(part2);
|
||||
content2.setContentType(contentType);
|
||||
content2.setContentType(ContentType("application", "pidf+xml"));
|
||||
Content content3;
|
||||
content3.setBody(part3);
|
||||
content3.addHeader("Content-Encoding", "b64");
|
||||
content3.setContentType(contentType);
|
||||
content3.setContentType(ContentType("application", "pidf+xml"));
|
||||
Content content4;
|
||||
Header header = Header("Content-Id", "toto");
|
||||
header.addParameter("param1", "value1");
|
||||
header.addParameter("param2", "");
|
||||
header.addParameter("param3", "value3");
|
||||
content4.addHeader(header);
|
||||
content4.setBody(part4);
|
||||
content4.setContentType(contentType);
|
||||
list<Content *> contents = {&content1, &content2, &content3, &content4};
|
||||
content4.setContentType(ContentType("application", "pidf+xml"));
|
||||
list<Content> contents = {content1, content2, content3, content4};
|
||||
|
||||
Content multipartContent = ContentManager::contentListToMultipart(contents);
|
||||
string originalStr(generated_multipart);
|
||||
string originalStr(multipart);
|
||||
originalStr.erase(std::remove(originalStr.begin(), originalStr.end(), ' '), originalStr.end());
|
||||
originalStr.erase(std::remove(originalStr.begin(), originalStr.end(), '\t'), originalStr.end());
|
||||
originalStr.erase(std::remove(originalStr.begin(), originalStr.end(), '\r'), originalStr.end());
|
||||
|
|
@ -369,67 +276,16 @@ void list_to_multipart () {
|
|||
BC_ASSERT_TRUE(originalStr == generatedStr);
|
||||
}
|
||||
|
||||
static void content_type_parsing(void) {
|
||||
string type = "message/external-body;access-type=URL;URL=\"https://www.linphone.org/img/linphone-open-source-voip-projectX2.png\"";
|
||||
ContentType contentType = ContentType(type);
|
||||
BC_ASSERT_STRING_EQUAL("message", contentType.getType().c_str());
|
||||
BC_ASSERT_STRING_EQUAL("external-body", contentType.getSubType().c_str());
|
||||
BC_ASSERT_STRING_EQUAL("URL", contentType.getParameter("access-type").getValue().c_str());
|
||||
BC_ASSERT_STRING_EQUAL("\"https://www.linphone.org/img/linphone-open-source-voip-projectX2.png\"", contentType.getParameter("URL").getValue().c_str());
|
||||
BC_ASSERT_STRING_EQUAL("", contentType.getParameter("boundary").getValue().c_str());
|
||||
BC_ASSERT_EQUAL(2, contentType.getParameters().size(), int, "%d");
|
||||
lInfo() << "Content-Type is " << contentType;
|
||||
BC_ASSERT_TRUE(type == contentType.asString());
|
||||
|
||||
type = "multipart/mixed;boundary=-----------------------------14737809831466499882746641450";
|
||||
contentType = ContentType(type);
|
||||
BC_ASSERT_STRING_EQUAL("multipart", contentType.getType().c_str());
|
||||
BC_ASSERT_STRING_EQUAL("mixed", contentType.getSubType().c_str());
|
||||
BC_ASSERT_STRING_EQUAL("-----------------------------14737809831466499882746641450", contentType.getParameter("boundary").getValue().c_str());
|
||||
BC_ASSERT_STRING_EQUAL("", contentType.getParameter("access-type").getValue().c_str());
|
||||
BC_ASSERT_EQUAL(1, contentType.getParameters().size(), int, "%d");
|
||||
lInfo() << "Content-Type is " << contentType;
|
||||
BC_ASSERT_TRUE(type == contentType.asString());
|
||||
|
||||
type = "plain/text";
|
||||
contentType = ContentType(type);
|
||||
BC_ASSERT_STRING_EQUAL("plain", contentType.getType().c_str());
|
||||
BC_ASSERT_STRING_EQUAL("text", contentType.getSubType().c_str());
|
||||
BC_ASSERT_STRING_EQUAL("", contentType.getParameter("boundary").getValue().c_str());
|
||||
BC_ASSERT_EQUAL(0, contentType.getParameters().size(), int, "%d");
|
||||
lInfo() << "Content-Type is " << contentType;
|
||||
BC_ASSERT_TRUE(type == contentType.asString());
|
||||
}
|
||||
|
||||
static void content_header_parsing(void) {
|
||||
string value = "toto;param1=value1;param2;param3=value3";
|
||||
Header header = Header("Content-Id", value);
|
||||
BC_ASSERT_TRUE(header.getValue() == "toto");
|
||||
BC_ASSERT_TRUE(header.getParameter("param1").getValue() == "value1");
|
||||
BC_ASSERT_TRUE(header.getParameter("param2").getValue().empty());
|
||||
BC_ASSERT_TRUE(header.getParameter("param3").getValue() == "value3");
|
||||
BC_ASSERT_EQUAL(3, header.getParameters().size(), int, "%d");
|
||||
BC_ASSERT_STRING_EQUAL("", header.getParameter("encoding").getValue().c_str());
|
||||
|
||||
value = "b64";
|
||||
header = Header("Content-Encoding", value);
|
||||
BC_ASSERT_TRUE(header.getValue() == value);
|
||||
BC_ASSERT_EQUAL(0, header.getParameters().size(), int, "%d");
|
||||
BC_ASSERT_STRING_EQUAL("", header.getParameter("access-type").getValue().c_str());
|
||||
}
|
||||
|
||||
test_t contents_tests[] = {
|
||||
test_t content_manager_tests[] = {
|
||||
TEST_NO_TAG("Multipart to list", multipart_to_list),
|
||||
TEST_NO_TAG("List to multipart", list_to_multipart),
|
||||
TEST_NO_TAG("Content type parsing", content_type_parsing),
|
||||
TEST_NO_TAG("Content header parsing", content_header_parsing)
|
||||
TEST_NO_TAG("List to multipart", list_to_multipart)
|
||||
};
|
||||
|
||||
test_suite_t contents_test_suite = {
|
||||
"Contents",
|
||||
test_suite_t content_manager_test_suite = {
|
||||
"Content manager",
|
||||
nullptr,
|
||||
nullptr,
|
||||
liblinphone_tester_before_each,
|
||||
liblinphone_tester_after_each,
|
||||
sizeof(contents_tests) / sizeof(contents_tests[0]), contents_tests
|
||||
sizeof(content_manager_tests) / sizeof(content_manager_tests[0]), content_manager_tests
|
||||
};
|
||||
|
|
@ -423,12 +423,12 @@ 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();
|
||||
|
||||
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageReceived,1));
|
||||
BC_ASSERT_TRUE(marieMessage->getInternalContent().getContentType().isEmpty()); // Internal content is cleaned after message is sent or received
|
||||
BC_ASSERT_STRING_EQUAL(marieMessage->getInternalContent().getContentType().asString().c_str(), ""); // Internal content is cleaned after message is sent or received
|
||||
|
||||
BC_ASSERT_PTR_NOT_NULL(pauline->stat.last_received_chat_message);
|
||||
if (pauline->stat.last_received_chat_message != NULL) {
|
||||
|
|
|
|||
|
|
@ -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((const char*)linphone_content_get_buffer(content),notify_content);
|
||||
BC_ASSERT_STRING_EQUAL(notify_content,(const char*)linphone_content_get_buffer(content));
|
||||
}
|
||||
mgr=get_manager(lc);
|
||||
mgr->stat.number_of_NotifyReceived++;
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ extern test_suite_t call_video_test_suite;
|
|||
extern test_suite_t clonable_object_test_suite;
|
||||
extern test_suite_t conference_event_test_suite;
|
||||
extern test_suite_t conference_test_suite;
|
||||
extern test_suite_t contents_test_suite;
|
||||
extern test_suite_t content_manager_test_suite;
|
||||
extern test_suite_t cpim_test_suite;
|
||||
extern test_suite_t dtmf_test_suite;
|
||||
extern test_suite_t event_test_suite;
|
||||
|
|
|
|||
|
|
@ -2294,19 +2294,15 @@ void text_message_with_custom_content_type_and_lime(void) {
|
|||
|
||||
|
||||
static int im_encryption_engine_process_incoming_message_cb(LinphoneImEncryptionEngine *engine, LinphoneChatRoom *room, LinphoneChatMessage *msg) {
|
||||
ms_debug("IM encryption process incoming message with content type %s", linphone_chat_message_get_content_type(msg));
|
||||
if (linphone_chat_message_get_content_type(msg)) {
|
||||
if (strcmp(linphone_chat_message_get_content_type(msg), "cipher/b64") == 0) {
|
||||
size_t b64Size = 0;
|
||||
unsigned char *output;
|
||||
const char *data = linphone_chat_message_get_text(msg);
|
||||
ms_debug("IM encryption process incoming message crypted message is %s", data);
|
||||
bctbx_base64_decode(NULL, &b64Size, (unsigned char *)data, strlen(data));
|
||||
bctbx_base64_decode(NULL, &b64Size, (unsigned char *)linphone_chat_message_get_text(msg), strlen(linphone_chat_message_get_text(msg)));
|
||||
output = (unsigned char *)ms_malloc(b64Size+1),
|
||||
bctbx_base64_decode(output, &b64Size, (unsigned char *)data, strlen(data));
|
||||
bctbx_base64_decode(output, &b64Size, (unsigned char *)linphone_chat_message_get_text(msg), strlen(linphone_chat_message_get_text(msg)));
|
||||
output[b64Size] = '\0';
|
||||
linphone_chat_message_set_text(msg, (char *)output);
|
||||
ms_debug("IM encryption process incoming message decrypted message is %s", output);
|
||||
ms_free(output);
|
||||
linphone_chat_message_set_content_type(msg, "text/plain");
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
content->setBody("Hello Part 1");
|
||||
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);
|
||||
content->setBody("Hello Part 2");
|
||||
marieMessage->addContent(*content);
|
||||
}
|
||||
|
||||
linphone_core_set_file_transfer_server(marie->lc,"https://www.linphone.org:444/lft.php");
|
||||
|
|
@ -82,20 +82,7 @@ static void chat_message_multipart_modifier_base(bool first_file_transfer, bool
|
|||
|
||||
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageReceived,1));
|
||||
BC_ASSERT_PTR_NOT_NULL(pauline->stat.last_received_chat_message);
|
||||
|
||||
if (first_file_transfer || second_file_transfer) {
|
||||
LinphoneContent *content = linphone_chat_message_get_file_transfer_information(pauline->stat.last_received_chat_message);
|
||||
BC_ASSERT_PTR_NOT_NULL(content);
|
||||
linphone_content_unref(content);
|
||||
}
|
||||
if (!first_file_transfer || !second_file_transfer) {
|
||||
const char *content = linphone_chat_message_get_text_content(pauline->stat.last_received_chat_message);
|
||||
BC_ASSERT_PTR_NOT_NULL(content);
|
||||
if (!first_file_transfer)
|
||||
BC_ASSERT_STRING_EQUAL(content, "Hello part 1");
|
||||
else if (!second_file_transfer)
|
||||
BC_ASSERT_STRING_EQUAL(content, "Hello part 2");
|
||||
}
|
||||
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_content_type(pauline->stat.last_received_chat_message), "multipart/mixed");
|
||||
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
|
|
|
|||
|
|
@ -430,10 +430,8 @@ static void test_presence_list_base(bool_t enable_compression) {
|
|||
lcs = bctbx_list_append(lcs, pauline->lc);
|
||||
|
||||
wait_for_list(lcs, &laure->stat.number_of_NotifyPresenceReceived, 2, 4000);
|
||||
BC_ASSERT_GREATER(laure->stat.number_of_NotifyPresenceReceived, 2, int, "%d");
|
||||
BC_ASSERT_LOWER(laure->stat.number_of_NotifyPresenceReceived, 3, int, "%d");
|
||||
BC_ASSERT_GREATER(linphone_friend_list_get_expected_notification_version(linphone_core_get_default_friend_list(laure->lc)), 1, int, "%d");
|
||||
BC_ASSERT_LOWER(linphone_friend_list_get_expected_notification_version(linphone_core_get_default_friend_list(laure->lc)), 2, int, "%d");
|
||||
BC_ASSERT_EQUAL(laure->stat.number_of_NotifyPresenceReceived, 2, int, "%d");
|
||||
BC_ASSERT_EQUAL(linphone_friend_list_get_expected_notification_version(linphone_core_get_default_friend_list(laure->lc)), 1, int, "%d");
|
||||
lf = linphone_friend_list_find_friend_by_address(linphone_core_get_default_friend_list(laure->lc), get_identity_address(marie));
|
||||
if (!BC_ASSERT_PTR_NOT_NULL(lf)) goto end;
|
||||
BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusBusy, int, "%d");
|
||||
|
|
@ -487,8 +485,7 @@ static void test_presence_list_base(bool_t enable_compression) {
|
|||
/* The number of PresenceReceived events can be 3 or 4 here. TODO: ideally it should always be 3. */
|
||||
BC_ASSERT_GREATER(laure->stat.number_of_NotifyPresenceReceived, 3, int, "%d");
|
||||
BC_ASSERT_LOWER(laure->stat.number_of_NotifyPresenceReceived, 4, int, "%d");
|
||||
BC_ASSERT_GREATER(linphone_friend_list_get_expected_notification_version(linphone_core_get_default_friend_list(laure->lc)), 2, int, "%d");
|
||||
BC_ASSERT_LOWER(linphone_friend_list_get_expected_notification_version(linphone_core_get_default_friend_list(laure->lc)), 3, int, "%d");
|
||||
BC_ASSERT_EQUAL(linphone_friend_list_get_expected_notification_version(linphone_core_get_default_friend_list(laure->lc)), 2, int, "%d");
|
||||
lf = linphone_friend_list_find_friend_by_address(linphone_core_get_default_friend_list(laure->lc), get_identity_address(marie));
|
||||
BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOnThePhone, int, "%d");
|
||||
|
||||
|
|
|
|||
|
|
@ -606,7 +606,7 @@ void liblinphone_tester_add_suites() {
|
|||
bc_tester_add_suite(&stun_test_suite);
|
||||
bc_tester_add_suite(&event_test_suite);
|
||||
bc_tester_add_suite(&conference_event_test_suite);
|
||||
bc_tester_add_suite(&contents_test_suite);
|
||||
bc_tester_add_suite(&content_manager_test_suite);
|
||||
bc_tester_add_suite(&flexisip_test_suite);
|
||||
bc_tester_add_suite(&remote_provisioning_test_suite);
|
||||
bc_tester_add_suite(&quality_reporting_test_suite);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue