Commit a830806c authored by François Grisez's avatar François Grisez

Replace SalCustomBody by LinphonePrivate::Content

parent 86b626d3
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include "offeranswer.h" #include "offeranswer.h"
#include <bctoolbox/defs.h> #include <bctoolbox/defs.h>
#include <belle-sip/provider.h> #include <belle-sip/provider.h>
#include <stdexcept>
using namespace std; using namespace std;
...@@ -11,7 +12,7 @@ using namespace std; ...@@ -11,7 +12,7 @@ using namespace std;
LINPHONE_BEGIN_NAMESPACE LINPHONE_BEGIN_NAMESPACE
int SalCallOp::set_local_media_description(SalMediaDescription *desc) { 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); bctbx_error("cannot set local media description on SalOp [%p] because a custom body is already set", this);
return -1; return -1;
} }
...@@ -32,13 +33,21 @@ int SalCallOp::set_local_media_description(SalMediaDescription *desc) { ...@@ -32,13 +33,21 @@ int SalCallOp::set_local_media_description(SalMediaDescription *desc) {
return 0; return 0;
} }
int SalCallOp::set_local_custom_body(SalCustomBody *body) { int SalCallOp::set_local_custom_body(const Content &body) {
if (this->local_media) { if (this->local_media) {
bctbx_error("cannot set custom body on SalOp [%p] because a local media description is already set", this); bctbx_error("cannot set custom body on SalOp [%p] because a local media description is already set", this);
return -1; return -1;
} }
if (this->custom_body) sal_custom_body_unref(this->custom_body); this->custom_body = body;
this->custom_body = sal_custom_body_ref(body ? body : NULL); 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; return 0;
} }
...@@ -50,24 +59,31 @@ belle_sip_header_allow_t *SalCallOp::create_allow(bool_t enable_update) { ...@@ -50,24 +59,31 @@ belle_sip_header_allow_t *SalCallOp::create_allow(bool_t enable_update) {
return header_allow; return header_allow;
} }
int SalCallOp::set_custom_body(belle_sip_message_t *msg, const SalCustomBody *body) { int SalCallOp::set_custom_body(belle_sip_message_t *msg, const Content &body) {
if (body->data_length > SIP_MESSAGE_BODY_LIMIT) { 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); bctbx_error("trying to add a body greater than %dkB to message [%p]", SIP_MESSAGE_BODY_LIMIT/1024, msg);
return -1; 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); bctbx_error("trying to add an empty custom body to message [%p]", msg);
return -1; 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_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(body->data_length); 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_type));
belle_sip_message_add_header(msg, BELLE_SIP_HEADER(content_length)); belle_sip_message_add_header(msg, BELLE_SIP_HEADER(content_length));
char *buffer = bctbx_new(char, body->data_length); char *buffer = bctbx_new(char, bodySize);
memcpy(buffer, body->raw_data, body->data_length); memcpy(buffer, body.getBody().data(), bodySize);
belle_sip_message_assign_body(msg, buffer, body->data_length); belle_sip_message_assign_body(msg, buffer, bodySize);
return 0; return 0;
} }
...@@ -75,31 +91,32 @@ int SalCallOp::set_custom_body(belle_sip_message_t *msg, const SalCustomBody *bo ...@@ -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) { 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; belle_sip_error_code error = BELLE_SIP_BUFFER_OVERFLOW;
size_t length = 0; size_t length = 0;
size_t bufLen = 2048;
if (session_desc == NULL) return -1; if (session_desc == NULL) return -1;
size_t bufLen = 2048; vector<char> buff(bufLen);
char *buff = reinterpret_cast<char *>(belle_sip_malloc(bufLen));
/* try to marshal the description. This could go higher than 2k so we iterate */ /* 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){ while( error != BELLE_SIP_OK && bufLen <= SIP_MESSAGE_BODY_LIMIT) {
error = belle_sip_object_marshal(BELLE_SIP_OBJECT(session_desc),buff,bufLen,&length); error = belle_sip_object_marshal(BELLE_SIP_OBJECT(session_desc),buff.data(),bufLen,&length);
if( error != BELLE_SIP_OK ){ if( error != BELLE_SIP_OK ){
bufLen *= 2; bufLen *= 2;
length = 0; length = 0;
buff = reinterpret_cast<char *>(belle_sip_realloc(buff,bufLen)); buff.resize(bufLen);
} }
} }
/* give up if hard limit reached */ /* 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); ms_error("Buffer too small (%d) or not enough memory, giving up SDP", (int)bufLen);
return -1; return -1;
} }
buff.resize(length);
SalMimeType *mimetype = sal_mime_type_new("application", "sdp"); Content body;
SalCustomBody *body = sal_custom_body_new_with_buffer_moving(mimetype, buff, length); body.setContentType("application/sdp");
body.setBody(move(buff));
set_custom_body(msg, body); set_custom_body(msg, body);
sal_custom_body_unref(body);
return 0; return 0;
} }
...@@ -124,7 +141,7 @@ void SalCallOp::fill_invite(belle_sip_request_t* invite) { ...@@ -124,7 +141,7 @@ void SalCallOp::fill_invite(belle_sip_request_t* invite) {
this->sdp_offering=TRUE; this->sdp_offering=TRUE;
set_sdp_from_desc(BELLE_SIP_MESSAGE(invite),this->local_media); set_sdp_from_desc(BELLE_SIP_MESSAGE(invite),this->local_media);
} else this->sdp_offering=FALSE; } 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); set_custom_body(BELLE_SIP_MESSAGE(invite), this->custom_body);
} }
} }
...@@ -165,16 +182,17 @@ void SalCallOp::cancelling_invite(const SalErrorInfo *info) { ...@@ -165,16 +182,17 @@ void SalCallOp::cancelling_invite(const SalErrorInfo *info) {
this->state=State::Terminating; this->state=State::Terminating;
} }
SalCustomBody *SalCallOp::extract_body(belle_sip_message_t *message) { Content SalCallOp::extract_body(belle_sip_message_t *message) {
const char *body_str = belle_sip_message_get_body(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_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); 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 = content_type ? belle_sip_header_content_type_get_type(content_type) : NULL;
const char *type_str = belle_sip_header_content_type_get_type(content_type); const char *subtype_str = content_type ? belle_sip_header_content_type_get_subtype(content_type) : NULL;
const char *subtype_str = belle_sip_header_content_type_get_subtype(content_type); size_t length = content_length ? belle_sip_header_content_length_get_content_length(content_length) : 0;
size_t length = belle_sip_header_content_length_get_content_length(content_length); const char *body_str = belle_sip_message_get_body(message);
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); if (type_str && subtype_str) body.setContentType(ContentType(type_str, subtype_str));
if (length > 0 && body_str) body.setBody(body_str, length);
return body; return body;
} }
...@@ -193,18 +211,13 @@ int SalCallOp::extract_sdp(belle_sip_message_t* message,belle_sdp_session_descri ...@@ -193,18 +211,13 @@ int SalCallOp::extract_sdp(belle_sip_message_t* message,belle_sdp_session_descri
return 0; return 0;
} }
SalCustomBody *body = extract_body(message); Content body = extract_body(message);
if (body == NULL) return 0; if (body.getContentType() != "application/sdp") {
if (strcmp("application", body->type->type) != 0 || strcmp("sdp", body->type->subtype) != 0) {
sal_custom_body_unref(body);
*error = SalReasonUnsupportedContent; *error = SalReasonUnsupportedContent;
return -1; return -1;
} }
*session_desc = belle_sdp_session_description_parse(string(body->raw_data, body->data_length).c_str()); *session_desc = belle_sdp_session_description_parse(body.getBodyAsString().c_str());
sal_custom_body_unref(body);
if (*session_desc == NULL) { if (*session_desc == NULL) {
ms_error("Failed to parse SDP message."); ms_error("Failed to parse SDP message.");
*error = SalReasonNotAcceptable; *error = SalReasonNotAcceptable;
......
...@@ -30,7 +30,8 @@ public: ...@@ -30,7 +30,8 @@ public:
SalCallOp(Sal *sal): SalOp(sal) {} SalCallOp(Sal *sal): SalOp(sal) {}
int set_local_media_description(SalMediaDescription *desc); 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_remote_media_description() {return this->remote_media;}
SalMediaDescription *get_final_media_description(); SalMediaDescription *get_final_media_description();
...@@ -67,13 +68,13 @@ public: ...@@ -67,13 +68,13 @@ public:
private: private:
static belle_sip_header_allow_t *create_allow(bool_t enable_update); 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(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); static int set_sdp_from_desc(belle_sip_message_t *msg, const SalMediaDescription *desc);
void set_released(); void set_released();
static void process_io_error_cb(void *user_ctx, const belle_sip_io_error_event_t *event); static void process_io_error_cb(void *user_ctx, const belle_sip_io_error_event_t *event);
void cancelling_invite(const SalErrorInfo *info); 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); 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); static void set_addr_to_0000(char value[], size_t sz);
void sdp_process(); void sdp_process();
......
...@@ -174,98 +174,6 @@ int sal_media_description_get_nb_active_streams(const SalMediaDescription *md) { ...@@ -174,98 +174,6 @@ int sal_media_description_get_nb_active_streams(const SalMediaDescription *md) {
return nb; 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){ static bool_t is_null_address(const char *addr){
return strcmp(addr,"0.0.0.0")==0 || strcmp(addr,"::0")==0; return strcmp(addr,"0.0.0.0")==0 || strcmp(addr,"::0")==0;
} }
......
...@@ -362,40 +362,6 @@ int sal_media_description_get_nb_active_streams(const SalMediaDescription *md); ...@@ -362,40 +362,6 @@ int sal_media_description_get_nb_active_streams(const SalMediaDescription *md);
} }
#endif #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{ typedef enum SalReason{
SalReasonNone, /*no error, please leave first so that it takes 0 value*/ SalReasonNone, /*no error, please leave first so that it takes 0 value*/
......
...@@ -95,9 +95,6 @@ SalOp::~SalOp() { ...@@ -95,9 +95,6 @@ SalOp::~SalOp() {
sal_media_description_unref(this->local_media); sal_media_description_unref(this->local_media);
if (this->remote_media) if (this->remote_media)
sal_media_description_unref(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) if (this->call_id)
ms_free((void *)this->call_id); ms_free((void *)this->call_id);
if (this->service_route) { if (this->service_route) {
......
...@@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ...@@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <belle-sip/types.h> #include <belle-sip/types.h>
#include "sal.h" #include "sal.h"
#include "sal.hpp" #include "sal.hpp"
#include "content/content.h"
LINPHONE_BEGIN_NAMESPACE LINPHONE_BEGIN_NAMESPACE
...@@ -208,7 +209,7 @@ protected: ...@@ -208,7 +209,7 @@ protected:
char *remote_contact = NULL; char *remote_contact = NULL;
SalMediaDescription *local_media = NULL; SalMediaDescription *local_media = NULL;
SalMediaDescription *remote_media = NULL; SalMediaDescription *remote_media = NULL;
SalCustomBody *custom_body = NULL; Content custom_body;
void *user_pointer = NULL; void *user_pointer = NULL;
const char* call_id = NULL; const char* call_id = NULL;
char* realm = NULL; char* realm = NULL;
......
...@@ -66,14 +66,22 @@ ContentType &ContentType::operator= (const ContentType &src) { ...@@ -66,14 +66,22 @@ ContentType &ContentType::operator= (const ContentType &src) {
return *this; return *this;
} }
bool ContentType::operator== (const ContentType &contentType) { bool ContentType::operator== (const ContentType &contentType) const {
return getType() == contentType.getType() && getSubType() == contentType.getSubType(); return getType() == contentType.getType() && getSubType() == contentType.getSubType();
} }
bool ContentType::operator== (const string &contentType) { bool ContentType::operator== (const string &contentType) const {
return *this == ContentType(contentType); 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 { const string &ContentType::getType () const {
L_D(); L_D();
return d->type; return d->type;
......
...@@ -35,8 +35,10 @@ public: ...@@ -35,8 +35,10 @@ public:
ContentType &operator= (const ContentType &src); ContentType &operator= (const ContentType &src);
bool operator== (const ContentType &contentType); bool operator== (const ContentType &contentType) const;
bool operator== (const std::string &contentType); bool operator== (const std::string &contentType) const;
bool operator!= (const ContentType &contentType) const;
bool operator!= (const std::string &contentType) const;
bool isValid () const; bool isValid () const;
......
...@@ -107,6 +107,11 @@ void Content::setBody (const vector<char> &body) { ...@@ -107,6 +107,11 @@ void Content::setBody (const vector<char> &body) {
d->body = body; d->body = body;
} }
void Content::setBody (const std::vector<char> &&body) {
L_D();
d->body = body;
}
void Content::setBody (const string &body) { void Content::setBody (const string &body) {
L_D(); L_D();
d->body = vector<char>(body.cbegin(), body.cend()); d->body = vector<char>(body.cbegin(), body.cend());
......
...@@ -49,6 +49,7 @@ public: ...@@ -49,6 +49,7 @@ public:
const std::vector<char> &getBody () const; const std::vector<char> &getBody () const;
std::string getBodyAsString () const; std::string getBodyAsString () const;
void setBody (const std::vector<char> &body); void setBody (const std::vector<char> &body);
void setBody (const std::vector<char> &&body);
void setBody (const std::string &body); void setBody (const std::string &body);
void setBody (const void *buffer, size_t size); void setBody (const void *buffer, size_t size);
size_t getSize () const; size_t getSize () const;
......
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