Commit 1a8e5456 authored by Simon Morlat's avatar Simon Morlat

implement dialog serialization

parent 3d18c79d
......@@ -57,10 +57,10 @@ BELLESIP_EXPORT const belle_sip_header_call_id_t *belle_sip_dialog_get_call_id(c
BELLESIP_EXPORT const belle_sip_header_address_t *belle_sip_dialog_get_local_party(const belle_sip_dialog_t *dialog);
BELLESIP_EXPORT const belle_sip_header_address_t *belle_sip_dialog_get_remote_party(const belle_sip_dialog_t *dialog);
/*
/**
* get the value of the last cseq used to issue a request
*@return local cseq
* */
* @return local cseq
**/
BELLESIP_EXPORT unsigned int belle_sip_dialog_get_local_seq_number(const belle_sip_dialog_t *dialog);
unsigned int belle_sip_dialog_get_remote_seq_number(const belle_sip_dialog_t *dialog);
......@@ -74,11 +74,11 @@ BELLESIP_EXPORT const belle_sip_header_address_t *belle_sip_dialog_get_remote_ta
BELLESIP_EXPORT const belle_sip_list_t* belle_sip_dialog_get_route_set(belle_sip_dialog_t *dialog);
BELLESIP_EXPORT belle_sip_dialog_state_t belle_sip_dialog_get_state(const belle_sip_dialog_t *dialog);
/*
/**
* return the dialog state before last transition. Can be useful to detect early avorted dialogs
* @param dialog
* @returns state
* */
**/
BELLESIP_EXPORT belle_sip_dialog_state_t belle_sip_dialog_get_previous_state(const belle_sip_dialog_t *dialog);
......@@ -89,12 +89,15 @@ BELLESIP_EXPORT int belle_sip_dialog_is_secure(const belle_sip_dialog_t *dialog)
BELLESIP_EXPORT void belle_sip_dialog_send_ack(belle_sip_dialog_t *dialog, belle_sip_request_t *request);
BELLESIP_EXPORT void belle_sip_dialog_terminate_on_bye(belle_sip_dialog_t *dialog, int val);
/*
/**
* Give access to the last transaction processed by a dialog. Can be useful to get reason code for dialog terminated before reaching established state
* @param dialog
* @return last transaction
*/
BELLESIP_EXPORT belle_sip_transaction_t* belle_sip_dialog_get_last_transaction(const belle_sip_dialog_t *dialog);
BELLESIP_EXPORT int belle_sip_dialog_request_pending(belle_sip_dialog_t *dialog);
BELLE_SIP_END_DECLS
#endif
......
......@@ -328,9 +328,13 @@ int belle_sip_dialog_update(belle_sip_dialog_t *obj,belle_sip_transaction_t* tra
int is_retransmition=FALSE;
belle_sip_request_t *req=belle_sip_transaction_get_request(transaction);
belle_sip_response_t *resp=belle_sip_transaction_get_response(transaction);
belle_sip_object_ref(transaction);
if (obj->last_transaction) belle_sip_object_unref(obj->last_transaction);
obj->last_transaction=transaction;
belle_sip_object_ref(obj->last_transaction);
if (!resp)
return 0;
/*first update local/remote cseq*/
if (as_uas) {
......@@ -495,9 +499,15 @@ belle_sip_request_t *belle_sip_dialog_create_request(belle_sip_dialog_t *obj, co
belle_sip_request_t *req;
if (obj->state != BELLE_SIP_DIALOG_CONFIRMED && obj->state != BELLE_SIP_DIALOG_EARLY) {
belle_sip_error("Cannot create method [%s] from dialog [%p] in state [%s]",method,obj,belle_sip_dialog_state_to_string(obj->state));
belle_sip_error("belle_sip_dialog_create_request(): cannot create [%s] request from dialog [%p] in state [%s]",method,obj,belle_sip_dialog_state_to_string(obj->state));
return NULL;
}
if (strcmp(method,"BYE")!=0 && obj->last_transaction && belle_sip_transaction_state_is_transient(belle_sip_transaction_get_state(obj->last_transaction))){
/*don't prevent to send a BYE in any case */
belle_sip_error("belle_sip_dialog_create_request(): cannot create [%s] request from dialog [%p] while pending transaction in state [%s]",method,obj,belle_sip_transaction_state_to_string(belle_sip_transaction_get_state(obj->last_transaction)));
return NULL;
}
if (obj->local_cseq==0) obj->local_cseq=110;
if (strcmp(method,"ACK")!=0) obj->local_cseq++;
req=belle_sip_request_create(belle_sip_header_address_get_uri(obj->remote_target),
......@@ -516,6 +526,7 @@ belle_sip_request_t *belle_sip_dialog_create_request(belle_sip_dialog_t *obj, co
}
return req;
}
static unsigned int is_system_header(belle_sip_header_t* header) {
const char* name=belle_sip_header_get_name(header);
return strcasecmp(BELLE_SIP_VIA,name) ==0
......@@ -728,3 +739,8 @@ belle_sip_dialog_t* belle_sip_provider_find_dialog(const belle_sip_provider_t *p
belle_sip_transaction_t* belle_sip_dialog_get_last_transaction(const belle_sip_dialog_t *dialog) {
return dialog->last_transaction;
}
int belle_sip_dialog_request_pending(belle_sip_dialog_t *dialog){
return dialog->last_transaction ? belle_sip_transaction_state_is_transient(belle_sip_transaction_get_state(dialog->last_transaction)) : FALSE;
}
......@@ -49,6 +49,7 @@ static void nist_set_completed(belle_sip_nist_t *obj){
else tval=0;
obj->timer_J=belle_sip_timeout_source_new((belle_sip_source_func_t)nist_on_timer_J,obj,tval);
belle_sip_transaction_start_timer(base,obj->timer_J);
belle_sip_transaction_set_state(base,BELLE_SIP_TRANSACTION_COMPLETED);
}
static int nist_send_new_response(belle_sip_nist_t *obj, belle_sip_response_t *resp){
......
......@@ -90,16 +90,22 @@ static void belle_sip_provider_dispatch_request(belle_sip_provider_t* prov, bell
belle_sip_server_transaction_on_request(t,req);
belle_sip_object_unref(t);
}else{
const char *method=belle_sip_request_get_method(req);
ev.dialog=NULL;
/* Should we limit to ACK ? */
/*Search for a dialog if exist */
ev.dialog=belle_sip_provider_find_dialog_from_msg(prov,req,1/*request=uas*/);
if (strcmp("ACK",belle_sip_request_get_method(req))==0){
if (!ev.dialog) {
belle_sip_warning("Provider [%p] received an unexpected stateless ACK",prov);
} else if (belle_sip_dialog_handle_ack(ev.dialog,req)==-1){
/*absorbed ACK retransmission, ignore */
if (ev.dialog){
if (strcmp("ACK",method)==0){
if (belle_sip_dialog_handle_ack(ev.dialog,req)==-1){
/*absorbed ACK retransmission, ignore */
return;
}
}else if (belle_sip_dialog_request_pending(ev.dialog) && strcmp(method,"BYE")!=0){
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,491));
return;
}
}
......@@ -410,6 +416,7 @@ static void notify_dialog_terminated(belle_sip_dialog_terminated_event_t* ev) {
belle_sip_object_unref(ev->dialog);
belle_sip_free(ev);
}
void belle_sip_provider_remove_dialog(belle_sip_provider_t *prov, belle_sip_dialog_t *dialog){
belle_sip_dialog_terminated_event_t* ev=belle_sip_malloc(sizeof(belle_sip_dialog_terminated_event_t));
ev->source=prov;
......@@ -443,7 +450,7 @@ belle_sip_client_transaction_t *belle_sip_provider_create_client_transaction(bel
send the original request.*/
t->next_hop=(belle_sip_hop_t*)belle_sip_object_ref(inv_transaction->next_hop);
} else {
belle_sip_error (" No corresponding ict nor dest found for cancel request attached to transaction [%p]",t);
belle_sip_error ("No corresponding ict nor dest found for cancel request attached to transaction [%p]",t);
}
}
}
......
......@@ -42,9 +42,12 @@ const char *belle_sip_transaction_state_to_string(belle_sip_transaction_state_t
}
void belle_sip_transaction_set_state(belle_sip_transaction_t *t, belle_sip_transaction_state_t state) {
belle_sip_message("Changing transaction [%p], from state [%s] to [%s]",t
,belle_sip_transaction_state_to_string(t->state)
,belle_sip_transaction_state_to_string(state));
belle_sip_message("Changing [%s] [%s] transaction [%p], from state [%s] to [%s]",
BELLE_SIP_OBJECT_IS_INSTANCE_OF(t,belle_sip_client_transaction_t) ? "client" : "server",
belle_sip_request_get_method(t->request),
t,
belle_sip_transaction_state_to_string(t->state),
belle_sip_transaction_state_to_string(state));
t->state=state;
}
static void belle_sip_transaction_init(belle_sip_transaction_t *t, belle_sip_provider_t *prov, belle_sip_request_t *req){
......@@ -150,6 +153,9 @@ void belle_sip_transaction_set_dialog(belle_sip_transaction_t *t, belle_sip_dial
if (dialog) belle_sip_object_ref(dialog);
if (t->dialog) belle_sip_object_unref(t->dialog); /*to avoid keeping unexpected ref*/
t->dialog=dialog;
if (t->dialog){
belle_sip_dialog_update(dialog,t,BELLE_SIP_OBJECT_IS_INSTANCE_OF(t,belle_sip_server_transaction_t));
}
}
/*
......@@ -206,7 +212,6 @@ void belle_sip_server_transaction_send_response(belle_sip_server_transaction_t *
2xx and 101-199 responses with a To tag, where the request was
INVITE, will establish a dialog.*/
if (dialog && status_code>100 && status_code<300){
belle_sip_response_fill_for_dialog(resp,base->request);
}
}
......
......@@ -215,8 +215,8 @@ static void callee_process_response_event(void *user_ctx, const belle_sip_respon
belle_sip_main_loop_quit(belle_sip_stack_get_main_loop(stack));
}
belle_sip_message("callee_process_response_event [%i] on dialog [%p] for state [%s]",status
,dialog
,belle_sip_dialog_state_to_string(belle_sip_dialog_get_state(dialog)));
,dialog
,belle_sip_dialog_state_to_string(belle_sip_dialog_get_state(dialog)));
}
......
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