From b5e0165503501a7a4eb7e8f405734db2b7b1d0c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Grisez?= Date: Fri, 29 Sep 2017 17:52:38 +0200 Subject: [PATCH] Reworks Sal in order to be able to send and accept INVITEs with not-SDP body --- coreapi/sal/call_op.cpp | 237 ++++++++++++++++------------ coreapi/sal/call_op.h | 75 +++++---- coreapi/sal/sal_op.cpp | 4 - coreapi/sal/sal_op.h | 3 - src/c-wrapper/api/c-call-params.cpp | 4 +- src/content/content.cpp | 5 + src/content/content.h | 2 + tester/call_single_tester.c | 15 +- 8 files changed, 204 insertions(+), 141 deletions(-) diff --git a/coreapi/sal/call_op.cpp b/coreapi/sal/call_op.cpp index 7ee12ad0d..68daf9355 100644 --- a/coreapi/sal/call_op.cpp +++ b/coreapi/sal/call_op.cpp @@ -3,21 +3,27 @@ #include "offeranswer.h" #include #include -#include using namespace std; -#define SIP_MESSAGE_BODY_LIMIT 16*1024 // 16kB - LINPHONE_BEGIN_NAMESPACE +SalCallOp::~SalCallOp() { + if (this->local_media) sal_media_description_unref(this->local_media); + if (this->remote_media) sal_media_description_unref(this->remote_media); +} + int SalCallOp::set_local_media_description(SalMediaDescription *desc) { - 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; - } - if (desc) sal_media_description_ref(desc); + + belle_sip_error_code error; + belle_sdp_session_description_t *sdp = media_description_to_sdp(desc); + vector buffer = marshal_media_description(sdp, error); + if (error != BELLE_SIP_OK) return -1; + + this->local_body.setContentType("application/sdp"); + this->local_body.setBody(move(buffer)); + if (this->local_media) sal_media_description_unref(this->local_media); this->local_media=desc; @@ -33,21 +39,30 @@ int SalCallOp::set_local_media_description(SalMediaDescription *desc) { 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; +int SalCallOp::set_local_body(const Content &body) { + Content bodyCopy = body; + return set_local_body(move(bodyCopy)); } -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; +int SalCallOp::set_local_body(const Content &&body) { + if (!body.isValid()) return -1; + + if (body.getContentType() == "application/sdp") { + SalMediaDescription *desc = NULL; + if (body.getSize() > 0) { + belle_sdp_session_description_t *sdp = belle_sdp_session_description_parse(body.getBodyAsString().c_str()); + if (sdp == NULL) return -1; + desc = sal_media_description_new(); + if (sdp_to_media_description(sdp, desc) != 0) { + sal_media_description_unref(desc); + return -1; + } + } + if (this->local_media) sal_media_description_unref(this->local_media); + this->local_media = desc; } - this->custom_body = body; + + this->local_body = body; return 0; } @@ -64,38 +79,31 @@ int SalCallOp::set_custom_body(belle_sip_message_t *msg, const Content &body) { 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 (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); + bctbx_error("trying to add a body greater than %lukB to message [%p]", (unsigned long)SIP_MESSAGE_BODY_LIMIT/1024, msg); return -1; } - belle_sip_header_content_type_t *content_type = belle_sip_header_content_type_create(contentType.getType().c_str(), contentType.getSubType().c_str()); + if (contentType.isValid()) { + belle_sip_header_content_type_t *content_type = belle_sip_header_content_type_create(contentType.getType().c_str(), contentType.getSubType().c_str()); + belle_sip_message_add_header(msg, BELLE_SIP_HEADER(content_type)); + } 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, bodySize); - memcpy(buffer, body.getBody().data(), bodySize); - belle_sip_message_assign_body(msg, buffer, bodySize); + if (bodySize > 0) { + char *buffer = bctbx_new(char, bodySize); + memcpy(buffer, body.getBody().data(), bodySize); + belle_sip_message_assign_body(msg, buffer, bodySize); + } return 0; } -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; +std::vector SalCallOp::marshal_media_description(belle_sdp_session_description_t *session_desc, belle_sip_error_code &error) { size_t length = 0; size_t bufLen = 2048; - - if (session_desc == NULL) return -1; - vector buff(bufLen); + error = BELLE_SIP_BUFFER_OVERFLOW; /* try to marshal the description. This could go higher than 2k so we iterate */ while( error != BELLE_SIP_OK && bufLen <= SIP_MESSAGE_BODY_LIMIT) { @@ -106,12 +114,24 @@ int SalCallOp::set_sdp(belle_sip_message_t *msg,belle_sdp_session_description_t* buff.resize(bufLen); } } + /* give up if hard limit reached */ if (error != BELLE_SIP_OK) { ms_error("Buffer too small (%d) or not enough memory, giving up SDP", (int)bufLen); - return -1; + return std::vector(); // return a new vector in order to free the buffer held by 'buff' vector } + buff.resize(length); + return buff; +} + +int SalCallOp::set_sdp(belle_sip_message_t *msg,belle_sdp_session_description_t* session_desc) { + belle_sip_error_code error; + + if (session_desc == NULL) return -1; + + vector buff = marshal_media_description(session_desc, error); + if (error != BELLE_SIP_OK) return -1; Content body; body.setContentType("application/sdp"); @@ -132,18 +152,12 @@ int SalCallOp::set_sdp_from_desc(belle_sip_message_t *msg, const SalMediaDescrip void SalCallOp::fill_invite(belle_sip_request_t* invite) { belle_sip_message_add_header(BELLE_SIP_MESSAGE(invite),BELLE_SIP_HEADER(create_allow(this->root->enable_sip_update))); - if (this->root->session_expires!=0){ 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")); } - if (this->local_media){ - this->sdp_offering=TRUE; - set_sdp_from_desc(BELLE_SIP_MESSAGE(invite),this->local_media); - } else this->sdp_offering=FALSE; - if (this->custom_body.getBody().size() > 0) { - set_custom_body(BELLE_SIP_MESSAGE(invite), this->custom_body); - } + this->sdp_offering = (this->local_body.getContentType() == "application/sdp"); + set_custom_body(BELLE_SIP_MESSAGE(invite), this->local_body); } void SalCallOp::set_released() { @@ -196,7 +210,7 @@ Content SalCallOp::extract_body(belle_sip_message_t *message) { return body; } -int SalCallOp::extract_sdp(belle_sip_message_t* message,belle_sdp_session_description_t** session_desc, SalReason *error) { +int SalCallOp::parse_sdp_body(const Content &body,belle_sdp_session_description_t** session_desc, SalReason *error) { *session_desc = NULL; *error = SalReasonNone; @@ -210,12 +224,6 @@ int SalCallOp::extract_sdp(belle_sip_message_t* message,belle_sdp_session_descri ms_error("Simulating no SDP for op %p", this); return 0; } - - Content body = extract_body(message); - if (body.getContentType() != "application/sdp") { - *error = SalReasonUnsupportedContent; - return -1; - } *session_desc = belle_sdp_session_description_parse(body.getBodyAsString().c_str()); if (*session_desc == NULL) { @@ -290,21 +298,27 @@ void SalCallOp::sdp_process(){ } } -void SalCallOp::handle_sdp_from_response(belle_sip_response_t* response) { - belle_sdp_session_description_t* sdp; +void SalCallOp::handle_body_from_response(belle_sip_response_t* response) { SalReason reason; + belle_sdp_session_description_t* sdp; + Content body = extract_body(BELLE_SIP_MESSAGE(response)); if (this->remote_media){ sal_media_description_unref(this->remote_media); this->remote_media=NULL; } - if (extract_sdp(BELLE_SIP_MESSAGE(response),&sdp,&reason)==0) { - if (sdp){ - this->remote_media=sal_media_description_new(); - sdp_to_media_description(sdp,this->remote_media); - }/*if no sdp in response, what can we do ?*/ + if (body.getContentType() == "application/sdp") { + if (parse_sdp_body(body, &sdp, &reason) == 0) { + if (sdp) { + this->remote_media = sal_media_description_new(); + sdp_to_media_description(sdp, this->remote_media); + this->remote_body = move(body); + }/*if no sdp in response, what can we do ?*/ + } + /* process sdp in any case to reset result media description*/ + if (this->local_media) sdp_process(); + } else { + this->remote_body = move(body); } - /* process sdp in any case to reset result media description*/ - if (this->local_media) sdp_process(); } void SalCallOp::set_error(belle_sip_response_t* response, bool_t fatal){ @@ -366,7 +380,7 @@ void SalCallOp::process_response_cb(void *op_base, const belle_sip_response_even } else if (code >= 180 && code<200) { belle_sip_response_t *prev_response=reinterpret_cast(belle_sip_object_data_get(BELLE_SIP_OBJECT(dialog),"early_response")); if (!prev_response || code>belle_sip_response_get_status_code(prev_response)){ - op->handle_sdp_from_response(response); + op->handle_body_from_response(response); op->root->callbacks.call_ringing(op); } belle_sip_object_data_set(BELLE_SIP_OBJECT(dialog),"early_response",belle_sip_object_ref(response),belle_sip_object_unref); @@ -376,7 +390,7 @@ void SalCallOp::process_response_cb(void *op_base, const belle_sip_response_even } } else if (code >=200 && code<300) { if (strcmp("UPDATE",method)==0) { - op->handle_sdp_from_response(response); + op->handle_body_from_response(response); op->root->callbacks.call_accepted(op); } else if (strcmp("CANCEL", method) == 0) { op->root->callbacks.call_cancel_done(op); @@ -390,7 +404,7 @@ void SalCallOp::process_response_cb(void *op_base, const belle_sip_response_even case State::Active: /*re-invite, INFO, UPDATE case*/ if (strcmp("INVITE",method)==0){ if (code >=200 && code<300) { - op->handle_sdp_from_response(response); + op->handle_body_from_response(response); ack=belle_sip_dialog_create_ack(op->dialog,belle_sip_dialog_get_local_seq_number(op->dialog)); if (ack == NULL) { ms_error("This call has been already terminated."); @@ -518,30 +532,58 @@ int SalCallOp::is_media_description_acceptable(SalMediaDescription *md) { return TRUE; } -SalReason SalCallOp::process_sdp_for_invite(belle_sip_request_t* invite) { - belle_sdp_session_description_t* sdp; +SalReason SalCallOp::process_body_for_invite(belle_sip_request_t* invite) { SalReason reason = SalReasonNone; - SalErrorInfo sei; + + Content body = extract_body(BELLE_SIP_MESSAGE(invite)); + if (!body.isValid()) return SalReasonUnsupportedContent; + + if (body.getContentType() == "application/sdp") { + belle_sdp_session_description_t* sdp; + if (parse_sdp_body(body, &sdp, &reason) == 0) { + if (sdp) { + this->sdp_offering = FALSE; + if (this->remote_media) sal_media_description_unref(this->remote_media); + this->remote_media = sal_media_description_new(); + sdp_to_media_description(sdp, this->remote_media); + /*make some sanity check about the SDP received*/ + if (!is_media_description_acceptable(this->remote_media)) { + reason = SalReasonNotAcceptable; + } + belle_sip_object_unref(sdp); + } else this->sdp_offering = TRUE; /*INVITE without SDP*/ + } + if (reason != SalReasonNone) { + SalErrorInfo sei; + memset(&sei, 0, sizeof(sei)); + sal_error_info_set(&sei, reason, "SIP", 0, NULL, NULL); + decline_with_error_info(&sei, NULL); + sal_error_info_reset(&sei); + } + } + this->remote_body = move(body); + return reason; +} - memset(&sei, 0, sizeof(sei)); - if (extract_sdp(BELLE_SIP_MESSAGE(invite),&sdp,&reason)==0) { - if (sdp){ - this->sdp_offering=FALSE; - this->remote_media=sal_media_description_new(); - sdp_to_media_description(sdp,this->remote_media); - /*make some sanity check about the SDP received*/ - if (!is_media_description_acceptable(this->remote_media)){ - reason=SalReasonNotAcceptable; +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") { + belle_sdp_session_description_t *sdp; + if (parse_sdp_body(body, &sdp, &reason) == 0) { + if (sdp) { + if (this->remote_media) sal_media_description_unref(this->remote_media); + this->remote_media = sal_media_description_new(); + sdp_to_media_description(sdp, this->remote_media); + this->sdp_process(); + belle_sip_object_unref(sdp); + } else { + ms_warning("SDP expected in ACK but not found."); } - belle_sip_object_unref(sdp); - }else this->sdp_offering=TRUE; /*INVITE without SDP*/ - } - - if (reason != SalReasonNone){ - sal_error_info_set(&sei, reason,"SIP", 0, NULL, NULL); - decline_with_error_info(&sei,NULL); - sal_error_info_reset(&sei); + } } + this->remote_body = move(body); return reason; } @@ -581,7 +623,6 @@ void SalCallOp::process_request_event_cb(void *op_base, const belle_sip_request_ SalCallOp * op = (SalCallOp *)op_base; SalReason reason; belle_sip_server_transaction_t* server_transaction=NULL; - belle_sdp_session_description_t* sdp; belle_sip_request_t* req = belle_sip_request_event_get_request(event); belle_sip_dialog_state_t dialog_state; belle_sip_response_t* resp; @@ -624,7 +665,7 @@ void SalCallOp::process_request_event_cb(void *op_base, const belle_sip_request_ ms_warning("replace header already set"); } - if ( (reason = op->process_sdp_for_invite(req)) == SalReasonNone) { + if ( (reason = op->process_body_for_invite(req)) == SalReasonNone) { if ((call_info=belle_sip_message_get_header(BELLE_SIP_MESSAGE(req),"Call-Info"))) { if( strstr(belle_sip_header_get_unparsed_value(call_info),"answer-after=") != NULL) { op->auto_answer_asked=TRUE; @@ -659,7 +700,7 @@ void SalCallOp::process_request_event_cb(void *op_base, const belle_sip_request_ belle_sip_server_transaction_send_response(server_transaction,resp); } else if (strcmp("UPDATE",method)==0) { op->reset_descriptions(); - if (op->process_sdp_for_invite(req)==SalReasonNone) + if (op->process_body_for_invite(req)==SalReasonNone) op->root->callbacks.call_updating(op,TRUE); } else { belle_sip_error("Unexpected method [%s] for dialog state BELLE_SIP_DIALOG_EARLY",belle_sip_request_get_method(req)); @@ -673,19 +714,7 @@ void SalCallOp::process_request_event_cb(void *op_base, const belle_sip_request_ if (!op->pending_client_trans || !belle_sip_transaction_state_is_transient(belle_sip_transaction_get_state((belle_sip_transaction_t*)op->pending_client_trans))){ if (op->sdp_offering){ - SalReason reason; - if (op->extract_sdp(BELLE_SIP_MESSAGE(req),&sdp,&reason)==0) { - if (sdp){ - if (op->remote_media) - sal_media_description_unref(op->remote_media); - op->remote_media=sal_media_description_new(); - sdp_to_media_description(sdp,op->remote_media); - op->sdp_process(); - belle_sip_object_unref(sdp); - }else{ - ms_warning("SDP expected in ACK but not found."); - } - } + op->process_body_for_ack(req); } op->root->callbacks.call_ack_received(op, (SalCustomHeader*)req); }else{ @@ -705,7 +734,7 @@ void SalCallOp::process_request_event_cb(void *op_base, const belle_sip_request_ } else { /*re-invite*/ op->reset_descriptions(); - if (op->process_sdp_for_invite(req)==SalReasonNone) + if (op->process_body_for_invite(req)==SalReasonNone) op->root->callbacks.call_updating(op,is_update); } } else if (strcmp("INFO",method)==0){ diff --git a/coreapi/sal/call_op.h b/coreapi/sal/call_op.h index 8ac3605bb..1b4757d37 100644 --- a/coreapi/sal/call_op.h +++ b/coreapi/sal/call_op.h @@ -28,12 +28,14 @@ LINPHONE_BEGIN_NAMESPACE class SalCallOp: public SalOp, public SalMessageOpInterface { public: SalCallOp(Sal *sal): SalOp(sal) {} + ~SalCallOp() override; int set_local_media_description(SalMediaDescription *desc); - int set_local_custom_body(const Content &body); - int set_local_custom_body(const Content &&bdoy); + int set_local_body(const Content &body); + int set_local_body(const Content &&body); SalMediaDescription *get_remote_media_description() {return this->remote_media;} + const Content &get_remote_body() const {return this->remote_body;} SalMediaDescription *get_final_media_description(); int call(const char *from, const char *to, const char *subject); @@ -47,7 +49,7 @@ public: int refer(const char *refer_to_); int refer_with_replaces(SalCallOp *other_call_op); int set_referer(SalCallOp *refered_call); - SalCallOp *get_replaces(); + SalCallOp *get_replaces(); int send_dtmf(char dtmf); int terminate() {return terminate_with_error(NULL);} int terminate_with_error(const SalErrorInfo *info); @@ -62,46 +64,65 @@ public: void set_replaces(const char *call_id, const char *from_tag, const char *to_tag); void set_sdp_handling(SalOpSDPHandling handling); -// int send_message(const char *from, const char *to, const char *msg) override {return MessageOpInterface::send_message(from, to, msg);} + // Implementation of SalMessageOpInterface int send_message(const char *from, const char *to, const char* content_type, const char *msg, const char *peer_uri) override; int reply(SalReason reason) override {return SalOp::reply_message(reason);} private: + virtual void fill_cbs() override; + void set_released(); + + void set_error(belle_sip_response_t* response, bool_t fatal); + void call_terminated(belle_sip_server_transaction_t* server_transaction, int status_code, belle_sip_request_t* cancel_request); + void reset_descriptions(); + + int parse_sdp_body(const Content &body,belle_sdp_session_description_t** session_desc, SalReason *error); + void sdp_process(); + void handle_body_from_response(belle_sip_response_t* response); + SalReason process_body_for_invite(belle_sip_request_t* invite); + SalReason process_body_for_ack(belle_sip_request_t *ack); + void handle_offer_answer_response(belle_sip_response_t* response); + + void fill_invite(belle_sip_request_t* invite); + void cancelling_invite(const SalErrorInfo *info); + int refer_to(belle_sip_header_refer_to_t* refer_to, belle_sip_header_referred_by_t* referred_by); + int send_notify_for_refer(int code, const char *reason); + void notify_last_response(SalCallOp *newcall); + void process_refer(const belle_sip_request_event_t *event, belle_sip_server_transaction_t *server_transaction); + void process_notify(const belle_sip_request_event_t *event, belle_sip_server_transaction_t* server_transaction); + + static void set_addr_to_0000(char value[], size_t sz); + static int is_media_description_acceptable(SalMediaDescription *md); + static bool_t is_a_pending_invite_incoming_transaction(belle_sip_transaction_t *tr); + static void set_call_as_released(SalCallOp *op); + static void unsupported_method(belle_sip_server_transaction_t* server_transaction,belle_sip_request_t* request); + static belle_sip_header_reason_t *make_reason_header( const SalErrorInfo *info); static belle_sip_header_allow_t *create_allow(bool_t enable_update); + static std::vector marshal_media_description(belle_sdp_session_description_t *session_desc, belle_sip_error_code &error); + + // belle_sip_message handlers 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 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(); - void handle_sdp_from_response(belle_sip_response_t* response); - void set_error(belle_sip_response_t* response, bool_t fatal); + + // Callbacks static int vfu_retry_cb (void *user_data, unsigned int events); static void process_response_cb(void *op_base, const belle_sip_response_event_t *event); static void process_timeout_cb(void *user_ctx, const belle_sip_timeout_event_t *event); static void process_transaction_terminated_cb(void *user_ctx, const belle_sip_transaction_terminated_event_t *event); - static int is_media_description_acceptable(SalMediaDescription *md); - SalReason process_sdp_for_invite(belle_sip_request_t* invite); - void call_terminated(belle_sip_server_transaction_t* server_transaction, int status_code, belle_sip_request_t* cancel_request); - void reset_descriptions(); - static void unsupported_method(belle_sip_server_transaction_t* server_transaction,belle_sip_request_t* request); - static bool_t is_a_pending_invite_incoming_transaction(belle_sip_transaction_t *tr); static void process_request_event_cb(void *op_base, const belle_sip_request_event_t *event); - static void set_call_as_released(SalCallOp *op); static void process_dialog_terminated_cb(void *ctx, const belle_sip_dialog_terminated_event_t *event); - virtual void fill_cbs() override; - void fill_invite(belle_sip_request_t* invite); - static belle_sip_header_reason_t *make_reason_header( const SalErrorInfo *info); - int refer_to(belle_sip_header_refer_to_t* refer_to, belle_sip_header_referred_by_t* referred_by); - void notify_last_response(SalCallOp *newcall); - int send_notify_for_refer(int code, const char *reason); - void process_refer(const belle_sip_request_event_t *event, belle_sip_server_transaction_t *server_transaction); - void process_notify(const belle_sip_request_event_t *event, belle_sip_server_transaction_t* server_transaction); - void handle_offer_answer_response(belle_sip_response_t* response); + + // Private constants + static const size_t SIP_MESSAGE_BODY_LIMIT = 16*1024; // 16kB + + // Attributes + SalMediaDescription *local_media = NULL; + SalMediaDescription *remote_media = NULL; + Content local_body; + Content remote_body; }; LINPHONE_END_NAMESPACE diff --git a/coreapi/sal/sal_op.cpp b/coreapi/sal/sal_op.cpp index a73d018ce..d3c26b8fd 100644 --- a/coreapi/sal/sal_op.cpp +++ b/coreapi/sal/sal_op.cpp @@ -95,10 +95,6 @@ SalOp::~SalOp() { if (this->remote_contact_address){ sal_address_destroy(this->remote_contact_address); } - if (this->local_media) - sal_media_description_unref(this->local_media); - if (this->remote_media) - sal_media_description_unref(this->remote_media); 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 118784620..8ae42afe8 100644 --- a/coreapi/sal/sal_op.h +++ b/coreapi/sal/sal_op.h @@ -211,9 +211,6 @@ protected: char *remote_ua = NULL; SalAddress* remote_contact_address = NULL; char *remote_contact = NULL; - SalMediaDescription *local_media = NULL; - SalMediaDescription *remote_media = NULL; - Content custom_body; void *user_pointer = NULL; const char* call_id = NULL; char* realm = NULL; diff --git a/src/c-wrapper/api/c-call-params.cpp b/src/c-wrapper/api/c-call-params.cpp index cec561f98..a6c55f39a 100644 --- a/src/c-wrapper/api/c-call-params.cpp +++ b/src/c-wrapper/api/c-call-params.cpp @@ -499,8 +499,10 @@ void linphone_call_params_unref (LinphoneCallParams *cp) { LinphoneCallParams *linphone_call_params_new (LinphoneCore *core) { LinphoneCallParams *params = _linphone_CallParams_init(); - L_SET_CPP_PTR_FROM_C_OBJECT(params, new LinphonePrivate::MediaSessionParams()); + auto mediaSessionParams = new LinphonePrivate::MediaSessionParams(); + L_SET_CPP_PTR_FROM_C_OBJECT(params, mediaSessionParams); L_GET_CPP_PTR_FROM_C_OBJECT(params)->initDefault(core); + delete mediaSessionParams; return params; } diff --git a/src/content/content.cpp b/src/content/content.cpp index fb2b64113..9c12562dc 100644 --- a/src/content/content.cpp +++ b/src/content/content.cpp @@ -132,4 +132,9 @@ bool Content::isEmpty () const { return getSize() == 0; } +bool Content::isValid() const { + L_D(); + return d->contentType.isValid() || d->body.empty(); +} + LINPHONE_END_NAMESPACE diff --git a/src/content/content.h b/src/content/content.h index 5c7b00c3a..352bcfcf0 100644 --- a/src/content/content.h +++ b/src/content/content.h @@ -55,6 +55,8 @@ public: void setBody (const void *buffer, size_t size); size_t getSize () const; + + bool isValid() const; bool isEmpty () const; diff --git a/tester/call_single_tester.c b/tester/call_single_tester.c index c658917d8..890a897a2 100644 --- a/tester/call_single_tester.c +++ b/tester/call_single_tester.c @@ -217,12 +217,17 @@ void liblinphone_tester_check_rtcp(LinphoneCoreManager* caller, LinphoneCoreMana break; } - linphone_call_stats_unref(audio_stats1); - linphone_call_stats_unref(audio_stats2); + if (audio_stats1) linphone_call_stats_unref(audio_stats1); + if (audio_stats2) linphone_call_stats_unref(audio_stats2); if (video_stats1) linphone_call_stats_unref(video_stats1); if (video_stats2) linphone_call_stats_unref(video_stats2); wait_for_until(caller->lc,callee->lc,NULL,0,20); /*just to sleep while iterating*/ }while (!liblinphone_tester_clock_elapsed(&ts,max_time_to_wait)); + + if (audio_stats1) linphone_call_stats_unref(audio_stats1); + if (audio_stats2) linphone_call_stats_unref(audio_stats2); + if (video_stats1) linphone_call_stats_unref(video_stats1); + if (video_stats2) linphone_call_stats_unref(video_stats2); audio_stats1 = linphone_call_get_audio_stats(c1); video_stats1 = linphone_call_get_video_stats(c1); @@ -262,6 +267,12 @@ void liblinphone_tester_check_rtcp(LinphoneCoreManager* caller, LinphoneCoreMana } } + + if (audio_stats1) linphone_call_stats_unref(audio_stats1); + if (audio_stats2) linphone_call_stats_unref(audio_stats2); + if (video_stats1) linphone_call_stats_unref(video_stats1); + if (video_stats2) linphone_call_stats_unref(video_stats2); + linphone_call_unref(c1); linphone_call_unref(c2); }