/*

*****************************************************************************
*                                                                           *
*  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.                                                              *
*                                                                           *
*****************************************************************************

Module Name:

   digix25.h

Abstract:

   This is the primary header file for the DIGIX25 MAC driver.

--*/


//
// NOTE:  I assume ntddk.h, ndis.h, ndiswan.h are included
//        before this file, digix25.h, is included.
//
#include <ndistapi.h>

// temporary
typedef USHORT ushort;

// Spider Streams specific include files
#include "types.h"
#include "stream.h"
#include "ll_proto.h"
#include "ll_control.h"
#include "x25_proto.h"
#include "x25_control.h"
#include "x25db.h"

// Good setting for DigiDebugLevel: f800063f

#define DIGIINIT               ((ULONG)0x00000001)
#define DIGISETINFO            ((ULONG)0x00000002)
#define DIGIGETINFO            ((ULONG)0x00000004)
#define DIGIWANINFO            ((ULONG)0x00000008)

#define DIGISXBINFO            ((ULONG)0x00000010)
#define DIGIX25ROUTE           ((ULONG)0x00000020)
#define DIGIRECVDATA           ((ULONG)0x00000040)
#define DIGITXDATA             ((ULONG)0x00000080)

#define DIGIREFERENCE          ((ULONG)0x00000100)
#define DIGIWANERR             ((ULONG)0x00000200)
#define DIGIWANERRDATA         ((ULONG)0x00000400)
#define DIGIOPENCALLS          ((ULONG)0x00000800)

#define DIGIDIAG1              ((ULONG)0x00001000)
#define DIGIDIAG2              ((ULONG)0x00002000)
#define DIGIDIAG3              ((ULONG)0x00004000)
#define DIGIDIAG4              ((ULONG)0x00008000)

#define DIGIDIAG5              ((ULONG)0x00010000)
#define DIGIDIAG6              ((ULONG)0x00020000)
#define DIGIDIAG7              ((ULONG)0x00040000)
#define DIGIDIAG8              ((ULONG)0x00080000)

#define DIGICALLCTRL           ((ULONG)0x00100000)
#define DIGIMAKECALL           ((ULONG)0x00200000)
#define DIGIDROP               ((ULONG)0x00400000)
#define DIGICLOSECALL          ((ULONG)0x00800000)

#define DIGITAPIEVENT          ((ULONG)0x01000000)
#define DIGITAPIFLOW           ((ULONG)0x02000000)
#define DIGICALLOBJ            ((ULONG)0x04000000)
#define DIGIVERYLOUD           ((ULONG)0x08000000)

#define DIGIFLOW               ((ULONG)0x10000000)
#define DIGIERRORS             ((ULONG)0x20000000)
#define DIGINOTIMPLEMENTED     ((ULONG)0x40000000)
#define DIGIBUGCHECK           ((ULONG)0x80000000)

#define DIGIINFO               (DIGIGETINFO | DIGISETINFO)


// Ndis version info
#define DIGIX25_NDIS_MAJOR_VER   0x03
#define DIGIX25_NDIS_MINOR_VER   0x00

// Size of the ethernet address
#define DIGIX25_LENGTH_OF_ADDRESS 6

// Size of data portion used in GetMsg requests.  Use the largest incoming 
// packet we expect to receive from the adapter.
#define DEFAULT_EXTRA_DATA_SIZE  1576

// Maximum frame size we can send/receive.
#define MAX_FRAME_SIZE 1500

// Maximum MTU size we can handle.
#define MAX_MTU_SIZE 1514

// Maximum number of frames we can send at any given time.
#define DIGI_X25_WINDOW_SIZE 2

#define DIGIX25_MAX_MULTICAST 64;
#define DEFAULT_LINE_SPEED 64000

// The following two media type values *must* match!!!!!
#define MEDIA_TYPE_X25_ANSI     "X25"
#define MEDIA_TYPE_X25_UNICODE  NDIS_STRING_CONST("X25")

// Used in calls to NewCallObject() to indicate no preference for AddressID
#define DIGI_ADDRESSID_ANY		( (ULONG) -1 )

// firmware streams device to open for x25 protocol stack
#define X25_DEVICE_NAME "X250"

//
// Internal Call states
//
enum CALL_OBJECT_STATE
{
	INTERNAL_CALL_STATE_UNKNOWN = 0,
	INTERNAL_CALL_STATE_IDLE,
	INTERNAL_CALL_STATE_OFFERING,
	INTERNAL_CALL_STATE_ACCEPTED,
	INTERNAL_CALL_STATE_DIALTONE,
	INTERNAL_CALL_STATE_PROCEEDING,
	INTERNAL_CALL_STATE_CONNECTED,
	INTERNAL_CALL_STATE_CLOSING,
	INTERNAL_CALL_STATE_MAX
};


//
// SpecialFlags settings
//
#define CALL_OBJ_SPECIAL_1                0x00000001
#define CALL_OBJ_DROP_FRAME               0x00000002

//                           
// These flags indicate the type of connection which as been established.
// If neither the PPP_CONNECTION or RAS_CONNECTION bits are set, then
// it indicates unknown framing type.  The bit assignments for these
// 2 bits are as follows:
//    SpecialFlag:
//
//       76543210|76543210|76543210|76543210
//       xxxxxxxx|xxxxx00x|xxxxxxxx|xxxxxxxx Unknown Framing type
//       xxxxxxxx|xxxxx01x|xxxxxxxx|xxxxxxxx PPP Framing
//       xxxxxxxx|xxxxx10x|xxxxxxxx|xxxxxxxx RAS Framing
//       xxxxxxxx|xxxxx11x|xxxxxxxx|xxxxxxxx Undefined
//
#define CALL_OBJ_PAD_CONNECTION           0x00010000  
#define CALL_OBJ_PPP_FRAMING              0x00020000  
#define CALL_OBJ_RAS_FRAMING              0x00040000

#define CALL_OBJ_FRAME_MASK               (CALL_OBJ_PPP_FRAMING | CALL_OBJ_RAS_FRAMING)
#define CALL_OBJ_UNKNOWN_FRAMING          0x00000000
                                                      
//
// enumeration of various types of objects.
//
typedef enum DIGIWAN_TYPE
{
   DIGIWAN_TYPE_UNKNOWN,
   DIGIWAN_TYPE_DRIVER_OBJECT,
   DIGIWAN_TYPE_ADAPTER_OBJECT,
   DIGIWAN_TYPE_LINE_OBJECT,
   DIGIWAN_TYPE_CALL_OBJECT,
   DIGIWAN_TYPE_ADAPTER_CONTEXT,
	DIGIWAN_TYPE_PHYS_ADAPTER,
	DIGIWAN_TYPE_DEFERRED_GETMSG,
	DIGIWAN_TYPE_ROUTE_ENTRY,
	DIGIWAN_TYPE_ALIAS_ENTRY,
   DIGIWAN_TYPE_MAX
} DIGIWAN_TYPE;

// Pre-define this so it can be included in the driver object.
struct DIGIWAN_ADAPTER_OBJECT;

// This record type is used to store X25 Driver global data.  It is
// used as the MacContext in the call to NdisMRegisterMac.
typedef struct DIGIWAN_DRIVER_OBJECT
{
   // Indicate type of object this is.
   DIGIWAN_TYPE  Type;

   PDRIVER_OBJECT DriverObject;

   // The handle returned by NdisMInitializeWrapper.
   NDIS_HANDLE WrapperHandle;

   // The single Wan adapter exposed to Ndis.
   struct DIGIWAN_ADAPTER_OBJECT *WanAdapter;

}  DIGIWAN_DRIVER_OBJECT, *PDIGIWAN_DRIVER_OBJECT;


//
// This structure contains all the information about a single wan
// adapter exposed to Ndis.
//
typedef struct DIGIWAN_ADAPTER_OBJECT
{
   // Indicate type of object this is.
   DIGIWAN_TYPE  Type; // always DIGIWAN_TYPE_ADAPTER_OBJECT

   // Adapter name in ascii, i.e. "DigiWan1000"
   CHAR Name[32];

	// Service name, i.e. "DigiWan"
	CHAR ServiceName[16];

	// Adapter instance, i.e. "1000"
	CHAR Instance[16];

   // Unicode Adapter Name
   UNICODE_STRING UAdapterName;

   // This is the handle given by the wrapper for calling ndis
   // functions.
   NDIS_HANDLE MiniportAdapterHandle;

   //
   // The ethernet address currently in use.
   //
   UCHAR StationAddress[((DIGIX25_LENGTH_OF_ADDRESS + 
                        (sizeof(ULONG)-1)) & ~(sizeof(ULONG)-1))];

   // TAPI base device ID.
   ULONG TapiBaseID;

   //
   // Keep track of the total number of endpoints for this adapter.  This is 
   // the number of "ports" or tapidevices we expose to RAS.
   //
   ULONG NumberOfEndpoints;

   //
   // Keep track of the number of packets we indicate we can handle from
   // NDISWAN on the send path.
   //
   USHORT MaxSendWindow;

	// Tx WAN packets from Ndis will alloc extra bytes before and after the data
	// buffer as defined by these padding values.
	ULONG HeaderPadding;
	ULONG TailPadding;

   // AdapterContext Queue for indicating status and data up to NDIS Miniport Wrapper.
	struct
	{
	   // The queue.
	   LIST_ENTRY Queue;

	   // Spinlock to protect the queue
	   NDIS_SPIN_LOCK Lock;

	   // AdapterContext queue is processed on expiration of this timer
	   NDIS_MINIPORT_TIMER Timer;

		// Protects against recursion in the AdapterContextTimerFunction.
		BOOLEAN InTimerFunc;
	} AdapterContext;

	// Single logical line on our single logical wan adapter.  That's the paradigm.
	struct
	{
		HTAPI_LINE htLine;
		ULONG DeviceID;
		ULONG NotifyStates;	// Line states enabled for tapi indications
		ULONG CurrentState;
	} Line;

	// List of physical adapters supported by this single logical adapter.
	// Entries on this list are of type DIGIWAN_PHYS_ADAPTER.
	LIST_ENTRY PhysAdapters;

	// Spinlock to protect callobjects queue.
	NDIS_SPIN_LOCK Lock;

} DIGIWAN_ADAPTER_OBJECT, *PDIGIWAN_ADAPTER_OBJECT;



#define DIGIWAN_PHYS_ADAPTER_NAME_MAXLENGTH 16

//
// Describes a single physical adapter running X.25
//
typedef struct DIGIWAN_PHYS_ADAPTER
{
	DIGIWAN_TYPE Type;

	// The name of the adapter/device this struct represents (i.e. DigiSxb2)
	UNICODE_STRING Name;

	// Used to link on the AdapterObject->PhysAdapters list
	LIST_ENTRY List;

	// Pointer to parent AdapterObject.
	PDIGIWAN_ADAPTER_OBJECT WanAdapter;

	// The NT Device (i.e. DigiSxb2) on which we send requests for this line
	HANDLE hDevice;

	// The Sxb stream on which we place a listen request to listen for 
	// incoming calls.  Each physical adapter needs only one listen stream, 
	// regardless of the number of ports.
	HANDLE hListenStream;

	// Dpc object used for deferred GetMsg's on this stream.
	KDPC Dpc;

	// Used to link the calls currently in the tapi state LINECALLSTATE_OFFERING 
	// waiting to be answered or dropped.
	LIST_ENTRY OfferingCalls;

	KSPIN_LOCK Lock;

} DIGIWAN_PHYS_ADAPTER, *PDIGIWAN_PHYS_ADAPTER;


//
// This structure holds information about a given link.  When a link
// is established, the stucture is used to keep information regarding
// the link.
//
typedef struct DIGIWAN_CALL_OBJECT
{
   DIGIWAN_TYPE  Type;

	// Number identifying the virtual wan adapter endpoint for this call object.
	ULONG AddressID;

	// Handle of sxb stream on which this call communicates
	HANDLE hStream;

	// Pointer to phys adapter on which the call resides
	PDIGIWAN_PHYS_ADAPTER PhysAdapter;

	// Port identifier on the adapter
	ULONG Snid;

	// Dpc object used for deferred GetMsg's on this stream.
	KDPC Dpc;

	// Connection ID posted on an incoming call (N_CI)
	ULONG conn_id;

   // List Entry for keeping track of call objects.
   LIST_ENTRY List;

	// Timeout used to clear unanswered incoming calls
	NDIS_MINIPORT_TIMER OfferingTimeout;

	// Pointer to AdapterObject
	PDIGIWAN_ADAPTER_OBJECT pAdapter;

   // Handle on which all calls to the Wan wrapper are sent
   // once a link has been established.
   NDIS_HANDLE WrapperLinkHandle;

   // Keep track of what the current receieve buffer size.  If the call is from a 
   // direct connection, then we will use MAX_MTU_SIZE.  If the call is from a 
   // PAD client, then we use MAX_MTU_SIZE * 2.  This takes into account a frame
   // twice the size of an ethernet frame due to async transparency.
   ULONG CurrentMaxMtuSize;

   // Holds the current incoming packet for this call.
   PUCHAR RxBuffer;

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

   KSPIN_LOCK Lock;

   // Tapi call handle
   HTAPI_CALL htCall;

   // Current state indicated to Tapi
   ULONG TapiCallState;

	// Current state of call specific to this driver
   ULONG InternalCallState;

   // Keep track of the address we are currently connected with.
	UCHAR RemoteAddress[DTEMAXSIZE];
	ULONG RemoteAddressLength;

   // General TAPI info we keep around for queries later.
   ULONG AppSpecific;

   // bearer mode of current call
   ULONG CurBearerMode;
   ULONG BearerModes;

   // media mode currently being monitored
   ULONG CurMediaMode;
   ULONG MediaModes;

   ULONG LocalLinkSpeed;
   ULONG RemoteLinkSpeed;

   //
   // Wan Wrapper Information
   //
   ULONG MaxSendFrameSize;
   ULONG MaxRecvFrameSize;
   ULONG PreamblePadding;
   ULONG PostamblePadding;
   ULONG SendFramingBits;
   ULONG RecvFramingBits;
   ULONG SendCompressionBits;
   ULONG RecvCompressionBits;
   ULONG SendACCM;
   ULONG RecvACCM;

   //
   // RAS downlevel Async PAD client info
   //
   ULONG SendFeatureBits;
   ULONG RecvFeatureBits;

   ULONG SpecialFlags;

   //
   // Call statistic information
   //
   ULONG MtuOverrun;
   ULONG PacketsRecv;
   ULONG PacketsSend;
   ULONG FramesDropped;

}  DIGIWAN_CALL_OBJECT, *PDIGIWAN_CALL_OBJECT;



typedef struct ALIAS_ENTRY
{
	ULONG Type;

	// Next alias entry
	struct ALIAS_ENTRY *pNext;

	// Friendly name
	UNICODE_STRING Alias;

	// NT devicename for the adapter, i.e. DigiSxb2
	UNICODE_STRING DeviceName;

	// Snid: identifies the adapter port associated with this alias
	ULONG Snid;

	// Pointer to physAdapter object which defines the adapter and keeps the 
	// device handle used to communicate with DigiSxb for this adapter.
	PDIGIWAN_PHYS_ADAPTER PhysAdapter;
	
} ALIAS_ENTRY, *PALIAS_ENTRY;

typedef struct ROUTE_ENTRY
{
	ULONG Type;

	// Next Router entry
	struct ROUTE_ENTRY *pNext;

	// X.25 address
	ANSI_STRING Address;

	// Alias defining the adapter and port/snid
	PALIAS_ENTRY pAlias;

} ROUTE_ENTRY, *PROUTE_ENTRY;



typedef enum DIGI_MEM_COMPARES
{
   AddressesAreEqual,
   AddressesOverlap,
   AddressesAreDisjoint
} DIGI_MEM_COMPARES,*PDIGI_MEM_COMPARES;


//
// We do this union so we can guarantee that the required data is alway
// available.
//
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;


typedef struct DIGIWAN_DEFERRED_GETMSG
{
	ULONG Type;
	PKDPC pDpc;
	HANDLE hStream;
	ULONG ControlLength;
	PUCHAR pData;
	ULONG DataLength;
	HANDLE Context;
	PDSL_GETMSG_COMPLETION_ROUTINE CompletionRoutine;
} DIGIWAN_DEFERRED_GETMSG, *PDIGIWAN_DEFERRED_GETMSG;


//
// Global variables in digix25.c
//
extern ULONG DigiDebugLevel;
extern const PHYSICAL_ADDRESS DigiPhysicalZero;
extern PALIAS_ENTRY gpAliasList;

//
// Global Driver Object which keeps track of the various adapters.
//
extern PDIGIWAN_DRIVER_OBJECT DigiX25DriverObject;

//
// Exported global data for pad.c
//
extern ULONG PADThroughputClassTable[];
