static void process_dialog_terminated(void *ctx, const belle_sip_dialog_terminated_event_t *event) { SalOp* op=(SalOp*)ctx; if (op->dialog && op->dialog==belle_sip_dialog_terminated_event_get_dialog(event)) { /*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_event_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; default: break; } belle_sip_main_loop_do_later(belle_sip_stack_get_main_loop(op->base.root->stack) ,(belle_sip_callback_t) call_set_released , op); } else { ms_error("dialog unknown for op "); } }
void belle_sip_dialog_process_queue(belle_sip_dialog_t* dialog){ /*process queue does not process synchronously. * This is to let the application handle responses and eventually submit new requests without being blocked. * Typically when a reINVITE is challenged, we want a chance to re-submit an authenticated request before processing * queued requests*/ belle_sip_main_loop_do_later(dialog->provider->stack->ml,(belle_sip_callback_t)_belle_sip_dialog_process_queue,belle_sip_object_ref(dialog)); }
static void belle_sip_channel_handle_error(belle_sip_channel_t *obj){ if (obj->state!=BELLE_SIP_CHANNEL_READY){ /* Previous connection attempts were failed (channel could not get ready).*/ /* See if you can retry on an alternate ip address.*/ if (obj->current_peer && obj->current_peer->ai_next){ /*obj->current_peer may be null in case of dns error*/ obj->current_peer=obj->current_peer->ai_next; channel_set_state(obj,BELLE_SIP_CHANNEL_RETRY); belle_sip_channel_close(obj); belle_sip_main_loop_do_later(obj->stack->ml,(belle_sip_callback_t)channel_connect_next,belle_sip_object_ref(obj)); return; }/*else we have already tried all the ip addresses, so give up and notify the error*/ }/*else the channel was previously working good with the current ip address but now fails, so let's notify the error*/ obj->state=BELLE_SIP_CHANNEL_ERROR; channel_end_send_background_task(obj); /*Because error notification will in practice trigger the destruction of possible transactions and this channel, * it is safer to invoke the listener outside the current call stack. * Indeed the channel encounters network errors while being called for transmiting by a transaction. */ belle_sip_main_loop_do_later(obj->stack->ml,(belle_sip_callback_t)channel_invoke_state_listener_defered,belle_sip_object_ref(obj)); }