More work

This commit is contained in:
Sylvain Berfini 2018-02-08 13:06:39 +01:00
parent 122098ac04
commit 96c01f7052
14 changed files with 90 additions and 71 deletions

View file

@ -222,7 +222,7 @@ void linphone_chat_message_add_text_content(LinphoneChatMessage *msg, const char
LinphonePrivate::ContentType contentType = LinphonePrivate::ContentType::PlainText;
content->setContentType(contentType);
content->setBody(L_C_TO_STRING(c_content));
L_GET_CPP_PTR_FROM_C_OBJECT(msg)->addContent(*content);
L_GET_CPP_PTR_FROM_C_OBJECT(msg)->addContent(content);
}
bool_t linphone_chat_message_has_text_content(const LinphoneChatMessage *msg) {
@ -284,7 +284,7 @@ int linphone_chat_message_set_text(LinphoneChatMessage *msg, const char* text) {
LinphoneContent *linphone_chat_message_get_file_transfer_information(LinphoneChatMessage *msg) {
const LinphonePrivate::Content *content = L_GET_PRIVATE_FROM_C_OBJECT(msg)->getFileTransferInformation();
if (content) return L_GET_C_BACK_PTR(content);
if (content) return linphone_content_ref(L_GET_C_BACK_PTR(content));
return NULL;
}

View file

@ -166,27 +166,27 @@ const char * linphone_content_get_custom_header(const LinphoneContent *content,
const char *linphone_content_get_key(const LinphoneContent *content) {
const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content);
if (c->isFile()) {
const LinphonePrivate::FileContent *fc = static_cast<const LinphonePrivate::FileContent *>(c);
return L_STRING_TO_C(fc->getFileKey());
if (c->getContentType() == LinphonePrivate::ContentType::FileTransfer) {
const LinphonePrivate::FileTransferContent *ftc = static_cast<const LinphonePrivate::FileTransferContent *>(c);
return ftc->getFileKeyAsString();
}
return NULL;
}
size_t linphone_content_get_key_size(const LinphoneContent *content) {
const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content);
if (c->isFile()) {
const LinphonePrivate::FileContent *fc = static_cast<const LinphonePrivate::FileContent *>(c);
return fc->getFileKey().length();
if (c->getContentType() == LinphonePrivate::ContentType::FileTransfer) {
const LinphonePrivate::FileTransferContent *ftc = static_cast<const LinphonePrivate::FileTransferContent *>(c);
return ftc->getFileKey().size();
}
return 0;
}
void linphone_content_set_key(LinphoneContent *content, const char *key, const size_t keyLength) {
LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content);
if (c->isFile()) {
LinphonePrivate::FileContent *fc = static_cast<LinphonePrivate::FileContent *>(c);
fc->setFileKey(L_C_TO_STRING(key));
if (c->getContentType() == LinphonePrivate::ContentType::FileTransfer) {
LinphonePrivate::FileTransferContent *ftc = static_cast<LinphonePrivate::FileTransferContent *>(c);
ftc->setFileKey(key, keyLength);
}
}

View file

@ -301,7 +301,7 @@ void ChatMessagePrivate::setFileTransferInformation (Content *content) {
L_Q();
if (content->isFile()) {
q->addContent(*content);
q->addContent(content);
} else {
// This scenario is more likely to happen because the caller is using the C API
LinphoneContent *c_content = L_GET_C_BACK_PTR(content);
@ -312,7 +312,7 @@ void ChatMessagePrivate::setFileTransferInformation (Content *content) {
if (!content->isEmpty()) {
fileContent->setBody(content->getBody());
}
q->addContent(*fileContent);
q->addContent(fileContent);
}
}
@ -354,7 +354,7 @@ void ChatMessagePrivate::sendImdn (Imdn::Type imdnType, LinphoneReason reason) {
Content *content = new Content();
content->setContentType("message/imdn+xml");
content->setBody(Imdn::createXml(imdnId, time, imdnType, reason));
msg->addContent(*content);
msg->addContent(content);
if (reason != LinphoneReasonNone)
msg->getPrivate()->setEncryptionPrevented(true);
@ -676,7 +676,7 @@ void ChatMessagePrivate::send () {
if (content->getContentType() == ContentType::FileTransfer) {
FileTransferContent *fileTransferContent = (FileTransferContent *)content;
it = contents.erase(it);
q->addContent(*fileTransferContent->getFileContent());
q->addContent(fileTransferContent->getFileContent());
delete fileTransferContent;
} else {
it++;
@ -881,18 +881,18 @@ const list<Content *> &ChatMessage::getContents () const {
return d->contents;
}
void ChatMessage::addContent (Content &content) {
void ChatMessage::addContent (Content *content) {
L_D();
if (d->isReadOnly) return;
d->contents.push_back(&content);
d->contents.push_back(content);
}
void ChatMessage::removeContent (const Content &content) {
void ChatMessage::removeContent (const Content *content) {
L_D();
if (d->isReadOnly) return;
d->contents.remove(&const_cast<Content &>(content));
d->contents.remove(const_cast<Content *>(content));
}
const Content &ChatMessage::getInternalContent () const {

View file

@ -94,8 +94,8 @@ public:
void setToBeStored (bool value);
const std::list<Content *> &getContents () const;
void addContent (Content &content);
void removeContent (const Content &content);
void addContent (Content *content);
void removeContent (const Content *content);
const Content &getInternalContent () const;
void setInternalContent (const Content &content);

View file

@ -82,7 +82,7 @@ void ChatRoomPrivate::sendIsComposingNotification () {
Content *content = new Content();
content->setContentType(ContentType::ImIsComposing);
content->setBody(payload);
chatMessage->addContent(*content);
chatMessage->addContent(content);
chatMessage->getPrivate()->send();
}
}
@ -389,7 +389,7 @@ shared_ptr<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;
}

View file

@ -246,12 +246,6 @@ void FileTransferChatMessageModifier::processResponseFromPostFile (const belle_h
}
// shall we encrypt the file
if (is_file_encryption_enabled && message->getChatRoom()) {
LinphoneImEncryptionEngineCbs *imee_cbs = linphone_im_encryption_engine_get_callbacks(imee);
LinphoneImEncryptionEngineCbsGenerateFileTransferKeyCb generate_file_transfer_key_cb =
linphone_im_encryption_engine_cbs_get_generate_file_transfer_key(imee_cbs);
if (generate_file_transfer_key_cb) {
generate_file_transfer_key_cb(imee, L_GET_C_BACK_PTR(message->getChatRoom()), L_GET_C_BACK_PTR(message));
}
// temporary storage for the Content-disposition header value : use a generic filename to not leak it
// Actual filename stored in msg->file_transfer_information->name will be set in encrypted msg
// sended to the
@ -294,9 +288,32 @@ void FileTransferChatMessageModifier::processResponseFromPostFile (const belle_h
const char *body = belle_sip_message_get_body((belle_sip_message_t *)event->response);
if (body && strlen(body) > 0) {
FileTransferContent *fileTransferContent = new FileTransferContent();
fileTransferContent->setContentType(ContentType::FileTransfer);
message->addContent(fileTransferContent);
LinphoneImEncryptionEngine *imee = linphone_core_get_im_encryption_engine(message->getCore()->getCCore());
bool_t is_file_encryption_enabled = FALSE;
if (imee && message->getChatRoom()) {
LinphoneImEncryptionEngineCbs *imee_cbs = linphone_im_encryption_engine_get_callbacks(imee);
LinphoneImEncryptionEngineCbsIsEncryptionEnabledForFileTransferCb is_encryption_enabled_for_file_transfer_cb =
linphone_im_encryption_engine_cbs_get_is_encryption_enabled_for_file_transfer(imee_cbs);
if (is_encryption_enabled_for_file_transfer_cb) {
is_file_encryption_enabled = is_encryption_enabled_for_file_transfer_cb(imee, L_GET_C_BACK_PTR(message->getChatRoom()));
}
}
if (is_file_encryption_enabled && message->getChatRoom()) {
LinphoneImEncryptionEngineCbs *imee_cbs = linphone_im_encryption_engine_get_callbacks(imee);
LinphoneImEncryptionEngineCbsGenerateFileTransferKeyCb generate_file_transfer_key_cb =
linphone_im_encryption_engine_cbs_get_generate_file_transfer_key(imee_cbs);
if (generate_file_transfer_key_cb) {
generate_file_transfer_key_cb(imee, L_GET_C_BACK_PTR(message->getChatRoom()), L_GET_C_BACK_PTR(message));
}
}
// if we have an encryption key for the file, we must insert it into the msg and restore the correct filename
string content_key = currentFileContentToTransfer->getFileKey();
if (!content_key.empty()) {
const char *content_key = fileTransferContent->getFileKeyAsString();
size_t content_key_size = fileTransferContent->getFileKey().size();
if (content_key_size > 0) {
// parse the msg body
xmlDocPtr xmlMessageBody = xmlParseDoc((const xmlChar *)body);
@ -309,16 +326,15 @@ void FileTransferChatMessageModifier::processResponseFromPostFile (const belle_h
xmlChar *typeAttribute = xmlGetProp(cur, (const xmlChar *)"type");
// this is the node we are looking for : add a file-key children node
if (!xmlStrcmp(typeAttribute, (const xmlChar *)"file")) {
size_t content_key_size = content_key.length();
// need to parse the children node to update the file-name one
xmlNodePtr fileInfoNodeChildren = cur->xmlChildrenNode;
// convert key to base64
size_t b64Size;
bctbx_base64_encode(nullptr, &b64Size, (unsigned char *)content_key.c_str(), content_key_size);
bctbx_base64_encode(nullptr, &b64Size, (unsigned char *)content_key, content_key_size);
unsigned char *keyb64 = (unsigned char *)ms_malloc0(b64Size + 1);
int xmlStringLength;
bctbx_base64_encode(keyb64, &b64Size, (unsigned char *)content_key.c_str(), content_key_size);
bctbx_base64_encode(keyb64, &b64Size, (unsigned char *)content_key, content_key_size);
keyb64[b64Size] = '\0'; // libxml need a null terminated string
// add the node containing the key to the file-info node
@ -354,11 +370,9 @@ void FileTransferChatMessageModifier::processResponseFromPostFile (const belle_h
}
FileContent *fileContent = currentFileContentToTransfer;
fileTransferContent->setContentType(ContentType::FileTransfer);
fileTransferContent->setFileContent(fileContent);
message->removeContent(*fileContent);
message->addContent(*fileTransferContent);
message->removeContent(fileContent);
message->updateState(ChatMessage::State::FileTransferDone);
releaseHttpRequest();
@ -566,7 +580,7 @@ ChatMessageModifier::Result FileTransferChatMessageModifier::decode (const share
fileTransferContent->setContentType(internalContent.getContentType());
fileTransferContent->setBody(internalContent.getBody());
fillFileTransferContentInformationsFromVndGsmaRcsFtHttpXml(fileTransferContent);
message->addContent(*fileTransferContent);
message->addContent(fileTransferContent);
return ChatMessageModifier::Result::Done;
}
@ -641,8 +655,7 @@ static void createFileTransferInformationsFromVndGsmaRcsFtHttpXml (FileTransferC
uint8_t *keyBuffer = (uint8_t *)malloc(keyLength);
// decode the key into local key buffer
bctbx_base64_decode(keyBuffer, &keyLength, (unsigned char *)keyb64, strlen((const char *)keyb64));
string key = string((const char *)keyBuffer);
fileContent->setFileKey(key);
fileTransferContent->setFileKey((const char *)keyBuffer, keyLength);
// duplicate key value into the linphone content private structure
xmlFree(keyb64);
free(keyBuffer);
@ -715,7 +728,6 @@ void FileTransferChatMessageModifier::onRecvBody (belle_sip_user_body_handler_t
// Legacy: call back given by application level
linphone_core_notify_file_transfer_recv(message->getCore()->getCCore(), msg, content, (const char *)buffer, size);
}
linphone_content_unref(content);
}
} else {
lWarning() << "File transfer decrypt failed with code " << (int)retval;
@ -763,12 +775,12 @@ void FileTransferChatMessageModifier::onRecvEnd (belle_sip_user_body_handler_t *
if (retval <= 0 && message->getState() != ChatMessage::State::FileTransferError) {
// Remove the FileTransferContent from the message and store the FileContent
FileContent *fileContent = currentFileContentToTransfer;
message->addContent(*fileContent);
message->addContent(fileContent);
for (Content *content : message->getContents()) {
if (content->getContentType() == ContentType::FileTransfer) {
FileTransferContent *fileTransferContent = (FileTransferContent*)content;
if (fileTransferContent->getFileContent() == fileContent) {
message->removeContent(*content);
message->removeContent(content);
delete fileTransferContent;
break;
}
@ -821,7 +833,7 @@ void FileTransferChatMessageModifier::processResponseHeadersFromGetFile (const b
} else {
lWarning() << "No file transfer information for msg [" << this << "]: creating...";
FileContent *content = createFileTransferInformationFromHeaders(response);
message->addContent(*content);
message->addContent(content);
}
size_t body_size = 0;

View file

@ -120,7 +120,7 @@ ChatMessageModifier::Result MultipartChatMessageModifier::decode (const shared_p
}
content->setContentType(contentType);
content->setBody(contentBody);
message->addContent(*content);
message->addContent(content);
lInfo() << "Parsed and added content with type " << contentType.asString();
}

View file

@ -36,7 +36,6 @@ public:
string fileName;
string filePath;
size_t fileSize = 0;
string fileKey;
};
// -----------------------------------------------------------------------------
@ -48,7 +47,6 @@ FileContent::FileContent (const FileContent &src) : Content(*new FileContentPriv
d->fileName = src.getFileName();
d->filePath = src.getFilePath();
d->fileSize = src.getFileSize();
d->fileKey = src.getFileKey();
}
FileContent::FileContent (FileContent &&src) : Content(*new FileContentPrivate) {
@ -56,7 +54,6 @@ FileContent::FileContent (FileContent &&src) : Content(*new FileContentPrivate)
d->fileName = move(src.getPrivate()->fileName);
d->filePath = move(src.getPrivate()->filePath);
d->fileSize = move(src.getPrivate()->fileSize);
d->fileKey = move(src.getPrivate()->fileKey);
}
FileContent &FileContent::operator= (const FileContent &src) {
@ -66,7 +63,6 @@ FileContent &FileContent::operator= (const FileContent &src) {
d->fileName = src.getFileName();
d->filePath = src.getFilePath();
d->fileSize = src.getFileSize();
d->fileKey = src.getFileKey();
}
return *this;
@ -78,7 +74,6 @@ FileContent &FileContent::operator= (FileContent &&src) {
d->fileName = move(src.getPrivate()->fileName);
d->filePath = move(src.getPrivate()->filePath);
d->fileSize = move(src.getPrivate()->fileSize);
d->fileKey = move(src.getPrivate()->fileKey);
return *this;
}
@ -87,8 +82,7 @@ bool FileContent::operator== (const FileContent &content) const {
return Content::operator==(content) &&
d->fileName == content.getFileName() &&
d->filePath == content.getFilePath() &&
d->fileSize == content.getFileSize() &&
d->fileKey == content.getFileKey();
d->fileSize == content.getFileSize();
}
void FileContent::setFileSize (size_t size) {
@ -121,16 +115,6 @@ const string &FileContent::getFilePath () const {
return d->filePath;
}
void FileContent::setFileKey (const string &key) {
L_D();
d->fileKey = key;
}
const string &FileContent::getFileKey () const {
L_D();
return d->fileKey;
}
bool FileContent::isFile () const {
return true;
}

View file

@ -48,9 +48,6 @@ public:
void setFilePath (const std::string &path);
const std::string &getFilePath () const;
void setFileKey (const std::string &key);
const std::string &getFileKey () const;
bool isFile () const override;
private:

View file

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

View file

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

View file

@ -708,7 +708,7 @@ shared_ptr<EventLog> MainDbPrivate::selectConferenceChatMessageEvent (
string data;
fetchContentAppData(session, *content, contentId, data);
}
chatMessage->addContent(*content);
chatMessage->addContent(content);
}
}

View file

@ -426,7 +426,7 @@ static void cpim_chat_message_modifier_base(bool_t use_multipart) {
Content *content = new Content();
content->setContentType(ContentType::PlainText);
content->setBody("Hello Part 2");
marieMessage->addContent(*content);
marieMessage->addContent(content);
}
marieMessage->send();

View file

@ -53,13 +53,13 @@ static void chat_message_multipart_modifier_base(bool first_file_transfer, bool
content->setContentType("video/mkv");
content->setFilePath(send_filepath);
content->setFileName("sintel_trailer_opus_h264.mkv");
marieMessage->addContent(*content);
marieMessage->addContent(content);
bc_free(send_filepath);
} else {
Content *content = new Content();
content->setContentType(ContentType::PlainText);
content->setBody("Hello Part 1");
marieMessage->addContent(*content);
marieMessage->addContent(content);
}
if (second_file_transfer) {
@ -68,13 +68,13 @@ static void chat_message_multipart_modifier_base(bool first_file_transfer, bool
content->setContentType("file/vcf");
content->setFilePath(send_filepath);
content->setFileName("vcards.vcf");
marieMessage->addContent(*content);
marieMessage->addContent(content);
bc_free(send_filepath);
} else {
Content *content = new Content();
content->setContentType(ContentType::PlainText);
content->setBody("Hello Part 2");
marieMessage->addContent(*content);
marieMessage->addContent(content);
}
linphone_core_set_file_transfer_server(marie->lc,"https://www.linphone.org:444/lft.php");