Exemple #1
0
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;
}
Exemple #2
0
static void belle_sip_channel_destroy(belle_sip_channel_t *obj){
	if (obj->peer_list) freeaddrinfo(obj->peer_list);
	if (obj->peer_cname) belle_sip_free(obj->peer_cname);
	belle_sip_free(obj->peer_name);
	if (obj->local_ip) belle_sip_free(obj->local_ip);
	obj->listeners=for_each_weak_unref_free(obj->listeners,(belle_sip_object_destroy_notify_t)channel_remove_listener,obj);
	if (obj->resolver_ctx>0) belle_sip_resolver_context_cancel(obj->resolver_ctx);
	if (obj->inactivity_timer){
		belle_sip_main_loop_remove_source(obj->stack->ml,obj->inactivity_timer);
		belle_sip_object_unref(obj->inactivity_timer);
	}
	if (obj->public_ip) belle_sip_free(obj->public_ip);
	if (obj->outgoing_messages) belle_sip_list_free_with_data(obj->outgoing_messages,belle_sip_object_unref);
	channel_end_send_background_task(obj);
	channel_end_recv_background_task(obj);
	/*normally this should do nothing because it sould have been terminated already,
		however leaving a background task open is so dangerous that we have to be paranoid*/
	belle_sip_message("Channel [%p] destroyed",obj);
}
Exemple #3
0
static void channel_on_recv_background_task_ended(belle_sip_channel_t *obj){
	belle_sip_warning("channel [%p]: recv background task has to be ended now, but work isn't finished.",obj);
	channel_end_recv_background_task(obj);
}