#include "./include/8ecp.h"
#include <stdlib.h>
#include <stdio.h>
#include "./include/8ecp_debug.h"

SAP_In_8ECP SAPIn8ECP;
//time_t t[_8KE1_NUM];		//save the time when the heartbeat message of a 8KE1 was received.
BYTE	s_msg[128];
Card_Struct card_struct[_8KE1_NUM];
int _8ecp_bind (_8ECP_SAP * sap) 
{
	if (SAPIn8ECP.inUse == InUse)
	{
		perror ("unable to bind a SAP, because the SAP is in use.");
		return -1;
    }
	else	//If bind successful, save the user name and the functions
	{
		SAPIn8ECP.inUse = InUse;
		strcpy (SAPIn8ECP._8ecp_sap.name, (*sap).name);
		SAPIn8ECP._8ecp_sap.update_mg_status = sap->update_mg_status;
		SAPIn8ECP._8ecp_sap.update_trk_status = sap->update_trk_status;
		return 0;
    }
}
int _8ecp_unbind (BYTE sapIndex) 
{
	if (sapIndex != 0)
	{
		perror ("unable to unbind the SAP, because the SAP is not in use");
		return -1;
    }
	else				//If unbind successful, set the default value of SAPIn8ECP
	{
		SAPIn8ECP.inUse = NotInUse;
		memset (SAPIn8ECP._8ecp_sap.name, 0,
	    strlen (SAPIn8ECP._8ecp_sap.name));
		SAPIn8ECP._8ecp_sap.update_mg_status = NULL;
		SAPIn8ECP._8ecp_sap.update_trk_status = NULL;
		return 0;
    }
}

int _8ecp_createMG(WORD mgNo, DWORD ip, BYTE cardNo)
{
	card_struct[cardNo].mgNo = mgNo;
	card_struct[cardNo].ip = ip;
	return 1;
}


int _8ecp_deleteMG(WORD mgNo, DWORD ip, BYTE cardNo)
{
	if(card_struct[cardNo].ip != ip)
	{
		printf("the ip is not correct, in 8ecp the ip of card %d is: %ld\n", cardNo, card_struct[cardNo].ip);
		return 0;
	}
	if(card_struct[cardNo].mgNo != mgNo)
	{
		printf("the mgNo is not correct, in 8ecp the mgNo of card %d is: %d\n", cardNo, card_struct[cardNo].mgNo);
		return 0;
	}
	card_struct[cardNo].ip = 0;;
	card_struct[cardNo].mgNo = 0;
	return 1;
}


/*
calcurate the IP address where the 8ECP PDU will be sent to
*/ 
struct sockaddr_in getIP (WORD orgChnl) 
{
	//char ip3, ip[16];
	//WORD mgNo;
	BYTE cardNo;
	struct sockaddr_in s;
	/* ip3 = orgChnl / 256;		//the ID of the 8KE1
  	sprintf (ip, "172.18.%d.1", ip3);
	*/
	cardNo = orgChnl / 256;
	memset (&s, 0, sizeof (struct sockaddr));
	s.sin_family = AF_INET;
  	s.sin_port = htons (PORT);
  	s.sin_addr.s_addr = card_struct[cardNo].ip;
  	bzero (&(s.sin_zero), 8);
  	return s;
}
void _8ecp_connect_chnl (WORD orgChnl, WORD dstChnl, BYTE ecDisable) 
{
	//int i;
	DWORD tempip;
	_8ECP_PDU _8ecp_pdu;
	message_list msg_list;
	struct sockaddr_in sin_addr;
	BYTE temstr[15];
  	if (!SAPIn8ECP.inUse)
    {
		perror ("SAP is not bind!");
      	return;
    }
  	sin_addr = getIP (orgChnl);
  	memset (&_8ecp_pdu, 0, sizeof (struct _8ECP_PDU));
  	_8ecp_pdu.CPC_IFA_Inf = 0x87;
  	if (ecDisable == 0)
    	_8ecp_pdu.type = 0;
  	else if (ecDisable == 1)
    	_8ecp_pdu.type = 06;
  	 else
    {
      	perror ("the value of ecDisable is error!");
     	return;
    }
  	_8ecp_pdu.sourceTimeSlotNo = orgChnl % 256;	//the ID of the timeslot on the 8KE1
  	_8ecp_pdu.dstModuleID = dstChnl / 256;
  	_8ecp_pdu.dstTimeSlotNo = dstChnl % 256;
  	msg_list.msgSrcPort = PORT;
  	msg_list.msgDstIP = sin_addr.sin_addr.s_addr;
	tempip = ntohl(msg_list.msgDstIP);
  	msg_list.msgDstPort = PORT;
  	msg_list.msgLength = sizeof (_8ecp_pdu);
  	memcpy (msg_list.msgContent, &_8ecp_pdu, msg_list.msgLength);
  	memcpy(&temstr,&_8ecp_pdu, msg_list.msgLength);
	log_procedure(0, temstr);  //0:Send msg 1:recv msg
  	iptrPutMessage (msg_list);
}
void _8ecp_connect_dtmf (WORD orgChnl, WORD dstChnl, BYTE dtmfNo) 
{
  	struct sockaddr_in sin_addr;
	//int i;
	BYTE temstr[15];
  	_8ECP_PDU _8ecp_pdu;
  	message_list msg_list;
  	if (!SAPIn8ECP.inUse)
    {
      	perror ("SAP is not bind!");
      	return;
	}
  	sin_addr = getIP (orgChnl);
  	memset (&_8ecp_pdu, 0, sizeof (struct _8ECP_PDU));
  	_8ecp_pdu.CPC_IFA_Inf = 0x87;
  	_8ecp_pdu.type = 03;
  	_8ecp_pdu.sourceTimeSlotNo = orgChnl % 256;	//the ID of the timeslot on the 8KE1
  	_8ecp_pdu.dstModuleID = dstChnl / 256;
  	_8ecp_pdu.dstTimeSlotNo = dstChnl % 256;
  	_8ecp_pdu.Value = dtmfNo;
  	msg_list.msgSrcPort = PORT;
  	msg_list.msgDstIP = sin_addr.sin_addr.s_addr;
  	msg_list.msgDstPort = PORT;
  	msg_list.msgLength = sizeof (_8ecp_pdu);
  	memcpy (msg_list.msgContent, &_8ecp_pdu, msg_list.msgLength);
  	memcpy(&temstr, &_8ecp_pdu, msg_list.msgLength);
	log_procedure(0, temstr);
  	iptrPutMessage (msg_list);
}
void _8ecp_connect_tone (WORD orgChnl, WORD dstChnl, BYTE toneNo, WORD duration) 
{
  	struct sockaddr_in sin_addr;
	//int i;
	BYTE temstr[15];
  	_8ECP_PDU _8ecp_pdu;
  	message_list msg_list;
  	sin_addr = getIP (orgChnl);
  	if (!SAPIn8ECP.inUse)
    {
      	perror ("SAP is not bind!");
      	return;
    }
  	sin_addr = getIP (orgChnl);
  	memset (&_8ecp_pdu, 0, sizeof (struct _8ECP_PDU));
  	_8ecp_pdu.CPC_IFA_Inf = 0x87;
  	_8ecp_pdu.type = 2;
  	_8ecp_pdu.sourceTimeSlotNo = orgChnl % 256;	//the ID of the timeslot on the 8KE1
  	_8ecp_pdu.dstModuleID = dstChnl / 256;
  	_8ecp_pdu.dstTimeSlotNo = dstChnl % 256;
  	_8ecp_pdu.Value = toneNo;
  	_8ecp_pdu.duration = duration;
  	msg_list.msgSrcPort = PORT;
  	msg_list.msgDstIP = sin_addr.sin_addr.s_addr;
  	msg_list.msgDstPort = PORT;
  	msg_list.msgLength = sizeof (_8ecp_pdu);
  	memcpy (msg_list.msgContent, &_8ecp_pdu, msg_list.msgLength);
  	memcpy(&temstr, &_8ecp_pdu, msg_list.msgLength);
	log_procedure(0, temstr);
  	iptrPutMessage (msg_list);
}
void _8ecp_timer () 
{
  
	_8ecp_mon ();
}
int trap_proc (BYTE oid_len, DWORD * oid_ptr, BYTE * pdata, BYTE msg_len,
	   snmp_addr * addr) 
{
  	DWORD * oid_in;
  	WORD mgNo;
  	BYTE cardNo;
  	BYTE  temstr[128];
  	//int i, index;
  	//time_t now;
  	if(oid_ptr[10] != 1)
  		return 0;
  	if(oid_ptr[11] != 1)
  		return 0;
  	if(oid_ptr[12] != 4)
  		return 0;
  
 	log_procedure(1, pdata); 
  
  	memset(&temstr, 0, sizeof(temstr));
  	oid_in = oid_ptr + OID_Prefix;
  	cardNo = E1NumOnCSU * pdata[0] + pdata[1];
  	mgNo = card_struct[cardNo].mgNo;
  	if ((SAPIn8ECP._8ecp_sap.update_mg_status == NULL)||(mgNo == 0))
    	return 0;
  	else
  		SAPIn8ECP._8ecp_sap.update_mg_status (mgNo, 1);
  	if ((SAPIn8ECP._8ecp_sap.update_trk_status == NULL) || (mgNo ==0))
    	return 0;
  	else
  	{
  		{
  			if(pdata[25]&0x01)
  				SAPIn8ECP._8ecp_sap.update_trk_status (mgNo, 0, 1);	//trk on MG is nok
  			else
  				SAPIn8ECP._8ecp_sap.update_trk_status (mgNo, 0, 0);	//trk on MG is nok
  		}
  		{
  			if(pdata[25]&0x02)
  				SAPIn8ECP._8ecp_sap.update_trk_status (mgNo, 1, 1);	//trk on MG is nok
  			else
  				SAPIn8ECP._8ecp_sap.update_trk_status (mgNo, 1, 0);	//trk on MG is nok
  		}
  		{
  			if(pdata[25]&0x04)
  				SAPIn8ECP._8ecp_sap.update_trk_status (mgNo, 2, 1);	//trk on MG is nok
  			else
  				SAPIn8ECP._8ecp_sap.update_trk_status (mgNo, 2, 0);	//trk on MG is nok
  		}
  		{
  			if(pdata[25]&0x08)
  				SAPIn8ECP._8ecp_sap.update_trk_status (mgNo, 3, 1);	//trk on MG is nok
  			else
  				SAPIn8ECP._8ecp_sap.update_trk_status (mgNo, 3, 0);	//trk on MG is nok
  		}
  		{
  			if(pdata[25]&0x10)
  				SAPIn8ECP._8ecp_sap.update_trk_status (mgNo, 4, 1);	//trk on MG is nok
  			else
  				SAPIn8ECP._8ecp_sap.update_trk_status (mgNo, 4, 0);	//trk on MG is nok
  		}
  		{
  			if(pdata[25]&0x20)
  				SAPIn8ECP._8ecp_sap.update_trk_status (mgNo, 5, 1);	//trk on MG is nok
  			else
  				SAPIn8ECP._8ecp_sap.update_trk_status (mgNo, 5, 0);	//trk on MG is nok
  		}
  		{
  			if(pdata[25]&0x40)
  				SAPIn8ECP._8ecp_sap.update_trk_status (mgNo, 6, 1);	//trk on MG is nok
  			else
  				SAPIn8ECP._8ecp_sap.update_trk_status (mgNo, 6, 0);	//trk on MG is nok
  		}
  		{
  			if(pdata[25]&0x80)
  				SAPIn8ECP._8ecp_sap.update_trk_status (mgNo, 7, 1);	//trk on MG is nok
  			else
  				SAPIn8ECP._8ecp_sap.update_trk_status (mgNo, 7, 0);	//trk on MG is nok
  		}  		  		
  	}
	return 0;
}
void _8ecp_init () 
{
  	printf ("8ECP init start!\n");
  	SAPIn8ECP.inUse = NotInUse;
  	memset (SAPIn8ECP._8ecp_sap.name, 0, sizeof (SAPIn8ECP._8ecp_sap.name));
  	SAPIn8ECP._8ecp_sap.update_mg_status = NULL;
  	SAPIn8ECP._8ecp_sap.update_trk_status = NULL;
  	//memset (&t, 0, sizeof (t));
  	memset(&card_struct, 0, sizeof(Card_Struct));
  	_8ecp_debug_set ();
  	inquire_trapmsg ((void *) trap_proc);	//register, get heartbeat msg
  	printf ("8ECP init complete!\n");
}


