コード例 #1
0
ファイル: nict.c プロジェクト: rogerhzh/bellesip_XIA
static int nict_on_timer_E(belle_sip_nict_t *obj){
	belle_sip_transaction_t *base=(belle_sip_transaction_t*)obj;
	const belle_sip_timer_config_t *cfg=belle_sip_transaction_get_timer_config(base);

	switch(base->state){
		case BELLE_SIP_TRANSACTION_TRYING:
		{
			/*reset the timer */
			unsigned int prev_timeout=belle_sip_source_get_timeout(obj->timer_E);
			belle_sip_source_set_timeout(obj->timer_E,MIN(2*prev_timeout,(unsigned int)cfg->T2));
			belle_sip_message("nict_on_timer_E: sending retransmission");
			belle_sip_channel_queue_message(base->channel,(belle_sip_message_t*)base->request);
		}
		break;
		case BELLE_SIP_TRANSACTION_PROCEEDING:
			belle_sip_source_set_timeout(obj->timer_E,cfg->T2);
			belle_sip_message("nict_on_timer_E: sending retransmission");
			belle_sip_channel_queue_message(base->channel,(belle_sip_message_t*)base->request);
		break;
		default:
			/*if we are not in these cases, timer_E does nothing, so remove it*/
			return BELLE_SIP_STOP;
		break;
	}
	return BELLE_SIP_CONTINUE;
}
コード例 #2
0
ファイル: cast_test.c プロジェクト: smking1122/heqinphone
static void cast_test(void) {
    belle_sip_stack_t *stack=belle_sip_stack_new(NULL);
    belle_sip_listening_point_t *lp=belle_sip_stack_create_listening_point(stack,"0.0.0.0",7060,"UDP");
    belle_sip_provider_t *provider;
    belle_sip_request_t *req=belle_sip_request_new();
    belle_sip_response_t *resp=belle_sip_response_new();
    belle_sip_message_t *msg;
    int tmp;

    BC_ASSERT_PTR_NOT_NULL(stack);
    BC_ASSERT_PTR_NOT_NULL(lp);
    provider=belle_sip_stack_create_provider(stack,lp);
    BC_ASSERT_PTR_NOT_NULL(provider);
    BC_ASSERT_PTR_NOT_NULL(req);
    BC_ASSERT_PTR_NOT_NULL(resp);

    belle_sip_message("Casting belle_sip_request_t to belle_sip_message_t");
    msg=BELLE_SIP_MESSAGE(req);
    BC_ASSERT_PTR_NOT_NULL(msg);
    belle_sip_message("Ok.");
    belle_sip_message("Casting belle_sip_response_t to belle_sip_message_t");
    msg=BELLE_SIP_MESSAGE(resp);
    BC_ASSERT_PTR_NOT_NULL(msg);
    belle_sip_message("Ok.");
    tmp=BELLE_SIP_IS_INSTANCE_OF(req,belle_sip_response_t);
    belle_sip_message("Casting belle_sip_request_t to belle_sip_response_t: %s",tmp ? "yes" : "no");
    BC_ASSERT_EQUAL(tmp,0,int,"%d");
    belle_sip_object_unref(req);
    belle_sip_object_unref(resp);
    belle_sip_object_unref(provider);
    belle_sip_object_unref(stack);
}
コード例 #3
0
static void caller_process_response_event(void *user_ctx, const belle_sip_response_event_t *event){
	belle_sip_client_transaction_t* client_transaction = belle_sip_response_event_get_client_transaction(event);
	belle_sip_header_from_t* from=belle_sip_message_get_header_by_type(belle_sip_response_event_get_response(event),belle_sip_header_from_t);
	belle_sip_header_cseq_t* invite_cseq=belle_sip_message_get_header_by_type(belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(client_transaction)),belle_sip_header_cseq_t);
	belle_sip_request_t* ack;
	belle_sip_dialog_t* dialog;
	int status;
	if (!belle_sip_uri_equals(BELLE_SIP_URI(user_ctx),belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(from)))) {
		belle_sip_message("Message [%p] not for caller, skipping",belle_sip_response_event_get_response(event));
		return; /*not for the caller*/
	}

	status = belle_sip_response_get_status_code(belle_sip_response_event_get_response(event));
	belle_sip_message("caller_process_response_event [%i]",status);
	if (BC_ASSERT_PTR_NOT_NULL(client_transaction)) {
		dialog = belle_sip_transaction_get_dialog(BELLE_SIP_TRANSACTION(client_transaction));
		if (BC_ASSERT_PTR_NOT_NULL(dialog)) {
			BC_ASSERT_PTR_EQUAL(caller_dialog,dialog);
			if (belle_sip_dialog_get_state(dialog) == BELLE_SIP_DIALOG_NULL) {
				BC_ASSERT_EQUAL(status,100, int, "%d");
			} else if (belle_sip_dialog_get_state(dialog) == BELLE_SIP_DIALOG_EARLY){
				BC_ASSERT_EQUAL(status,180, int, "%d");
				/*send 200ok from callee*/
				belle_sip_server_transaction_send_response(inserv_transaction,ok_response);
				belle_sip_object_unref(ok_response);
				ok_response=NULL;
			} else if (belle_sip_dialog_get_state(dialog) == BELLE_SIP_DIALOG_CONFIRMED) {
コード例 #4
0
ファイル: refresher.c プロジェクト: MorphyMac/belle-sip
static int is_contact_address_acurate(const belle_sip_refresher_t* refresher,belle_sip_request_t* request) {
	belle_sip_header_contact_t* contact;
	if ((contact = get_first_contact_in_unknown_state(request))){
		/*check if contact ip/port is consistant with  public channel ip/port*/
		int channel_public_port = refresher->transaction->base.channel->public_port;
		int contact_port = belle_sip_uri_get_listening_port(belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(contact)));
		const char* channel_public_ip = refresher->transaction->base.channel->public_ip;
		const char* contact_ip = belle_sip_uri_get_host(belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(contact)));

		if (channel_public_port == contact_port
				&& channel_public_ip && contact_ip
				&& strcmp(channel_public_ip,contact_ip) == 0) {
			/*nothing to do contact is accurate*/
			belle_sip_header_contact_set_unknown(contact,FALSE);
			return TRUE;
		} else {
			belle_sip_message("Refresher [%p]: contact address [%s:%i] does not match channel address[%s:%i] on channel [%p]"	,refresher
					,contact_ip
					,contact_port
					,channel_public_ip
					,channel_public_port
					,refresher->transaction->base.channel);
			return FALSE;
		}
	} else {
		belle_sip_message("Refresher [%p]:  has no contact for request [%p].", refresher,request);
		return TRUE;
	}
}
コード例 #5
0
ファイル: channel.c プロジェクト: fremaks/linphone_sdk
static int acquire_chuncked_body(belle_sip_channel_t *obj){
	belle_sip_channel_input_stream_t *st=&obj->input_stream;
	int readsize;
	do{
		if (st->chunk_size==-1){
			char *tmp;
			/*belle_sip_message("seeing: %s",st->read_ptr);*/
			while ( (tmp=strstr(st->read_ptr,"\r\n"))==st->read_ptr){/*skip \r\n*/
				st->read_ptr+=2;
			}

			if (tmp!=NULL){
				/*the chunk length is there*/
				long chunksize=strtol(st->read_ptr,NULL,16);
				if (chunksize>=0 && chunksize!=LONG_MAX){
					if (chunksize==0){
						belle_sip_message("Got end of chunked body");
						st->read_ptr=tmp+4; /*last chunk indicator finishes with two \r\n*/
						if (st->read_ptr>st->write_ptr) st->read_ptr=st->write_ptr;
						belle_sip_channel_message_ready(obj);
						return BELLE_SIP_CONTINUE;
					}else{
						belle_sip_message("Will get a chunk of %i bytes",(int)chunksize);
						st->chunk_size=chunksize;
						st->chunk_read_size=0;
						st->read_ptr=tmp+2;
					}
				}else{
					belle_sip_error("Chunk parse error");
					belle_sip_channel_input_stream_reset(st);
					return BELLE_SIP_CONTINUE;
				}
			}else{
				/*need more data*/
				return BELLE_SIP_STOP;
			}
		}
		readsize=MIN(st->write_ptr-st->read_ptr,st->chunk_size-st->chunk_read_size);
		if (readsize>0){
			feed_body(obj,readsize);
			st->chunk_read_size+=readsize;
		}
		if (st->chunk_size==st->chunk_read_size){
			/*we have a chunk completed*/
			st->content_length+=st->chunk_size;
			belle_sip_message("Chunk of [%i] bytes completed",st->chunk_size);
			st->chunk_size=-1;/*wait for next chunk indicator*/
		}else{
			/*need more data*/
			return BELLE_SIP_STOP;
		}
	}while(st->write_ptr-st->read_ptr>0); /*no need to continue if nothing to read*/
	return BELLE_SIP_STOP;
}
コード例 #6
0
ファイル: dialog.c プロジェクト: natib/belle-sip
int belle_sip_dialog_handle_ack(belle_sip_dialog_t *obj, belle_sip_request_t *ack){
	belle_sip_header_cseq_t *cseq=belle_sip_message_get_header_by_type(ack,belle_sip_header_cseq_t);
	if (obj->needs_ack && belle_sip_header_cseq_get_seq_number(cseq)==obj->remote_cseq){
		belle_sip_message("Incoming INVITE has ACK, dialog is happy");
		obj->needs_ack=FALSE;
		belle_sip_dialog_stop_200Ok_retrans(obj);
		belle_sip_dialog_process_queue(obj);
		return 0;
	}
	belle_sip_message("Dialog ignoring incoming ACK (surely a retransmission)");
	return -1;
}
コード例 #7
0
int belle_sip_tls_listening_point_set_root_ca(belle_sip_tls_listening_point_t *lp, const char *path){
	if (lp->root_ca){
		belle_sip_free(lp->root_ca);
		lp->root_ca=NULL;
	}
	if (path){
		lp->root_ca=belle_sip_strdup(path);
		belle_sip_message("Root ca path set to %s",lp->root_ca);
	} else {
		belle_sip_message("Root ca path disabled");
	}
	return 0;
}
コード例 #8
0
ファイル: auth_event.c プロジェクト: Distrotech/belle-sip
int belle_tls_verify_policy_set_root_ca(belle_tls_verify_policy_t *obj, const char *path){
	if (obj->root_ca){
		belle_sip_free(obj->root_ca);
		obj->root_ca=NULL;
	}
	if (path){
		obj->root_ca=belle_sip_strdup(path);
		belle_sip_message("Root ca path set to %s",obj->root_ca);
	} else {
		belle_sip_message("Root ca path disabled");
	}
	return 0;
}
コード例 #9
0
void belle_sip_object_dump_active_objects(void){
	belle_sip_list_t *elem;
	
	if (all_objects){
		belle_sip_message("List of leaked objects:");
		for(elem=all_objects;elem!=NULL;elem=elem->next){
			belle_sip_object_t *obj=(belle_sip_object_t*)elem->data;
			char* content= belle_sip_object_to_string(obj);
			belle_sip_message("%s(%p) ref=%i, content [%10s...]",obj->vptr->type_name,obj,obj->ref,content);
			belle_sip_free(content);
		}
	}else belle_sip_message("No objects leaked.");
}
コード例 #10
0
ファイル: dialog.c プロジェクト: natib/belle-sip
/*
 * return 0 if dialog handle the 200ok
 * */
static int belle_sip_dialog_handle_200Ok(belle_sip_dialog_t *obj, belle_sip_response_t *msg){
	if (obj->last_out_ack){
		belle_sip_header_cseq_t *cseq=belle_sip_message_get_header_by_type(msg,belle_sip_header_cseq_t);
		if (cseq){
			belle_sip_header_cseq_t *ack_cseq=belle_sip_message_get_header_by_type(obj->last_out_ack,belle_sip_header_cseq_t);
			if (belle_sip_header_cseq_get_seq_number(cseq)==belle_sip_header_cseq_get_seq_number(ack_cseq)){
				/*pass for retransmission*/
				belle_sip_message("Dialog retransmitting last ack automatically");
				belle_sip_provider_send_request(obj->provider,obj->last_out_ack);
				return 0;
			}else belle_sip_message("No already created ACK matching 200Ok for dialog [%p]",obj);
		}
	}
	return -1;
}
コード例 #11
0
ファイル: transaction.c プロジェクト: dnduc789/submodules
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);
	}
}
コード例 #12
0
ファイル: channel.c プロジェクト: fremaks/linphone_sdk
static int send_buffer(belle_sip_channel_t *obj, const char *buffer, size_t size){
	int ret=0;
	char *logbuf=NULL;

	if (obj->stack->send_error == 0){
		ret=belle_sip_channel_send(obj,buffer,size);
	}else if (obj->stack->send_error<0){
		/*for testing purpose only */
		ret=obj->stack->send_error;
	} else {
		ret=size; /*to silently discard message*/
	}

	if (ret<0){
		if (!belle_sip_error_code_is_would_block(-ret)){
			belle_sip_error("channel [%p]: could not send [%i] bytes from [%s://%s:%i] to [%s:%i]"	,obj
				,(int)size
				,belle_sip_channel_get_transport_name(obj)
				,obj->local_ip
				,obj->local_port
				,obj->peer_name
				,obj->peer_port);
			channel_set_state(obj,BELLE_SIP_CHANNEL_ERROR);
		}/*ewouldblock error has to be handled by caller*/
	}else if (size==(size_t)ret){
		logbuf=make_logbuf(BELLE_SIP_LOG_MESSAGE, buffer,size);
		belle_sip_message("channel [%p]: message %s to [%s://%s:%i], size: [%i] bytes\n%s"
							,obj
							,obj->stack->send_error==0?"sent":"silently discarded"
							,belle_sip_channel_get_transport_name(obj)
							,obj->peer_name
							,obj->peer_port
							,ret
							,logbuf);
	}else{
		logbuf=make_logbuf(BELLE_SIP_LOG_MESSAGE,buffer,ret);
		belle_sip_message("channel [%p]: message partly sent to [%s://%s:%i], sent: [%i/%i] bytes:\n%s"
							,obj
							,belle_sip_channel_get_transport_name(obj)
							,obj->peer_name
							,obj->peer_port
							,ret
							,(int)size
							,logbuf);
	}
	if (logbuf) belle_sip_free(logbuf);
	return ret;
}
コード例 #13
0
ファイル: channel.c プロジェクト: PeterXu/sipstack
static void queue_message_delayed(belle_sip_channel_t *obj, belle_sip_message_t *msg){
	delay_send_t *ctx=belle_sip_malloc(sizeof(delay_send_t));
	ctx->chan=(belle_sip_channel_t*)belle_sip_object_ref(obj);
	ctx->msg=(belle_sip_message_t*)belle_sip_object_ref(msg);
	belle_sip_main_loop_add_timeout(obj->stack->ml,(belle_sip_source_func_t)on_delayed_send_do,ctx,obj->stack->tx_delay);
	belle_sip_message("channel %p: message sending delayed by %i ms",obj,obj->stack->tx_delay);
}
コード例 #14
0
static void test_overflow(void){
	belle_sdp_session_description_t* sdp;
	belle_sip_list_t *mds;
	belle_sdp_media_description_t *vmd;
	int i;
	const size_t orig_buffsize=1024;
	size_t buffsize=orig_buffsize;
	char *buffer=belle_sip_malloc0(buffsize);
	size_t offset=0;
	
	sdp=belle_sdp_session_description_parse(big_sdp);
	CU_ASSERT_PTR_NOT_NULL(sdp);
	mds=belle_sdp_session_description_get_media_descriptions(sdp);
	CU_ASSERT_PTR_NOT_NULL(mds);
	CU_ASSERT_PTR_NOT_NULL(mds->next);
	vmd=(belle_sdp_media_description_t*)mds->next->data;
	for(i=0;i<16;i++){
		belle_sdp_media_description_add_attribute(vmd,belle_sdp_attribute_create("candidate","2 1 UDP 1694498815 82.65.223.97 9078 typ srflx raddr 192.168.0.2 rport 9078"));
	}

	CU_ASSERT_EQUAL(belle_sip_object_marshal(BELLE_SIP_OBJECT(sdp),buffer,buffsize,&offset),BELLE_SIP_BUFFER_OVERFLOW);
	belle_sip_message("marshal size is %i",(int)offset);
	CU_ASSERT_TRUE(offset==buffsize);
	belle_sip_object_unref(sdp);
	belle_sip_free(buffer);
}
コード例 #15
0
ファイル: channel.c プロジェクト: fremaks/linphone_sdk
static int acquire_body_simple(belle_sip_channel_t *obj, int end_of_stream){
	int content_length=obj->input_stream.content_length;
	size_t to_read=obj->input_stream.write_ptr-obj->input_stream.read_ptr;
	belle_sip_message_t *msg=obj->input_stream.msg;
	belle_sip_body_handler_t *bh=belle_sip_message_get_body_handler(msg);
	size_t cursize=belle_sip_body_handler_get_transfered_size(bh);

	if ((cursize == 0) && (to_read == 0)) {
		/**
		 * No data has been received yet, so do not call feed_body() with a size
		 * of 0 that is meaning that the transfer is finished.
		 */
	} else {
		to_read=MIN(content_length-cursize, to_read);
		feed_body(obj,to_read);
	}

	if (end_of_stream ||  belle_sip_body_handler_get_transfered_size(bh)>=content_length){
		/*great body completed*/
		belle_sip_message("channel [%p] read [%i] bytes of body from [%s:%i]"	,obj
			,content_length
			,obj->peer_name
			,obj->peer_port);
		belle_sip_channel_message_ready(obj);
		return BELLE_SIP_CONTINUE;
	}
	/*body is not finished, we need more data*/
	return BELLE_SIP_STOP;
}
コード例 #16
0
static void client_process_auth_requested(void *obj, belle_sip_auth_event_t *event){
	BELLESIP_UNUSED(obj);
	belle_sip_message("process_auth_requested requested for [%s@%s]"
			,belle_sip_auth_event_get_username(event)
			,belle_sip_auth_event_get_realm(event));
	belle_sip_auth_event_set_passwd(event,PASSWD);
}
コード例 #17
0
static void client_process_response_event(void *obj, const belle_sip_response_event_t *event){
	//belle_sip_client_transaction_t* client_transaction = belle_sip_response_event_get_client_transaction(event);
	endpoint_t* endpoint = (endpoint_t*)obj;
	int status = belle_sip_response_get_status_code(belle_sip_response_event_get_response(event));
	belle_sip_message("caller_process_response_event [%i]",status);
	switch (status) {
	case 200:
		endpoint->stat.twoHundredOk++;
		if (endpoint->connection_family!=AF_UNSPEC){
			const char *host;
			int family_found;
			belle_sip_header_contact_t *ct=belle_sip_message_get_header_by_type(
				(belle_sip_message_t*)belle_sip_response_event_get_response(event),belle_sip_header_contact_t);
			CU_ASSERT_PTR_NOT_NULL_FATAL(ct);
			host=belle_sip_uri_get_host(belle_sip_header_address_get_uri((belle_sip_header_address_t*)ct));
			if (strchr(host,':')) family_found=AF_INET6;
			else family_found=AF_INET;
			CU_ASSERT_TRUE(family_found==endpoint->connection_family);
		}
		break;
	case 401:endpoint->stat.fourHundredOne++; break;
	default: break;
	}


}
コード例 #18
0
ファイル: channel.c プロジェクト: PeterXu/sipstack
static void channel_end_recv_background_task(belle_sip_channel_t *obj){
	if (obj->recv_bg_task_id){
		belle_sip_message("channel [%p]: ending recv background task with id=[%x].",obj,obj->recv_bg_task_id);
		belle_sip_end_background_task(obj->recv_bg_task_id);
		obj->recv_bg_task_id=0;
	}
}
コード例 #19
0
ファイル: listeningpoint.c プロジェクト: Distrotech/belle-sip
static int send_keep_alive(belle_sip_channel_t* obj) {
	/*keep alive*/
	const char* crlfcrlf = "\r\n\r\n";
	int size=strlen(crlfcrlf);
	int err=belle_sip_channel_send(obj,crlfcrlf,size);
	
	if (err<=0 && !belle_sip_error_code_is_would_block(-err) && err!=-EINTR){
		belle_sip_error("channel [%p]: could not send [%i] bytes of keep alive from [%s://%s:%i]  to [%s:%i]"	,obj
			,size
			,belle_sip_channel_get_transport_name(obj)
			,obj->local_ip
			,obj->local_port
			,obj->peer_name
			,obj->peer_port);

		return -1;
	}else{
		belle_sip_message("channel [%p]: keep alive sent to [%s://%s:%i]"
							,obj
							,belle_sip_channel_get_transport_name(obj)
							,obj->peer_name
							,obj->peer_port);
		return 0;
	}
}
コード例 #20
0
ファイル: refresher.c プロジェクト: MorphyMac/belle-sip
belle_sip_refresher_t* belle_sip_refresher_new(belle_sip_client_transaction_t* transaction) {
	belle_sip_refresher_t* refresher;
	belle_sip_transaction_state_t state=belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(transaction));
	belle_sip_request_t* request = belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(transaction));
	int is_register=strcmp("REGISTER",belle_sip_request_get_method(request))==0;

	refresher = (belle_sip_refresher_t*)belle_sip_object_new(belle_sip_refresher_t);
	refresher->transaction=transaction;
	refresher->state=stopped;
	refresher->number_of_retry=0;
	belle_sip_object_ref(transaction);
	refresher->retry_after=DEFAULT_RETRY_AFTER;

	if (belle_sip_transaction_get_dialog(BELLE_SIP_TRANSACTION(transaction))) {
		set_or_update_dialog(refresher, belle_sip_transaction_get_dialog(BELLE_SIP_TRANSACTION(transaction)));
	}
	belle_sip_provider_add_internal_sip_listener(transaction->base.provider,BELLE_SIP_LISTENER(refresher), is_register);
	if (set_expires_from_trans(refresher)==-1){
		belle_sip_error("Unable to extract refresh value from transaction [%p]",transaction);
	}
	if (belle_sip_transaction_state_is_transient(state)) {
		belle_sip_message("Refresher [%p] takes ownership of transaction [%p]",refresher,transaction);
		transaction->base.is_internal=1;
		refresher->state=started;
	}else{
		belle_sip_refresher_start(refresher);
	}
	return refresher;
}
コード例 #21
0
ファイル: channel.c プロジェクト: fremaks/linphone_sdk
static int belle_sip_channel_process_read_data(belle_sip_channel_t *obj){
	int num;
	int ret=BELLE_SIP_CONTINUE;

	/*prevent system to suspend the process until we have finish reading everything from the socket and notified the upper layer*/
	if (obj->input_stream.state == WAITING_MESSAGE_START)
		channel_begin_recv_background_task(obj);

	if (obj->simulated_recv_return>0) {
		num=belle_sip_channel_recv(obj,obj->input_stream.write_ptr,belle_sip_channel_input_stream_get_buff_length(&obj->input_stream)-1);
	} else {
		belle_sip_message("channel [%p]: simulating recv() returning %i",obj,obj->simulated_recv_return);
		num=obj->simulated_recv_return;
	}
	if (num>0){
		char *begin=obj->input_stream.write_ptr;
		char *logbuf=make_logbuf(BELLE_SIP_LOG_MESSAGE,begin,num);
		obj->input_stream.write_ptr+=num;
		/*first null terminate the read buff*/
		*obj->input_stream.write_ptr='\0';
		if (num>20) /*to avoid tracing server based keep alives*/
			belle_sip_message("channel [%p]: received [%i] new bytes from [%s://%s:%i]:\n%s",
					obj,
					num,
					belle_sip_channel_get_transport_name(obj),
					obj->peer_name,
					obj->peer_port,
					logbuf);
		belle_sip_free(logbuf);
		belle_sip_channel_process_stream(obj,FALSE);
	} else if (num == 0) {
		/*before closing the channel, check if there was a pending message to receive, whose body acquisition is to be finished.*/
		belle_sip_channel_process_stream(obj,TRUE);
		channel_set_state(obj,BELLE_SIP_CHANNEL_DISCONNECTED);
		ret=BELLE_SIP_STOP;
	} else if (belle_sip_error_code_is_would_block(-num)){
		belle_sip_message("channel [%p]: recv() EWOULDBLOCK",obj);
		ret=BELLE_SIP_CONTINUE;
	}else{
		belle_sip_error("Receive error on channel [%p]",obj);
		channel_set_state(obj,BELLE_SIP_CHANNEL_ERROR);
		ret=BELLE_SIP_STOP;
	}
	if (obj->input_stream.state == WAITING_MESSAGE_START)
		channel_end_recv_background_task(obj);
	return ret;
}
コード例 #22
0
ファイル: refresher.c プロジェクト: gijung00/belle-sip
static int set_expires_from_trans(belle_sip_refresher_t* refresher) {
	belle_sip_transaction_t* transaction = BELLE_SIP_TRANSACTION(refresher->transaction);
	belle_sip_response_t*response=transaction->last_response;
	belle_sip_request_t*request=belle_sip_transaction_get_request(transaction);
	belle_sip_header_expires_t*  expires_header=belle_sip_message_get_header_by_type(request,belle_sip_header_expires_t);
	belle_sip_header_contact_t* contact_header;

	refresher->obtained_expires=-1;

	if (strcmp("REGISTER",belle_sip_request_get_method(request))==0
			|| expires_header /*if request has an expire header, refresher can always work*/) {

		if (expires_header)
			refresher->target_expires = belle_sip_header_expires_get_expires(expires_header);

		/*An "expires" parameter on the "Contact" header has no semantics for
		*   SUBSCRIBE and is explicitly not equivalent to an "Expires" header in
		*  a SUBSCRIBE request or response.
		*/
		if (strcmp("REGISTER",belle_sip_request_get_method(request))==0){
			if (!expires_header && (contact_header=belle_sip_message_get_header_by_type((belle_sip_message_t*)request,belle_sip_header_contact_t))){
				int ct_expires=belle_sip_header_contact_get_expires(BELLE_SIP_HEADER_CONTACT(contact_header));
				if (ct_expires!=-1) refresher->target_expires=ct_expires;
			}
			/*check in response also to get the obtained expires*/
			if ((contact_header=belle_sip_refresher_get_contact(refresher))!=NULL){
				/*matching contact, check for its possible expires param*/
				refresher->obtained_expires=belle_sip_header_contact_get_expires(BELLE_SIP_HEADER_CONTACT(contact_header));
			}
		}
		if (refresher->obtained_expires==-1){
			/*no contact with expire or not relevant, looking for Expires header*/
			if (response && (expires_header=(belle_sip_header_expires_t*)belle_sip_message_get_header(BELLE_SIP_MESSAGE(response),BELLE_SIP_EXPIRES))) {
				refresher->obtained_expires = belle_sip_header_expires_get_expires(expires_header);
			}
		}
		if (refresher->obtained_expires==-1) {
			belle_sip_message("Neither Expires header nor corresponding Contact header found, checking from original request");
			refresher->obtained_expires=refresher->target_expires;
		}else if (refresher->target_expires>0 && refresher->obtained_expires==0){
			const char* reason = response ? belle_sip_response_get_reason_phrase(response) : NULL;
			/*check this case because otherwise we are going to loop fast in sending refresh requests.*/
			/*"Test account created" is a special reason given by testers when we create temporary account.
			Since this is a bit of hack, we can ignore logging in that case*/
			if (reason && strcmp(reason, "Test account created") != 0) {
				belle_sip_warning("Server replied with 0 expires, what does that mean?");
			}
			/*suppose it's a server bug and assume our target_expires is understood.*/
			refresher->obtained_expires=refresher->target_expires;
		}
	} else if (strcmp("INVITE",belle_sip_request_get_method(request))==0) {
		belle_sip_error("Refresher does not support INVITE yet");
		return -1;
	} else {
		belle_sip_error("Refresher does not support [%s] yet",belle_sip_request_get_method(request));
		return -1;
	}
	return 0;
}
コード例 #23
0
static void process_io_error(void *user_ctx, const belle_sip_io_error_event_t *event){
	BELLESIP_UNUSED(user_ctx);
	BELLESIP_UNUSED(event);
	belle_sip_message("process_io_error, exiting main loop");
	belle_sip_main_loop_quit(belle_sip_stack_get_main_loop(stack));
	io_error_count++;
	/*CU_ASSERT(CU_FALSE);*/
}
コード例 #24
0
static void callee_process_request_event(void *user_ctx, const belle_sip_request_event_t *event) {
	belle_sip_dialog_t* dialog;
	belle_sip_response_t* ringing_response;
	belle_sip_header_content_type_t* content_type ;
	belle_sip_header_content_length_t* content_length;
	belle_sip_server_transaction_t* server_transaction = belle_sip_request_event_get_server_transaction(event);
	belle_sip_header_to_t* to=belle_sip_message_get_header_by_type(belle_sip_request_event_get_request(event),belle_sip_header_to_t);
	const char* method;
	if (!belle_sip_uri_equals(BELLE_SIP_URI(user_ctx),belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(to)))) {
		belle_sip_message("Message [%p] not for callee, skipping",belle_sip_request_event_get_request(event));
		return; /*not for the callee*/
	}
	method = belle_sip_request_get_method(belle_sip_request_event_get_request(event));
	if (!server_transaction && strcmp(method,"ACK")!=0) {
		server_transaction= belle_sip_provider_create_server_transaction(prov,belle_sip_request_event_get_request(event));
	}

	belle_sip_message("callee_process_request_event received [%s] message",method);
	dialog = belle_sip_request_event_get_dialog(event);
	if (!dialog ) {
		BC_ASSERT_STRING_EQUAL_FATAL("INVITE",method);
		dialog=belle_sip_provider_create_dialog(prov,BELLE_SIP_TRANSACTION(server_transaction));
		callee_dialog=dialog;
		inserv_transaction=server_transaction;
	}
	if (belle_sip_dialog_get_state(dialog) == BELLE_SIP_DIALOG_NULL) {
		ringing_response = belle_sip_response_create_from_request(belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(server_transaction)),180);
		/*prepare 200ok*/
		ok_response = belle_sip_response_create_from_request(belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(server_transaction)),200);
		content_length= belle_sip_header_content_length_create(strlen(sdp));
		content_type = belle_sip_header_content_type_create("application","sdp");
		belle_sip_message_add_header(BELLE_SIP_MESSAGE(ok_response),BELLE_SIP_HEADER(content_type));
		belle_sip_message_add_header(BELLE_SIP_MESSAGE(ok_response),BELLE_SIP_HEADER(content_length));
		belle_sip_message_set_body(BELLE_SIP_MESSAGE(ok_response),sdp,strlen(sdp));
		belle_sip_object_ref(ok_response);
		/*only send ringing*/
		belle_sip_server_transaction_send_response(server_transaction,ringing_response);
	} else if (belle_sip_dialog_get_state(dialog) == BELLE_SIP_DIALOG_CONFIRMED) {
		/*time to send bye*/
		belle_sip_client_transaction_t* client_transaction = belle_sip_provider_create_client_transaction(prov,belle_sip_dialog_create_request(dialog,"BYE"));
		belle_sip_client_transaction_send_request(client_transaction);
	} else {
		belle_sip_warning("Unexpected state [%s] for dialog [%p]",belle_sip_dialog_state_to_string(belle_sip_dialog_get_state(dialog)),dialog );
	}

}
コード例 #25
0
ファイル: sipstack.c プロジェクト: Distrotech/belle-sip
void belle_sip_stack_set_timer_config(belle_sip_stack_t *stack,const belle_sip_timer_config_t *timer_config){
	belle_sip_message("Setting timer config to T1 [%i], T2 [%i], T3 [%i], T4 [%i] on stack [%p]", timer_config->T1
																								, timer_config->T2
																								, timer_config->T3
																								, timer_config->T4
																								, stack);
	stack->timer_config=*timer_config;
}
コード例 #26
0
ファイル: udp_listeningpoint.c プロジェクト: Gui13/belle-sip
BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_END


static belle_sip_socket_t create_udp_socket(const char *addr, int *port, int *family){
	struct addrinfo hints={0};
	struct addrinfo *res=NULL;
	int err;
	belle_sip_socket_t sock;
	char portnum[10];
	int optval=1;
	
	if (*port==-1) *port=0; /*random port for bind()*/

	snprintf(portnum,sizeof(portnum),"%i",*port);
	hints.ai_family=AF_UNSPEC;
	hints.ai_socktype=SOCK_DGRAM;
	hints.ai_protocol=IPPROTO_UDP;
	hints.ai_flags=AI_NUMERICSERV;
	err=getaddrinfo(addr,portnum,&hints,&res);
	if (err!=0){
		belle_sip_error("getaddrinfo() failed for %s port %i: %s",addr,*port,gai_strerror(err));
		return -1;
	}
	*family=res->ai_family;
	sock=socket(res->ai_family,res->ai_socktype,res->ai_protocol);
	if (sock==-1){
		belle_sip_error("Cannot create UDP socket: %s",belle_sip_get_socket_error_string());
		freeaddrinfo(res);
		return -1;
	}
	err = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
			(char*)&optval, sizeof (optval));
	if (err == -1){
		belle_sip_warning ("Fail to set SIP/UDP address reusable: %s.", belle_sip_get_socket_error_string());
	}
	
	err=bind(sock,res->ai_addr,res->ai_addrlen);
	if (err==-1){
		belle_sip_error("udp bind() failed for %s port %i: %s",addr,*port,belle_sip_get_socket_error_string());
		close_socket(sock);
		freeaddrinfo(res);
		return -1;
	}
	freeaddrinfo(res);
	if (*port==0){
		struct sockaddr_storage saddr;
		socklen_t saddr_len=sizeof(saddr);
		err=getsockname(sock,(struct sockaddr*)&saddr,&saddr_len);
		if (err==0){
			err=getnameinfo((struct sockaddr*)&saddr,saddr_len,NULL,0,portnum,sizeof(portnum),NI_NUMERICSERV|NI_NUMERICHOST);
			if (err==0){
				*port=atoi(portnum);
				belle_sip_message("Random UDP port is %i",*port);
			}else belle_sip_error("udp bind failed, getnameinfo(): %s",gai_strerror(err));
		}else belle_sip_error("udp bind failed, getsockname(): %s",belle_sip_get_socket_error_string());
	}
	return sock;
}
コード例 #27
0
ファイル: channel.c プロジェクト: PeterXu/sipstack
int belle_sip_channel_notify_timeout(belle_sip_channel_t *obj){
	const int too_long=60;
	if (belle_sip_time_ms() - obj->last_recv_time>=(too_long * 1000)){
		belle_sip_message("A timeout related to this channel occured and no message received during last %i seconds. This channel is suspect, moving to error state",too_long);
		channel_set_state(obj,BELLE_SIP_CHANNEL_ERROR);
		return TRUE;
	}
	return FALSE;
}
コード例 #28
0
static void http_provider_uninit(belle_http_provider_t *obj){
	belle_sip_message("http provider destroyed.");
	belle_sip_free(obj->bind_ip);
	belle_sip_list_for_each(obj->tcp_channels,(void (*)(void*))belle_sip_channel_force_close);
	belle_sip_list_free_with_data(obj->tcp_channels,belle_sip_object_unref);
	belle_sip_list_for_each(obj->tls_channels,(void (*)(void*))belle_sip_channel_force_close);
	belle_sip_list_free_with_data(obj->tls_channels,belle_sip_object_unref);
	belle_sip_object_unref(obj->verify_ctx);
}
コード例 #29
0
static void testMalformedFrom_process_response_cb(void *user_ctx, const belle_sip_response_event_t *event){
	int status = belle_sip_response_get_status_code(belle_sip_response_event_get_response(event));

	belle_sip_message("testMalformedFrom_process_response_cb [%i]",status);

	(*(int*)user_ctx) += 1; // increment the call counter

	CU_ASSERT( status == 400 );
}
コード例 #30
0
ファイル: transaction.c プロジェクト: HackLinux/VideoCallVoIP
void belle_sip_transaction_set_state(belle_sip_transaction_t *t, belle_sip_transaction_state_t 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;
}