mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-21 13:08:08 +00:00
add custom header test
fix memory leaks fix invalid reads
This commit is contained in:
parent
18d2111995
commit
00c3f621ce
11 changed files with 143 additions and 48 deletions
5
NEWS
5
NEWS
|
|
@ -1,3 +1,8 @@
|
|||
linphone-3.7...??
|
||||
* multiple SIP transports simualtaneously now allowed
|
||||
* IP dual stack: can use IPv6 and IPv4 simultaneously
|
||||
* fully asynchronous behavior: no more lengthly DNS or connections
|
||||
|
||||
linphone-3.xxx --
|
||||
* fix bug in zRTP support (upgrade required)
|
||||
*
|
||||
|
|
|
|||
|
|
@ -193,6 +193,8 @@ static void process_request_event(void *sal, const belle_sip_request_event_t *ev
|
|||
if (!op->base.call_id) {
|
||||
op->base.call_id=ms_strdup(belle_sip_header_call_id_get_call_id(BELLE_SIP_HEADER_CALL_ID(belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req), belle_sip_header_call_id_t))));
|
||||
}
|
||||
|
||||
sal_op_assign_recv_headers(op,(belle_sip_message_t*)req);
|
||||
if (op->callbacks.process_request_event) {
|
||||
op->callbacks.process_request_event(op,event);
|
||||
} else {
|
||||
|
|
@ -702,6 +704,7 @@ SalCustomHeader *sal_custom_header_append(SalCustomHeader *ch, const char *name,
|
|||
|
||||
if (msg==NULL){
|
||||
msg=(belle_sip_message_t*)belle_sip_request_new();
|
||||
belle_sip_object_ref(msg);
|
||||
}
|
||||
h=BELLE_SIP_HEADER(belle_sip_header_extension_parse(tmp));
|
||||
ms_free(tmp);
|
||||
|
|
@ -714,19 +717,15 @@ SalCustomHeader *sal_custom_header_append(SalCustomHeader *ch, const char *name,
|
|||
}
|
||||
|
||||
const char *sal_custom_header_find(const SalCustomHeader *ch, const char *name){
|
||||
belle_sip_header_t *h=belle_sip_message_get_header((belle_sip_message_t*)ch,name);
|
||||
|
||||
if (h){
|
||||
if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(h,belle_sip_header_extension_t)){
|
||||
return belle_sip_header_extension_get_value(BELLE_SIP_HEADER_EXTENSION(h));
|
||||
}else{
|
||||
char *tmp=belle_sip_object_to_string((belle_sip_object_t*)h);
|
||||
char *p=tmp+strlen(belle_sip_header_get_name(h))+1+1; /*header name + : + ' '*/
|
||||
char *ret=belle_sip_strdup(p);
|
||||
belle_sip_free(tmp);
|
||||
/*TODO: fix memory leak here*/
|
||||
|
||||
return ret;
|
||||
if (ch){
|
||||
belle_sip_header_t *h=belle_sip_message_get_header((belle_sip_message_t*)ch,name);
|
||||
|
||||
if (h){
|
||||
if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(h,belle_sip_header_extension_t)){
|
||||
return belle_sip_header_extension_get_value(BELLE_SIP_HEADER_EXTENSION(h));
|
||||
}else{
|
||||
return belle_sip_header_get_unparsed_value(h);
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
|
|
@ -740,22 +739,11 @@ SalCustomHeader *sal_custom_header_clone(const SalCustomHeader *ch){
|
|||
return (SalCustomHeader*)belle_sip_object_ref((belle_sip_message_t*)ch);
|
||||
}
|
||||
|
||||
const SalCustomHeader *sal_op_get_custom_header(SalOp *op){
|
||||
const SalCustomHeader *sal_op_get_recv_custom_header(SalOp *op){
|
||||
SalOpBase *b=(SalOpBase *)op;
|
||||
return b->custom_headers;
|
||||
}
|
||||
|
||||
/*
|
||||
* Warning: this function takes owneship of the custom headers
|
||||
*/
|
||||
void sal_op_set_custom_header(SalOp *op, SalCustomHeader* ch){
|
||||
SalOpBase *b=(SalOpBase *)op;
|
||||
if (b->custom_headers){
|
||||
sal_custom_header_free(b->custom_headers);
|
||||
b->custom_headers=NULL;
|
||||
}
|
||||
if (ch) belle_sip_object_ref((belle_sip_message_t*)ch);
|
||||
b->custom_headers=ch;
|
||||
return b->recv_custom_headers;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -128,5 +128,6 @@ void sal_add_pending_auth(Sal *sal, SalOp *op);
|
|||
|
||||
void sal_add_presence_info(belle_sip_message_t *notify, SalPresenceStatus online_status);
|
||||
|
||||
void sal_op_assign_recv_headers(SalOp *op, belle_sip_message_t *incoming);
|
||||
|
||||
#endif /* SAL_IMPL_H_ */
|
||||
|
|
|
|||
|
|
@ -102,7 +102,11 @@ static int set_sdp(belle_sip_message_t *msg,belle_sdp_session_description_t* ses
|
|||
}
|
||||
}
|
||||
static int set_sdp_from_desc(belle_sip_message_t *msg, const SalMediaDescription *desc){
|
||||
return set_sdp(msg,media_description_to_sdp(desc));
|
||||
int err;
|
||||
belle_sdp_session_description_t *sdp=media_description_to_sdp(desc);
|
||||
err=set_sdp(msg,sdp);
|
||||
belle_sip_object_unref(sdp);
|
||||
return err;
|
||||
|
||||
}
|
||||
static void call_process_io_error(void *user_ctx, const belle_sip_io_error_event_t *event){
|
||||
|
|
@ -261,6 +265,7 @@ static void call_response_event(void *op_base, const belle_sip_response_event_t
|
|||
}
|
||||
if (op->sdp_answer){
|
||||
set_sdp(BELLE_SIP_MESSAGE(response),op->sdp_answer);
|
||||
belle_sip_object_unref(op->sdp_answer);
|
||||
op->sdp_answer=NULL;
|
||||
}
|
||||
belle_sip_dialog_send_ack(op->dialog,ack);
|
||||
|
|
@ -571,6 +576,7 @@ static void handle_offer_answer_response(SalOp* op, belle_sip_response_t* respon
|
|||
if (op->sdp_answer==NULL) sdp_process(op);
|
||||
if (op->sdp_answer){
|
||||
set_sdp(BELLE_SIP_MESSAGE(response),op->sdp_answer);
|
||||
belle_sip_object_unref(op->sdp_answer);
|
||||
op->sdp_answer=NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,9 @@ SalOp * sal_op_new(Sal *sal){
|
|||
void sal_op_release(SalOp *op){
|
||||
op->state=SalOpStateTerminated;
|
||||
sal_op_set_user_pointer(op,NULL);/*mandatory because releasing op doesn not mean freeing op. Make sure back pointer will not be used later*/
|
||||
if (op->refresher) belle_sip_refresher_stop(op->refresher);
|
||||
if (op->refresher) {
|
||||
belle_sip_refresher_stop(op->refresher);
|
||||
}
|
||||
sal_op_unref(op);
|
||||
}
|
||||
void sal_op_release_impl(SalOp *op){
|
||||
|
|
@ -42,6 +44,8 @@ void sal_op_release_impl(SalOp *op){
|
|||
belle_sip_object_unref(op->refresher);
|
||||
op->refresher=NULL;
|
||||
}
|
||||
if (op->result)
|
||||
sal_media_description_unref(op->result);
|
||||
if(op->replaces) belle_sip_object_unref(op->replaces);
|
||||
if(op->referred_by) belle_sip_object_unref(op->referred_by);
|
||||
|
||||
|
|
@ -146,6 +150,19 @@ void sal_op_resend_request(SalOp* op, belle_sip_request_t* request) {
|
|||
sal_op_send_request(op,request);
|
||||
}
|
||||
|
||||
static void add_headers(belle_sip_header_t *h, belle_sip_message_t *msg){
|
||||
if (belle_sip_message_get_header(msg,belle_sip_header_get_name(h))==NULL)
|
||||
belle_sip_message_add_header(msg,h);
|
||||
}
|
||||
|
||||
static void _sal_op_add_custom_headers(SalOp *op, belle_sip_message_t *msg){
|
||||
if (op->base.sent_custom_headers){
|
||||
belle_sip_message_t *ch=(belle_sip_message_t*)op->base.sent_custom_headers;
|
||||
belle_sip_list_t *l=belle_sip_message_get_all_headers(ch);
|
||||
belle_sip_list_for_each2(l,(void (*)(void *, void *))add_headers,msg);
|
||||
belle_sip_list_free(l);
|
||||
}
|
||||
}
|
||||
|
||||
static int _sal_op_send_request_with_contact(SalOp* op, belle_sip_request_t* request,bool_t add_contact) {
|
||||
belle_sip_client_transaction_t* client_transaction;
|
||||
|
|
@ -153,6 +170,8 @@ static int _sal_op_send_request_with_contact(SalOp* op, belle_sip_request_t* req
|
|||
belle_sip_uri_t* outbound_proxy=NULL;
|
||||
belle_sip_header_contact_t* contact;
|
||||
|
||||
_sal_op_add_custom_headers(op, (belle_sip_message_t*)request);
|
||||
|
||||
if (!op->dialog || belle_sip_dialog_get_state(op->dialog) == BELLE_SIP_DIALOG_NULL) {
|
||||
/*don't put route header if dialog is in confirmed state*/
|
||||
const MSList *elem=sal_op_get_route_addresses(op);
|
||||
|
|
@ -316,10 +335,9 @@ void* sal_op_unref(SalOp* op) {
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int sal_op_send_and_create_refresher(SalOp* op,belle_sip_request_t* req, int expires,belle_sip_refresher_listener_t listener ) {
|
||||
if (sal_op_send_request_with_expires(op,req,expires)) {
|
||||
return -1;
|
||||
} else {
|
||||
if (sal_op_send_request_with_expires(op,req,expires)==0) {
|
||||
if (op->refresher) {
|
||||
belle_sip_refresher_stop(op->refresher);
|
||||
belle_sip_object_unref(op->refresher);
|
||||
|
|
@ -332,6 +350,7 @@ int sal_op_send_and_create_refresher(SalOp* op,belle_sip_request_t* req, int exp
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char* sal_op_state_to_string(const SalOpSate_t value) {
|
||||
|
|
@ -344,3 +363,27 @@ const char* sal_op_state_to_string(const SalOpSate_t value) {
|
|||
return "Unknon";
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Warning: this function takes owneship of the custom headers
|
||||
*/
|
||||
void sal_op_set_sent_custom_header(SalOp *op, SalCustomHeader* ch){
|
||||
SalOpBase *b=(SalOpBase *)op;
|
||||
if (b->sent_custom_headers){
|
||||
sal_custom_header_free(b->sent_custom_headers);
|
||||
b->sent_custom_headers=NULL;
|
||||
}
|
||||
if (ch) belle_sip_object_ref((belle_sip_message_t*)ch);
|
||||
b->sent_custom_headers=ch;
|
||||
}
|
||||
|
||||
void sal_op_assign_recv_headers(SalOp *op, belle_sip_message_t *incoming){
|
||||
if (incoming) belle_sip_object_ref(incoming);
|
||||
if (op->base.recv_custom_headers){
|
||||
belle_sip_object_unref(op->base.recv_custom_headers);
|
||||
op->base.recv_custom_headers=NULL;
|
||||
}
|
||||
if (incoming){
|
||||
op->base.recv_custom_headers=(SalCustomHeader*)incoming;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -457,6 +457,7 @@ int sdp_to_media_description ( belle_sdp_session_description_t *session_desc, S
|
|||
unsigned int componentID;
|
||||
int offset;
|
||||
const char *ptr = value;
|
||||
const char *endptr=value+strlen(ptr);
|
||||
while (3 == sscanf(ptr, "%u %s %u%n", &componentID, candidate.addr, &candidate.port, &offset)) {
|
||||
if ((componentID > 0) && (componentID <= SAL_MEDIA_DESCRIPTION_MAX_ICE_REMOTE_CANDIDATES)) {
|
||||
SalIceRemoteCandidate *remote_candidate = &stream->ice_remote_candidates[componentID - 1];
|
||||
|
|
@ -464,7 +465,9 @@ int sdp_to_media_description ( belle_sdp_session_description_t *session_desc, S
|
|||
remote_candidate->port = candidate.port;
|
||||
}
|
||||
ptr += offset;
|
||||
if (ptr[offset] == ' ') ptr += 1;
|
||||
if (ptr<endptr){
|
||||
if (ptr[offset] == ' ') ptr += 1;
|
||||
}else break;
|
||||
}
|
||||
} else if ((keywordcmp("ice-ufrag", att_name) == 0) && (value != NULL)) {
|
||||
strncpy(stream->ice_ufrag, value, sizeof(stream->ice_ufrag));
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ static void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatM
|
|||
linphone_transfer_routes_to_op(routes,op);
|
||||
sal_op_set_user_pointer(op, msg); /*if out of call, directly store msg*/
|
||||
if (msg->custom_headers){
|
||||
sal_op_set_custom_header(op,msg->custom_headers);
|
||||
sal_op_set_sent_custom_header(op,msg->custom_headers);
|
||||
msg->custom_headers=NULL; /*transfered to the SalOp*/
|
||||
}
|
||||
}
|
||||
|
|
@ -186,7 +186,7 @@ void linphone_core_message_received(LinphoneCore *lc, SalOp *op, const SalMessag
|
|||
msg->time=sal_msg->time;
|
||||
msg->state=LinphoneChatMessageStateDelivered;
|
||||
msg->is_read=FALSE;
|
||||
ch=sal_op_get_custom_header(op);
|
||||
ch=sal_op_get_recv_custom_header(op);
|
||||
if (ch) msg->custom_headers=sal_custom_header_clone(ch);
|
||||
|
||||
if (sal_msg->url) {
|
||||
|
|
|
|||
|
|
@ -478,8 +478,7 @@ LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddr
|
|||
linphone_core_get_local_ip(lc,NULL,call->localip);
|
||||
linphone_call_init_common(call,from,to);
|
||||
_linphone_call_params_copy(&call->params,params);
|
||||
sal_op_set_custom_header(call->op,call->params.custom_headers);
|
||||
call->params.custom_headers=NULL;
|
||||
sal_op_set_sent_custom_header(call->op,call->params.custom_headers);
|
||||
|
||||
if (linphone_core_get_firewall_policy(call->core) == LinphonePolicyUseIce) {
|
||||
call->ice_session = ice_session_new();
|
||||
|
|
@ -828,7 +827,7 @@ const LinphoneCallParams * linphone_call_get_remote_params(LinphoneCall *call){
|
|||
cp->low_bandwidth=TRUE;
|
||||
}
|
||||
}
|
||||
cp->custom_headers=(SalCustomHeader*)sal_op_get_custom_header(call->op);
|
||||
cp->custom_headers=(SalCustomHeader*)sal_op_get_recv_custom_header(call->op);
|
||||
return cp;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -461,8 +461,10 @@ void __sal_op_free(SalOp *op){
|
|||
ms_list_for_each(b->route_addresses,(void (*)(void*)) sal_address_destroy);
|
||||
b->route_addresses=ms_list_free(b->route_addresses);
|
||||
}
|
||||
if (b->custom_headers)
|
||||
sal_custom_header_free(b->custom_headers);
|
||||
if (b->recv_custom_headers)
|
||||
sal_custom_header_free(b->recv_custom_headers);
|
||||
if (b->sent_custom_headers)
|
||||
sal_custom_header_free(b->sent_custom_headers);
|
||||
ms_free(op);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -249,7 +249,8 @@ typedef struct SalOpBase{
|
|||
const char* call_id;
|
||||
char *remote_contact;
|
||||
SalAddress* service_route; /*as defined by rfc3608, might be a list*/
|
||||
SalCustomHeader *custom_headers;
|
||||
SalCustomHeader *sent_custom_headers;
|
||||
SalCustomHeader *recv_custom_headers;
|
||||
} SalOpBase;
|
||||
|
||||
|
||||
|
|
@ -520,8 +521,10 @@ SalCustomHeader *sal_custom_header_append(SalCustomHeader *ch, const char *name,
|
|||
const char *sal_custom_header_find(const SalCustomHeader *ch, const char *name);
|
||||
void sal_custom_header_free(SalCustomHeader *ch);
|
||||
SalCustomHeader *sal_custom_header_clone(const SalCustomHeader *ch);
|
||||
const SalCustomHeader *sal_op_get_custom_header(SalOp *op);
|
||||
void sal_op_set_custom_header(SalOp *op, SalCustomHeader* ch);
|
||||
|
||||
const SalCustomHeader *sal_op_get_recv_custom_header(SalOp *op);
|
||||
|
||||
void sal_op_set_sent_custom_header(SalOp *op, SalCustomHeader* ch);
|
||||
|
||||
void sal_enable_logs();
|
||||
void sal_disable_logs();
|
||||
|
|
|
|||
|
|
@ -92,14 +92,18 @@ static void linphone_call_cb(LinphoneCall *call,void * user_data) {
|
|||
counters->number_of_IframeDecoded++;
|
||||
}
|
||||
|
||||
bool_t call(LinphoneCoreManager* caller_mgr,LinphoneCoreManager* callee_mgr) {
|
||||
|
||||
|
||||
bool_t call_with_params(LinphoneCoreManager* caller_mgr,LinphoneCoreManager* callee_mgr, const LinphoneCallParams *params) {
|
||||
int retry=0;
|
||||
stats initial_caller=caller_mgr->stat;
|
||||
stats initial_callee=callee_mgr->stat;
|
||||
|
||||
|
||||
|
||||
CU_ASSERT_PTR_NOT_NULL(linphone_core_invite_address(caller_mgr->lc,callee_mgr->identity));
|
||||
if (!params){
|
||||
CU_ASSERT_PTR_NOT_NULL(linphone_core_invite_address(caller_mgr->lc,callee_mgr->identity));
|
||||
}else{
|
||||
CU_ASSERT_PTR_NOT_NULL(linphone_core_invite_address_with_params(caller_mgr->lc,callee_mgr->identity,params));
|
||||
}
|
||||
|
||||
/*linphone_core_invite(caller_mgr->lc,"pauline");*/
|
||||
|
||||
|
|
@ -141,6 +145,10 @@ bool_t call(LinphoneCoreManager* caller_mgr,LinphoneCoreManager* callee_mgr) {
|
|||
|
||||
}
|
||||
|
||||
bool_t call(LinphoneCoreManager* caller_mgr,LinphoneCoreManager* callee_mgr){
|
||||
return call_with_params(caller_mgr,callee_mgr,NULL);
|
||||
}
|
||||
|
||||
static void simple_call(void) {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new(liblinphone_tester_file_prefix, "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new(liblinphone_tester_file_prefix, "pauline_rc");
|
||||
|
|
@ -190,6 +198,7 @@ static void simple_call(void) {
|
|||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
|
||||
static void simple_call_compatibility_mode(void) {
|
||||
char route[256];
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new(liblinphone_tester_file_prefix, "marie_rc");
|
||||
|
|
@ -417,6 +426,41 @@ static void call_with_ice(void) {
|
|||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
|
||||
static void call_with_custom_headers(void) {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new(liblinphone_tester_file_prefix, "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new(liblinphone_tester_file_prefix, "pauline_rc");
|
||||
LinphoneCall *c1,*c2;
|
||||
LinphoneCallParams *params;
|
||||
const LinphoneCallParams *remote_params;
|
||||
const char *hvalue;
|
||||
|
||||
params=linphone_core_create_default_call_parameters(marie->lc);
|
||||
linphone_call_params_add_custom_header(params,"Weather","bad");
|
||||
linphone_call_params_add_custom_header(params,"Working","yes");
|
||||
|
||||
CU_ASSERT_TRUE(call_with_params(pauline,marie,params));
|
||||
linphone_call_params_destroy(params);
|
||||
|
||||
c1=linphone_core_get_current_call(marie->lc);
|
||||
c2=linphone_core_get_current_call(pauline->lc);
|
||||
|
||||
CU_ASSERT_PTR_NOT_NULL(c1);
|
||||
CU_ASSERT_PTR_NOT_NULL(c2);
|
||||
|
||||
remote_params=linphone_call_get_remote_params(c1);
|
||||
hvalue=linphone_call_params_get_custom_header(remote_params,"Weather");
|
||||
CU_ASSERT_PTR_NOT_NULL(hvalue);
|
||||
CU_ASSERT_TRUE(strcmp(hvalue,"bad")==0);
|
||||
|
||||
/*just to sleep*/
|
||||
linphone_core_terminate_all_calls(pauline->lc);
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1));
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1));
|
||||
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
|
||||
static void call_paused_resumed(void) {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new(liblinphone_tester_file_prefix, "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new(liblinphone_tester_file_prefix, "pauline_rc");
|
||||
|
|
@ -773,6 +817,7 @@ test_t call_tests[] = {
|
|||
{ "Simple call transfer", simple_call_transfer },
|
||||
{ "Call transfer existing call outgoing call", call_transfer_existing_call_outgoing_call },
|
||||
{ "Call with ICE", call_with_ice },
|
||||
{ "Call with custom headers",call_with_custom_headers}
|
||||
};
|
||||
|
||||
test_suite_t call_test_suite = {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue