diff --git a/src/chat/chat-message/chat-message-p.h b/src/chat/chat-message/chat-message-p.h index 919bae443..7ffe61832 100644 --- a/src/chat/chat-message/chat-message-p.h +++ b/src/chat/chat-message/chat-message-p.h @@ -26,8 +26,8 @@ #include "chat/chat-room/chat-room-id.h" #include "chat/modifier/file-transfer-chat-message-modifier.h" #include "chat/notification/imdn.h" -#include "content/content-type.h" #include "content/content.h" +#include "content/content-type.h" #include "content/file-content.h" #include "content/file-transfer-content.h" #include "db/main-db.h" diff --git a/src/chat/chat-message/chat-message.cpp b/src/chat/chat-message/chat-message.cpp index 6048f5439..6010dadbb 100644 --- a/src/chat/chat-message/chat-message.cpp +++ b/src/chat/chat-message/chat-message.cpp @@ -33,17 +33,15 @@ #include "chat/chat-room/real-time-text-chat-room.h" #include "chat/modifier/cpim-chat-message-modifier.h" #include "chat/modifier/encryption-chat-message-modifier.h" -#include "chat/modifier/file-transfer-chat-message-modifier.h" #include "chat/modifier/multipart-chat-message-modifier.h" +#include "chat/notification/imdn.h" #include "conference/participant.h" #include "conference/participant-imdn-state.h" -#include "content/file-content.h" +#include "content/content-disposition.h" #include "content/header/header-param.h" -#include "content/content.h" #include "core/core.h" #include "core/core-p.h" #include "logger/logger.h" -#include "chat/notification/imdn.h" #include "sip-tools/sip-headers.h" #include "ortp/b64.h" @@ -462,6 +460,7 @@ void ChatMessagePrivate::sendImdn (Imdn::Type imdnType, LinphoneReason reason) { shared_ptr msg = q->getChatRoom()->createChatMessage(); Content *content = new Content(); + content->setContentDisposition(ContentDisposition::Notification); content->setContentType(ContentType::Imdn); content->setBody(Imdn::createXml(imdnId, time, imdnType, reason)); msg->addContent(content); @@ -773,13 +772,16 @@ void ChatMessagePrivate::send () { auto msgOp = dynamic_cast(op); if (!externalBodyUrl.empty()) { - 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()) { - msgOp->send_message(internalContent.getContentType().asString().c_str(), internalContent.getBodyAsUtf8String().c_str()); + Content content; + ContentType contentType(ContentType::ExternalBody); + contentType.addParameter("access-type", "URL"); + contentType.addParameter("URL", "\"" + externalBodyUrl + "\""); + content.setContentType(contentType); + msgOp->sendMessage(content); } else { - msgOp->send_message(ContentType::PlainText.asString().c_str(), internalContent.getBodyAsUtf8String().c_str()); + if (!internalContent.getContentType().isValid()) + internalContent.setContentType(ContentType::PlainText); + msgOp->sendMessage(internalContent); } // Restore FileContents and remove FileTransferContents diff --git a/src/chat/chat-room/server-group-chat-room-p.h b/src/chat/chat-room/server-group-chat-room-p.h index 0ddcbdd48..daa8ae629 100644 --- a/src/chat/chat-room/server-group-chat-room-p.h +++ b/src/chat/chat-room/server-group-chat-room-p.h @@ -69,7 +69,7 @@ public: private: struct Message { Message (const std::string &from, const ContentType &contentType, const std::string &text, const SalCustomHeader *salCustomHeaders) - : fromAddr(from) + : fromAddr(from) { content.setContentType(contentType); if (!text.empty()) diff --git a/src/chat/modifier/cpim-chat-message-modifier.cpp b/src/chat/modifier/cpim-chat-message-modifier.cpp index 3f361b9c9..af207fff5 100644 --- a/src/chat/modifier/cpim-chat-message-modifier.cpp +++ b/src/chat/modifier/cpim-chat-message-modifier.cpp @@ -20,8 +20,9 @@ #include "address/address.h" #include "chat/chat-message/chat-message-p.h" #include "chat/cpim/cpim.h" -#include "content/content-type.h" #include "content/content.h" +#include "content/content-disposition.h" +#include "content/content-type.h" #include "logger/logger.h" #include "cpim-chat-message-modifier.h" @@ -59,6 +60,12 @@ ChatMessageModifier::Result CpimChatMessageModifier::encode (const shared_ptrgetContents().front(); } + if (content->getContentDisposition().isValid()) { + Cpim::GenericHeader contentDispositionHeader; + contentDispositionHeader.setName("Content-Disposition"); + contentDispositionHeader.setValue(content->getContentDisposition().asString()); + cpimMessage.addContentHeader(contentDispositionHeader); + } Cpim::GenericHeader contentTypeHeader; contentTypeHeader.setName("Content-Type"); contentTypeHeader.setValue(content->getContentType().asString()); @@ -100,10 +107,11 @@ ChatMessageModifier::Result CpimChatMessageModifier::decode (const shared_ptrgetContentHeaders(); if (l) { for (const auto &header : *l.get()) { - if (header->getName() == "Content-Type") { + if (header->getName() == "Content-Disposition") { + newContent.setContentDisposition(ContentDisposition(header->getValue())); + } else if (header->getName() == "Content-Type") { contentTypeFound = true; newContent.setContentType(ContentType(header->getValue())); - break; } } } diff --git a/src/content/content-disposition.cpp b/src/content/content-disposition.cpp index 1a14d9bd7..b7c6c9f16 100644 --- a/src/content/content-disposition.cpp +++ b/src/content/content-disposition.cpp @@ -38,6 +38,7 @@ public: // ----------------------------------------------------------------------------- +const ContentDisposition ContentDisposition::Notification("notification"); const ContentDisposition ContentDisposition::RecipientList("recipient-list"); const ContentDisposition ContentDisposition::RecipientListHistory("recipient-list-history; handling=optional"); diff --git a/src/content/content-disposition.h b/src/content/content-disposition.h index 9021f0e2c..e01b289bb 100644 --- a/src/content/content-disposition.h +++ b/src/content/content-disposition.h @@ -52,6 +52,7 @@ public: std::string asString () const; + static const ContentDisposition Notification; static const ContentDisposition RecipientList; static const ContentDisposition RecipientListHistory; diff --git a/src/sal/call-op.cpp b/src/sal/call-op.cpp index f28a096fa..3773585d3 100644 --- a/src/sal/call-op.cpp +++ b/src/sal/call-op.cpp @@ -1530,10 +1530,11 @@ void SalCallOp::process_notify(const belle_sip_request_event_t *event, belle_sip } } -int SalCallOp::send_message(const char* content_type, const char *msg) { - if (!this->dialog) return -1; - belle_sip_request_t* req=belle_sip_dialog_create_queued_request(this->dialog,"MESSAGE"); - prepare_message_request(req, content_type, msg); +int SalCallOp::sendMessage (const Content &content) { + if (!this->dialog) + return -1; + belle_sip_request_t *req = belle_sip_dialog_create_queued_request(this->dialog, "MESSAGE"); + prepareMessageRequest(req, content); return send_request(req); } diff --git a/src/sal/call-op.h b/src/sal/call-op.h index fea958e6d..8c1a484e3 100644 --- a/src/sal/call-op.h +++ b/src/sal/call-op.h @@ -66,7 +66,7 @@ public: void set_sdp_handling(SalOpSDPHandling handling); // Implementation of SalMessageOpInterface - int send_message(const char* content_type, const char *msg) override; + int sendMessage (const Content &content) override; int reply(SalReason reason) override {return SalOp::reply_message(reason);} private: diff --git a/src/sal/message-op-interface.h b/src/sal/message-op-interface.h index acc5ea49c..ea00bdc6a 100644 --- a/src/sal/message-op-interface.h +++ b/src/sal/message-op-interface.h @@ -20,17 +20,49 @@ #ifndef _L_SAL_MESSAGE_OP_INTERFACE_H_ #define _L_SAL_MESSAGE_OP_INTERFACE_H_ +#include + +#include "content/content.h" +#include "content/content-type.h" + LINPHONE_BEGIN_NAMESPACE class SalMessageOpInterface { public: virtual ~SalMessageOpInterface() = default; - virtual int send_message(const char* content_type, const char *msg) = 0; + virtual int sendMessage (const Content &content) = 0; virtual int reply(SalReason reason) = 0; protected: - void prepare_message_request(belle_sip_request_t *req, const char* content_type, const char *msg); + void prepareMessageRequest (belle_sip_request_t *req, const Content &content) { + time_t curtime = std::time(nullptr); + belle_sip_message_add_header( + BELLE_SIP_MESSAGE(req), + BELLE_SIP_HEADER(belle_sip_header_date_create_from_time(&curtime)) + ); + const ContentType &contentType = content.getContentType(); + std::string contentTypeStr = std::string(BELLE_SIP_CONTENT_TYPE ": ") + contentType.asString(); + belle_sip_message_add_header( + BELLE_SIP_MESSAGE(req), + BELLE_SIP_HEADER(belle_sip_header_content_type_parse(contentTypeStr.c_str())) + ); + if (content.isEmpty()) { + belle_sip_message_add_header( + BELLE_SIP_MESSAGE(req), + BELLE_SIP_HEADER(belle_sip_header_content_length_create(0)) + ); + } else { + std::string body = content.getBodyAsUtf8String(); + size_t contentLength = body.size(); + belle_sip_message_add_header( + BELLE_SIP_MESSAGE(req), + BELLE_SIP_HEADER(belle_sip_header_content_length_create(contentLength)) + ); + belle_sip_message_set_body(BELLE_SIP_MESSAGE(req), body.c_str(), contentLength); + } + } + }; LINPHONE_END_NAMESPACE diff --git a/src/sal/message-op.cpp b/src/sal/message-op.cpp index 090f5f50e..29acdab93 100644 --- a/src/sal/message-op.cpp +++ b/src/sal/message-op.cpp @@ -77,27 +77,13 @@ void SalMessageOp::fill_cbs() { this->type=Type::Message; } -void SalMessageOpInterface::prepare_message_request(belle_sip_request_t *req, const char* content_type, const char *msg) { - char content_type_raw[256]; - size_t content_length = msg?strlen(msg):0; - time_t curtime = ms_time(NULL); - snprintf(content_type_raw,sizeof(content_type_raw),BELLE_SIP_CONTENT_TYPE ": %s",content_type); - belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_content_type_parse(content_type_raw))); - belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_content_length_create(content_length))); - belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_date_create_from_time(&curtime))); - if (msg){ - /*don't call set_body() with null argument because it resets content type and content length*/ - belle_sip_message_set_body(BELLE_SIP_MESSAGE(req), msg, content_length); - } -} - -int SalMessageOp::send_message(const char* content_type, const char *msg) { +int SalMessageOp::sendMessage (const Content &content) { fill_cbs(); this->dir = Dir::Outgoing; belle_sip_request_t *req = build_request("MESSAGE"); if (!req) return -1; - prepare_message_request(req, content_type, msg); + prepareMessageRequest(req, content); return send_request(req); } diff --git a/src/sal/message-op.h b/src/sal/message-op.h index 9c1527ba8..922cc0381 100644 --- a/src/sal/message-op.h +++ b/src/sal/message-op.h @@ -29,7 +29,7 @@ class SalMessageOp: public SalOp, public SalMessageOpInterface { public: SalMessageOp(Sal *sal): SalOp(sal) {} - int send_message(const char* content_type, const char *msg) override; + int sendMessage (const Content &content) override; int reply(SalReason reason) override {return SalOp::reply_message(reason);} private: diff --git a/src/sal/op.cpp b/src/sal/op.cpp index 497a7a99b..33a641906 100644 --- a/src/sal/op.cpp +++ b/src/sal/op.cpp @@ -1040,7 +1040,7 @@ void SalOp::process_incoming_message(const belle_sip_request_event_t *event) { 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);