diff --git a/NEWS b/NEWS index 5b775e1bb..6a7106c6d 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,14 @@ 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 + * +sip.instance parameter (RFC???) + * alias parameter (RFC????) + * better management of network disconnections + * SIP/TLS handled through lightweighted polarssl library (instead of openssl) + * SIP transaction state machines improved (RFC6026) + * Privacy API + * Full support of rich presence + linphone-3.6.1 -- June 17, 2013 * fix memory leak with some video cameras on windows. diff --git a/coreapi/bellesip_sal/sal_impl.c b/coreapi/bellesip_sal/sal_impl.c index 2ff7041e6..e147efd32 100644 --- a/coreapi/bellesip_sal/sal_impl.c +++ b/coreapi/bellesip_sal/sal_impl.c @@ -181,6 +181,10 @@ static void process_request_event(void *sal, const belle_sip_request_event_t *ev if (dialog) { op=(SalOp*)belle_sip_dialog_get_application_data(dialog); + if (op==NULL && op->state==SalOpStateTerminated){ + ms_warning("Receiving request for null or terminated op [%p], ignored",op); + return; + } }else if (strcmp("INVITE",method)==0) { op=sal_op_new((Sal*)sal); op->dir=SalOpDirIncoming; diff --git a/coreapi/bellesip_sal/sal_impl.h b/coreapi/bellesip_sal/sal_impl.h index 7bc92e2c7..2848e97ac 100644 --- a/coreapi/bellesip_sal/sal_impl.h +++ b/coreapi/bellesip_sal/sal_impl.h @@ -128,8 +128,8 @@ void sal_op_message_fill_cbs(SalOp*op); void sal_op_subscribe_fill_cbs(SalOp*op); /*call transfer*/ -void sal_op_process_refer(SalOp *op, const belle_sip_request_event_t *event); -void sal_op_call_process_notify(SalOp *op, const belle_sip_request_event_t *event); +void sal_op_process_refer(SalOp *op, const belle_sip_request_event_t *event, belle_sip_server_transaction_t *tr); +void sal_op_call_process_notify(SalOp *op, const belle_sip_request_event_t *event, belle_sip_server_transaction_t *tr); /*create SalAuthInfo by copying username and realm from suth event*/ SalAuthInfo* sal_auth_info_create(belle_sip_auth_event_t* event) ; void sal_add_pending_auth(Sal *sal, SalOp *op); diff --git a/coreapi/bellesip_sal/sal_op_call.c b/coreapi/bellesip_sal/sal_op_call.c index 05157cb04..dc3489aca 100644 --- a/coreapi/bellesip_sal/sal_op_call.c +++ b/coreapi/bellesip_sal/sal_op_call.c @@ -23,10 +23,13 @@ static void call_set_released(SalOp* op){ op->state=SalOpStateTerminated; op->base.root->callbacks.call_released(op); } + +/*used when the SalOp was ref'd by the dialog*/ static void call_set_released_and_unref(SalOp* op) { call_set_released(op); sal_op_unref(op); } + static void call_set_error(SalOp* op,belle_sip_response_t* response){ SalError error=SalErrorUnknown; SalReason sr=SalReasonUnknown; @@ -41,7 +44,6 @@ static void call_set_error(SalOp* op,belle_sip_response_t* response){ if (reason_header != NULL){ ms_free(reason); } - call_set_released(op); } static void sdp_process(SalOp *h){ @@ -124,60 +126,28 @@ static void process_dialog_terminated(void *ctx, const belle_sip_dialog_terminat SalOp* op=(SalOp*)ctx; if (op->dialog && op->dialog==belle_sip_dialog_terminated_get_dialog(event)) { - belle_sip_transaction_t* trans=belle_sip_dialog_get_last_transaction(op->dialog); - + /*belle_sip_transaction_t* trans=belle_sip_dialog_get_last_transaction(op->dialog);*/ + ms_message("Dialog [%p] terminated for op [%p]",belle_sip_dialog_terminated_get_dialog(event),op); + switch(belle_sip_dialog_get_previous_state(op->dialog)) { - case BELLE_SIP_DIALOG_CONFIRMED: - if (op->state!=SalOpStateTerminated && op->state!=SalOpStateTerminating) { - /*this is probably a "normal termination from a BYE*/ - op->base.root->callbacks.call_terminated(op,op->dir==SalOpDirIncoming?sal_op_get_from(op):sal_op_get_to(op)); - op->state=SalOpStateTerminating; - } - break; - case BELLE_SIP_DIALOG_NULL: { - if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(trans,belle_sip_server_transaction_t)) { - /*call declined very early, no need to notify call release*/ - break; - } - } - default: { - - belle_sip_response_t* response=belle_sip_transaction_get_response(trans); - int code = belle_sip_response_get_status_code(response); - if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(trans,belle_sip_client_transaction_t)) { - switch (code) { - case 487: - call_set_released(op); - break; - case 401: - case 407: - if (op->state!=SalOpStateTerminating) { - /*normal termination for challenged dialog */ - break; - } - default: - call_set_error(op,response); + case BELLE_SIP_DIALOG_CONFIRMED: + if (op->state!=SalOpStateTerminated && op->state!=SalOpStateTerminating) { + /*this is probably a "normal termination from a BYE*/ + op->base.root->callbacks.call_terminated(op,op->dir==SalOpDirIncoming?sal_op_get_from(op):sal_op_get_to(op)); + op->state=SalOpStateTerminating; } - } else { - sal_op_ref(op); /*to make sure op is still there when call released is scheduled*/ - belle_sip_main_loop_do_later(belle_sip_stack_get_main_loop(op->base.root->stack) - ,(belle_sip_callback_t) call_set_released_and_unref - , op); - } - + break; + default: + break; } - } - belle_sip_object_unref(op->dialog); - op->dialog=NULL; - sal_op_unref(op); + belle_sip_main_loop_do_later(belle_sip_stack_get_main_loop(op->base.root->stack) + ,(belle_sip_callback_t) call_set_released_and_unref + , op); } else { ms_error("dialog unknown for op "); } - - ms_message("Dialog [%p] terminated for op [%p]",belle_sip_dialog_terminated_get_dialog(event) - ,op); - } + static void handle_sdp_from_response(SalOp* op,belle_sip_response_t* response) { belle_sdp_session_description_t* sdp; if ((sdp=belle_sdp_session_description_create(BELLE_SIP_MESSAGE(response)))) { @@ -205,21 +175,22 @@ static void call_response_event(void *op_base, const belle_sip_response_event_t if (!client_transaction) { - ms_warning("Discarding state less response [%i] on op [%p]",code,op); + ms_warning("Discarding stateless response [%i] on op [%p]",code,op); return; } req=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(client_transaction)); set_or_update_dialog(op,belle_sip_response_event_get_dialog(event)); dialog_state=op->dialog?belle_sip_dialog_get_state(op->dialog):BELLE_SIP_DIALOG_NULL; + + ms_message("Op [%p] receiving call response [%i], dialog is [%p] in state [%s]",op,code,op->dialog,belle_sip_dialog_state_to_string(dialog_state)); switch(dialog_state) { - case BELLE_SIP_DIALOG_NULL: case BELLE_SIP_DIALOG_EARLY: { if (strcmp("INVITE",belle_sip_request_get_method(req))==0 ) { - if ( op->state == SalOpStateTerminating) { + if (op->state == SalOpStateTerminating) { if (strcmp("CANCEL",belle_sip_request_get_method(belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(op->pending_client_trans))))!=0) { - if (code <200) { + if (code<200) { cancelling_invite(op); } else if (code<400) { sal_op_send_request(op,belle_sip_dialog_create_request(op->dialog,"BYE")); @@ -229,32 +200,16 @@ static void call_response_event(void *op_base, const belle_sip_response_event_t } else { /*nop, already cancelled*/ } - break; } else if (code >= 180 && code<300) { handle_sdp_from_response(op,response); op->base.root->callbacks.call_ringing(op); - break; } else if (code>=300){ - if (dialog_state==BELLE_SIP_DIALOG_NULL) { - call_set_error(op,response); - break; - } else { - /*nop let process_dialog_terminated manage error reporting*/ - } + call_set_error(op,response); + if (op->dialog==NULL) call_set_released(op); } - - } else if (strcmp("CANCEL",belle_sip_request_get_method(req))==0 - || strcmp("BYE",belle_sip_request_get_method(req))==0) { - break;/*200ok for cancel or BYE*/ - } else { - /*nop error*/ - } - if (code >= 100 && code < 180) { - ms_message("call op [%p] receive [%i]",op,code); - } else { - ms_error("call op [%p] receive an unexpected answer [%i]",op,code); } } + break; case BELLE_SIP_DIALOG_CONFIRMED: { switch (op->state) { case SalOpStateEarly:/*invite case*/ @@ -278,7 +233,9 @@ static void call_response_event(void *op_base, const belle_sip_response_event_t op->state=SalOpStateActive; } else { - /*nop*/ + if (code >= 300){ + call_set_error(op,response); + } } break; case SalOpStateTerminating: @@ -290,12 +247,9 @@ static void call_response_event(void *op_base, const belle_sip_response_event_t break; } case BELLE_SIP_DIALOG_TERMINATED: { - /*if (code>=400 && strcmp("INVITE",belle_sip_request_get_method(req))==0){ + if (code >= 300){ call_set_error(op,response); - call_set_released(op); - op->state=SalOpStateTerminated; - break; - }*/ + } break; } /* no break */ @@ -366,6 +320,7 @@ static void process_sdp_for_invite(SalOp* op,belle_sip_request_t* invite) { }else op->sdp_offering=TRUE; } + static void process_request_event(void *op_base, const belle_sip_request_event_t *event) { SalOp* op = (SalOp*)op_base; belle_sip_server_transaction_t* server_transaction=NULL; @@ -383,7 +338,7 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t } if (strcmp("INVITE",belle_sip_request_get_method(req))==0) { - if (op->pending_server_trans)belle_sip_object_unref(op->pending_server_trans); + if (op->pending_server_trans) belle_sip_object_unref(op->pending_server_trans); /*updating pending invite transaction*/ op->pending_server_trans=server_transaction; belle_sip_object_ref(op->pending_server_trans); @@ -502,9 +457,9 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t resp=sal_op_create_response_from_request(op,req,200); belle_sip_server_transaction_send_response(server_transaction,resp); }else if (strcmp("REFER",belle_sip_request_get_method(req))==0) { - sal_op_process_refer(op,event); + sal_op_process_refer(op,event,server_transaction); } else if (strcmp("NOTIFY",belle_sip_request_get_method(req))==0) { - sal_op_call_process_notify(op,event); + sal_op_call_process_notify(op,event,server_transaction); } else if (strcmp("OPTIONS",belle_sip_request_get_method(req))==0) { resp=sal_op_create_response_from_request(op,req,200); belle_sip_server_transaction_send_response(server_transaction,resp); @@ -706,15 +661,18 @@ int sal_call_decline(SalOp *op, SalReason reason, const char *redirection /*opti } int sal_call_update(SalOp *op, const char *subject){ belle_sip_request_t *reinvite=belle_sip_dialog_create_request(op->dialog,"INVITE"); - belle_sip_message_add_header(BELLE_SIP_MESSAGE(reinvite),belle_sip_header_create( "Subject", subject)); - sal_op_fill_invite(op, reinvite); - return sal_op_send_request(op,reinvite); + if (reinvite){ + belle_sip_message_add_header(BELLE_SIP_MESSAGE(reinvite),belle_sip_header_create( "Subject", subject)); + sal_op_fill_invite(op, reinvite); + return sal_op_send_request(op,reinvite); + } + return -1; } + SalMediaDescription * sal_call_get_remote_media_description(SalOp *h){ return h->base.remote_media;; } - SalMediaDescription * sal_call_get_final_media_description(SalOp *h){ if (h->base.local_media && h->base.remote_media && !h->result){ sdp_process(h); @@ -763,8 +721,8 @@ int sal_call_terminate(SalOp *op){ } else { /*just schedule call released*/ belle_sip_main_loop_do_later(belle_sip_stack_get_main_loop(op->base.root->stack) - ,(belle_sip_callback_t) call_set_released - , op); + ,(belle_sip_callback_t) call_set_released + , op); } break; } diff --git a/coreapi/bellesip_sal/sal_op_call_transfer.c b/coreapi/bellesip_sal/sal_op_call_transfer.c index b0058e15e..c7fca7241 100644 --- a/coreapi/bellesip_sal/sal_op_call_transfer.c +++ b/coreapi/bellesip_sal/sal_op_call_transfer.c @@ -168,14 +168,14 @@ int sal_call_notify_refer_state(SalOp *op, SalOp *newcall){ } -void sal_op_process_refer(SalOp *op, const belle_sip_request_event_t *event){ +void sal_op_process_refer(SalOp *op, const belle_sip_request_event_t *event, belle_sip_server_transaction_t *server_transaction){ belle_sip_request_t* req = belle_sip_request_event_get_request(event); belle_sip_header_refer_to_t *refer_to= belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_refer_to_t); belle_sip_header_referred_by_t *referred_by= belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_referred_by_t); - belle_sip_server_transaction_t* server_transaction = belle_sip_provider_create_server_transaction(op->base.root->prov,req); belle_sip_response_t* resp; belle_sip_uri_t* refer_to_uri; char* refer_to_uri_str; + ms_message("Receiving REFER request on op [%p]",op); if (refer_to) { refer_to_uri=belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(refer_to)); @@ -200,8 +200,7 @@ void sal_op_process_refer(SalOp *op, const belle_sip_request_event_t *event){ } -void sal_op_call_process_notify(SalOp *op, const belle_sip_request_event_t *event){ - belle_sip_server_transaction_t* server_transaction = belle_sip_provider_create_server_transaction(op->base.root->prov,belle_sip_request_event_get_request(event)); +void sal_op_call_process_notify(SalOp *op, const belle_sip_request_event_t *event, belle_sip_server_transaction_t* server_transaction){ belle_sip_request_t* req = belle_sip_request_event_get_request(event); const char* body = belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)); belle_sip_header_t* header_event=belle_sip_message_get_header(BELLE_SIP_MESSAGE(req),"Event"); diff --git a/coreapi/bellesip_sal/sal_op_impl.c b/coreapi/bellesip_sal/sal_op_impl.c index 0f829de91..3feb54f98 100644 --- a/coreapi/bellesip_sal/sal_op_impl.c +++ b/coreapi/bellesip_sal/sal_op_impl.c @@ -31,7 +31,7 @@ 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*/ + sal_op_set_user_pointer(op,NULL);/*mandatory because releasing op doesn't not mean freeing op. Make sure back pointer will not be used later*/ if (op->refresher) { belle_sip_refresher_stop(op->refresher); } @@ -292,7 +292,6 @@ SalReason sal_reason_to_sip_code(SalReason r){ case SalReasonUnknown: ret=400; break; - case SalReasonBusy: ret=486; break; @@ -320,6 +319,9 @@ SalReason sal_reason_to_sip_code(SalReason r){ case SalReasonServiceUnavailable: ret=503; break; + case SalReasonRequestPending: + ret=491; + break; } return ret; } @@ -354,6 +356,10 @@ void sal_compute_sal_errors_from_code(int code ,SalError* sal_err,SalReason* sal break; case 487: break; + case 491: + *sal_err=SalErrorFailure; + *sal_reason=SalReasonRequestPending; + break; case 600: *sal_err=SalErrorFailure; *sal_reason=SalReasonDoNotDisturb; diff --git a/coreapi/bellesip_sal/sal_op_presence.c b/coreapi/bellesip_sal/sal_op_presence.c index 62acc81aa..99769f326 100644 --- a/coreapi/bellesip_sal/sal_op_presence.c +++ b/coreapi/bellesip_sal/sal_op_presence.c @@ -47,6 +47,7 @@ void sal_add_presence_info(SalOp *op, belle_sip_message_t *notify, SalPresenceMo static void presence_process_io_error(void *user_ctx, const belle_sip_io_error_event_t *event){ ms_error("presence_process_io_error not implemented yet"); } + static void presence_process_dialog_terminated(void *ctx, const belle_sip_dialog_terminated_event_t *event) { SalOp* op= (SalOp*)ctx; if (op->dialog) { diff --git a/coreapi/bellesip_sal/sal_op_publish.c b/coreapi/bellesip_sal/sal_op_publish.c index c54d3f8e4..9f23b849d 100644 --- a/coreapi/bellesip_sal/sal_op_publish.c +++ b/coreapi/bellesip_sal/sal_op_publish.c @@ -35,7 +35,7 @@ static void publish_refresher_listener ( const belle_sip_refresher_t* refresher } } /*presence publish */ -int sal_publish_presence(SalOp *op, const char *from, const char *to, SalPresenceModel *presence){ +int sal_publish_presence(SalOp *op, const char *from, const char *to, int expires, SalPresenceModel *presence){ belle_sip_request_t *req=NULL; if(!op->refresher || !belle_sip_refresher_get_transaction(op->refresher)) { if (from) @@ -47,13 +47,13 @@ int sal_publish_presence(SalOp *op, const char *from, const char *to, SalPresenc req=sal_op_build_request(op,"PUBLISH"); belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),belle_sip_header_create("Event","presence")); sal_add_presence_info(op,BELLE_SIP_MESSAGE(req),presence); - return sal_op_send_and_create_refresher(op,req,600,publish_refresher_listener); + return sal_op_send_and_create_refresher(op,req,expires,publish_refresher_listener); } else { /*update presence status*/ const belle_sip_client_transaction_t* last_publish_trans=belle_sip_refresher_get_transaction(op->refresher); belle_sip_request_t* last_publish=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(last_publish_trans)); sal_add_presence_info(op,BELLE_SIP_MESSAGE(last_publish),presence); - return belle_sip_refresher_refresh(op->refresher,BELLE_SIP_REFRESHER_REUSE_EXPIRES); + return belle_sip_refresher_refresh(op->refresher,expires); } } diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index 352ab3c58..f4a475dae 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -646,6 +646,11 @@ static void call_failure(SalOp *op, SalError error, SalReason sr, const char *de if (lc->vtable.display_status) lc->vtable.display_status(lc,msg); break; + case SalReasonRequestPending: + /*restore previous state, the application will decide to resubmit the action if relevant*/ + linphone_call_set_state(call,call->prevstate,msg); + return; + break; default: if (lc->vtable.display_status) lc->vtable.display_status(lc,_("Call failed.")); diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index dd63fdb0a..c19a7a882 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -700,6 +700,7 @@ void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const LinphoneCore *lc=call->core; if (call->state!=cstate){ + call->prevstate=call->state; if (call->state==LinphoneCallEnd || call->state==LinphoneCallError){ if (cstate!=LinphoneCallReleased){ ms_warning("Spurious call state change from %s to %s, ignored.",linphone_call_state_to_string(call->state), @@ -2585,7 +2586,7 @@ void linphone_call_set_contact_op(LinphoneCall* call) { if (contact){ sal_op_set_contact(call->op, contact); #ifndef USE_BELLESIP - ms_free(contact); + ms_free(contact); #else linphone_address_destroy(contact); #endif diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index c5dc2d056..5f3aa37a1 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -2813,7 +2813,7 @@ void linphone_core_notify_incoming_call(LinphoneCore *lc, LinphoneCall *call){ if (sal_media_description_empty(md) || linphone_core_incompatible_security(lc,md)){ sal_call_decline(call->op,SalReasonMedia,NULL); linphone_core_del_call(lc,call); - linphone_call_ref(call); + linphone_call_unref(call); return; } } @@ -3327,7 +3327,7 @@ int linphone_core_terminate_call(LinphoneCore *lc, LinphoneCall *the_call) switch (call->state) { case LinphoneCallReleased: case LinphoneCallEnd: - ms_warning("No need to terminate a call [%p] in sate [%s]",call,linphone_call_state_to_string(call->state)); + ms_warning("No need to terminate a call [%p] in state [%s]",call,linphone_call_state_to_string(call->state)); return -1; case LinphoneCallIncomingReceived: case LinphoneCallIncomingEarlyMedia: diff --git a/coreapi/misc.c b/coreapi/misc.c index 24775553d..272d37960 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -1219,6 +1219,10 @@ LinphoneReason linphone_reason_from_sal(SalReason r){ break; case SalReasonServiceUnavailable: ret=LinphoneReasonIOError; + break; + case SalReasonRequestPending: + ret=LinphoneReasonNone; + break; } return ret; } diff --git a/coreapi/private.h b/coreapi/private.h index f1b0ccee2..1e28939c9 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -163,7 +163,8 @@ struct _LinphoneCall char localip[LINPHONE_IPADDR_SIZE]; /* our best guess for local ipaddress for this call */ time_t start_time; /*time at which the call was initiated*/ time_t media_start_time; /*time at which it was accepted, media streams established*/ - LinphoneCallState state; + LinphoneCallState state; + LinphoneCallState prevstate; LinphoneCallState transfer_state; /*idle if no transfer*/ LinphoneReason reason; LinphoneProxyConfig *dest_proxy; @@ -384,7 +385,6 @@ struct _LinphoneProxyConfig char *realm; char *contact_params; int expires; - int reg_time; SalOp *op; char *type; struct _SipSetupContext *ssctx; @@ -396,6 +396,8 @@ struct _LinphoneProxyConfig bool_t reg_sendregister; bool_t publish; bool_t dial_escape_plus; + bool_t send_publish; + bool_t pad[3]; void* user_data; time_t deletion_date; LinphoneReason error; diff --git a/coreapi/proxy.c b/coreapi/proxy.c index 814c00766..aacde9920 100644 --- a/coreapi/proxy.c +++ b/coreapi/proxy.c @@ -252,11 +252,6 @@ void linphone_proxy_config_edit(LinphoneProxyConfig *obj){ sal_unregister(obj->op); } } - if (obj->publish_op){ - /*we should certainly cancel our publish by some manner*/ - sal_op_release(obj->publish_op); - obj->publish_op=NULL; - } } void linphone_proxy_config_apply(LinphoneProxyConfig *obj,LinphoneCore *lc) @@ -858,7 +853,7 @@ int linphone_proxy_config_send_publish(LinphoneProxyConfig *proxy, LinphonePrese sal_op_set_from(proxy->publish_op,linphone_proxy_config_get_identity(proxy)); sal_op_set_to(proxy->publish_op,linphone_proxy_config_get_identity(proxy)); } - err=sal_publish_presence(proxy->publish_op,NULL,NULL,(SalPresenceModel *)presence); + err=sal_publish_presence(proxy->publish_op,NULL,NULL,proxy->expires,(SalPresenceModel *)presence); return err; } @@ -1186,10 +1181,12 @@ void linphone_proxy_config_update(LinphoneProxyConfig *cfg){ if (can_register(cfg)){ linphone_proxy_config_register(cfg); cfg->commit=FALSE; + if (cfg->publish) cfg->send_publish=TRUE; } } - if (cfg->publish && cfg->publish_op==NULL && cfg->state==LinphoneRegistrationOk){ + if (cfg->send_publish && (cfg->state==LinphoneRegistrationOk || cfg->state==LinphoneRegistrationCleared)){ linphone_proxy_config_send_publish(cfg,lc->presence_model); + cfg->send_publish=FALSE; } } diff --git a/include/sal/sal.h b/include/sal/sal.h index 0e94faf5b..48f9905be 100644 --- a/include/sal/sal.h +++ b/include/sal/sal.h @@ -273,7 +273,8 @@ typedef enum SalReason{ SalReasonMedia, SalReasonForbidden, SalReasonUnknown, - SalReasonServiceUnavailable + SalReasonServiceUnavailable, + SalReasonRequestPending }SalReason; const char* sal_reason_to_string(const SalReason reason); @@ -538,7 +539,7 @@ int sal_notify_presence(SalOp *op, SalPresenceModel *presence); int sal_notify_presence_close(SalOp *op); /*presence publish */ -int sal_publish_presence(SalOp *op, const char *from, const char *to, SalPresenceModel *presence); +int sal_publish_presence(SalOp *op, const char *from, const char *to, int expires, SalPresenceModel *presence); /*ping: main purpose is to obtain its own contact address behind firewalls*/ diff --git a/tester/call_tester.c b/tester/call_tester.c index 0817082c1..d16180732 100644 --- a/tester/call_tester.c +++ b/tester/call_tester.c @@ -336,22 +336,22 @@ static void cancelled_ringing_call(void) { static void early_declined_call(void) { LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); - LinphoneCallLog* in_call; + LinphoneCallLog* out_call_log; LinphoneCall* out_call; linphone_core_set_max_calls(marie->lc,0); out_call = linphone_core_invite(pauline->lc,"marie"); linphone_call_ref(out_call); - CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallReleased,1)); + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallError,1)); CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCallError,1); /* FIXME http://git.linphone.org/mantis/view.php?id=757 - CU_ASSERT_EQUAL(ms_list_size(linphone_core_get_call_logs(marie->lc)),1); - CU_ASSERT_EQUAL(linphone_call_get_reason(out_call),LinphoneReasonDeclined); + + CU_ASSERT_EQUAL(linphone_call_get_reason(out_call),LinphoneReasonBusy); */ - if (ms_list_size(linphone_core_get_call_logs(marie->lc))>0) { - CU_ASSERT_PTR_NOT_NULL(in_call=(LinphoneCallLog*)(linphone_core_get_call_logs(marie->lc)->data)); - CU_ASSERT_EQUAL(linphone_call_log_get_status(in_call),LinphoneCallDeclined); + if (ms_list_size(linphone_core_get_call_logs(pauline->lc))>0) { + CU_ASSERT_PTR_NOT_NULL(out_call_log=(LinphoneCallLog*)(linphone_core_get_call_logs(pauline->lc)->data)); + CU_ASSERT_EQUAL(linphone_call_log_get_status(out_call_log),LinphoneCallAborted); } linphone_call_unref(out_call); linphone_core_manager_destroy(marie); diff --git a/tester/liblinphone_tester.c b/tester/liblinphone_tester.c index cd278a7f9..466ef1278 100644 --- a/tester/liblinphone_tester.c +++ b/tester/liblinphone_tester.c @@ -99,29 +99,29 @@ static LinphoneCore* configure_lc_from(LinphoneCoreVTable* v_table, const char* if (path==NULL) path="."; - if (path && file){ - snprintf(filepath, sizeof(filepath), "%s/%s", path, file); + if (file){ + sprintf(filepath, "%s/%s", path, file); CU_ASSERT_TRUE_FATAL(ortp_file_exist(filepath)==0); } lc = linphone_core_new(v_table,NULL,*filepath!='\0' ? filepath : NULL,NULL); - if (path){ + #ifndef ANDROID - snprintf(rootcapath, sizeof(rootcapath), "%s/certificates/cacert.pem", path); + snprintf(rootcapath, sizeof(rootcapath), "%s/certificates/cacert.pem", path); #else - snprintf(rootcapath, sizeof(rootcapath), "%s/cacert.pem", path); + snprintf(rootcapath, sizeof(rootcapath), "%s/cacert.pem", path); #endif - linphone_core_set_root_ca(lc,rootcapath); + linphone_core_set_root_ca(lc,rootcapath); - sprintf(dnsuserhostspath, "%s/%s", path, userhostsfile); - sal_set_dns_user_hosts_file(lc->sal, dnsuserhostspath); + sprintf(dnsuserhostspath, "%s/%s", path, userhostsfile); + sal_set_dns_user_hosts_file(lc->sal, dnsuserhostspath); + + sprintf(ringpath, "%s/%s", path, "oldphone.wav"); + sprintf(ringbackpath, "%s/%s", path, "ringback.wav"); + linphone_core_set_ring(lc, ringpath); + linphone_core_set_ringback(lc, ringbackpath); - sprintf(ringpath, "%s/%s", path, "oldphone.wav"); - sprintf(ringbackpath, "%s/%s", path, "ringback.wav"); - linphone_core_set_ring(lc, ringpath); - linphone_core_set_ringback(lc, ringbackpath); - } return lc; } diff --git a/tester/tester_hosts b/tester/tester_hosts index b5ffa240a..39b811654 100644 --- a/tester/tester_hosts +++ b/tester/tester_hosts @@ -1 +1 @@ -37.59.129.74 sip.example.org sipopen.example.org auth.example.org auth1.example.org auth2.example.org +94.23.19.176 sip.example.org sipopen.example.org auth.example.org auth1.example.org auth2.example.org