/************************************************/
/*Title:	xuatest.c                           */
/*Descr:	Processor for xUA Unitest           */
/*Author:	Yi Zane                         */
/*Create:	2006-05-17                          */
/************************************************/
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <termio.h>
#include <sys/stat.h>
#include <sys/io.h>

#include "../../public/includes.h"
#include "../../public/asn1.h"
#include "../../public/function.h"
#include "../../debug/debug.h"
#include "../../snmp/snmp.h"
#include "../../iptrans/iptrans.h"
#include "../m2ua.h"
#define TEST_PORT		4955
#define xUA_HOST_IP		pBYTE[0],pBYTE[1],pBYTE[2],pBYTE[3]
#define xUA_CLIENT_IP		pBYTE[0],pBYTE[1],pBYTE[2],pBYTE[3]
static	 char				clientip[20];
static in_buffer		*inbuf;
static out_buffer		*outbuf;
struct itimerval		itimer,old_itimer;


void QueryUP();
void QueryIUA();
void QueryM2UA();
void On_Timer();
void SetTimer();
void init_shmPort_iptrans(WORD port,in_buffer ** inbuf,out_buffer **outbuf);
int recv_message(in_buffer *pbuf, message_list *pmsg);
int send_message(out_buffer *pbuf, message_list *pmsg);

//--------------------------------------------------
extern char				hostip[20];
extern char				hostname[50];
extern ulong			host_ip;
extern int 				iptrMainInit();
extern	int				m2ua_hex_to_ascii(BYTE *from_hex, BYTE from_len, BYTE *to_asc);

int main(int argc, char *argv[])
{
	pid_t		pid;
	BYTE*		pBYTE;

	if(argc==2 && strstr(argv[1],"-d"))
	{
		if((pid=fork())!=0)
			exit(0);
		setsid();
	}

	init_shmPort_iptrans(TEST_PORT,&inbuf,&outbuf);

	debug_init();
	heartbeat_init(0x0400);
	iptrMainInit();
	snmp_init(4957);
	m2ua_init();

	pBYTE	=	(BYTE*)&host_ip;

	{
		//link param
		//e1_to_linkset,e1_to_slc,e1_to_mtp3,e1_lk_type,e1_to_sg,e1_to_iid,remote_ip,inactive,inactive_tm,e1_to_alterMTP3
		BYTE		linkparam0[]={0x00,0x00,xUA_HOST_IP,0x07,0x00,0x00,xUA_HOST_IP,0x01,0x01,xUA_HOST_IP};		
		BYTE		linkparam1[]={0x01,0x01,xUA_HOST_IP,0x07,0x01,0x00,xUA_HOST_IP,0x01,0x01,xUA_HOST_IP};
		BYTE		linkparam2[]={0x02,0x02,xUA_HOST_IP,0x03,0x02,0x00,xUA_HOST_IP,0x01,0x01,xUA_HOST_IP};		
		BYTE		linkparam3[]={0x03,0x03,xUA_HOST_IP,0x03,0x03,0x00,xUA_HOST_IP,0x01,0x01,xUA_HOST_IP};		
		set_m2ua_link(0,linkparam0);
		set_m2ua_link(1,linkparam1);
		set_m2ua_link(2,linkparam2);
		set_m2ua_link(3,linkparam3);		
	}
#ifdef _testISDN	
	{
				BYTE		sgparam1[]={0x01,0x01,0x02,0xAC,0x36,0xF2,0x70};	//iua	-server  172.54.242.112
				BYTE		enable_lk[]={0xA5,0x01,0x03,0x00,0x07,0x00};	//iua	 A5 01 03 00 07 00
				set_m2ua_sg(1,sgparam1);	//sg=1  iua	-server	
				if(!put_xua_msg((xua_up_msg_t*)enable_lk))
				{
					printf("Put message to xUA. Msg_Class = 0x%x\n", *enable_lk);
				}
				else
					printf("Put message error\n");					
				
	}
#endif	

	SetTimer();

	while(1)
	{
		usleep(50);
	}
	return 1;
}

void QueryUP()
{
	message_list			msgbuf;
	BYTE						buf[256];
	BYTE						*iua_msg;
	BYTE						*pBYTE;
	static	BYTE						set_sgflag=1;
	if(recv_message(inbuf, &msgbuf)==0)
		return;
	printf("Receive Message From User:%ld\n",msgbuf.msgSrcIP);
	

	if(set_sgflag)
	{	
		pBYTE	=	(BYTE*)&msgbuf.msgSrcIP;
		sprintf(clientip,"%d.%d.%d.%d", xUA_CLIENT_IP);
#ifndef _testISDN		
		{
			//enable,server,xUA_ack,ip
			BYTE		sgparam0[]={0x01,0x00,0x02,xUA_CLIENT_IP};	//iua	-client			
			BYTE		sgparam1[]={0x01,0x01,0x02,xUA_CLIENT_IP};	//iua	-server
			BYTE		sgparam2[]={0x01,0x00,0x00,xUA_CLIENT_IP};	//m2ua	-client
			BYTE		sgparam3[]={0x01,0x01,0x00,xUA_CLIENT_IP};	//m2ua	-server
			
			set_m2ua_sg(0,sgparam0);	//sg=0  iua	-client
			set_m2ua_sg(1,sgparam1);	//sg=1  iua	-server	
			set_m2ua_sg(2,sgparam2);	//sg=2  m2ua	-client
			set_m2ua_sg(3,sgparam3);	//sg=3  m2ua	-server				
		}
#endif		
		set_sgflag = 0;		
	}

	
	memset(buf,0,sizeof(buf));
	iua_msg = buf+RESERVE_FOR_IUAHEAD;	
	#ifndef _testISDN		
		memcpy(iua_msg, msgbuf.msgContent, msgbuf.msgLength);
	#else
		memcpy(iua_msg+3, msgbuf.msgContent, msgbuf.msgLength);
		iua_msg[0]=IUA_QPTM_MSG;//msg_class
		iua_msg[1]=1;//LINK
		iua_msg[2]=msgbuf.msgLength+3;//len
	#endif		
			
	if(!put_xua_msg((xua_up_msg_t*)iua_msg))
	{
		printf("Put message to xUA. Msg_Class = 0x%x\n", *iua_msg);
	}
	else
		printf("Put message error\n");	
}

void QueryIUA()
{
	message_list			msgbuf;
	xua_up_msg_t			*msgToIUAup;
	int								msglen;
	BYTE						buf[256];

	if((msglen=get_xua_msg(IUA_APP,&msgToIUAup)) < 0)
			return;
	if(msgToIUAup->msg_class==IUA_MGMT_CMD)//hreatbeat
		return;	
	#ifndef _testISDN			
		memcpy(msgbuf.msgContent, msgToIUAup, msglen);
	#else
		memcpy(msgbuf.msgContent, msgToIUAup->msg.iua.content,msgToIUAup->msg.iua.len);
	#endif
	msgbuf.msgLength = msglen;
	msgbuf.msgDstIP = inet_addr(clientip);
	msgbuf.msgDstPort = TEST_PORT;
	msgbuf.msgSrcPort = TEST_PORT;
	m2ua_hex_to_ascii((BYTE *)msgToIUAup,msglen,buf);
	printf("\33[31mQueryIUA:%s\33[37m\n",buf);
	send_message(outbuf, &msgbuf); 
}

void QueryM2UA()
{
	message_list			msgbuf;
	m2ua_up_msg_t			*msgToM2UAup;
	int								msglen;
	BYTE						buf[256];

	if((msglen=get_m2ua_msg(&msgToM2UAup)) < 0)
		return;
	if(msgToM2UAup->sio==0xEF)//hreatbeat
		return;	
	memcpy(msgbuf.msgContent, msgToM2UAup,msgToM2UAup->len+2);
	msgbuf.msgLength = msgToM2UAup->len+2;
	msgbuf.msgDstIP = inet_addr(clientip);
	msgbuf.msgDstPort = TEST_PORT;
	msgbuf.msgSrcPort = TEST_PORT;
	m2ua_hex_to_ascii((BYTE *)msgToM2UAup,msgbuf.msgLength,buf);
	printf("\33[31mQueryIUA:%s\33[37m\n",buf);
	send_message(outbuf, &msgbuf); 
}


void On_Timer()
{
	iptrans_timer();
	snmp_timer();
	debug_rt();
	m2ua_timer();


	QueryUP();
	QueryIUA();
	QueryM2UA();
}

void SetTimer()
{
	struct sigaction	act;
	act.sa_handler=On_Timer;
	sigemptyset(&act.sa_mask);
	act.sa_flags=0;
	if(sigaction(SIGALRM,&act,NULL)<0)
	{
		perror("Produce Sigaction");
		exit(1);
	}
	
	itimer.it_interval.tv_sec=0;
	itimer.it_interval.tv_usec=10*1000;
	itimer.it_value.tv_sec=0;
	itimer.it_value.tv_usec=10*1000;

	if (setitimer(ITIMER_REAL,&itimer,&old_itimer) !=0 )
	{
		printf("Setting Timer  error! \n");
		exit(1);
	}
}


void init_shmPort_iptrans(WORD port,in_buffer ** inbuf,out_buffer **outbuf)
{
	int			shmid;
	static iptrans_shm		*pshm;

	if((shmid=shmget(IPTRANS_SHM_KEY,sizeof(iptrans_shm),IPTRANS_SHM_PERM))==-1)
	{
		if((shmid=shmget(IPTRANS_SHM_KEY,sizeof(iptrans_shm),IPTRANS_SHM_PERM|IPC_CREAT))==-1)
		{
			printf("fail to open share memory");
			exit(1);
		}
	}
	if((pshm=(iptrans_shm *)shmat(shmid,0,0))==(iptrans_shm *)-1)
	{
		printf("fail to attach share memory");
		exit(1);
	}

	*inbuf=&pshm->msgPortIn[port-PORT_BASE_NUM];
	(*inbuf)->msgReadSub = (*inbuf)->msgWriteSub=0;
	*outbuf=&pshm->msgPortOut;
	printf("init_shmPort_iptrans() complete...Port=%d\n",port);
}

int recv_message(in_buffer *pbuf, message_list *pmsg)
{
    if (pbuf->msgReadSub == pbuf->msgWriteSub)
        return 0;
    memcpy(pmsg, &pbuf->msgList[pbuf->msgReadSub], sizeof(message_list));
    pbuf->msgReadSub=(pbuf->msgReadSub+1)%IN_LIST_NUM;

	return 1;
}

int send_message(out_buffer *pbuf, message_list *pmsg)
{
    memcpy(&pbuf->msgList[pbuf->msgWriteSub], pmsg, sizeof(message_list));

    pbuf->msgWriteSub=(pbuf->msgWriteSub+1)%OUT_LIST_NUM;
  
    if (pbuf->msgReadSub == pbuf->msgWriteSub)
            pbuf->msgReadSub=(pbuf->msgReadSub+1)%OUT_LIST_NUM;
		
	return 1;
}

