/*++
*******************************************************************************
* 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:

   digippp.h

Abstract:

   Common includes, defines, structs for the digiisdn driver.


--*/

#ifndef DIGIISDN
#define DIGIISDN

#define UNICODE
#include <ntddk.h>
#include <ndis.h>
#include <ndiswan.h>
#include <ndistapi.h>

// Digi Driver libraries
#include "digilib.h"
#include "dsapi.h"
#include "dxbreg.h"
#include "pppreg.h"

// Digi type definitions used by firmware headers
#include "dxbtypes.h"

#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 DIGIMDMENGINE		DEBUG_00100000
// #define DIGIV2				DEBUG_00200000

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


// Constants used for Wan and Tapi indications

#define DIGI_PPP_MAX_FRAME_SIZE	2048
#define DIGI_PPP_SEND_WINDOW 		4
#define DIGI_PPP_FRAMING_BITS 		(PPP_FRAMING|PPP_COMPRESS_PROTOCOL_FIELD|TAPI_PROVIDER|RAS_FRAMING)
#define DIGI_PPP_HEADER_PADDING 	0
#define DIGI_PPP_TAIL_PADDING		0
#define DIGI_PPP_COMP_BITS			0

// Used by Tapi and AddTapiDevices code.
#define DIGI_PPP_PROVIDER_MEDIA		"PPP"
#define DIGI_PPP_PROVIDER_DEVICE	"DgdsPpp"

typedef enum DIGI_PPP_OBJECT_TYPE
{
	DIGI_PPP_TYPE_UNKNOWN,
	DIGI_PPP_TYPE_ADAPTER,
	DIGI_PPP_TYPE_CALL,
	DIGI_PPP_TYPE_QUEUE_ENTRY,
	DIGI_PPP_TYPE_RXENGINE,
	DIGI_PPP_TYPE_MDMENGINE,
	DIGI_PPP_TYPE_COUNT
} DIGI_PPP_OBJECT_TYPE;


typedef enum DIGI_PPP_CONN_TYPE
{
	DIGI_PPP_CONN_UNKNOWN,
	DIGI_PPP_CONN_TOLLSAVER,
	DIGI_PPP_CONN_D56,
	DIGI_PPP_CONN_D64,
	DIGI_PPP_CONN_COUNT
} DIGI_PPP_CONN_TYPE;



struct DIGI_PPP_ADAPTER;
typedef struct DIGI_PPP_ADAPTER DIGI_PPP_ADAPTER, *PDIGI_PPP_ADAPTER;

struct DIGI_PPP_CALL;
typedef struct DIGI_PPP_CALL DIGI_PPP_CALL, *PDIGI_PPP_CALL;

struct DIGI_PPP_LINE;
typedef struct DIGI_PPP_LINE DIGI_PPP_LINE, *PDIGI_PPP_LINE;

struct DIGI_PPP_EVENT_HANDLERS;
typedef struct DIGI_PPP_EVENT_HANDLERS DIGI_PPP_EVENT_HANDLERS, *PDIGI_PPP_EVENT_HANDLERS;

struct DIGI_PPP_MDMENGINE;
typedef struct DIGI_PPP_MDMENGINE DIGI_PPP_MDMENGINE, *PDIGI_PPP_MDMENGINE;

//
// DIGI_PPP_CODEC is a table of function pointers to routines which write and read (hence 
// CODE and DECODE == CODEC) Spider DIGI_PPP 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 (*PDIGI_PPP_XN_CONNECT)  ( IN PVOID   pOwner,
                                        IN HANDLE  hStream,
                                        IN ULONG   Snid,
                                        IN ULONG   MaxFrameSize,
                                        IN ULONG   ConnType,
                                        IN PSTRING pRemoteAddress );

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

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

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

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

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

typedef struct DIGI_PPP_CODEC
{
	PDIGI_PPP_XN_CONNECT  XnConnect;
	PDIGI_PPP_XN_CONNACK  XnConnack;
	PDIGI_PPP_XN_DISCONN  XnDisconn;
	PDIGI_PPP_XN_CONNEND  XnConnend;
	PDIGI_PPP_XN_LISTEN   XnListen;
	PDIGI_PPP_INTERPRETER XnInterpreter;
	ULONG             XnCbControl;	// GetMsg Control buffer max size
	PCSTR             XnDeviceName;	// Firmware device to open for DIGI_PPP services
} DIGI_PPP_CODEC;


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

typedef VOID (*PDIGI_PPP_ON_CONNECT) ( IN PVOID          pOwner, 
                                       IN ULONG          ChanIndex, 
                                       IN ULONG          Channel,
                                       IN DIGI_PPP_CONN_TYPE ConnType );

typedef VOID (*PDIGI_PPP_ON_CONNACK) ( IN PVOID pOwner,
                                       IN ULONG ChanIndex, 
                                       IN ULONG Channel );

typedef VOID (*PDIGI_PPP_ON_CDACTIVE) (PVOID pAdapter, ULONG line );

typedef VOID (*PDIGI_PPP_ON_CONNEND) (PVOID pAdapter,ULONG line) ;

typedef VOID (*PDIGI_PPP_ON_RXDATA)  ( IN PVOID pOwner,
                                       IN PVOID pData,
                                       IN ULONG cbData );

typedef struct DIGI_PPP_EVENT_HANDLERS
{
	PDIGI_PPP_ON_CDACTIVE OnCDActive;
	PDIGI_PPP_ON_CONNEND  OnConnend;
	PDIGI_PPP_ON_RXDATA   OnData;
} DIGI_PPP_EVENT_HANDLERS, *PDIGI_PPP_EVENT_HANDLERS;


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

#define RXENGINE_GETMSG_COUNT 2

typedef struct DIGI_PPP_RXENGINE
{
	DIGI_PPP_OBJECT_TYPE Type;
	HANDLE               hStream;
	HANDLE               hOwner;
	PDIGI_PPP_EVENT_HANDLERS pDispatch;
	PDIGI_PPP_INTERPRETER    Interpreter;
	ULONG                cbMaxControl;
	ULONG                cbMaxData;
	KDPC                 Dpc;
	KTIMER               Timer;
	KEVENT               Stopped;
	KEVENT               Running;

	// Count of currently pended GetMsg requests.
	ULONG                nGetMsgPending;
	DIGI_SPINLOCK        Lock;

	BOOLEAN              fHalt;			// Halting?
	BOOLEAN              fStarted;		// Engine started?
	BOOLEAN              fDpcRunning;	// The Msg DPC is running?
	BOOLEAN              fPendingHalt;	// Wait till all MSG's are sent?

} DIGI_PPP_RXENGINE, *PDIGI_PPP_RXENGINE;



typedef struct DIGI_PPP_MDMENGINE
{
	DIGI_PPP_OBJECT_TYPE Type;
	HANDLE               hStream;
	DIGI_SPINLOCK        Lock;
	BOOLEAN              fHalt;		// Halting?
	BOOLEAN              fStarted;	// Engine started?
	ULONG	               iLine;
	PDIGI_PPP_ADAPTER    pAdapter;
	PKTHREAD             pThread;
	PDIGI_PPP_EVENT_HANDLERS pDispatch;

} DIGI_PPP_MDMENGINE, *PDIGI_PPP_MDMENGINE;



// An DIGI_PPP_ADAPTER represents a virtual adapter exposed to Ndis.  We expose a virtual
// DIGI_PPP 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 DIGI_PPP_ADAPTER
{
	DIGI_PPP_OBJECT_TYPE Type;

	// String defines name of the adapter, i.e. DigiPPP1001.
	#define CB_DIGI_PPP_ADAPTER_NAME_MAX 32
	ANSI_STRING Name;
	CHAR        NameBuffer[CB_DIGI_PPP_ADAPTER_NAME_MAX];
	// I think this is the firmware module devicename to open, e.g. WAN0.
	CHAR        LineName[CB_DIGI_PPP_ADAPTER_NAME_MAX];

	#define CB_DIGI_PPP_ADAPTER_NUMBER_MAX 8
	ANSI_STRING Number;
	CHAR        NumberBuffer[CB_DIGI_PPP_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
	DIGI_PPP_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
	
   	// 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 
	// DIGI_PPP API version specific structs.
	DIGI_PPP_CODEC XnDispatch;
	DIGI_PPP_EVENT_HANDLERS DispatchTable;

	// Sync line parameters
	struct 
	{
		ULONG	ExternalClocking;	// Really a boolean
		ULONG	LineSpeed;	
		ULONG	IsNrzi;
	} Sync;

	ULONG	MaxFrameSize;
	BOOLEAN IsCsuLine;	// TRUE if on a CSU, FALSE if on a Sync line.

} DIGI_PPP_ADAPTER, *PDIGI_PPP_ADAPTER;


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


// An DIGI_PPP_LINE represents a TAPI line.  Internally, there is a one-to-one mapping 
// between an DIGI_PPP_LINE and an DIGI_PPP_CALL.  
typedef struct DIGI_PPP_LINE
{
	HTAPI_LINE         htLine;		// Tapi handle associated with this line.  Set on OID_TAPI_OPEN
	DIGI_PPP_CALL      *pCall;
	BOOLEAN            Listen;		// Set if Tapi is listening, via SetDefaultMediaDetection
	BOOLEAN            Closing;	// Set while TapiClose is in progress.
	HANDLE             hStream;
	ULONG              Snid;
	ULONG              Speed;		// linespeed in bps.
	PDIGI_PPP_ADAPTER  pAdapter;
	ULONG              iLine;
	DIGI_PPP_RXENGINE  RxEngine;
	DIGI_PPP_MDMENGINE MdmEngine;

} DIGI_PPP_LINE, *PDIGI_PPP_LINE;


// An DIGI_PPP_CALL represents an active DIGI_PPP call.  Each call is exposed to Ndis as a 
// single "line".
typedef struct DIGI_PPP_CALL
{
	DIGI_PPP_OBJECT_TYPE Type;

	ULONG State;

	DIGI_SPINLOCK Lock;

	// 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
	PDIGI_PPP_ADAPTER pAdapter;
	HDRV_LINE         hdLine;

	// String defines the address (phone number) of the remote endpoint
	STRING RemoteAddress;
	#define DIGI_PPP_NUMBER_SIZE 32
	CHAR RemoteAddressBuffer[DIGI_PPP_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 PPPQueueTimer 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;

	ULONG Rate;			// linespeed in bps.

	// Our own version of the connection speed, i.e. TollSaver (voice), Digital 56 or 64
	DIGI_PPP_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_PPP_CALL, *PDIGI_PPP_CALL;


__inline NTSTATUS XnConnect( IN PDIGI_PPP_ADAPTER  pAdapter,
                             IN PVOID          pOwner,
                             IN HANDLE         hStream,
                             IN ULONG          Snid,
                             IN ULONG          MaxFrameSize,
									  IN ULONG          ConnType,
                             IN PSTRING        pRemoteAddress )
{
	return pAdapter->XnDispatch.XnConnect( pOwner, hStream, Snid, MaxFrameSize, ConnType, pRemoteAddress );
}


__inline NTSTATUS XnConnack( IN PDIGI_PPP_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 PDIGI_PPP_ADAPTER pAdapter,
                             IN PVOID         pOwner,
                             IN HANDLE        hStream,
                             IN ULONG         ChanIndex,
                             IN ULONG         Channel )
{
	return pAdapter->XnDispatch.XnDisconn( pOwner, hStream, ChanIndex, Channel );
}


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


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


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

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

#include "pppcall.h"
#include "pppcircuit.h"
#include "pppcsu.h"
#include "ppplan.h"
#include "pppmodem.h"
#include "pppmp.h"
#include "pppqueue.h"
#include "ppprx.h"
#include "pppsync.h"
#include "ppptapi.h"
#include "pppwan.h"
#endif
