/*****************************************************************************
 * Copyright (c) 1990-2000 Digi International Inc., All Rights Reserved
 * 
 * This software contains proprietary and confidential information of Digi
 * International Inc.  By accepting transfer of this copy, Recipient agrees
 * to retain this software in confidence, to prevent disclosure to others,
 * and to make no use of this software other than that for which it was
 * delivered.  This is an unpublished copyrighted work of Digi International
 * Inc.  Except as permitted by federal law, 17 USC 117, copying is strictly
 * prohibited.
 * 
 * Restricted Rights Legend
 *
 * Use, duplication, or disclosure by the Government is subject to
 * restrictions set forth in sub-paragraph (c)(1)(ii) of The Rights in
 * Technical Data and Computer Software clause at DFARS 252.227-7031 or
 * subparagraphs (c)(1) and (2) of the Commercial Computer Software -
 * Restricted Rights at 48 CFR 52.227-19, as applicable.
 *
 * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
 *
 *****************************************************************************/

static const char tsquared_c_rcsid[] = "@(#) " "$Id: tsquared.c,v 1.10 2000/10/13 12:38:13 jamesp Exp $";

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "tsquared.h"
#include "span.h"
#include "dbgprintf.h"


static BOOL initialized = FALSE;
static uint32 last_error = MGMT_OK;


/***********************************************************************************/
/***********************************************************************************/
/*      Managment Channel Setup Functions */


BOOL ValidateShimVersion(void)
{
#define MINIMUM_SHIM_VERSION	2

	BOOL valid = FALSE;

	get_mgmt_shim_ver_response_t shim_ver_rsp = {0};
	valid = (GetMgmtShimVersion(&shim_ver_rsp) && (shim_ver_rsp.ver >= MINIMUM_SHIM_VERSION));

	return valid;
}

BOOL OpenMgmtChannel(void)
{
	if (!initialized)
	{
		if (!build_span())
		{
			last_error = MGMT_PAM_ERROR_UNABLETOLOADSHIM;
		}
		else
		{
			initialized = TRUE;

			if (!ValidateShimVersion())
			{
				if (GetMgmtLastError() == MGMT_OK)
					last_error = MGMT_PAM_ERROR_INVALIDSHIMVERSION;
				CloseMgmtChannel();
			}
		}
	}

	return initialized;
}


BOOL CloseMgmtChannel(void)
{
	demolish_span();
	initialized = FALSE;
	return TRUE;
}


uint32 GetMgmtLastError(void)
{
	return last_error;
}


/***********************************************************************************/
/***********************************************************************************/
/*      Common Functions */


BOOL CommandSendReceive(uint32 BoardNumber, uint16 Command, void *mpkt, uint16 mpktlen, void *rpkt, uint16 rpktlen)
{
	if (!OpenMgmtChannel())
		return FALSE;

	memset(rpkt, 0, rpktlen);
	last_error = CallMgmtCommand(BoardNumber, Command, mpkt, mpktlen, rpkt, rpktlen);

	return last_error == MGMT_OK;
}


BOOL CommandSend(uint32 BoardNumber, uint16 Command, void *mpkt, uint16 mpktlen)
{
	return CommandSendReceive(BoardNumber, Command, mpkt, mpktlen, NULL, 0);
}


BOOL CommandReceive(uint32 BoardNumber, uint16 Command, void *rpkt, uint16 rpktlen)
{
	return CommandSendReceive(BoardNumber, Command, NULL, 0, rpkt, rpktlen);
}




/***********************************************************************************/
/***********************************************************************************/
/*      Managment Functions */


BOOL GetMgmtBoardCount(get_mgmt_board_no_response_t * response)
{
	return CommandReceive(-1, GET_MGMT_BOARD_NO, (void *) response, sizeof (get_mgmt_board_no_response_t));
}


BOOL GetMgmtBoardInfo(uint32 BoardNumber, get_mgmt_board_info_response_t * response)
{
	get_mgmt_board_info_request_t request;

	request.BoardNo = BoardNumber;
	return CommandSendReceive(BoardNumber, GET_MGMT_BOARD_INFO, (void *) &request, sizeof (get_mgmt_board_info_request_t), (void *) response, sizeof (get_mgmt_board_info_response_t));
}


BOOL GetMgmtShimVersion(get_mgmt_shim_ver_response_t * response)
{
	return CommandReceive(-1, GET_MGMT_SHIM_VER, (void *) response, sizeof (get_mgmt_shim_ver_response_t));
}


BOOL GetMgmtDriverVersions(uint32 BoardNumber, get_mgmt_drv_vers_response_t * response)
{
	return CommandReceive(BoardNumber, GET_MGMT_DRV_VERS, (void *) response, sizeof (get_mgmt_drv_vers_response_t));
}


//BOOL SetMgmtStopTrace(void)
// {
// return CommandSendReceive(-1, SET_MGMT_STOP_TRC, NULL, 0, NULL, 0);
// }




/***********************************************************************************/
/***********************************************************************************/
/*      Adapter Functions */


BOOL GetAdapterInfo(uint32 BoardNumber, get_adapter_info_response_t * response)
{
	return CommandReceive(BoardNumber, GET_ADAPTER_INFO, (void *) response, sizeof (get_adapter_info_response_t));
}


BOOL GetAdapterState(uint32 BoardNumber, get_adapter_state_response_t * response)
{
	return CommandReceive(BoardNumber, GET_ADAPTER_STATE, (void *) response, sizeof (get_adapter_state_response_t));
}


BOOL GetModemNationality(uint32 BoardNumber, get_modem_nationality_response_t * response)
{
	return CommandReceive(BoardNumber, GET_MODEM_NATIONALITY, (void *) response, sizeof (get_modem_nationality_response_t));
}


BOOL SetModemNationality(uint32 BoardNumber, uint32 CountryCode)
{
	set_modem_nationality_request_t request;

	request.country_code = CountryCode;

	return CommandSend(BoardNumber, SET_MODEM_NATIONALITY, (void *) &request, sizeof (set_modem_nationality_request_t));
}


BOOL GetManagementProtocolVersion(uint32 BoardNumber, get_mgmt_protocol_ver_response_t * response)
{
	return CommandReceive(BoardNumber, GET_MGMT_PROTOCOL_VERSION, (void *) response, sizeof (get_mgmt_protocol_ver_response_t));
}




/***********************************************************************************/
/***********************************************************************************/
/*      DS1 Functions */


//GET_DS1_CONFIG              get_ds1_config_request_t            get_ds1_config_response_t
BOOL GetDS1Configuration(uint32 BoardNumber, uint32 Port, get_ds1_config_response_t * response)
{
	get_ds1_config_request_t request;

	request.port = Port;
	return CommandSendReceive(BoardNumber, GET_DS1_CONFIG, (void *) &request, sizeof (get_ds1_config_request_t), (void *) response, sizeof (get_ds1_config_response_t));
}


//SET_DS1_CONFIG              set_ds1_config_request_t            null
BOOL SetDS1Configuration(uint32 BoardNumber, set_ds1_config_request_t * request)
{
	return CommandSend(BoardNumber, SET_DS1_CONFIG, (void *) request, sizeof (set_ds1_config_request_t));
}


//GET_DS1_EXT_CONFIG           get_ds1_ext_config_request_t        get_ds1_ext_config_response_t
BOOL GetDS1ExtendedConfiguration(uint32 BoardNumber, uint32 Port, get_ds1_ext_config_response_t * response)
{
	get_ds1_ext_config_request_t request;

	request.port = Port;
	return CommandSendReceive(BoardNumber, GET_DS1_EXT_CONFIG, (void *) &request, sizeof (get_ds1_ext_config_request_t), (void *) response, sizeof (get_ds1_ext_config_response_t));
}


//SET_DS1_EXT_CONFIG           set_ds1_ext_config_request_t        null
BOOL SetDS1ExtendedConfiguration(uint32 BoardNumber, set_ds1_ext_config_request_t * request)
{
	return CommandSend(BoardNumber, SET_DS1_EXT_CONFIG, (void *) request, sizeof (set_ds1_ext_config_request_t));
}


//GET_DS1_STATUS              get_ds1_status_request_t            get_ds1_status_response_t
BOOL GetDS1Status(uint32 BoardNumber, uint32 Port, get_ds1_status_response_t * response)
{
	get_ds1_status_request_t request;

	request.port = Port;
	return CommandSendReceive(BoardNumber, GET_DS1_STATUS, (void *) &request, sizeof (get_ds1_status_request_t), (void *) response, sizeof (get_ds1_status_response_t));
}


//GET_DS1_EXT_STATUS           get_ds1_ext_status_request_t        get_ds1_ext_status_response_t
BOOL GetDS1ExtendedStatus(uint32 BoardNumber, uint32 Port, get_ds1_ext_status_response_t * response)
{
	get_ds1_ext_status_request_t request;

	request.port = Port;
	return CommandSendReceive(BoardNumber, GET_DS1_EXT_STATUS, (void *) &request, sizeof (get_ds1_ext_status_request_t), (void *) response, sizeof (get_ds1_ext_status_response_t));
}


//GET_DS1_CT1_SIG_STATUS         get_ds1_ct1_sig_status_request_t    get_ds1_ct1_sig_status_response_t
BOOL GetDS1CT1SignalStatus(uint32 BoardNumber, uint32 Port, uint32 Channel, get_ds1_ct1_sig_status_response_t * response)
{
	get_ds1_ct1_sig_status_request_t request;

	request.port = Port;
	request.channel = Channel;
	return CommandSendReceive(BoardNumber, GET_DS1_CT1_SIG_STATUS, (void *) &request, sizeof (get_ds1_ct1_sig_status_request_t), (void *) response, sizeof (get_ds1_ct1_sig_status_response_t));
}


//GET_DS1_ALL_CT1_SIG_STATUS      get_all_ds1_ct1_sig_status_request_t    get_all_ds1_ct1_sig_status_response_t
BOOL GetDS1AllCT1SignalStatus(uint32 BoardNumber, uint32 Port, get_all_ds1_ct1_sig_status_response_t * response)
{
	get_all_ds1_ct1_sig_status_request_t request;

	request.port = Port;
	return CommandSendReceive(BoardNumber, GET_DS1_ALL_CT1_SIG_STATUS, (void *) &request, sizeof (get_all_ds1_ct1_sig_status_request_t), (void *) response, sizeof (get_all_ds1_ct1_sig_status_response_t));
}




/***********************************************************************************/
/***********************************************************************************/
/*      BRI Functions */


//GET_BRI_CONFIG              get_bri_config_request_t            get_bri_config_response_t
BOOL GetBRIConfiguration(uint32 BoardNumber, uint32 Port, get_bri_config_response_t * response)
{
	get_bri_config_request_t request;

	request.port = Port;
	return CommandSendReceive(BoardNumber, GET_BRI_CONFIG, (void *) &request, sizeof (get_bri_config_request_t), (void *) response, sizeof (get_bri_config_response_t));
}


//SET_BRI_CONFIG              set_bri_config_request_t            null
BOOL SetBRIConfiguration(uint32 BoardNumber, set_bri_config_request_t * request)
{
	return CommandSend(BoardNumber, SET_BRI_CONFIG, (void *) request, sizeof (set_bri_config_request_t));
}


//GET_BRI_STATUS              get_bri_status_request_t            get_bri_status_response_t
BOOL GetBRIStatus(uint32 BoardNumber, uint32 Port, get_bri_status_response_t * response)
{
	get_bri_status_request_t request;

	request.port = Port;
	return CommandSendReceive(BoardNumber, GET_BRI_STATUS, (void *) &request, sizeof (get_bri_status_request_t), (void *) response, sizeof (get_bri_status_response_t));
}




/***********************************************************************************/
/***********************************************************************************/
/*      Serial Functions */


//GET_SERIAL_CONFIG             get_serial_config_request_t            get_serial_config_response_t
BOOL GetSerialConfiguration(uint32 BoardNumber, uint32 Channel, get_serial_config_response_t * response)
{
	get_serial_config_request_t request;

	request.channel = Channel;
	return CommandSendReceive(BoardNumber, GET_SERIAL_CONFIG, (void *) &request, sizeof (get_serial_config_request_t), (void *) response, sizeof (get_serial_config_response_t));
}


//SET_SERIAL_CONFIG             set_serial_config_request_t            null
BOOL SetSerialConfiguration(uint32 BoardNumber, set_serial_config_request_t * request)
{
	return CommandSend(BoardNumber, SET_SERIAL_CONFIG, (void *) request, sizeof (set_serial_config_request_t));
}


//GET_SERIAL_STATUS             get_serial_status_request_t            get_serial_status_response_t
BOOL GetSerialStatus(uint32 BoardNumber, uint32 Channel, get_serial_status_response_t * response)
{
	get_serial_status_request_t request;

	request.channel = Channel;
	return CommandSendReceive(BoardNumber, GET_SERIAL_STATUS, (void *) &request, sizeof (get_serial_status_request_t), (void *) response, sizeof (get_serial_status_response_t));
}


//GET_SERIAL_EXT_CONFIG     get_serial_ext_config_request_t     get_serial_ext_config_response_t
BOOL GetSerialExtendedConfiguration(uint32 BoardNumber, uint32 Channel, get_serial_ext_config_response_t * response)
{
	get_serial_ext_config_request_t request;

	request.channel = Channel;
	return CommandSendReceive(BoardNumber, GET_SERIAL_EXT_CONFIG, (void *) &request, sizeof (get_serial_ext_config_request_t), (void *) response, sizeof (get_serial_ext_config_response_t));
}


//SET_SERIAL_EXT_CONFIG     set_serial_ext_config_request_t     null
BOOL SetSerialExtendedConfiguration(uint32 BoardNumber, set_serial_ext_config_request_t * request)
{
	return CommandSend(BoardNumber, SET_SERIAL_EXT_CONFIG, (void *) request, sizeof (set_serial_ext_config_request_t));
}


//GET_SERIAL_EXT_STATUS     get_serial_ext_status_request_t     get_serial_ext_status_response_t
BOOL GetSerialExtendedStatus(uint32 BoardNumber, uint32 Channel, get_serial_ext_status_response_t * response)
{
	get_serial_ext_status_request_t request;

	request.channel = Channel;
	return CommandSendReceive(BoardNumber, GET_SERIAL_EXT_STATUS, (void *) &request, sizeof (get_serial_ext_status_request_t), (void *) response, sizeof (get_serial_ext_status_response_t));
}


BOOL GetSerialTestChannelMode(uint32 BoardNumber, uint32 Channel, get_serial_channel_test_mode_response_t * response)
{
	get_serial_channel_test_mode_request_t request;

	request.channel = Channel;
	return CommandSendReceive(BoardNumber, GET_SERIAL_CHANNEL_MODE, (void *) &request, sizeof (request), (void *) response, sizeof (*response));
}

BOOL SetSerialTestChannelMode(uint32 BoardNumber, set_serial_channel_test_mode_request_t * request)
{
	return CommandSend(BoardNumber, SET_SERIAL_CHANNEL_MODE, (void *) request, sizeof (*request));
}

BOOL GetSerialTestStatus(uint32 BoardNumber, uint32 Channel, get_serial_test_status_response_t * response)
{
	get_serial_test_status_request_t request;

	request.channel = Channel;
	return CommandSendReceive(BoardNumber, GET_SERIAL_TEST_STATUS, (void *) &request, sizeof (get_serial_test_status_request_t), (void *) response, sizeof (get_serial_test_status_response_t));
}

BOOL SetSerialTestStatus(uint32 BoardNumber, set_serial_test_status_request_t * request)
{
#ifdef FORCE_TESTMODE_ASYNC
	/*
	 *  Because of a particular firmware oddity,
	 *  we can't assume that the default will be
	 *  to have the serial controller in async. mode.
	 *  So that we don't have to modify the PAM server,
	 *  we force the test mode to be asynchronous here.
	 */ 
	if (request)
		request->st.frame_mode = SERIAL_FRAME_NONE;
#endif

	return CommandSend(BoardNumber, SET_SERIAL_TEST_STATUS, (void *) request, sizeof (*request));
}

BOOL GetSerialTestConfiguration(uint32 BoardNumber, uint32 Channel, get_serial_test_config_response_t * response)
{
	get_serial_test_config_request_t request;

	request.channel = Channel;
	return CommandSendReceive(BoardNumber, GET_SERIAL_TEST_CONFIG, (void *) &request, sizeof (get_serial_test_config_request_t), (void *) response, sizeof (get_serial_test_config_response_t));
}

BOOL SetSerialTestConfiguration(uint32 BoardNumber, set_serial_test_config_request_t * request)
{
	return CommandSend(BoardNumber, SET_SERIAL_TEST_CONFIG, (void *) request, sizeof (*request));
}


/***********************************************************************************/
/***********************************************************************************/
/*      Call Functions */


//GET_CALL_STATUS                 get_call_status_request_t              get_call_status_response_t
BOOL GetCallStatus(uint32 BoardNumber, uint32 Port, uint32 Channel, get_call_status_response_t * response)
{
	get_call_status_request_t request;

	request.port = Port;
	request.channel = Channel;
	return CommandSendReceive(BoardNumber, GET_CALL_STATUS, (void *) &request, sizeof (get_call_status_request_t), (void *) response, sizeof (get_call_status_response_t));
}


//GET_ALL_CALL_STATUS            get_all_call_status_request_t       get_all_call_status_response_t
BOOL GetAllCallStatus(uint32 BoardNumber, uint32 Port, get_all_call_status_response_t * response)
{
	get_all_call_status_request_t request;

	request.port = Port;
	return CommandSendReceive(BoardNumber, GET_ALL_CALL_STATUS, (void *) &request, sizeof (get_all_call_status_request_t), (void *) response, sizeof (get_all_call_status_response_t));
}




/***********************************************************************************/
/***********************************************************************************/
/*      Modem Functions */


//GET_MODEM_CONFIG               get_modem_config_request_t             get_modem_config_response_t
BOOL GetModemConfiguration(uint32 BoardNumber, uint32 Channel, get_modem_config_response_t * response)
{
	get_modem_config_request_t request;

	request.channel = Channel;
	return CommandSendReceive(BoardNumber, GET_MODEM_CONFIG, (void *) &request, sizeof (get_modem_config_request_t), (void *) response, sizeof (get_modem_config_response_t));
}


//SET_MODEM_CONFIG               set_modem_config_request_t             null
BOOL SetModemConfiguration(uint32 BoardNumber, set_modem_config_request_t * request)
{
	return CommandSend(BoardNumber, SET_MODEM_CONFIG, (void *) request, sizeof (set_modem_config_request_t));
}


//GET_MODEM_STATUS               get_modem_status_request_t             get_modem_status_response_t
BOOL GetModemStatus(uint32 BoardNumber, uint32 Channel, get_modem_status_response_t * response)
{
	get_modem_status_request_t request;

	request.channel = Channel;
	return CommandSendReceive(BoardNumber, GET_MODEM_STATUS, (void *) &request, sizeof (get_modem_status_request_t), (void *) response, sizeof (get_modem_status_response_t));
}


//GET_MODEM_EXT_CONFIG       get_modem_ext_config_request_t      get_modem_ext_config_response_t
BOOL GetModemExtendedConfiguration(uint32 BoardNumber, uint32 Channel, get_modem_ext_config_response_t * response)
{
	get_modem_ext_config_request_t request;

	request.channel = Channel;
	return CommandSendReceive(BoardNumber, GET_MODEM_EXT_CONFIG, (void *) &request, sizeof (get_modem_ext_config_request_t), (void *) response, sizeof (get_modem_ext_config_response_t));
}


//SET_MODEM_EXT_CONFIG       set_modem_ext_config_request_t      null
BOOL SetModemExtendedConfiguration(uint32 BoardNumber, set_modem_ext_config_request_t * request)
{
	return CommandSend(BoardNumber, SET_MODEM_EXT_CONFIG, (void *) request, sizeof (set_modem_ext_config_request_t));
}


//GET_MODEM_EXT_STATUS       get_modem_ext_status_request_t      get_modem_ext_status_response_t
BOOL GetModemExtendedStatus(uint32 BoardNumber, uint32 Channel, get_modem_ext_status_response_t * response)
{
	get_modem_ext_status_request_t request;

	request.channel = Channel;
	return CommandSendReceive(BoardNumber, GET_MODEM_EXT_STATUS, (void *) &request, sizeof (get_modem_ext_status_request_t), (void *) response, sizeof (get_modem_ext_status_response_t));
}




/***********************************************************************************/
/***********************************************************************************/
/*      D Channel Functions */


//GET_DCHAN_EXT_CONFIG       get_dchan_ext_config_request_t      get_dchan_ext_config_response_t
BOOL GetDChannelExtendedConfiguration(uint32 BoardNumber, uint32 Port, get_dchan_ext_config_response_t * response)
{
	get_dchan_ext_config_request_t request;

	request.port = Port;
	return CommandSendReceive(BoardNumber, GET_DCHAN_EXT_CONFIG, (void *) &request, sizeof (get_dchan_ext_config_request_t), (void *) response, sizeof (get_dchan_ext_config_response_t));
}


//SET_DCHAN_EXT_CONFIG       set_dchan_ext_config_request_t      null
BOOL SetDChannelExtendedConfiguration(uint32 BoardNumber, set_dchan_ext_config_request_t * request)
{
	return CommandSend(BoardNumber, SET_MODEM_EXT_CONFIG, (void *) request, sizeof (set_dchan_ext_config_request_t));
}


//GET_DCHAN_EXT_STATUS       get_dchan_ext_status_request_t      get_dchan_ext_status_response_t
BOOL GetDChannelExtendedStatus(uint32 BoardNumber, uint32 Port, get_dchan_ext_status_response_t * response)
{
	get_dchan_ext_status_request_t request;

	request.port = Port;
	return CommandSendReceive(BoardNumber, GET_DCHAN_EXT_STATUS, (void *) &request, sizeof (get_dchan_ext_status_request_t), (void *) response, sizeof (get_dchan_ext_status_response_t));
}




/***********************************************************************************/
/***********************************************************************************/
/*      B CHannel Functions */


//GET_BCHAN_STATUS               get_bchan_status_request_t             get_bchan_status_response_t
BOOL GetBChannelStatus(uint32 BoardNumber, uint32 Channel, get_bchan_status_response_t * response)
{
	get_bchan_status_request_t request;

	request.channel = Channel;
	return CommandSendReceive(BoardNumber, GET_BCHAN_STATUS, (void *) &request, sizeof (get_bchan_status_request_t), (void *) response, sizeof (get_bchan_status_response_t));
}


//GET_BCHAN_EXT_CONFIG       get_bchan_ext_config_request_t      get_bchan_ext_config_response_t
BOOL GetBChannelExtendedConfiguration(uint32 BoardNumber, uint32 Channel, get_bchan_ext_config_response_t * response)
{
	get_bchan_ext_config_request_t request;

	request.channel = Channel;
	return CommandSendReceive(BoardNumber, GET_BCHAN_EXT_CONFIG, (void *) &request, sizeof (get_bchan_ext_config_request_t), (void *) response, sizeof (get_bchan_ext_config_response_t));
}


//SET_BCHAN_EXT_CONFIG       set_bchan_ext_config_request_t      null
BOOL SetBChannelExtendedConfiguration(uint32 BoardNumber, set_bchan_ext_config_request_t * request)
{
	return CommandSend(BoardNumber, SET_BCHAN_EXT_CONFIG, (void *) request, sizeof (set_bchan_ext_config_request_t));
}


//GET_BCHAN_EXT_STATUS       get_bchan_ext_status_request_t      get_bchan_ext_status_response_t
BOOL GetBChannelExtendedStatus(uint32 BoardNumber, uint32 Channel, get_bchan_ext_status_response_t * response)
{
	get_bchan_ext_status_request_t request;

	request.channel = Channel;
	return CommandSendReceive(BoardNumber, GET_BCHAN_EXT_STATUS, (void *) &request, sizeof (get_bchan_ext_status_request_t), (void *) response, sizeof (get_bchan_ext_status_response_t));
}
