Commit ba32650e authored by jehan's avatar jehan

better error handling

parent ed84b00f
......@@ -60,6 +60,13 @@ belle_sip_dialog_t* belle_sip_dialog_terminated_get_dialog(const belle_sip_dialo
belle_sip_client_transaction_t *belle_sip_timeout_event_get_client_transaction(const belle_sip_timeout_event_t* event);
belle_sip_server_transaction_t *belle_sip_timeout_event_get_server_transaction(const belle_sip_timeout_event_t* event);
/**
* Transaction Termonated Event
*/
belle_sip_client_transaction_t *belle_sip_transaction_terminated_event_get_client_transaction(const belle_sip_transaction_terminated_event_t* event);
belle_sip_server_transaction_t *belle_sip_transaction_terminated_event_get_server_transaction(const belle_sip_transaction_terminated_event_t* event);
/*auth event*/
void belle_sip_auth_event_destroy(belle_sip_auth_event_t* event);
const char* belle_sip_auth_event_get_username(const belle_sip_auth_event_t* event);
......
......@@ -71,11 +71,13 @@
const belle_sip_list_t *__elem=list;\
do{\
interface_name *__obj=(interface_name*)__elem->data;\
belle_sip_object_ref(__obj);\
void *__method=BELLE_SIP_INTERFACE_GET_METHODS(__obj,interface_name)->method;\
if (__method) BELLE_SIP_INTERFACE_GET_METHODS(__obj,interface_name)->
#define __BELLE_SIP_INVOKE_LISTENER_END \
__elem=__elem->next;\
belle_sip_object_unref(__obj);\
}while(__elem!=NULL);\
}
......@@ -523,7 +525,6 @@ struct belle_sip_transaction{
belle_sip_dialog_t *dialog;
char *branch_id;
belle_sip_transaction_state_t state;
belle_sip_transaction_state_t previous_state; /*just to provide user with information regarding state transition*/
uint64_t start_time;
void *appdata;
unsigned int is_internal;
......
......@@ -31,7 +31,7 @@ void belle_sip_listening_point_init(belle_sip_listening_point_t *lp, belle_sip_s
static void belle_sip_listening_point_uninit(belle_sip_listening_point_t *lp){
belle_sip_listening_point_clean_channels(lp);
belle_sip_message("Listening [%p] on [%s://%s:%i] destroyed" ,lp
belle_sip_message("Listening point [%p] on [%s://%s:%i] destroyed" ,lp
,belle_sip_uri_get_transport_param(BELLE_SIP_LISTENING_POINT(lp)->listening_uri)
,belle_sip_uri_get_host(BELLE_SIP_LISTENING_POINT(lp)->listening_uri)
,belle_sip_uri_get_port(BELLE_SIP_LISTENING_POINT(lp)->listening_uri));
......@@ -65,12 +65,17 @@ void belle_sip_listening_point_remove_channel(belle_sip_listening_point_t *lp, b
void belle_sip_listening_point_clean_channels(belle_sip_listening_point_t *lp){
int existing_channels;
belle_sip_list_t* iterator;
belle_sip_list_t* channels=belle_sip_list_copy(lp->channels);
if ((existing_channels=belle_sip_list_size(lp->channels)) > 0) {
belle_sip_warning("Listening point destroying [%i] channels",existing_channels);
}
for (iterator=lp->channels;iterator!=NULL;iterator=iterator->next) {
belle_sip_main_loop_remove_source(lp->stack->ml,(belle_sip_source_t*)(iterator->data));
for (iterator=channels;iterator!=NULL;iterator=iterator->next) {
/*first, every existing channel must be set to error*/
channel_set_state((belle_sip_channel_t*)(iterator->data),BELLE_SIP_CHANNEL_DISCONNECTED);
belle_sip_channel_close((belle_sip_channel_t*)(iterator->data));
}
belle_sip_list_free(channels);
lp->channels=belle_sip_list_free_with_data(lp->channels,(void (*)(void*))belle_sip_object_unref);
}
......
......@@ -71,9 +71,9 @@ static void channel_state_changed(belle_sip_channel_listener_t *obj, belle_sip_c
belle_sip_provider_t* prov=BELLE_SIP_PROVIDER(obj);
if (state == BELLE_SIP_CHANNEL_ERROR || state == BELLE_SIP_CHANNEL_DISCONNECTED) {
ev.transport=belle_sip_channel_get_transport_name(chan);
ev.source=BELLE_SIP_OBJECT(obj); /*FIXME, must be either trans, dialog or provider, but not only prov */
ev.port=chan->peer_port;
ev.host=chan->peer_name;
ev.source=BELLE_SIP_OBJECT(prov);
BELLE_SIP_PROVIDER_INVOKE_LISTENERS(prov->listeners,process_io_error,&ev);
belle_sip_provider_release_channel(prov,chan);
}
......@@ -217,25 +217,7 @@ static void fix_outgoing_via(belle_sip_provider_t *p, belle_sip_channel_t *chan,
belle_sip_message("Computing branch id %s for message sent statelessly", branchid);
}
}
/*
static void belle_sip_provider_read_message(belle_sip_provider_t *prov, belle_sip_channel_t *chan){
char buffer[belle_sip_network_buffer_size];
int err;
err=belle_sip_channel_recv(chan,buffer,sizeof(buffer));
if (err>0){
belle_sip_message_t *msg;
buffer[err]='\0';
belle_sip_message("provider %p read message from %s:%i\n%s",prov,chan->peer_name,chan->peer_port,buffer);
msg=belle_sip_message_parse(buffer);
if (msg){
if (belle_sip_message_is_request(msg)) fix_incoming_via(BELLE_SIP_REQUEST(msg),chan->peer);
belle_sip_provider_dispatch_message(prov,msg);
}else{
belle_sip_error("Could not parse this message.");
}
}
}
*/
static int channel_on_event(belle_sip_channel_listener_t *obj, belle_sip_channel_t *chan, unsigned int revents){
if (revents & BELLE_SIP_EVENT_READ){
belle_sip_message_t *msg=belle_sip_channel_pick_message(chan);
......@@ -581,8 +563,14 @@ belle_sip_client_transaction_t * belle_sip_provider_find_matching_client_transac
}
void belle_sip_provider_remove_client_transaction(belle_sip_provider_t *prov, belle_sip_client_transaction_t *t){
prov->client_transactions=belle_sip_list_remove(prov->client_transactions,t);
belle_sip_object_unref(t);
belle_sip_list_t* elem=belle_sip_list_find(prov->client_transactions,t);
if (elem) {
prov->client_transactions=belle_sip_list_delete_link(prov->client_transactions,elem);
belle_sip_object_unref(t);
} else {
belle_sip_error("trying to remove transaction [%p] not part of provider [%p]",t,prov);
}
}
void belle_sip_provider_add_server_transaction(belle_sip_provider_t *prov, belle_sip_server_transaction_t *t){
......
......@@ -109,7 +109,7 @@ static void process_timeout(void *user_ctx, const belle_sip_timeout_event_t *eve
return;
}
static void process_transaction_terminated(void *user_ctx, const belle_sip_transaction_terminated_event_t *event) {
belle_sip_message("process_transaction_terminated Transaction terminated [%p]",event);
/*belle_sip_message("process_transaction_terminated Transaction terminated [%p]",event);*/
}
static void destroy(belle_sip_refresher_t *refresher){
......
......@@ -62,12 +62,7 @@ belle_sip_object_t* belle_sip_io_error_event_get_source(const belle_sip_io_error
return event->source;
}
belle_sip_client_transaction_t *belle_sip_timeout_event_get_client_transaction(const belle_sip_timeout_event_t* event) {
return BELLE_SIP_CLIENT_TRANSACTION(event->transaction);
}
belle_sip_server_transaction_t *belle_sip_timeout_event_get_server_transaction(const belle_sip_timeout_event_t* event) {
return BELLE_SIP_SERVER_TRANSACTION(event->transaction);
}
typedef struct belle_sip_callbacks belle_sip_callbacks_t;
......@@ -148,3 +143,16 @@ belle_sip_listener_t *belle_sip_listener_create_from_callbacks(const belle_sip_l
return BELLE_SIP_LISTENER(obj);
}
belle_sip_client_transaction_t *belle_sip_transaction_terminated_event_get_client_transaction(const belle_sip_transaction_terminated_event_t* event) {
return event->is_server_transaction ? NULL:BELLE_SIP_CLIENT_TRANSACTION(event->transaction);
}
belle_sip_server_transaction_t *belle_sip_transaction_terminated_event_get_server_transaction(const belle_sip_transaction_terminated_event_t* event) {
return event->is_server_transaction ? BELLE_SIP_SERVER_TRANSACTION(event->transaction):NULL;
}
belle_sip_client_transaction_t *belle_sip_timeout_event_get_client_transaction(const belle_sip_timeout_event_t* event) {
return event->is_server_transaction ? NULL:BELLE_SIP_CLIENT_TRANSACTION(event->transaction);
}
belle_sip_server_transaction_t *belle_sip_timeout_event_get_server_transaction(const belle_sip_timeout_event_t* event) {
return event->is_server_transaction ? BELLE_SIP_SERVER_TRANSACTION(event->transaction):NULL;
}
......@@ -253,6 +253,7 @@ int belle_sip_client_transaction_send_request_to(belle_sip_client_transaction_t
belle_sip_hop_t* hop;
belle_sip_channel_t *chan;
belle_sip_provider_t *prov=t->base.provider;
int result=-1;
if (t->base.state!=BELLE_SIP_TRANSACTION_INIT){
belle_sip_error("belle_sip_client_transaction_send_request: bad state.");
......@@ -268,10 +269,9 @@ int belle_sip_client_transaction_send_request_to(belle_sip_client_transaction_t
} else {
hop = belle_sip_stack_create_next_hop(prov->stack,t->base.request);
}
belle_sip_provider_add_client_transaction(t->base.provider,t); /*add it in any case*/
chan=belle_sip_provider_get_channel(prov,hop->host, hop->port, hop->transport);
if (chan){
belle_sip_provider_add_client_transaction(t->base.provider,t);
belle_sip_object_ref(chan);
belle_sip_channel_add_listener(chan,BELLE_SIP_CHANNEL_LISTENER(t));
t->base.channel=chan;
......@@ -283,9 +283,14 @@ int belle_sip_client_transaction_send_request_to(belle_sip_client_transaction_t
/*otherwise we can send immediately*/
BELLE_SIP_OBJECT_VPTR(t,belle_sip_client_transaction_t)->send_request(t);
}
}else belle_sip_error("belle_sip_client_transaction_send_request(): no channel available");
result=0;
}else {
belle_sip_error("belle_sip_client_transaction_send_request(): no channel available");
belle_sip_transaction_terminate(BELLE_SIP_TRANSACTION(t));
result=-1;
}
belle_sip_hop_free(hop);
return 0;
return result;
}
static unsigned int should_dialog_be_created(belle_sip_client_transaction_t *t, belle_sip_response_t *resp){
......@@ -349,18 +354,28 @@ static void client_transaction_destroy(belle_sip_client_transaction_t *t ){
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_client_transaction_t *t=(belle_sip_client_transaction_t*)l;
belle_sip_io_error_event_t ev;
belle_sip_message("transaction on_channel_state_changed");
belle_sip_message("transaction [%p] channel state changed to [%s]"
,t
,belle_sip_channel_state_to_string(state));
switch(state){
case BELLE_SIP_CHANNEL_READY:
BELLE_SIP_OBJECT_VPTR(t,belle_sip_client_transaction_t)->send_request(t);
break;
case BELLE_SIP_CHANNEL_DISCONNECTED:
case BELLE_SIP_CHANNEL_ERROR:
ev.transport=belle_sip_channel_get_transport_name(chan);
ev.source=BELLE_SIP_OBJECT(t);
ev.port=chan->peer_port;
ev.host=chan->peer_name;
BELLE_SIP_PROVIDER_INVOKE_LISTENERS_FOR_TRANSACTION(((belle_sip_transaction_t*)t),process_io_error,&ev);
if (belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(t))!=BELLE_SIP_TRANSACTION_COMPLETED
&& belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(t))!=BELLE_SIP_TRANSACTION_CONFIRMED
&& belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(t))!=BELLE_SIP_TRANSACTION_ACCEPTED
&& belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(t))!=BELLE_SIP_TRANSACTION_TERMINATED) {
BELLE_SIP_PROVIDER_INVOKE_LISTENERS_FOR_TRANSACTION(((belle_sip_transaction_t*)t),process_io_error,&ev);
}
if (belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(t))!=BELLE_SIP_TRANSACTION_TERMINATED) /*avoid double notification*/
belle_sip_transaction_terminate(BELLE_SIP_TRANSACTION(t));
break;
default:
/*ignored*/
......
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