Commit 9fd810d1 authored by Ghislain MARY's avatar Ghislain MARY
Browse files

Do not terminate INVITE transaction immediately when the connectivity is lost.

This is to implement the section 5.5 of RFC 6141.
parent dcded2d1
......@@ -844,6 +844,8 @@ int belle_sip_dialog_update(belle_sip_dialog_t *obj,belle_sip_transaction_t* tra
void belle_sip_dialog_check_ack_sent(belle_sip_dialog_t*obj);
int belle_sip_dialog_handle_ack(belle_sip_dialog_t *obj, belle_sip_request_t *ack);
void belle_sip_dialog_queue_client_transaction(belle_sip_dialog_t *dialog, belle_sip_client_transaction_t *tr);
void belle_sip_dialog_stop_200Ok_retrans(belle_sip_dialog_t *obj);
/*
belle_sip_response_t
......
......@@ -19,7 +19,6 @@
#include "belle_sip_internal.h"
static void belle_sip_dialog_init_200Ok_retrans(belle_sip_dialog_t *obj, belle_sip_response_t *resp);
static void belle_sip_dialog_stop_200Ok_retrans(belle_sip_dialog_t *obj);
static int belle_sip_dialog_handle_200Ok(belle_sip_dialog_t *obj, belle_sip_response_t *msg);
static void belle_sip_dialog_process_queue(belle_sip_dialog_t* dialog);
static belle_sip_request_t *create_request(belle_sip_dialog_t *obj, const char *method, int full);
......@@ -368,7 +367,7 @@ static void belle_sip_dialog_init_200Ok_retrans(belle_sip_dialog_t *obj, belle_s
obj->last_200Ok=(belle_sip_response_t*)belle_sip_object_ref(resp);
}
static void belle_sip_dialog_stop_200Ok_retrans(belle_sip_dialog_t *obj){
void belle_sip_dialog_stop_200Ok_retrans(belle_sip_dialog_t *obj){
belle_sip_main_loop_t *ml=obj->provider->stack->ml;
if (obj->timer_200Ok){
belle_sip_main_loop_remove_source(ml,obj->timer_200Ok);
......
......@@ -132,6 +132,13 @@ static void belle_sip_provider_dispatch_request(belle_sip_provider_t* prov, bell
/* Should we limit to ACK ? */
/*Search for a dialog if exist */
if (strcmp("CANCEL",method) == 0) {
/* Call leg does not exist */
belle_sip_server_transaction_t *tr = belle_sip_provider_create_server_transaction(prov, req);
belle_sip_server_transaction_send_response(tr, belle_sip_response_create_from_request(req, 481));
return;
}
ev.dialog=belle_sip_provider_find_dialog_from_message(prov,(belle_sip_message_t*)req,1/*request=uas*/);
if (ev.dialog){
if (strcmp("ACK",method)==0){
......@@ -139,6 +146,8 @@ static void belle_sip_provider_dispatch_request(belle_sip_provider_t* prov, bell
/*absorbed ACK retransmission, ignore */
return;
}
}else if ((strcmp("INVITE",method)==0)&&(ev.dialog->needs_ack)){
belle_sip_dialog_stop_200Ok_retrans(ev.dialog);
}else if (!belle_sip_dialog_is_authorized_transaction(ev.dialog,method)){
belle_sip_server_transaction_t *tr=belle_sip_provider_create_server_transaction(prov,req);
belle_sip_server_transaction_send_response(tr,
......
......@@ -83,6 +83,12 @@ static int server_transaction_on_call_repair_timer(belle_sip_transaction_t *t) {
return BELLE_SIP_STOP;
}
static int client_transaction_on_call_repair_timer(belle_sip_transaction_t *t) {
belle_sip_transaction_terminate(t);
belle_sip_object_unref(t);
return BELLE_SIP_STOP;
}
static void on_channel_state_changed(belle_sip_channel_listener_t *l, belle_sip_channel_t *chan, belle_sip_channel_state_t state){
belle_sip_transaction_t *t=(belle_sip_transaction_t*)l;
belle_sip_io_error_event_t ev;
......@@ -114,12 +120,14 @@ static void on_channel_state_changed(belle_sip_channel_listener_t *l, belle_sip_
if (t->timed_out)
notify_timeout((belle_sip_transaction_t*)t);
if (t->dialog && (belle_sip_dialog_get_state(t->dialog) == BELLE_SIP_DIALOG_EARLY)) {
if (!t->timed_out && BELLE_SIP_OBJECT_IS_INSTANCE_OF(t, belle_sip_server_transaction_t)) {
const belle_sip_timer_config_t *cfg = belle_sip_transaction_get_timer_config(t);
t->call_repair_timer = belle_sip_timeout_source_new((belle_sip_source_func_t)server_transaction_on_call_repair_timer, t, 32 * cfg->T1);
belle_sip_transaction_start_timer(t, t->call_repair_timer);
}
if (!t->timed_out && BELLE_SIP_OBJECT_IS_INSTANCE_OF(t, belle_sip_server_transaction_t)) {
const belle_sip_timer_config_t *cfg = belle_sip_transaction_get_timer_config(t);
t->call_repair_timer = belle_sip_timeout_source_new((belle_sip_source_func_t)server_transaction_on_call_repair_timer, t, 32 * cfg->T1);
belle_sip_transaction_start_timer(t, t->call_repair_timer);
} else if (!t->timed_out && BELLE_SIP_OBJECT_IS_INSTANCE_OF(t, belle_sip_client_transaction_t)) {
const belle_sip_timer_config_t *cfg = belle_sip_transaction_get_timer_config(t);
t->call_repair_timer = belle_sip_timeout_source_new((belle_sip_source_func_t)client_transaction_on_call_repair_timer, t, 32 * cfg->T1);
belle_sip_transaction_start_timer(t, t->call_repair_timer);
} else {
belle_sip_transaction_terminate(t);
belle_sip_object_unref(t);
......@@ -373,8 +381,8 @@ belle_sip_request_t * belle_sip_client_transaction_create_cancel(belle_sip_clien
belle_sip_error("belle_sip_client_transaction_create_cancel() cannot be used for ACK or non-INVITE transactions.");
return NULL;
}
if (t->base.state!=BELLE_SIP_TRANSACTION_PROCEEDING){
belle_sip_error("belle_sip_client_transaction_create_cancel() can only be used in state BELLE_SIP_TRANSACTION_PROCEEDING"
if ((t->base.state != BELLE_SIP_TRANSACTION_PROCEEDING) && (t->base.state != BELLE_SIP_TRANSACTION_CALLING)) {
belle_sip_error("belle_sip_client_transaction_create_cancel() can only be used in state PROCEEDING or CALLING"
" but current transaction state is %s",belle_sip_transaction_state_to_string(t->base.state));
return NULL;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment