/***********************************************************
Copyright (C), LGC Wireless.
File Name:		isdn_test.c
Description:	For isdn module test
Version:		v9.0.0
Author:			Gengxin Chen
Create Date:	2008-2-19
History:
	<author>	<date>		<version>		<desc>
	
************************************************************/
#include "../src/include/isdn_rm.h"
#include "../src/include/isdn_ext.h"
#include "../src/include/isdn_inc.h"


#define CODE_SETUP "a1 04 03 80 90 a3 18 03 a1 83 81 6c 07 00 80 35 31 30 30 31 70 06 81 35 32 30 30 31"
#define CODE_CALL_PROC "18 03 A9 83 81"
#define CODE_ALERT "1E 02 83 88"
#define CODE_DISCONN "08 02 83 90"

int test_len;
static int cc_state[8192] = {0};

extern int CStrToHex(u8 dst[], u8 *src);
extern int q931_msg_encode(u8 *dst, IsdnMsgStr *src);
extern int isdn_msg_decode(IsdnMsgStr *dst, u8 *src, u8 msgtype, u8 len);
extern void isdn_set_cause(CauseStr *cause_ptr, u8 val);

void test_isdn_msg_encode(u8 type)
{
	int ret;
	int i;
	memset(&iua_sd_msg, 0, sizeof(IuaMsgStr));
	IuaMsgStr *dst = &iua_sd_msg;
	u8 *flw_ptr = dst->msgcontent.isdn_msg.ie_content;	//message flow pointer
	
	memcpy(&isdn_sd_msg, &isdn_rv_msg, sizeof(IsdnMsgStr));
	isdn_sd_msg.msg_m.msg_type = type;
	ret = q931_msg_encode(flw_ptr, &isdn_sd_msg);
	printf("ret=%d\n",ret);
	for(i=0; i<ret; i++)
	{
		printf("%2x ",flw_ptr[i]);
	}
	printf("\n");
}

void test_isdn_msg_decode(u8 type)
{
	u8 *ptr = "";
	memset(&isdn_rv_msg, 0, sizeof(IsdnMsgStr));
	memset(&iua_rv_msg, 0, sizeof(IuaMsgStr));
	switch(type)
	{
		case MSG_SETUP:
			ptr = CODE_SETUP;
			break;
		case MSG_SETUP_ACK:
		case MSG_CALL_PROC:
			ptr = CODE_CALL_PROC;
			break;
		case MSG_ALERT:
			ptr = CODE_ALERT;
			break;
		case MSG_DISC:
		case MSG_REL:
		case MSG_REL_COMP:
			ptr = CODE_DISCONN;
			break;
		default:
			break;
	}

	CStrToHex(iua_rv_msg.msgcontent.isdn_msg.ie_content, ptr);
	isdn_msg_decode(&isdn_rv_msg, iua_rv_msg.msgcontent.isdn_msg.ie_content, type, test_len);
}


int isdn_setup_ind(Pst *pst, IsdnSetup *ptr)
{
	cc_state[pst->sp_proc_id] = 1;
	return 1;
}
int isdn_alert_ind(Pst *pst, IsdnAlert *ptr)
{
	return 1;
}
int isdn_setup_cnf(Pst *pst, IsdnConn *ptr)
{
	return 1;
}
int isdn_disc_ind(Pst *pst, IsdnDisc *ptr)
{
	IsdnRel src;
	memset(&src, 0, sizeof(IsdnRel));
	
	isdn_rel_req(pst, &src);
	return 1;
}
int isdn_rel_ind(Pst *pst, IsdnRel *ptr)
{
	return 1;
}
int isdn_rel_cnf(Pst *pst, IsdnRelComp *ptr)
{
	return 1;
}
int isdn_stat_ind(Pst *pst, IsdnStatus *ptr)
{
	return 1;
}
void msc_isdn_init(int *sap_id)
{
	ISDN_Sap_Attrib_ sap;
	memset(&sap,0,sizeof(ISDN_Sap_Attrib_));
	sap.event_handle.h_isdn_setup_ind = (f_isdn_setup_ind *)isdn_setup_ind;
	sap.event_handle.h_isdn_alert_ind = (f_isdn_alert_ind *)isdn_alert_ind;
	sap.event_handle.h_isdn_setup_cnf = (f_isdn_setup_cnf *)isdn_setup_cnf;
	sap.event_handle.h_isdn_disc_ind = (f_isdn_disc_ind *)isdn_disc_ind;
	sap.event_handle.h_isdn_rel_ind = (f_isdn_rel_ind *)isdn_rel_ind;
	sap.event_handle.h_isdn_rel_cnf = (f_isdn_rel_cnf *)isdn_rel_cnf;
	sap.event_handle.h_isdn_stat_ind = (f_isdn_stat_ind *)isdn_stat_ind;

	if((*sap_id = isdn_bind_sap(&sap)) == -1)
	{
		printf("add sap error!\r\n");
		return;
	}
}

void isdn_cc_fsm(u32 pid)
{
	int offset, circuit_id;
	static int i = 0;
	Pst pst;
	IsdnMsgStr isdn_msg;

	memset(&isdn_msg, 0, sizeof(IsdnMsgStr));
	pst.sp_proc_id = pid;
	pst.su_proc_id = isdn_rs.port_pond[pid].su_proc_id;

	circuit_id = pid / ISDN_CIRCUIT_CIC;
	offset = pid % ISDN_CIRCUIT_CIC;
	pst.cic = isdn_rs.circuit_pond[circuit_id].attrib.head_cic + offset;
	pst.cg_id = isdn_rs.circuit_pond[circuit_id].cg_id;
	pst.circuit_id = circuit_id;

	if((isdn_rs.port_pond[pid].cic_state.call_state == CALLOUT_FLAG && isdn_rs.circuit_pond[circuit_id].user_network_if == NETWORK_SIDE) || 
		(isdn_rs.port_pond[pid].cic_state.call_state == CALLIN_FLAG && isdn_rs.circuit_pond[circuit_id].user_network_if == USER_SIDE)) 
	{
		switch(cc_state[pid])
		{
			case 1:
				cc_state[pid] = 2;
				break;
			case 2:
				memcpy(&isdn_msg.msg_list.callProc.chnl_id, &isdn_rv_msg.msg_list.setup.chnl_id, sizeof(ChnlId));
/*				isdn_msg.msg_list.alert.prg_ind.pres = 1;
				isdn_msg.msg_list.alert.prg_ind.code_stan = 0;
				isdn_msg.msg_list.alert.prg_ind.loc = 3;
				isdn_msg.msg_list.alert.prg_ind.prg_descr = 8;
				isdn_alert_req(&pst, &isdn_msg.msg_list.alert);*/
				isdn_msg.msg_list.callProc.chnl_id.b3.pref_excl = 1;
				isdn_call_proc_req(&pst, &isdn_msg.msg_list.callProc);
				cc_state[pid] = 3;
				break;
			case 3:
				cc_state[pid] = 4;
				break;
			case 4:
				isdn_setup_resp(&pst, &isdn_msg.msg_list.conn);
				cc_state[pid] = 5;
				break;
			case 5:
				i++;
				if(i % 150 == 0)
				{
					i = 0;
					cc_state[pid] = 6;
				}
				break;
			case 6:
//				isdn_set_cause(&isdn_msg.msg_list.disc.cause, CAUSE_NORMAL);
//				isdn_disc_req(&pst, &isdn_msg.msg_list.disc);
				cc_state[pid] = 0;
				break;
			default:
				break;
		}
	}
	else if((isdn_rs.port_pond[pid].cic_state.call_state == CALLIN_FLAG && isdn_rs.circuit_pond[circuit_id].user_network_if == NETWORK_SIDE) || 
		(isdn_rs.port_pond[pid].cic_state.call_state == CALLOUT_FLAG && isdn_rs.circuit_pond[circuit_id].user_network_if == USER_SIDE))
	{
		switch(cc_state[pid])
		{
			case 1:
				i++;
				if(i % 400 == 0)
				{
					i = 0;
//					cc_state[pid] = 2;
				}
				break;
			case 2:
//				isdn_set_cause(&isdn_msg.msg_list.disc.cause, CAUSE_NORMAL);
//				isdn_disc_req(&pst, &isdn_msg.msg_list.disc);
				memcpy(&isdn_msg.msg_list.restart.chnl_id, &isdn_sd_msg.msg_list.setup.chnl_id, sizeof(ChnlId));
				isdn_msg.msg_list.restart.restart_ind.pres = 1;
				isdn_msg.msg_list.restart.restart_ind.clas = 0;
				isdn_m_restart_req(&pst, &isdn_msg.msg_list.restart);
				cc_state[pid] = 0;
				break;
			default:
				break;
		}
	}
}


static int flag[256] = {0};
void isdn_cc_setup_fsm(u16 circuit_id)
{
	static int i = 0;
	Pst pst;
	IsdnSetup setup;
	u8 cg_digit[] = {5,1,0,0,1};
	u8 cd_digit[] = {5,2,0,0,1};

	memset(&setup, 0, sizeof(IsdnSetup));	
	if(!flag[circuit_id])
	{
		flag[circuit_id] = 1;
		pst.circuit_id = circuit_id;
		pst.cg_id = isdn_rs.circuit_pond[circuit_id].cg_id;
		pst.su_proc_id = 0;
		
		setup.sd_comp.pres = 1;
		setup.br_cap.pres = 1;
		setup.br_cap.ext_flag = 1;
		setup.br_cap.code_stan = 0;
		setup.br_cap.tran_cap = 0;
		setup.br_cap.b4.tran_mode = 0;
		setup.br_cap.b4.tran_rate = 0x10;
		setup.br_cap.b5.usr_layer1 = 3;
		setup.br_cap.b5.has_ext_a = 1;		
		setup.chnl_id.pres = 1;
		setup.chnl_id.b3.int_id_pre = 0;
		setup.chnl_id.b3.int_type = 1;
		setup.chnl_id.b3.pref_excl = 0;
		setup.chnl_id.b3.chnl_ind = 0;
		setup.chnl_id.b3.info_chnl_sel = 1;
		setup.chnl_id.b3.code_stan = 0;
		setup.chnl_id.b3.num_map = 0;
		setup.chnl_id.b3.chnl_type = 3;
		setup.chnl_id.b3.chnl_num = 2;	//CIC
		setup.cg_pty_num.pres = 1;
		setup.cg_pty_num.b3.num_type = 0;
		setup.cg_pty_num.b3.num_plan_id = 0;
		setup.cg_pty_num.b3.has_ext_a = 0;
		setup.cg_pty_num.b3.pres_ind = 0;
		setup.cg_pty_num.b3.screen_ind = 0;
		setup.cg_pty_num.ext_flag = 1;
		setup.cg_pty_num.num_digit_len = sizeof(cg_digit);
		memcpy(&setup.cg_pty_num.num_digit, cg_digit, setup.cg_pty_num.num_digit_len);
		setup.cd_pty_num.pres = 1;
		setup.cd_pty_num.num_type = 0;
		setup.cd_pty_num.num_plan_id = 1;
		setup.cd_pty_num.num_digit_len = sizeof(cd_digit);
		memcpy(&setup.cd_pty_num.num_digit, cd_digit, setup.cd_pty_num.num_digit_len);

		setup.rpt_ind.pres = 1;
		setup.prg_ind.pres = 1;
		setup.prg_ind.loc = 3;
		setup.prg_ind.prg_descr = 8;
		setup.nt_sp_fac.pres = 1;
		setup.nt_sp_fac.b3.len_net_id = 2;
		setup.nt_sp_fac.b3.net_id_type = 2;
		setup.nt_sp_fac.b3.net_id_plan = 1;
		setup.nt_sp_fac.b3.net_id = 2; //?? {2,0,5}
		setup.nt_sp_fac.spec = 2;
//		setup.disp.pres = 1;
//		setup.disp.disp_info_len = 
		
		pst.cic = isdn_rs.circuit_pond[circuit_id].attrib.head_cic + setup.chnl_id.b3.chnl_num;
//		isdn_setup_req(&pst, &setup);
//		cc_state[pst.sp_proc_id] = 1;
	}

	if(++i == 700)	//more calls
	{
		i = 0;
		flag[circuit_id] = 0;
	}
}

void cc_timer()
{
	u16 i, j;
	u32 offset, pid;

	for(i = 0; i < ISDN_MAX_CIRCUIT; i++)	//for timer  
	{
		if(isdn_rs.circuit_pond[i].enable == 0)
			continue;
		if((isdn_rs.attrib.isdn_run_mode == 1) && 
			(isdn_rs.circuit_pond[i].attrib.plat_id != isdn_rs.attrib.systemID))
			continue;
		
		offset = ISDN_CIRCUIT_CIC * i;
		for(j = 0; j < ISDN_CIRCUIT_CIC; j++)
		{
			pid = offset + j;
			if(isdn_rs.port_pond[pid].enable == 1)
				isdn_cc_fsm(pid);
		}
		if(isdn_rs.circuit_pond[i].lk3_status == LK_IS)
			isdn_cc_setup_fsm(i);
	}

}




