Commit 08c6ab45 authored by Sylvain Berfini's avatar Sylvain Berfini 🐮
Browse files

Fixed issues related to multi file transfer in same ChatMessage + fixed Content user data

parent 735073c8
......@@ -336,9 +336,9 @@ void _linphone_chat_room_clear_callbacks (LinphoneChatRoom *cr);
void _linphone_chat_message_notify_msg_state_changed(LinphoneChatMessage* msg, LinphoneChatMessageState state);
void _linphone_chat_message_notify_participant_imdn_state_changed(LinphoneChatMessage* msg, const LinphoneParticipantImdnState *state);
void _linphone_chat_message_notify_file_transfer_recv(LinphoneChatMessage *msg, const LinphoneContent* content, const LinphoneBuffer *buffer);
void _linphone_chat_message_notify_file_transfer_send(LinphoneChatMessage *msg, const LinphoneContent* content, size_t offset, size_t size);
void _linphone_chat_message_notify_file_transfer_progress_indication(LinphoneChatMessage *msg, const LinphoneContent* content, size_t offset, size_t total);
void _linphone_chat_message_notify_file_transfer_recv(LinphoneChatMessage *msg, LinphoneContent* content, const LinphoneBuffer *buffer);
void _linphone_chat_message_notify_file_transfer_send(LinphoneChatMessage *msg, LinphoneContent* content, size_t offset, size_t size);
void _linphone_chat_message_notify_file_transfer_progress_indication(LinphoneChatMessage *msg, LinphoneContent* content, size_t offset, size_t total);
void _linphone_chat_message_notify_ephemeral_message_timer_started(LinphoneChatMessage* msg);
void _linphone_chat_message_notify_ephemeral_message_deleted(LinphoneChatMessage* msg);
void _linphone_chat_message_clear_callbacks (LinphoneChatMessage *msg);
......@@ -545,9 +545,9 @@ void linphone_core_notify_message_received(LinphoneCore *lc, LinphoneChatRoom *r
void linphone_core_notify_message_sent(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *message);
void linphone_core_notify_message_received_unable_decrypt(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *message);
void linphone_core_notify_chat_room_read(LinphoneCore *lc, LinphoneChatRoom *room);
void linphone_core_notify_file_transfer_recv(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, const char* buff, size_t size);
void linphone_core_notify_file_transfer_send(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, char* buff, size_t* size);
void linphone_core_notify_file_transfer_progress_indication(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t total);
void linphone_core_notify_file_transfer_recv(LinphoneCore *lc, LinphoneChatMessage *message, LinphoneContent* content, const char* buff, size_t size);
void linphone_core_notify_file_transfer_send(LinphoneCore *lc, LinphoneChatMessage *message, LinphoneContent* content, char* buff, size_t* size);
void linphone_core_notify_file_transfer_progress_indication(LinphoneCore *lc, LinphoneChatMessage *message, LinphoneContent* content, size_t offset, size_t total);
void linphone_core_notify_is_composing_received(LinphoneCore *lc, LinphoneChatRoom *room);
void linphone_core_notify_dtmf_received(LinphoneCore* lc, LinphoneCall *call, int dtmf);
/*
......
......@@ -188,17 +188,17 @@ void linphone_core_notify_message_received_unable_decrypt(LinphoneCore *lc, Linp
#else
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
void linphone_core_notify_file_transfer_recv(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, const char* buff, size_t size) {
void linphone_core_notify_file_transfer_recv(LinphoneCore *lc, LinphoneChatMessage *message, LinphoneContent* content, const char* buff, size_t size) {
NOTIFY_IF_EXIST(file_transfer_recv, lc,message,content,buff,size);
cleanup_dead_vtable_refs(lc);
}
void linphone_core_notify_file_transfer_send(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, char* buff, size_t* size) {
void linphone_core_notify_file_transfer_send(LinphoneCore *lc, LinphoneChatMessage *message, LinphoneContent* content, char* buff, size_t* size) {
NOTIFY_IF_EXIST(file_transfer_send, lc,message,content,buff,size);
cleanup_dead_vtable_refs(lc);
}
void linphone_core_notify_file_transfer_progress_indication(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t total) {
void linphone_core_notify_file_transfer_progress_indication(LinphoneCore *lc, LinphoneChatMessage *message, LinphoneContent* content, size_t offset, size_t total) {
NOTIFY_IF_EXIST(file_transfer_progress_indication, lc,message,content,offset,total);
cleanup_dead_vtable_refs(lc);
}
......
......@@ -161,7 +161,7 @@ typedef void (*LinphoneChatMessageCbsParticipantImdnStateChangedCb)(LinphoneChat
* @param content #LinphoneContent incoming content information
* @param buffer #LinphoneBuffer holding the received data. Empty buffer means end of file.
*/
typedef void (*LinphoneChatMessageCbsFileTransferRecvCb)(LinphoneChatMessage *msg, const LinphoneContent* content, const LinphoneBuffer *buffer);
typedef void (*LinphoneChatMessageCbsFileTransferRecvCb)(LinphoneChatMessage *msg, LinphoneContent* content, const LinphoneBuffer *buffer);
/**
* File transfer send callback prototype. This function is called by the core when an outgoing file transfer is started. This function is called until size is set to 0.
......@@ -171,7 +171,7 @@ typedef void (*LinphoneChatMessageCbsFileTransferRecvCb)(LinphoneChatMessage *ms
* @param size the number of bytes expected by the framework
* @return A #LinphoneBuffer object holding the data written by the application. An empty buffer means end of file.
*/
typedef LinphoneBuffer * (*LinphoneChatMessageCbsFileTransferSendCb)(LinphoneChatMessage *msg, const LinphoneContent* content, size_t offset, size_t size);
typedef LinphoneBuffer * (*LinphoneChatMessageCbsFileTransferSendCb)(LinphoneChatMessage *msg, LinphoneContent* content, size_t offset, size_t size);
/**
* File transfer progress indication callback prototype.
......@@ -180,7 +180,7 @@ typedef LinphoneBuffer * (*LinphoneChatMessageCbsFileTransferSendCb)(LinphoneCha
* @param offset The number of bytes sent/received since the beginning of the transfer.
* @param total The total number of bytes to be sent/received.
*/
typedef void (*LinphoneChatMessageCbsFileTransferProgressIndicationCb)(LinphoneChatMessage *msg, const LinphoneContent* content, size_t offset, size_t total);
typedef void (*LinphoneChatMessageCbsFileTransferProgressIndicationCb)(LinphoneChatMessage *msg, LinphoneContent* content, size_t offset, size_t total);
/**
* Callback used to notify an ephemeral message that its lifespan before disappearing has started to decrease.
......
......@@ -232,7 +232,7 @@ typedef void (*LinphoneCoreCbsMessageReceivedUnableDecryptCb)(LinphoneCore *lc,
* @param buff pointer to the received data
* @param size number of bytes to be read from buff. 0 means end of file.
*/
typedef void (*LinphoneCoreFileTransferRecvCb)(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, const char* buff, size_t size);
typedef void (*LinphoneCoreFileTransferRecvCb)(LinphoneCore *lc, LinphoneChatMessage *message, LinphoneContent* content, const char* buff, size_t size);
/**
* File transfer send callback prototype. This function is called by the core upon an outgoing file transfer is started. This function is called until size is set to 0.
......@@ -243,7 +243,7 @@ typedef void (*LinphoneCoreFileTransferRecvCb)(LinphoneCore *lc, LinphoneChatMes
* @param size as input value, it represents the number of bytes expected by the framework. As output value, it means the number of bytes wrote by the application in the buffer. 0 means end of file.
*
*/
typedef void (*LinphoneCoreFileTransferSendCb)(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, char* buff, size_t* size);
typedef void (*LinphoneCoreFileTransferSendCb)(LinphoneCore *lc, LinphoneChatMessage *message, LinphoneContent* content, char* buff, size_t* size);
/**
* File transfer progress indication callback prototype.
......@@ -253,7 +253,7 @@ typedef void (*LinphoneCoreFileTransferSendCb)(LinphoneCore *lc, LinphoneChatMes
* @param offset The number of bytes sent/received since the beginning of the transfer.
* @param total The total number of bytes to be sent/received.
*/
typedef void (*LinphoneCoreFileTransferProgressIndicationCb)(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t total);
typedef void (*LinphoneCoreFileTransferProgressIndicationCb)(LinphoneCore *lc, LinphoneChatMessage *message, LinphoneContent* content, size_t offset, size_t total);
/**
* Is composing notification callback prototype.
......
......@@ -115,6 +115,18 @@ LINPHONE_PUBLIC void linphone_chat_message_resend_2(LinphoneChatMessage *msg);
*/
LINPHONE_PUBLIC void *linphone_vcard_get_belcard(LinphoneVcard *vcard);
/**
* Allow multipart on a basic chat room
* @donotwrap
*/
LINPHONE_PUBLIC void linphone_chat_room_allow_multipart(LinphoneChatRoom *room);
/**
* Allow cpim on a basic chat room
* @donotwrap
*/
LINPHONE_PUBLIC void linphone_chat_room_allow_cpim(LinphoneChatRoom *room);
/**
* @}
*/
......
......@@ -156,15 +156,15 @@ void _linphone_chat_message_notify_participant_imdn_state_changed(LinphoneChatMe
NOTIFY_IF_EXIST(ParticipantImdnStateChanged, participant_imdn_state_changed, msg, state)
}
void _linphone_chat_message_notify_file_transfer_recv(LinphoneChatMessage *msg, const LinphoneContent* content, const LinphoneBuffer *buffer) {
void _linphone_chat_message_notify_file_transfer_recv(LinphoneChatMessage *msg, LinphoneContent* content, const LinphoneBuffer *buffer) {
NOTIFY_IF_EXIST(FileTransferRecv, file_transfer_recv, msg, content, buffer)
}
void _linphone_chat_message_notify_file_transfer_send(LinphoneChatMessage *msg, const LinphoneContent* content, size_t offset, size_t size) {
void _linphone_chat_message_notify_file_transfer_send(LinphoneChatMessage *msg, LinphoneContent* content, size_t offset, size_t size) {
NOTIFY_IF_EXIST(FileTransferSend, file_transfer_send, msg, content, offset, size)
}
void _linphone_chat_message_notify_file_transfer_progress_indication(LinphoneChatMessage *msg, const LinphoneContent* content, size_t offset, size_t total) {
void _linphone_chat_message_notify_file_transfer_progress_indication(LinphoneChatMessage *msg, LinphoneContent* content, size_t offset, size_t total) {
NOTIFY_IF_EXIST(FileTransferProgressIndication, file_transfer_progress_indication, msg, content, offset, total)
}
......@@ -335,7 +335,9 @@ void linphone_chat_message_add_file_content (LinphoneChatMessage *msg, LinphoneC
if (linphone_content_get_size(c_content) > 0) {
fileContent->setBody(linphone_content_get_string_buffer(c_content));
}
fileContent->setUserData(linphone_content_get_user_data(c_content));
L_GET_CPP_PTR_FROM_C_OBJECT(msg)->addContent(fileContent);
lInfo() << "File content [" << fileContent << "] added into message [" << msg << "]";
}
void linphone_chat_message_add_text_content (LinphoneChatMessage *msg, const char *text) {
......
......@@ -81,6 +81,14 @@ static list<LinphonePrivate::IdentityAddress> _get_identity_address_list_from_ad
}
*/
void linphone_chat_room_allow_multipart(LinphoneChatRoom *room) {
L_GET_CPP_PTR_FROM_C_OBJECT(room)->allowMultipart(true);
}
void linphone_chat_room_allow_cpim(LinphoneChatRoom *room) {
L_GET_CPP_PTR_FROM_C_OBJECT(room)->allowCpim(true);
}
// =============================================================================
// Public functions.
// =============================================================================
......
......@@ -85,11 +85,11 @@ void linphone_content_unref (LinphoneContent *content) {
}
void *linphone_content_get_user_data (const LinphoneContent *content) {
return L_GET_USER_DATA_FROM_C_OBJECT(content);
return L_GET_CPP_PTR_FROM_C_OBJECT(content)->getUserData().getValue<void *>();
}
void linphone_content_set_user_data (LinphoneContent *content, void *user_data) {
return L_SET_USER_DATA_FROM_C_OBJECT(content, user_data);
return L_GET_CPP_PTR_FROM_C_OBJECT(content)->setUserData(user_data);
}
// =============================================================================
......
......@@ -64,7 +64,8 @@ public:
virtual void generateFileTransferKey (
const std::shared_ptr<AbstractChatRoom> &ChatRoom,
const std::shared_ptr<ChatMessage> &message
const std::shared_ptr<ChatMessage> &message,
FileTransferContent *fileTransferContent
) {}
virtual int downloadingFile (
......@@ -72,7 +73,8 @@ public:
size_t offset,
const uint8_t *buffer,
size_t size,
uint8_t *decryptedBuffer
uint8_t *decryptedBuffer,
FileTransferContent *fileTransferContent
) { return 0; }
virtual int uploadingFile (
......@@ -80,7 +82,8 @@ public:
size_t offset,
const uint8_t *buffer,
size_t *size,
uint8_t *encryptedBuffer
uint8_t *encryptedBuffer,
FileTransferContent *fileTransferContent
) { return 0; }
virtual void mutualAuthentication (
......
......@@ -100,7 +100,7 @@ bool LegacyEncryptionEngine::isEncryptionEnabledForFileTransfer (const shared_pt
return false;
}
void LegacyEncryptionEngine::generateFileTransferKey (const shared_ptr<AbstractChatRoom> &chatRoom, const shared_ptr<ChatMessage> &message) {
void LegacyEncryptionEngine::generateFileTransferKey (const shared_ptr<AbstractChatRoom> &chatRoom, const shared_ptr<ChatMessage> &message, FileTransferContent *fileTransferContent) {
LinphoneImEncryptionEngine *imee = linphone_core_get_im_encryption_engine(chatRoom->getCore()->getCCore());
LinphoneImEncryptionEngineCbs *imee_cbs = linphone_im_encryption_engine_get_callbacks(imee);
LinphoneImEncryptionEngineCbsGenerateFileTransferKeyCb generate_file_transfer_key_cb =
......@@ -110,7 +110,7 @@ void LegacyEncryptionEngine::generateFileTransferKey (const shared_ptr<AbstractC
}
}
int LegacyEncryptionEngine::downloadingFile (const shared_ptr<ChatMessage> &message, size_t offset, const uint8_t *buffer, size_t size, uint8_t *decryptedBuffer) {
int LegacyEncryptionEngine::downloadingFile (const shared_ptr<ChatMessage> &message, size_t offset, const uint8_t *buffer, size_t size, uint8_t *decryptedBuffer, FileTransferContent *fileTransferContent) {
shared_ptr<AbstractChatRoom> chatRoom = message->getChatRoom();
LinphoneImEncryptionEngine *imee = linphone_core_get_im_encryption_engine(chatRoom->getCore()->getCCore());
LinphoneImEncryptionEngineCbs *imee_cbs = linphone_im_encryption_engine_get_callbacks(imee);
......@@ -121,7 +121,7 @@ int LegacyEncryptionEngine::downloadingFile (const shared_ptr<ChatMessage> &mess
return -1;
}
int LegacyEncryptionEngine::uploadingFile (const shared_ptr<ChatMessage> &message, size_t offset, const uint8_t *buffer, size_t *size, uint8_t *encryptedBuffer) {
int LegacyEncryptionEngine::uploadingFile (const shared_ptr<ChatMessage> &message, size_t offset, const uint8_t *buffer, size_t *size, uint8_t *encryptedBuffer, FileTransferContent *fileTransferContent) {
shared_ptr<AbstractChatRoom> chatRoom = message->getChatRoom();
LinphoneImEncryptionEngine *imee = linphone_core_get_im_encryption_engine(chatRoom->getCore()->getCCore());
LinphoneImEncryptionEngineCbs *imee_cbs = linphone_im_encryption_engine_get_callbacks(imee);
......
......@@ -33,9 +33,9 @@ public:
ChatMessageModifier::Result processIncomingMessage (const std::shared_ptr<ChatMessage> &message, int &errorCode) override;
ChatMessageModifier::Result processOutgoingMessage (const std::shared_ptr<ChatMessage> &message, int &errorCode) override;
bool isEncryptionEnabledForFileTransfer (const std::shared_ptr<AbstractChatRoom> &ChatRoom) override;
void generateFileTransferKey (const std::shared_ptr<AbstractChatRoom> &ChatRoom, const std::shared_ptr<ChatMessage> &message) override;
int downloadingFile (const std::shared_ptr<ChatMessage> &message, size_t offset, const uint8_t *buffer, size_t size, uint8_t *decrypted_buffer) override;
int uploadingFile (const std::shared_ptr<ChatMessage> &message, size_t offset, const uint8_t *buffer, size_t *size, uint8_t *encrypted_buffer) override;
void generateFileTransferKey (const std::shared_ptr<AbstractChatRoom> &ChatRoom, const std::shared_ptr<ChatMessage> &message, FileTransferContent *fileTransferContent) override;
int downloadingFile (const std::shared_ptr<ChatMessage> &message, size_t offset, const uint8_t *buffer, size_t size, uint8_t *decrypted_buffer, FileTransferContent *fileTransferContent) override;
int uploadingFile (const std::shared_ptr<ChatMessage> &message, size_t offset, const uint8_t *buffer, size_t *size, uint8_t *encrypted_buffer, FileTransferContent *fileTransferContent) override;
};
LINPHONE_END_NAMESPACE
......
......@@ -453,19 +453,13 @@ bool LimeX3dhEncryptionEngine::isEncryptionEnabledForFileTransfer (const shared_
void LimeX3dhEncryptionEngine::generateFileTransferKey (
const shared_ptr<AbstractChatRoom> &chatRoom,
const shared_ptr<ChatMessage> &message
const shared_ptr<ChatMessage> &message,
FileTransferContent *fileTransferContent
) {
char keyBuffer [FILE_TRANSFER_KEY_SIZE];// temporary storage of generated key: 192 bits of key + 64 bits of initial vector
// generate a random 192 bits key + 64 bits of initial vector and store it into the file_transfer_information->key field of the msg
sal_get_random_bytes((unsigned char *)keyBuffer, FILE_TRANSFER_KEY_SIZE);
for (Content *content : message->getContents()) {
if (content->isFileTransfer()) {
FileTransferContent *fileTransferContent = static_cast<FileTransferContent *>(content);
fileTransferContent->setFileKey(keyBuffer, FILE_TRANSFER_KEY_SIZE);
return;
}
}
fileTransferContent->setFileKey(keyBuffer, FILE_TRANSFER_KEY_SIZE);
}
int LimeX3dhEncryptionEngine::downloadingFile (
......@@ -473,15 +467,14 @@ int LimeX3dhEncryptionEngine::downloadingFile (
size_t offset,
const uint8_t *buffer,
size_t size,
uint8_t *decrypted_buffer
uint8_t *decrypted_buffer,
FileTransferContent *fileTransferContent
) {
const Content *content = message->getPrivate()->getFileTransferContent();
if (!content)
if (fileTransferContent == nullptr)
return -1;
const FileTransferContent *fileTransferContent = static_cast<const FileTransferContent *>(content);
Content *content = static_cast<Content *>(fileTransferContent);
const char *fileKey = fileTransferContent->getFileKey().data();
if (!fileKey)
return -1;
......@@ -519,31 +512,22 @@ int LimeX3dhEncryptionEngine::uploadingFile (
size_t offset,
const uint8_t *buffer,
size_t *size,
uint8_t *encrypted_buffer
uint8_t *encrypted_buffer,
FileTransferContent *fileTransferContent
) {
const Content *content = message->getPrivate()->getFileTransferContent();
if (!content)
if (fileTransferContent == nullptr)
return -1;
const FileTransferContent *fileTransferContent = dynamic_cast<const FileTransferContent *>(content);
Content *content = static_cast<Content *>(fileTransferContent);
const char *fileKey = fileTransferContent->getFileKey().data();
if (!fileKey)
return -1;
/* This is the final call, get an auth tag and insert it in the fileTransferContent*/
if (!buffer || *size == 0) {
char authTag[FILE_TRANSFER_AUTH_TAG_SIZE]; // store the authentication tag generated at the end of encryption, size is fixed at 16 bytes
int ret=bctbx_aes_gcm_encryptFile(linphone_content_get_cryptoContext_address(L_GET_C_BACK_PTR(content)), NULL, FILE_TRANSFER_AUTH_TAG_SIZE, NULL, authTag);
for (Content *content : message->getContents()) {
if (content->isFileTransfer()) {
FileTransferContent *tmpTransferContent = static_cast<FileTransferContent *>(content);
tmpTransferContent->setFileAuthTag(authTag, 16);
return ret;
}
}
int ret = bctbx_aes_gcm_encryptFile(linphone_content_get_cryptoContext_address(L_GET_C_BACK_PTR(content)), NULL, FILE_TRANSFER_AUTH_TAG_SIZE, NULL, authTag);
fileTransferContent->setFileAuthTag(authTag, 16);
return ret;
}
......
......@@ -93,7 +93,8 @@ public:
void generateFileTransferKey (
const std::shared_ptr<AbstractChatRoom> &ChatRoom,
const std::shared_ptr<ChatMessage> &message
const std::shared_ptr<ChatMessage> &message,
FileTransferContent *fileTransferContent
) override;
int downloadingFile (
......@@ -101,7 +102,8 @@ public:
size_t offset,
const uint8_t *buffer,
size_t size,
uint8_t *decrypted_buffer
uint8_t *decrypted_buffer,
FileTransferContent *fileTransferContent
) override;
int uploadingFile (
......@@ -109,7 +111,8 @@ public:
size_t offset,
const uint8_t *buffer,
size_t *size,
uint8_t *encrypted_buffer
uint8_t *encrypted_buffer,
FileTransferContent *fileTransferContent
) override;
void mutualAuthentication (
......
......@@ -61,10 +61,11 @@ ChatMessageModifier::Result FileTransferChatMessageModifier::encode (const share
chatMessage = message;
currentFileContentToTransfer = nullptr;
currentFileTransferContent = nullptr;
// For each FileContent, upload it and create a FileTransferContent
for (Content *content : message->getContents()) {
if (content->isFile()) {
lInfo() << "Found file content, set it for file upload";
lInfo() << "Found file content [" << content << "], set it for file upload";
FileContent *fileContent = (FileContent *)content;
currentFileContentToTransfer = fileContent;
break;
......@@ -183,7 +184,7 @@ int FileTransferChatMessageModifier::onSendBody (
if (imee) {
size_t max_size = *size;
uint8_t *encrypted_buffer = (uint8_t *)ms_malloc0(max_size);
retval = imee->uploadingFile(L_GET_CPP_PTR_FROM_C_OBJECT(msg), offset, buffer, size, encrypted_buffer);
retval = imee->uploadingFile(L_GET_CPP_PTR_FROM_C_OBJECT(msg), offset, buffer, size, encrypted_buffer, currentFileTransferContent);
if (retval == 0) {
if (*size > max_size) {
lError() << "IM encryption engine process upload file callback returned a size bigger than the size of the buffer, so it will be truncated !";
......@@ -209,7 +210,7 @@ void FileTransferChatMessageModifier::onSendEnd (belle_sip_user_body_handler_t *
EncryptionEngine *imee = message->getCore()->getEncryptionEngine();
if (imee) {
imee->uploadingFile(message, 0, nullptr, 0, nullptr);
imee->uploadingFile(message, 0, nullptr, 0, nullptr, currentFileTransferContent);
}
}
......@@ -247,6 +248,7 @@ void FileTransferChatMessageModifier::processResponseFromPostFile (const belle_h
fileTransferContent->setFileSize(currentFileContentToTransfer->getFileSize()); // Copy file size information
fileTransferContent->setFilePath(currentFileContentToTransfer->getFilePath()); // Copy file path information
message->getPrivate()->addContent(fileTransferContent);
currentFileTransferContent = fileTransferContent;
// shall we encrypt the file
if (isFileEncryptionEnabled && message->getChatRoom()) {
......@@ -254,7 +256,7 @@ void FileTransferChatMessageModifier::processResponseFromPostFile (const belle_h
// actual filename stored in msg->file_transfer_information->name will be set in encrypted msg
first_part_header = "form-data; name=\"File\"; filename=\"filename.txt\"";
imee->generateFileTransferKey(message->getChatRoom(), message);
imee->generateFileTransferKey(message->getChatRoom(), message, currentFileTransferContent);
} else {
first_part_header = "form-data; name=\"File\"; filename=\"" + currentFileContentToTransfer->getFileName() + "\"";
}
......@@ -269,7 +271,7 @@ void FileTransferChatMessageModifier::processResponseFromPostFile (const belle_h
first_part_bh = (belle_sip_body_handler_t *)belle_sip_file_body_handler_new(currentFileContentToTransfer->getFilePath().c_str(), nullptr, this);
belle_sip_file_body_handler_set_user_body_handler((belle_sip_file_body_handler_t *)first_part_bh, body_handler);
// Ensure the file size has been set to the correct value
fileTransferContent->setFileSize(belle_sip_file_body_handler_get_file_size((belle_sip_file_body_handler_t *)first_part_bh));
currentFileTransferContent->setFileSize(belle_sip_file_body_handler_get_file_size((belle_sip_file_body_handler_t *)first_part_bh));
} else if (!currentFileContentToTransfer->isEmpty()) {
first_part_bh = (belle_sip_body_handler_t *)belle_sip_memory_body_handler_new_from_buffer(
ms_strdup(currentFileContentToTransfer->getBodyAsString().c_str()),
......@@ -290,24 +292,11 @@ void FileTransferChatMessageModifier::processResponseFromPostFile (const belle_h
fileUploadBeginBackgroundTask();
uploadFile(BELLE_SIP_BODY_HANDLER(bh));
} else if (code == 200) { // file has been uploaded correctly, get server reply and send it
FileTransferContent *fileTransferContent = nullptr;
for (Content *c : message->getPrivate()->getContents()) {
if (c->isFileTransfer()) {
FileTransferContent *tmpContent = static_cast<FileTransferContent *>(c);
if (!tmpContent->getFileContent() && tmpContent->getSize() == 0) {
// If FileTransferContent doesn't have a FileContent yet and is empty
// It's the one we seek, otherwise it may be a previous uploaded FileTransferContent
fileTransferContent = tmpContent;
break;
}
}
}
const char *body = belle_sip_message_get_body((belle_sip_message_t *)event->response);
if (body && strlen(body) > 0) {
// if we have an encryption key for the file, we must insert it into the msg and restore the correct filename
const unsigned char *contentKey = reinterpret_cast<const unsigned char *>(fileTransferContent->getFileKey().data());
size_t contentKeySize = fileTransferContent->getFileKeySize();
const unsigned char *contentKey = reinterpret_cast<const unsigned char *>(currentFileTransferContent->getFileKey().data());
size_t contentKeySize = currentFileTransferContent->getFileKeySize();
if (contentKeySize > 0) {
// parse the msg body
xmlDocPtr xmlMessageBody = xmlParseDoc((const xmlChar *)body);
......@@ -339,9 +328,9 @@ void FileTransferChatMessageModifier::processResponseFromPostFile (const belle_h
ms_free(keyb64);
// Do we have an authentication tag? If yes insert it
size_t contentAuthTagSize = fileTransferContent->getFileAuthTagSize();
size_t contentAuthTagSize = currentFileTransferContent->getFileAuthTagSize();
if (contentAuthTagSize>0) {
const unsigned char *contentAuthTag = reinterpret_cast<const unsigned char *>(fileTransferContent->getFileAuthTag().data());
const unsigned char *contentAuthTag = reinterpret_cast<const unsigned char *>(currentFileTransferContent->getFileAuthTag().data());
// Convert it to b64
b64Size=0;
bctbx_base64_encode(nullptr, &b64Size, contentAuthTag, contentAuthTagSize);
......@@ -372,7 +361,7 @@ void FileTransferChatMessageModifier::processResponseFromPostFile (const belle_h
char *buffer;
int xmlStringLength;
xmlDocDumpFormatMemoryEnc(xmlMessageBody, (xmlChar **)&buffer, &xmlStringLength, "UTF-8", 0);
fileTransferContent->setBody(buffer);
currentFileTransferContent->setBody(buffer);
break;
}
xmlFree(typeAttribute);
......@@ -382,13 +371,12 @@ void FileTransferChatMessageModifier::processResponseFromPostFile (const belle_h
}
xmlFreeDoc(xmlMessageBody);
} else { // no encryption key, transfer in plain, just copy the msg sent by server
fileTransferContent->setBody(body);
currentFileTransferContent->setBody(body);
}
FileContent *fileContent = currentFileContentToTransfer;
fileTransferContent->setFileContent(fileContent);
message->getPrivate()->removeContent(fileContent);
currentFileTransferContent->setFileContent(currentFileContentToTransfer);
message->getPrivate()->removeContent(currentFileContentToTransfer);
currentFileTransferContent = nullptr;
message->getPrivate()->setState(ChatMessage::State::FileTransferDone);
releaseHttpRequest();
......@@ -396,44 +384,29 @@ void FileTransferChatMessageModifier::processResponseFromPostFile (const belle_h
fileUploadEndBackgroundTask();
} else {
lWarning() << "Received empty response from server, file transfer failed";
FileTransferContent *fileTransferContent = nullptr;
for (Content *c : message->getPrivate()->getContents()) {
if (c->isFileTransfer()) {
fileTransferContent = static_cast<FileTransferContent *>(c);
message->getPrivate()->removeContent(fileTransferContent);
delete fileTransferContent;
break;
}
}
message->getPrivate()->removeContent(currentFileTransferContent);
delete currentFileTransferContent;
currentFileTransferContent = nullptr;
message->getPrivate()->setState(ChatMessage::State::NotDelivered);
releaseHttpRequest();
fileUploadEndBackgroundTask();
}
} else if (code == 400) {
lWarning() << "Received HTTP code response " << code << " for file transfer, probably meaning file is too large";
FileTransferContent *fileTransferContent = nullptr;
for (Content *c : message->getPrivate()->getContents()) {
if (c->isFileTransfer()) {
fileTransferContent = static_cast<FileTransferContent *>(c);
message->getPrivate()->removeContent(fileTransferContent);
delete fileTransferContent;
break;
}
}
message->getPrivate()->removeContent(currentFileTransferContent);
delete currentFileTransferContent;
currentFileTransferContent = nullptr;
message->getPrivate()->setState(ChatMessage::State::FileTransferError);
releaseHttpRequest();
fileUploadEndBackgroundTask();
} else {
lWarning() << "Unhandled HTTP code response " << code << " for file transfer";
FileTransferContent *fileTransferContent = nullptr;
for (Content *c : message->getPrivate()->getContents()) {
if (c->isFileTransfer()) {
fileTransferContent = static_cast<FileTransferContent *>(c);
message->getPrivate()->removeContent(fileTransferContent);
delete fileTransferContent;
break;
}
}
message->getPrivate()->removeContent(currentFileTransferContent);
delete currentFileTransferContent;
currentFileTransferContent = nullptr;
message->getPrivate()->setState(ChatMessage::State::NotDelivered);
releaseHttpRequest();
fileUploadEndBackgroundTask();
......@@ -774,7 +747,7 @@ void FileTransferChatMessageModifier::onRecvBody (belle_sip_user_body_handler_t
EncryptionEngine *imee = message->getCore()->getEncryptionEngine();
if (imee) {
uint8_t *decrypted_buffer = (uint8_t *)ms_malloc0(size);
retval = imee->downloadingFile(message, offset, buffer, size, decrypted_buffer);
retval = imee->downloadingFile(message, offset, buffer, size, decrypted_buffer, currentFileTransferContent);
if (retval == 0) {
memcpy(buffer, decrypted_buffer, size);
}
......@@ -818,7 +791,7 @@ void FileTransferChatMessageModifier::onRecvEnd (belle_sip_user_body_handler_t *
int retval = -1;
EncryptionEngine *imee = message->getCore()->getEncryptionEngine();
if (imee) {
retval = imee->downloadingFile(message, 0, nullptr, 0, nullptr);
retval = imee->downloadingFile(message, 0, nullptr, 0, nullptr, currentFileTransferContent);
}
if (retval == 0 || retval == -1) {
......@@ -842,26 +815,27 @@ void FileTransferChatMessageModifier::onRecvEnd (belle_sip_user_body_handler_t *
// Remove the FileTransferContent from the message and store the FileContent
FileContent *fileContent = currentFileContentToTransfer;
message->getPrivate()->addContent(fileContent);
for (Content *content : message->getContents()) {
if (content->isFileTransfer()) {
FileTransferContent *fileTransferContent = static_cast<FileTransferContent *>(content);
if (fileTransferContent->getFileContent() == fileContent) {
message->getPrivate()->removeContent(content);