/***********************************************************
Copyright (C), LGC Wireless.
File Name:		isdn_uif.c
Description:	ISDN USER INTERFACE
Version:		v9.0.0
Author:			Gengxin Chen
Create Date:	2008-2-19
History:
	<author>	<date>		<version>		<desc>
	
************************************************************/

#include "./include/isdn_const.h"
#include "./include/isdn_rm.h"
#include "./include/isdn_debug.h"
#include "./include/isdn_ext.h"
#include "./include/isdn_inc.h"


extern void isdn_cpc_proc(u32 pid);
extern void isdn_restart_ctrl(u32 pid);
extern void service_bc_proc(u32 pid);


/*************************************************************
Function:		isdn_setup_req
Description:	msc invokes the function to request setup
Output:		pst:post structure pointer, ptr:isdn setup structure pointer
Return:		ISDN_CM_OK:success
			ISDN_CM_FAILED:failed
*************************************************************/
int isdn_setup_req(Pst *pst, IsdnSetup *ptr)
{
	const pal_circuit_struct *circuit_ptr = NULL;
	circuit_ptr = pal_locate_circuit(pst->cg_id, pst->cic);
	if(circuit_ptr == NULL)
	{
		isdn_trace_func(0, "APP => function trace: %s\r\n", __FUNCTION__);
		return ISDN_CM_FAILED;
	}
	pst->sp_proc_id = find_port_by_cic(pst->cic, circuit_ptr->id);
	isdn_rs.port_pond[pst->sp_proc_id].su_proc_id = pst->su_proc_id;
	isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd = ISDN_SETUP_REQ;
	isdn_rs.port_pond[pst->sp_proc_id].trace_flag = pst->trace_flag;
	isdn_rs.port_pond[pst->sp_proc_id].enable = 1;
	isdn_trace_func(pst->sp_proc_id, "APP => function trace: %s\r\n", __FUNCTION__);
	
	if(isdn_rs.port_pond[pst->sp_proc_id].cic_state.call_state != IDLE_FLAG)
	{
		isdn_log_err(pst->sp_proc_id, "call state is not idle, but is %d\n", isdn_rs.port_pond[pst->sp_proc_id].cic_state.call_state);
		return ISDN_CM_FAILED;
	}
	memcpy(&(isdn_sd_msg.msg_list.setup), ptr, sizeof(IsdnSetup));
	if(circuit_ptr->attrib.user_network_if)
		isdn_rs.port_pond[pst->sp_proc_id].cic_state.call_state = CALLOUT_FLAG;
	else
		isdn_rs.port_pond[pst->sp_proc_id].cic_state.call_state = CALLIN_FLAG;
	isdn_cpc_proc(pst->sp_proc_id);
	if(isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd != 0)
	{
		isdn_trace_func(pst->sp_proc_id, "[waring]primitive cmd discard.(cmd=%d)\r\n", isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd);
		isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd = 0;
	}
	
	return ISDN_CM_OK;
}

/*************************************************************
Function:		isdn_m_info_req
Description:	msc invokes the function to request more information
Output:		pst:post structure pointer, ptr:isdn setup ack structure pointer
Return:		ISDN_CM_OK:success
			ISDN_CM_FAILED:failed
*************************************************************/
int isdn_m_info_req(Pst *pst, IsdnSetupAck *ptr)
{
	isdn_trace_func(pst->sp_proc_id, "APP => function trace: %s\r\n", __FUNCTION__);
	if(pst->sp_proc_id >= ISDN_MAX_PORT)
	{
		isdn_log_err(0, "pid=%d, is paranormal)\n", pst->sp_proc_id);
		return ISDN_CM_FAILED;
	}
	isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd = ISDN_MORE_INFO_REQ;
	memcpy(&(isdn_sd_msg.msg_list.setupAck), ptr, sizeof(IsdnSetupAck));
	isdn_cpc_proc(pst->sp_proc_id);
	if(isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd != 0)
	{
		isdn_trace_func(pst->sp_proc_id, "[waring]primitive cmd discard.(cmd=%d)\r\n", isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd);
		isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd = 0;
	}

	return ISDN_CM_OK;
}

/*************************************************************
Function:		isdn_call_proc_req
Description:	msc invokes the function to request call proceeding
Output:		pst:post structure pointer, ptr:isdn call proceeding structure pointer
Return:		ISDN_CM_OK:success
			ISDN_CM_FAILED:failed
*************************************************************/
int isdn_call_proc_req(Pst *pst, IsdnCallProc *ptr)
{
	isdn_trace_func(pst->sp_proc_id, "APP => function trace: %s\r\n", __FUNCTION__);
	if(pst->sp_proc_id >= ISDN_MAX_PORT)
	{
		isdn_log_err(0, "pid=%d, is paranormal)\n", pst->sp_proc_id);
		return ISDN_CM_FAILED;
	}
	isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd = ISDN_PROC_REQ;
	memcpy(&(isdn_sd_msg.msg_list.callProc), ptr, sizeof(IsdnCallProc));
	isdn_cpc_proc(pst->sp_proc_id);
	if(isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd != 0)
	{
		isdn_trace_func(pst->sp_proc_id, "[waring]primitive cmd discard.(cmd=%d)\r\n", isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd);
		isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd = 0;
	}
	
	return ISDN_CM_OK;
}

/*************************************************************
Function:		isdn_alert_req
Description:	msc invokes the function to request alerting
Output:		pst:post structure pointer, ptr:isdn alerting structure pointer
Return:		ISDN_CM_OK:success
			ISDN_CM_FAILED:failed
*************************************************************/
int isdn_alert_req(Pst *pst, IsdnAlert *ptr)
{
	isdn_trace_func(pst->sp_proc_id, "APP => function trace: %s\r\n", __FUNCTION__);
	if(pst->sp_proc_id >= ISDN_MAX_PORT)
	{
		isdn_log_err(0, "pid=%d, is paranormal)\n", pst->sp_proc_id);
		return ISDN_CM_FAILED;
	}
	isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd = ISDN_ALERT_REQ;
	memcpy(&(isdn_sd_msg.msg_list.alert), ptr, sizeof(IsdnAlert));
	isdn_cpc_proc(pst->sp_proc_id);
	if(isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd != 0)
	{
		isdn_trace_func(pst->sp_proc_id, "[waring]primitive cmd discard.(cmd=%d)\r\n", isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd);
		isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd = 0;
	}

	return ISDN_CM_OK;
}

/*************************************************************
Function:		isdn_setup_resp
Description:	msc invokes the function to request setup response
Output:		pst:post structure pointer, ptr:isdn connect structure pointer
Return:		ISDN_CM_OK:success
			ISDN_CM_FAILED:failed
*************************************************************/
int isdn_setup_resp(Pst *pst, IsdnConn *ptr)
{
	isdn_trace_func(pst->sp_proc_id, "APP => function trace: %s\r\n", __FUNCTION__);
	if(pst->sp_proc_id >= ISDN_MAX_PORT)
	{
		isdn_log_err(0, "pid=%d, is paranormal)\n", pst->sp_proc_id);
		return ISDN_CM_FAILED;
	}
	isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd = ISDN_SETUP_RSP;
	memcpy(&(isdn_sd_msg.msg_list.conn), ptr, sizeof(IsdnConn));
	isdn_cpc_proc(pst->sp_proc_id);
	if(isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd != 0)
	{
		isdn_trace_func(pst->sp_proc_id, "[waring]primitive cmd discard.(cmd=%d)\r\n", isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd);
		isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd = 0;
	}

	return ISDN_CM_OK;
}

/*************************************************************
Function:		isdn_disc_req
Description:	msc invokes the function to request disconnect
Output:		pst:post structure pointer, ptr:isdn disconnect structure pointer
Return:		ISDN_CM_OK:success
			ISDN_CM_FAILED:failed
*************************************************************/
int isdn_disc_req(Pst *pst, IsdnDisc *ptr)
{
	isdn_trace_func(pst->sp_proc_id, "APP => function trace: %s\r\n", __FUNCTION__);
	if(pst->sp_proc_id >= ISDN_MAX_PORT)
	{
		isdn_log_err(0, "pid=%d, is paranormal)\n", pst->sp_proc_id);
		return ISDN_CM_FAILED;
	}
	isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd = ISDN_DISCONNECT_REQ;
	memcpy(&(isdn_sd_msg.msg_list.disc), ptr, sizeof(IsdnDisc));
	isdn_cpc_proc(pst->sp_proc_id);
	if(isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd != 0)
	{
		isdn_trace_func(pst->sp_proc_id, "[waring]primitive cmd discard.(cmd=%d)\r\n", isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd);
		isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd = 0;
	}

	return ISDN_CM_OK;
}

/*************************************************************
Function:		isdn_rel_req
Description:	msc invokes the function to request release
Output:		pst:post structure pointer, ptr:isdn release structure pointer
Return:		ISDN_CM_OK:success
			ISDN_CM_FAILED:failed
*************************************************************/
int isdn_rel_req(Pst *pst, IsdnRel *ptr)
{
	isdn_trace_func(pst->sp_proc_id, "APP => function trace: %s\r\n", __FUNCTION__);
	if(pst->sp_proc_id >= ISDN_MAX_PORT)
	{
		isdn_log_err(0, "pid=%d, is paranormal)\n", pst->sp_proc_id);
		return ISDN_CM_FAILED;
	}
	isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd = ISDN_RELEASE_REQ;
	memcpy(&(isdn_sd_msg.msg_list.rel), ptr, sizeof(IsdnRel));
	isdn_cpc_proc(pst->sp_proc_id);
	if(isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd != 0)
	{
		isdn_trace_func(pst->sp_proc_id, "[waring]primitive cmd discard.(cmd=%d)\r\n", isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd);
		isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd = 0;
	}

	return ISDN_CM_OK;
}

int isdn_rej_req(Pst *pst, IsdnRelComp *ptr)
{
	isdn_trace_func(pst->sp_proc_id, "APP => function trace: %s\r\n", __FUNCTION__);
	if(pst->sp_proc_id >= ISDN_MAX_PORT)
	{
		isdn_log_err(0, "pid=%d, is paranormal)\n", pst->sp_proc_id);
		return ISDN_CM_FAILED;
	}
	isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd = ISDN_REJECT_REQ;
	memcpy(&(isdn_sd_msg.msg_list.relComp), ptr, sizeof(IsdnRelComp));
	isdn_cpc_proc(pst->sp_proc_id);
	if(isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd != 0)
	{
		isdn_trace_func(pst->sp_proc_id, "[waring]primitive cmd discard.(cmd=%d)\r\n", isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd);
		isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd = 0;
	}

	return ISDN_CM_OK;
}
/*************************************************************
Function:		isdn_info_req
Description:	msc invokes the function to request information
Output:		pst:post structure pointer, ptr:isdn information structure pointer
Return:		ISDN_CM_OK:success
			ISDN_CM_FAILED:failed
*************************************************************/
int isdn_info_req(Pst *pst, IsdnInfo *ptr)
{
	isdn_trace_func(pst->sp_proc_id, "APP => function trace: %s\r\n", __FUNCTION__);
	if(pst->sp_proc_id >= ISDN_MAX_PORT)
	{
		isdn_log_err(0, "pid=%d, is paranormal\r\n", pst->sp_proc_id);
		return ISDN_CM_FAILED;
	}
	isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd = ISDN_INFO_REQ;
	memcpy(&(isdn_sd_msg.msg_list.info), ptr, sizeof(IsdnInfo));
	isdn_cpc_proc(pst->sp_proc_id);
	if(isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd != 0)
	{
		isdn_trace_func(pst->sp_proc_id, "[waring]primitive cmd discard.(cmd=%d)\r\n", isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd);
		isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd = 0;
	}

	return ISDN_CM_OK;
}

/*************************************************************
Function:		isdn_prog_req
Description:	msc invokes the function to request progress
Output:		pst:post structure pointer, ptr:isdn progress structure pointer
Return:		ISDN_CM_OK:success
			ISDN_CM_FAILED:failed
*************************************************************/
int isdn_prog_req(Pst *pst, IsdnProg *ptr)
{
	isdn_trace_func(pst->sp_proc_id, "APP => function trace: %s\r\n", __FUNCTION__);
	if(pst->sp_proc_id >= ISDN_MAX_PORT)
	{
		isdn_log_err(0, "pid=%d, is paranormal\r\n", pst->sp_proc_id);
		return ISDN_CM_FAILED;
	}
	isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd = ISDN_PROG_REQ;
	memcpy(&(isdn_sd_msg.msg_list.prog), ptr, sizeof(IsdnProg));
	isdn_cpc_proc(pst->sp_proc_id);
	if(isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd != 0)
	{
		isdn_trace_func(pst->sp_proc_id, "[waring]primitive cmd discard.(cmd=%d)\r\n", isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd);
		isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd = 0;
	}

	return ISDN_CM_OK;
}

/*************************************************************
Function:		isdn_noti_req
Description:	msc invokes the function to request notify
Output:		pst:post structure pointer, ptr:isdn notify structure pointer
Return:		ISDN_CM_OK:success
			ISDN_CM_FAILED:failed
*************************************************************/
int isdn_noti_req(Pst * pst, IsdnNoti * ptr)
{
	isdn_trace_func(pst->sp_proc_id, "APP => function trace: %s\r\n", __FUNCTION__);
	if(pst->sp_proc_id >= ISDN_MAX_PORT)
	{
		isdn_log_err(0, "pid=%d, is paranormal\r\n", pst->sp_proc_id);
		return ISDN_CM_FAILED;
	}
	isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd = ISDN_NOTI_REQ;
	memcpy(&(isdn_sd_msg.msg_list.noti), ptr, sizeof(IsdnNoti));
	isdn_cpc_proc(pst->sp_proc_id);
	if(isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd != 0)
	{
		isdn_trace_func(pst->sp_proc_id, "[waring]primitive cmd discard.(cmd=%d)\r\n", isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd);
		isdn_rs.port_pond[pst->sp_proc_id].primitive_cmd = 0;
	}

	return ISDN_CM_OK;
}

/*************************************************************
Function:		isdn_m_restart_req
Description:	msc invokes the function to request management restart
Output:		pst:post structure pointer, ptr:isdn restart structure pointer
Return:		ISDN_CM_OK:success
			ISDN_CM_FAILED:failed
*************************************************************/
int isdn_m_restart_req(Pst *pst, IsdnRestart *ptr)		//restart indicated channel
{
	u32 pid, link_id;
	int circuit_id;
	const pal_cg_struct *cg_ptr = NULL;
	const pal_circuit_struct *circuit_ptr = NULL;
	isdn_trace_func(0, "APP => function trace: %s\r\n", __FUNCTION__);
	cg_ptr = pal_cg_ptr(pst->cg_id);
	if(cg_ptr == NULL)
		return ISDN_CM_FAILED;
	if(cg_ptr->attrib.protocol != PROTO_ISDN)
		return ISDN_CM_FAILED;
	circuit_ptr = pal_locate_circuit(pst->cg_id, pst->cic);
	if(circuit_ptr == NULL)
	{
		isdn_log_err(0, "isdn_m_restart_req err!circuit_ptr cann't be found by vcg_id=%d,cic=%ld \r\n", pst->cg_id, pst->cic);
		return ISDN_CM_FAILED;
	}
	circuit_id = circuit_ptr->id;
	pst->sp_proc_id = find_port_by_cic(pst->cic, circuit_id);
	if(pst->sp_proc_id >= ISDN_MAX_PORT)
	{
		isdn_log_err(0, "pid=%d, is paranormal\r\n", pst->sp_proc_id);
		return ISDN_CM_FAILED;
	}
	memcpy(&(isdn_sd_msg.msg_list.restart), ptr, sizeof(IsdnRestart));
	pid = (circuit_id) * ISDN_CIRCUIT_CIC;
	link_id = circuit_ptr->attrib.link_id;
	if(ptr->restart_ind.clas == 0)
		isdn_rs.port_pond[pid].cic_val = pst->cic;
	else
		isdn_rs.port_pond[pid].cic_val = 0;
	isdn_rs.link_pond[link_id].restart_clas = ptr->restart_ind.clas;
	isdn_rs.port_pond[pid].g_pri_cmd = ISDN_M_RESTART_REQ;
	isdn_restart_ctrl(pid);
	if(isdn_rs.port_pond[pid].g_pri_cmd != 0)
	{
		isdn_trace_func(pid, "[waring]global primitive cmd discard.(cmd=%d)\r\n", isdn_rs.port_pond[pst->sp_proc_id].g_pri_cmd);
		isdn_rs.port_pond[pid].g_pri_cmd = 0;
	}

	return ISDN_CM_OK;
}


//ansi
int isdn_service_bc_req(Pst *pst, IsdnService *ptr)
{
	const pal_circuit_struct *circuit_ptr = NULL;
	circuit_ptr = pal_locate_circuit(pst->cg_id, pst->cic);
	if(circuit_ptr == NULL)
	{
		isdn_trace_func(0, "APP => function trace: %s\r\n", __FUNCTION__);
		return ISDN_CM_FAILED;
	}
	pst->sp_proc_id = find_port_by_cic(pst->cic, circuit_ptr->id);
	isdn_rs.port_pond[pst->sp_proc_id].su_proc_id = pst->su_proc_id;
	isdn_rs.port_pond[pst->sp_proc_id].g_pri_cmd = ISDN_SERVICE_REQ;
	isdn_rs.port_pond[pst->sp_proc_id].trace_flag = pst->trace_flag;
//	isdn_rs.port_pond[pst->sp_proc_id].enable = 1;
	isdn_trace_func(pst->sp_proc_id, "APP => function trace: %s\r\n", __FUNCTION__);
	memcpy(&(isdn_sd_msg.msg_list.service), ptr, sizeof(IsdnService));
	service_bc_proc(pst->sp_proc_id);
	if(isdn_rs.port_pond[pst->sp_proc_id].g_pri_cmd != 0)
	{
		isdn_trace_func(pst->sp_proc_id, "[waring]global primitive cmd discard.(cmd=%d)\r\n", isdn_rs.port_pond[pst->sp_proc_id].g_pri_cmd);
		isdn_rs.port_pond[pst->sp_proc_id].g_pri_cmd = 0;
	}

	return ISDN_CM_OK;
}

int isdn_service_bc_rsp(Pst *pst, IsdnServAck *ptr)
{
	isdn_trace_func(pst->sp_proc_id, "APP => function trace: %s\r\n", __FUNCTION__);
	if(pst->sp_proc_id >= ISDN_MAX_PORT)
	{
		isdn_log_err(0, "pid=%d, is paranormal\r\n", pst->sp_proc_id);
		return ISDN_CM_FAILED;
	}
	isdn_rs.port_pond[pst->sp_proc_id].g_pri_cmd = ISDN_SERVICE_RSP;
	memcpy(&(isdn_sd_msg.msg_list.servAck), ptr, sizeof(IsdnServAck));
	service_bc_proc(pst->sp_proc_id);
	if(isdn_rs.port_pond[pst->sp_proc_id].g_pri_cmd != 0)
	{
		isdn_trace_func(pst->sp_proc_id, "[waring]global primitive cmd discard.(cmd=%d)\r\n", isdn_rs.port_pond[pst->sp_proc_id].g_pri_cmd);
		isdn_rs.port_pond[pst->sp_proc_id].g_pri_cmd = 0;
	}

	return ISDN_CM_OK;
}

