diff --git a/coreapi/bellesip_sal/sal_impl.c b/coreapi/bellesip_sal/sal_impl.c index ccb8f7f52..79d7c0fb4 100644 --- a/coreapi/bellesip_sal/sal_impl.c +++ b/coreapi/bellesip_sal/sal_impl.c @@ -64,10 +64,10 @@ void sal_process_authentication(SalOp *op, belle_sip_response_t *response) { static void process_dialog_terminated(void *sal, const belle_sip_dialog_terminated_event_t *event){ belle_sip_dialog_t* dialog = belle_sip_dialog_terminated_get_dialog(event); SalOp* op = belle_sip_dialog_get_application_data(dialog); - if (op->callbacks.process_dialog_terminated) { + if (op && op->callbacks.process_dialog_terminated) { op->callbacks.process_dialog_terminated(op,event); } else { - ms_error("sal process_dialog_terminated not implemented yet"); + ms_error("sal process_dialog_terminated no op found for this dialog [%p], ignoring",dialog); } } static void process_io_error(void *user_ctx, const belle_sip_io_error_event_t *event){ diff --git a/coreapi/bellesip_sal/sal_impl.h b/coreapi/bellesip_sal/sal_impl.h index aca82a252..d98e85b42 100644 --- a/coreapi/bellesip_sal/sal_impl.h +++ b/coreapi/bellesip_sal/sal_impl.h @@ -75,6 +75,7 @@ belle_sip_request_t* sal_op_build_request(SalOp *op,const char* method); void sal_op_call_fill_cbs(SalOp*op); +void set_or_update_dialog(SalOp* op, const belle_sip_response_event_t* event); void sal_op_set_remote_ua(SalOp*op,belle_sip_message_t* message); int sal_op_send_request(SalOp* op, belle_sip_request_t* request); diff --git a/coreapi/bellesip_sal/sal_op_call.c b/coreapi/bellesip_sal/sal_op_call.c index 5c672860c..f2456d997 100644 --- a/coreapi/bellesip_sal/sal_op_call.c +++ b/coreapi/bellesip_sal/sal_op_call.c @@ -87,6 +87,9 @@ static void call_process_io_error(void *user_ctx, const belle_sip_io_error_event static void process_dialog_terminated(void *ctx, const belle_sip_dialog_terminated_event_t *event) { SalOp* op=(SalOp*)ctx; if (op->dialog) { + op->base.root->callbacks.call_terminated(op,op->dir==SalOpDirIncoming?sal_op_get_from(op):sal_op_get_to(op)); + op->state=SalOpStateTerminated; + belle_sip_object_unref(op->dialog); op->dialog=NULL; } } @@ -168,31 +171,30 @@ static void call_response_event(void *op_base, const belle_sip_response_event_t } return; } - /*check if dialog has changed*/ - if (belle_sip_response_event_get_dialog(event) != op->dialog) { - ms_message("Dialog as changed from [%p] to [%p] for op [%p], updating",op->dialog,belle_sip_response_event_get_dialog(event),op); - /*fixme, shouldn't we cancel previous dialog*/ - belle_sip_object_unref(op->dialog); - op->dialog=belle_sip_response_event_get_dialog(event); - belle_sip_object_ref(op->dialog); - } + set_or_update_dialog(op,event); + /*check if op is terminating*/ - dialog_state=belle_sip_dialog_get_state(op->dialog); + if (op->state == SalOpStateTerminating - && (dialog_state==BELLE_SIP_DIALOG_NULL - || dialog_state==BELLE_SIP_DIALOG_EARLY)) { + && (!op->dialog + || belle_sip_dialog_get_state(op->dialog)==BELLE_SIP_DIALOG_NULL + || belle_sip_dialog_get_state(op->dialog)==BELLE_SIP_DIALOG_EARLY)) { cancelling_invite(op); return; } - /*else dialog*/ + if (!op->dialog) { + ms_message("call op [%p] receive out of dialog answer [%i]",op,code); + return; + } + dialog_state=belle_sip_dialog_get_state(op->dialog); switch(dialog_state) { case BELLE_SIP_DIALOG_NULL: { - ms_error("op [%p] receive an unexpected answer [%i]",op,code); + ms_error("call op [%p] receive an unexpected answer [%i]",op,code); break; } case BELLE_SIP_DIALOG_EARLY: { @@ -200,7 +202,7 @@ static void call_response_event(void *op_base, const belle_sip_response_event_t handle_sdp_from_response(op,response); op->base.root->callbacks.call_ringing(op); } else { - ms_error("op [%p] receive an unexpected answer [%i]",op,code); + ms_error("call op [%p] receive an unexpected answer [%i]",op,code); } break; } @@ -229,13 +231,13 @@ static void call_response_event(void *op_base, const belle_sip_response_event_t case SalOpStateTerminated: default: - ms_error("op [%p] receive answer [%i] not implemented",op,code); + ms_error("call op [%p] receive answer [%i] not implemented",op,code); } break; } case BELLE_SIP_DIALOG_TERMINATED: default: { - ms_error("op [%p] receive answer [%i] not implemented",op,code); + ms_error("call op [%p] receive answer [%i] not implemented",op,code); } /* no break */ } @@ -253,7 +255,7 @@ static void call_terminated(SalOp* op,belle_sip_server_transaction_t* server_tra op->base.root->callbacks.call_terminated(op,op->dir==SalOpDirIncoming?sal_op_get_from(op):sal_op_get_to(op)); resp=belle_sip_response_create_from_request(request,status_code); belle_sip_server_transaction_send_response(server_transaction,resp); - op->state=SalOpStateTerminated; + return; } static void unsupported_method(belle_sip_server_transaction_t* server_transaction,belle_sip_request_t* request) { @@ -283,7 +285,7 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t belle_sip_request_t* req = belle_sip_request_event_get_request(event); belle_sip_header_t* replace_header; belle_sip_dialog_state_t dialog_state; - + belle_sip_response_t* resp; belle_sip_header_t* call_info; if (!op->dialog) { @@ -335,7 +337,7 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t } } else { belle_sip_error("Unexpected method [%s] for dialog state BELLE_SIP_DIALOG_EARLY"); - unsupported_method(server_transaction,belle_sip_request_event_get_request(event)); + unsupported_method(server_transaction,req); } break; } @@ -358,7 +360,9 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t }*/ op->base.root->callbacks.call_ack(op); } else if(strcmp("BYE",belle_sip_request_get_method(req))==0) { - call_terminated(op,server_transaction,belle_sip_request_event_get_request(event),200); + resp=belle_sip_response_create_from_request(req,200); + belle_sip_server_transaction_send_response(server_transaction,resp); + /*call end is notified by dialog deletion*/ } else if(strcmp("INVITE",belle_sip_request_get_method(req))==0) { /*re-invite*/ if (op->base.remote_media){ @@ -374,6 +378,7 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t op->base.root->callbacks.call_updating(op); } else { ms_error("unexpected method [%s] for dialog [%p]",belle_sip_request_get_method(req),op->dialog); + unsupported_method(server_transaction,req); } break; default: { @@ -425,11 +430,7 @@ int sal_call(SalOp *op, const char *from, const char *to){ sal_op_call_fill_cbs(op); sal_op_send_request(op,req); - /*op->pending_inv_client_trans = client_transaction = belle_sip_provider_create_client_transaction(prov,req); - belle_sip_transaction_set_application_data(BELLE_SIP_TRANSACTION(client_transaction),op); - op->dialog=belle_sip_provider_create_dialog(prov,BELLE_SIP_TRANSACTION(client_transaction)); - belle_sip_client_transaction_send_request(client_transaction); - */ + return 0; } void sal_op_call_fill_cbs(SalOp*op) { @@ -588,7 +589,7 @@ int sal_call_send_dtmf(SalOp *h, char dtmf){ return -1; } int sal_call_terminate(SalOp *op){ - belle_sip_dialog_state_t dialog_state=belle_sip_dialog_get_state(op->dialog); + belle_sip_dialog_state_t dialog_state=op->dialog?belle_sip_dialog_get_state(op->dialog):BELLE_SIP_DIALOG_NULL; /*no dialog = dialog in NULL state*/ op->state=SalOpStateTerminating; switch(dialog_state) { case BELLE_SIP_DIALOG_CONFIRMED: { @@ -605,7 +606,7 @@ int sal_call_terminate(SalOp *op){ cancelling_invite(op); break; } else { - ms_error("Don't know how to termination NUL dialog [%p]",op->dialog); + ms_error("Don't know how to termination NUlL dialog for op [%p]",op); } break; } diff --git a/coreapi/bellesip_sal/sal_op_impl.c b/coreapi/bellesip_sal/sal_op_impl.c index 94419e79d..5d1946cc7 100644 --- a/coreapi/bellesip_sal/sal_op_impl.c +++ b/coreapi/bellesip_sal/sal_op_impl.c @@ -108,30 +108,26 @@ void sal_op_resend_request(SalOp* op, belle_sip_request_t* request) { belle_sip_header_cseq_set_seq_number(cseq,belle_sip_header_cseq_get_seq_number(cseq)+1); sal_op_send_request(op,request); } -static bool_t is_request_creating_dialog(belle_sip_request_t* request) { - return strcmp("INVITE",belle_sip_request_get_method(request))==0 - || - strcmp("SUBSCRIBE",belle_sip_request_get_method(request))==0; -} + int sal_op_send_request(SalOp* op, belle_sip_request_t* request) { belle_sip_client_transaction_t* client_transaction; belle_sip_provider_t* prov=op->base.root->prov; belle_sip_header_route_t* route_header; - if (!op->dialog || belle_sip_dialog_get_state(op->dialog)!=BELLE_SIP_DIALOG_CONFIRMED) { + if (!op->dialog) { /*don't put route header if dialog is in confirmed state*/ if (sal_op_get_route_address(op)) { route_header = belle_sip_header_route_create(BELLE_SIP_HEADER_ADDRESS(sal_op_get_route_address(op))); belle_sip_message_add_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_HEADER(route_header)); } } + client_transaction = belle_sip_provider_create_client_transaction(prov,request); belle_sip_transaction_set_application_data(BELLE_SIP_TRANSACTION(client_transaction),op); - /*in case DIALOG is in state NULL create a new dialog*/ - if (!op->dialog && is_request_creating_dialog(request)) { - op->dialog=belle_sip_provider_create_dialog(prov,BELLE_SIP_TRANSACTION(client_transaction)); + if ( strcmp("INVITE",belle_sip_request_get_method(request))==0) { op->pending_inv_client_trans=client_transaction; /*update pending inv for being able to cancel*/ - belle_sip_dialog_set_application_data(op->dialog,op); - } else if (!belle_sip_message_get_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_AUTHORIZATION) + } + + if (!belle_sip_message_get_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_AUTHORIZATION) && !belle_sip_message_get_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_PROXY_AUTHORIZATION)) { /*hmm just in case we already have authentication param in cache*/ belle_sip_provider_add_authorization(op->base.root->prov,request,NULL); @@ -201,3 +197,14 @@ bool_t sal_compute_sal_errors(belle_sip_response_t* response,SalError* sal_err,S return FALSE; } } +void set_or_update_dialog(SalOp* op, const belle_sip_response_event_t* event) { + /*check if dialog has changed*/ + if (belle_sip_response_event_get_dialog(event) != op->dialog) { + ms_message("Dialog set from [%p] to [%p] for op [%p]",op->dialog,belle_sip_response_event_get_dialog(event),op); + /*fixme, shouldn't we cancel previous dialog*/ + if (op->dialog)belle_sip_object_unref(op->dialog); + op->dialog=belle_sip_response_event_get_dialog(event); + belle_sip_dialog_set_application_data(op->dialog,op); + belle_sip_object_ref(op->dialog); + } +} diff --git a/coreapi/bellesip_sal/sal_op_presence.c b/coreapi/bellesip_sal/sal_op_presence.c index 84db5b0a2..a4d8900fd 100644 --- a/coreapi/bellesip_sal/sal_op_presence.c +++ b/coreapi/bellesip_sal/sal_op_presence.c @@ -424,7 +424,11 @@ static void presence_response_event(void *op_base, const belle_sip_response_even op->base.root->callbacks.notify_presence(op,SalSubscribeTerminated, SalPresenceOffline,NULL); return; } - + set_or_update_dialog(op_base,event); + if (!op->dialog) { + ms_message("presence op [%p] receive out of dialog answer [%i]",op,code); + return; + } dialog_state=belle_sip_dialog_get_state(op->dialog); @@ -432,7 +436,7 @@ static void presence_response_event(void *op_base, const belle_sip_response_even case BELLE_SIP_DIALOG_NULL: case BELLE_SIP_DIALOG_EARLY: { - ms_error("op [%p] receive an unexpected answer [%i]",op,code); + ms_error("presence op [%p] receive an unexpected answer [%i]",op,code); break; } case BELLE_SIP_DIALOG_CONFIRMED: { @@ -456,7 +460,7 @@ static void presence_response_event(void *op_base, const belle_sip_response_even } break; default: { - ms_error("op [%p] receive answer [%i] not implemented",op,code); + ms_error("presence op [%p] receive answer [%i] not implemented",op,code); } /* no break */ } @@ -569,7 +573,7 @@ void sal_op_presence_fill_cbs(SalOp*op) { /*presence publish */ int sal_publish(SalOp *op, const char *from, const char *to, SalPresenceStatus status){ - ms_fatal("sal_publish not implemented yet"); + ms_error("sal_publish not implemented yet"); return -1; } /*presence Subscribe/notify*/ @@ -590,7 +594,7 @@ int sal_subscribe_presence(SalOp *op, const char *from, const char *to){ return sal_op_send_request(op,req); } int sal_unsubscribe(SalOp *op){ - belle_sip_request_t* req=belle_sip_dialog_create_request(op->dialog,"SUBSCRIBE"); + belle_sip_request_t* req=op->dialog?belle_sip_dialog_create_request(op->dialog,"SUBSCRIBE"):NULL; /*cannot create request if dialog not set yet*/ if (!req) { ms_error("Cannot unsubscribe to [%s]",sal_op_get_to(op)); return -1; diff --git a/tester/liblinphone_tester.c b/tester/liblinphone_tester.c index bdd78c750..5c9f9106d 100644 --- a/tester/liblinphone_tester.c +++ b/tester/liblinphone_tester.c @@ -643,7 +643,7 @@ static void call_early_media() { int init_test_suite () { -CU_pSuite pSuite = CU_add_suite("liblinphone", init, uninit); +CU_pSuite pSuite = CU_add_suite("Setup", init, uninit); if (NULL == CU_add_test(pSuite, "linphone address tester", linphone_address_test)) { @@ -652,6 +652,8 @@ CU_pSuite pSuite = CU_add_suite("liblinphone", init, uninit); if (NULL == CU_add_test(pSuite, "linphone core init/uninit tester", core_init_test)) { return CU_get_error(); } + + pSuite = CU_add_suite("Register", init, uninit); if (NULL == CU_add_test(pSuite, "simple register tester", simple_register)) { return CU_get_error(); } @@ -670,6 +672,8 @@ CU_pSuite pSuite = CU_add_suite("liblinphone", init, uninit); if (NULL == CU_add_test(pSuite, "multi account", multiple_proxy)) { return CU_get_error(); } + + pSuite = CU_add_suite("Call", init, uninit); if (NULL == CU_add_test(pSuite, "call_early_declined", call_early_declined)) { return CU_get_error(); } @@ -694,9 +698,13 @@ CU_pSuite pSuite = CU_add_suite("liblinphone", init, uninit); if (NULL == CU_add_test(pSuite, "call_srtp", call_srtp)) { return CU_get_error(); } + + pSuite = CU_add_suite("Message", init, uninit); if (NULL == CU_add_test(pSuite, "text_message", text_message)) { return CU_get_error(); } + + pSuite = CU_add_suite("Presence", init, uninit); if (NULL == CU_add_test(pSuite, "simple_subscribe", simple_subscribe)) { return CU_get_error(); }