From f1f84e7c60d27d7870b616661c52787f5c0e5006 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 9 Nov 2017 12:59:29 +0100 Subject: [PATCH] Changes & improvements for FileTransfer --- src/chat/chat-message/chat-message.cpp | 13 ++-- .../file-transfer-chat-message-modifier.cpp | 67 ++++++++++++++++++- src/content/file-transfer-content.cpp | 17 +++++ src/content/file-transfer-content.h | 3 + 4 files changed, 89 insertions(+), 11 deletions(-) diff --git a/src/chat/chat-message/chat-message.cpp b/src/chat/chat-message/chat-message.cpp index c3a520072..7b80dd35c 100644 --- a/src/chat/chat-message/chat-message.cpp +++ b/src/chat/chat-message/chat-message.cpp @@ -457,17 +457,12 @@ LinphoneReason ChatMessagePrivate::receive () { MultipartChatMessageModifier mcmm; mcmm.decode(q->getSharedFromThis(), errorCode); + // This will check if internal content is FileTransfer and make the appropriate changes + fileTransferChatMessageModifier.decode(q->getSharedFromThis(), errorCode); + if (contents.size() == 0) { // All previous modifiers only altered the internal content, let's fill the content list - // But first check if content type is file transfer - if (internalContent.getContentType() == ContentType::FileTransfer) { - FileTransferContent *content = new FileTransferContent(); - content->setContentType(internalContent.getContentType()); - content->setBody(internalContent.getBody()); - contents.push_back(content); - } else { - contents.push_back(&internalContent); - } + contents.push_back(&internalContent); } // --------------------------------------- diff --git a/src/chat/modifier/file-transfer-chat-message-modifier.cpp b/src/chat/modifier/file-transfer-chat-message-modifier.cpp index e167a7a7e..38f01d55e 100644 --- a/src/chat/modifier/file-transfer-chat-message-modifier.cpp +++ b/src/chat/modifier/file-transfer-chat-message-modifier.cpp @@ -505,7 +505,71 @@ void FileTransferChatMessageModifier::fileUploadEndBackgroundTask () { // ---------------------------------------------------------- +static void fillFileTransferContentInformationsFromVndGsmaRcsFtHttpXml(FileTransferContent *fileTransferContent) { + xmlChar *file_url = nullptr; + xmlDocPtr xmlMessageBody; + xmlNodePtr cur; + /* parse the msg body to get all informations from it */ + xmlMessageBody = xmlParseDoc((const xmlChar *)fileTransferContent->getBodyAsString().c_str()); + + cur = xmlDocGetRootElement(xmlMessageBody); + if (cur != nullptr) { + cur = cur->xmlChildrenNode; + while (cur != nullptr) { + if (!xmlStrcmp(cur->name, (const xmlChar *)"file-info")) { + /* we found a file info node, check if it has a type="file" attribute */ + xmlChar *typeAttribute = xmlGetProp(cur, (const xmlChar *)"type"); + if (!xmlStrcmp(typeAttribute, (const xmlChar *)"file")) { /* this is the node we are looking for */ + cur = cur->xmlChildrenNode; /* now loop on the content of the file-info node */ + while (cur != nullptr) { + if (!xmlStrcmp(cur->name, (const xmlChar *)"file-name")) { + xmlChar *filename = xmlNodeListGetString(xmlMessageBody, cur->xmlChildrenNode, 1); + fileTransferContent->setFileName((char *)filename); + + xmlFree(filename); + } + if (!xmlStrcmp(cur->name, (const xmlChar *)"data")) { + file_url = xmlGetProp(cur, (const xmlChar *)"url"); + } + + cur = cur->next; + } + xmlFree(typeAttribute); + break; + } + xmlFree(typeAttribute); + } + cur = cur->next; + } + } + xmlFreeDoc(xmlMessageBody); + + fileTransferContent->setFileUrl((const char *)file_url); // Set file url in the file transfer content for the download + + xmlFree(file_url); +} + ChatMessageModifier::Result FileTransferChatMessageModifier::decode (const shared_ptr &message, int &errorCode) { + chatMessage = message; + + Content internalContent = chatMessage->getInternalContent(); + if (internalContent.getContentType() == ContentType::FileTransfer) { + FileTransferContent *fileTransferContent = new FileTransferContent(); + fileTransferContent->setContentType(internalContent.getContentType()); + fileTransferContent->setBody(internalContent.getBody()); + fillFileTransferContentInformationsFromVndGsmaRcsFtHttpXml(fileTransferContent); + chatMessage->addContent(fileTransferContent); + return ChatMessageModifier::Result::Done; + } else { + for (Content *content : chatMessage->getContents()) { + if (content->getContentType() == ContentType::FileTransfer) { + FileTransferContent *fileTransferContent = (FileTransferContent *)content; + fillFileTransferContentInformationsFromVndGsmaRcsFtHttpXml(fileTransferContent); + } + } + return ChatMessageModifier::Result::Done; + } + return ChatMessageModifier::Result::Skipped; } @@ -539,6 +603,7 @@ static void createFileTransferInformationsFromVndGsmaRcsFtHttpXml (FileTransferC if (!xmlStrcmp(cur->name, (const xmlChar *)"file-name")) { xmlChar *filename = xmlNodeListGetString(xmlMessageBody, cur->xmlChildrenNode, 1); fileContent->setFileName((char *)filename); + xmlFree(filename); } if (!xmlStrcmp(cur->name, (const xmlChar *)"content-type")) { @@ -589,8 +654,6 @@ static void createFileTransferInformationsFromVndGsmaRcsFtHttpXml (FileTransferC xmlFreeDoc(xmlMessageBody); fileContent->setFilePath(fileTransferContent->getFilePath()); // Copy file path from file transfer content to file content for file body handler - fileTransferContent->setFileUrl((const char *)file_url); // Set file url in the file transfer content for the download - // Link the FileContent to the FileTransferContent fileTransferContent->setFileContent(fileContent); diff --git a/src/content/file-transfer-content.cpp b/src/content/file-transfer-content.cpp index a5583ad58..9c851177b 100644 --- a/src/content/file-transfer-content.cpp +++ b/src/content/file-transfer-content.cpp @@ -29,6 +29,7 @@ LINPHONE_BEGIN_NAMESPACE class FileTransferContentPrivate : public ContentPrivate { public: + string fileName; string fileUrl; string filePath; FileContent *fileContent = nullptr; @@ -42,6 +43,7 @@ FileTransferContent::FileTransferContent() : Content(*new FileTransferContentPri FileTransferContent::FileTransferContent (const FileTransferContent &src) : Content(*new FileTransferContentPrivate) { L_D(); + d->fileName = src.getFileName(); d->fileUrl = src.getFileUrl(); d->filePath = src.getFilePath(); d->fileContent = src.getFileContent(); @@ -49,6 +51,7 @@ FileTransferContent::FileTransferContent (const FileTransferContent &src) : Cont FileTransferContent::FileTransferContent (FileTransferContent &&src) : Content(*new FileTransferContentPrivate) { L_D(); + d->fileName = move(src.getPrivate()->fileName); d->fileUrl = move(src.getPrivate()->fileUrl); d->filePath = move(src.getPrivate()->filePath); d->fileContent = move(src.getPrivate()->fileContent); @@ -58,6 +61,7 @@ FileTransferContent &FileTransferContent::operator= (const FileTransferContent & L_D(); if (this != &src) { Content::operator=(src); + d->fileName = src.getFileName(); d->fileUrl = src.getFileUrl(); d->filePath = src.getFilePath(); d->fileContent = src.getFileContent(); @@ -69,6 +73,7 @@ FileTransferContent &FileTransferContent::operator= (const FileTransferContent & FileTransferContent &FileTransferContent::operator= (FileTransferContent &&src) { L_D(); Content::operator=(move(src)); + d->fileName = move(src.getPrivate()->fileName); d->fileUrl = move(src.getPrivate()->fileUrl); d->filePath = move(src.getPrivate()->filePath); d->fileContent = move(src.getPrivate()->fileContent); @@ -78,10 +83,21 @@ FileTransferContent &FileTransferContent::operator= (FileTransferContent &&src) bool FileTransferContent::operator== (const FileTransferContent &content) const { L_D(); return Content::operator==(content) && + d->fileName == content.getFileName() && d->fileUrl == content.getFileUrl() && d->filePath == content.getFilePath(); } +void FileTransferContent::setFileName(const string &name) { + L_D(); + d->fileName = name; +} + +const string& FileTransferContent::getFileName() const { + L_D(); + return d->fileName; +} + void FileTransferContent::setFileUrl(const string &url) { L_D(); d->fileUrl = url; @@ -117,6 +133,7 @@ LinphoneContent * FileTransferContent::toLinphoneContent() const { content = linphone_core_create_content(NULL); 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()); return content; } diff --git a/src/content/file-transfer-content.h b/src/content/file-transfer-content.h index c2965bb29..09615ca8b 100644 --- a/src/content/file-transfer-content.h +++ b/src/content/file-transfer-content.h @@ -39,6 +39,9 @@ public: FileTransferContent &operator= (FileTransferContent &&src); bool operator== (const FileTransferContent &content) const; + void setFileName(const std::string &name); + const std::string& getFileName() const; + void setFileUrl(const std::string &url); const std::string& getFileUrl() const;