static void notify_timeout(belle_sip_transaction_t *t){
	belle_sip_timeout_event_t ev;
	ev.source=(belle_sip_object_t*)t->provider;
	ev.transaction=t;
	ev.is_server_transaction=BELLE_SIP_OBJECT_IS_INSTANCE_OF(t,belle_sip_server_transaction_t);
	BELLE_SIP_PROVIDER_INVOKE_LISTENERS_FOR_TRANSACTION(t,process_timeout,&ev);
}
static void server_transaction_notify(belle_sip_server_transaction_t *t, belle_sip_request_t *req, belle_sip_dialog_t *dialog){
	belle_sip_request_event_t event;

	event.source=(belle_sip_object_t*)t->base.provider;
	event.server_transaction=t;
	event.dialog=dialog;
	event.request=req;
	BELLE_SIP_PROVIDER_INVOKE_LISTENERS_FOR_TRANSACTION(((belle_sip_transaction_t*) t),process_request_event,&event);
}
Exemple #3
0
void belle_sip_client_transaction_notify_response(belle_sip_client_transaction_t *t, belle_sip_response_t *resp){
	belle_sip_transaction_t *base=(belle_sip_transaction_t*)t;
	belle_sip_request_t* req = belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(t));
	const char* method = belle_sip_request_get_method(req);
	belle_sip_response_event_t event;
	belle_sip_dialog_t *dialog=base->dialog;
	int status_code =  belle_sip_response_get_status_code(resp);
	if (base->last_response)
		belle_sip_object_unref(base->last_response);
	base->last_response=(belle_sip_response_t*)belle_sip_object_ref(resp);

	if (dialog){
		if (status_code>=101 && status_code<300
			&& strcmp(method,"INVITE")==0
			&& (dialog->state==BELLE_SIP_DIALOG_EARLY || dialog->state==BELLE_SIP_DIALOG_CONFIRMED)){
			/*make sure this response matches the current dialog, or creates a new one*/
			if (!belle_sip_dialog_match(dialog,(belle_sip_message_t*)resp,FALSE)){
				dialog=belle_sip_provider_find_dialog_from_message(t->base.provider,(belle_sip_message_t*)resp,FALSE);
				if (!dialog){
					dialog=belle_sip_provider_create_dialog_internal(t->base.provider,BELLE_SIP_TRANSACTION(t),FALSE);/*belle_sip_dialog_new(base);*/
					belle_sip_message("Handling response creating a new dialog !");
				}
			}
		}
	} else if (should_dialog_be_created(t,resp)) {
		dialog=belle_sip_provider_create_dialog_internal(t->base.provider,BELLE_SIP_TRANSACTION(t),FALSE);
	}

	if (dialog && belle_sip_dialog_update(dialog,BELLE_SIP_TRANSACTION(t),FALSE)) {
		/* retransmition, just return*/
		belle_sip_message("[%p] is a 200 ok retransmition on dialog [%p], skiping",resp,dialog);
		return;
	}

	event.source=(belle_sip_object_t*)base->provider;
	event.client_transaction=t;
	event.dialog=dialog;
	event.response=(belle_sip_response_t*)resp;
	BELLE_SIP_PROVIDER_INVOKE_LISTENERS_FOR_TRANSACTION(((belle_sip_transaction_t*)t),process_response_event,&event);
	/*check that 200Ok for INVITEs have been acknowledged by listener*/
	if (dialog && strcmp(method,"INVITE")==0){
		belle_sip_dialog_check_ack_sent(dialog);
	}
	/*report a server having internal errors for REGISTER to the channel, in order to go to a fallback IP*/
	if (status_code == 500 && strcmp(method,"REGISTER") == 0){
		belle_sip_channel_notify_server_error(base->channel);
	}
}
Exemple #4
0
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;
	belle_sip_transaction_state_t tr_state=belle_sip_transaction_get_state((belle_sip_transaction_t*)t);

	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:
			if (tr_state==BELLE_SIP_TRANSACTION_INIT && BELLE_SIP_OBJECT_IS_INSTANCE_OF(t,belle_sip_client_transaction_t) ){
				belle_sip_client_transaction_t *ct = (belle_sip_client_transaction_t*) t;
				BELLE_SIP_OBJECT_VPTR(ct,belle_sip_client_transaction_t)->send_request(ct);
			}
		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;
			if ( tr_state!=BELLE_SIP_TRANSACTION_COMPLETED
				&& tr_state!=BELLE_SIP_TRANSACTION_CONFIRMED
				&& tr_state!=BELLE_SIP_TRANSACTION_ACCEPTED
				&& tr_state!=BELLE_SIP_TRANSACTION_TERMINATED) {
				BELLE_SIP_PROVIDER_INVOKE_LISTENERS_FOR_TRANSACTION(((belle_sip_transaction_t*)t),process_io_error,&ev);
			}
			if (t->timed_out)
				notify_timeout((belle_sip_transaction_t*)t);

			belle_sip_transaction_terminate(t);
		break;
		default:
			/*ignored*/
		break;
	}
}