/*      XAPP coding test function c file        */
/*      created by Liu Wei  2006-01-13          */
/*      Version 1.0                             */
/*      -------------------------------------   */

#include "xapp_coding_test.h"
#include "xapp_main.h"

CAP_Message CAP_Com_OpenResponse = {
     {0, 16}
     ,
     CAP_FLAG,
     {0, 0, 0}
     ,
     {0, 0, 0}
     ,
     CAP_O_OPEN,                //CAP_O_OPEN,
     CAP_RESPONSE,              //RESPONSE,
     {2,                        //RESULT=accept
               1,               //
               1,               //acn tag
               2,               //len
               50,              //acn
               2,               //acn version
          0,}                   //end flag
};

CAP_Message CAP_Com_End = {
     {0, 12}
     ,
     CAP_FLAG,
     {0, 0, 0}
     ,
     {0, 0, 0}
     ,
     CAP_O_END,                 //CAP_O_END,
     CAP_REQUEST,               //REQUEST,
     {1,                        //release method
               0,               //optional part
          0,}
};

int bcd_hton(BYTE * netbcd, const BYTE * hostbcd, BYTE max_octet)
{
     int  i;
     BYTE bcd_h, bcd_l;

     for(i = 0; i < max_octet; i++)
     {
          if((bcd_h = hostbcd[i] >> 4) == 0x0f)
               return i * 2;
          else if((bcd_l = hostbcd[i] & 0x0f) == 0x0f)
          {
               netbcd[i] = bcd_h & 0x0f;
               return i * 2 + 1;
          }
          else
               netbcd[i] = (bcd_l << 4) | bcd_h;
     }
     return i * 2;
}

/* end by "F" */
int bcd_ntoh(BYTE * hostbcd, const BYTE * netbcd, BYTE max_octet)
{
     int  i;
     int  bcd_h, bcd_l;

     for(i = 0; i < max_octet; i++)
     {
          if((bcd_h = netbcd[i] & 0x0f) == 0x0f)
          {
               memset(&hostbcd[i], 0xff, max_octet - i);
               return i * 2;
          }
          else if((bcd_l = netbcd[i] >> 4) == 0x0f)
          {
               hostbcd[i] = (bcd_h << 4) | 0x0f;
               memset(&hostbcd[i + 1], 0xff, max_octet - i - 1);
               return i * 2 + 1;
          }
          else
          {
               hostbcd[i] = (bcd_h << 4) | bcd_l;
          }
     }
     return i * 2;
}

void isdn_aton(u8 *normal_isdn,u8 *anti_isdn)
{
	u8		ii;
	u8		aa=0,bb=0;
	u8		isdn_len;

	isdn_len = anti_isdn[0];
	if (isdn_len > ISDN_LEN)
		isdn_len = ISDN_LEN;
	normal_isdn[0] = anti_isdn[1];
	for (ii = 1;ii < isdn_len;ii ++)
	{
		if ((anti_isdn[ii+1] & 0x0f) >= 0x0e)
			break;
		aa = (anti_isdn[ii+1] & 0x0f0) >> 4;
		if (aa > 0x0c)
			aa = 0x0e;
		bb = anti_isdn[ii+1] & 0x0f;
		normal_isdn[ii] = (bb << 4) + aa;
	}
	for (;ii < ISDN_LEN;ii ++)
		normal_isdn[ii] = 0x0ee;
}

void imsi_aton(u8 *normal_imsi,u8 *anti_imsi)
{	// the IMSI must 15 digits
	u8		ii;
	u8		aa,bb=0;

	normal_imsi[0] = 0;
	for (ii = 0;ii < IMSI_LEN*2;ii++)
	{
		if ((ii % 2) == 1)
		{
			aa = anti_imsi[ii/2] & 0x0f;
			normal_imsi[ii/2] |= aa;
		}
		else
		{
			if (ii/2 != IMSI_LEN -1)
			{
				bb = anti_imsi[ii/2] & 0x0f0;
				normal_imsi[ii/2+1] = bb;
			}
		}
	}
}

/*	+++++++++++++++++++++++++++++++++++++++++++++++++	*/
/*	transfer IMSI format from normal to anti sequence	*/
/*	0460022157127001 --> 64002251177200f1				*/
/*	+++++++++++++++++++++++++++++++++++++++++++++++++	*/
void imsi_ntoa(u8 *anti_imsi,u8 *normal_imsi)
{
	u8		ii;
	u8		aa,bb=0;

	for (ii = 1;ii <= IMSI_LEN*2;ii++)
	{
		if ((ii % 2) == 1)
			bb = normal_imsi[ii/2] & 0x0f;
		else
		{
			if (ii == IMSI_LEN * 2)
				aa = 0x0f0;
			else
				aa = normal_imsi[ii/2] & 0x0f0;
			anti_imsi[ii/2-1] = aa | bb;
		}
	}
}

/*	+++++++++++++++++++++++++++++++++++++++++++++++++	*/
/*	transfer IMSI format from normal to ascii string	*/
/*	0460022157127001 --> "460022157127001"				*/
/*	+++++++++++++++++++++++++++++++++++++++++++++++++	*/
void imsi_ntos(u8 *str_imsi,u8 *normal_imsi)
{
	u8		len;
	u8		ii,jj;
	
	str_imsi[0] = (normal_imsi[0] & 0x0f) + '0';
	len = 1;
	for (ii = 1;ii < IMSI_LEN;ii ++)
	{
		jj = (normal_imsi[ii] >> 4) & 0x0f;
		str_imsi[len++] = jj + '0';
		jj = normal_imsi[ii] & 0x0f;
		str_imsi[len++] = jj + '0';
	}
	str_imsi[len] = '\0';
}

/*	+++++++++++++++++++++++++++++++++++++++++++++++++	*/
/*	transfer IMSI format from ascii string to normal	*/
/*	"460022157127001" --> 0460022157127001				*/
/*	+++++++++++++++++++++++++++++++++++++++++++++++++	*/
void imsi_ston(u8 *normal_imsi,u8 *str_imsi)
{
	if (strlen(str_imsi) != IMSI_LEN*2-1)
		return;
	normal_imsi[0] = str_imsi[0] - '0';
	AsciiToBcd(normal_imsi+1,str_imsi+1,IMSI_LEN*2-2);
}
/*	+++++++++++++++++++++++++++++++++++++++++++++++++	*/
/*	transfer ISDN format from normal to ascii string	*/
/*	918675557127001EEE --> "8675557127001"				*/
/*	+++++++++++++++++++++++++++++++++++++++++++++++++	*/
void isdn_ntos(u8 *str_isdn,u8 *normal_isdn)
{
	u8		len = 0;
	u8		ii,jj;

	for (ii = 1;ii < ISDN_LEN;ii ++)
	{
		jj = (normal_isdn[ii] >> 4) & 0x0f;
		if (jj > 0x0c)
			break;
		str_isdn[len++] = jj + '0';
		jj = normal_isdn[ii] & 0x0f;
		if (jj > 0x0c)
			break;
		str_isdn[len++] = jj + '0';
	}
	str_isdn[len] = '\0';
}

void isdn_ntoa(u8 * anti_isdn, u8 * normal_isdn)
{
     u8   ii;
     u8   aa = 0, bb = 0;
     u8   len;

     anti_isdn[1] = normal_isdn[0];     // nature of address and numbering plan indicator
     len = 1;
     for(ii = 1; ii < ISDN_LEN; ii++)
     {
          if(normal_isdn[ii] == 0xee)
               break;
          else
          {
               aa = (normal_isdn[ii] & 0x0f0) >> 4;
               bb = normal_isdn[ii] & 0x0f;
               if(bb > 0x0c)
                    bb = 0x0f;
               anti_isdn[ii + 1] = (bb << 4) + aa;
               len++;
          }
     }
     anti_isdn[0] = len;
}

/*	+++++++++++++++++++++++++++++++++++++++++++++++++	*/
/*	transfer ISDN format from ascii string to normal	*/
/*	"8675557127001" --> 918675557127001EEE				*/
/*	return value: 0--string has error; 1--success		*/
/*	+++++++++++++++++++++++++++++++++++++++++++++++++	*/
u8 isdn_ston(u8 *normal_isdn,u8 *str_isdn)
{
	u8		ii;
	u8		len;

	len = strlen(str_isdn);
	if (len > ISDN_LEN*2-2)
		return 0;
	if ((len % 2) == 1)		// odd number
	{
		AsciiToBcd(normal_isdn+1,str_isdn,len-1);
		ii = len/2 + 1;
		normal_isdn[ii] = (str_isdn[len-1] - '0') << 4;
		normal_isdn[ii] |= 0x0E;
	}
	else
	{
		AsciiToBcd(normal_isdn+1,str_isdn,len);
		ii = len/2;
	}
	memset(normal_isdn+ii+1,0xEE,ISDN_LEN-ii-1);
	normal_isdn[0] = 0x91;	// default value
	return 1;
}


u8 set_gtai_isdn(u8 * gtai, u8 * isdn)
{
     u8   temp_buf[32];
     u8   ii;
     u8   len;

     isdn_ntoa(temp_buf, isdn);
     ii = temp_buf[0];
     memcpy(gtai, temp_buf + 2, ii - 1);
     if((temp_buf[ii] & 0x0f0) == 0x0f0)
          len = ii * 2 - 3;
     else
          len = ii * 2 - 2;
     return len;
}

void xapp_set_sccpadd(u8 ssn, u8 * gtt_num, struct SCCP_ADDRESS *sccp_add)
{
     sccp_add->DPC = 0;         // set SCCP address
     sccp_add->NetID = 4;
     sccp_add->SSN = ssn;
     sccp_add->RI = 0;
     sccp_add->GTI = 0x04;
     sccp_add->TT = 0;
     sccp_add->NAI = 4;
     sccp_add->NP = 1;          // MSISDN
     sccp_add->len = set_gtai_isdn(sccp_add->GTAI, gtt_num);
}

u8 get_mapp_open(struct MapComSrv_struct *com_ptr, u8 ssn)
{
     u8   data_flow[1024];

     if(!map_get_open(data_flow, ssn))
          return 0;
     if(!map_com_ftos(com_ptr, data_flow))
          return 0;
     printf("-->>: Recv OpenInd !\r\n");
     return 1;
}

u8 send_mapp_comdata(struct MapComSrv_struct * com_ptr, u8 DelimiterFlag)
{
     u8   data_flow[1024];

     map_com_stof(com_ptr, data_flow, DelimiterFlag);
     return map_send_comdata(data_flow);
}

u8 recv_mapp_comdata(struct MapComSrv_struct * com_ptr, u32 did)
{
     u8   data_flow[1024];

     if(!map_get_comdata(data_flow, did))
          return 0;
     if(!map_com_ftos(com_ptr, data_flow))
          return 0;
     return 1;
}

int send_mapp_oprdata(struct MapOprData_struct *opr_ptr, u8 DelimiterFlag)
{
     u8   data_flow[1024];

     map_opr_stof(opr_ptr, data_flow, DelimiterFlag);
     return map_send_oprdata(data_flow);
}

int recv_mapp_oprdata(struct MapOprData_struct *opr_ptr, u32 did)
{
     u8   data_flow[1024];

     if(!map_get_oprdata(data_flow, did))
          return 0;
     if(!map_opr_ftos(opr_ptr, data_flow))
          return 0;
     return 1;
}

int send_mapp_open_req(WORD dialog_id)
{
     struct MapComSrv_struct map_com;

     map_com.message_type = MAP_OPEN;
     map_com.message_flag = MAP_REQUEST;
     map_com.port_id = 0;
     map_com.dialogue_id = test_xapp.did;
     map_com.dlg_list.open_arg.acn_data.acn = 0;
     map_com.dlg_list.open_arg.acn_data.acn_ver = 1; 
     memcpy(&map_com.dlg_list.open_arg.local_add, &test_xapp.local_add, sizeof(SCCP_ADDR));
     memcpy(&map_com.dlg_list.open_arg.peer_add, &test_xapp.peer_add, sizeof(SCCP_ADDR));
     map_com.dlg_list.open_arg.param_flag = 0x0b;
     send_mapp_comdata(&map_com, 1);
     printf("<<--: Send OpenReq !\r\n");
     return 1;
}

int send_mapp_open_conf()
{
     struct MapComSrv_struct map_com;
     struct MapOpen_Res *open_res;

     map_com.message_type = MAP_OPEN;
     map_com.message_flag = MAP_RESPONSE;
     map_com.port_id = 0;
     map_com.dialogue_id = test_xapp.did;
     map_com.dlg_list.open_arg.acn_data.acn = 0;
     map_com.dlg_list.open_arg.acn_data.acn_ver = 1;
     memcpy(&map_com.dlg_list.open_arg.local_add, &test_xapp.local_add, sizeof(SCCP_ADDR));
     memcpy(&map_com.dlg_list.open_arg.peer_add, &test_xapp.peer_add, sizeof(SCCP_ADDR));
     open_res = (MapOpen_Res *) & map_com.dlg_list.open_res;
     open_res->result = OpenResultAccept;
     open_res->param_flag = 0x08;
     if(send_mapp_comdata(&map_com, 1))
     {
          printf("<<--: Send OpenConf !\r\n");
          return 1;
     }
     return 0;
}

int send_mapp_close(WORD dialog_id)
{

     struct MapComSrv_struct map_com;

     map_com.message_type = MAP_CLOSE;
     map_com.message_flag = MAP_REQUEST;
     map_com.port_id = 0;
     map_com.dialogue_id = test_xapp.did;
     map_com.dlg_list.open_arg.acn_data.acn_ver = 1;
     memcpy(&map_com.dlg_list.open_arg.local_add, &test_xapp.local_add, sizeof(SCCP_ADDR));
     memcpy(&map_com.dlg_list.open_arg.peer_add, &test_xapp.peer_add, sizeof(SCCP_ADDR));
     map_com.dlg_list.close_arg.release_method = NormalRelease;
     map_com.dlg_list.close_arg.param_flag = 0x01;
     send_mapp_comdata(&map_com, 1);
     printf("<<--: Send Close !\r\n");
     return 1;
}

u8 get_capp_open(struct MapComSrv_struct * com_ptr, u8 ssn)
{
     u8   data_flow[1024];

     if(!cap_get_open(data_flow, ssn))
          return 0;
     if(!cap_com_ftos(com_ptr, data_flow))
          return 0;
     printf("-->>: Recv OpenInd !\r\n");
     return 1;
}

u8 send_capp_comdata(struct MapComSrv_struct * com_ptr, u8 DelimiterFlag)
{
     u8   data_flow[1024];

     cap_com_stof(com_ptr, data_flow, DelimiterFlag);
     return cap_send_comdata(data_flow);
}

u8 recv_capp_comdata(struct MapComSrv_struct * com_ptr, u32 did)
{
     u8   data_flow[1024];

     if(!cap_get_comdata(data_flow, did))
          return 0;
     if(!cap_com_ftos(com_ptr, data_flow))
          return 0;
     return 1;
}

int send_capp_oprdata(struct MapOprData_struct *opr_ptr, u8 DelimiterFlag)
{
     u8   data_flow[1024];

     cap_opr_stof(opr_ptr, data_flow, DelimiterFlag);
     return cap_send_oprdata(data_flow);
}

int recv_capp_oprdata(struct MapOprData_struct *opr_ptr, u32 did)
{
     u8   data_flow[1024];

     if(!cap_get_oprdata(data_flow, did))
          return 0;
     if(!cap_opr_ftos(opr_ptr, data_flow))
          return 0;
     return 1;
}

/*
   u8 send_capp_oprdata(CAP_Message *pcapmsg , u8 len)
   {    
   pcapmsg->msgOperaCode = test_xapp.operation_type;
   pcapmsg->msgServiceCode = 0x8a;
   pcapmsg->msgOperaType = MAP_REQUEST;
   pcapmsg->msgContent[0] =  test_xapp.invoke_id;
   pcapmsg->msgContent[1] = 1;          //pointer to paramter
   pcapmsg->msgContent[2] = 1;          //Tag of parameter
   pcapmsg->msgContent[3] = 0;          //length1
   pcapmsg->msgContent[4] = len;        //length2
   pcapmsg->msgContent[5 + len] = 0x10; //delimiter
   pcapmsg->msgContent[6 + len] = 0;
   pcapmsg->msgContent[7 + len] = 0;

   pcapmsg->msgLength[0] = 0;
   pcapmsg->msgLength[1] = 17 + len;
   if(!cap_send_oprdata((char *)pcapmsg))
   {
   return 0;
   }
   return 1;
   }

   u8   recv_capp_oprdata(CAP_Message *capmsg , u32 did) 
   {
   return cap_get_oprdata((unsigned char *)capmsg, did);
   }
 */
int send_capp_open_req(unsigned char acn, unsigned char acn_v, unsigned short dlgid)
{
     struct MapComSrv_struct map_com;

     map_com.message_type = CAP_O_OPEN;
     map_com.message_flag = CAP_REQUEST;
     map_com.port_id = 0;
     map_com.dialogue_id = test_xapp.did;
     map_com.dlg_list.open_arg.acn_data.acn = acn;
     map_com.dlg_list.open_arg.acn_data.acn_ver = 1;
     memcpy(&map_com.dlg_list.open_arg.local_add, &test_xapp.local_add, sizeof(SCCP_ADDR));
     memcpy(&map_com.dlg_list.open_arg.peer_add, &test_xapp.peer_add, sizeof(SCCP_ADDR));
     map_com.dlg_list.open_arg.param_flag = 0x0b;
     send_capp_comdata(&map_com, 1);
     printf("<<--: Send OpenReq !\r\n");
     return 1;
}

void send_capp_open_conf(unsigned char acn, unsigned char acn_v, unsigned short dlgid)
{
     CAP_Message capmsg;

     memcpy(&capmsg, &CAP_Com_OpenResponse, 18);
     capmsg.dialogue_id[0] = dlgid >> 8;
     capmsg.dialogue_id[1] = dlgid;
     capmsg.msgContent[4] = acn;
     capmsg.msgContent[5] = acn_v;
     cap_send_comdata((unsigned char *)&capmsg);
}

void send_capp_close(unsigned short dlgid)
{
     CAP_Message capmsg;

     memcpy(&capmsg, &CAP_Com_End, 14);
     capmsg.dialogue_id[0] = dlgid >> 8;
     capmsg.dialogue_id[1] = dlgid;
     cap_send_comdata((unsigned char *)&capmsg);
}

int build_xapp_msg()
{
     if(test_xapp.xapp_type)
     {
          int  len;
          struct CapArg *cap_opr;
          struct MapOprData_struct *data_ptr;
          u8   buf[1024];

          cap_opr = &test_xapp.xapp.capp.cap_opr;
          data_ptr = &test_xapp.xapp.capp.data_ptr;

          data_ptr->port_id = cap_opr->port_id;
          data_ptr->dialogue_id = cap_opr->dialogue_id;
          data_ptr->invoke_id = cap_opr->invoke_id;
          data_ptr->message_type = cap_opr->ocode;
          data_ptr->message_flag = cap_opr->message_flag;
          data_ptr->param_flag = 0x1f;

          len = encode_capmsg(*cap_opr, buf, MAX_MAPPOPR_LEN);
          if(len == 0 || len > MAX_MAPPOPR_LEN)
               return 0;
          data_ptr->param_len = len;

          memcpy(data_ptr->param, buf, len);
          data_ptr->param_flag |= 0x20;
          return len;
     }
     else
     {
          struct MapOprData_struct *data_ptr;
          struct MapOprSrv_struct *srv_ptr;
          int  len;
          u8   buf[1024];

          data_ptr = &test_xapp.xapp.mapp.data_ptr;
          srv_ptr = &test_xapp.xapp.mapp.map_opr;

          data_ptr->port_id = srv_ptr->port_id;
          data_ptr->dialogue_id = srv_ptr->dialogue_id;
          data_ptr->invoke_id = srv_ptr->invoke_id;
          data_ptr->message_type = srv_ptr->message_type;
          data_ptr->message_flag = srv_ptr->message_flag;
          //data_ptr->linked_id =1;
          data_ptr->param_flag = 0x1f;

          len = build_mapparam(srv_ptr, buf);
          if(len == 0 || len > MAX_MAPPOPR_LEN) 
               return 0;
          data_ptr->param_len = len;

          memcpy(data_ptr->param, buf, len);
          data_ptr->param_flag |= 0x20;
          return len;
     }
     return 0;
}

int extract_xapp_msg()
{
     if(test_xapp.xapp_type)
     {
          int  len;
          struct CapArg *cap_opr;
          struct MapOprData_struct *data_ptr;

          data_ptr = &test_xapp.xapp.capp.data_ptr;
          cap_opr = &test_xapp.xapp.capp.cap_opr;

          cap_opr->port_id = data_ptr->port_id;
          cap_opr->dialogue_id = data_ptr->dialogue_id;
          cap_opr->invoke_id = data_ptr->invoke_id;
          cap_opr->ocode = data_ptr->message_type;
          cap_opr->message_flag = data_ptr->message_flag;

          decode_capmsg(data_ptr->param, data_ptr->param_len, cap_opr->ocode, cap_opr->message_flag, cap_opr);
          return len;
     }
     else
     {
          struct MapOprData_struct *data_ptr;
          struct MapOprSrv_struct *srv_ptr;

          data_ptr = &test_xapp.xapp.mapp.data_ptr;
          srv_ptr = &test_xapp.xapp.mapp.map_opr;

          srv_ptr->port_id = data_ptr->port_id;
          srv_ptr->dialogue_id = data_ptr->dialogue_id;
          srv_ptr->invoke_id = data_ptr->invoke_id;
          srv_ptr->message_type = data_ptr->message_type;
          srv_ptr->message_flag = data_ptr->message_flag;
          if(!(data_ptr->param_flag & 0x20))    // has not parameter
               return RER;
          extract_mapparam(srv_ptr, data_ptr->message_type, data_ptr->message_flag, data_ptr->param_len, data_ptr->param);
          return ROK;
     }
     return RER;
}


void extract_sri()
{
	struct MapOprSrv_struct opr_ptr;
	u8 opr_code = SndRoutInfo;
	u8 opr_flag = MAP_CONFIRM;
	u32 pre_param_len= 21;
	u8  *pre_param;
	u8	buf[256],temp_buf[256];
	u8	str[256]="A313890864009200000083F10407916857951230F7";
	
	Str2Bcd( buf ,str ,pre_param_len );   
	

	Bcd2Str_Space(temp_buf, str,pre_param_len); 
	printf("\r\nextract code :[%d] len :[%ld]\r\n%s\r\n",opr_code,pre_param_len,str);

	pre_param = (u8*)&buf; 
	opr_ptr.version =3;
	extract_mapparam( &opr_ptr, opr_code , opr_flag , pre_param_len , pre_param );
    
}
