diff --git a/coreapi/sal/call_op.cpp b/coreapi/sal/call_op.cpp index aa7ecf193..83cc8e7a7 100644 --- a/coreapi/sal/call_op.cpp +++ b/coreapi/sal/call_op.cpp @@ -3,6 +3,7 @@ #include "offeranswer.h" #include #include +#include using namespace std; @@ -11,7 +12,7 @@ using namespace std; LINPHONE_BEGIN_NAMESPACE int SalCallOp::set_local_media_description(SalMediaDescription *desc) { - if (this->custom_body) { + if (this->custom_body.getBody().size() > 0) { bctbx_error("cannot set local media description on SalOp [%p] because a custom body is already set", this); return -1; } @@ -32,13 +33,21 @@ int SalCallOp::set_local_media_description(SalMediaDescription *desc) { return 0; } -int SalCallOp::set_local_custom_body(SalCustomBody *body) { +int SalCallOp::set_local_custom_body(const Content &body) { if (this->local_media) { bctbx_error("cannot set custom body on SalOp [%p] because a local media description is already set", this); return -1; } - if (this->custom_body) sal_custom_body_unref(this->custom_body); - this->custom_body = sal_custom_body_ref(body ? body : NULL); + this->custom_body = body; + return 0; +} + +int SalCallOp::set_local_custom_body(const Content &&body) { + if (this->local_media) { + bctbx_error("cannot set custom body on SalOp [%p] because a local media description is already set", this); + return -1; + } + this->custom_body = body; return 0; } @@ -50,24 +59,31 @@ belle_sip_header_allow_t *SalCallOp::create_allow(bool_t enable_update) { return header_allow; } -int SalCallOp::set_custom_body(belle_sip_message_t *msg, const SalCustomBody *body) { - if (body->data_length > SIP_MESSAGE_BODY_LIMIT) { +int SalCallOp::set_custom_body(belle_sip_message_t *msg, const Content &body) { + ContentType contentType = body.getContentType(); + size_t bodySize = body.getBody().size(); + + if (bodySize > SIP_MESSAGE_BODY_LIMIT) { bctbx_error("trying to add a body greater than %dkB to message [%p]", SIP_MESSAGE_BODY_LIMIT/1024, msg); return -1; } - if (body->data_length == 0 || body->raw_data == NULL) { + if (bodySize == 0) { bctbx_error("trying to add an empty custom body to message [%p]", msg); return -1; } + if (!contentType.isValid()) { + bctbx_error("trying to add a custom body with an invalid content type to message [%p]", msg); + return -1; + } - belle_sip_header_content_type_t *content_type = belle_sip_header_content_type_create(body->type->type, body->type->subtype); - belle_sip_header_content_length_t *content_length = belle_sip_header_content_length_create(body->data_length); + belle_sip_header_content_type_t *content_type = belle_sip_header_content_type_create(contentType.getType().c_str(), contentType.getSubType().c_str()); + belle_sip_header_content_length_t *content_length = belle_sip_header_content_length_create(bodySize); belle_sip_message_add_header(msg, BELLE_SIP_HEADER(content_type)); belle_sip_message_add_header(msg, BELLE_SIP_HEADER(content_length)); - char *buffer = bctbx_new(char, body->data_length); - memcpy(buffer, body->raw_data, body->data_length); - belle_sip_message_assign_body(msg, buffer, body->data_length); + char *buffer = bctbx_new(char, bodySize); + memcpy(buffer, body.getBody().data(), bodySize); + belle_sip_message_assign_body(msg, buffer, bodySize); return 0; } @@ -75,31 +91,32 @@ int SalCallOp::set_custom_body(belle_sip_message_t *msg, const SalCustomBody *bo int SalCallOp::set_sdp(belle_sip_message_t *msg,belle_sdp_session_description_t* session_desc) { belle_sip_error_code error = BELLE_SIP_BUFFER_OVERFLOW; size_t length = 0; + size_t bufLen = 2048; if (session_desc == NULL) return -1; - size_t bufLen = 2048; - char *buff = reinterpret_cast(belle_sip_malloc(bufLen)); + vector buff(bufLen); /* try to marshal the description. This could go higher than 2k so we iterate */ - while( error != BELLE_SIP_OK && bufLen <= SIP_MESSAGE_BODY_LIMIT && buff != NULL){ - error = belle_sip_object_marshal(BELLE_SIP_OBJECT(session_desc),buff,bufLen,&length); + while( error != BELLE_SIP_OK && bufLen <= SIP_MESSAGE_BODY_LIMIT) { + error = belle_sip_object_marshal(BELLE_SIP_OBJECT(session_desc),buff.data(),bufLen,&length); if( error != BELLE_SIP_OK ){ bufLen *= 2; length = 0; - buff = reinterpret_cast(belle_sip_realloc(buff,bufLen)); + buff.resize(bufLen); } } /* give up if hard limit reached */ - if (error != BELLE_SIP_OK || buff == NULL) { + if (error != BELLE_SIP_OK) { ms_error("Buffer too small (%d) or not enough memory, giving up SDP", (int)bufLen); return -1; } + buff.resize(length); - SalMimeType *mimetype = sal_mime_type_new("application", "sdp"); - SalCustomBody *body = sal_custom_body_new_with_buffer_moving(mimetype, buff, length); + Content body; + body.setContentType("application/sdp"); + body.setBody(move(buff)); set_custom_body(msg, body); - sal_custom_body_unref(body); return 0; } @@ -124,7 +141,7 @@ void SalCallOp::fill_invite(belle_sip_request_t* invite) { this->sdp_offering=TRUE; set_sdp_from_desc(BELLE_SIP_MESSAGE(invite),this->local_media); } else this->sdp_offering=FALSE; - if (this->custom_body) { + if (this->custom_body.getBody().size() > 0) { set_custom_body(BELLE_SIP_MESSAGE(invite), this->custom_body); } } @@ -165,16 +182,17 @@ void SalCallOp::cancelling_invite(const SalErrorInfo *info) { this->state=State::Terminating; } -SalCustomBody *SalCallOp::extract_body(belle_sip_message_t *message) { - const char *body_str = belle_sip_message_get_body(message); +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_length_t *content_length = belle_sip_message_get_header_by_type(message, belle_sip_header_content_length_t); - if (!(body_str && content_type && content_length)) return NULL; - const char *type_str = belle_sip_header_content_type_get_type(content_type); - const char *subtype_str = belle_sip_header_content_type_get_subtype(content_type); - size_t length = belle_sip_header_content_length_get_content_length(content_length); - SalMimeType *mime_type = sal_mime_type_new(type_str, subtype_str); - SalCustomBody *body = sal_custom_body_new_with_buffer_copy(mime_type, body_str, length); + 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; + size_t length = content_length ? belle_sip_header_content_length_get_content_length(content_length) : 0; + const char *body_str = belle_sip_message_get_body(message); + + if (type_str && subtype_str) body.setContentType(ContentType(type_str, subtype_str)); + if (length > 0 && body_str) body.setBody(body_str, length); return body; } @@ -193,18 +211,13 @@ int SalCallOp::extract_sdp(belle_sip_message_t* message,belle_sdp_session_descri return 0; } - SalCustomBody *body = extract_body(message); - if (body == NULL) return 0; - - if (strcmp("application", body->type->type) != 0 || strcmp("sdp", body->type->subtype) != 0) { - sal_custom_body_unref(body); + Content body = extract_body(message); + if (body.getContentType() != "application/sdp") { *error = SalReasonUnsupportedContent; return -1; } - *session_desc = belle_sdp_session_description_parse(string(body->raw_data, body->data_length).c_str()); - sal_custom_body_unref(body); - + *session_desc = belle_sdp_session_description_parse(body.getBodyAsString().c_str()); if (*session_desc == NULL) { ms_error("Failed to parse SDP message."); *error = SalReasonNotAcceptable; diff --git a/coreapi/sal/call_op.h b/coreapi/sal/call_op.h index 2f773ae83..a8a5616bf 100644 --- a/coreapi/sal/call_op.h +++ b/coreapi/sal/call_op.h @@ -30,7 +30,8 @@ public: SalCallOp(Sal *sal): SalOp(sal) {} int set_local_media_description(SalMediaDescription *desc); - int set_local_custom_body(SalCustomBody *body); + int set_local_custom_body(const Content &body); + int set_local_custom_body(const Content &&bdoy); SalMediaDescription *get_remote_media_description() {return this->remote_media;} SalMediaDescription *get_final_media_description(); @@ -67,13 +68,13 @@ public: private: static belle_sip_header_allow_t *create_allow(bool_t enable_update); - static int set_custom_body(belle_sip_message_t *msg, const SalCustomBody *body); + static int set_custom_body(belle_sip_message_t *msg, const Content &body); static int set_sdp(belle_sip_message_t *msg,belle_sdp_session_description_t* session_desc); static int set_sdp_from_desc(belle_sip_message_t *msg, const SalMediaDescription *desc); void set_released(); static void process_io_error_cb(void *user_ctx, const belle_sip_io_error_event_t *event); void cancelling_invite(const SalErrorInfo *info); - static SalCustomBody *extract_body(belle_sip_message_t *message); + static Content extract_body(belle_sip_message_t *message); int extract_sdp(belle_sip_message_t* message,belle_sdp_session_description_t** session_desc, SalReason *error); static void set_addr_to_0000(char value[], size_t sz); void sdp_process(); diff --git a/coreapi/sal/sal.c b/coreapi/sal/sal.c index 4dee10831..2ed838a4e 100644 --- a/coreapi/sal/sal.c +++ b/coreapi/sal/sal.c @@ -174,98 +174,6 @@ int sal_media_description_get_nb_active_streams(const SalMediaDescription *md) { return nb; } -SalMimeType *sal_mime_type_new(const char *type, const char *subtype) { - SalMimeType *mime_type = bctbx_new0(SalMimeType, 1); - if (type) mime_type->type = bctbx_strdup(type); - if (subtype) mime_type->subtype = bctbx_strdup(subtype); - return mime_type; -} - -SalMimeType *sal_mime_type_copy(const SalMimeType *mime_type) { - SalMimeType *new_mime_type = bctbx_new0(SalMimeType, 1); - if (mime_type->type) new_mime_type->type = bctbx_strdup(mime_type->type); - if (mime_type->subtype) new_mime_type->subtype = bctbx_strdup(mime_type->subtype); - return new_mime_type; -} - -SalMimeType *sal_mime_type_ref(SalMimeType *mime_type) { - if (!mime_type) return NULL; - mime_type->ref++; - return mime_type; -} - -void sal_mime_type_unref(SalMimeType *mime_type) { - mime_type->ref--; - if (mime_type->ref <= 0) { - if (mime_type->type) bctbx_free(mime_type->type); - if (mime_type->subtype) bctbx_free(mime_type->subtype); - } - bctbx_free(mime_type); -} - -SalCustomBody *sal_custom_body_new(SalMimeType *type) { - if (type == NULL) { - bctbx_error("creating a SalCustomBody from NULL SalMimeType"); - return NULL; - } - SalCustomBody *body = bctbx_new0(SalCustomBody, 1); - body->type = sal_mime_type_ref(type); - return body; -} - -SalCustomBody *sal_custom_body_new_with_buffer_copy(SalMimeType *type, const char *raw_data, size_t data_length) { - SalCustomBody *body = sal_custom_body_new(type); - if (body == NULL) return NULL; - body->data_length = data_length; - if (data_length > 0 && raw_data) { - body->raw_data = bctbx_new(char, data_length); - memcpy(body->raw_data, raw_data, data_length); - } - return body; -} - -SalCustomBody *sal_custom_body_new_with_buffer_moving(SalMimeType *type, char *raw_data, size_t data_length) { - SalCustomBody *body = sal_custom_body_new(type); - if (body == NULL) return NULL; - sal_custom_body_set_buffer_by_moving(body, raw_data, data_length); - return body; -} - -SalCustomBody *sal_custom_body_ref(SalCustomBody *body) { - if (!body) return NULL; - body->ref++; - return body; -} - -void sal_custom_body_unref(SalCustomBody *body) { - body->ref--; - if (body->ref <= 0) { - if (body->type) sal_mime_type_unref(body->type); - if (body->raw_data) bctbx_free(body->raw_data); - } - bctbx_free(body); -} - -void sal_custom_body_set_buffer_by_copy(SalCustomBody *body, const char *buffer, size_t length) { - char *buff_copy = NULL; - if (buffer && length > 0) { - buff_copy = bctbx_new(char, length); - memcpy(buff_copy, buffer, length); - } else length = 0; - sal_custom_body_set_buffer_by_moving(body, buff_copy, length); -} - -void sal_custom_body_set_buffer_by_moving(SalCustomBody *body, char *buffer, size_t length) { - if (body->raw_data) bctbx_free(body->raw_data); - if (length > 0 && buffer) { - body->raw_data = buffer; - body->data_length = length; - } else { - body->raw_data = NULL; - body->data_length = length; - } -} - static bool_t is_null_address(const char *addr){ return strcmp(addr,"0.0.0.0")==0 || strcmp(addr,"::0")==0; } diff --git a/coreapi/sal/sal.h b/coreapi/sal/sal.h index e45e170cf..37ca7f84e 100644 --- a/coreapi/sal/sal.h +++ b/coreapi/sal/sal.h @@ -362,40 +362,6 @@ int sal_media_description_get_nb_active_streams(const SalMediaDescription *md); } #endif -typedef struct _SalMimeType { - int ref; - char *type; - char *subtype; -} SalMimeType; - -typedef struct _SalCustomBody { - int ref; - SalMimeType *type; - size_t data_length; - char *raw_data; -} SalCustomBody; - -#ifdef __cplusplus -extern "C" { -#endif - -SalMimeType *sal_mime_type_new(const char *type, const char *subtype); -SalMimeType *sal_mime_type_copy(const SalMimeType *mime_type); -SalMimeType *sal_mime_type_ref(SalMimeType *mime_type); -void sal_mime_type_unref(SalMimeType *mime_type); - -SalCustomBody *sal_custom_body_new(SalMimeType *type); -SalCustomBody *sal_custom_body_new_with_buffer_copy(SalMimeType *type, const char *raw_data, size_t data_length); -SalCustomBody *sal_custom_body_new_with_buffer_moving(SalMimeType *type, char *raw_data, size_t data_length); -SalCustomBody *sal_custom_body_ref(SalCustomBody *body); -void sal_custom_body_unref(SalCustomBody *body); -void sal_custom_body_set_buffer_by_copy(SalCustomBody *body, const char *buffer, size_t length); -void sal_custom_body_set_buffer_by_moving(SalCustomBody *body, char *buffer, size_t length); - -#ifdef __cplusplus -} -#endif - typedef enum SalReason{ SalReasonNone, /*no error, please leave first so that it takes 0 value*/ diff --git a/coreapi/sal/sal_op.cpp b/coreapi/sal/sal_op.cpp index e2fa78e09..a72cae041 100644 --- a/coreapi/sal/sal_op.cpp +++ b/coreapi/sal/sal_op.cpp @@ -95,9 +95,6 @@ SalOp::~SalOp() { sal_media_description_unref(this->local_media); if (this->remote_media) sal_media_description_unref(this->remote_media); - if (this->custom_body) { - sal_custom_body_unref(this->custom_body); - } if (this->call_id) ms_free((void *)this->call_id); if (this->service_route) { diff --git a/coreapi/sal/sal_op.h b/coreapi/sal/sal_op.h index 1a58b2b43..d30b3b4d8 100644 --- a/coreapi/sal/sal_op.h +++ b/coreapi/sal/sal_op.h @@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include #include "sal.h" #include "sal.hpp" +#include "content/content.h" LINPHONE_BEGIN_NAMESPACE @@ -208,7 +209,7 @@ protected: char *remote_contact = NULL; SalMediaDescription *local_media = NULL; SalMediaDescription *remote_media = NULL; - SalCustomBody *custom_body = NULL; + Content custom_body; void *user_pointer = NULL; const char* call_id = NULL; char* realm = NULL; diff --git a/src/content/content-type.cpp b/src/content/content-type.cpp index 1605d6eed..8df3a234b 100644 --- a/src/content/content-type.cpp +++ b/src/content/content-type.cpp @@ -66,14 +66,22 @@ ContentType &ContentType::operator= (const ContentType &src) { return *this; } -bool ContentType::operator== (const ContentType &contentType) { +bool ContentType::operator== (const ContentType &contentType) const { return getType() == contentType.getType() && getSubType() == contentType.getSubType(); } -bool ContentType::operator== (const string &contentType) { +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); +} + const string &ContentType::getType () const { L_D(); return d->type; diff --git a/src/content/content-type.h b/src/content/content-type.h index c78d75c33..8e3851cbf 100644 --- a/src/content/content-type.h +++ b/src/content/content-type.h @@ -35,8 +35,10 @@ public: ContentType &operator= (const ContentType &src); - bool operator== (const ContentType &contentType); - bool operator== (const std::string &contentType); + 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; bool isValid () const; diff --git a/src/content/content.cpp b/src/content/content.cpp index 8b055e6ba..23b56f3cb 100644 --- a/src/content/content.cpp +++ b/src/content/content.cpp @@ -107,6 +107,11 @@ void Content::setBody (const vector &body) { d->body = body; } +void Content::setBody (const std::vector &&body) { + L_D(); + d->body = body; +} + void Content::setBody (const string &body) { L_D(); d->body = vector(body.cbegin(), body.cend()); diff --git a/src/content/content.h b/src/content/content.h index f25b0d783..62b5cbe20 100644 --- a/src/content/content.h +++ b/src/content/content.h @@ -49,6 +49,7 @@ public: const std::vector &getBody () const; std::string getBodyAsString () const; void setBody (const std::vector &body); + void setBody (const std::vector &&body); void setBody (const std::string &body); void setBody (const void *buffer, size_t size); size_t getSize () const;