static int tsip_dialog_invite_ice_callback(const tnet_ice_event_t *e)
{
	int ret = 0;
	tsip_dialog_invite_t *dialog;

	TSK_DEBUG_INFO("ICE callback: %s", e->phrase);

	dialog = tsk_object_ref(TSK_OBJECT(e->userdata));

	// Do not lock: caller is thread safe

	switch(e->type){
		case tnet_ice_event_type_gathering_completed:
		case tnet_ice_event_type_conncheck_succeed:
		case tnet_ice_event_type_conncheck_failed:
		case tnet_ice_event_type_cancelled:
			{
				if(dialog->ice.last_action_id != tsk_fsm_state_none){
					if(tsip_dialog_invite_ice_got_local_candidates(dialog)){
						ret = tsip_dialog_fsm_act(TSIP_DIALOG(dialog), dialog->ice.last_action_id, dialog->ice.last_message, dialog->ice.last_action);
						dialog->ice.last_action_id = tsk_fsm_state_none;
					}
				}
				if(dialog->ice.start_smgr){
					ret = tsip_dialog_invite_msession_start(dialog);
				}
				break;
			}
		// fatal errors which discard ICE process
		case tnet_ice_event_type_gathering_host_candidates_failed:
		case tnet_ice_event_type_gathering_reflexive_candidates_failed:
		case tnet_ice_event_type_gathering_relay_candidates_failed:
			{
				if (dialog->ice.last_action_id != tsk_fsm_state_none) {
					ret = tsip_dialog_fsm_act(TSIP_DIALOG(dialog), dialog->ice.last_action_id, dialog->ice.last_message, dialog->ice.last_action);
					dialog->ice.last_action_id = tsk_fsm_state_none;
				}
				break;
			}
		// TURN session disconnected while we're in call
		case tnet_ice_event_type_turn_connection_broken:
			{
				ret = tsip_dialog_fsm_act_2(TSIP_DIALOG(dialog), _fsm_action_oBYE);
				break;
			}
        default: break;
	}

	TSK_OBJECT_SAFE_FREE(dialog);

	return ret;
}
/**Timer manager callback.
 *
 * @param self	The owner of the signaled timer. 
 * @param	timer_id		The identifier of the signaled timer.
 *
 * @return	Zero if succeed and non-zero error code otherwise.  
**/
int tsip_dialog_register_timer_callback(const tsip_dialog_register_t* self, tsk_timer_id_t timer_id)
{
	int ret = -1;

	if(self){
		if(timer_id == self->timerrefresh.id){
			ret = tsip_dialog_fsm_act(TSIP_DIALOG(self), _fsm_action_oREGISTER, tsk_null, tsk_null);
		}
		else if(timer_id == self->timershutdown.id){
			ret = tsip_dialog_fsm_act(TSIP_DIALOG(self), _fsm_action_shutdown_timedout, tsk_null, tsk_null);
		}
	}
	return ret;
}
/**
 * Callback function called to alert the dialog for new events from the transaction/transport layers.
 *
 * @param [in,out]	self	A reference to the dialog.
 * @param	type		The event type. 
 * @param [in,out]	msg	The incoming SIP/IMS message. 
 *
 * @return	Zero if succeed and non-zero error code otherwise. 
**/
int tsip_dialog_subscribe_event_callback(const tsip_dialog_subscribe_t *self, tsip_dialog_event_type_t type, const tsip_message_t *msg)
{
	int ret = -1;

	switch(type)
	{
	case tsip_dialog_i_msg:
		{
			if(msg && TSIP_MESSAGE_IS_RESPONSE(msg)){
				//
				//	RESPONSE
				//
				const tsip_action_t* action = tsip_dialog_keep_action(TSIP_DIALOG(self), msg) ? TSIP_DIALOG(self)->curr_action : tsk_null;
				if(TSIP_RESPONSE_IS_1XX(msg)){
					ret = tsip_dialog_fsm_act(TSIP_DIALOG(self), _fsm_action_1xx, msg, action);
				}
				else if(TSIP_RESPONSE_IS_2XX(msg)){
					ret = tsip_dialog_fsm_act(TSIP_DIALOG(self), _fsm_action_2xx, msg, action);
				}
				else if(TSIP_RESPONSE_IS(msg,401) || TSIP_RESPONSE_IS(msg,407) || TSIP_RESPONSE_IS(msg,421) || TSIP_RESPONSE_IS(msg,494)){
					ret = tsip_dialog_fsm_act(TSIP_DIALOG(self), _fsm_action_401_407_421_494, msg, action);
				}
				else if(TSIP_RESPONSE_IS(msg,423)){
					ret = tsip_dialog_fsm_act(TSIP_DIALOG(self), _fsm_action_423, msg, action);
				}
				else{
					// Alert User
					ret = tsip_dialog_fsm_act(TSIP_DIALOG(self), _fsm_action_error, msg, action);
					/* TSK_DEBUG_WARN("Not supported status code: %d", TSIP_RESPONSE_CODE(msg)); */
				}
			}
			else{
				//
				//	REQUEST
				//
				if(TSIP_REQUEST_IS_NOTIFY(msg)){
					ret = tsip_dialog_fsm_act(TSIP_DIALOG(self), _fsm_action_notify, msg, tsk_null);
				}
			}
			break;
		}

	case tsip_dialog_canceled:
		{
			ret = tsip_dialog_fsm_act(TSIP_DIALOG(self), _fsm_action_cancel, msg, tsk_null);
			break;
		}

	case tsip_dialog_terminated:
	case tsip_dialog_timedout:
	case tsip_dialog_error:
	case tsip_dialog_transport_error:
		{
			ret = tsip_dialog_fsm_act(TSIP_DIALOG(self), _fsm_action_transporterror, msg, tsk_null);
			break;
		}
	}
	
	return ret;
}
Example #4
0
int tsip_api_publish_send_publish(const tsip_ssession_handle_t *ss, ...)
{
	const tsip_ssession_t* _ss;
	va_list ap;
	tsip_action_t* action;
	tsip_dialog_t* dialog;
	int ret = -1;

	if(!(_ss = ss) || !_ss->stack){
		TSK_DEBUG_ERROR("Invalid parameter.");
		return ret;
	}

	/* Checks if the stack has been started */
	if(!TSK_RUNNABLE(_ss->stack)->started){
		TSK_DEBUG_ERROR("Stack not started.");
		return -2;
	}
	
	va_start(ap, ss);
	if((action = _tsip_action_create(tsip_atype_publish, &ap))){
		if(!(dialog = tsip_dialog_layer_find_by_ss(_ss->stack->layer_dialog, ss))){
			dialog = tsip_dialog_layer_new(_ss->stack->layer_dialog, tsip_dialog_PUBLISH, ss);
		}
		ret = tsip_dialog_fsm_act(dialog, action->type, tsk_null, action);
		
		tsk_object_unref(dialog);
		TSK_OBJECT_SAFE_FREE(action);
	}
	va_end(ap);

	return ret;
}
static int tsip_dialog_message_event_callback(const tsip_dialog_message_t *self, tsip_dialog_event_type_t type, const tsip_message_t *msg)
{
	int ret = -1;

	switch(type)
	{
	case tsip_dialog_i_msg:
		{
			if(msg){
				if(TSIP_MESSAGE_IS_RESPONSE(msg)){
					const tsip_action_t* action = tsip_dialog_keep_action(TSIP_DIALOG(self), msg) ? TSIP_DIALOG(self)->curr_action : tsk_null;
					if(TSIP_RESPONSE_IS_1XX(msg)){
						ret = tsip_dialog_fsm_act(TSIP_DIALOG(self), _fsm_action_1xx, msg, action);
					}
					else if(TSIP_RESPONSE_IS_2XX(msg)){
						ret = tsip_dialog_fsm_act(TSIP_DIALOG(self), _fsm_action_2xx, msg, action);
					}
					else if(TSIP_RESPONSE_CODE(msg) == 401 || TSIP_RESPONSE_CODE(msg) == 407 || TSIP_RESPONSE_CODE(msg) == 421 || TSIP_RESPONSE_CODE(msg) == 494){
						ret = tsip_dialog_fsm_act(TSIP_DIALOG(self), _fsm_action_401_407_421_494, msg, action);
					}
					else if(TSIP_RESPONSE_IS_3456(msg)){
						ret = tsip_dialog_fsm_act(TSIP_DIALOG(self), _fsm_action_300_to_699, msg, action);
					}
					else{ /* Should never happen */
						ret = tsip_dialog_fsm_act(TSIP_DIALOG(self), _fsm_action_error, msg, action);
					}
				}
				else if (TSIP_REQUEST_IS_MESSAGE(msg)){ /* have been checked by dialog layer...but */
					// REQUEST ==> Incoming MESSAGE
					ret = tsip_dialog_fsm_act(TSIP_DIALOG(self), _fsm_action_receiveMESSAGE, msg, tsk_null);
				}
			}
			break;
		}

	case tsip_dialog_canceled:
		{
			ret = tsip_dialog_fsm_act(TSIP_DIALOG(self), _fsm_action_cancel, msg, tsk_null);
			break;
		}

	case tsip_dialog_terminated:
	case tsip_dialog_timedout:
	case tsip_dialog_error:
	case tsip_dialog_transport_error:
		{
			ret = tsip_dialog_fsm_act(TSIP_DIALOG(self), _fsm_action_transporterror, msg, tsk_null);
			break;
		}
	}

	return ret;
}