You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
771 lines
23 KiB
771 lines
23 KiB
/*
|
|
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
|
|
|
(C) Copyright 1998
|
|
All rights reserved.
|
|
|
|
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
|
|
|
Portions of this software are:
|
|
|
|
(C) Copyright 1995, 1999 TriplePoint, Inc. -- http://www.TriplePoint.com
|
|
License to use this software is granted under the terms outlined in
|
|
the TriplePoint Software Services Agreement.
|
|
|
|
(C) Copyright 1992 Microsoft Corp. -- http://www.Microsoft.com
|
|
License to use this software is granted under the terms outlined in
|
|
the Microsoft Windows Device Driver Development Kit.
|
|
|
|
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
|
|
|
@doc INTERNAL Tspi Tspi_c
|
|
|
|
@module Tspi.c |
|
|
|
|
This module contains all the Miniport TAPI OID processing routines. It
|
|
is called by the <f MiniportSetInformation> and <f MiniportQueryInformation>
|
|
routines to handle the TAPI OIDs.
|
|
|
|
This driver conforms to the NDIS 3.0 Miniport interface and provides
|
|
extensions to support Telephonic Services.
|
|
|
|
@head3 Contents |
|
|
@index class,mfunc,func,msg,mdata,struct,enum | Tspi_c
|
|
|
|
@end
|
|
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
|
*/
|
|
|
|
|
|
/* @doc EXTERNAL INTERNAL
|
|
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
|
|
|
@topic 4.0 NDISWAN TAPI Service Provider Interface |
|
|
|
|
The Connection Wrapper interface defines how WAN miniport NIC drivers
|
|
implement telephonic services. It is closely related to the Service
|
|
Provider Interface established in Windows Telephony version 1.0, with
|
|
telephony-aware NDIS miniport NIC drivers taking the place of TAPI
|
|
service providers. This section touches briefly on the concepts
|
|
embodied in Windows Telephony, but the reader is advised to consult the
|
|
documentation published with the Telephony SDK for an in-depth
|
|
discussion.
|
|
|
|
<f Note>: There are subtle differences between the TAPI specification and the
|
|
Windows 95 TAPI implementation. Please refer to the Microsoft Win32 SDK
|
|
for details on the Win32 TAPI specification.
|
|
|
|
The Connection Wrapper itself is an extension of the NDIS WAN library,
|
|
and serves as a router for telephonic requests passed down through TAPI
|
|
from user-mode client applications. WAN Miniport NIC drivers register
|
|
for Connection Wrapper services by calling NdisMRegisterMiniport, and
|
|
then register one or more adapters. When registration and other driver
|
|
initialization have successfully completed, WAN miniport NIC drivers can
|
|
receive telephonic requests from the Connection Wrapper via the standard
|
|
NdisMSetInformation and NdisMQueryInformation mechanisms, and respond by
|
|
calling NdisMQueryInformationComplete or NdisMSetInformationComplete and
|
|
NdisMIndicateStatus to notify the Connection Wrapper of asynchronous
|
|
request completion and unsolicited events (e.g. incoming calls, remote
|
|
disconnections), respectively.
|
|
|
|
@end
|
|
*/
|
|
|
|
#define __FILEID__ TSPI_OBJECT_TYPE
|
|
// Unique file ID for error logging
|
|
|
|
#include "Miniport.h" // Defines all the miniport objects
|
|
#include "string.h"
|
|
|
|
#if defined(NDIS_LCODE)
|
|
# pragma NDIS_LCODE // Windows 95 wants this code locked down!
|
|
# pragma NDIS_LDATA
|
|
#endif
|
|
|
|
|
|
/* @doc INTERNAL Tspi Tspi_c STR_EQU
|
|
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
|
|
|
@func
|
|
|
|
<f STR_EQU> compares two strings for equality, ignoring case.
|
|
|
|
@parm IN PCHAR | s1 |
|
|
A pointer to the string to be compared.
|
|
|
|
@parm IN PCHAR | s2 |
|
|
A pointer to the string to be compared.
|
|
|
|
@parm IN int | len |
|
|
The length of the strings in bytes.
|
|
|
|
@rdesc STR_EQU returns TRUE if the strings are equal, otherwise FASLE.
|
|
|
|
*/
|
|
|
|
BOOLEAN STR_EQU(
|
|
IN PCHAR s1,
|
|
IN PCHAR s2,
|
|
IN int len
|
|
)
|
|
{
|
|
DBG_FUNC("STR_EQU")
|
|
|
|
int index;
|
|
int c1 = 0;
|
|
int c2 = 0;
|
|
|
|
for (index = 0; index < len; index++)
|
|
{
|
|
c1 = *s1++;
|
|
c2 = *s2++;
|
|
if (c1 == 0 || c2 == 0)
|
|
{
|
|
break;
|
|
}
|
|
if (c1 >= 'A' && c1 <= 'Z')
|
|
{
|
|
c1 += 'a' - 'A';
|
|
}
|
|
if (c2 >= 'A' && c2 <= 'Z')
|
|
{
|
|
c2 += 'a' - 'A';
|
|
}
|
|
if (c1 != c2)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
return (c1 == c2);
|
|
}
|
|
|
|
/*
|
|
// This defines the prototype for all TAPI OID request handlers.
|
|
*/
|
|
typedef NDIS_STATUS (__stdcall * PTSPI_REQUEST)
|
|
(
|
|
IN PMINIPORT_ADAPTER_OBJECT pAdapter,
|
|
IN PVOID Request,
|
|
OUT PULONG BytesUsed,
|
|
OUT PULONG BytesNeeded
|
|
);
|
|
|
|
/* @doc EXTERNAL INTERNAL Tspi Tspi_c TSPI_OID_INFO
|
|
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
|
|
|
@struct TSPI_OID_INFO |
|
|
|
|
This structure defines the format of the TAPI OID table entries.
|
|
|
|
@comm
|
|
|
|
*/
|
|
|
|
typedef struct TSPI_OID_INFO
|
|
{
|
|
ULONG Oid; // @field
|
|
// TSPI OID value which identifies this record uniquely.
|
|
|
|
ULONG MinBytesNeeded; // @field
|
|
// Minimum number of bytes needed when this request is given to
|
|
// the miniport.
|
|
|
|
PTSPI_REQUEST Request; // @field
|
|
// Pointer to a function which will be invoked to handle the
|
|
// TSPI request.
|
|
|
|
PUCHAR OidString; // @field
|
|
// OID description string.
|
|
|
|
} TSPI_OID_INFO, *PTSPI_OID_INFO;
|
|
|
|
/*
|
|
// The NDISTAPI.H file defines some of the variable length structures with
|
|
// an extra byte at end (e.g. UCHAR VarArgs[1]). Since the caller is not
|
|
// required to use the optional fields, the length of the structure passed
|
|
// in can be exactly equal to the size of the TAPI request structure, without
|
|
// any extra bytes. So we use TSPI_OPTIONAL_SIZE compensate for this
|
|
// problem in our minimum structure size requirements. With structure pad,
|
|
// there is an additional 4 bytes at the end.
|
|
*/
|
|
#define TSPI_OPTIONAL_SIZE sizeof(ULONG)
|
|
|
|
/*
|
|
// The following is a list of all the possible TAPI OIDs.
|
|
// WARNING! The list is ordered so that it can be indexed directly by the
|
|
// (OID_TAPI_xxx - OID_TAPI_ACCEPT).
|
|
*/
|
|
DBG_STATIC TSPI_OID_INFO TspiSupportedOidTable[] =
|
|
{
|
|
{
|
|
OID_TAPI_ACCEPT,
|
|
sizeof(NDIS_TAPI_ACCEPT)-TSPI_OPTIONAL_SIZE,
|
|
TspiAccept,
|
|
"OID_TAPI_ACCEPT"
|
|
},
|
|
{
|
|
OID_TAPI_ANSWER,
|
|
sizeof(NDIS_TAPI_ANSWER)-TSPI_OPTIONAL_SIZE,
|
|
TspiAnswer,
|
|
"OID_TAPI_ANSWER"
|
|
},
|
|
{
|
|
OID_TAPI_CLOSE,
|
|
sizeof(NDIS_TAPI_CLOSE),
|
|
TspiClose,
|
|
"OID_TAPI_CLOSE"
|
|
},
|
|
{
|
|
OID_TAPI_CLOSE_CALL,
|
|
sizeof(NDIS_TAPI_CLOSE_CALL),
|
|
TspiCloseCall,
|
|
"OID_TAPI_CLOSE_CALL"
|
|
},
|
|
{
|
|
OID_TAPI_CONDITIONAL_MEDIA_DETECTION,
|
|
sizeof(NDIS_TAPI_CONDITIONAL_MEDIA_DETECTION),
|
|
TspiConditionalMediaDetection,
|
|
"OID_TAPI_CONDITIONAL_MEDIA_DETECTION"
|
|
},
|
|
{
|
|
OID_TAPI_DROP,
|
|
sizeof(NDIS_TAPI_DROP)-TSPI_OPTIONAL_SIZE,
|
|
TspiDrop,
|
|
"OID_TAPI_DROP"
|
|
},
|
|
{
|
|
OID_TAPI_GET_ADDRESS_CAPS,
|
|
sizeof(NDIS_TAPI_GET_ADDRESS_CAPS),
|
|
TspiGetAddressCaps,
|
|
"OID_TAPI_GET_ADDRESS_CAPS"
|
|
},
|
|
{
|
|
OID_TAPI_GET_ADDRESS_ID,
|
|
sizeof(NDIS_TAPI_GET_ADDRESS_ID)-TSPI_OPTIONAL_SIZE,
|
|
TspiGetAddressID,
|
|
"OID_TAPI_GET_ADDRESS_ID"
|
|
},
|
|
{
|
|
OID_TAPI_GET_ADDRESS_STATUS,
|
|
sizeof(NDIS_TAPI_GET_ADDRESS_STATUS),
|
|
TspiGetAddressStatus,
|
|
"OID_TAPI_GET_ADDRESS_STATUS"
|
|
},
|
|
{
|
|
OID_TAPI_GET_CALL_ADDRESS_ID,
|
|
sizeof(NDIS_TAPI_GET_CALL_ADDRESS_ID),
|
|
TspiGetCallAddressID,
|
|
"OID_TAPI_GET_CALL_ADDRESS_ID"
|
|
},
|
|
{
|
|
OID_TAPI_GET_CALL_INFO,
|
|
sizeof(NDIS_TAPI_GET_CALL_INFO),
|
|
TspiGetCallInfo,
|
|
"OID_TAPI_GET_CALL_INFO"
|
|
},
|
|
{
|
|
OID_TAPI_GET_CALL_STATUS,
|
|
sizeof(NDIS_TAPI_GET_CALL_STATUS),
|
|
TspiGetCallStatus,
|
|
"OID_TAPI_GET_CALL_STATUS"
|
|
},
|
|
{
|
|
OID_TAPI_GET_DEV_CAPS,
|
|
sizeof(NDIS_TAPI_GET_DEV_CAPS),
|
|
TspiGetDevCaps,
|
|
"OID_TAPI_GET_DEV_CAPS"
|
|
},
|
|
{
|
|
OID_TAPI_GET_DEV_CONFIG,
|
|
sizeof(NDIS_TAPI_GET_DEV_CONFIG),
|
|
TspiGetDevConfig,
|
|
"OID_TAPI_GET_DEV_CONFIG"
|
|
},
|
|
{
|
|
OID_TAPI_GET_ID,
|
|
sizeof(NDIS_TAPI_GET_ID),
|
|
TspiGetID,
|
|
"OID_TAPI_GET_ID"
|
|
},
|
|
{
|
|
OID_TAPI_GET_LINE_DEV_STATUS,
|
|
sizeof(NDIS_TAPI_GET_LINE_DEV_STATUS),
|
|
TspiGetLineDevStatus,
|
|
"OID_TAPI_GET_LINE_DEV_STATUS"
|
|
},
|
|
{
|
|
OID_TAPI_MAKE_CALL,
|
|
sizeof(NDIS_TAPI_MAKE_CALL),
|
|
TspiMakeCall,
|
|
"OID_TAPI_MAKE_CALL"
|
|
},
|
|
{
|
|
OID_TAPI_OPEN,
|
|
sizeof(NDIS_TAPI_OPEN),
|
|
TspiOpen,
|
|
"OID_TAPI_OPEN"
|
|
},
|
|
{
|
|
OID_TAPI_PROVIDER_INITIALIZE,
|
|
sizeof(OID_TAPI_PROVIDER_INITIALIZE),
|
|
TspiProviderInitialize,
|
|
"OID_TAPI_PROVIDER_INITIALIZE"
|
|
},
|
|
{
|
|
OID_TAPI_PROVIDER_SHUTDOWN,
|
|
sizeof(NDIS_TAPI_PROVIDER_SHUTDOWN),
|
|
TspiProviderShutdown,
|
|
"OID_TAPI_PROVIDER_SHUTDOWN"
|
|
},
|
|
{
|
|
OID_TAPI_SET_APP_SPECIFIC,
|
|
sizeof(NDIS_TAPI_SET_APP_SPECIFIC),
|
|
TspiSetAppSpecific,
|
|
"OID_TAPI_SET_APP_SPECIFIC"
|
|
},
|
|
{
|
|
OID_TAPI_SET_CALL_PARAMS,
|
|
sizeof(NDIS_TAPI_SET_CALL_PARAMS),
|
|
TspiSetCallParams,
|
|
"OID_TAPI_SET_CALL_PARAMS"
|
|
},
|
|
{
|
|
OID_TAPI_SET_DEFAULT_MEDIA_DETECTION,
|
|
sizeof(NDIS_TAPI_SET_DEFAULT_MEDIA_DETECTION),
|
|
TspiSetDefaultMediaDetection,
|
|
"OID_TAPI_SET_DEFAULT_MEDIA_DETECTION"
|
|
},
|
|
{
|
|
OID_TAPI_SET_DEV_CONFIG,
|
|
sizeof(NDIS_TAPI_SET_DEV_CONFIG)-TSPI_OPTIONAL_SIZE,
|
|
TspiSetDevConfig,
|
|
"OID_TAPI_SET_DEV_CONFIG"
|
|
},
|
|
{
|
|
OID_TAPI_SET_MEDIA_MODE,
|
|
sizeof(NDIS_TAPI_SET_MEDIA_MODE),
|
|
TspiSetMediaMode,
|
|
"OID_TAPI_SET_MEDIA_MODE"
|
|
},
|
|
{
|
|
OID_TAPI_SET_STATUS_MESSAGES,
|
|
sizeof(NDIS_TAPI_SET_STATUS_MESSAGES),
|
|
TspiSetStatusMessages,
|
|
"OID_TAPI_SET_STATUS_MESSAGES"
|
|
},
|
|
{
|
|
0,
|
|
0,
|
|
NULL,
|
|
"OID_UNKNOWN"
|
|
}
|
|
};
|
|
|
|
#define NUM_OID_ENTRIES (sizeof(TspiSupportedOidTable) / sizeof(TspiSupportedOidTable[0]))
|
|
|
|
/* @doc INTERNAL Tspi Tspi_c GetOidInfo
|
|
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
|
|
|
@func
|
|
|
|
<f GetOidInfo> converts an NDIS TAPI OID to a TSPI_OID_INFO pointer.
|
|
|
|
@parm IN NDIS_OID | Oid |
|
|
The OID to be converted.
|
|
|
|
@rdesc GetOidInfo returns a pointer into the TspiSupportedOidTable for the
|
|
associated OID. If the Oid is not supported in the table, a pointer
|
|
to the last entry is returned, which will contain a NULL Request pointer.
|
|
|
|
*/
|
|
|
|
PTSPI_OID_INFO GetOidInfo(
|
|
IN NDIS_OID Oid
|
|
)
|
|
{
|
|
DBG_FUNC("GetOidInfo")
|
|
|
|
UINT i;
|
|
|
|
for (i = 0; i < NUM_OID_ENTRIES-1; i++)
|
|
{
|
|
if (TspiSupportedOidTable[i].Oid == Oid)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
return (&TspiSupportedOidTable[i]);
|
|
}
|
|
|
|
/* @doc INTERNAL Tspi Tspi_c TspiRequestHandler
|
|
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
|
|
|
@func
|
|
|
|
The <f TspiRequestHandler> request allows for inspection of the TAPI
|
|
portion of the driver's capabilities and current line status.
|
|
|
|
If the Miniport does not complete the call immediately (by returning
|
|
NDIS_STATUS_PENDING), it must call NdisMQueryInformationComplete to
|
|
complete the call. The Miniport controls the buffers pointed to by
|
|
InformationBuffer, BytesWritten, and BytesNeeded until the request
|
|
completes.
|
|
|
|
No other requests will be submitted to the Miniport until
|
|
this request has been completed.
|
|
|
|
<f Note>: Interrupts are in any state during this call.
|
|
|
|
@parm IN PMINIPORT_ADAPTER_OBJECT | pAdapter |
|
|
A pointer to the Miniport's adapter context structure <t MINIPORT_ADAPTER_OBJECT>.
|
|
This is the <t MiniportAdapterContext> we passed into <f NdisMSetAttributes>.
|
|
|
|
@parm IN NDIS_OID | Oid |
|
|
The OID. (See section 2.2.1,2 of the Extensions to NDIS 3.0 Miniports to
|
|
support Telephonic Services specification for a complete description of
|
|
the OIDs.)
|
|
|
|
@parm IN PVOID | InformationBuffer |
|
|
The buffer that will receive the information. (See section 2.2.1,2 of
|
|
the Extensions to NDIS 3.0 Miniports to support Telephonic Services
|
|
specification for a description of the length required for each OID.)
|
|
|
|
@parm IN ULONG | InformationBufferLength |
|
|
The length in bytes of InformationBuffer.
|
|
|
|
@parm OUT PULONG | BytesUsed |
|
|
Returns the number of bytes used from the InformationBuffer.
|
|
|
|
@parm OUT PULONG | BytesNeeded |
|
|
Returns the number of additional bytes needed to satisfy the OID.
|
|
|
|
@rdesc This routine returns one of the following values:
|
|
@flag NDIS_STATUS_SUCCESS |
|
|
If this function is successful.
|
|
|
|
<f Note>: A non-zero return value indicates one of the following error codes:
|
|
|
|
@iex
|
|
NDIS_STATUS_INVALID_DATA
|
|
NDIS_STATUS_INVALID_LENGTH
|
|
NDIS_STATUS_NOT_SUPPORTED
|
|
NDIS_STATUS_PENDING
|
|
NDIS_STATUS_SUCCESS
|
|
|
|
*/
|
|
|
|
NDIS_STATUS TspiRequestHandler(
|
|
IN PMINIPORT_ADAPTER_OBJECT pAdapter,
|
|
IN NDIS_OID Oid,
|
|
IN PVOID InformationBuffer,
|
|
IN ULONG InformationBufferLength,
|
|
OUT PULONG BytesUsed,
|
|
OUT PULONG BytesNeeded
|
|
)
|
|
{
|
|
DBG_FUNC("TspiRequestHandler")
|
|
|
|
NDIS_STATUS Status;
|
|
|
|
PTSPI_OID_INFO OidInfo;
|
|
|
|
DBG_ENTER(pAdapter);
|
|
|
|
/*
|
|
// Get TSPI_OID_INFO pointer.
|
|
*/
|
|
OidInfo = GetOidInfo(Oid);
|
|
|
|
DBG_REQUEST(pAdapter,
|
|
("(OID=0x%08X %s)\n\t\tInfoLength=%d InfoBuffer=0x%X MinLength=%d\n",
|
|
Oid, OidInfo->OidString,
|
|
InformationBufferLength,
|
|
InformationBuffer,
|
|
OidInfo->MinBytesNeeded
|
|
));
|
|
|
|
/*
|
|
// Make sure this is a valid request.
|
|
*/
|
|
if (OidInfo->Request != NULL)
|
|
{
|
|
/*
|
|
// If the buffer provided is at least the minimum required,
|
|
// call the handler to do the work.
|
|
*/
|
|
if (InformationBufferLength >= OidInfo->MinBytesNeeded)
|
|
{
|
|
/*
|
|
// Default BytesUsed indicates that we used the minimum necessary.
|
|
*/
|
|
*BytesUsed = OidInfo->MinBytesNeeded;
|
|
|
|
/*
|
|
// Default BytesNeeded indicates that we don't need any more.
|
|
*/
|
|
*BytesNeeded = 0;
|
|
|
|
Status = OidInfo->Request(pAdapter, InformationBuffer,
|
|
BytesUsed, BytesNeeded);
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
// The caller did not provide an adequate buffer, so we have to
|
|
// tell them how much more we need to satisfy the request.
|
|
// Actually, this is the minimum additional bytes we'll need,
|
|
// the request handler may have even more bytes to add.
|
|
*/
|
|
*BytesUsed = 0;
|
|
*BytesNeeded = (OidInfo->MinBytesNeeded - InformationBufferLength);
|
|
Status = NDIS_STATUS_INVALID_LENGTH;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Status = NDIS_STATUS_TAPI_OPERATIONUNAVAIL;
|
|
}
|
|
|
|
DBG_REQUEST(pAdapter,
|
|
("RETURN: Status=0x%X Needed=%d Used=%d\n",
|
|
Status, *BytesNeeded, *BytesUsed));
|
|
|
|
/*
|
|
// Indicate a status complete if it's needed.
|
|
*/
|
|
if (pAdapter->NeedStatusCompleteIndication)
|
|
{
|
|
pAdapter->NeedStatusCompleteIndication = FALSE;
|
|
NdisMIndicateStatusComplete(pAdapter->MiniportAdapterHandle);
|
|
}
|
|
|
|
DBG_RETURN(pAdapter, Status);
|
|
return (Status);
|
|
}
|
|
|
|
|
|
/* @doc INTERNAL Tspi Tspi_c TspiProviderInitialize
|
|
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
|
|
|
@func
|
|
|
|
This request initializes the TAPI portion of the miniport.
|
|
|
|
@parm IN PMINIPORT_ADAPTER_OBJECT | pAdapter |
|
|
A pointer to the Miniport's adapter context structure <t MINIPORT_ADAPTER_OBJECT>.
|
|
This is the <t MiniportAdapterContext> we passed into <f NdisMSetAttributes>.
|
|
|
|
@parm IN PNDIS_TAPI_PROVIDER_INITIALIZE | Request |
|
|
A pointer to the NDIS_TAPI request structure for this call.
|
|
|
|
@iex
|
|
typedef struct _NDIS_TAPI_PROVIDER_INITIALIZE
|
|
{
|
|
IN ULONG ulRequestID;
|
|
IN ULONG ulDeviceIDBase;
|
|
OUT ULONG ulNumLineDevs;
|
|
OUT ULONG ulProviderID;
|
|
|
|
} NDIS_TAPI_PROVIDER_INITIALIZE, *PNDIS_TAPI_PROVIDER_INITIALIZE;
|
|
|
|
@rdesc This routine returns one of the following values:
|
|
@flag NDIS_STATUS_SUCCESS |
|
|
If this function is successful.
|
|
|
|
<f Note>: A non-zero return value indicates one of the following error codes:
|
|
|
|
@iex
|
|
NDIS_STATUS_RESOURCES
|
|
NDIS_STATUS_FAILURE
|
|
NDIS_STATUS_TAPI_RESOURCEUNAVAIL
|
|
|
|
*/
|
|
|
|
NDIS_STATUS TspiProviderInitialize(
|
|
IN PMINIPORT_ADAPTER_OBJECT pAdapter,
|
|
IN PNDIS_TAPI_PROVIDER_INITIALIZE Request,
|
|
OUT PULONG BytesWritten,
|
|
OUT PULONG BytesNeeded
|
|
)
|
|
{
|
|
DBG_FUNC("TspiProviderInitialize")
|
|
|
|
DBG_ENTER(pAdapter);
|
|
DBG_PARAMS(pAdapter,
|
|
("\n\tulDeviceIDBase=%d\n"
|
|
"\tNumLineDevs=%d\n",
|
|
Request->ulDeviceIDBase,
|
|
pAdapter->NumBChannels
|
|
));
|
|
/*
|
|
// Save the device ID base value.
|
|
*/
|
|
pAdapter->DeviceIdBase = Request->ulDeviceIDBase;
|
|
|
|
/*
|
|
// Return the number of lines.
|
|
*/
|
|
Request->ulNumLineDevs = pAdapter->NumBChannels;
|
|
|
|
/*
|
|
// Before completing the PROVIDER_INIT request, the miniport should fill
|
|
// in the ulNumLineDevs field of the request with the number of line
|
|
// devices supported by the adapter. The miniport should also set the
|
|
// ulProviderID field to a unique (per adapter) value. (There is no
|
|
// method currently in place to guarantee unique ulProviderID values,
|
|
// so we use the virtual address of our adapter structure.)
|
|
*/
|
|
Request->ulProviderID = (ULONG) (ULONG_PTR)pAdapter;
|
|
|
|
/*
|
|
// TODO - Reinitialize the stat counters.
|
|
*/
|
|
pAdapter->TotalRxBytes = 0;
|
|
pAdapter->TotalTxBytes = 0;
|
|
pAdapter->TotalRxPackets = 0;
|
|
pAdapter->TotalTxPackets = 0;
|
|
|
|
/*
|
|
// Try to connect to the DChannel.
|
|
*/
|
|
if (DChannelOpen(pAdapter->pDChannel) != NDIS_STATUS_SUCCESS)
|
|
{
|
|
DBG_ERROR(pAdapter,("Returning NDIS_STATUS_TAPI_NODRIVER\n"));
|
|
return (NDIS_STATUS_TAPI_NODRIVER);
|
|
}
|
|
|
|
DBG_RETURN(pAdapter, NDIS_STATUS_SUCCESS);
|
|
return (NDIS_STATUS_SUCCESS);
|
|
}
|
|
|
|
|
|
/* @doc INTERNAL Tspi Tspi_c TspiProviderShutdown
|
|
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
|
|
|
@func
|
|
|
|
This request shuts down the miniport. The miniport should terminate any
|
|
activities it has in progress.
|
|
|
|
@parm IN PMINIPORT_ADAPTER_OBJECT | pAdapter |
|
|
A pointer to the Miniport's adapter context structure <t MINIPORT_ADAPTER_OBJECT>.
|
|
This is the <t MiniportAdapterContext> we passed into <f NdisMSetAttributes>.
|
|
|
|
@parm IN PNDIS_TAPI_PROVIDER_SHUTDOWN | Request |
|
|
A pointer to the NDIS_TAPI request structure for this call.
|
|
|
|
@iex
|
|
typedef struct _NDIS_TAPI_PROVIDER_SHUTDOWN
|
|
{
|
|
IN ULONG ulRequestID;
|
|
|
|
} NDIS_TAPI_PROVIDER_SHUTDOWN, *PNDIS_TAPI_PROVIDER_SHUTDOWN;
|
|
|
|
@rdesc This routine returns one of the following values:
|
|
@flag NDIS_STATUS_SUCCESS |
|
|
If this function is successful.
|
|
|
|
*/
|
|
|
|
NDIS_STATUS TspiProviderShutdown(
|
|
IN PMINIPORT_ADAPTER_OBJECT pAdapter,
|
|
IN PNDIS_TAPI_PROVIDER_SHUTDOWN Request,
|
|
OUT PULONG BytesRead,
|
|
OUT PULONG BytesNeeded
|
|
)
|
|
{
|
|
DBG_FUNC("TspiProviderShutdown")
|
|
|
|
PBCHANNEL_OBJECT pBChannel;
|
|
// A Pointer to one of our <t BCHANNEL_OBJECT>'s.
|
|
|
|
USHORT BChannelIndex;
|
|
// Index into the pBChannelArray.
|
|
|
|
DBG_ENTER(pAdapter);
|
|
|
|
/*
|
|
// Hangup all of the lines.
|
|
*/
|
|
for (BChannelIndex = 0; BChannelIndex < pAdapter->NumBChannels; BChannelIndex++)
|
|
{
|
|
pBChannel = GET_BCHANNEL_FROM_INDEX(pAdapter, BChannelIndex);
|
|
|
|
if (pBChannel->IsOpen)
|
|
{
|
|
/*
|
|
// Close the BChannel - any open call will be dropped.
|
|
*/
|
|
BChannelClose(pBChannel);
|
|
}
|
|
}
|
|
pAdapter->NumLineOpens = 0;
|
|
|
|
/*
|
|
// Close DChannel.
|
|
*/
|
|
DChannelClose(pAdapter->pDChannel);
|
|
|
|
DBG_RETURN(pAdapter, NDIS_STATUS_SUCCESS);
|
|
return (NDIS_STATUS_SUCCESS);
|
|
}
|
|
|
|
|
|
/* @doc INTERNAL Tspi Tspi_c TspiResetHandler
|
|
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
|
|
|
@func
|
|
|
|
<f TspiResetHandler> is called by the MiniportReset routine after the
|
|
hardware has been reset due to some failure detection. We need to make
|
|
sure the line and call state information is conveyed properly to the
|
|
Connection Wrapper.
|
|
|
|
We only generate hangups on streams which have issued ENABLE_D_CHANNELs
|
|
|
|
This function is called when the PRI board is RESET and when we receive a
|
|
T1_STATUS message with RED alarm set. When we get a RED alarm, we issue
|
|
disable D channel messages for all open links. This is indicated by the
|
|
argument nohup_Link set to NULL.
|
|
|
|
@parm IN PMINIPORT_ADAPTER_OBJECT | pAdapter |
|
|
A pointer to the Miniport's adapter context structure <t MINIPORT_ADAPTER_OBJECT>.
|
|
This is the <t MiniportAdapterContext> we passed into <f NdisMSetAttributes>.
|
|
|
|
*/
|
|
|
|
VOID TspiResetHandler(
|
|
IN PMINIPORT_ADAPTER_OBJECT pAdapter
|
|
)
|
|
{
|
|
DBG_FUNC("TspiResetHandler")
|
|
|
|
PBCHANNEL_OBJECT pBChannel;
|
|
// A Pointer to one of our <t BCHANNEL_OBJECT>'s.
|
|
|
|
USHORT BChannelIndex;
|
|
// Index into the pBChannelArray.
|
|
|
|
DBG_ENTER(pAdapter);
|
|
|
|
/*
|
|
// Force disconnect on all lines.
|
|
*/
|
|
for (BChannelIndex = 0; BChannelIndex < pAdapter->NumBChannels; BChannelIndex++)
|
|
{
|
|
pBChannel = GET_BCHANNEL_FROM_INDEX(pAdapter, BChannelIndex);
|
|
|
|
if (pBChannel->IsOpen &&
|
|
pBChannel->CallState != 0 &&
|
|
pBChannel->CallState != LINECALLSTATE_IDLE)
|
|
{
|
|
TspiCallStateHandler(pAdapter, pBChannel,
|
|
LINECALLSTATE_IDLE,
|
|
0);
|
|
pBChannel->CallState = 0;
|
|
}
|
|
}
|
|
|
|
DBG_LEAVE(pAdapter);
|
|
}
|
|
|