/*      XAP provider interface c file           */
/*      Written by Liu Zhiguo 2003-08-26        */
/*      Version 1.0                                                     */
/*      --------------------------------        */
#include "../../public/src/include/public.h"
#include "../../public/src/include/license_id.h"
#include "../../tcap/src/include/itcap.h"
#include "../../tcap/src/include/idmanage.h"
#include "xap_provider.h"
#include "xap_monitor.h"
#include "mapp/map_public.h"
#include "capp/cap_public.h"

extern int itcap_reg_ssn(u8 ssn);
int xap_mscid_to_num ( u8 * mscid, u8 ssn, u8 * num )
{
    int i;

    for ( i = 0; i < 256; i++ )
    {
        if( ( memcmp ( mscid, xap_inter_ptr->mscidToNum[i], 3 ) == 0 ) && ( xap_inter_ptr->mscidToNum[i][3] == ssn ) )
        {
            memcpy ( num, xap_inter_ptr->mscidToNum[4], 10 );
            return 1;
        }
    }
    return 0;
}

void xap_get_mcc ( u8 * mcc )
{
    memcpy ( mcc, xap_inter_ptr->mcc, 2 );
}

void xap_get_mnc ( u8 * mnc )
{
    memcpy ( mnc, &xap_inter_ptr->mnc, 2 );
}

void xap_get_cc ( u8 * cc )
{
    memcpy ( cc, xap_inter_ptr->cc, 2 );
}

void xap_get_ndc ( u8 * ndc )
{
    memcpy ( ndc, xap_inter_ptr->ndc, 3 );
}

void xap_get_interprefix ( u8 * inter_prefix )
{
    memcpy ( inter_prefix, xap_inter_ptr->inter_prefix, 2 );
}

void xap_get_nationalprefix ( u8 * national_prefix )
{
    memcpy ( national_prefix, xap_inter_ptr->national_prefix, 2 );
}

void xap_get_localprefix ( u8 * local_prefix )
{
    memcpy ( local_prefix, xap_inter_ptr->local_prefix, 2 );
}

int imap_reg_ssn ( u8 ssn )
{
    u8  ii, jj;

    ii = xap_inter_ptr->regssn_len;
    if( ii >= MAX_XAP_SSN )
    {
        xap_send_error ( "Can not register ssn in map provider" );
        return -1;
    }
    for ( jj = 0; jj < ii; jj++ )
    {
        if( xap_inter_ptr->reg_ssn[jj] == ssn )
        {
            xap_send_error ( "ssn has registered in map provider" );
            return -1;
        }
    }
    xap_inter_ptr->reg_ssn[ii] = ssn;
    xap_inter_ptr->regssn_flag[ii] = XAP_MAP_SSN;
    xap_inter_ptr->regssn_len++;
    return itcap_reg_ssn ( ssn );
}

u8 map_check_sendcom ( u32 did )
{
    struct xapp_vm_data *vm_ptr;

    if( did >= ( xap_vm_ptr->grantdid ) )
        return 0;
    vm_ptr = ( xapp_vm_data * ) & xap_vm_ptr->xap_data[did];
    if( vm_ptr->recvcom_flag == 0 )
        return 1;
    return 0;
}

u8 map_send_comdata_struct ( MapComSrv_struct * map_com )       // send map common service data
{
    u32 temp_did;
    struct xapp_vm_data *vm_ptr;
    struct psmvm_data *psm_ptr;

    if( xap_vm_ptr->debug_data.send_control )
    {
        u8  data_flow[512];

        map_com_stof ( map_com, data_flow, 1 );
        xap_send_error ( "[%d]Sending Com:%d in Structure", map_com->dialogue_id, map_com->message_type );
        xap_msg_display ( data_flow );
    }

    temp_did = map_com->dialogue_id;
    if( temp_did >= ( xap_vm_ptr->grantdid ) )
    {
        xap_send_error ( "[%d]Com:%d sending did error", temp_did, map_com->message_type );
        return 0;
    }
    vm_ptr = ( xapp_vm_data * ) & xap_vm_ptr->xap_data[temp_did];
    if( ( vm_ptr->recvcom_flag == 1 ) && ( map_com->message_type != MAP_U_ABORT ) )     /* daniel change on 2005-4-29 */
    {
        xap_send_error ( "[%d]Com:%d sending without permit", temp_did, map_com->message_type );
        return 0;
    }
    psm_ptr = ( psmvm_data * ) & vm_ptr->psm_data;
    //      if (result == 2 || map_com->message_type == MAP_DELIMITER)
    psm_ptr->delimiter_flag = 1;
    if( map_com->message_type != MAP_DELIMITER )
    {
        memcpy ( &vm_ptr->recvcom_data, map_com, sizeof ( MapComSrv_struct ) );
        psm_ptr->msg_type = map_com->message_type;
        psm_ptr->msg_flag = map_com->message_flag;
        vm_ptr->recvcom_flag = 1;
		xap_watch_dog(27);
    }
    xap_watch_dog(25);
    return 1;
}

u8 map_send_comdata ( u8 * data_flow )  // send map common service data
{
    u8  result;
    u32 temp_did;
    struct xapp_vm_data *vm_ptr;
    struct psmvm_data *psm_ptr;
    struct MapComSrv_struct map_com;

    //xap_msg_display ( data_flow );
    if( ( result = map_com_ftos ( &map_com, data_flow ) ) == 0 )
    {
        xap_send_error ( "[%d]Com:%d sending translate error", map_com.dialogue_id, map_com.message_type );
        return 0;
    }
    temp_did = map_com.dialogue_id;
    if( temp_did >= ( xap_vm_ptr->grantdid ) )
    {
        xap_send_error ( "[%d]Com:%d sending did error", temp_did, map_com.message_type );
        return 0;
    }
    vm_ptr = ( xapp_vm_data * ) & xap_vm_ptr->xap_data[temp_did];
    if( ( vm_ptr->recvcom_flag == 1 ) && ( map_com.message_type != MAP_U_ABORT ) )      /* daniel change on 2005-4-29 */
    {
        xap_send_error ( "[%d]Com:%d sending without permit", temp_did, map_com.message_type );
        return 0;
    }
    psm_ptr = ( psmvm_data * ) & vm_ptr->psm_data;
    if( result == 2 || map_com.message_type == MAP_DELIMITER )
    {
    	if (result == 2)
    		xap_watch_dog(64);
    	else
    		xap_watch_dog(65);
        psm_ptr->delimiter_flag = 1;
    }
    if( map_com.message_type != MAP_DELIMITER )
    {
        memcpy ( &vm_ptr->recvcom_data, &map_com, sizeof ( MapComSrv_struct ) );
        psm_ptr->msg_type = map_com.message_type;
        psm_ptr->msg_flag = map_com.message_flag;
        vm_ptr->recvcom_flag = 1;
		xap_watch_dog(28);
    }
    xap_watch_dog(25);
    return 1;
}

u8 map_check_sendopr ( u32 did )
{
    struct xapp_vm_data *vm_ptr;

    if( did >= ( xap_vm_ptr->grantdid ) )
        return 0;
    vm_ptr = ( xapp_vm_data * ) & xap_vm_ptr->xap_data[did];
    if( vm_ptr->recvopr_flag == 1 )
        return 0;
    return 1;
}

u8 map_send_oprdata ( u8 * data_flow )  // send map operation service data
{
    u8  result;
    u32 temp_did;
    struct xapp_vm_data *vm_ptr;
    struct MapOprData_struct map_opr;

    //xap_msg_display ( data_flow );
    if( ( result = map_opr_ftos ( &map_opr, data_flow ) ) == 0 )
    {
        xap_send_error ( "[%d]Opr:%d sending translate error", map_opr.dialogue_id, map_opr.message_type );
        return 0;
    }
    temp_did = map_opr.dialogue_id;
    if( temp_did >= ( xap_vm_ptr->grantdid ) )
    {
        xap_send_error ( "[%d]Opr:%d sending did error", temp_did, map_opr.message_type );
        return 0;
    }
    vm_ptr = ( xapp_vm_data * ) & xap_vm_ptr->xap_data[temp_did];
    if( vm_ptr->recvopr_flag == 1 )
    {
        xap_send_error ( "[%d]Opr:%d sending without permit", temp_did, map_opr.message_type );
        return 0;
    }
    xap_msg_display ( data_flow );
    memcpy ( &vm_ptr->recvopr_data, &map_opr, sizeof ( MapOprData_struct ) );
    if( result == 2 )
    {
        vm_ptr->psm_data.delimiter_flag = 1;
        xap_watch_dog(68);
    }
    vm_ptr->recvopr_flag = 1;
    xap_watch_dog(45);
	xap_watch_dog(47);
	if(map_opr.message_type == SndRoutInfo)
	{
		if(map_opr.message_flag == 1)
		{
			xap_watch_dog(16);
		}
		else
		{
			xap_watch_dog(17);	
		}
	}
	else if(map_opr.message_type == ProvRoamNum)
	{
		if(map_opr.message_flag == 1)
		{
			xap_watch_dog(20);
		}
		else
		{
			xap_watch_dog(21);	
		}
	}
    return 1;
}

u8 map_send_oprdata_struct ( MapOprData_struct * map_opr )      // send map operation service data
{
    u32 temp_did;
    struct xapp_vm_data *vm_ptr;

    //      struct  MapOprData_struct       map_opr;

    temp_did = map_opr->dialogue_id;
    if( temp_did >= ( xap_vm_ptr->grantdid ) )
    {
        xap_send_error ( "[%d]Opr:%d sending did error", temp_did, map_opr->message_type );
        return 0;
    }
    vm_ptr = ( xapp_vm_data * ) & xap_vm_ptr->xap_data[temp_did];

    if( xap_vm_ptr->debug_data.send_control )
    {
        u8  data_flow[512];

        map_opr_stof ( map_opr, data_flow, 1 );
        xap_send_error ( "[%d]Sending Opr:%d in Structure ", map_opr->dialogue_id, map_opr->message_type );
        xap_msg_display ( data_flow );
    }
    if( vm_ptr->recvopr_flag == 1 )
    {
        xap_send_error ( "[%d]Opr:%d sending without permit", temp_did, map_opr->message_type );
        return 0;
    }
    memcpy ( &vm_ptr->recvopr_data, map_opr, sizeof ( MapOprData_struct ) );
    //      if (result == 2)
    vm_ptr->psm_data.delimiter_flag = 0;
    vm_ptr->recvopr_flag = 1;
    xap_watch_dog(45);
	xap_watch_dog(48);
	if(map_opr->message_type == SndRoutInfo)
	{
		if(map_opr->message_flag == 1)
		{
			xap_watch_dog(16);
		}
		else
		{
			xap_watch_dog(17);	
		}
	}
	else if(map_opr->message_type == ProvRoamNum)
	{
		if(map_opr->message_flag == 1)
		{
			xap_watch_dog(20);
		}
		else
		{
			xap_watch_dog(21);	
		}
	}
    return 1;
}

u8 map_get_comdata ( u8 * data_flow, u32 did )
{
    struct xapp_vm_data *vm_ptr;
    struct psmvm_data *psm_ptr;

    if( did >= ( xap_vm_ptr->grantdid ) )
        return 0;
    vm_ptr = ( xapp_vm_data * ) & xap_vm_ptr->xap_data[did];
    if( vm_ptr->sendcom_flag == 0 )
        return 0;
    psm_ptr = ( psmvm_data * ) & vm_ptr->psm_data;
    map_com_stof ( &vm_ptr->sendcom_data, data_flow, 0 );
    vm_ptr->sendcom_flag = 0;
    xap_watch_dog(6);
    xap_watch_dog(7);
    xap_msg_display ( data_flow );
    return 1;
}

u8 map_get_comdata_struct ( MapComSrv_struct * map_com, u32 did )
{
    struct xapp_vm_data *vm_ptr;
    struct psmvm_data *psm_ptr;

    if( did >= ( xap_vm_ptr->grantdid ) )
        return 0;
    vm_ptr = ( xapp_vm_data * ) & xap_vm_ptr->xap_data[did];
    if( vm_ptr->sendcom_flag == 0 )
        return 0;
    psm_ptr = ( psmvm_data * ) & vm_ptr->psm_data;
    memcpy ( map_com, &vm_ptr->sendcom_data, sizeof ( struct MapComSrv_struct ) );
    if( xap_vm_ptr->debug_data.send_control )
    {
        u8  data_flow[512];

        map_com_stof ( map_com, data_flow, 0 );
        xap_msg_display ( data_flow );
    }
    vm_ptr->sendcom_flag = 0;
    xap_watch_dog(6);
    xap_watch_dog(8);
    return 1;
}

u8 map_get_open ( u8 * data_flow, u8 ssn )
{
    u8  aa;
    u8  ii;
    u8  flag = 0;
    u32 temp_did;

    for ( aa = 0; aa < xap_inter_ptr->regssn_len; aa++ )
    {
        if( xap_inter_ptr->reg_ssn[aa] == ssn ) // find ssn
        {
            flag = 1;
            break;
        }
    }
    if( flag == 0 )
    {
        xap_send_error ( "SSN--%d is not registerd", ssn );
        return 0;
    }
    ii = xap_inter_ptr->open_tail[aa];
    if( xap_inter_ptr->open_head[aa] == ii )    // empty
        return 0;
    temp_did = xap_inter_ptr->open_did[aa][ii];
    xap_inter_ptr->open_tail[aa] = ( ii + 1 ) % XAP_OPEN_LEN;
    if( !map_get_comdata ( data_flow, temp_did ) )
        return 0;
    return 1;
}

u8 map_get_open_struct ( MapComSrv_struct * map_com, u8 ssn )
{
    u8  aa;
    u8  ii;
    u8  flag = 0;
    u32 temp_did;

    for ( aa = 0; aa < xap_inter_ptr->regssn_len; aa++ )
    {
        if( xap_inter_ptr->reg_ssn[aa] == ssn ) // find ssn
        {
            flag = 1;
            break;
        }
    }
    if( flag == 0 )
    {
        xap_send_error ( "SSN--%d is not registerd", ssn );
        return 0;
    }
    ii = xap_inter_ptr->open_tail[aa];
    if( xap_inter_ptr->open_head[aa] == ii )    // empty
        return 0;
    temp_did = xap_inter_ptr->open_did[aa][ii];
    xap_inter_ptr->open_tail[aa] = ( ii + 1 ) % XAP_OPEN_LEN;
    if( !map_get_comdata_struct ( map_com, temp_did ) )
        return 0;
    return 1;
}

u8 map_get_oprdata ( u8 * data_flow, u32 did )
{
    struct xapp_vm_data *vm_ptr;
    struct psmvm_data *psm_ptr;

    if( did >= ( xap_vm_ptr->grantdid ) )
        return 0;
    vm_ptr = ( xapp_vm_data * ) & xap_vm_ptr->xap_data[did];
    if( vm_ptr->sendopr_flag != 1 )
        return 0;
    psm_ptr = ( psmvm_data * ) & vm_ptr->psm_data;
    map_opr_stof ( &vm_ptr->sendopr_data, data_flow, 0 );
    vm_ptr->sendopr_flag = 0;
    xap_watch_dog(11);
    xap_msg_display ( data_flow );
    
    if(vm_ptr->sendopr_data.message_type == SndRoutInfo)
	{
		if(vm_ptr->sendopr_data.message_flag == 2)
		{
			xap_watch_dog(18);
		}
		else
		{
			xap_watch_dog(19);	
		}
	}
	else if(vm_ptr->sendopr_data.message_type == ProvRoamNum)
	{
		if(vm_ptr->sendopr_data.message_flag == 2)
		{
			xap_watch_dog(22);
		}
		else
		{
			xap_watch_dog(23);	
		}
	}
	
    return 1;
}

u8 map_get_oprdata_struct ( MapOprData_struct * map_opr, u32 did )
{
    struct xapp_vm_data *vm_ptr;
    struct psmvm_data *psm_ptr;

    if( did >= ( xap_vm_ptr->grantdid ) )
        return 0;
    vm_ptr = ( xapp_vm_data * ) & xap_vm_ptr->xap_data[did];
    if( vm_ptr->sendopr_flag != 1 )
        return 0;
    psm_ptr = ( psmvm_data * ) & vm_ptr->psm_data;

    memcpy ( map_opr, &vm_ptr->sendopr_data, sizeof ( struct MapOprData_struct ) );
    if( xap_vm_ptr->debug_data.send_control )
    {
        u8  data_flow[512];

        map_opr_stof ( map_opr, data_flow, 0 );
        xap_msg_display ( data_flow );
    }
    vm_ptr->sendopr_flag = 0;
    xap_watch_dog(11);
	if(vm_ptr->sendopr_data.message_type == SndRoutInfo)
	{
		if(vm_ptr->sendopr_data.message_flag == 2)
		{
			xap_watch_dog(18);
		}
		else
		{
			xap_watch_dog(19);	
		}
	}
	else if(vm_ptr->sendopr_data.message_type == ProvRoamNum)
	{
		if(vm_ptr->sendopr_data.message_flag == 2)
		{
			xap_watch_dog(22);
		}
		else
		{
			xap_watch_dog(23);	
		}
	}
    return 1;
}

int map_get_oprType ( u32 did )
{
    struct xapp_vm_data *vm_ptr;

    if( did >= ( xap_vm_ptr->grantdid ) )
        return 0;
    vm_ptr = ( xapp_vm_data * ) & xap_vm_ptr->xap_data[did];
    if( vm_ptr->psm_data.psm_state == XAP_IDLE )
    {
        return -1;
    }
    if( ( vm_ptr->sendopr_data.message_type != 0 ) && ( vm_ptr->sendopr_flag != 0 ) )
    {
        return vm_ptr->sendopr_data.message_type;
    }
    return 0;
}

u32 map_get_dialogueid ( u8 ssn )
{
    u32 did;

    if( ( did = assign_did (  ) ) == 0 )
    {
        xap_send_error ( "Fail to get did(Map)" );
        return 0;
    }
    xap_vm_ptr->xap_data[did].psm_data.xap_flag = XAP_MAP_SSN;
    xap_watch_dog(55);
    return did;
}

#if _SUPPORT_ANSI
u32 is41_get_dialogueid ( u8 ssn )
{
    u32 did;

    if( ( did = assign_did (  ) ) == 0 )
    {
        xap_send_error ( "IS41 Fail to get did(Map)" );
        return 0;
    }
    xap_vm_ptr->xap_data[did].psm_data.xap_flag = XAP_IS41_SSN;
    xap_watch_dog(56);
    return did;
}
#endif

u8 map_get_invokeid ( u32 did )
{
    return assign_iid ( did );
}

#if _SUPPORT_ANSI
u8 map_check_map_flag ( u32 did )
{
    if( did >= ( xap_vm_ptr->grantdid ) )
        return 0;
    if( xap_vm_ptr->xap_data[did].psm_data.xap_flag == XAP_IS41_SSN || xap_vm_ptr->xap_data[did].psm_data.xap_flag == XAP_AIN_SSN )
        return 0;

    return 1;
}
#endif

u8 get_xap_flag(u32 did)
{
    if( did >= ( xap_vm_ptr->grantdid ) )
        return 0;
	
	return xap_vm_ptr->xap_data[did].psm_data.xap_flag; 	
}

int icap_reg_ssn ( u8 ssn )
{
    u8  ii, jj;
    if(wxc2_get_license(LIC_CAP)<=0)
    {
        xap_send_error ( "Can not register ssn in cap provider:no license" );
	return -1;
    }
    ii = xap_inter_ptr->regssn_len;
    if( ii >= MAX_XAP_SSN )
    {
        xap_send_error ( "Can not register ssn in map provider" );
        return -1;
    }
    for ( jj = 0; jj < ii; jj++ )
    {
        if( xap_inter_ptr->reg_ssn[jj] == ssn )
        {
            xap_send_error ( "ssn has registered in map provider" );
            return -1;
        }
    }
    xap_inter_ptr->reg_ssn[ii] = ssn;
    xap_inter_ptr->regssn_flag[ii] = XAP_CAP_SSN;
    xap_inter_ptr->regssn_len++;
    return itcap_reg_ssn ( ssn );
}

u8 cap_check_sendcom ( u32 did )
{
    struct xapp_vm_data *vm_ptr;

    if( did >= ( xap_vm_ptr->grantdid ) )
        return 0;
    vm_ptr = ( xapp_vm_data * ) & xap_vm_ptr->xap_data[did];
    if( vm_ptr->recvcom_flag == 0 )
        return 1;
    return 0;
}

u8 cap_send_comdata ( u8 * data_flow )  // send cap common service data
{
    u8  result;
    u32 temp_did;
    struct xapp_vm_data *vm_ptr;
    struct psmvm_data *psm_ptr;
    struct MapComSrv_struct map_com;

    //xap_msg_display ( data_flow );
    if( ( result = cap_com_ftos ( &map_com, data_flow ) ) == 0 )
        return 0;
    temp_did = map_com.dialogue_id;
    if( temp_did >= ( xap_vm_ptr->grantdid ) )
        return 0;
    vm_ptr = ( xapp_vm_data * ) & xap_vm_ptr->xap_data[temp_did];
    if( vm_ptr->recvcom_flag == 1 )
        return 0;
    psm_ptr = ( psmvm_data * ) & vm_ptr->psm_data;
    if( result == 2 || map_com.message_type == MAP_DELIMITER )
        psm_ptr->delimiter_flag = 1;
    if( map_com.message_type != MAP_DELIMITER )
    {
        memcpy ( &vm_ptr->recvcom_data, &map_com, sizeof ( MapComSrv_struct ) );
        psm_ptr->msg_type = map_com.message_type;
        psm_ptr->msg_flag = map_com.message_flag;
        vm_ptr->recvcom_flag = 1;
		xap_watch_dog(29);
    }
    xap_watch_dog(25);
    return 1;
}

u8 cap_check_sendopr ( u32 did )
{
    struct xapp_vm_data *vm_ptr;

    if( did >= ( xap_vm_ptr->grantdid ) )
        return 0;
    vm_ptr = ( xapp_vm_data * ) & xap_vm_ptr->xap_data[did];
    if( vm_ptr->recvopr_flag == 1 )
        return 0;
    return 1;
}

u8 cap_send_oprdata ( u8 * data_flow )  // send cap operation service data
{
    u8  result;
    u32 temp_did;
    struct xapp_vm_data *vm_ptr;
    struct MapOprData_struct map_opr;
    //u8 info[1024];

    //xap_msg_display ( data_flow );
    if( ( result = cap_opr_ftos ( &map_opr, data_flow ) ) == 0 )
    {
        xap_send_error ( "errro: cap ftos failed" );
        return 0;
    }
    temp_did = map_opr.dialogue_id;
    if( temp_did >= ( xap_vm_ptr->grantdid ) )
    {
        xap_send_error ( "cap errro: did > max did" );
        return 0;
    }
    vm_ptr = ( xapp_vm_data * ) & xap_vm_ptr->xap_data[temp_did];
    if( vm_ptr->recvopr_flag == 1 )
    {
        //xap_send_error("cap errro: quence full");
        return 0;
    }
    xap_msg_display ( data_flow );
    memcpy ( &vm_ptr->recvopr_data, &map_opr, sizeof ( MapOprData_struct ) );
    if( result == 2 )
    {
        vm_ptr->psm_data.delimiter_flag = 1;
        //xap_send_ascout("Delimiter Flag = YES\r\n");
    }
    vm_ptr->recvopr_flag = 1;
    xap_watch_dog(45);
	xap_watch_dog(49);
    //sprintf(info, "cap_send_oprdata: did: %ld, iid: %d, iid_state: %d\r\n", map_opr.dialogue_id, map_opr.invoke_id, xap_vm_ptr->xap_data[map_opr.dialogue_id].psm_data.opr_state[map_opr.invoke_id]);
    //xap_send_ascout(info);

    return 1;
}

u8 cap_get_comdata ( u8 * data_flow, u32 did )
{
    struct xapp_vm_data *vm_ptr;
    struct psmvm_data *psm_ptr;

    vm_ptr = ( xapp_vm_data * ) & xap_vm_ptr->xap_data[did];
    if( vm_ptr->sendcom_flag == 0 )
        return 0;
    psm_ptr = ( psmvm_data * ) & vm_ptr->psm_data;
    cap_com_stof ( &vm_ptr->sendcom_data, data_flow, 0 );
    vm_ptr->sendcom_flag = 0;
    xap_watch_dog(6);
    xap_watch_dog(9);
    xap_msg_display ( data_flow );
    return 1;
}

u8 cap_get_open ( u8 * data_flow, u8 ssn )
{
    u8  aa;
    u8  ii;
    u8  flag = 0;
    u32 temp_did;

    for ( aa = 0; aa < xap_inter_ptr->regssn_len; aa++ )
    {
        if( xap_inter_ptr->reg_ssn[aa] == ssn ) // find ssn
        {
            flag = 1;
            break;
        }
    }
    if( flag == 0 )
    {
        xap_send_error ( "SSN--%d is not registerd", ssn );
        return 0;
    }
    ii = xap_inter_ptr->open_tail[aa];
    if( xap_inter_ptr->open_head[aa] == ii )    // empty
        return 0;
    temp_did = xap_inter_ptr->open_did[aa][ii];
    xap_inter_ptr->open_tail[aa] = ( ii + 1 ) % XAP_OPEN_LEN;
    if( !cap_get_comdata ( data_flow, temp_did ) )
        return 0;
    return 1;
}

u8 cap_get_oprdata ( u8 * data_flow, u32 did )
{
    struct xapp_vm_data *vm_ptr;
    struct psmvm_data *psm_ptr;

    if( did >= ( xap_vm_ptr->grantdid ) )
        return 0;
    vm_ptr = ( xapp_vm_data * ) & xap_vm_ptr->xap_data[did];
    if( vm_ptr->sendopr_flag != 1 )
        return 0;
    psm_ptr = ( psmvm_data * ) & vm_ptr->psm_data;
    cap_opr_stof ( &vm_ptr->sendopr_data, data_flow, 0 );
    vm_ptr->sendopr_flag = 0;
    xap_watch_dog(11);
    xap_msg_display ( data_flow );
    return 1;
}

u32 cap_get_dialogueid ( u8 ssn )
{
    u32 did;

    if( ( did = assign_did (  ) ) == 0 )
    {
        xap_send_error ( "Fail to get did(Cap)" );
        return 0;
    }
    xap_vm_ptr->xap_data[did].psm_data.xap_flag = XAP_CAP_SSN;
    xap_watch_dog(57);
    return did;
}

u8 cap_get_invokeid ( u32 did )
{
    return assign_iid ( did );
}

u8 xapp_check_did_state ( u32 did )
{
    if( xap_vm_ptr->xap_data[did].psm_data.psm_state == XAP_IDLE )
    {
        return 1;
    }
    xap_vm_ptr->debug_data.watch_dog[108]++;
    return 0;
}

u8 xapp_check_did ( u32 did )
{
    if( xap_vm_ptr->xap_data[did].psm_data.psm_state <= XAP_IDLE )
    {
        return 1;
    }
    return 0;
}

u8 map_send_oprsrv ( MapOprSrv_struct * srv_ptr, u8 DelimiterFlag, u8 * data_flow )
{
    u32 len;
    u8  buf[4096];
    MapOprData_struct data_ptr;

    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.param_flag = 0x1f;
#if _SUPPORT_ANSI	
	if(map_check_map_flag(srv_ptr->dialogue_id))	
#endif		
	    len = build_mapparam ( srv_ptr, buf );
#if _SUPPORT_ANSI
	else 
	{
		len = build_ainparam(srv_ptr, buf);	
		data_ptr.map_flag = IS41_FLAG;
	}
#endif	
    //printf ( "map_send_oprsrv: build map param len ; %d \n", len );
    if( len < 0 || len > MAX_MAPPOPR_LEN )
    {
        xap_send_error ( "map_send_oprsrv: build mapparam too long!" );
        return 0;
    }
    data_ptr.param_len = len;
    memcpy ( data_ptr.param, buf, len );
    data_ptr.param_flag |= 0x20;
    map_opr_stof ( &data_ptr, data_flow, DelimiterFlag );

    return map_send_oprdata ( data_flow );
}

u8 map_send_comsrv ( MapComSrv_struct * com_ptr, u8 uDelimiterFlag, u8 * data_flow )
{
    map_com_stof ( com_ptr, data_flow, uDelimiterFlag );
    return map_send_comdata ( data_flow );
}

u8 map_send_open ( MapOpenArgParam * pOpenParam, u8 * uDataFlow )
{
    MapComSrv_struct map_com;
    MapOpen_Arg *pOpenArg;

    pOpenArg = &map_com.dlg_list.open_arg;

    map_com.message_type = MAP_OPEN;
    map_com.message_flag = MAP_REQUEST;
    map_com.port_id = pOpenParam->pid;
    map_com.dialogue_id = pOpenParam->did;
    memcpy ( &pOpenArg->local_add, &pOpenParam->local_add, sizeof ( SCCP_ADDR ) );
    memcpy ( &pOpenArg->peer_add, &pOpenParam->peer_add, sizeof ( SCCP_ADDR ) );
    pOpenArg->acn_data.acn = pOpenParam->acn;
    pOpenArg->acn_data.acn_ver = map_get_acnver ( &pOpenParam->local_add, pOpenParam->acn );
    pOpenArg->param_flag = 0x0b;
	xap_watch_dog(60);
	if (pOpenParam->uDelimeterFlag != 0)
		xap_watch_dog(61);
    return map_send_comsrv ( &map_com, pOpenParam->uDelimeterFlag, uDataFlow );
}

u8 map_send_close ( u32 pid, u32 did, u8 uCloseReasion )
{
    MapComSrv_struct map_com;
    u8  uDataFlow[4096];

    map_com.message_type = MAP_CLOSE;
    map_com.message_flag = MAP_REQUEST;
    map_com.port_id = pid;
    map_com.dialogue_id = did;
    map_com.dlg_list.close_arg.release_method = uCloseReasion;
    map_com.dlg_list.close_arg.param_flag = 0x01;

    return map_send_comsrv ( &map_com, 0, uDataFlow );

}

u8 map_extract_param ( MapOprSrv_struct * srv_ptr, MapOprData_struct * data_ptr, int ver )
{
    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;
    srv_ptr->version = ver;
/*
    if( !( data_ptr->param_flag & 0x20 ) )      // has not parameter
        return 0;
	//some response doesn't take any parameter, like V2 fwdMOSMSResponse...
*/
	if(get_xap_flag(srv_ptr->dialogue_id) == XAP_AIN_SSN)
		return extract_ainparam(srv_ptr, data_ptr->message_type, data_ptr->message_flag, data_ptr->param_len, data_ptr->param);
	
    return extract_mapparam ( srv_ptr, data_ptr->message_type, data_ptr->message_flag, data_ptr->param_len, data_ptr->param );
}

u8 cap_send_oprsrv ( CapArg * pCapArg, u8 DelimiterFlag, u8 * data_flow )
{

    u32 len;
    u8  buf[4096];
    MapOprData_struct data_ptr;

    data_ptr.port_id = pCapArg->port_id;
    data_ptr.dialogue_id = pCapArg->dialogue_id;
    data_ptr.invoke_id = pCapArg->invoke_id;
    data_ptr.message_type = pCapArg->ocode;
    data_ptr.message_flag = pCapArg->message_flag;
    data_ptr.param_flag = 0x1f;
    len = encode_capmsg ( *pCapArg, buf, 4096 );
    //printf ( "cap_send_oprsrv: build map param len ; %d \n", len );
    if( len == 0 || len > MAX_MAPPOPR_LEN )
    {
        xap_send_error ( "cap_send_oprsrv: build capparam too long!" );
        return 0;
    }
    data_ptr.param_len = len;
    memcpy ( data_ptr.param, buf, len );
    data_ptr.param_flag |= 0x20;
    cap_opr_stof ( &data_ptr, data_flow, DelimiterFlag );

    return cap_send_oprdata ( data_flow );
}

u8 cap_send_comsrv ( MapComSrv_struct * com_ptr, u8 uDelimiterFlag, u8 * data_flow )
{
    cap_com_stof ( com_ptr, data_flow, uDelimiterFlag );
    return cap_send_comdata ( data_flow );
}

void wxc2_trace_xapp(u32 did)
{
	if (did >= (xap_vm_ptr->grantdid))
		return;
	xap_vm_ptr->debug_data.monitor_did = did;
}

/******AIN*********/
int ain_reg_ssn ( u8 ssn )
{
    u8  ii, jj;

    ii = xap_inter_ptr->regssn_len;
    if( ii >= MAX_XAP_SSN )
    {
        xap_send_error ( "Can not register ssn in xap provider" );
        return -1;
    }
    for ( jj = 0; jj < ii; jj++ )
    {
        if( xap_inter_ptr->reg_ssn[jj] == ssn )
        {
            xap_send_error ( "ssn has registered in xap provider" );
            return -1;
        }
    }
    xap_inter_ptr->reg_ssn[ii] = ssn;
    xap_inter_ptr->regssn_flag[ii] = XAP_AIN_SSN;
    xap_inter_ptr->regssn_len++;
    return itcap_reg_ssn ( ssn );
}

u32 ain_get_dialogueid ( u8 ssn )
{
    u32 did;

    if( ( did = assign_did (  ) ) == 0 )
    {
        xap_send_error ( "Fail to get did(AIN)" );
        return 0;
    }
    xap_vm_ptr->xap_data[did].psm_data.xap_flag = XAP_AIN_SSN;
    xap_watch_dog(100);
    return did;
}

u8 ain_get_invokeid ( u32 did )
{
	 return assign_iid ( did );
}

int ain_send_oprsrv( MapOprSrv_struct *srv_ptr, u8 DelimiterFlag, u8 *data_flow )
{
   u32 len;
    u8  buf[4096];
    MapOprData_struct data_ptr;

    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.param_flag = 0x1f;
    len = build_mapparam ( srv_ptr, buf );
    //printf ( "map_send_oprsrv: build map param len ; %d \n", len );
    if( len < 0 || len > MAX_MAPPOPR_LEN )
    {
        xap_send_error ( "ain_send_oprsrv: build mapparam too long!" );
        return 0;
    }
    data_ptr.param_len = len;
    memcpy ( data_ptr.param, buf, len );
    data_ptr.param_flag |= 0x20;
    map_opr_stof ( &data_ptr, data_flow, DelimiterFlag );

    return map_send_oprdata ( data_flow );
}

u8 ain_get_oprdata_struct ( MapOprData_struct *map_opr, u32 did)//get query or response data
{
	return map_get_oprdata_struct(map_opr, did);
}
u8 ain_send_open( MapOpenArgParam *pOpenParam, u8 *uDataFlow)//set sccp address
{
	//BYTE				len;
	MapComSrv_struct	map_com_srv;
	MapOpen_Arg *pOpenArg;

   	 pOpenArg = &map_com_srv.dlg_list.open_arg;
	map_com_srv.map_flag = IS41_FLAG;
	 map_com_srv.message_type = MAP_OPEN;
	 map_com_srv.message_flag = MAP_REQUEST;
	 map_com_srv.port_id = pOpenParam->pid;
	 map_com_srv.dialogue_id = pOpenParam->did;
	 memcpy ( &pOpenArg->local_add, &pOpenParam->local_add, sizeof ( SCCP_ADDR ) );
	 memcpy ( &pOpenArg->peer_add, &pOpenParam->peer_add, sizeof ( SCCP_ADDR ) );
//	 pOpenArg->acn_data.acn = pOpenParam->acn;
//	 pOpenArg->acn_data.acn_ver = map_get_acnver ( &pOpenParam->local_add, pOpenParam->acn );
//	 pOpenArg->param_flag = 0x0b;
	 pOpenArg->param_flag = 0x0a;
	xap_watch_dog(60);
	if (pOpenParam->uDelimeterFlag != 0)
		xap_watch_dog(61);
    	return map_send_comsrv ( &map_com_srv, pOpenParam->uDelimeterFlag, uDataFlow );
}
u8 ain_send_close ( u32 pid, u32 did, u8 uCloseReasion )
{
	return 1;
}
u8 ain_get_open(u8 *data_flow, u8 ssn )//get query command
{
	return 1;
}
/******AIN*********/
