/*++
*******************************************************************************
* 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        "DigiPPP"

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 pOwner) ;

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?
    PDIGI_PPP_ADAPTER    pAdapter;
    HANDLE               hLine;
    PKTHREAD             pThread;
    PDIGI_PPP_EVENT_HANDLERS pDispatch; // callback routines
} 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;

    // 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
