/*++
*******************************************************************************
* Copyright (c) 1990-98 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				*
*																										*
*******************************************************************************

Module Name:

   digiisdn.h

Abstract:

   Common includes, defines, structs for the digiisdn driver.


Author:

   Michael Zarns

--*/


#define UNICODE
#include <ntddk.h>
#include "digilib.h"	// Needed for NT5_BUILD definition

#if NT5_BUILD
#pragma message( "\nCompiling with NDIS50_MINIPORT defined\n" )
#define NDIS50_MINIPORT 1
#endif

#include <ndis.h>
#include <ndiswan.h>
#include <ndistapi.h>

// #include "dxbtypes.h"
/*
typedef 	ULONG uint32;
typedef		USHORT uint16;
typedef 	UCHAR uint8;
typedef		LONG  int32;
typedef		CHAR  int8;
*/


// Stream specific include files

#include <types.h>
#include <stream.h>
#include <stropts.h>


#include "ll_proto.h"
#include "ll_control.h"
#include "x25_proto.h"
#include "x25_control.h"
#include "x25db.h"


#include "dsapi.h"
#include "dxbreg.h"

// Digi type definitions used by firmware headers



#define DIGIINIT			DEBUG_00000001
#define DIGIMP				DEBUG_00000002
#define DIGICALL			DEBUG_00000004
#define DIGISTATE			DEBUG_00000008

#define DIGIQUEUE			DEBUG_00000010
#define DIGIRXENGINE 	DEBUG_00000020
#define DIGILISTEN		DEBUG_00000040

#define DIGITX				DEBUG_00000100
#define DIGITXDATA		DEBUG_00000200
#define DIGIRX				DEBUG_00000400
#define DIGIRXDATA		DEBUG_00000800

#define DIGITAPIOID		DEBUG_00001000
#define DIGIWANOID		DEBUG_00002000
#define DIGILANOID		DEBUG_00004000
#define DIGIOID			DEBUG_00008000

#define DIGITAPIEVENT	DEBUG_00010000
#define DIGIWANEVENT		DEBUG_00020000

#define DIGIX25				DEBUG_00100000
#define DIGIDIAG				DEBUG_00200000

#define DIGIWARN		DEBUG_WARN
#define DIGIERROR		DEBUG_ERROR
#define DIGIBREAK		DEBUG_BREAK

#define	X25_BAUD_RATE	204800
#define X25_DEVICE_NAME	"X250"
#define CALL_OBJ_PAD_CONNECTION           0x00010000  
#define CALL_OBJ_PPP_FRAMING              0x00020000  
#define CALL_OBJ_RAS_FRAMING              0x00040000
#define CALL_OBJ_SPECIAL_1                0x00000001
#define CALL_OBJ_DROP_FRAME               0x00000002


#define CALL_OBJ_FRAME_MASK               (CALL_OBJ_PPP_FRAMING | CALL_OBJ_RAS_FRAMING)
#define CALL_OBJ_UNKNOWN_FRAMING          0x00000000
#define MAX_MTU_SIZE 1514
#define DEFAULT_EXTRA_DATA_SIZE			1576

extern ULONG PADThroughputClassTable[];







// Constants used for Wan and Tapi indications
#define X25_MAX_FRAME_SIZE	1524
#define X25_SEND_WINDOW 		4
#define X25_FRAMING_BITS 		(PPP_FRAMING|PPP_COMPRESS_PROTOCOL_FIELD|TAPI_PROVIDER|RAS_FRAMING)
#define X25_HEADER_PADDING 	4
#define X25_TAIL_PADDING		4
#define X25_COMP_BITS			0

// Used by Tapi and AddTapiDevices code.
#define X25_PROVIDER_MEDIA					"X25"
#define X25_PROVIDER_DEVICE					"DigiWanX"

typedef enum X25_OBJECT_TYPE
{
	X25_TYPE_UNKNOWN,
	X25_TYPE_ADAPTER,
	X25_TYPE_CALL,
	X25_TYPE_QUEUE_ENTRY,
	X25_TYPE_RXENGINE,
	X25_TYPE_COUNT
} X25_OBJECT_TYPE;


typedef enum X25_CONN_TYPE
{
	X25_CONN_UNKNOWN,
	X25_CONN_TOLLSAVER,
	X25_CONN_D56,
	X25_CONN_D64,
	X25_CONN_COUNT
} X25_CONN_TYPE;



struct X25_CALL;
typedef struct X25_CALL X25_CALL, *PX25_CALL;

struct X25_LINE;
typedef struct X25_LINE X25_LINE, *PX25_LINE;

struct X25_EVENT_HANDLERS;
typedef struct X25_EVENT_HANDLERS X25_EVENT_HANDLERS, *PX25_EVENT_HANDLERS;

//
// ISDN_CODEC is a table of function pointers to routines which write and read (hence 
// CODE and DECODE == CODEC) Spider ISDN messages.  To support PRIme and Dense adapters
// which have different versions of the API, we encapsulate the version specific code
// behind this dispatch table.
//
typedef NTSTATUS (*PX25_XN_CONNECT)  (  IN HANDLE  hStream,
                                        IN ULONG   Snid,
										PUCHAR pRemoteAddress,
										IN ULONG AddressLength );

typedef NTSTATUS (*PX25_XN_CONNACK)  ( IN PVOID   pOwner,
                                        IN HANDLE  hStream,
                                        IN ULONG   ChanIndex,
                                        IN ULONG   Channel );

typedef NTSTATUS (*PX25_XN_DISCONN)  ( IN PVOID   pOwner,
                                        IN HANDLE  hStream,
                                        ULONG   ConnId );

typedef NTSTATUS (*PX25_XN_CONNEND)  ( IN PVOID   pOwner,
                                        IN HANDLE  hStream,
                                        IN ULONG   ChanIndex,
                                        IN ULONG   Channel );

typedef NTSTATUS (*PX25_XN_LISTEN)   ( IN PVOID   pOwner,
                                        IN HANDLE  hStream,
                                        IN ULONG   Snid );

typedef VOID (*PX25_INTERPRETER) ( IN PVOID                pOwner,
                                    IN PX25_EVENT_HANDLERS pDispatchTable,
                                    IN PVOID                pControl,
                                    IN ULONG                cbControl,
                                    IN PVOID                pData, 
                                    IN ULONG                cbData );

typedef struct X25_CODEC
{
	PX25_XN_CONNECT  XnConnect;
	PX25_XN_CONNACK  XnConnack;
	PX25_XN_DISCONN  XnDisconn;
	PX25_XN_LISTEN   XnListen;
	PX25_INTERPRETER XnInterpreter;
	ULONG             XnCbControl;	// GetMsg Control buffer max size
	PCSTR             XnDeviceName;	// Firmware device to open for X25
} X25_CODEC;


//
// ISDN_EVENT_HANDLERS is a table of function pointers to handlers for input (rx) 
// Spider ISDN message handlers.  We handle the messages differently depending on 
// whether they're received on a listen stream or a standard call stream.  
//

typedef VOID (*PX25_ON_CONNECT) (IN PVOID          pOwner,
								IN PVOID pControl ,
								IN PVOID pData );


typedef VOID (*PX25_ON_CONNACK) ( IN PVOID pOwner,
                                   IN PVOID pControl, 
                                   IN PVOID pData );

typedef VOID (*PX25_ON_CACTIVE) ( IN PVOID pOwner );

typedef VOID (*PX25_ON_DISCONN) ( IN PVOID pOwner,IN PVOID pControl, IN PVOID pData);                          
                                  
typedef VOID (*PX25_ON_CONNEND) ( IN PVOID pOwner,
								IN PVOID pControl, 
								IN PVOID pData);
                                   

typedef VOID (*PX25_ON_LISTEN)  ( IN PVOID pOwner );

typedef VOID (*PX25_ON_RXDATA)  ( IN PVOID pOwner,
                                   IN PVOID pControl,
								   IN ULONG cbControl,
								   IN PVOID	pData,
                                   IN ULONG cbData );

typedef struct X25_EVENT_HANDLERS
{
	PX25_ON_CONNECT	OnConnect;  			// N_CI
	PX25_ON_CONNACK  OnConnack;				// N_CC
	PX25_ON_DISCONN  OnDisconn;				// N_DI
	PX25_ON_CONNEND  OnConnend;				// N_DC
	PX25_ON_LISTEN	OnListen;				
	PX25_ON_RXDATA   OnData;
} X25_EVENT_HANDLERS, *PX25_EVENT_HANDLERS;


// An ISDN_RXENGINE struct is used by the RxEngine to keep it's state.

#define RXENGINE_GETMSG_COUNT 2

typedef struct X25_RXENGINE
{
	X25_OBJECT_TYPE     Type;
	HANDLE               hStream;
	HANDLE               hOwner;
	PX25_EVENT_HANDLERS pDispatch;
	PX25_INTERPRETER    Interpreter;
	ULONG                cbMaxControl;
	ULONG                cbMaxData;
	KDPC                 Dpc;
	KTIMER               Timer;
	KEVENT               Stopped;
	// Count of currently pended GetMsg requests.
	ULONG                nGetMsgPending;
	DIGI_SPINLOCK        Lock;

	BOOLEAN              fHalt;		// Halting?
	BOOLEAN              fStarted;	// Engine started?

} X25_RXENGINE, *PX25_RXENGINE;


// An X25_ADAPTER represents a virtual adapter exposed to Ndis.  We expose a virtual
// X25 adapter to Ndis for each line.  Thus, a two-line card exposes two adapters to
// Ndis, each associated with a single physical line.

typedef struct X25_ADAPTER
{
	X25_OBJECT_TYPE Type;

	// String defines name of the adapter, i.e. DigiIsdn1001.
	#define CB_X25_ADAPTER_NAME_MAX 32
	ANSI_STRING Name;
	CHAR        NameBuffer[CB_X25_ADAPTER_NAME_MAX];

	#define CB_X25_ADAPTER_NUMBER_MAX 8
	ANSI_STRING Number;
	CHAR        NumberBuffer[CB_X25_ADAPTER_NUMBER_MAX];

	LIST_ENTRY ListEntry;	// Entry on list of adapters.

	// Tapi and Ndis info
	HANDLE        hMiniport;	// Handle identifying this adapter for Ndis and Tapi.
	ULONG         TapiBaseId;	// Base DeviceId assigned by Tapi.  One DeviceId per line
	ULONG         nLines;		// Number of Lines == # DeviceIds == # Calls == # BChannels
	X25_LINE     * pLines ;		// Array of size nLines
	DIGI_SPINLOCK Lock;

	// Dxb related info
	HANDLE hDevice;			// DsApi device handle represents the adapter
	ULONG  Snid;				// SubNetwork ID identifies the physical line on the adapter
	ULONG LinkSpeed;			// The line speed configured for the wire.
	
	// Used because we need to "listen" for incoming calls.
	struct 
	{
		HANDLE        hStream;				// Dxb stream handle for listen stream
		X25_RXENGINE RxEngine;
		LIST_ENTRY    OfferingListHead;	// List of calls offering incoming connections to Tapi
	} Listen;

	// Call management
	struct
	{
		PKTHREAD   pThread;
		LIST_ENTRY Queue;
		KEVENT     WorkEvent;
		KEVENT     HaltEvent;
	} Mgr;

	// Adapter Context Queue and associated baggage
	struct 
	{
		NDIS_MINIPORT_TIMER Timer;
		DIGI_SPINLOCK       Lock;
		LIST_ENTRY          ListHead;
		BOOLEAN             Ready;		// Entries can only be inserted when "Ready"
	} Queue;

	// XN* Dispatch table.  Use function pointers here encapsulate reading/writing 
	// X25 API version specific structs.
	X25_CODEC XnDispatch;

} X25_ADAPTER, *PX25_ADAPTER;

#define AdapterAcquireLock( pAdapter ) DigiAcquireSpinLock( &(pAdapter)->Lock )
#define AdapterReleaseLock( pAdapter ) DigiReleaseSpinLock( &(pAdapter)->Lock )

// An X25_LINE represents a TAPI line.  Internally, there is a one-to-one mapping 
// between an X25_LINE and an X25_CALL.  
typedef struct X25_LINE
{
	HTAPI_LINE htLine;		// Tapi handle associated with this line.  Set on OID_TAPI_OPEN
	X25_CALL  *pCall;
	BOOLEAN    Listen;		// Set if Tapi is listening, via SetDefaultMediaDetection

} X25_LINE, *PX25_LINE;


// An X25_CALL represents an active X25 call.  Each call is exposed to Ndis as a 
// single "line".
typedef struct X25_CALL
{
	X25_OBJECT_TYPE Type;

	ULONG State;

	// List held by adapter of calls currently "offering" incoming connections to Tapi
	LIST_ENTRY OfferingListEntry;

	// Call Mgr Thread fields
	struct 
	{
		LIST_ENTRY ListEntry;	// Entry on list of calls with "work to do" by the thread
		ULONG      Action;		// The type of "work to do" for this call
	} Mgr;

	// Parent adapter and line
	PX25_ADAPTER pAdapter;
	HDRV_LINE     hdLine;

	// String defines the address (phone number) of the remote endpoint
	STRING RemoteAddress;
	ULONG  RemoteAddressLength;
	#define X25_NUMBER_SIZE 32
	CHAR RemoteAddressBuffer[X25_NUMBER_SIZE+1];	// Add 1 to force NULL termination

	// Tapi handle for this call.  Used when sending indications up to Tapi.
	HTAPI_CALL htCall;

	ULONG  TapiState;		// State last passed up to Tapi.

	// Ndis wan handle identifying this connection.  Returned from WanLineup, used to 
	// send indications up to Ndis.
	HANDLE hLink;

	// List used only by IsdnQueueTimer to keep track of links which need an
	// NdisMWanIndicateReceiveComplete indication sent up.
	LIST_ENTRY RxCompleteListEntry;

	// Required Tapi param.  Ignored, but passed back to Tapi on request.
	ULONG AppSpecific;

	// Dxb Stream handle used for all communication with the adapter for this call.
	HANDLE hStream;

	// Bearer Mode current and mask requested in Tapi MakeCall request
	ULONG BearerModeMask;
	ULONG BearerMode;

	// Media Mode current and mask requested in Tapi MakeCall request
	ULONG MediaModeMask;
	ULONG MediaMode;

	// Min and Max rate from Tapi MakeCall request
	ULONG RateMin;
	ULONG RateMax;

	// Our own version of the connection speed, i.e. TollSaver (voice), Digital 56 or 64
	X25_CONN_TYPE ConnType;

	// WAN Get/Set Info baggage
	ULONG MaxSendFrameSize;
	ULONG MaxRecvFrameSize;
	ULONG HeaderPadding;
	ULONG TailPadding;
	ULONG SendFramingBits;
	ULONG RecvFramingBits;
	ULONG SendCompressionBits;
	ULONG RecvCompressionBits;
	ULONG SendACCM;
	ULONG RecvACCM;

	DIGI_SPINLOCK Lock;

	X25_RXENGINE RxEngine;

	struct 
	{
		ULONG  ChanIndex;
		ULONG  Channel;
	} Incoming;


	ULONG AddressID;
	ULONG conn_id;
	ULONG SpecialFlags;
	ULONG CurrentMaxMtuSize;
	ULONG LocalLinkSpeed;
	ULONG RemoteLinkSpeed;
	// Holds the current incoming packet for this call.
   PUCHAR RxBuffer;

	// Offset into RxBuffer at which new incoming data should be placed.
   ULONG RxOffset;

	ULONG MtuOverrun;
   ULONG PacketsRecv;
   ULONG PacketsSend;
   ULONG FramesDropped;
    ULONG SendFeatureBits;



	
} X25_CALL, *PX25_CALL;


__inline NTSTATUS XnConnectIndication( IN PX25_ADAPTER pAdapter,
					HANDLE  hStream,
					ULONG   Snid,
					PUCHAR pRemoteAddress,
					IN ULONG AddressLength)

{
  	return pAdapter->XnDispatch.XnConnect( hStream, Snid, pRemoteAddress, AddressLength );
}


__inline NTSTATUS XnConnectConfirm( IN PX25_ADAPTER pAdapter,
                             IN PVOID         pOwner,
                             IN HANDLE        hStream,
                             IN ULONG         ChanIndex,
                             IN ULONG         Channel )
{
	return pAdapter->XnDispatch.XnConnack( pOwner, hStream, ChanIndex, Channel );
}


__inline NTSTATUS XnDisconn( IN PX25_CALL pCall,	
                             IN HANDLE        hStream,
                             IN ULONG         ConnId)
{
	return pCall->pAdapter->XnDispatch.XnDisconn( pCall, hStream, ConnId );
}

/*
__inline NTSTATUS XnConnend( IN PX25_ADAPTER pAdapter,
                             IN PVOID         pOwner,
                             IN HANDLE        hStream
                             )
{
	return pAdapter->XnDispatch.XnConnend( pOwner, hStream );
}
*/

__inline NTSTATUS XnListen( IN PX25_ADAPTER pAdapter,
                            IN HANDLE        hStream,
                            IN ULONG         Snid )
{
	return pAdapter->XnDispatch.XnListen( pAdapter, hStream, Snid );
}


__inline ULONG XnCbControl( IN PX25_ADAPTER pAdapter )
{
	return pAdapter->XnDispatch.XnCbControl;
}

__inline PCSTR XnDeviceName( IN PX25_ADAPTER pAdapter )
{
	return pAdapter->XnDispatch.XnDeviceName;
}

typedef union X25_primitives
{
   struct xcallf     xcall;
   struct xccnff     xccnf;
   struct xdataf     xdata;
   struct xdatacf    xdatac;
   struct xedataf    xedata;
   struct xedatacf   xedatac;
   struct xrstf      xrst;
   struct xrscf      xrscf;
   struct xdiscf     xdisc;
   struct xdcnff     xdcnf;
   struct xabortf    abort;
   struct xlistenf   xlisten;
   struct xcanlisf   xcanlis;
   struct pvcattf    pvcatt;
   struct pvcdetf    pvcdet;
   struct i_xdiscf	 i_xdisc;
} X25_PRIMITIVES;



#include "x25call.h"
#include "x25lan.h"
#include "x25listen.h"
#include "x25mp.h"
#include "x25queue.h"
#include "x25rx.h"
#include "x25tapi.h"
#include "x25wan.h"

