void belle_sip_transaction_terminate(belle_sip_transaction_t *t){ if (belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(t))!=BELLE_SIP_TRANSACTION_TERMINATED) { belle_sip_transaction_set_state(t,BELLE_SIP_TRANSACTION_TERMINATED); belle_sip_message("%s%s %s transaction [%p] terminated" ,BELLE_SIP_OBJECT_IS_INSTANCE_OF(t,belle_sip_client_transaction_t)?"Client":"Server" ,t->is_internal?" internal":"" ,belle_sip_request_get_method(belle_sip_transaction_get_request(t)) ,t); BELLE_SIP_OBJECT_VPTR(t,belle_sip_transaction_t)->on_terminate(t); belle_sip_provider_set_transaction_terminated(t->provider,t); } }
static void ict_on_response(belle_sip_ict_t *obj, belle_sip_response_t *resp){ belle_sip_transaction_t *base=(belle_sip_transaction_t*)obj; int code=belle_sip_response_get_status_code(resp); const belle_sip_timer_config_t *cfg=belle_sip_transaction_get_timer_config(base); switch (base->state){ case BELLE_SIP_TRANSACTION_CALLING: belle_sip_transaction_set_state(base,BELLE_SIP_TRANSACTION_PROCEEDING); /* no break*/ case BELLE_SIP_TRANSACTION_PROCEEDING: if (code>=300){ belle_sip_transaction_set_state(base,BELLE_SIP_TRANSACTION_COMPLETED); belle_sip_channel_queue_message(base->channel,(belle_sip_message_t*)make_ack(obj,resp)); belle_sip_client_transaction_notify_response((belle_sip_client_transaction_t*)obj,resp); obj->timer_D=belle_sip_timeout_source_new((belle_sip_source_func_t)ict_on_timer_D,obj,cfg->T1*64); belle_sip_transaction_start_timer(base,obj->timer_D); }else if (code>=200){ obj->timer_M=belle_sip_timeout_source_new((belle_sip_source_func_t)ict_on_timer_M,obj,cfg->T1*64); belle_sip_transaction_start_timer(base,obj->timer_M); belle_sip_transaction_set_state(base,BELLE_SIP_TRANSACTION_ACCEPTED); belle_sip_client_transaction_notify_response((belle_sip_client_transaction_t*)obj,resp); }else if (code>=100){ belle_sip_client_transaction_notify_response((belle_sip_client_transaction_t*)obj,resp); } break; case BELLE_SIP_TRANSACTION_ACCEPTED: if (code>=200 && code<300){ belle_sip_client_transaction_notify_response((belle_sip_client_transaction_t*)obj,resp); } break; case BELLE_SIP_TRANSACTION_COMPLETED: if (code>=300 && obj->ack){ belle_sip_channel_queue_message(base->channel,(belle_sip_message_t*)obj->ack); } break; default: break; } }
static void nict_set_completed(belle_sip_nict_t *obj, belle_sip_response_t *resp){ belle_sip_transaction_t *base=(belle_sip_transaction_t*)obj; const belle_sip_timer_config_t *cfg=belle_sip_transaction_get_timer_config(base); belle_sip_transaction_set_state(base,BELLE_SIP_TRANSACTION_COMPLETED); if (obj->timer_K) belle_sip_fatal("Should never happen."); belle_sip_client_transaction_notify_response((belle_sip_client_transaction_t*)obj,resp); if (!belle_sip_channel_is_reliable(base->channel)){ obj->timer_K=belle_sip_timeout_source_new((belle_sip_source_func_t)nict_on_timer_K,obj,cfg->T4); belle_sip_object_set_name((belle_sip_object_t*)obj->timer_K,"timer_K"); belle_sip_transaction_start_timer(base,obj->timer_K); }else belle_sip_transaction_terminate(base); }
static void nict_send_request(belle_sip_nict_t *obj){ belle_sip_transaction_t *base=(belle_sip_transaction_t*)obj; const belle_sip_timer_config_t *cfg=belle_sip_transaction_get_timer_config(base); belle_sip_transaction_set_state(base,BELLE_SIP_TRANSACTION_TRYING); obj->timer_F=belle_sip_timeout_source_new((belle_sip_source_func_t)nict_on_timer_F,obj,cfg->T1*64); belle_sip_object_set_name((belle_sip_object_t*)obj->timer_F,"timer_F"); belle_sip_transaction_start_timer(base,obj->timer_F); if (!belle_sip_channel_is_reliable(base->channel)){ obj->timer_E=belle_sip_timeout_source_new((belle_sip_source_func_t)nict_on_timer_E,obj,cfg->T1); belle_sip_object_set_name((belle_sip_object_t*)obj->timer_E,"timer_E"); belle_sip_transaction_start_timer(base,obj->timer_E); } belle_sip_channel_queue_message(base->channel,(belle_sip_message_t*)base->request); }
void belle_sip_transaction_terminate(belle_sip_transaction_t *t){ if (belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(t))!=BELLE_SIP_TRANSACTION_TERMINATED) { int is_client=BELLE_SIP_OBJECT_IS_INSTANCE_OF(t,belle_sip_client_transaction_t); belle_sip_transaction_set_state(t,BELLE_SIP_TRANSACTION_TERMINATED); if (t->dialog && (!t->last_response || belle_sip_response_get_status_code(t->last_response)<200)){ /*inform the dialog if a transaction terminates without final response.*/ belle_sip_dialog_update(t->dialog,t,!is_client); } belle_sip_message("%s%s %s transaction [%p] terminated" ,is_client ? "Client":"Server" ,t->is_internal ? " internal":"" ,belle_sip_request_get_method(belle_sip_transaction_get_request(t)) ,t); BELLE_SIP_OBJECT_VPTR(t,belle_sip_transaction_t)->on_terminate(t); belle_sip_provider_set_transaction_terminated(t->provider,t); } }
static void ict_send_request(belle_sip_ict_t *obj){ belle_sip_transaction_t *base=(belle_sip_transaction_t*)obj; const belle_sip_timer_config_t *cfg=belle_sip_transaction_get_timer_config(base); belle_sip_transaction_set_state(base,BELLE_SIP_TRANSACTION_CALLING); if (!belle_sip_channel_is_reliable(base->channel)){ obj->timer_A=belle_sip_timeout_source_new((belle_sip_source_func_t)ict_on_timer_A,obj,cfg->T1); belle_sip_transaction_start_timer(base,obj->timer_A); } obj->timer_B=belle_sip_timeout_source_new((belle_sip_source_func_t)ict_on_timer_B,obj,cfg->T1*64); belle_sip_transaction_start_timer(base,obj->timer_B); belle_sip_channel_queue_message(base->channel,(belle_sip_message_t*)base->request); }
static void nict_on_response(belle_sip_nict_t *obj, belle_sip_response_t *resp){ belle_sip_transaction_t *base=(belle_sip_transaction_t*)obj; int code=belle_sip_response_get_status_code(resp); switch(base->state){ case BELLE_SIP_TRANSACTION_TRYING: if (code<200){ belle_sip_transaction_set_state(base,BELLE_SIP_TRANSACTION_PROCEEDING); belle_sip_client_transaction_notify_response((belle_sip_client_transaction_t*)obj,resp); } else { nict_set_completed(obj,resp); } break; case BELLE_SIP_TRANSACTION_PROCEEDING: if (code>=200){ nict_set_completed(obj,resp); } break; default: break; } }