static void belle_sip_udp_listening_point_uninit(belle_sip_udp_listening_point_t *lp){
	if (lp->sock!=-1) close_socket(lp->sock);
	if (lp->source) {
		belle_sip_main_loop_remove_source(lp->base.stack->ml,lp->source);
		belle_sip_object_unref(lp->source);
	}
}
Example #2
0
static void cancel_retry(belle_sip_refresher_t* refresher) {
	if (refresher->timer){
		belle_sip_main_loop_remove_source(belle_sip_stack_get_main_loop(refresher->transaction->base.provider->stack),refresher->timer);
		belle_sip_object_unref(refresher->timer);
		refresher->timer=NULL;
	}
}
static void belle_sip_main_loop_destroy(belle_sip_main_loop_t *ml){
	while (ml->sources){
		belle_sip_main_loop_remove_source(ml,(belle_sip_source_t*)ml->sources->data);
	}
	if (belle_sip_object_pool_cleanable(ml->pool)){
		belle_sip_object_unref(ml->pool);
	}
}
Example #4
0
static void belle_sip_dialog_stop_200Ok_retrans(belle_sip_dialog_t *obj){
	belle_sip_main_loop_t *ml=obj->provider->stack->ml;
	if (obj->timer_200Ok){
		belle_sip_main_loop_remove_source(ml,obj->timer_200Ok);
		belle_sip_object_unref(obj->timer_200Ok);
		obj->timer_200Ok=NULL;
	}
	if (obj->timer_200Ok_end){
		belle_sip_main_loop_remove_source(ml,obj->timer_200Ok_end);
		belle_sip_object_unref(obj->timer_200Ok_end);
		obj->timer_200Ok_end=NULL;
	}
	if (obj->last_200Ok){
		belle_sip_object_unref(obj->last_200Ok);
		obj->last_200Ok=NULL;
	}
}
void belle_sip_stream_listening_point_destroy_server_socket(belle_sip_stream_listening_point_t *lp){
	if (lp->server_sock!=(belle_sip_socket_t)-1){
		close_socket(lp->server_sock);
		lp->server_sock=-1;
	}
	if (lp->source){
		belle_sip_main_loop_remove_source(lp->base.stack->ml,lp->source);
		belle_sip_object_unref(lp->source);
		lp->source=NULL;
	}
}
Example #6
0
static void belle_sip_refresher_stop_internal(belle_sip_refresher_t* refresher,int cancel_pending_transaction) {
	belle_sip_message("Refresher [%p] stopped.",refresher);
	if (refresher->timer){
		belle_sip_main_loop_remove_source(belle_sip_stack_get_main_loop(refresher->transaction->base.provider->stack), refresher->timer);
		belle_sip_object_unref(refresher->timer);
		refresher->timer=NULL;
	}
	if (cancel_pending_transaction && refresher->transaction && belle_sip_transaction_state_is_transient(belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(refresher->transaction)))) {
		belle_sip_transaction_terminate(BELLE_SIP_TRANSACTION(refresher->transaction)); /*refresher cancelled, no need to continue to retransmit*/
	}
	refresher->state=stopped;
}
Example #7
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);
}
Example #8
0
static void update_inactivity_timer(belle_sip_channel_t *obj, int from_recv){
	int inactive_timeout=belle_sip_stack_get_inactive_transport_timeout(obj->stack)*1000;
	if (inactive_timeout>0){
		if (!obj->inactivity_timer ){
			obj->inactivity_timer=belle_sip_main_loop_create_timeout(obj->stack->ml,channel_inactive_timeout,obj,inactive_timeout,"Channel inactivity timer");
		}else{
			/*restart the timer for new period*/
			belle_sip_source_set_timeout(obj->inactivity_timer,inactive_timeout);
		}
	}else{
		if (obj->inactivity_timer){
			belle_sip_main_loop_remove_source(obj->stack->ml,obj->inactivity_timer);
			belle_sip_object_unref(obj->inactivity_timer);
			obj->inactivity_timer=NULL;
		}
	}
	if (from_recv)
		obj->last_recv_time=belle_sip_time_ms();
}
Example #9
0
void belle_sip_listening_point_set_keep_alive(belle_sip_listening_point_t *lp,int ms) {
	if (ms <=0) {
		if (lp->keep_alive_timer) {
			belle_sip_main_loop_remove_source(lp->stack->ml,lp->keep_alive_timer);
			belle_sip_object_unref(lp->keep_alive_timer);
			lp->keep_alive_timer=NULL;
		}
		return;
	}

	if (!lp->keep_alive_timer) {
		lp->keep_alive_timer = belle_sip_main_loop_create_timeout(lp->stack->ml
			, keep_alive_timer_func
			, lp
			, ms
			,"keep alive") ;
	} else {
		belle_sip_source_set_timeout(lp->keep_alive_timer,ms);
	}
	return;
}
Example #10
0
void belle_sip_channel_close(belle_sip_channel_t *obj){
	if (BELLE_SIP_OBJECT_VPTR(obj,belle_sip_channel_t)->close)
		BELLE_SIP_OBJECT_VPTR(obj,belle_sip_channel_t)->close(obj); /*udp channel doesn't have close function*/
	belle_sip_main_loop_remove_source(obj->stack->ml,(belle_sip_source_t*)obj);
	belle_sip_source_uninit((belle_sip_source_t*)obj);
}
void belle_sip_main_loop_sleep(belle_sip_main_loop_t *ml, int milliseconds){
	belle_sip_source_t * s=belle_sip_main_loop_create_timeout(ml,(belle_sip_source_func_t)belle_sip_main_loop_quit,ml,milliseconds,"Main loop sleep timer");
	belle_sip_main_loop_run(ml);
	belle_sip_main_loop_remove_source(ml,s);
	belle_sip_object_unref(s);
}
void belle_sip_main_loop_iterate(belle_sip_main_loop_t *ml){
	size_t pfd_size = ml->nsources * sizeof(belle_sip_pollfd_t);
	belle_sip_pollfd_t *pfd=(belle_sip_pollfd_t*)belle_sip_malloc0(pfd_size);
	int i=0;
	belle_sip_source_t *s;
	belle_sip_list_t *elem,*next;
	uint64_t min_time_ms=(uint64_t)-1;
	int duration=-1;
	int ret;
	uint64_t cur;
	belle_sip_list_t *to_be_notified=NULL;
	int can_clean=belle_sip_object_pool_cleanable(ml->pool); /*iterate might not be called by the thread that created the main loop*/ 
	belle_sip_object_pool_t *tmp_pool=NULL;
	
	if (!can_clean){
		/*Push a temporary pool for the time of the iterate loop*/
		tmp_pool=belle_sip_object_pool_push();
	}
	
	/*Step 1: prepare the pollfd table and get the next timeout value */
	for(elem=ml->sources;elem!=NULL;elem=next){
		next=elem->next;
		s=(belle_sip_source_t*)elem->data;
		if (!s->cancelled){
			if (s->fd!=(belle_sip_fd_t)-1){
				belle_sip_source_to_poll(s,pfd,i);
				++i;
			}
			if (s->timeout>=0){
				if (min_time_ms>s->expire_ms){
					min_time_ms=s->expire_ms;
				}
			}
		}
	}
	
	if (min_time_ms!=(uint64_t)-1 ){
		int64_t diff;
		/* compute the amount of time to wait for shortest timeout*/
		cur=belle_sip_time_ms();
		diff=min_time_ms-cur;
		if (diff>0)
			duration=(int)diff;
		else 
			duration=0;
	}
	/* do the poll */
	ret=belle_sip_poll(pfd,i,duration);
	if (ret==-1){
		goto end;
	}
	
	/* Step 2: examine poll results and determine the list of source to be notified */
	cur=belle_sip_time_ms();
	for(elem=ml->sources;elem!=NULL;elem=elem->next){
		unsigned revents=0;
		s=(belle_sip_source_t*)elem->data;

		if (!s->cancelled){
			if (s->fd!=(belle_sip_fd_t)-1){
				if (s->notify_required) { /*for testing purpose to force channel to read*/
					revents=BELLE_SIP_EVENT_READ;
					s->notify_required=0; /*reset*/
				} else {
					revents=belle_sip_source_get_revents(s,pfd);
				}
				s->revents=revents;
			}
			if (revents!=0 || (s->timeout>=0 && cur>=s->expire_ms)){
				to_be_notified=belle_sip_list_append(to_be_notified,belle_sip_object_ref(s));
				s->expired=TRUE;
				if (s->revents==0)
					s->revents=BELLE_SIP_EVENT_TIMEOUT;
			}
		}else to_be_notified=belle_sip_list_append(to_be_notified,belle_sip_object_ref(s));
	}
	
	/* Step 3: notify those to be notified */
	for(elem=to_be_notified;elem!=NULL;){
		s=(belle_sip_source_t*)elem->data;
		next=elem->next;
		if (!s->cancelled){
			char *objdesc=belle_sip_object_to_string((belle_sip_object_t*)s);
			if (s->timeout>0)/*to avoid too many traces*/ belle_sip_debug("source %s notified revents=%u, timeout=%i",objdesc,revents,s->timeout);
			belle_sip_free(objdesc);
			ret=s->notify(s->data,s->revents);
			if (ret==BELLE_SIP_STOP || s->oneshot){
				/*this source needs to be removed*/
				belle_sip_main_loop_remove_source(ml,s);
			}else if (s->revents==BELLE_SIP_EVENT_TIMEOUT){
				/*timeout needs to be started again */
				s->expire_ms+=s->timeout;
				s->expired=FALSE;
			}
		}else belle_sip_main_loop_remove_source(ml,s);
		belle_sip_object_unref(s);
		belle_sip_free(elem); /*free just the element*/
		elem=next;
	}
	
	if (can_clean) belle_sip_object_pool_clean(ml->pool);
	else if (tmp_pool) belle_sip_object_unref(tmp_pool);
end:
	belle_sip_free(pfd);
}
Example #13
0
void sal_cancel_timer(Sal *sal, belle_sip_source_t *timer) {
	belle_sip_main_loop_t *ml = belle_sip_stack_get_main_loop(sal->stack);
	belle_sip_main_loop_remove_source(ml, timer);
}