Commit e8e1e130 authored by Ghislain MARY's avatar Ghislain MARY

Improve handling of content types.

parent 34318366
......@@ -21,7 +21,7 @@ int SalCallOp::set_local_media_description(SalMediaDescription *desc) {
vector<char> buffer = marshal_media_description(sdp, error);
if (error != BELLE_SIP_OK) return -1;
this->local_body.setContentType("application/sdp");
this->local_body.setContentType(ContentType::Sdp);
this->local_body.setBody(move(buffer));
if (this->local_media) sal_media_description_unref(this->local_media);
......@@ -47,7 +47,7 @@ int SalCallOp::set_local_body(const Content &body) {
int SalCallOp::set_local_body(const Content &&body) {
if (!body.isValid()) return -1;
if (body.getContentType() == "application/sdp") {
if (body.getContentType() == ContentType::Sdp) {
SalMediaDescription *desc = NULL;
if (body.getSize() > 0) {
belle_sdp_session_description_t *sdp = belle_sdp_session_description_parse(body.getBodyAsString().c_str());
......@@ -139,7 +139,7 @@ int SalCallOp::set_sdp(belle_sip_message_t *msg,belle_sdp_session_description_t*
if (error != BELLE_SIP_OK) return -1;
Content body;
body.setContentType("application/sdp");
body.setContentType(ContentType::Sdp);
body.setBody(move(buff));
set_custom_body(msg, body);
......@@ -161,7 +161,7 @@ void SalCallOp::fill_invite(belle_sip_request_t* invite) {
belle_sip_message_add_header(BELLE_SIP_MESSAGE(invite),belle_sip_header_create( "Session-expires", "600;refresher=uas"));
belle_sip_message_add_header(BELLE_SIP_MESSAGE(invite),belle_sip_header_create( "Supported", "timer"));
}
this->sdp_offering = (this->local_body.getContentType() == "application/sdp");
this->sdp_offering = (this->local_body.getContentType() == ContentType::Sdp);
set_custom_body(BELLE_SIP_MESSAGE(invite), this->local_body);
}
......@@ -204,6 +204,7 @@ void SalCallOp::cancelling_invite(const SalErrorInfo *info) {
Content SalCallOp::extract_body(belle_sip_message_t *message) {
Content body;
belle_sip_header_content_type_t *content_type = belle_sip_message_get_header_by_type(message, belle_sip_header_content_type_t);
belle_sip_header_content_disposition_t *contentDisposition = belle_sip_message_get_header_by_type(message, belle_sip_header_content_disposition_t);
belle_sip_header_content_length_t *content_length = belle_sip_message_get_header_by_type(message, belle_sip_header_content_length_t);
const char *type_str = content_type ? belle_sip_header_content_type_get_type(content_type) : NULL;
const char *subtype_str = content_type ? belle_sip_header_content_type_get_subtype(content_type) : NULL;
......@@ -211,6 +212,8 @@ Content SalCallOp::extract_body(belle_sip_message_t *message) {
const char *body_str = belle_sip_message_get_body(message);
if (type_str && subtype_str) body.setContentType(ContentType(type_str, subtype_str));
if (contentDisposition)
body.setContentDisposition(belle_sip_header_content_disposition_get_content_disposition(contentDisposition));
if (length > 0 && body_str) body.setBody(body_str, length);
return body;
}
......@@ -311,7 +314,7 @@ void SalCallOp::handle_body_from_response(belle_sip_response_t* response) {
sal_media_description_unref(this->remote_media);
this->remote_media=NULL;
}
if (body.getContentType() == "application/sdp") {
if (body.getContentType() == ContentType::Sdp) {
if (parse_sdp_body(body, &sdp, &reason) == 0) {
if (sdp) {
this->remote_media = sal_media_description_new();
......@@ -543,7 +546,7 @@ SalReason SalCallOp::process_body_for_invite(belle_sip_request_t* invite) {
Content body = extract_body(BELLE_SIP_MESSAGE(invite));
if (!body.isValid()) return SalReasonUnsupportedContent;
if (body.getContentType() == "application/sdp") {
if (body.getContentType() == ContentType::Sdp) {
belle_sdp_session_description_t* sdp;
if (parse_sdp_body(body, &sdp, &reason) == 0) {
if (sdp) {
......@@ -574,7 +577,7 @@ SalReason SalCallOp::process_body_for_ack(belle_sip_request_t *ack) {
SalReason reason = SalReasonNone;
Content body = extract_body(BELLE_SIP_MESSAGE(ack));
if (!body.isValid()) return SalReasonUnsupportedContent;
if (body.getContentType() == "application/sdp") {
if (body.getContentType() == ContentType::Sdp) {
belle_sdp_session_description_t *sdp;
if (parse_sdp_body(body, &sdp, &reason) == 0) {
if (sdp) {
......
......@@ -318,11 +318,11 @@ void * linphone_chat_message_get_message_state_changed_cb_user_data(LinphoneChat
// =============================================================================
const char * linphone_chat_message_get_content_type(LinphoneChatMessage *msg) {
return L_STRING_TO_C(L_GET_PRIVATE_FROM_C_OBJECT(msg)->getContentType());
return L_STRING_TO_C(L_GET_PRIVATE_FROM_C_OBJECT(msg)->getContentType().asString());
}
void linphone_chat_message_set_content_type(LinphoneChatMessage *msg, const char *content_type) {
L_GET_PRIVATE_FROM_C_OBJECT(msg)->setContentType(L_C_TO_STRING(content_type));
L_GET_PRIVATE_FROM_C_OBJECT(msg)->setContentType(ContentType(L_C_TO_STRING(content_type)));
}
const char *linphone_chat_message_get_text(LinphoneChatMessage *msg) {
......@@ -362,11 +362,11 @@ LinphoneReason linphone_chat_message_get_reason(LinphoneChatMessage *msg) {
}
bool_t linphone_chat_message_is_file_transfer(LinphoneChatMessage *msg) {
return LinphonePrivate::ContentType::isFileTransfer(linphone_chat_message_get_content_type(msg));
return LinphonePrivate::ContentType(linphone_chat_message_get_content_type(msg)) == LinphonePrivate::ContentType::FileTransfer;
}
bool_t linphone_chat_message_is_text(LinphoneChatMessage *msg) {
return LinphonePrivate::ContentType::isText(linphone_chat_message_get_content_type(msg));
return LinphonePrivate::ContentType(linphone_chat_message_get_content_type(msg)) == LinphonePrivate::ContentType::PlainText;
}
const char *linphone_chat_message_state_to_string(const LinphoneChatMessageState state) {
......
......@@ -68,13 +68,13 @@ public:
// Methods only used for C wrapper
// -----------------------------------------------------------------------------
const std::string& getContentType();
void setContentType(const std::string& contentType);
const ContentType &getContentType();
void setContentType(const ContentType &contentType);
const std::string& getText();
void setText(const std::string& text);
const std::string &getText();
void setText(const std::string &text);
LinphoneContent * getFileTransferInformation() const;
LinphoneContent *getFileTransferInformation() const;
void setFileTransferInformation(LinphoneContent *content);
// -----------------------------------------------------------------------------
......@@ -128,7 +128,7 @@ private:
SalCustomHeader *salCustomHeaders = NULL;
unsigned long backgroundTaskId;
// Cache for returned values, used for compatibility with previous C API
std::string cContentType = "";
ContentType cContentType;
std::string cText = "";
// Used for compatibility with previous C API
LinphoneContent *cFileTransferInformation = NULL;
......
......@@ -139,19 +139,19 @@ string ChatMessagePrivate::getSalCustomHeaderValue(const string& name) {
// -----------------------------------------------------------------------------
const string& ChatMessagePrivate::getContentType() {
if (!internalContent.getContentType().asString().empty()) {
cContentType = internalContent.getContentType().asString();
const ContentType& ChatMessagePrivate::getContentType() {
if (internalContent.getContentType().isValid()) {
cContentType = internalContent.getContentType();
} else {
if (contents.size() > 0) {
Content content = contents.front();
cContentType = content.getContentType().asString();
cContentType = content.getContentType();
}
}
return cContentType;
}
void ChatMessagePrivate::setContentType(const string& contentType) {
void ChatMessagePrivate::setContentType(const ContentType &contentType) {
internalContent.setContentType(contentType);
}
......@@ -681,7 +681,7 @@ void ChatMessagePrivate::processResponseFromPostFile(const belle_http_response_e
} else { // no encryption key, transfer in plain, just copy the msg sent by server
setText(body);
}
setContentType("application/vnd.gsma.rcs-ft-http+xml");
setContentType(ContentType::FileTransfer);
q->updateState(ChatMessage::State::FileTransferDone);
releaseHttpRequest();
send();
......@@ -977,7 +977,7 @@ LinphoneReason ChatMessagePrivate::receive() {
// Start of message modification
// ---------------------------------------
if (ContentType::isCpim(getContentType())) {
if (getContentType() == ContentType::Cpim) {
CpimChatMessageModifier ccmm;
ccmm.decode(this);
}
......@@ -1000,9 +1000,9 @@ LinphoneReason ChatMessagePrivate::receive() {
// End of message modification
// ---------------------------------------
if ((retval <= 0) && (linphone_core_is_content_type_supported(chatRoom->getCore(), getContentType().c_str()) == FALSE)) {
if ((retval <= 0) && (linphone_core_is_content_type_supported(chatRoom->getCore(), getContentType().asString().c_str()) == FALSE)) {
retval = 415;
lError() << "Unsupported MESSAGE (content-type " << getContentType() << " not recognized)";
lError() << "Unsupported MESSAGE (content-type " << getContentType().asString() << " not recognized)";
}
if (retval > 0) {
......@@ -1011,10 +1011,10 @@ LinphoneReason ChatMessagePrivate::receive() {
return reason;
}
if (ContentType::isFileTransfer(getContentType())) {
if (getContentType() == ContentType::FileTransfer) {
createFileTransferInformationsFromVndGsmaRcsFtHttpXml();
store = true;
} else if (ContentType::isText(getContentType())) {
} else if (getContentType() == ContentType::PlainText) {
store = true;
}
......@@ -1071,12 +1071,12 @@ void ChatMessagePrivate::send() {
// ---------------------------------------
string clearTextMessage;
string clearTextContentType;
ContentType clearTextContentType;
if (!getText().empty()) {
clearTextMessage = getText().c_str();
}
if (!getContentType().empty()) {
if (getContentType().isValid()) {
clearTextContentType = getContentType();
}
......@@ -1110,8 +1110,8 @@ void ChatMessagePrivate::send() {
ms_free(content_type);
} else {
auto msgOp = dynamic_cast<SalMessageOpInterface *>(op);
if (!getContentType().empty()) {
msgOp->send_message(from.asString().c_str(), chatRoom->getPeerAddress().asString().c_str(), getContentType().c_str(), getText().c_str(), chatRoom->getPeerAddress().asStringUriOnly().c_str());
if (getContentType().isValid()) {
msgOp->send_message(from.asString().c_str(), chatRoom->getPeerAddress().asString().c_str(), getContentType().asString().c_str(), getText().c_str(), chatRoom->getPeerAddress().asStringUriOnly().c_str());
} else {
msgOp->send_message(from.asString().c_str(), chatRoom->getPeerAddress().asString().c_str(), getText().c_str());
}
......@@ -1121,7 +1121,7 @@ void ChatMessagePrivate::send() {
/* We replace the encrypted message by the original one so it can be correctly stored and displayed by the application */
setText(clearTextMessage);
}
if (!getContentType().empty() && getContentType() == clearTextContentType) {
if (getContentType().isValid() && (getContentType() == clearTextContentType)) {
/* We replace the encrypted content type by the original one */
setContentType(clearTextContentType);
}
......
......@@ -137,7 +137,7 @@ void ChatRoomPrivate::sendImdn (const string &payload, LinphoneReason reason) {
}
if (retval <= 0) {
op->send_message(identity, peerAddress.asString().c_str(), msg->getPrivate()->getContentType().c_str(), msg->getPrivate()->getText().c_str(), nullptr);
op->send_message(identity, peerAddress.asString().c_str(), msg->getPrivate()->getContentType().asString().c_str(), msg->getPrivate()->getText().c_str(), nullptr);
}
linphone_address_unref(peer);
......@@ -227,7 +227,7 @@ void ChatRoomPrivate::sendIsComposingNotification () {
}
if (retval <= 0) {
op->send_message(identity, peerAddress.asString().c_str(), msg->getPrivate()->getContentType().c_str(), msg->getPrivate()->getText().c_str(), nullptr);
op->send_message(identity, peerAddress.asString().c_str(), msg->getPrivate()->getContentType().asString().c_str(), msg->getPrivate()->getText().c_str(), nullptr);
}
op->unref();
}
......@@ -424,13 +424,13 @@ LinphoneReason ChatRoomPrivate::messageReceived (SalOp *op, const SalMessage *sa
goto end;
}
if (ContentType::isImIsComposing(msg->getPrivate()->getContentType())) {
if (msg->getPrivate()->getContentType() == ContentType::ImIsComposing) {
isComposingReceived(msg->getPrivate()->getText());
increaseMsgCount = FALSE;
if (lp_config_get_int(core->config, "sip", "deliver_imdn", 0) != 1) {
goto end;
}
} else if (ContentType::isImdn(msg->getPrivate()->getContentType())) {
} else if (msg->getPrivate()->getContentType() == ContentType::Imdn) {
imdnReceived(msg->getPrivate()->getText());
increaseMsgCount = FALSE;
if (lp_config_get_int(core->config, "sip", "deliver_imdn", 0) != 1) {
......@@ -461,7 +461,7 @@ end:
void ChatRoomPrivate::chatMessageReceived (shared_ptr<ChatMessage> msg) {
L_Q();
if (!ContentType::isImdn(msg->getPrivate()->getContentType()) && !ContentType::isImIsComposing(msg->getPrivate()->getContentType())) {
if ((msg->getPrivate()->getContentType() != ContentType::Imdn) && (msg->getPrivate()->getContentType() != ContentType::ImIsComposing)) {
notifyChatMessageReceived(msg);
remoteIsComposing = false;
linphone_core_notify_is_composing_received(core, L_GET_C_BACK_PTR(q));
......@@ -733,7 +733,7 @@ void ChatRoom::sendMessage (shared_ptr<ChatMessage> msg) {
msg->getPrivate()->setDirection(ChatMessage::Direction::Outgoing);
/* Check if we shall upload a file to a server */
if (msg->getPrivate()->getFileTransferInformation() && msg->getPrivate()->getContentType().empty()) {
if (msg->getPrivate()->getFileTransferInformation() && !msg->getPrivate()->getContentType().isValid()) {
/* Open a transaction with the server and send an empty request(RCS5.1 section 3.5.4.8.3.1) */
if (msg->uploadFile() == 0) {
/* Add to transient list only if message is going out */
......
......@@ -81,8 +81,7 @@ int CpimChatMessageModifier::decode (ChatMessagePrivate *messagePrivate) {
content = messagePrivate->contents.front();
}
ContentType contentType = content.getContentType();
if (ContentType::isCpim(contentType.asString())) {
if (content.getContentType() == ContentType::Cpim) {
const vector<char> body = content.getBody();
string contentBody(body.begin(), body.end());
shared_ptr<const Cpim::Message> message = Cpim::Message::createFromString(contentBody);
......@@ -97,7 +96,7 @@ int CpimChatMessageModifier::decode (ChatMessagePrivate *messagePrivate) {
return 500;
}
} else {
lError() << "[CPIM] Message is not CPIM but " << contentType.asString();
lError() << "[CPIM] Message is not CPIM but " << content.getContentType().asString();
return -1;
}
return 0;
......
......@@ -16,6 +16,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "linphone/utils/utils.h"
#include "object/clonable-object-p.h"
#include "content-type.h"
......@@ -34,6 +36,16 @@ public:
// -----------------------------------------------------------------------------
const ContentType ContentType::Cpim("message/cpim");
const ContentType ContentType::FileTransfer("application/vnd.gsma.rcs-ft-http+xml");
const ContentType ContentType::Imdn("message/imdn+xml");
const ContentType ContentType::ImIsComposing("application/im-iscomposing+xml");
const ContentType ContentType::PlainText("text/plain");
const ContentType ContentType::ResourceLists("application/resource-lists+xml");
const ContentType ContentType::Sdp("application/sdp");
// -----------------------------------------------------------------------------
ContentType::ContentType (const string &contentType) : ClonableObject(*new ContentTypePrivate) {
L_D();
......@@ -71,16 +83,8 @@ bool ContentType::operator== (const ContentType &contentType) const {
return getType() == contentType.getType() && getSubType() == contentType.getSubType();
}
bool ContentType::operator== (const string &contentType) const {
return *this == ContentType(contentType);
}
bool ContentType::operator!= (const ContentType &contentType) const {
return !(*this == contentType);
}
bool ContentType::operator!= (const std::string &contentType) const {
return !(*this == contentType);
return !operator==(contentType);
}
const string &ContentType::getType () const {
......@@ -91,7 +95,7 @@ const string &ContentType::getType () const {
bool ContentType::setType (const string &type) {
L_D();
if (type.find('/') == string::npos) {
d->type = type;
d->type = Utils::stringToLower(type);
return true;
}
return false;
......@@ -105,7 +109,7 @@ const string &ContentType::getSubType () const {
bool ContentType::setSubType (const string &subType) {
L_D();
if (subType.find('/') == string::npos) {
d->subType = subType;
d->subType = Utils::stringToLower(subType);
return true;
}
return false;
......@@ -121,40 +125,4 @@ string ContentType::asString () const {
return isValid() ? d->type + "/" + d->subType : "";
}
bool ContentType::isFileTransfer () const {
return isFileTransfer(asString());
}
bool ContentType::isImIsComposing () const {
return isFileTransfer(asString());
}
bool ContentType::isImdn () const {
return isImdn(asString());
}
bool ContentType::isText () const {
return isText(asString());
}
bool ContentType::isFileTransfer (const string &contentType) {
return contentType == "application/vnd.gsma.rcs-ft-http+xml";
}
bool ContentType::isImIsComposing (const string &contentType) {
return contentType == "application/im-iscomposing+xml";
}
bool ContentType::isImdn (const string &contentType) {
return contentType == "message/imdn+xml";
}
bool ContentType::isText (const string &contentType) {
return contentType == "text/plain";
}
bool ContentType::isCpim(const string &contentType) {
return contentType == "Message/CPIM";
}
LINPHONE_END_NAMESPACE
......@@ -36,9 +36,12 @@ public:
ContentType &operator= (const ContentType &src);
bool operator== (const ContentType &contentType) const;
bool operator== (const std::string &contentType) const;
bool operator!= (const ContentType &contentType) const;
bool operator!= (const std::string &contentType) const;
// Delete these operators to prevent putting complicated content-type strings
// in the code. Instead define static const ContentType objects below.
bool operator== (const std::string &contentType) const = delete;
bool operator!= (const std::string &contentType) const = delete;
bool isValid () const;
......@@ -50,16 +53,13 @@ public:
std::string asString () const;
bool isFileTransfer () const;
bool isImIsComposing () const;
bool isImdn () const;
bool isText () const;
static bool isFileTransfer (const std::string &contentType);
static bool isImIsComposing (const std::string &contentType);
static bool isImdn (const std::string &contentType);
static bool isText (const std::string &contentType);
static bool isCpim (const std::string &contentType);
static const ContentType Cpim;
static const ContentType FileTransfer;
static const ContentType Imdn;
static const ContentType ImIsComposing;
static const ContentType PlainText;
static const ContentType ResourceLists;
static const ContentType Sdp;
private:
L_DECLARE_PRIVATE(ContentType);
......
......@@ -395,7 +395,7 @@ static void cpim_chat_message_modifier(void) {
marieRoom->sendMessage(marieMessage);
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageReceived,1));
BC_ASSERT_TRUE(ContentType::isCpim(marieMessage->getInternalContent().getContentType().asString()));
BC_ASSERT_TRUE(marieMessage->getInternalContent().getContentType() == ContentType::Cpim);
BC_ASSERT_PTR_NOT_NULL(pauline->stat.last_received_chat_message);
if (pauline->stat.last_received_chat_message != NULL) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment