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

Replace SalCustomBody by LinphonePrivate::Content

parent 86b626d3
......@@ -3,6 +3,7 @@
#include "offeranswer.h"
#include <bctoolbox/defs.h>
#include <belle-sip/provider.h>
#include <stdexcept>
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<char *>(belle_sip_malloc(bufLen));
vector<char> 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<char *>(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;
......
......@@ -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();
......
......@@ -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;
}
......
......@@ -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*/
......
......@@ -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) {
......
......@@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <belle-sip/types.h>
#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;
......
......@@ -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;
......
......@@ -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;
......
......@@ -107,6 +107,11 @@ void Content::setBody (const vector<char> &body) {
d->body = body;
}
void Content::setBody (const std::vector<char> &&body) {
L_D();
d->body = body;
}
void Content::setBody (const string &body) {
L_D();
d->body = vector<char>(body.cbegin(), body.cend());
......
......@@ -49,6 +49,7 @@ public:
const std::vector<char> &getBody () const;
std::string getBodyAsString () const;
void setBody (const std::vector<char> &body);
void setBody (const std::vector<char> &&body);
void setBody (const std::string &body);
void setBody (const void *buffer, size_t size);
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