Exemplo n.º 1
0
belle_sip_hop_t * belle_sip_stack_get_next_hop(belle_sip_stack_t *stack, belle_sip_request_t *req) {
	belle_sip_header_route_t *route=BELLE_SIP_HEADER_ROUTE(belle_sip_message_get_header(BELLE_SIP_MESSAGE(req),"route"));
	belle_sip_uri_t *uri;

	if (route!=NULL){
		uri=belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(route));
	}else{
		uri=belle_sip_request_get_uri(req);
	}
	return belle_sip_hop_new_from_uri(uri);
}
Exemplo n.º 2
0
int belle_sip_client_transaction_send_request_to(belle_sip_client_transaction_t *t,belle_sip_uri_t* outbound_proxy) {
	belle_sip_channel_t *chan;
	belle_sip_provider_t *prov=t->base.provider;
	belle_sip_dialog_t *dialog=t->base.dialog;
	belle_sip_request_t *req=t->base.request;
	int result=-1;

	if (t->base.state!=BELLE_SIP_TRANSACTION_INIT){
		belle_sip_error("belle_sip_client_transaction_send_request: bad state.");
		return -1;
	}

	/*check uris components compliance*/
	if (!belle_sip_request_check_uris_components(t->base.request)) {
		belle_sip_error("belle_sip_client_transaction_send_request: bad request for transaction [%p]",t);
		return -1;
	}
	/*store preset route for future use by refresher*/
	if (outbound_proxy){
		t->preset_route=outbound_proxy;
		belle_sip_object_ref(t->preset_route);
	}

	if (t->base.sent_by_dialog_queue){
		
		/*it can be sent immediately, so update the request with latest cseq and route_set */
		/*update route and contact just in case they changed*/
		belle_sip_dialog_update_request(dialog,req);
	} else if (t->base.request->dialog_queued){
		/*this request was created by belle_sip_dialog_create_queued_request().*/
		if (belle_sip_dialog_request_pending(dialog) || dialog->queued_ct!=NULL){
			/*it cannot be sent immediately, queue the transaction into dialog*/
			belle_sip_message("belle_sip_client_transaction_send_request(): transaction [%p], cannot send request now because dialog is busy"
			" or other transactions are queued, so queuing into dialog.",t);
			belle_sip_dialog_queue_client_transaction(dialog,t);
			return 0;
		}
		belle_sip_dialog_update_request(dialog,req);
	}

	if (dialog){
		belle_sip_dialog_update(dialog,(belle_sip_transaction_t*)t,BELLE_SIP_OBJECT_IS_INSTANCE_OF(t,belle_sip_server_transaction_t));
	}

	if (!t->next_hop) {
		if (t->preset_route) {
			t->next_hop=belle_sip_hop_new_from_uri(t->preset_route);
		} else {
			t->next_hop = belle_sip_stack_get_next_hop(prov->stack,t->base.request);
		}
		belle_sip_object_ref(t->next_hop);
	} else {
		/*next hop already preset, probably in case of CANCEL*/
	}
	belle_sip_provider_add_client_transaction(t->base.provider,t); /*add it in any case*/
	chan=belle_sip_provider_get_channel(prov,t->next_hop);
	if (chan){
		belle_sip_object_ref(chan);
		belle_sip_channel_add_listener(chan,BELLE_SIP_CHANNEL_LISTENER(t));
		t->base.channel=chan;
		if (belle_sip_channel_get_state(chan)==BELLE_SIP_CHANNEL_INIT){
			belle_sip_message("belle_sip_client_transaction_send_request(): waiting channel to be ready");
			belle_sip_channel_prepare(chan);
			/*the channel will notify us when it is ready*/
		} else if (belle_sip_channel_get_state(chan)==BELLE_SIP_CHANNEL_READY){
			/*otherwise we can send immediately*/
			BELLE_SIP_OBJECT_VPTR(t,belle_sip_client_transaction_t)->send_request(t);
		}
		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;
	}
	return result;
}